diff --git a/CLOBBER b/CLOBBER index 1a23e9a0205..4ffd5a21871 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Multiple bugs that happened to trigger bug 1042115. +Bug 1046585 moved files to a different directory and required a clobber. diff --git a/Makefile.in b/Makefile.in index 369de4402f9..1c7526b33f6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -219,6 +219,7 @@ ifdef MOZ_CRASHREPORTER echo building symbol store $(RM) -r $(DIST)/crashreporter-symbols $(RM) '$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip' + $(RM) '$(DIST)/$(SYMBOL_FULL_ARCHIVE_BASENAME).zip' $(NSINSTALL) -D $(DIST)/crashreporter-symbols OBJCOPY='$(OBJCOPY)' \ $(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \ diff --git a/accessible/windows/ia2/Makefile.in b/accessible/windows/ia2/Makefile.in deleted file mode 100644 index 23e125e87c2..00000000000 --- a/accessible/windows/ia2/Makefile.in +++ /dev/null @@ -1,9 +0,0 @@ -# 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/. - -# The midl generated code include Windows headers which defines min and max -# macros which conflicts with std::min/max. Suppress the macros: -OS_CXXFLAGS += -DNOMINMAX - -include $(topsrcdir)/config/rules.mk diff --git a/accessible/windows/ia2/moz.build b/accessible/windows/ia2/moz.build index 8d207ed47e2..2c0ef388c33 100644 --- a/accessible/windows/ia2/moz.build +++ b/accessible/windows/ia2/moz.build @@ -45,3 +45,8 @@ LOCAL_INCLUDES += [ ] FINAL_LIBRARY = 'xul' + +# The midl generated code include Windows headers which defines min and max +# macros which conflicts with std::min/max. Suppress the macros: +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/accessible/windows/uia/Makefile.in b/accessible/windows/uia/Makefile.in deleted file mode 100644 index 23e125e87c2..00000000000 --- a/accessible/windows/uia/Makefile.in +++ /dev/null @@ -1,9 +0,0 @@ -# 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/. - -# The midl generated code include Windows headers which defines min and max -# macros which conflicts with std::min/max. Suppress the macros: -OS_CXXFLAGS += -DNOMINMAX - -include $(topsrcdir)/config/rules.mk diff --git a/accessible/windows/uia/moz.build b/accessible/windows/uia/moz.build index 3431d126ed5..6f98f6882a6 100644 --- a/accessible/windows/uia/moz.build +++ b/accessible/windows/uia/moz.build @@ -18,3 +18,8 @@ LOCAL_INCLUDES += [ ] FINAL_LIBRARY = 'xul' + +# The midl generated code include Windows headers which defines min and max +# macros which conflicts with std::min/max. Suppress the macros: +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/b2g/app/B2GLoader.cpp b/b2g/app/B2GLoader.cpp new file mode 100644 index 00000000000..7e0aa962784 --- /dev/null +++ b/b2g/app/B2GLoader.cpp @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 autoindent cindent expandtab: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsXULAppAPI.h" +#include "application.ini.h" +#include "nsXPCOMGlue.h" +#include "nsStringGlue.h" +#include "nsCOMPtr.h" +#include "nsIFile.h" +#include "BinaryPath.h" +#include "nsAutoPtr.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL + +#define ASSERT(x) if (!(x)) { MOZ_CRASH(); } + + +// Functions being loaded by XPCOMGlue +XRE_ProcLoaderServiceRunType XRE_ProcLoaderServiceRun; +XRE_ProcLoaderClientInitType XRE_ProcLoaderClientInit; +XRE_ProcLoaderPreloadType XRE_ProcLoaderPreload; +extern XRE_CreateAppDataType XRE_CreateAppData; +extern XRE_GetFileFromPathType XRE_GetFileFromPath; + +static const nsDynamicFunctionLoad kXULFuncs[] = { + { "XRE_ProcLoaderServiceRun", (NSFuncPtr*) &XRE_ProcLoaderServiceRun }, + { "XRE_ProcLoaderClientInit", (NSFuncPtr*) &XRE_ProcLoaderClientInit }, + { "XRE_ProcLoaderPreload", (NSFuncPtr*) &XRE_ProcLoaderPreload }, + { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, + { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath }, + { nullptr, nullptr } +}; + +static int +GetDirnameSlash(const char *aPath, char *aOutDir, int aMaxLen) +{ + char *lastSlash = strrchr(aPath, XPCOM_FILE_PATH_SEPARATOR[0]); + if (lastSlash == nullptr) { + return 0; + } + int cpsz = lastSlash - aPath + 1; // include slash + if (aMaxLen <= cpsz) { + return 0; + } + strncpy(aOutDir, aPath, cpsz); + aOutDir[cpsz] = 0; + return cpsz; +} + +static bool +GetXPCOMPath(const char *aProgram, char *aOutPath, int aMaxLen) +{ + nsAutoArrayPtr progBuf(new char[aMaxLen]); + nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf); + NS_ENSURE_SUCCESS(rv, false); + + int len = GetDirnameSlash(progBuf, aOutPath, aMaxLen); + NS_ENSURE_TRUE(!!len, false); + + NS_ENSURE_TRUE((len + sizeof(XPCOM_DLL)) < aMaxLen, false); + char *afterSlash = aOutPath + len; + strcpy(afterSlash, XPCOM_DLL); + return true; +} + +static bool +LoadLibxul(const char *aXPCOMPath) +{ + nsresult rv; + + XPCOMGlueEnablePreload(); + rv = XPCOMGlueStartup(aXPCOMPath); + NS_ENSURE_SUCCESS(rv, false); + + rv = XPCOMGlueLoadXULFunctions(kXULFuncs); + NS_ENSURE_SUCCESS(rv, false); + + return true; +} + +/** + * Return true if |arg| matches the given argument name. + */ +static bool +IsArg(const char* arg, const char* s) +{ + if (*arg == '-') { + if (*++arg == '-') { + ++arg; + } + return !strcasecmp(arg, s); + } + +#if defined(XP_WIN) + if (*arg == '/') { + return !strcasecmp(++arg, s); + } +#endif + + return false; +} + +static already_AddRefed +GetAppIni(int argc, const char *argv[]) +{ + nsCOMPtr appini; + nsresult rv; + + // Allow firefox.exe to launch XULRunner apps via -app + // Note that -app must be the *first* argument. + const char *appDataFile = getenv("XUL_APP_FILE"); + if (appDataFile && *appDataFile) { + rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini)); + NS_ENSURE_SUCCESS(rv, nullptr); + } else if (argc > 1 && IsArg(argv[1], "app")) { + if (argc == 2) { + return nullptr; + } + + rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini)); + NS_ENSURE_SUCCESS(rv, nullptr); + + char appEnv[MAXPATHLEN]; + snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]); + if (putenv(appEnv)) { + return nullptr; + } + } + + return appini.forget(); +} + +static bool +LoadStaticData(int argc, const char *argv[]) +{ + char xpcomPath[MAXPATHLEN]; + bool ok = GetXPCOMPath(argv[0], xpcomPath, MAXPATHLEN); + NS_ENSURE_TRUE(ok, false); + + ok = LoadLibxul(xpcomPath); + NS_ENSURE_TRUE(ok, false); + + char progDir[MAXPATHLEN]; + ok = GetDirnameSlash(xpcomPath, progDir, MAXPATHLEN); + NS_ENSURE_TRUE(ok, false); + + nsCOMPtr appini = GetAppIni(argc, argv); + const nsXREAppData *appData; + if (appini) { + nsresult rv = + XRE_CreateAppData(appini, const_cast(&appData)); + NS_ENSURE_SUCCESS(rv, false); + } else { + appData = &sAppData; + } + + XRE_ProcLoaderPreload(progDir, appData); + + if (appini) { + XRE_FreeAppData(const_cast(appData)); + } + + return true; +} + +/** + * Fork and run parent and child process. + * + * The parent is the b2g process and child for Nuwa. + */ +static int +RunProcesses(int argc, const char *argv[]) +{ + /* + * The original main() of the b2g process. It is renamed to + * b2g_main() for the b2g loader. + */ + int b2g_main(int argc, const char *argv[]); + + int ipcSockets[2] = {-1, -1}; + int r = socketpair(AF_LOCAL, SOCK_STREAM, 0, ipcSockets); + ASSERT(r == 0); + int parentSock = ipcSockets[0]; + int childSock = ipcSockets[1]; + + r = fcntl(parentSock, F_SETFL, O_NONBLOCK); + ASSERT(r != -1); + r = fcntl(childSock, F_SETFL, O_NONBLOCK); + ASSERT(r != -1); + + pid_t pid = fork(); + ASSERT(pid >= 0); + bool isChildProcess = pid == 0; + + close(isChildProcess ? parentSock : childSock); + + if (isChildProcess) { + /* The Nuwa process */ + /* This provides the IPC service of loading Nuwa at the process. + * The b2g process would send a IPC message of loading Nuwa + * as the replacement of forking and executing plugin-container. + */ + return XRE_ProcLoaderServiceRun(getppid(), childSock, argc, argv); + } + + // The b2g process + int childPid = pid; + XRE_ProcLoaderClientInit(childPid, parentSock); + return b2g_main(argc, argv); +} + +/** + * B2G Loader is responsible for loading the b2g process and the + * Nuwa process. It forks into the parent process, for the b2g + * process, and the child process, for the Nuwa process. + * + * The loader loads libxul and performs initialization of static data + * before forking, so relocation of libxul and static data can be + * shared between the b2g process, the Nuwa process, and the content + * processes. + */ +int +main(int argc, const char* argv[]) +{ + const char *program = argv[0]; + /* + * Before fork(), libxul and static data of Gecko are loaded for + * sharing. + */ + bool ok = LoadStaticData(argc, argv); + if (!ok) { + return 255; + } + + return RunProcesses(argc, argv); +} diff --git a/b2g/app/moz.build b/b2g/app/moz.build index 77879ddb444..82b60ad6db3 100644 --- a/b2g/app/moz.build +++ b/b2g/app/moz.build @@ -9,6 +9,11 @@ if not CONFIG['LIBXUL_SDK']: PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin" else: PROGRAM = CONFIG['MOZ_APP_NAME'] + if CONFIG['MOZ_B2G_LOADER']: + SOURCES += [ + 'B2GLoader.cpp', + ] + SOURCES += [ 'nsBrowserApp.cpp', ] diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp index bf57ef44574..f4b3e8e45a8 100644 --- a/b2g/app/nsBrowserApp.cpp +++ b/b2g/app/nsBrowserApp.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "nsCOMPtr.h" #include "nsIFile.h" @@ -163,9 +164,22 @@ static int do_main(int argc, char* argv[]) return XRE_main(argc, argv, &sAppData, 0); } -int main(int argc, char* argv[]) +#ifdef MOZ_B2G_LOADER +/* + * The main() in B2GLoader.cpp is the new main function instead of the + * main() here if it is enabled. So, rename it to b2g_man(). + */ +#define main b2g_main +#define _CONST const +#else +#define _CONST +#endif + +int main(int argc, _CONST char* argv[]) { +#ifndef MOZ_B2G_LOADER char exePath[MAXPATHLEN]; +#endif #ifdef MOZ_WIDGET_GONK // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to @@ -175,7 +189,9 @@ int main(int argc, char* argv[]) android::ProcessState::self()->startThreadPool(); #endif - nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath); + nsresult rv; +#ifndef MOZ_B2G_LOADER + rv = mozilla::BinaryPath::Get(argv[0], exePath); if (NS_FAILED(rv)) { Output("Couldn't calculate the application directory.\n"); return 255; @@ -186,6 +202,7 @@ int main(int argc, char* argv[]) return 255; strcpy(++lastSlash, XPCOM_DLL); +#endif // MOZ_B2G_LOADER #if defined(XP_UNIX) // If the b2g app is launched from adb shell, then the shell will wind @@ -209,6 +226,9 @@ int main(int argc, char* argv[]) DllBlocklist_Initialize(); #endif + // B2G loader has already initialized Gecko so we can't initialize + // it again here. +#ifndef MOZ_B2G_LOADER // We do this because of data in bug 771745 XPCOMGlueEnablePreload(); @@ -219,6 +239,7 @@ int main(int argc, char* argv[]) } // Reset exePath so that it is the directory name and not the xpcom dll name *lastSlash = 0; +#endif // MOZ_B2G_LOADER rv = XPCOMGlueLoadXULFunctions(kXULFuncs); if (NS_FAILED(rv)) { @@ -253,7 +274,25 @@ int main(int argc, char* argv[]) int result; { ScopedLogging log; - result = do_main(argc, argv); + char **_argv; + + /* + * Duplicate argument vector to conform non-const argv of + * do_main() since XRE_main() is very stupid with non-const argv. + */ + _argv = new char *[argc + 1]; + for (int i = 0; i < argc; i++) { + _argv[i] = strdup(argv[i]); + MOZ_ASSERT(_argv[i] != nullptr); + } + _argv[argc] = nullptr; + + result = do_main(argc, _argv); + + for (int i = 0; i < argc; i++) { + free(_argv[i]); + } + delete[] _argv; } return result; diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index d6b7b6d01fb..8d8ffb95e17 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index ce0428c1ac6..1504b6198a2 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 1d13daf7789..eb69fb11e14 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index d6b7b6d01fb..8d8ffb95e17 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 6fbcd6cab73..c453c4c7783 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index ac5025ed754..fe961056f9f 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "3842156466e71f41748f86777a1b8fbd379441c0", + "revision": "92b742f333b1f695de3de7c10316bc5ee652d084", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index f3c6b3be044..64d3b921789 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index ec6f85bfb1a..8b59a58ee4e 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index abf8f310868..896f6c73dd1 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index d313fc9629a..2a8a306a1b6 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/confvars.sh b/b2g/confvars.sh index f77d791fb0d..98ef5283328 100644 --- a/b2g/confvars.sh +++ b/b2g/confvars.sh @@ -59,6 +59,7 @@ MOZ_B2G=1 if test "$OS_TARGET" = "Android"; then MOZ_NUWA_PROCESS=1 +MOZ_B2G_LOADER=1 fi MOZ_FOLD_LIBS=1 diff --git a/configure.in b/configure.in index df2d7af316f..40db08e510b 100644 --- a/configure.in +++ b/configure.in @@ -8614,6 +8614,14 @@ if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then AC_DEFINE(MOZ_NUWA_PROCESS) fi AC_SUBST(MOZ_NUWA_PROCESS) +if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_B2G_LOADER"; then + if test -z "$MOZ_NUWA_PROCESS"; then + AC_MSG_ERROR([B2G loader works with Nuwa]); + fi + export MOZ_B2G_LOADER + AC_DEFINE(MOZ_B2G_LOADER) +fi +AC_SUBST(MOZ_B2G_LOADER) AC_SUBST(NSPR_CFLAGS) AC_SUBST(NSPR_LIBS) diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp index 408a686125f..04c160c5ff5 100644 --- a/content/media/AudioStream.cpp +++ b/content/media/AudioStream.cpp @@ -588,11 +588,6 @@ void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive) if (cubeb_stream_set_panning(mCubebStream, 0.0) != CUBEB_OK) { NS_WARNING("Could not pan audio output to the center."); } - // This a microphone that goes through the headphone plug, reset the - // output to prevent echo building up. - if (strcmp(device->input_name, "emic") == 0) { - Reset(); - } } cubeb_stream_device_destroy(mCubebStream, device); } @@ -600,10 +595,30 @@ void AudioStream::PanOutputIfNeeded(bool aMicrophoneActive) #endif } -void AudioStream::DeviceChangedCallback() { +void AudioStream::ResetStreamIfNeeded() +{ + cubeb_device * device; + // Only reset a device if a mic is active, and this is a low latency stream. + if (!mMicrophoneActive || mLatencyRequest != LowLatency) { + return; + } + if (cubeb_stream_get_current_device(mCubebStream, &device) == CUBEB_OK) { + // This a microphone that goes through the headphone plug, reset the + // output to prevent echo building up. + if (strcmp(device->input_name, "emic") == 0) { + LOG(("Resetting audio output")); + Reset(); + } + cubeb_stream_device_destroy(mCubebStream, device); + } +} + +void AudioStream::DeviceChangedCallback() +{ MonitorAutoLock mon(mMonitor); PanOutputIfNeeded(mMicrophoneActive); mShouldDropFrames = true; + ResetStreamIfNeeded(); } // This code used to live inside AudioStream::Init(), but on Mac (others?) @@ -1127,6 +1142,9 @@ AudioStream::GetTimeStretched(void* aBuffer, long aFrames, int64_t &aTimeMs) void AudioStream::Reset() { + + MOZ_ASSERT(mLatencyRequest == LowLatency, "We should only be reseting low latency streams"); + mShouldDropFrames = true; mNeedsStart = true; @@ -1160,21 +1178,13 @@ AudioStream::Reset() mBuffer.Reset(); mBuffer.SetCapacity(bufferLimit); - - if (mLatencyRequest == LowLatency) { - // Don't block this thread to initialize a cubeb stream. - // When this is done, it will start callbacks from Cubeb. Those will - // cause us to move from INITIALIZED to RUNNING. Until then, we - // can't access any cubeb functions. - // Use a RefPtr to avoid leaks if Dispatch fails - RefPtr init = new AudioInitTask(this, mLatencyRequest, params); - init->Dispatch(); - return; - } - // High latency - open synchronously - OpenCubeb(params, mLatencyRequest); - - CheckForStart(); + // Don't block this thread to initialize a cubeb stream. + // When this is done, it will start callbacks from Cubeb. Those will + // cause us to move from INITIALIZED to RUNNING. Until then, we + // can't access any cubeb functions. + // Use a RefPtr to avoid leaks if Dispatch fails + RefPtr init = new AudioInitTask(this, mLatencyRequest, params); + init->Dispatch(); } long diff --git a/content/media/AudioStream.h b/content/media/AudioStream.h index 2789c5fdba0..c2914b2f742 100644 --- a/content/media/AudioStream.h +++ b/content/media/AudioStream.h @@ -240,6 +240,7 @@ public: // application. void SetMicrophoneActive(bool aActive); void PanOutputIfNeeded(bool aMicrophoneActive); + void ResetStreamIfNeeded(); // Block until buffered audio data has been consumed. void Drain(); diff --git a/content/media/directshow/Makefile.in b/content/media/directshow/Makefile.in deleted file mode 100644 index 64225645225..00000000000 --- a/content/media/directshow/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -# 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/. - -ifeq ($(OS_ARCH),WINNT) -OS_CXXFLAGS += -DNOMINMAX -endif diff --git a/content/media/directshow/moz.build b/content/media/directshow/moz.build index 5c2e0008e6a..a939640417e 100644 --- a/content/media/directshow/moz.build +++ b/content/media/directshow/moz.build @@ -42,3 +42,5 @@ LOCAL_INCLUDES += [ '/media/webrtc/trunk/webrtc/modules/video_capture/windows', ] +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/content/media/fmp4/Makefile.in b/content/media/fmp4/Makefile.in deleted file mode 100644 index 64225645225..00000000000 --- a/content/media/fmp4/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -# 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/. - -ifeq ($(OS_ARCH),WINNT) -OS_CXXFLAGS += -DNOMINMAX -endif diff --git a/content/media/fmp4/apple/AppleATDecoder.cpp b/content/media/fmp4/apple/AppleATDecoder.cpp index 5a08d0b426c..4642b189cf2 100644 --- a/content/media/fmp4/apple/AppleATDecoder.cpp +++ b/content/media/fmp4/apple/AppleATDecoder.cpp @@ -131,6 +131,7 @@ AppleATDecoder::Drain() { LOG("Draining AudioToolbox AAC decoder"); mTaskQueue->AwaitIdle(); + mCallback->DrainComplete(); return Flush(); } diff --git a/content/media/fmp4/apple/AppleVTDecoder.cpp b/content/media/fmp4/apple/AppleVTDecoder.cpp index 014de520995..9a21abf1746 100644 --- a/content/media/fmp4/apple/AppleVTDecoder.cpp +++ b/content/media/fmp4/apple/AppleVTDecoder.cpp @@ -111,19 +111,26 @@ AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample) nsresult AppleVTDecoder::Flush() { + nsresult rv = WaitForAsynchronousFrames(); + if (NS_FAILED(rv)) { + LOG("AppleVTDecoder::Drain failed waiting for platform decoder."); + } mReorderQueue.Clear(); - return Drain(); + return rv; } nsresult AppleVTDecoder::Drain() { - OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession); - if (rv != noErr) { - LOG("Error %d draining frames", rv); - return NS_ERROR_FAILURE; + mTaskQueue->AwaitIdle(); + nsresult rv = WaitForAsynchronousFrames(); + if (NS_FAILED(rv)) { + LOG("AppleVTDecoder::Drain failed waiting for platform decoder."); + return rv; } - return DrainReorderedFrames(); + DrainReorderedFrames(); + mCallback->DrainComplete(); + return NS_OK; } // @@ -192,12 +199,22 @@ PlatformCallback(void* decompressionOutputRefCon, } nsresult +AppleVTDecoder::WaitForAsynchronousFrames() +{ + OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession); + if (rv != noErr) { + LOG("AppleVTDecoder: Error %d waiting for asynchronous frames", rv); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +void AppleVTDecoder::DrainReorderedFrames() { while (!mReorderQueue.IsEmpty()) { mCallback->Output(mReorderQueue.Pop()); } - return NS_OK; } // Copy and return a decoded frame. diff --git a/content/media/fmp4/apple/AppleVTDecoder.h b/content/media/fmp4/apple/AppleVTDecoder.h index 46173923328..1492c9eb8fa 100644 --- a/content/media/fmp4/apple/AppleVTDecoder.h +++ b/content/media/fmp4/apple/AppleVTDecoder.h @@ -52,7 +52,8 @@ private: nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample); // Method to set up the decompression session. nsresult InitializeSession(); - nsresult DrainReorderedFrames(); + nsresult WaitForAsynchronousFrames(); + void DrainReorderedFrames(); }; } // namespace mozilla diff --git a/content/media/fmp4/moz.build b/content/media/fmp4/moz.build index bc6ef9a3120..a01735fe79c 100644 --- a/content/media/fmp4/moz.build +++ b/content/media/fmp4/moz.build @@ -61,3 +61,6 @@ if CONFIG['MOZ_APPLEMEDIA']: FINAL_LIBRARY = 'xul' FAIL_ON_WARNINGS = True + +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/content/media/wmf/Makefile.in b/content/media/wmf/Makefile.in deleted file mode 100644 index 64225645225..00000000000 --- a/content/media/wmf/Makefile.in +++ /dev/null @@ -1,7 +0,0 @@ -# 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/. - -ifeq ($(OS_ARCH),WINNT) -OS_CXXFLAGS += -DNOMINMAX -endif diff --git a/content/media/wmf/moz.build b/content/media/wmf/moz.build index 20c033f515a..6b1d653ee9a 100644 --- a/content/media/wmf/moz.build +++ b/content/media/wmf/moz.build @@ -27,3 +27,6 @@ SOURCES += [ FAIL_ON_WARNINGS = True FINAL_LIBRARY = 'xul' + +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 224e60a7a3f..7dbd195be9d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -44,6 +44,7 @@ #include "nsRect.h" #include "prenv.h" #include "nsIDOMWindow.h" +#include "nsIGlobalObject.h" #include "nsIWebBrowserChrome.h" #include "nsPoint.h" #include "nsIObserverService.h" @@ -1008,6 +1009,7 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) *aSink = mContentListener; } else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) || + aIID.Equals(NS_GET_IID(nsIGlobalObject)) || aIID.Equals(NS_GET_IID(nsPIDOMWindow)) || aIID.Equals(NS_GET_IID(nsIDOMWindow)) || aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) && diff --git a/dom/apps/src/OfflineCacheInstaller.jsm b/dom/apps/src/OfflineCacheInstaller.jsm index 16b5dd1e419..358b3834914 100644 --- a/dom/apps/src/OfflineCacheInstaller.jsm +++ b/dom/apps/src/OfflineCacheInstaller.jsm @@ -23,7 +23,9 @@ let makeFile = CC('@mozilla.org/file/local;1', 'initWithPath'); let MutableArray = CC('@mozilla.org/array;1', 'nsIMutableArray'); -const nsICache = Ci.nsICache; +let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", {}); + +const nsICacheStorage = Ci.nsICacheStorage; const nsIApplicationCache = Ci.nsIApplicationCache; const applicationCacheService = Cc['@mozilla.org/network/application-cache-service;1'] @@ -47,32 +49,34 @@ function enableOfflineCacheForApp(origin, appId) { function storeCache(applicationCache, url, file, itemType) { - let session = Services.cache.createSession(applicationCache.clientID, - nsICache.STORE_OFFLINE, true); - session.asyncOpenCacheEntry(url, nsICache.ACCESS_WRITE, { - onCacheEntryAvailable: function (cacheEntry, accessGranted, status) { - cacheEntry.setMetaDataElement('request-method', 'GET'); - cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n'); + let storage = + Services.cache2.appCacheStorage(LoadContextInfo.default, applicationCache); + let uri = Services.io.newURI(url, null, null); + storage.asyncOpenURI(uri, "", nsICacheStorage.OPEN_TRUNCATE, { + onCacheEntryAvailable: + function (cacheEntry, isNew, appCache, result) { + cacheEntry.setMetaDataElement('request-method', 'GET'); + cacheEntry.setMetaDataElement('response-head', 'HTTP/1.1 200 OK\r\n'); - let outputStream = cacheEntry.openOutputStream(0); + let outputStream = cacheEntry.openOutputStream(0); - // Input-Output stream machinery in order to push nsIFile content into cache - let inputStream = Cc['@mozilla.org/network/file-input-stream;1'] - .createInstance(Ci.nsIFileInputStream); - inputStream.init(file, 1, -1, null); - let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1'] - .createInstance(Ci.nsIBufferedOutputStream); - bufferedOutputStream.init(outputStream, 1024); - bufferedOutputStream.writeFrom(inputStream, inputStream.available()); - bufferedOutputStream.flush(); - bufferedOutputStream.close(); - inputStream.close(); + // Input-Output stream machinery in order to push nsIFile content into cache + let inputStream = Cc['@mozilla.org/network/file-input-stream;1'] + .createInstance(Ci.nsIFileInputStream); + inputStream.init(file, 1, -1, null); + let bufferedOutputStream = Cc['@mozilla.org/network/buffered-output-stream;1'] + .createInstance(Ci.nsIBufferedOutputStream); + bufferedOutputStream.init(outputStream, 1024); + bufferedOutputStream.writeFrom(inputStream, inputStream.available()); + bufferedOutputStream.flush(); + bufferedOutputStream.close(); + inputStream.close(); - cacheEntry.markValid(); - debug (file.path + ' -> ' + url + ' (' + itemType + ')'); - applicationCache.markEntry(url, itemType); - cacheEntry.close(); - } + cacheEntry.markValid(); + debug (file.path + ' -> ' + url + ' (' + itemType + ')'); + applicationCache.markEntry(url, itemType); + cacheEntry.close(); + } }); } diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index dcdb290e5c9..9e68f7e48bb 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -3672,9 +3672,9 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement, MaybeTransform transform; forwarder->GetShadowManager()->SendGetAnimationTransform( layer->AsShadowableLayer()->GetShadow(), &transform); - if (transform.type() == MaybeTransform::Tgfx3DMatrix) { - cssValue = - nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix()); + if (transform.type() == MaybeTransform::TMatrix4x4) { + gfx3DMatrix matrix = To3DMatrix(transform.get_Matrix4x4()); + cssValue = nsComputedDOMStyle::MatrixToCSSValue(matrix); } } } diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 7e24f2bf850..e97b8b8a7cd 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -52,6 +52,32 @@ def isTypeCopyConstructible(type): (type.isInterface() and type.isGeckoInterface())) +def idlTypeNeedsCycleCollection(type): + type = type.unroll() # Takes care of sequences and nullables + if ((type.isPrimitive() and type.tag() in builtinNames) or + type.isEnum() or + type.isDOMString() or + type.isByteString() or + type.isAny() or + type.isObject() or + type.isSpiderMonkeyInterface()): + return False + elif type.isCallback() or type.isGeckoInterface(): + return True + elif type.isUnion(): + return any(idlTypeNeedsCycleCollection(t) for t in type.flatMemberTypes) + elif type.isMozMap(): + if idlTypeNeedsCycleCollection(type.inner): + raise TypeError("Cycle collection for type %s is not supported" % type) + return False + elif type.isDictionary(): + if any(idlTypeNeedsCycleCollection(m.type) for m in type.inner.members): + raise TypeError("Cycle collection for type %s is not supported" % type) + return False + else: + raise TypeError("Don't know whether to cycle-collect type %s" % type) + + def wantsAddProperty(desc): return (desc.concrete and desc.wrapperCache and @@ -1160,6 +1186,8 @@ def UnionTypes(descriptors, dictionaries, callbacks, config): declarations = set() unionStructs = dict() owningUnionStructs = dict() + traverseMethods = dict() + unlinkMethods = dict() for t, descriptor, dictionary in getAllTypes(descriptors, dictionaries, callbacks): # Add info for the given type. descriptor and dictionary, if present, are @@ -1227,8 +1255,20 @@ def UnionTypes(descriptors, dictionaries, callbacks, config): assert not f.nullable() addHeadersForType(f) + if idlTypeNeedsCycleCollection(t): + declarations.add(("mozilla::dom::%s" % CGUnionStruct.unionTypeName(t, True), False)) + traverseMethods[name] = CGCycleCollectionTraverseForOwningUnionMethod(t) + unlinkMethods[name] = CGCycleCollectionUnlinkForOwningUnionMethod(t) + + # The order of items in CGList is important. + # Since the union structs friend the unlinkMethods, the forward-declaration + # for these methods should come before the class declaration. Otherwise + # some compilers treat the friend declaration as a forward-declaration in + # the class scope. return (headers, implheaders, declarations, - CGList(SortedDictValues(unionStructs) + + CGList(SortedDictValues(traverseMethods) + + SortedDictValues(unlinkMethods) + + SortedDictValues(unionStructs) + SortedDictValues(owningUnionStructs), "\n")) @@ -3263,6 +3303,47 @@ class CGIsPermittedMethod(CGAbstractMethod): switch = CGSwitch("propFirstChar", caseList) return switch.define() + "\nreturn false;\n" + +class CGCycleCollectionTraverseForOwningUnionMethod(CGAbstractMethod): + """ + ImplCycleCollectionUnlink for owning union type. + """ + def __init__(self, type): + self.type = type + args = [Argument("nsCycleCollectionTraversalCallback&", "aCallback"), + Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion"), + Argument("const char*", "aName"), + Argument("uint32_t", "aFlags", "0")] + CGAbstractMethod.__init__(self, None, "ImplCycleCollectionTraverse", "void", args) + + def definition_body(self): + memberNames = [getUnionMemberName(t) + for t in self.type.flatMemberTypes + if idlTypeNeedsCycleCollection(t)] + assert memberNames + + conditionTemplate = 'aUnion.Is%s()' + functionCallTemplate = 'ImplCycleCollectionTraverse(aCallback, aUnion.GetAs%s(), "m%s", aFlags);\n' + + ifStaments = (CGIfWrapper(CGGeneric(functionCallTemplate % (m, m)), + conditionTemplate % m) + for m in memberNames) + + return CGElseChain(ifStaments).define() + + +class CGCycleCollectionUnlinkForOwningUnionMethod(CGAbstractMethod): + """ + ImplCycleCollectionUnlink for owning union type. + """ + def __init__(self, type): + args = [Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion")] + CGAbstractMethod.__init__(self, None, "ImplCycleCollectionUnlink", "void", args) + + def definition_body(self): + return "aUnion.Uninit();\n" + + builtinNames = { IDLType.Tags.bool: 'bool', IDLType.Tags.int8: 'int8_t', @@ -8464,7 +8545,11 @@ class CGUnionStruct(CGThing): else: disallowCopyConstruction = True - friend = " friend class %sArgument;\n" % str(self.type) if not self.ownsMembers else "" + if self.ownsMembers: + friend = " friend void ImplCycleCollectionUnlink(%s& aUnion);\n" % CGUnionStruct.unionTypeName(self.type, True) + else: + friend = " friend class %sArgument;\n" % str(self.type) + bases = [ClassBase("AllOwningUnionBase")] if self.ownsMembers else [] return CGClass(selfName, bases=bases, @@ -10695,7 +10780,7 @@ def initIdsClassMethod(identifiers, atomCacheName): Argument("JSContext*", "cx"), Argument("%s*" % atomCacheName, "atomsCache") ], static=True, body=body, visibility="private") - + class CGDictionary(CGThing): def __init__(self, dictionary, descriptorProvider): self.dictionary = dictionary @@ -10884,7 +10969,7 @@ class CGDictionary(CGThing): def initIdsMethod(self): assert self.needToInitIds return initIdsClassMethod([m.identifier.name for m in self.dictionary.members], - "%sAtoms" % self.makeClassName(self.dictionary)) + "%sAtoms" % self.makeClassName(self.dictionary)) def traceDictionaryMethod(self): body = "" @@ -14033,7 +14118,7 @@ class CGEventClass(CGBindingImplClass): retVal = "" for m in self.descriptor.interface.members: # Unroll the type so we pick up sequences of interfaces too. - if m.isAttr() and m.type.unroll().isGeckoInterface(): + if m.isAttr() and idlTypeNeedsCycleCollection(m.type): retVal += (" NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" + CGDictionary.makeMemberName(m.identifier.name) + ")\n") @@ -14045,7 +14130,7 @@ class CGEventClass(CGBindingImplClass): if m.isAttr(): name = CGDictionary.makeMemberName(m.identifier.name) # Unroll the type so we pick up sequences of interfaces too. - if m.type.unroll().isGeckoInterface(): + if idlTypeNeedsCycleCollection(m.type): retVal += " NS_IMPL_CYCLE_COLLECTION_UNLINK(" + name + ")\n" elif m.type.isAny(): retVal += " tmp->" + name + ".setUndefined();\n" diff --git a/dom/bindings/OwningNonNull.h b/dom/bindings/OwningNonNull.h index ff32bc04934..8ab7fae8fa4 100644 --- a/dom/bindings/OwningNonNull.h +++ b/dom/bindings/OwningNonNull.h @@ -10,6 +10,7 @@ #define mozilla_dom_OwningNonNull_h #include "nsAutoPtr.h" +#include "nsCycleCollectionNoteChild.h" namespace mozilla { namespace dom { @@ -87,6 +88,16 @@ protected: #endif }; +template +inline void +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, + OwningNonNull& aField, + const char* aName, + uint32_t aFlags = 0) +{ + CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags); +} + } // namespace dom } // namespace mozilla diff --git a/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage.html b/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage.html index 7642dcfcb10..91697269579 100644 --- a/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage.html +++ b/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage.html @@ -43,8 +43,8 @@ function runTest() { } addEventListener('testready', function() { - // Cause the grace period of priority privilege for this new process to time - // out after 1s. + // Cause the CPU wake lock taken on behalf of this new process to time out + // after 1s. SpecialPowers.pushPrefEnv( {set: [["dom.ipc.systemMessageCPULockTimeoutSec", 1]]}, runTest); diff --git a/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html b/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html index 1885cdb12f1..92d99bf751e 100644 --- a/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html +++ b/dom/browser-element/mochitest/priority/test_ExpectingSystemMessage2.html @@ -57,9 +57,9 @@ function runTest() { } addEventListener('testready', function() { - // We don't want the grace period of priority privilege to time out during the - // test; should it really happen, we would see BACKGROUND priority instead of - // BACKGROUND_PERCEIVABLE. So set the timeout to a large value. + // We don't want this wake lock to time out during the test; if it did, then + // we might see BACKGROUND priority instead of BACKGROUND_PERCEIVABLE. So + // set the timeout to a large value. SpecialPowers.pushPrefEnv( {set: [["dom.ipc.systemMessageCPULockTimeoutSec", 99999]]}, runTest); diff --git a/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade.html b/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade.html index 198b579f442..0894ece6d7b 100644 --- a/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade.html +++ b/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade.html @@ -69,8 +69,8 @@ function runTest() { addEventListener('testready', function() { SpecialPowers.pushPrefEnv( {set: [ - /* Cause the grace period of priority privilege for the high-priority - * process to time out after 1s. */ + /* Cause the CPU wake lock taken on behalf of the high-priority process + * to time out after 1s. */ ["dom.ipc.systemMessageCPULockTimeoutSec", 1], ["dom.wakelock.enabled", true] ]}, diff --git a/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade2.html b/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade2.html index 123536298cd..67fe60174cd 100644 --- a/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade2.html +++ b/dom/browser-element/mochitest/priority/test_HighPriorityDowngrade2.html @@ -65,8 +65,8 @@ function runTest() { } addEventListener('testready', function() { - // Cause the grace period of priority privilege for the high-priority process - // never to time out during this test. + // Cause the CPU wake lock taken on behalf of the high-priority process never + // to time out during this test. SpecialPowers.pushPrefEnv( {set: [["dom.ipc.systemMessageCPULockTimeoutSec", 1000]]}, runTest); diff --git a/dom/camera/GonkCameraHwMgr.cpp b/dom/camera/GonkCameraHwMgr.cpp index 6d5d3564527..e215ee750c3 100644 --- a/dom/camera/GonkCameraHwMgr.cpp +++ b/dom/camera/GonkCameraHwMgr.cpp @@ -234,6 +234,7 @@ GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCam nsresult rv = cameraHardware->Init(); if (NS_FAILED(rv)) { DOM_CAMERA_LOGE("Failed to initialize camera hardware (0x%X)\n", rv); + cameraHardware->Close(); return nullptr; } diff --git a/dom/camera/test/test_camera_hardware_init_failure.html b/dom/camera/test/test_camera_hardware_init_failure.html index d5e3ec80049..a81aa1cda7b 100644 --- a/dom/camera/test/test_camera_hardware_init_failure.html +++ b/dom/camera/test/test_camera_hardware_init_failure.html @@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=940424 diff --git a/dom/events/crashtests/1035654-1.html b/dom/events/crashtests/1035654-1.html new file mode 100644 index 00000000000..6e3e3c0270e --- /dev/null +++ b/dom/events/crashtests/1035654-1.html @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/dom/events/crashtests/1035654-2.html b/dom/events/crashtests/1035654-2.html new file mode 100644 index 00000000000..19f5a1cc896 --- /dev/null +++ b/dom/events/crashtests/1035654-2.html @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/dom/events/crashtests/crashtests.list b/dom/events/crashtests/crashtests.list index d0389e2d06f..bb46657b1e4 100644 --- a/dom/events/crashtests/crashtests.list +++ b/dom/events/crashtests/crashtests.list @@ -6,6 +6,8 @@ load 457776-1.html load 496308-1.html load 682637-1.html load 1033343.html +load 1035654-1.html +load 1035654-2.html load eventctor-nulldictionary.html load eventctor-nullstorage.html load recursive-onload.html diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 7a051089934..5f2bfcd9fea 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -41,6 +41,7 @@ #include "mozilla/dom/PFileDescriptorSetParent.h" #include "mozilla/dom/PCycleCollectWithLogsParent.h" #include "mozilla/dom/PMemoryReportRequestParent.h" +#include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/bluetooth/PBluetoothParent.h" #include "mozilla/dom/PFMRadioParent.h" @@ -83,6 +84,7 @@ #include "nsIClipboard.h" #include "nsICycleCollectorListener.h" #include "nsIDOMGeoGeolocation.h" +#include "mozilla/dom/WakeLock.h" #include "nsIDOMWindow.h" #include "nsIExternalProtocolService.h" #include "nsIGfxInfo.h" @@ -183,6 +185,7 @@ using base::KillProcess; using namespace mozilla::dom::bluetooth; using namespace mozilla::dom::devicestorage; using namespace mozilla::dom::indexedDB; +using namespace mozilla::dom::power; using namespace mozilla::dom::mobilemessage; using namespace mozilla::dom::telephony; using namespace mozilla::hal; @@ -836,95 +839,6 @@ ContentParent::AnswerBridgeToChildProcess(const uint64_t& id) } } -namespace { - -class SystemMessageHandledListener MOZ_FINAL - : public nsITimerCallback - , public LinkedListElement -{ -public: - NS_DECL_ISUPPORTS - - SystemMessageHandledListener() {} - - static void OnSystemMessageHandled() - { - if (!sListeners) { - return; - } - - SystemMessageHandledListener* listener = sListeners->popFirst(); - if (!listener) { - return; - } - - // Careful: ShutDown() may delete |this|. - listener->ShutDown(); - } - - void Init(ContentParent* aContentParent) - { - MOZ_ASSERT(!mContentParent); - MOZ_ASSERT(!mTimer); - - // mTimer keeps a strong reference to |this|. When this object's - // destructor runs, it will remove itself from the LinkedList. - - if (!sListeners) { - sListeners = new LinkedList(); - ClearOnShutdown(&sListeners); - } - sListeners->insertBack(this); - - mContentParent = aContentParent; - - mTimer = do_CreateInstance("@mozilla.org/timer;1"); - - uint32_t timeoutSec = - Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30); - mTimer->InitWithCallback(this, timeoutSec * 1000, - nsITimer::TYPE_ONE_SHOT); - } - - NS_IMETHOD Notify(nsITimer* aTimer) - { - // Careful: ShutDown() may delete |this|. - ShutDown(); - return NS_OK; - } - -private: - ~SystemMessageHandledListener() {} - - static StaticAutoPtr > sListeners; - - void ShutDown() - { - ProcessPriorityManager::ResetProcessPriority(mContentParent, false); - - nsRefPtr kungFuDeathGrip = this; - - if (mContentParent) { - mContentParent = nullptr; - } - if (mTimer) { - mTimer->Cancel(); - mTimer = nullptr; - } - } - - nsRefPtr mContentParent; - nsCOMPtr mTimer; -}; - -StaticAutoPtr > - SystemMessageHandledListener::sListeners; - -NS_IMPL_ISUPPORTS(SystemMessageHandledListener, - nsITimerCallback) - -} // anonymous namespace - /*static*/ TabParent* ContentParent::CreateBrowserOrApp(const TabContext& aContext, Element* aFrameElement, @@ -1129,20 +1043,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext, return nullptr; } - // Request a higher priority above BACKGROUND if the child process is - // "critical" and probably has system messages coming soon. (A CPU wake lock - // may already be controlled by the B2G process in SystemMessageInternal.js - // for message handling.) This privilege is revoked once the message is - // delivered, or the grace period is up, whichever comes first. - nsCOMPtr browserFrame = do_QueryInterface(aFrameElement); - if (browserFrame && browserFrame->GetIsExpectingSystemMessage()) { - ProcessPriorityManager::ResetProcessPriority(p, true); - - // This object's Init() function keeps it alive. - nsRefPtr listener = - new SystemMessageHandledListener(); - listener->Init(p); - } + p->MaybeTakeCPUWakeLock(aFrameElement); return static_cast(browser); } @@ -1206,6 +1107,117 @@ ContentParent::Init() NS_ASSERTION(observer, "FileUpdateDispatcher is null"); } +namespace { + +class SystemMessageHandledListener MOZ_FINAL + : public nsITimerCallback + , public LinkedListElement +{ +public: + NS_DECL_ISUPPORTS + + SystemMessageHandledListener() {} + + static void OnSystemMessageHandled() + { + if (!sListeners) { + return; + } + + SystemMessageHandledListener* listener = sListeners->popFirst(); + if (!listener) { + return; + } + + // Careful: ShutDown() may delete |this|. + listener->ShutDown(); + } + + void Init(WakeLock* aWakeLock) + { + MOZ_ASSERT(!mWakeLock); + MOZ_ASSERT(!mTimer); + + // mTimer keeps a strong reference to |this|. When this object's + // destructor runs, it will remove itself from the LinkedList. + + if (!sListeners) { + sListeners = new LinkedList(); + ClearOnShutdown(&sListeners); + } + sListeners->insertBack(this); + + mWakeLock = aWakeLock; + + mTimer = do_CreateInstance("@mozilla.org/timer;1"); + + uint32_t timeoutSec = + Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30); + mTimer->InitWithCallback(this, timeoutSec * 1000, + nsITimer::TYPE_ONE_SHOT); + } + + NS_IMETHOD Notify(nsITimer* aTimer) + { + // Careful: ShutDown() may delete |this|. + ShutDown(); + return NS_OK; + } + +private: + ~SystemMessageHandledListener() {} + + static StaticAutoPtr > sListeners; + + void ShutDown() + { + nsRefPtr kungFuDeathGrip = this; + + ErrorResult rv; + mWakeLock->Unlock(rv); + + if (mTimer) { + mTimer->Cancel(); + mTimer = nullptr; + } + } + + nsRefPtr mWakeLock; + nsCOMPtr mTimer; +}; + +StaticAutoPtr > + SystemMessageHandledListener::sListeners; + +NS_IMPL_ISUPPORTS(SystemMessageHandledListener, + nsITimerCallback) + +} // anonymous namespace + +void +ContentParent::MaybeTakeCPUWakeLock(Element* aFrameElement) +{ + // Take the CPU wake lock on behalf of this processs if it's expecting a + // system message. We'll release the CPU lock once the message is + // delivered, or after some period of time, which ever comes first. + + nsCOMPtr browserFrame = + do_QueryInterface(aFrameElement); + if (!browserFrame || + !browserFrame->GetIsExpectingSystemMessage()) { + return; + } + + nsRefPtr pms = PowerManagerService::GetInstance(); + nsRefPtr lock = + pms->NewWakeLockOnBehalfOfProcess(NS_LITERAL_STRING("cpu"), this); + + // This object's Init() function keeps it alive. + nsRefPtr listener = + new SystemMessageHandledListener(); + listener->Init(lock); +} + bool ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index e9498296fdc..5edb6287cc0 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -332,6 +332,12 @@ private: void Init(); + // If the frame element indicates that the child process is "critical" and + // has a pending system message, this function acquires the CPU wake lock on + // behalf of the child. We'll release the lock when the system message is + // handled or after a timeout, whichever comes first. + void MaybeTakeCPUWakeLock(Element* aFrameElement); + // Set the child process's priority and then check whether the child is // still alive. Returns true if the process is still alive, and false // otherwise. If you pass a FOREGROUND* priority here, it's (hopefully) diff --git a/dom/ipc/ProcessPriorityManager.cpp b/dom/ipc/ProcessPriorityManager.cpp index 3d17bde1f92..92d403f7959 100644 --- a/dom/ipc/ProcessPriorityManager.cpp +++ b/dom/ipc/ProcessPriorityManager.cpp @@ -131,12 +131,6 @@ public: ProcessPriority aPriority, uint32_t aBackgroundLRU = 0); - /** - * This function implements ProcessPriorityManager::ResetProcessPriority. - */ - void ResetProcessPriority(ContentParent* aContentParent, - bool aHandleSystemMessage); - /** * If a magic testing-only pref is set, notify the observer service on the * given topic with the given data. This is used for testing @@ -293,8 +287,6 @@ public: void ShutDown(); - void SetHandlesSystemMessage(bool aHandlesSystemMessage); - private: void FireTestOnlyObserverNotification( const char* aTopic, @@ -310,7 +302,6 @@ private: ProcessCPUPriority mCPUPriority; bool mHoldsCPUWakeLock; bool mHoldsHighPriorityWakeLock; - bool mHandlesSystemMessage; /** * Used to implement NameWithComma(). @@ -505,17 +496,6 @@ ProcessPriorityManagerImpl::SetProcessPriority(ContentParent* aContentParent, pppm->SetPriorityNow(aPriority, aBackgroundLRU); } -void -ProcessPriorityManagerImpl::ResetProcessPriority(ContentParent* aContentParent, - bool aHandleSystemMessage) -{ - MOZ_ASSERT(aContentParent); - nsRefPtr pppm = - GetParticularProcessPriorityManager(aContentParent); - pppm->SetHandlesSystemMessage(aHandleSystemMessage); - pppm->ResetPriorityNow(); -} - void ProcessPriorityManagerImpl::ObserveContentParentCreated( nsISupports* aContentParent) @@ -667,7 +647,6 @@ ParticularProcessPriorityManager::ParticularProcessPriorityManager( , mCPUPriority(PROCESS_CPU_PRIORITY_NORMAL) , mHoldsCPUWakeLock(false) , mHoldsHighPriorityWakeLock(false) - , mHandlesSystemMessage(false) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); LOGP("Creating ParticularProcessPriorityManager."); @@ -990,7 +969,7 @@ ParticularProcessPriorityManager::CurrentPriority() ProcessPriority ParticularProcessPriorityManager::ComputePriority() { - if ((mHandlesSystemMessage || mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) && + if ((mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) && HasAppType("critical")) { return PROCESS_PRIORITY_FOREGROUND_HIGH; } @@ -1011,7 +990,7 @@ ParticularProcessPriorityManager::ComputePriority() PROCESS_PRIORITY_FOREGROUND; } - if ((mHandlesSystemMessage || mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) && + if ((mHoldsCPUWakeLock || mHoldsHighPriorityWakeLock) && IsExpectingSystemMessage()) { return PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE; } @@ -1158,12 +1137,6 @@ ParticularProcessPriorityManager::ShutDown() mContentParent = nullptr; } -void -ParticularProcessPriorityManager::SetHandlesSystemMessage(bool aHandlesSystemMessage) -{ - mHandlesSystemMessage = aHandlesSystemMessage; -} - void ProcessPriorityManagerImpl::FireTestOnlyObserverNotification( const char* aTopic, @@ -1500,19 +1473,6 @@ ProcessPriorityManager::SetProcessPriority(ContentParent* aContentParent, } } -/* static */ void -ProcessPriorityManager::ResetProcessPriority(ContentParent* aContentParent, - bool aHandleSystemMessage) -{ - MOZ_ASSERT(aContentParent); - - ProcessPriorityManagerImpl* singleton = - ProcessPriorityManagerImpl::GetSingleton(); - if (singleton) { - singleton->ResetProcessPriority(aContentParent, aHandleSystemMessage); - } -} - /* static */ void ProcessPriorityManager::RemoveFromBackgroundLRUPool( ContentParent* aContentParent) diff --git a/dom/ipc/ProcessPriorityManager.h b/dom/ipc/ProcessPriorityManager.h index 63d9cf54365..58d222c7807 100644 --- a/dom/ipc/ProcessPriorityManager.h +++ b/dom/ipc/ProcessPriorityManager.h @@ -59,20 +59,6 @@ public: static void SetProcessPriority(dom::ContentParent* aContentParent, hal::ProcessPriority aPriority); - /** - * Reset the process priority of a given ContentParent's process in - * consideration of system message handling. - * - * Note that because this method takes a ContentParent*, you can only set the - * priority of your subprocesses. In fact, because we don't support nested - * content processes (bug 761935), you can only call this method from the - * main process. - * - * The process priority manager will determine a new appropriate priority. - */ - static void ResetProcessPriority(dom::ContentParent* aContentParent, - bool aHandleSystemMessage); - /** * Returns true iff this process's priority is FOREGROUND*. * diff --git a/dom/messages/SystemMessageInternal.js b/dom/messages/SystemMessageInternal.js index 08bbe973399..72708689626 100644 --- a/dom/messages/SystemMessageInternal.js +++ b/dom/messages/SystemMessageInternal.js @@ -39,16 +39,6 @@ try { kMaxPendingMessages = 5; } -//Limit the duration to hold the CPU wake lock. -let kCpuWakeLockTimeoutSec; -try { - kCpuWakeLockTimeoutSec = - Services.prefs.getIntPref("dom.ipc.systemMessageCPULockTimeoutSec"); -} catch (e) { - // getIntPref throws when the pref is not set. - kCpuWakeLockTimeoutSec = 30; -} - const kMessages =["SystemMessageManager:GetPendingMessages", "SystemMessageManager:HasPendingMessages", "SystemMessageManager:Register", @@ -159,7 +149,7 @@ SystemMessageInternal.prototype = { debug("Releasing the CPU wake lock because the system messages " + "were not handled by its registered page before time out."); this._cancelCpuWakeLock(aPageKey); - }.bind(this), kCpuWakeLockTimeoutSec * 1000, Ci.nsITimer.TYPE_ONE_SHOT); + }.bind(this), 30000, Ci.nsITimer.TYPE_ONE_SHOT); }, _releaseCpuWakeLock: function _releaseCpuWakeLock(aPageKey, aHandledCount) { diff --git a/dom/messages/SystemMessageManager.js b/dom/messages/SystemMessageManager.js index fe99ae3e646..202f5bfd6b7 100644 --- a/dom/messages/SystemMessageManager.js +++ b/dom/messages/SystemMessageManager.js @@ -108,8 +108,10 @@ SystemMessageManager.prototype = { this._dispatchMessage(aType, aDispatcher, aDispatcher.messages.shift()); } else { // No more messages that need to be handled, we can notify the - // ContentChild to propogate the event, so that the ContentParent can - // reset the process's priority. + // ContentChild to release the CPU wake lock grabbed by the ContentParent + // (i.e. NewWakeLockOnBehalfOfProcess()) and reset the process's priority. + // + // TODO: Bug 874353 - Remove SystemMessageHandledListener in ContentParent Services.obs.notifyObservers(/* aSubject */ null, "handle-system-messages-done", /* aData */ null); @@ -247,8 +249,11 @@ SystemMessageManager.prototype = { pageURL: this._pageURL, handledCount: messages.length }); - // We also need to notify the ContentChild to propogate the event, so that - // the ContentParent can reset the process's priority. + // We also need to notify the ContentChild to release the CPU wake lock + // grabbed by the ContentParent (i.e. NewWakeLockOnBehalfOfProcess()) and + // reset the process's priority. + // + // TODO: Bug 874353 - Remove SystemMessageHandledListener in ContentParent Services.obs.notifyObservers(/* aSubject */ null, "handle-system-messages-done", /* aData */ null); diff --git a/dom/promise/Promise.h b/dom/promise/Promise.h index 39144aa7815..b618bf5c21b 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -14,6 +14,7 @@ #include "nsCycleCollectionParticipant.h" #include "mozilla/dom/PromiseBinding.h" #include "mozilla/dom/ToJSValue.h" +#include "mozilla/WeakPtr.h" #include "nsWrapperCache.h" #include "nsAutoPtr.h" #include "js/TypeDecls.h" @@ -50,7 +51,8 @@ public: }; class Promise MOZ_FINAL : public nsISupports, - public nsWrapperCache + public nsWrapperCache, + public SupportsWeakPtr { friend class NativePromiseCallback; friend class PromiseResolverMixin; @@ -71,6 +73,7 @@ class Promise MOZ_FINAL : public nsISupports, public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise) + MOZ_DECLARE_REFCOUNTED_TYPENAME(Promise) // Promise creation tries to create a JS reflector for the Promise, so is // fallible. Furthermore, we don't want to do JS-wrapping on a 0-refcount diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index b8be1fc92b2..6b9a5454cb7 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -66,10 +66,10 @@ UpdatePromise::ResolveAllPromises(const nsACString& aScriptSpec, const nsACStrin RuntimeService* rs = RuntimeService::GetOrCreateService(); MOZ_ASSERT(rs); - nsTArray> array; + nsTArray> array; array.SwapElements(mPromises); for (uint32_t i = 0; i < array.Length(); ++i) { - nsTWeakRef& pendingPromise = array.ElementAt(i); + WeakPtr& pendingPromise = array.ElementAt(i); if (pendingPromise) { nsCOMPtr go = do_QueryInterface(pendingPromise->GetParentObject()); @@ -103,10 +103,10 @@ UpdatePromise::RejectAllPromises(nsresult aRv) MOZ_ASSERT(mState == Pending); mState = Rejected; - nsTArray> array; + nsTArray> array; array.SwapElements(mPromises); for (uint32_t i = 0; i < array.Length(); ++i) { - nsTWeakRef& pendingPromise = array.ElementAt(i); + WeakPtr& pendingPromise = array.ElementAt(i); if (pendingPromise) { // Since ServiceWorkerContainer is only exposed to windows we can be // certain about this cast. @@ -125,10 +125,10 @@ UpdatePromise::RejectAllPromises(const ErrorEventInit& aErrorDesc) MOZ_ASSERT(mState == Pending); mState = Rejected; - nsTArray> array; + nsTArray> array; array.SwapElements(mPromises); for (uint32_t i = 0; i < array.Length(); ++i) { - nsTWeakRef& pendingPromise = array.ElementAt(i); + WeakPtr& pendingPromise = array.ElementAt(i); if (pendingPromise) { // Since ServiceWorkerContainer is only exposed to windows we can be // certain about this cast. diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index 81f4245b065..3693f562dce 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -13,12 +13,12 @@ #include "mozilla/Preferences.h" #include "mozilla/TypedEnum.h" #include "mozilla/TypedEnumBits.h" +#include "mozilla/WeakPtr.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Promise.h" #include "nsRefPtrHashtable.h" #include "nsTArrayForwardDeclare.h" #include "nsTObserverArray.h" -#include "nsTWeakRef.h" class nsIScriptError; @@ -65,7 +65,7 @@ private: // XXXnsm: Right now we don't need to support AddPromise() after // already being resolved (i.e. true Promise-like behaviour). - nsTArray> mPromises; + nsTArray> mPromises; }; /* diff --git a/dom/xbl/nsXBLProtoImplMethod.cpp b/dom/xbl/nsXBLProtoImplMethod.cpp index cf53cebbc5c..437d844fe7c 100644 --- a/dom/xbl/nsXBLProtoImplMethod.cpp +++ b/dom/xbl/nsXBLProtoImplMethod.cpp @@ -8,11 +8,10 @@ #include "jsapi.h" #include "nsIContent.h" #include "nsIDocument.h" -#include "nsIScriptGlobalObject.h" +#include "nsIGlobalObject.h" #include "nsUnicharUtils.h" #include "nsReadableUtils.h" #include "nsXBLProtoImplMethod.h" -#include "nsIScriptContext.h" #include "nsJSUtils.h" #include "nsContentUtils.h" #include "nsCxPusher.h" @@ -20,6 +19,7 @@ #include "nsIXPConnect.h" #include "xpcpublic.h" #include "nsXBLPrototypeBinding.h" +#include "mozilla/dom/ScriptSettings.h" using namespace mozilla; @@ -278,20 +278,18 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd // nsXBLProtoImpl::InstallImplementation does. nsIDocument* document = aBoundElement->OwnerDoc(); - nsCOMPtr global = - do_QueryInterface(document->GetWindow()); + nsCOMPtr global = + do_QueryInterface(document->GetInnerWindow()); if (!global) { return NS_OK; } - nsCOMPtr context = global->GetContext(); - if (!context) { - return NS_OK; - } - nsAutoMicroTask mt; - AutoPushJSContext cx(context->GetNativeContext()); + // We are going to run script via JS::Call, so we need a script entry point, + // but as this is XBL related it does not appear in the HTML spec. + dom::AutoEntryScript aes(global); + JSContext* cx = aes.cx(); JS::Rooted globalObject(cx, global->GetGlobalJSObject()); @@ -299,15 +297,6 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd nsresult rv = nsContentUtils::WrapNative(cx, aBoundElement, &v); NS_ENSURE_SUCCESS(rv, rv); - // Use nsCxPusher to make sure we call ScriptEvaluated when we're done. - // - // Make sure to do this before entering the compartment, since pushing Push() - // may call JS_SaveFrameChain(), which puts us back in an unentered state. - nsCxPusher pusher; - if (!pusher.Push(aBoundElement)) - return NS_ERROR_UNEXPECTED; - MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext()); - JS::Rooted thisObject(cx, &v.toObject()); JS::Rooted scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId)); NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY); diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff index 5b4f51c2b7f..07948f5feda 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff +++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff @@ -8987,29 +8987,30 @@ > Yolande/M > Yolane/M > Yolanthe/M -10253c16003,16006 +10253c16003,16007 < York/M --- +> Yooper/MS > Yorgo/MS > York/MR > Yorke/M > Yorker/M -10258a16012,16013 +10258a16013,16014 > Yoshi/M > Yoshiko/M -10262a16018 +10262a16019 > Yovonnda/M -10264a16021 +10264a16022 > Ysabel/M -10271a16029 +10271a16030 > Yul/M -10273a16032 +10273a16033 > Yulma/M -10276a16036 +10276a16037 > Yurik/M -10278a16039 +10278a16040 > Yvon/M -10280c16041,16046 +10280c16042,16047 < Z/SMNXT --- > Yvor/M @@ -9018,24 +9019,24 @@ > Zaccaria/M > Zach > Zacharia/SM -10281a16048 +10281a16049 > Zacharie/M -10282a16050 +10282a16051 > Zacherie/M -10283a16052,16053 +10283a16053,16054 > Zack/M > Zackariah/M -10284a16055 +10284a16056 > Zahara/M -10286a16058 +10286a16059 > Zak/M -10292a16065 +10292a16066 > Zandra/M -10293a16067 +10293a16068 > Zaneta/M -10300a16075 +10300a16076 > Zarah/M -10301a16077,16083 +10301a16078,16084 > Zared/M > Zaria/M > Zarla/M @@ -9043,31 +9044,31 @@ > Zealand/M > Zeb/M > Zebadiah/M -10302a16085,16086 +10302a16086,16087 > Zebulen/M > Zebulon/M -10303a16088 +10303a16089 > Zed/M -10307a16093 +10307a16094 > Zelda/M -10310a16097 +10310a16098 > Zena/M -10311a16099 +10311a16100 > Zenia/M -10315a16104 +10315a16105 > Zerk/M -10321a16111 +10321a16112 > Zia/M -10325a16116 +10325a16117 > Zilvia/M -10333a16125,16126 +10333a16126,16127 > Zita/M > Zitella/M -10336a16130 +10336a16131 > Zollie/M -10337a16132 +10337a16133 > Zolly/M -10339a16135,16142 +10339a16136,16143 > Zonda/M > Zondra/M > Zonnya/M @@ -9076,713 +9077,716 @@ > Zorana/M > Zorina/M > Zorine/M -10346a16150 +10346a16151 > Zsazsa/M -10350a16155 +10350a16156 > Zulema/M -10354a16160 +10354a16161 > Zuzana/M -10460a16267 +10460a16268 > abridgement/MS -10488a16296,16297 +10488a16297,16298 > absorbance/S > absorbancy/M -10516,10517c16325 +10516,10517c16326 < abuse's < abuse/EGVDS --- > abuse/EGVDSM -10665a16474 +10665a16475 > acknowledgement/MS -10709,10710c16518 +10709,10710c16519 < act's < act/ASDGV --- > act/ASDGVM -10721,10722c16529 +10721,10722c16530 < active's < active/IKY --- > active/IKYSM -10724d16530 +10724d16531 < actives -10727,10728c16533 +10727,10728c16534 < activity's/I < activity/AS --- > activity/ASIM -10774,10775c16579 +10774,10775c16580 < address's < address/AGDS --- > address/AGDSM -10824c16628 +10824c16629 < admin/S --- > admin/MS -10936a16741 +10936a16742 > advocator/SM -10937a16743 +10937a16744 > adware/MS -10979,10980c16785 +10979,10980c16786 < affect's < affect/EGVDS --- > affect/EGVDSM -10990,10991c16795 +10990,10991c16796 < affiliate's < affiliate/EGNDS --- > affiliate/EGNDSM -11045c16849 +11045c16850 < afterward --- > afterward/S -11073a16878 +11073a16879 > aggregator/SM -11393d17197 +11393d17198 < altho -11579a17384 +11579a17385 > analyses -11631c17436 +11631c17437 < anecdotal --- > anecdotal/Y -11750a17556,17557 +11750a17557,17558 > anonymization/SM > anonymize/DSG -11804c17611 +11804c17612 < anthropomorphizing --- > anthropomorphize/DSG -11983c17790 +11983c17791 < app/S --- > app/MS -12035,12036c17842 +12035,12036c17843 < appointment's/A < appointment/ESM --- > appointment/ESMA -12135a17942,17943 +12135a17943,17944 > archaeoastronomy/M > archaeologic -12137a17946,17948 +12137a17947,17949 > archaeology/M > archaeomagnetic > archaeomagnetism -12152c17963 +12152c17964 < archeological --- > archeological/Y -12214,12215c18025 +12214,12215c18026 < arm's < arm/EAGDS --- > arm/EAGDSM -12255,12256c18065 +12255,12256c18066 < arrangement's/E < arrangement/ASM --- > arrangement/ASME -12427,12428c18236 +12427,12428c18237 < assign's < assign/ALGDS --- > assign/ALGDSM -12432c18240 +12432c18241 < assignees --- > assignee/MS -12446,12447c18254 +12446,12447c18255 < associate's < associate/EDSGNV --- > associate/EDSGNVM -12491a18299,18301 +12491a18300,18302 > astroarchaeology/SM > astrobiology/M > astrobleme/S -12584,12585c18394 +12584,12585c18395 < attempt's < attempt/ASDG --- > attempt/ASDGM -12685c18494 +12685c18495 < auteur --- > auteur/MS -12713a18523 +12713a18524 > autocomplete/S -12754a18565 +12754a18566 > avant-garde -12827d18637 +12827d18638 < awol -12829a18640 +12829a18641 > axe/M -12969c18780 +12969c18781 < badge/MZDRS --- > badge/MZDRSG -13018,13019c18829 +13018,13019c18830 < balance's < balance/UDSG --- > balance/UDSGM -13079,13080c18889 +13079,13080c18890 < band's < band/ESGD --- > band/ESGDM -13149,13150c18958 +13149,13150c18959 < bar's < bar/ECUTS --- > bar/ECUTSM -13195,13196c19003 +13195,13196c19004 < bark's < bark/CSGD --- > bark/CSGDM -13249,13250c19056 +13249,13250c19057 < base's < base/CDRSLTG --- > base/CDRSLTGM -13843,13844c19649 +13843,13844c19650 < bind's < bind/AUGS --- > bind/AUGSM -13864a19670 +13864a19671 > biodiesel/M -14118,14119c19924 +14118,14119c19925 < block's < block/UGDS --- > block/UGDSM -14179a19985,19987 +14179a19986,19988 > bloviate/SGD > bloviation > bloviator/SM -14210d20017 +14210d20018 < blueing's -14356,14357c20163 +14356,14357c20164 < bolt's < bolt/USGD --- > bolt/USGDM -14434a20241 +14434a20242 > bookselling -14455,14456c20262 +14455,14456c20263 < boot's < boot/ASGD --- > boot/ASGDM -14501,14502c20307 +14501,14502c20308 < bosom's < bosom/US --- > bosom/USM -14522a20328 +14522a20329 > botnet/MS -14785,14786c20591 +14785,14786c20592 < brief's < brief/CSDTGJ --- > brief/CSDTGJM -14841c20646 +14841c20647 < broadcast/AMGS --- > broadcast/AMGSD -14956,14957c20761 +14956,14957c20762 < buckle's < buckle/UDSG --- > buckle/UDSGM -14986,14987c20790 +14986,14987c20791 < bug's < bug/CS --- > bug/CSM -15039,15040c20842 +15039,15040c20843 < bullshitter's < bullshitter/S! --- > bullshitter/SM! -15078,15079c20880 +15078,15079c20881 < bunk's < bunk/CDGS --- > bunk/CDGSM -15093,15094c20894 +15093,15094c20895 < burden's < burden/USGD --- > burden/USGDM -15211,15212c21011 +15211,15212c21012 < button's < button/USDG --- > button/USDGM -15230d21028 +15230d21029 < byelaw/SM -15383d21180 +15383d21181 < callisthenics/M -15430,15431c21227 +15430,15431c21228 < camp's < camp/CSTGD --- > camp/CSTGDM -15460a21257,21259 +15460a21258,21260 > cancelled/U > canceller/M > cancelling -15518,15519c21317 +15518,15519c21318 < cant's < cant/CZRDGS --- > cant/CZRDGSM -15559a21358 +15559a21359 > capita -15609c21408 +15609c21409 < caravanserai's --- > caravanserai/M -15629,15630d21427 +15629,15630d21428 < carburetter/SM < carburettor/SM -15701a21499 +15701a21500 > carnitas -15788d21585 +15788d21586 < cashpoint/S -15797d21593 +15797d21594 < cassino/M -15832a21629 +15832a21630 > catalyses -15940d21736 +15940d21737 < caviare/M -16013,16014c21809 +16013,16014c21810 < cent's < cent/AR --- > cent/ARM -16098,16099c21893 +16098,16099c21894 < chain's < chain/UGDS --- > chain/UGDSM -16231,16232c22025 +16231,16232c22026 < charter's < charter/ASGD --- > charter/ASGDM -16277c22070 +16277c22071 < check/AGMDS --- > check/AGMDSU -16327c22120 +16327c22121 < chemistry/M --- > chemistry/MS -16372c22165 +16372c22166 < chickenshit/S! --- > chickenshit/SM! -16404c22197 +16404c22198 < children --- > children/M -16488d22280 +16488d22281 < chlorophyl/M -16629,16630c22421 +16629,16630c22422 < cider's < cider/S --- > cider/MS -16651,16652c22442,22443 +16651,16652c22443,22444 < cipher's < cipher/CGDS --- > cipher/CGDSM > ciphertext/S -16702,16703c22493 +16702,16703c22494 < cite's < cite/IAGSD --- > cite/IAGSDM -16733,16735c22523 +16733,16735c22524 < claim's < claim/CKEAGDS < claimable --- > claim/CKEAGDSMB -16783,16784c22571 +16783,16784c22572 < clasp's < clasp/UGDS --- > clasp/UGDSM -16794,16796c22581 +16794,16796c22582 < classified's < classified/U < classifieds --- > classified/MSU -16918,16919c22703 +16918,16919c22704 < cloak's < cloak/USDG --- > cloak/USDGM -16930,16931c22714 +16930,16931c22715 < clog's < clog/US --- > clog/USM -16944,16946c22727 +16944,16946c22728 < close's < close/EIGTSD < closeable --- > close/EIGTSDMB -17072d22852 +17072d22853 < cocain/M -17102,17103c22882 +17102,17103c22883 < cocksucker's < cocksucker/S! --- > cocksucker/SM! -17117,17118c22896 +17117,17118c22897 < code's < code/CAGDS --- > code/CAGDSM -17195,17196c22973 +17195,17196c22974 < coil's/A < coil/UADGS --- > coil/UADGSM -17245,17246c23022 +17245,17246c23023 < collect's < collect/ASGVD --- > collect/ASGVDM -17301a23078,23079 +17301a23079,23080 > colonoscope/SM > colonoscopy/SM -17304,17305c23082 +17304,17305c23083 < color's < color/AEGDS --- > color/AEGDSM -17311,17313c23088 +17311,17313c23089 < colored's < colored/U < coloreds --- > colored/MSU -17351,17352c23126 +17351,17352c23127 < combine's < combine/ADSG --- > combine/ADSGM -17371c23145 +17371c23146 < comer's --- > comer/M -17376,17377c23150 +17376,17377c23151 < comfit's < comfit/ES --- > comfit/ESM -17412c23185 +17412c23186 < comment/GSMDR --- > comment/GSMDRZ -17428,17429c23201 +17428,17429c23202 < commission's < commission/ACGSD --- > commission/ACGSDM -17442,17443c23214 +17442,17443c23215 < commode's < commode/EIS --- > commode/EISM -17447,17448c23218 +17447,17448c23219 < common's < common/UPRYT --- > common/UPRYTM -17537,17538c23307 +17537,17538c23308 < compilation's < compilation/AS --- > compilation/ASM -17597,17598c23366 +17597,17598c23367 < compress's < compress/CGVDS --- > compress/CGVDSM -17657,17658c23425 +17657,17658c23426 < concert's < concert/ESDG --- > concert/ESDGM -17719,17720c23486 +17719,17720c23487 < condition's < condition/AGSD --- > condition/AGSDM -17755c23521 +17755c23522 < confer/S --- > confer/SB -17800a23567 +17800a23568 > conformant -17986,17987c23753 +17986,17987c23754 < construct's < construct/CADVGS --- > construct/CADVGSM -17991,17992c23757 +17991,17992c23758 < constructionist's < constructionist/CS --- > constructionist/CSM -18122,18123c23887 +18122,18123c23888 < control's < control/CS --- > control/CSM -18151d23914 +18151d23915 < convenor/S -18169,18170c23932 +18169,18170c23933 < convert's < convert/AGSD --- > convert/AGSDM -18199,18200c23961 +18199,18200c23962 < cook's < cook/ADGS --- > cook/ADGSM -18206c23967 +18206c23968 < cookie/M --- > cookie/SM -18294,18295c24055 +18294,18295c24056 < cork's < cork/UDGS --- > cork/UDGSM -18375a24136,24137 +18375a24137,24138 > corrigibility/IM > corrigible/I -18389a24152 +18389a24153 > corruptibly/I -18467a24231 +18467a24232 > could've -18487,18488c24251 +18487,18488c24252 < countenance's < countenance/EGDS --- > countenance/EGDSM -18542,18543c24305 +18542,18543c24306 < coup's < coup/AS --- > coup/ASM -18545,18546c24307 +18545,18546c24308 < couple's < couple/CUDSG --- > couple/CUDSGM -18581,18582c24342 +18581,18582c24343 < cover's < cover/AEUGDS --- > cover/AEUGDSM -18585,18586c24345 +18585,18586c24346 < covering's < coverings --- > covering/MS -18739,18740c24498 +18739,18740c24499 < creation's/K < creation/ASM --- > creation/ASMK -18816a24575 +18816a24576 > crimeware/M -18880,18881c24639 +18880,18881c24640 < cross's < cross/AUGTSD --- > cross/AUGTSDM -18972,18973c24730 +18925a24685,24686 +> crowdfunded +> crowdfunding +18972,18973c24733 < crust's < crust/ISDG --- > crust/ISDGM -18988,18989c24745 +18988,18989c24748 < crypt's < crypt/CS --- > crypt/CSM -18999a24756 +18999a24759 > cryptologist/MS -19000a24758 +19000a24761 > cryptosystem/S -19035a24794 +19035a24797 > cul-de-sac -19104,19105c24863 +19104,19105c24866 < cure's < cure/KZGBDRS --- > cure/KZGBDRSM -19119,19120c24877 +19119,19120c24880 < curl's < curl/UDGS --- > curl/UDGSM -19131,19133c24888 +19131,19133c24891 < current's < current/FAY < currents --- > current/FAYSM -19142,19143c24897 +19142,19143c24900 < cursive's < cursive/EAY --- > cursive/EAYM -19167,19168c24921 +19167,19168c24924 < cuss's < cuss/FEGSD --- > cuss/FEGSDM -19246c24999 +19246c25002 < cysteine --- > cysteine/M -19536a25290 +19536a25293 > decertify/DSGNX -19935a25690 +19935a25693 > dequeue/DSG -19999a25755 +19999a25758 > designated/U -20196,20197c25952,25953 +20196,20197c25955,25956 < dialog/SM < dialogue/SM --- > dialog/SMGD > dialogue/SMRGD -20220a25977 +20220a25980 > diatomaceous -20481a26239 +20481a26242 > disclose/DSG -20633a26392 +20633a26395 > dissentious -20695,20696c26454 +20695,20696c26457 < district's < district/AS --- > district/ASM -20768c26526 +20768c26529 < djinn's --- > djinn/M -20830c26588 +20830c26591 < dogie/M --- > dogie/SM -20850,20851c26608 +20850,20851c26611 < dole's < dole/FGDS --- > dole/FGDSM -20895a26653 +20895a26656 > donator/MS -20918,20919c26676 +20918,20919c26679 < door's < door/IS --- > door/ISM -20975,20976c26732 +20975,20976c26735 < double's < double/ADSG --- > double/ADSGM -21067,21068c26823 +21067,21068c26826 < draft's < draft/ASDG --- > draft/ASDGM -21282,21283c27037 +21282,21283c27040 < duct's < duct/CIFDG --- > duct/CIFDGM -21291,21292c27045 +21291,21292c27048 < due's < due/IS --- > due/ISM -21355,21356c27108 +21355,21356c27111 < duplicate's < duplicate/AGNDS --- > duplicate/AGNDSM -21367a27120 +21367a27123 > durian/SM -21468,21469c27221 +21468,21469c27224 < earth's < earth/UDYG --- > earth/UDYGM -21523,21524c27275 +21523,21524c27278 < echo's < echo/ADG --- > echo/ADGM -21587,21588c27338 +21587,21588c27341 < edit's < edit/ADGS --- > edit/ADGSM -21735,21736c27485 +21735,21736c27488 < elect's < elect/ASDGV --- > elect/ASDGVM -21820a27570 +21820a27573 > elicitor/MS -21864,21865c27614 +21864,21865c27617 < em's < em/S --- > em/SM -21992,21993c27741 +21992,21993c27744 < employ's < employ/ADGLS --- > employ/ADGLSM -22071a27820 +22071a27823 > encyclopaedia -22196a27946 +22196a27949 > enqueue/DSG -22508a28259,28260 +22508a28262,28263 > eschatological > eschatologist/SM -22556a28309 +22556a28312 > estoppel -22638c28391 +22638c28394 < euthanize --- > euthanize/DSG -22719a28473 +22719a28476 > exabyte/MS -22722,22724c28476,28479 +22722,22724c28479,28482 < exact/SPDRYTG < exacting/Y < exaction/M @@ -9791,52 +9795,52 @@ > exacta/S > exacting/YP > exaction/MS -22726a28482 +22726a28485 > exactor/MS -22947a28704 +22947a28707 > experimentalism -23165,23166c28922 +23165,23166c28925 < face's < face/ACSDG --- > face/ACSDGM -23207,23208d28962 +23207,23208d28965 < faecal < faeces/M -23215c28969 +23215c28972 < faggoting's --- > faggot/SMG -23238,23239c28992 +23238,23239c28995 < faithful's < faithful/UPY --- > faithful/UPYM -23278,23279c29031 +23278,23279c29034 < fame's < fame/D --- > fame/DM -23418a29171 +23418a29174 > faux -23589,23590c29342 +23589,23590c29345 < fetter's < fetter/USGD --- > fetter/USGDM -23690,23691c29442 +23690,23691c29445 < figure's < figure/FEGSD --- > figure/FEGSDM -23699,23700c29450 +23699,23700c29453 < file's/KC < file/CAKGDS --- > file/CAKGDSM -23701a29452 +23701a29455 > filesystem/MS -23708,23711c29459,29460 +23708,23711c29462,29463 < filing's < filings < fill's @@ -9844,644 +9848,653 @@ --- > filing/SM > fill/AIDGSM -23715,23716c29464 +23715,23716c29467 < filling's < filling/S --- > filling/SM -23733,23734c29481 +23733,23734c29484 < filtrate's < filtrate/IGNDS --- > filtrate/IGNDSM -23745,23746c29492 +23745,23746c29495 < finance's < finance/ADSG --- > finance/ADSGM -23755,23756c29501 +23755,23756c29504 < fine's/F < fine/CAFTGDS --- > fine/CAFTGDSM -23776,23777c29521 +23776,23777c29524 < finish's < finish/ADSG --- > finish/ADSGM -24131,24132c29875 +24131,24132c29878 < flower's < flower/CSDG --- > flower/CSDGM -24155c29898 +24155c29901 < fluidized --- > fluidize/DSG -24185,24186c29928 +24185,24186c29931 < flux's < flux/ADG --- > flux/ADGM -24217,24218c29959,29960 +24217,24218c29962,29963 < focus's < focus/ADSG --- > foci > focus/ADSGM -24223,24224c29965 +24223,24224c29968 < fog's < fog/CS --- > fog/CSM -24238,24239c29979 +24238,24239c29982 < fold's < fold/IAUSGD --- > fold/IAUSGDM -24414,24415c30154 +24414,24415c30157 < forest's < forest/ACGDS --- > forest/ACGDSM -24464,24465c30203 +24464,24465c30206 < form's < form/CAIFDGS --- > form/CAIFDGSM -24609,24610c30347 +24585a30327,30328 +> frack/DRGS +> fracker/S +24609,24610c30352 < franchise's < franchise/EDSG --- > franchise/EDSGM -24633,24634c30370 +24633,24634c30375 < fraud's < fraud/S --- > fraud/SM -24639,24640c30375 +24639,24640c30380 < fray's < fray/CDGS --- > fray/CDGSM -24681,24682c30416 +24657a30398 +> freegan/S +24681,24682c30422 < freeze's < freeze/UAGS --- > freeze/UAGSM -24684c30418 +24684c30424 < freezing's --- > freezing/M -24733,24734c30467 +24733,24734c30473 < friendly's < friendly/UTPR --- > friendly/UTPRM -24736d30468 +24736d30474 < frier/M -24752,24753c30484 +24752,24753c30490 < fringe's < fringe/IDSG --- > fringe/IDSGM -24771,24772c30502 +24771,24772c30508 < frock's < frock/CUS --- > frock/CUSM -24786,24787c30516 +24786,24787c30522 < front's < front/FSDG --- > front/FSDGM -24800,24801c30529 +24800,24801c30535 < frost's < frost/CSDG --- > frost/CSDGM -24855,24856c30583,30584 +24855,24856c30589,30590 < fucker/M! < fuckhead/S! --- > fucker/SM! > fuckhead/SM! -24860,24861c30588 +24860,24861c30594 < fuel's < fuel/ADGS --- > fuel/ADGSM -24941,24942c30668 +24941,24942c30674 < furl's < furl/UDGS --- > furl/UDGSM -24953d30678 +24953d30684 < furore/MS -24969,24970c30694 +24969,24970c30700 < fuse's/A < fuse/CAIFGDS --- > fuse/CAIFGDSM -25038,25039c30762 +25038,25039c30768 < gain's < gain/ADGS --- > gain/ADGSM -25051,25052c30774 +25051,25052c30780 < gale's < gale/AS --- > gale/ASM -25125c30847 +25095a30824 +> gamify/NGDS +25125c30854 < gaolbird/S --- > gaolbirds -25169,25170c30891 +25169,25170c30898 < gas's < gas/CS --- > gas/CSM -25180d30900 +25180d30907 < gasolene/M -25190a30911 +25190a30918 > gastroenterologist/M -25262c30983 +25262c30990 < geezer/M --- > geezer/MS -25297,25298c31018 +25297,25298c31025 < generation's/C < generation/ASM --- > generation/ASMC -25327c31047 +25327c31054 < genomic --- > genomic/S -25462a31183 +25462a31190 > gigabit/MS -25464a31186,31188 +25464a31193,31195 > gigajoule/MS > gigapixel/MS > gigawatt/MS -25560d31283 +25560d31290 < glamourize/DSG -25674c31397 +25674c31404 < glycerine's --- > glycerine/M -25816,25817c31539 +25816,25817c31546 < gorge's < gorge/EDSG --- > gorge/EDSGM -25884,25885c31606 +25884,25885c31613 < grade's < grade/CADSG --- > grade/CADSGM -25905c31626 +25905c31633 < gram/MS --- > gram/KMS -25909d31629 +25909d31636 < gramme/SM -26063c31783,31784 +26063c31790,31791 < greybeard --- > grey/MDRTGSP > greybeard/SM -26066c31787 +26066c31794 < greyness --- > greyness/M -26246,26247d31966 +26246,26247d31973 < guerilla's < guerillas -26403,26404c32122 +26403,26404c32129 < habit's < habit/ISB --- > habit/ISBM -26432,26436d32149 +26432,26436d32156 < haemoglobin's < haemophilia/M < haemorrhage/DSMG < haemorrhoid/S < haemorrhoids/M -26555,26556c32268 +26555,26556c32275 < hand's < hand/UDGS --- > hand/UDGSM -26702,26703c32414 +26702,26703c32421 < harness's < harness/UDSG --- > harness/UDSGM -26888,26889c32599 +26725a32444 +> hashtag/S +26888,26889c32607 < hearse's < hearse/AS --- > hearse/ASM -26915,26916c32625 +26915,26916c32633 < heat's < heat/ADGS --- > heat/ADGSM -27167c32876 +27167c32884 < hexane --- > hexane/SM -27256,27257c32965 +27256,27257c32973 < hinge's < hinge/UDSG --- > hinge/UDSGM -27273a32982 +27273a32990 > hippopotami -27276,27277c32985 +27276,27277c32993 < hire's < hire/AGDS --- > hire/AGDSM -27302,27303c33010 +27302,27303c33018 < hitch's < hitch/UDSG --- > hitch/UDSGM -27512,27513c33219 +27512,27513c33227 < hook's < hook/UDSG --- > hook/UDSGM -27575,27576c33281 +27575,27576c33289 < horse's < horse/UDSG --- > horse/UDSGM -27666,27667c33371 +27666,27667c33379 < house's < house/ADSG --- > house/ADSGM -27841c33545 +27841c33553 < hurrah's --- > hurrah/M -27875d33578 +27875d33586 < hyaena/SM -27883,27884c33586 +27883,27884c33594 < hydrate's < hydrate/CGNDS --- > hydrate/CGNDSM -28017c33719 +28017c33727 < iPod/M --- > iPod/MS -28029,28030c33731 +28029,28030c33739 < ice's < ice/CDSG --- > ice/CDSGM -28105a33807 +28105a33815 > idolator/SM -28227c33929 +28227c33937 < immerse/XDSGN --- > immerse/XDSGNV -28513c34215 +28513c34223 < inbound --- > inbound/s -28531,28532c34233 +28531,28532c34241 < incentive's < incentive/ES --- > incentive/ESM -28560,28561c34261 +28560,28561c34269 < incline's < incline/EGDS --- > incline/EGDSM -28590,28591c34290 +28590,28591c34298 < incorrigibility/M < incorrigible --- > incorrigibleness -28593d34291 +28593d34299 < incorruptibly -28650a34349 +28650a34357 > indices -28812d34510 +28812d34518 < inflexion/SM -28981,28982c34679 +28981,28982c34687 < insert's < insert/AGSD --- > insert/AGSDM -29204a34902 +29204a34910 > intermediacy/S -29206c34904,34906 +29206c34912,34914 < intermediate/SMY --- > intermediate/SMYPGD > intermediation/SE > intermediator/SM -29216a34917 +29216a34925 > intern/GDL -29266a34968 +29266a34976 > interruptible/U -29272a34975,34978 +29272a34983,34986 > intersex > intersexual/MS > intersexualism > intersexuality -29724c35430 +29724c35438 < jewellery's --- > jewellery/M -29733,29734c35439 +29733,29734c35447 < jig's < jig/AS --- > jig/ASM -29736,29737c35441 +29736,29737c35449 < jigger's < jigger/ASDG --- > jigger/ASDGM -29799,29800c35503 +29799,29800c35511 < join's < join/AFDSG --- > join/AFDSGM -29803,29804c35506 +29803,29804c35514 < joint's < joint/EGSD --- > joint/EGSDM -29869,29870c35571,35572 +29869,29870c35579,35580 < judge's < judge/ADSG --- > judge/ADSGM > judgement/MS -30035a35738,35739 +30035a35746,35747 > keylogger/MS > keylogging/MS -30066c35770 +30066c35778 < kiddie/M --- > kiddie/SM -30102,30103c35806 +30102,30103c35814 < kind's < kind/UPRYT --- > kind/UPRYTM -30262,30263c35965 +30262,30263c35973 < kraut's < kraut/S! --- > kraut/MS! -30283,30284c35985 +30283,30284c35993 < label's < label/ASDG --- > label/ASDGM -30302,30303c36003 +30302,30303c36011 < lace's < lace/UGDS --- > lace/UGDSM -30497,30498c36197 +30497,30498c36205 < latch's < latch/UDSG --- > latch/UDSGM -30637c36336 +30637c36344 < learning's --- > learning/M -30643,30644c36342 +30643,30644c36350 < leash's < leash/UDSG --- > leash/UDSGM -30665a36364 +30665a36372 > lector/MS -30700c36399 +30700c36407 < legation's/AC --- > legation/ACM -30927,30928c36626 +30927,30928c36634 < light's/C < light/CASTGD --- > light/CASTGDM -30938c36636 +30938c36644 < lighting's --- > lighting/M -30981,30982c36679 +30981,30982c36687 < limit's < limit/CSZGDR --- > limit/CSZGDRM -30986c36683 +30986c36691 < limiter's --- > limiter/M -30990a36688,36690 +30990a36696,36698 > limnological > limnologist/MS > limnology/M -31031c36731 +31031c36739 < linguini's --- > linguini/M -31034c36734 +31034c36742 < linguistically --- > linguistical/Y -31047,31048c36747 +31047,31048c36755 < lint's < lint/CDSG --- > lint/CDSGM -31058a36758 +31058a36766 > lepidopterist/SM -31151,31152c36851 +31151,31152c36859 < liver's < liver/S --- > liver/MS -31170,31171c36869 +31170,31171c36877 < load's < load/AUGSD --- > load/AUGSDM -31211,31212c36909 +31211,31212c36917 < location's/A < location/ESM --- > location/ESMA -31291,31292c36988 +31291,31292c36996 < long's < long/KDSTG --- > long/KDSTGM -31379,31380c37075 +31379,31380c37083 < louse's < louse/CDSG --- > louse/CDSGM -31639a37335 +31639a37343 > mage/SM -31741,31742c37437 +31741,31742c37445 < make's/A < make/UAGS --- > make/UAGSM -31806a37502 +31806a37510 > malware/MS -31822,31823c37518 +31822,31823c37526 < man's/F < man/USY --- > man/USYMF -31924,31925c37619 +31924,31925c37627 < mantle's < mantle/EGDS --- > mantle/EGDSM -31940,31941c37634 +31940,31941c37642 < map's < map/AS --- > map/ASM -32061,32062c37754 +32061,32062c37762 < mask's < mask/UDSG --- > mask/UDSGM -32084,32085c37776 +32084,32085c37784 < master's < master/ADGS --- > master/ADGSM -32230c37921 +32230c37929 < meanie/M --- > meanie/MS -32246,32247c37937 +32246,32247c37945 < measure's < measure/ADSG --- > measure/ADSGM -32317,32318c38007 +32317,32318c38015 < megadeath/M < megadeaths --- > megadeath/SM -32320c38009 +32320c38017 < megajoules --- > megajoule/SM -32329c38018 +32329c38026 < megapixel/S --- > megapixel/MS -32361,32362c38050 +32361,32362c38058 < melt's < melt/ADSG --- > melt/ADSGM -32365,32366c38053 +32365,32366c38061 < member's < member/EAS --- > member/EASM -32708a38396 +32708a38404 > might've -32717a38406 +32717a38414 > migrator/SM -32760a38450 +32760a38458 > millennia -32777d38466 +32777d38474 < millionnaire/M -32806,32807c38495 +32806,32807c38503 < mind's < mind/ADRSZG --- > mind/ADRSZGM -32934a38623 +32934a38631 > miscommunication/S -32991a38681 +32991a38689 > misjudgement/MS -33027,33028c38717 +33027,33028c38725 < miss's < miss/EDSGV --- > miss/EDSGVM -33051,33052c38740 +33051,33052c38748 < mist's < mist/CDRSZG --- > mist/CDRSZGM -33056c38744 +33056c38752 < mister's --- > mister/M -33107,33108c38795 +33107,33108c38803 < mob's < mob/CS --- > mob/CSM -33448,33449c39135 +33448,33449c39143 < mortgage's < mortgage/AGDS --- > mortgage/AGDSM -33471,33472c39157 +33471,33472c39165 < mote's < mote/KCXSVN --- > mote/KCXSVNM -33539,33540c39224 +33539,33540c39232 < mounting's < mountings --- > mounting/MS -33784a39469 +33784a39477 > must've -33887,33888c39572 +33887,33888c39580 < name's < name/AGDS --- > name/AGDSM -33963c39647 +33963c39655 < native/MS --- > native/MSY -33970,33971c39654 +33970,33971c39662 < natural's < natural/UPY --- > natural/UPYM -33979,33980c39662 +33979,33980c39670 < nature's < nature/CS --- > nature/CSM -34133,34134c39815 +34133,34134c39823 < nerve's < nerve/UDSG --- > nerve/UDSGM -34169,34171c39850,39852 +34169,34171c39858,39860 < neurone/S < neurophysiology < neuroscience @@ -10489,874 +10502,892 @@ > neurophysiology/M > neuroscience/MS > neuroscientist/MS -34175a39857 +34175a39865 > neurosurgical -34275c39957 +34275c39965 < nightie/M --- > nightie/SM -34388,34389c40070 +34388,34389c40078 < nomination's/A < nomination/CSM --- > nomination/CSMA -34755,34756c40436 +34755,34756c40444 < note's < note/FCSDG --- > note/FCSDGM -34840,34841c40520 +34840,34841c40528 < number's < number/ASDG --- > number/ASDGM -35104a40784 +35104a40792 > octopi -35137,35138c40817 +35137,35138c40825 < offensive's < offensive/IYP --- > offensive/IYPM -35219d40897 +35219d40905 < oleomargarin/M -35226a40905 +35226a40913 > oligo -35345c41024 +35345c41032 < oppose/DSG --- > oppose/DSGRB -35452,35453c41131 +35452,35453c41139 < orient's < orient/AEDGS --- > orient/AEDGSM -35913c41591 +35913c41599 < oversize/D --- > oversize -36031,36032c41709 +36031,36032c41717 < pack's < pack/UADSG --- > pack/UADSGM -36034,36035c41711 +36034,36035c41719 < package's < package/AGDS --- > package/AGDSM -36041c41717 +36041c41725 < packing's --- > packing/M -36056,36059d41731 +36056,36059d41739 < paederast/S < paediatrician's < paediatricians < paediatrics/M -36290a41963,41964 +36290a41971,41972 > parallelization/SM > parallelize/SGD -36291a41966 +36291a41974 > paralyses -36377a42053 +36377a42061 > parkour -36403d42078 +36403d42086 < parrakeet/MS -36418,36419c42093 +36418,36419c42101 < part's < part/CDSG --- > part/CDSGM -36445,36447c42119 +36445,36447c42127 < partition's < partition/ADG < partitions --- > partition/ADGMS -36449d42120 +36449d42128 < partizan/SM -36621,36622c42292 +36621,36622c42300 < pay's < pay/ASGBL --- > pay/ASGBLM -37093a42764 +37093a42772 > petabyte/MS -37102c42773 +37102c42781 < petitioner/M --- > petitioner/MS -37221a42893,42894 +37221a42901,42902 > phlebotomist/SM > phlebotomize/SGD -37264a42938 +37228a42910 +> pho +37264a42947 > phosphorylate/DSGN -37310,37311c42984 +37310,37311c42993 < phrase's < phrase/AGDS --- > phrase/AGDSM -37316d42988 +37316d42997 < phrenetic -37469,37470c43141 +37469,37470c43150 < pine's < pine/AGDS --- > pine/AGDSM -37596,37597c43267 +37596,37597c43276 < place's < place/EAGLDS --- > place/EAGLDSM -37630a43301 +37630a43310 > plaintext -37636,37637c43307 +37636,37637c43316 < plane's < plane/CGDS --- > plane/CGDSM -37786,37787c43456 +37786,37787c43465 < ploy's < ploy/S --- > ploy/SM -37792,37793c43461 +37792,37793c43470 < plug's < plug/US --- > plug/USM -37796a43465 +37796a43474 > plugin/MS -37987c43656 +37987c43665 < polypeptide/S --- > polypeptide/MS -38106,38107c43775 +38106,38107c43784 < port's < port/CAEGDS --- > port/CAEGDSM -38134,38135c43802 +38134,38135c43811 < pose's/A < pose/CAKEGDS --- > pose/CAKEGDSM -38140,38141c43807 +38140,38141c43816 < position's/KC < position/ACKES --- > position/ACKESM -38260,38261c43926 +38260,38261c43935 < pound's < pound/KDSG --- > pound/KDSGM -38291d43955 +38266a43941 +> poutine/S +38291d43965 < practise's -38451a44116 +38451a44126 > prejudgement/MS -38568,38569c44233 +38568,38569c44243 < press's < press/ACGSD --- > press/ACGSDM -38638,38639c44302 +38638,38639c44312 < price's < price/AGDS --- > price/AGDSM -38756,38757c44419 +38756,38757c44429 < process's < process/AGDS --- > process/AGDSM -38780,38781c44442 +38780,38781c44452 < produce's < produce/AZGDRS --- > produce/AZGDRSM -38805a44467 +38805a44477 > profiler/SM -38835a44498 +38835a44508 > programmatically -38891a44555,44556 +38891a44565,44566 > pronate/DSGN > pronator/MS -38951c44616 +38951c44626 < proprietorship/M --- > proprietorship/MS -39039a44705 +39039a44715 > provender/M -39095a44762 +39095a44772 > pseudorandom/Y -39564a45232 +39564a45242 > quinoa -39581,39582c45249 +39581,39582c45259 < quire's < quire/IAS --- > quire/IASM -39614,39615c45281 +39614,39615c45291 < quote's < quote/UDSG --- > quote/UDSGM -39653,39654c45319 +39653,39654c45329 < racoon's < racoons --- > racoon/MS -39738,39739c45403 +39738,39739c45413 < rail's < rail/CGDS --- > rail/CGDSM -39816,39817c45480 +39816,39817c45490 < range's < range/CGDS --- > range/CGDSM -39873a45537,45538 +39873a45547,45548 > rasterization/M > rasterize/SGDR -39925,39926c45590 +39925,39926c45600 < ravel's < ravel/UDSG --- > ravel/UDSGM -40036a45701 +40036a45711 > recency -40140a45806 +40140a45816 > recurse/DGSV -40141a45808 +40141a45818 > recuse/DGS -40204,40205c45871 +40204,40205c45881 < reel's < reel/UGDS --- > reel/UGDSM -40208a45875 +40208a45885 > refactor/SMDG -40244d45910 +40244d45920 < reflexion/SM -40659d46324 +40659d46334 < resizing -40829c46494 +40829c46504 < reverie/M --- > reverie/MS -40895a46561,46563 +40895a46571,46573 > rheumatological > rheumatology/M > rheumatologist/SM -40944,40945c46612 +40944,40945c46622 < ride's < ride/CZGS --- > ride/CZGSM -41104,41105c46771 +41104,41105c46781 < robe's < robe/EGDS --- > robe/EGDSM -41132,41133c46798 +41132,41133c46808 < rogue's < rogue/KS --- > rogue/KSM -41185a46851 +41185a46861 > rootkit/MS -41258,41259c46924 +41258,41259c46934 < route's < route/ADSG --- > route/ADSGM -41415a47081 +41415a47091 > sabre/MS -41447,41448c47113 +41447,41448c47123 < saddle's < saddle/UDSG --- > saddle/UDSGM -41463,41464c47128 +41463,41464c47138 < safe's < safe/UYTPR --- > safe/UYTPRM -41544,41545c47208 +41544,41545c47218 < salt's < salt/CTGDS --- > salt/CTGDSM -41765,41766c47428 +41765,41766c47438 < say's < say/USG --- > say/USGM -41787,41788c47449 +41787,41788c47459 < scale's < scale/ACSDG --- > scale/ACSDGM -41806,41807c47467 +41806,41807c47477 < scan's < scan/AS --- > scan/ASM -41880,41881c47540 +41880,41881c47550 < schedule's < schedule/ADSG --- > schedule/ADSGM -41914c47573 +41914c47583 < schnaps's --- > schnaps/M -41949c47608 +41949c47618 < schrod's --- > schrod/SM -41998a47658 +41998a47668 > scot-free -42016,42017c47676 +42016,42017c47686 < scramble's < scramble/UGDS --- > scramble/UGDSM -42055,42056c47714 +42055,42056c47724 < screw's < screw/UDSG --- > screw/UDSGM -42065,42066c47723 +42065,42066c47733 < scribe's < scribe/IKCGSD --- > scribe/IKCGSDM -42170,42171c47827 +42170,42171c47837 < seal's < seal/AUSDG --- > seal/AUSDGM -42204,42205c47860 +42204,42205c47870 < seat's < seat/UGDS --- > seat/UGDSM -42288,42289c47943 +42288,42289c47953 < seed's < seed/AGDS --- > seed/AGDSM -42365,42367c48019,48020 +42359c48023,48024 +< self/M +--- +> self/MG +> selfie/S +42361a48027,48028 +> selfism +> selfist/S +42365,42367c48032,48033 < sell's < sell/AZGRS < seller's --- > sell/AZGRSM > seller/M -42524c48177 +42524c48190 < seraphim's --- > seraphim/M -42558,42559c48211 +42558,42559c48224 < serve's/AF < serve/FACGDS --- > serve/FACGDSM -42574,42575c48226 +42574,42575c48239 < serving's < servings --- > serving/MS -42594,42595c48245 +42594,42595c48258 < settle's < settle/AUGDS --- > settle/AUGDSM -42647,42648c48297 +42647,42648c48310 < shackle's < shackle/UGDS --- > shackle/UGDSM -42716,42717c48365 +42716,42717c48378 < shape's < shape/AGDS --- > shape/AGDSM -42851,42852c48499 +42851,42852c48512 < ship's < ship/ALS --- > ship/ALSM -42883,42885c48530 +42883,42885c48543 < shit's < shit/S! < shite/S! --- > shit/MS! -42887,42888c48532,48533 +42887,42888c48545,48546 < shithead/S! < shitload/! --- > shithead/MS! > shitload/MS! -42891c48536 +42891c48549 < shitty/RT! --- > shitty/TR! -42976a48622 +42976a48635 > should've -43008c48654 +43008c48667 < showtime --- > showtime/MS -43090,43091c48736 +43090,43091c48749 < side's < side/AGDS --- > side/AGDSM -43143,43144c48788 +43143,43144c48801 < sign's < sign/AFCGDS --- > sign/AFCGDSM -43163,43164c48807 +43163,43164c48820 < signing's/C < signings --- > signing/MCS -43328c48971 +43328c48984 < size/MGBDRS --- > size/AMGBDRS -43368,43369c49011 +43368,43369c49024 < skill's < skill/CSD --- > skill/CSDM -43724,43726c49366 +43724,43726c49379 < smoulder's < smouldered < smoulders --- > smoulder/GSMD -43752,43753c49392 +43752,43753c49405 < snap's < snap/US --- > snap/USM -43767,43768c49406,49408 +43767,43768c49419,49421 < snarl's < snarl/USDG --- > snarkily > snarky/TR > snarl/USDGM -44012,44013c49652 +44012,44013c49665 < solute's < solute/XN --- > solute/XNM -44015c49654 +44015c49667 < solution's/EA --- > solution/EAM -44021c49660 +44021c49673 < solver's --- > solver/M -44041a49681 +44041a49694 > sommelier/SM -44062c49702 +44062c49715 < sonofabitch --- > sonofabitch/! -44177,44178c49817 +44177,44178c49830 < sow's < sow/ASGD --- > sow/ASGDM -44346a49986 +44346a49999 > spelled -44348a49989 +44348a50002 > spelt -44371a50013 +44371a50026 > spick/S! -44383c50025 +44383c50038 < spik/S --- > spik/S! -44413,44414c50055 +44413,44414c50068 < spire's < spire/IFAS --- > spire/IFASM -44416,44417c50057 +44416,44417c50070 < spirit's < spirit/ISGD --- > spirit/ISGDM -44475,44476c50115 +44475,44476c50128 < spoil's < spoil/CSDRZG --- > spoil/CSDRZGM -44549,44550c50188 +44549,44550c50201 < spray's < spray/ASDG --- > spray/ASDGM -44688,44689c50326 +44688,44689c50339 < staff's < staff/ASDG --- > staff/ASDGM -44729,44730c50366 +44729,44730c50379 < stall's < stall/SDG --- > stall/SDGM -44985,44986c50621 +44871a50521 +> steampunk +44985,44986c50635 < still's < still/ITGSD --- > still/ITGSDM -45024,45025c50659 +45024,45025c50673 < stitch's < stitch/ADSG --- > stitch/ADSGM -45030,45031c50664 +45030,45031c50678 < stock's < stock/AGSD --- > stock/AGSDM -45090,45091c50723 +45090,45091c50737 < stop's < stop/US --- > stop/USM -45105,45106c50737 +45105,45106c50751 < store's < store/ADSG --- > store/ADSGM -45148,45149c50779 +45148,45149c50793 < strain's < strain/FADSG --- > strain/FADSGM -45164,45165c50794 +45164,45165c50808 < strap's < strap/US --- > strap/USM -45290,45291c50919 +45290,45291c50933 < structure's < structure/AGDS --- > structure/AGDSM -45330,45331c50958 +45330,45331c50972 < study's < study/AGDS --- > study/AGDSM -45368,45369c50995 +45368,45369c51009 < style's < style/ADSG --- > style/ADSGM -45455,45456c51081 +45455,45456c51095 < submission's < submission/AS --- > submission/ASM -45872,45873c51497 +45872,45873c51511 < surface's < surface/AGDS --- > surface/AGDSM -45918,45919c51542 +45918,45919c51556 < survey's < survey/ADGS --- > survey/ADGSM -46106a51730 +46106a51744 > syllabi -46160c51784 +46160c51798 < synch/GMD --- > synch/GMDS -46167d51790 +46167d51804 < synchs -46178a51802,51804 +46178a51816,51818 > synesthesia > synesthete/S > synesthetic -46203,46204c51829,51830 +46203,46204c51843,51844 < sysadmin/S < sysop/S --- > sysadmin/MS > sysop/MS -46363,46364c51989 +46363,46364c52003 < tangle's < tangle/UDSG --- > tangle/UDSGM -46632a52258,52259 +46632a52272,52273 > teleport/SGD > teleportation -46675,46676c52302 +46675,46676c52316 < template's < template/S --- > template/SM -46752a52379 +46752a52393 > terabit/MS -46753a52381,52382 +46753a52395,52396 > terahertz/M > terapixel/MS -46806,46807c52435 +46806,46807c52449 < test's/AFK < test/AKFCDGS --- > test/AKFCDGSM -46817a52446 +46817a52460 > testcase/MS -46831a52461 +46831a52475 > testsuite/MS -46845a52476 +46845a52490 > textbox/SM -46925a52557 +46925a52571 > theremin/MS -46999c52631 +46999c52645 < thinking's --- > thinking/M -47095,47096c52727 +47095,47096c52741 < throne's < throne/CDS --- > throne/CDSM -47188,47189c52819 +47188,47189c52833 < tie's < tie/AUSD --- > tie/AUSDM -47213,47214c52843 +47213,47214c52857 < till's < till/EDRZGS --- > till/EDRZGSM -47303,47304c52932 +47303,47304c52946 < tire's < tire/AGDS --- > tire/AGDSM -47433,47434c53061 +47433,47434c53075 < tone's < tone/IZGDRS --- > tone/IZGDRSM -47453,47455c53080,53081 +47453,47455c53094,53095 < tool's < tool/ADGS < toolbar --- > tool/ADGSM > toolbar/MS -47540,47541c53166 +47540,47541c53180 < tort's < tort/FEAS --- > tort/FEASM -47644a53270 +47644a53284 > traceur/SM -47657,47658c53283 +47657,47658c53297 < tract's < tract/CEKFAS --- > tract/CEKFASM -47755a53381 +47755a53395 > transfect/DSMG -47774a53401,53402 +47774a53415,53416 > transgenderism > transgene/MS -47807,47808c53435 +47807,47808c53449 < transmission's < transmission/AS --- > transmission/ASM -47928,47929c53555 +47928,47929c53569 < trench's < trench/AIGSD --- > trench/AIGSDM -47951c53577 +47951c53591 < triage/M --- > triage/MGS -47976,47977c53602 +47976,47977c53616 < tribute's < tribute/FS --- > tribute/FSM -47997a53623 +47997a53637 > trifecta/S -48165,48166c53791 +48165,48166c53805 < trust's/E < trust/IESGD --- > trust/IESGDM -48180,48181c53805 +48180,48181c53819 < try's < try/AGDS --- > try/AGDSM -48371,48372c53995 +48271a53910 +> turducken +48334a53974 +> tweep/S +48371,48372c54011 < twist's < twist/USDG --- > twist/USDGM -48396,48397c54019 +48396,48397c54035 < type's < type/AGDS --- > type/AGDSM -48869a54492 +48869a54508 > unlikeable -49163,49164c54786 +49163,49164c54802 < usual's < usual/UY --- > usual/UYM -49211c54833 +49211c54849 < vagina/M --- > vagina/MS -49249,49250c54871 +49249,49250c54887 < value's < value/CAGSD --- > value/CAGSDM -49292,49293c54913 +49292,49293c54929 < variant's < variant/IS --- > variant/ISM -49356,49357c54976 +49356,49357c54992 < veil's < veil/UDGS --- > veil/UDGSM -49368,49369c54987 +49368,49369c55003 < velour's < velours's --- > velour/MS -49398,49399c55016 +49398,49399c55032 < vent's < vent/DGS --- > vent/DGSM -49435,49436c55052 +49435,49436c55068 < verge's < verge/FDSG --- > verge/FDSGM -49478a55095 +49478a55111 > vertices -49488,49489c55105 +49488,49489c55121 < vest's < vest/ILDGS --- > vest/ILDGSM -49681,49682c55297 +49681,49682c55313 < visit's < visit/ASGD --- > visit/ASGDM -49772a55388,55390 +49772a55404,55406 > volcanological > volcanologist/MS > volcanology/M -49807,49808c55425 +49807,49808c55441 < vote's < vote/CGVDS --- > vote/CGVDSM -50148a55766 +50148a55782 > weaponize/DSG -50215,50216c55833 +50215,50216c55849 < weigh's < weigh/AGD --- > weigh/AGDM -50260,50261d55876 +50260,50261d55892 < werwolf/M < werwolves -50555,50556c56170 +50555,50556c56186 < wind's < wind/UASG --- > wind/UASGM -50626,50627c56240 +50626,50627c56256 < wire's < wire/AGDS --- > wire/AGDSM -50728c56341 +50728c56357 < women --- > women/M -50794,50796c56407,56408 +50794,50796c56423,56424 < wop/S! < word's < word/AJDSG --- > wop/MS! > word/AJDSGM -50801c56413 +50801c56429 < wording's --- > wording/M -50808,50809c56420 +50808,50809c56436 < work's < work/ADJSG --- > work/ADJSGM -50824c56435 +50824c56451 < working's --- > working/M -50884,50885c56495 +50884,50885c56511 < worthy's < worthy/UPRT --- > worthy/UPRTM -50903,50904c56513 +50903,50904c56529 < wrap's < wrap/US --- > wrap/USM -50945c56554 +50945c56570 < writing's --- > writing/M -51118,51119c56727 +51118,51119c56743 < yoke's < yoke/UGDS --- > yoke/UGDSM -51212,51213c56820 +51212,51213c56836 < zip's < zip/US --- > zip/USM -51228,51229c56835 +51228,51229c56851 < zone's < zone/AGDS --- diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic index fd99199088d..d29cd6a09d7 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic +++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic @@ -1,4 +1,4 @@ -57222 +57238 0/nm 0th/pt 1/n1 @@ -16232,6 +16232,7 @@ Yolane/M Yolanthe/M Yong/M Yonkers +Yooper/MS Yorgo/MS York/MR Yorke/M @@ -24946,6 +24947,8 @@ crow/MDGS crowbar/MS crowd/SMDG crowded/U +crowdfunded +crowdfunding crowfeet crowfoot/M crown/SMDG @@ -30603,6 +30606,8 @@ foyer/SM fps fr fracas/MS +frack/DRGS +fracker/S fractal/SM fraction/IASM fractional/Y @@ -30672,6 +30677,7 @@ freeborn freedman/M freedmen freedom/SM +freegan/S freehand freehold/ZMRS freeholder/M @@ -31098,6 +31104,7 @@ gamester/MS gamete/SM gametic gamey +gamify/NGDS gamin/SM gamine/SM gaminess/M @@ -32721,6 +32728,7 @@ harvester/M hash/AMDSG hasheesh/M hashish/M +hashtag/S hasn't hasp/MS hassle/DSMG @@ -43221,6 +43229,7 @@ phlegmatically phloem/M phlogiston phlox/M +pho phobia/MS phobic/MS phoebe/MS @@ -44254,6 +44263,7 @@ pounding/SM pour/GDSBJ pout/ZGMDRS pouter/M +poutine/S poverty/M pow powder/GSMD @@ -48346,9 +48356,12 @@ selenium/M selenographer/MS selenography/M selenology -self/M +self/MG +selfie/S selfish/UYP selfishness/UM +selfism +selfist/S selfless/YP selflessness/M selfsame @@ -50850,6 +50863,7 @@ steamer/M steamfitter/MS steamfitting/M steaminess/M +steampunk steamroll/ZGDRS steamroller/MDG steamship/MS @@ -54250,6 +54264,7 @@ turbot/SM turbulence/M turbulent/Y turd/MS +turducken tureen/SM turf/MDSG turfy/RT @@ -54313,6 +54328,7 @@ tweed/SM tweeds/M tweedy/RT tween +tweep/S tweet/SMDRZG tweeter/M tweezers/M diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 99355aa0d71..cbad1ce799a 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -288,6 +288,9 @@ public: Matrix mMatrix; //!< Transforms the pattern into user space }; +class StoredPattern; +class DrawTargetCaptureImpl; + /** * This is the base class for source surfaces. These objects are surfaces * which may be used as a source in a SurfacePattern or a DrawSurface call. @@ -331,6 +334,15 @@ public: } protected: + friend class DrawTargetCaptureImpl; + friend class StoredPattern; + + // This is for internal use, it ensures the SourceSurface's data remains + // valid during the lifetime of the SourceSurface. + // @todo XXX - We need something better here :(. But we may be able to get rid + // of CreateWrappingDataSourceSurface in the future. + virtual void GuaranteePersistance() {} + UserData mUserData; }; @@ -395,6 +407,7 @@ public: */ virtual TemporaryRef GetDataSurface(); +protected: bool mIsMapped; }; @@ -608,6 +621,8 @@ protected: GlyphRenderingOptions() {} }; +class DrawTargetCapture; + /** This is the main class used for all the drawing. It is created through the * factory and accepts drawing commands. The results of drawing to a target * may be used either through a Snapshot or by flushing the target and directly @@ -646,6 +661,15 @@ public: */ virtual void Flush() = 0; + /** + * Realize a DrawTargetCapture onto the draw target. + * + * @param aSource Capture DrawTarget to draw + * @param aTransform Transform to apply when replaying commands + */ + virtual void DrawCapturedDT(DrawTargetCapture *aCaptureDT, + const Matrix& aTransform); + /** * Draw a surface to the draw target. Possibly doing partial drawing or * applying scaling. No sampling happens outside the source. @@ -881,6 +905,14 @@ public: virtual TemporaryRef CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0; + /** + * Create a DrawTarget that captures the drawing commands and can be replayed + * onto a compatible DrawTarget afterwards. + * + * @param aSize Size of the area this DT will capture. + */ + virtual TemporaryRef CreateCaptureDT(const IntSize& aSize); + /** * Create a draw target optimized for drawing a shadow. * @@ -993,6 +1025,10 @@ protected: SurfaceFormat mFormat; }; +class DrawTargetCapture : public DrawTarget +{ +}; + class DrawEventRecorder : public RefCounted { public: diff --git a/gfx/2d/DrawCommand.h b/gfx/2d/DrawCommand.h new file mode 100644 index 00000000000..ed2c44e21af --- /dev/null +++ b/gfx/2d/DrawCommand.h @@ -0,0 +1,504 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_DRAWCOMMAND_H_ +#define MOZILLA_GFX_DRAWCOMMAND_H_ + +#include "2D.h" +#include "Filters.h" +#include + +namespace mozilla { +namespace gfx { + +MOZ_BEGIN_ENUM_CLASS(CommandType, int8_t) + DRAWSURFACE = 0, + DRAWFILTER, + DRAWSURFACEWITHSHADOW, + CLEARRECT, + COPYSURFACE, + COPYRECT, + FILLRECT, + STROKERECT, + STROKELINE, + STROKE, + FILL, + FILLGLYPHS, + MASK, + MASKSURFACE, + PUSHCLIP, + PUSHCLIPRECT, + POPCLIP, + SETTRANSFORM +MOZ_END_ENUM_CLASS(CommandType) + +class DrawingCommand +{ +public: + virtual ~DrawingCommand() {} + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aTransform) = 0; + +protected: + DrawingCommand(CommandType aType) + : mType(aType) + { + } + + CommandType GetType() { return mType; } + +private: + CommandType mType; +}; + +class StoredPattern +{ +public: + StoredPattern(const Pattern& aPattern) + { + Assign(aPattern); + } + + void Assign(const Pattern& aPattern) + { + switch (aPattern.GetType()) { + case PatternType::COLOR: + new (mColor)ColorPattern(*static_cast(&aPattern)); + return; + case PatternType::SURFACE: + { + SurfacePattern* surfPat = new (mColor)SurfacePattern(*static_cast(&aPattern)); + surfPat->mSurface->GuaranteePersistance(); + return; + } + case PatternType::LINEAR_GRADIENT: + new (mColor)LinearGradientPattern(*static_cast(&aPattern)); + return; + case PatternType::RADIAL_GRADIENT: + new (mColor)RadialGradientPattern(*static_cast(&aPattern)); + return; + } + } + + ~StoredPattern() + { + reinterpret_cast(mColor)->~Pattern(); + } + + operator Pattern&() + { + return *reinterpret_cast(mColor); + } + + operator const Pattern&() const + { + return *reinterpret_cast(mColor); + } + + StoredPattern(const StoredPattern& aPattern) + { + Assign(aPattern); + } + +private: + StoredPattern operator=(const StoredPattern& aOther) + { + // Block this so that we notice if someone's doing excessive assigning. + return *this; + } + + union { + char mColor[sizeof(ColorPattern)]; + char mLinear[sizeof(LinearGradientPattern)]; + char mRadial[sizeof(RadialGradientPattern)]; + char mSurface[sizeof(SurfacePattern)]; + }; +}; + +class DrawSurfaceCommand : public DrawingCommand +{ +public: + DrawSurfaceCommand(SourceSurface *aSurface, const Rect& aDest, + const Rect& aSource, const DrawSurfaceOptions& aSurfOptions, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::DRAWSURFACE) + , mSurface(aSurface), mDest(aDest) + , mSource(aSource), mSurfOptions(aSurfOptions) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions); + } + +private: + RefPtr mSurface; + Rect mDest; + Rect mSource; + DrawSurfaceOptions mSurfOptions; + DrawOptions mOptions; +}; + +class DrawFilterCommand : public DrawingCommand +{ +public: + DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect, + const Point& aDestPoint, const DrawOptions& aOptions) + : DrawingCommand(CommandType::DRAWSURFACE) + , mFilter(aFilter), mSourceRect(aSourceRect) + , mDestPoint(aDestPoint), mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->DrawFilter(mFilter, mSourceRect, mDestPoint, mOptions); + } + +private: + RefPtr mFilter; + Rect mSourceRect; + Point mDestPoint; + DrawOptions mOptions; +}; + +class ClearRectCommand : public DrawingCommand +{ +public: + ClearRectCommand(const Rect& aRect) + : DrawingCommand(CommandType::CLEARRECT) + , mRect(aRect) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->ClearRect(mRect); + } + +private: + Rect mRect; +}; + +class CopySurfaceCommand : public DrawingCommand +{ +public: + CopySurfaceCommand(SourceSurface* aSurface, + const IntRect& aSourceRect, + const IntPoint& aDestination) + : DrawingCommand(CommandType::COPYSURFACE) + , mSurface(aSurface) + , mSourceRect(aSourceRect) + , mDestination(aDestination) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aTransform) + { + MOZ_ASSERT(!aTransform.HasNonIntegerTranslation()); + Point dest(Float(mDestination.x), Float(mDestination.y)); + dest = aTransform * dest; + aDT->CopySurface(mSurface, mSourceRect, IntPoint(uint32_t(dest.x), uint32_t(dest.y))); + } + +private: + RefPtr mSurface; + IntRect mSourceRect; + IntPoint mDestination; +}; + +class FillRectCommand : public DrawingCommand +{ +public: + FillRectCommand(const Rect& aRect, + const Pattern& aPattern, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::FILLRECT) + , mRect(aRect) + , mPattern(aPattern) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->FillRect(mRect, mPattern, mOptions); + } + +private: + Rect mRect; + StoredPattern mPattern; + DrawOptions mOptions; +}; + +class StrokeRectCommand : public DrawingCommand +{ +public: + StrokeRectCommand(const Rect& aRect, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::STROKERECT) + , mRect(aRect) + , mPattern(aPattern) + , mStrokeOptions(aStrokeOptions) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions); + } + +private: + Rect mRect; + StoredPattern mPattern; + StrokeOptions mStrokeOptions; + DrawOptions mOptions; +}; + +class StrokeLineCommand : public DrawingCommand +{ +public: + StrokeLineCommand(const Point& aStart, + const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::STROKELINE) + , mStart(aStart) + , mEnd(aEnd) + , mPattern(aPattern) + , mStrokeOptions(aStrokeOptions) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions); + } + +private: + Point mStart; + Point mEnd; + StoredPattern mPattern; + StrokeOptions mStrokeOptions; + DrawOptions mOptions; +}; + +class FillCommand : public DrawingCommand +{ +public: + FillCommand(const Path* aPath, + const Pattern& aPattern, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::FILL) + , mPath(const_cast(aPath)) + , mPattern(aPattern) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->Fill(mPath, mPattern, mOptions); + } + +private: + RefPtr mPath; + StoredPattern mPattern; + DrawOptions mOptions; +}; + +class StrokeCommand : public DrawingCommand +{ +public: + StrokeCommand(const Path* aPath, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::STROKE) + , mPath(const_cast(aPath)) + , mPattern(aPattern) + , mStrokeOptions(aStrokeOptions) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions); + } + +private: + RefPtr mPath; + StoredPattern mPattern; + StrokeOptions mStrokeOptions; + DrawOptions mOptions; +}; + +class FillGlyphsCommand : public DrawingCommand +{ +public: + FillGlyphsCommand(ScaledFont* aFont, + const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const DrawOptions& aOptions, + const GlyphRenderingOptions* aRenderingOptions) + : DrawingCommand(CommandType::FILLGLYPHS) + , mFont(aFont) + , mPattern(aPattern) + , mOptions(aOptions) + , mRenderingOptions(const_cast(aRenderingOptions)) + { + mGlyphs.resize(aBuffer.mNumGlyphs); + memcpy(&mGlyphs.front(), aBuffer.mGlyphs, sizeof(Glyph) * aBuffer.mNumGlyphs); + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + GlyphBuffer buf; + buf.mNumGlyphs = mGlyphs.size(); + buf.mGlyphs = &mGlyphs.front(); + aDT->FillGlyphs(mFont, buf, mPattern, mOptions, mRenderingOptions); + } + +private: + RefPtr mFont; + std::vector mGlyphs; + StoredPattern mPattern; + DrawOptions mOptions; + RefPtr mRenderingOptions; +}; + +class MaskCommand : public DrawingCommand +{ +public: + MaskCommand(const Pattern& aSource, + const Pattern& aMask, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::MASK) + , mSource(aSource) + , mMask(aMask) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->Mask(mSource, mMask, mOptions); + } + +private: + StoredPattern mSource; + StoredPattern mMask; + DrawOptions mOptions; +}; + +class MaskSurfaceCommand : public DrawingCommand +{ +public: + MaskSurfaceCommand(const Pattern& aSource, + const SourceSurface* aMask, + const Point& aOffset, + const DrawOptions& aOptions) + : DrawingCommand(CommandType::MASKSURFACE) + , mSource(aSource) + , mMask(const_cast(aMask)) + , mOffset(aOffset) + , mOptions(aOptions) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->MaskSurface(mSource, mMask, mOffset, mOptions); + } + +private: + StoredPattern mSource; + RefPtr mMask; + Point mOffset; + DrawOptions mOptions; +}; + +class PushClipCommand : public DrawingCommand +{ +public: + PushClipCommand(const Path* aPath) + : DrawingCommand(CommandType::PUSHCLIP) + , mPath(const_cast(aPath)) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->PushClip(mPath); + } + +private: + RefPtr mPath; +}; + +class PushClipRectCommand : public DrawingCommand +{ +public: + PushClipRectCommand(const Rect& aRect) + : DrawingCommand(CommandType::PUSHCLIPRECT) + , mRect(aRect) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->PushClipRect(mRect); + } + +private: + Rect mRect; +}; + +class PopClipCommand : public DrawingCommand +{ +public: + PopClipCommand() + : DrawingCommand(CommandType::POPCLIP) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix&) + { + aDT->PopClip(); + } +}; + +class SetTransformCommand : public DrawingCommand +{ +public: + SetTransformCommand(const Matrix& aTransform) + : DrawingCommand(CommandType::SETTRANSFORM) + , mTransform(aTransform) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix& aMatrix) + { + Matrix transform = mTransform; + transform *= aMatrix; + aDT->SetTransform(transform); + } + +private: + Matrix mTransform; +}; + +} /* namespace mozilla */ +} /* namespace gfx */ + +#endif /* MOZILLA_GFX_DRAWCOMMAND_H_ */ diff --git a/gfx/2d/DrawTarget.cpp b/gfx/2d/DrawTarget.cpp new file mode 100644 index 00000000000..63f72899382 --- /dev/null +++ b/gfx/2d/DrawTarget.cpp @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "2D.h" +#include "Logging.h" + +#include "DrawTargetCapture.h" + +namespace mozilla { +namespace gfx { + +TemporaryRef +DrawTarget::CreateCaptureDT(const IntSize& aSize) +{ + RefPtr dt = new DrawTargetCaptureImpl(); + + if (!dt->Init(aSize, this)) { + gfxWarning() << "Failed to initialize Capture DrawTarget!"; + return nullptr; + } + + return dt; +} + +void +DrawTarget::DrawCapturedDT(DrawTargetCapture *aCaptureDT, + const Matrix& aTransform) +{ + if (aTransform.HasNonIntegerTranslation()) { + gfxWarning() << "Non integer translations are not supported for DrawCaptureDT at this time!"; + return; + } + static_cast(aCaptureDT)->ReplayToDrawTarget(this, aTransform); +} + +} +} diff --git a/gfx/2d/DrawTargetCapture.cpp b/gfx/2d/DrawTargetCapture.cpp new file mode 100644 index 00000000000..d53a98ec770 --- /dev/null +++ b/gfx/2d/DrawTargetCapture.cpp @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "DrawTargetCapture.h" +#include "DrawCommand.h" + +namespace mozilla { +namespace gfx { + + +DrawTargetCaptureImpl::~DrawTargetCaptureImpl() +{ + uint8_t* start = &mDrawCommandStorage.front(); + + uint8_t* current = start; + + while (current < start + mDrawCommandStorage.size()) { + reinterpret_cast(current + sizeof(uint32_t))->~DrawingCommand(); + current += *(uint32_t*)current; + } +} + +bool +DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT) +{ + if (!aRefDT) { + return false; + } + + mRefDT = aRefDT; + + mSize = aSize; + return true; +} + +TemporaryRef +DrawTargetCaptureImpl::Snapshot() +{ + RefPtr dt = mRefDT->CreateSimilarDrawTarget(mSize, mRefDT->GetFormat()); + + ReplayToDrawTarget(dt, Matrix()); + + return dt->Snapshot(); +} + +#define AppendCommand(arg) new (AppendToCommandList()) arg + +void +DrawTargetCaptureImpl::DrawSurface(SourceSurface *aSurface, + const Rect &aDest, + const Rect &aSource, + const DrawSurfaceOptions &aSurfOptions, + const DrawOptions &aOptions) +{ + aSurface->GuaranteePersistance(); + AppendCommand(DrawSurfaceCommand)(aSurface, aDest, aSource, aSurfOptions, aOptions); +} + +void +DrawTargetCaptureImpl::DrawFilter(FilterNode *aNode, + const Rect &aSourceRect, + const Point &aDestPoint, + const DrawOptions &aOptions) +{ + // @todo XXX - this won't work properly long term yet due to filternodes not + // being immutable. + AppendCommand(DrawFilterCommand)(aNode, aSourceRect, aDestPoint, aOptions); +} + +void +DrawTargetCaptureImpl::ClearRect(const Rect &aRect) +{ + AppendCommand(ClearRectCommand)(aRect); +} + +void +DrawTargetCaptureImpl::MaskSurface(const Pattern &aSource, + SourceSurface *aMask, + Point aOffset, + const DrawOptions &aOptions) +{ + aMask->GuaranteePersistance(); + AppendCommand(MaskSurfaceCommand)(aSource, aMask, aOffset, aOptions); +} + +void +DrawTargetCaptureImpl::CopySurface(SourceSurface* aSurface, + const IntRect& aSourceRect, + const IntPoint& aDestination) +{ + aSurface->GuaranteePersistance(); + AppendCommand(CopySurfaceCommand)(aSurface, aSourceRect, aDestination); +} + +void +DrawTargetCaptureImpl::FillRect(const Rect& aRect, + const Pattern& aPattern, + const DrawOptions& aOptions) +{ + AppendCommand(FillRectCommand)(aRect, aPattern, aOptions); +} + +void +DrawTargetCaptureImpl::StrokeRect(const Rect& aRect, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) +{ + AppendCommand(StrokeRectCommand)(aRect, aPattern, aStrokeOptions, aOptions); +} + +void +DrawTargetCaptureImpl::StrokeLine(const Point& aStart, + const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) +{ + AppendCommand(StrokeLineCommand)(aStart, aEnd, aPattern, aStrokeOptions, aOptions); +} + +void +DrawTargetCaptureImpl::Stroke(const Path* aPath, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) +{ + AppendCommand(StrokeCommand)(aPath, aPattern, aStrokeOptions, aOptions); +} + +void +DrawTargetCaptureImpl::Fill(const Path* aPath, + const Pattern& aPattern, + const DrawOptions& aOptions) +{ + AppendCommand(FillCommand)(aPath, aPattern, aOptions); +} + +void +DrawTargetCaptureImpl::FillGlyphs(ScaledFont* aFont, + const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const DrawOptions& aOptions, + const GlyphRenderingOptions* aRenderingOptions) +{ + AppendCommand(FillGlyphsCommand)(aFont, aBuffer, aPattern, aOptions, aRenderingOptions); +} + +void +DrawTargetCaptureImpl::Mask(const Pattern &aSource, + const Pattern &aMask, + const DrawOptions &aOptions) +{ + AppendCommand(MaskCommand)(aSource, aMask, aOptions); +} + +void +DrawTargetCaptureImpl::PushClip(const Path* aPath) +{ + AppendCommand(PushClipCommand)(aPath); +} + +void +DrawTargetCaptureImpl::PushClipRect(const Rect& aRect) +{ + AppendCommand(PushClipRectCommand)(aRect); +} + +void +DrawTargetCaptureImpl::PopClip() +{ + AppendCommand(PopClipCommand)(); +} + +void +DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform) +{ + AppendCommand(SetTransformCommand)(aTransform); +} + +void +DrawTargetCaptureImpl::ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform) +{ + uint8_t* start = &mDrawCommandStorage.front(); + + uint8_t* current = start; + + while (current < start + mDrawCommandStorage.size()) { + reinterpret_cast(current + sizeof(uint32_t))->ExecuteOnDT(aDT, aTransform); + current += *(uint32_t*)current; + } +} + +} +} diff --git a/gfx/2d/DrawTargetCapture.h b/gfx/2d/DrawTargetCapture.h new file mode 100644 index 00000000000..2ef8f0e6255 --- /dev/null +++ b/gfx/2d/DrawTargetCapture.h @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_DRAWTARGETCAPTURE_H_ +#define MOZILLA_GFX_DRAWTARGETCAPTURE_H_ + +#include "2D.h" +#include + +#include "Filters.h" + +namespace mozilla { +namespace gfx { + +class DrawingCommand; + +class DrawTargetCaptureImpl : public DrawTargetCapture +{ +public: + DrawTargetCaptureImpl() + {} + + bool Init(const IntSize& aSize, DrawTarget* aRefDT); + + virtual BackendType GetBackendType() const { return mRefDT->GetBackendType(); } + virtual DrawTargetType GetType() const { return mRefDT->GetType(); } + + virtual TemporaryRef Snapshot(); + virtual IntSize GetSize() { return mSize; } + + virtual void Flush() {} + virtual void DrawSurface(SourceSurface *aSurface, + const Rect &aDest, + const Rect &aSource, + const DrawSurfaceOptions &aSurfOptions, + const DrawOptions &aOptions); + virtual void DrawFilter(FilterNode *aNode, + const Rect &aSourceRect, + const Point &aDestPoint, + const DrawOptions &aOptions = DrawOptions()); + virtual void DrawSurfaceWithShadow(SourceSurface *aSurface, + const Point &aDest, + const Color &aColor, + const Point &aOffset, + Float aSigma, + CompositionOp aOperator) { /* Not implemented */ } + + virtual void ClearRect(const Rect &aRect); + virtual void MaskSurface(const Pattern &aSource, + SourceSurface *aMask, + Point aOffset, + const DrawOptions &aOptions = DrawOptions()); + + virtual void CopySurface(SourceSurface *aSurface, + const IntRect &aSourceRect, + const IntPoint &aDestination); + + virtual void FillRect(const Rect &aRect, + const Pattern &aPattern, + const DrawOptions &aOptions = DrawOptions()); + virtual void StrokeRect(const Rect &aRect, + const Pattern &aPattern, + const StrokeOptions &aStrokeOptions = StrokeOptions(), + const DrawOptions &aOptions = DrawOptions()); + virtual void StrokeLine(const Point &aStart, + const Point &aEnd, + const Pattern &aPattern, + const StrokeOptions &aStrokeOptions = StrokeOptions(), + const DrawOptions &aOptions = DrawOptions()); + virtual void Stroke(const Path *aPath, + const Pattern &aPattern, + const StrokeOptions &aStrokeOptions = StrokeOptions(), + const DrawOptions &aOptions = DrawOptions()); + virtual void Fill(const Path *aPath, + const Pattern &aPattern, + const DrawOptions &aOptions = DrawOptions()); + virtual void FillGlyphs(ScaledFont *aFont, + const GlyphBuffer &aBuffer, + const Pattern &aPattern, + const DrawOptions &aOptions = DrawOptions(), + const GlyphRenderingOptions *aRenderingOptions = nullptr); + virtual void Mask(const Pattern &aSource, + const Pattern &aMask, + const DrawOptions &aOptions = DrawOptions()); + virtual void PushClip(const Path *aPath); + virtual void PushClipRect(const Rect &aRect); + virtual void PopClip(); + + virtual void SetTransform(const Matrix &aTransform); + + virtual TemporaryRef CreateSourceSurfaceFromData(unsigned char *aData, + const IntSize &aSize, + int32_t aStride, + SurfaceFormat aFormat) const + { + return mRefDT->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat); + } + virtual TemporaryRef OptimizeSourceSurface(SourceSurface *aSurface) const + { + return mRefDT->OptimizeSourceSurface(aSurface); + } + + virtual TemporaryRef + CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const + { + return mRefDT->CreateSourceSurfaceFromNativeSurface(aSurface); + } + + virtual TemporaryRef + CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const + { + return mRefDT->CreateSimilarDrawTarget(aSize, aFormat); + } + + virtual TemporaryRef CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const + { + return mRefDT->CreatePathBuilder(aFillRule); + } + + virtual TemporaryRef + CreateGradientStops(GradientStop *aStops, + uint32_t aNumStops, + ExtendMode aExtendMode = ExtendMode::CLAMP) const + { + return mRefDT->CreateGradientStops(aStops, aNumStops, aExtendMode); + } + virtual TemporaryRef CreateFilter(FilterType aType) + { + return mRefDT->CreateFilter(aType); + } + + void ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform); + +protected: + ~DrawTargetCaptureImpl(); + +private: + + // This storage system was used to minimize the amount of heap allocations + // that are required while recording. It should be noted there's no + // guarantees on the alignments of DrawingCommands allocated in this array. + template + T* AppendToCommandList() + { + size_t oldSize = mDrawCommandStorage.size(); + mDrawCommandStorage.resize(mDrawCommandStorage.size() + sizeof(T) + sizeof(uint32_t)); + uint8_t* nextDrawLocation = &mDrawCommandStorage.front() + oldSize; + *(uint32_t*)(nextDrawLocation) = sizeof(T) + sizeof(uint32_t); + return reinterpret_cast(nextDrawLocation + sizeof(uint32_t)); + } + RefPtr mRefDT; + + IntSize mSize; + + std::vector mDrawCommandStorage; +}; + +} /* namespace mozilla */ +} /* namespace gfx */ + +#endif /* MOZILLA_GFX_DRAWTARGETCAPTURE_H_ */ diff --git a/gfx/2d/Matrix.h b/gfx/2d/Matrix.h index 2ddbf0e75d5..d360535ecc2 100644 --- a/gfx/2d/Matrix.h +++ b/gfx/2d/Matrix.h @@ -14,6 +14,11 @@ namespace mozilla { namespace gfx { +static bool FuzzyEqual(Float aV1, Float aV2) { + // XXX - Check if fabs does the smart thing and just negates the sign bit. + return fabs(aV2 - aV1) < 1e-6; +} + class Matrix { public: @@ -219,6 +224,16 @@ public: !FuzzyEqual(_12, 0.0) || !FuzzyEqual(_21, 0.0); } + /** + * Returns true if the matrix has any transform other + * than a translation or a -1 y scale (y axis flip) + */ + bool HasNonTranslationOrFlip() const { + return !FuzzyEqual(_11, 1.0) || + (!FuzzyEqual(_22, 1.0) && !FuzzyEqual(_22, -1.0)) || + !FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0); + } + /* Returns true if the matrix is an identity matrix. */ bool IsIdentity() const @@ -279,12 +294,6 @@ public: return !FuzzyEqual(_11, floor(_11 + 0.5)) || !FuzzyEqual(_22, floor(_22 + 0.5)); } - -private: - static bool FuzzyEqual(Float aV1, Float aV2) { - // XXX - Check if fabs does the smart thing and just negates the sign bit. - return fabs(aV2 - aV1) < 1e-6; - } }; class Matrix4x4 @@ -556,6 +565,85 @@ public: bool Invert(); + void ScalePost(Float aX, Float aY, Float aZ) + { + _11 *= aX; + _21 *= aX; + _31 *= aX; + _41 *= aX; + + _12 *= aY; + _22 *= aY; + _32 *= aY; + _42 *= aY; + + _13 *= aZ; + _23 *= aZ; + _33 *= aZ; + _43 *= aZ; + } + + void TranslatePost(Float aX, Float aY, Float aZ) + { + _11 += _14 * aX; + _21 += _24 * aX; + _31 += _34 * aX; + _41 += _44 * aX; + + _12 += _14 * aY; + _22 += _24 * aY; + _32 += _34 * aY; + _42 += _44 * aY; + + _13 += _14 * aZ; + _23 += _24 * aZ; + _33 += _34 * aZ; + _43 += _44 * aZ; + } + + bool FuzzyEqual(const Matrix4x4& o) const + { + return gfx::FuzzyEqual(_11, o._11) && gfx::FuzzyEqual(_12, o._12) && + gfx::FuzzyEqual(_13, o._13) && gfx::FuzzyEqual(_14, o._14) && + gfx::FuzzyEqual(_21, o._21) && gfx::FuzzyEqual(_22, o._22) && + gfx::FuzzyEqual(_23, o._23) && gfx::FuzzyEqual(_24, o._24) && + gfx::FuzzyEqual(_31, o._31) && gfx::FuzzyEqual(_32, o._32) && + gfx::FuzzyEqual(_33, o._33) && gfx::FuzzyEqual(_34, o._34) && + gfx::FuzzyEqual(_41, o._41) && gfx::FuzzyEqual(_42, o._42) && + gfx::FuzzyEqual(_43, o._43) && gfx::FuzzyEqual(_44, o._44); + } + + bool IsBackfaceVisible() const + { + // Inverse()._33 < 0; + Float det = Determinant(); + Float __33 = _12*_24*_41 - _14*_22*_41 + + _14*_21*_42 - _11*_24*_42 - + _12*_21*_44 + _11*_22*_44; + return (__33 * det) < 0; + } + + void NudgeToIntegersFixedEpsilon() + { + static const float error = 1e-5f; + NudgeToInteger(&_11, error); + NudgeToInteger(&_12, error); + NudgeToInteger(&_13, error); + NudgeToInteger(&_14, error); + NudgeToInteger(&_21, error); + NudgeToInteger(&_22, error); + NudgeToInteger(&_23, error); + NudgeToInteger(&_24, error); + NudgeToInteger(&_31, error); + NudgeToInteger(&_32, error); + NudgeToInteger(&_33, error); + NudgeToInteger(&_34, error); + NudgeToInteger(&_41, error); + NudgeToInteger(&_42, error); + NudgeToInteger(&_43, error); + NudgeToInteger(&_44, error); + } + // Set all the members of the matrix to NaN void SetNAN(); }; diff --git a/gfx/2d/SourceSurfaceRawData.cpp b/gfx/2d/SourceSurfaceRawData.cpp index 0f7b06da7f9..92be3baa33b 100644 --- a/gfx/2d/SourceSurfaceRawData.cpp +++ b/gfx/2d/SourceSurfaceRawData.cpp @@ -28,6 +28,20 @@ SourceSurfaceRawData::InitWrappingData(uint8_t *aData, return true; } +void +SourceSurfaceRawData::GuaranteePersistance() +{ + if (mOwnData) { + return; + } + + uint8_t* oldData = mRawData; + mRawData = new uint8_t[mStride * mSize.height]; + + memcpy(mRawData, oldData, mStride * mSize.height); + mOwnData = true; +} + bool SourceSurfaceAlignedRawData::Init(const IntSize &aSize, SurfaceFormat aFormat) diff --git a/gfx/2d/SourceSurfaceRawData.h b/gfx/2d/SourceSurfaceRawData.h index 9d1e7d6e036..13fd2f0c55b 100644 --- a/gfx/2d/SourceSurfaceRawData.h +++ b/gfx/2d/SourceSurfaceRawData.h @@ -32,6 +32,8 @@ public: SurfaceFormat aFormat, bool aOwnData); + virtual void GuaranteePersistance(); + private: uint8_t *mRawData; int32_t mStride; diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build index a11c3e52983..8bc8c23f282 100644 --- a/gfx/2d/moz.build +++ b/gfx/2d/moz.build @@ -97,7 +97,9 @@ UNIFIED_SOURCES += [ 'DataSourceSurface.cpp', 'DataSurfaceHelpers.cpp', 'DrawEventRecorder.cpp', + 'DrawTarget.cpp', 'DrawTargetCairo.cpp', + 'DrawTargetCapture.cpp', 'DrawTargetDual.cpp', 'DrawTargetRecording.cpp', 'DrawTargetTiled.cpp', diff --git a/gfx/gl/DecomposeIntoNoRepeatTriangles.h b/gfx/gl/DecomposeIntoNoRepeatTriangles.h index 3f99d42e678..2023afbf08d 100644 --- a/gfx/gl/DecomposeIntoNoRepeatTriangles.h +++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h @@ -10,7 +10,6 @@ #include "GLTypes.h" #include "nsRect.h" #include "nsTArray.h" -#include "gfx3DMatrix.h" namespace mozilla { namespace gl { diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 132e557047d..c502386962d 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -29,7 +29,6 @@ #include "GLDefs.h" #include "GLLibraryLoader.h" -#include "gfx3DMatrix.h" #include "nsISupportsImpl.h" #include "plstr.h" #include "nsDataHashtable.h" diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index c45968df289..38edaeaaa29 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -13,11 +13,11 @@ #include -#include "gfx3DMatrix.h" #include "gfxColor.h" #include "mozilla/gfx/Matrix.h" #include "GraphicsFilter.h" #include "gfxPoint.h" +#include "gfxPoint3D.h" #include "gfxRect.h" #include "nsRect.h" #include "nsRegion.h" @@ -217,32 +217,6 @@ struct ParamTraits } }; -template<> -struct ParamTraits -{ - typedef gfx3DMatrix paramType; - - static void Write(Message* msg, const paramType& param) - { -#define Wr(_f) WriteParam(msg, param. _f) - Wr(_11); Wr(_12); Wr(_13); Wr(_14); - Wr(_21); Wr(_22); Wr(_23); Wr(_24); - Wr(_31); Wr(_32); Wr(_33); Wr(_34); - Wr(_41); Wr(_42); Wr(_43); Wr(_44); -#undef Wr - } - - static bool Read(const Message* msg, void** iter, paramType* result) - { -#define Rd(_f) ReadParam(msg, iter, &result-> _f) - return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) && - Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) && - Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) && - Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44)); -#undef Rd - } -}; - template <> struct ParamTraits : public ContiguousTypedEnumSerializer< diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index dc58cbcb237..d2bba6b3db3 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -8,7 +8,6 @@ #include "ImageContainer.h" // for ImageContainer #include "ImageLayers.h" // for ImageLayer, etc #include "Layers.h" // for Layer, ContainerLayer, etc -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxColor.h" // for gfxRGBA #include "GraphicsFilter.h" // for GraphicsFilter #include "gfxPoint3D.h" // for gfxPoint3D @@ -26,6 +25,8 @@ #include "nsRect.h" // for nsIntRect #include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl +using namespace mozilla::gfx; + namespace mozilla { namespace layers { @@ -33,18 +34,18 @@ struct LayerPropertiesBase; LayerPropertiesBase* CloneLayerTreePropertiesInternal(Layer* aRoot); static nsIntRect -TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform) +TransformRect(const nsIntRect& aRect, const Matrix4x4& aTransform) { if (aRect.IsEmpty()) { return nsIntRect(); } - gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height); + Rect rect(aRect.x, aRect.y, aRect.width, aRect.height); rect = aTransform.TransformBounds(rect); rect.RoundOut(); nsIntRect intRect; - if (!gfxUtils::GfxRectToIntRect(rect, &intRect)) { + if (!gfxUtils::GfxRectToIntRect(ThebesRect(rect), &intRect)) { return nsIntRect(); } @@ -52,7 +53,7 @@ TransformRect(const nsIntRect& aRect, const gfx3DMatrix& aTransform) } static void -AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const gfx3DMatrix& aTransform) +AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform) { nsIntRegionRectIterator iter(aSource); const nsIntRect *r; @@ -114,7 +115,7 @@ struct LayerPropertiesBase : public LayerProperties if (mUseClipRect) { mClipRect = *aLayer->GetClipRect(); } - mTransform = gfx::To3DMatrix(aLayer->GetTransform()); + mTransform = aLayer->GetTransform(); } LayerPropertiesBase() : mLayer(nullptr) @@ -136,8 +137,7 @@ struct LayerPropertiesBase : public LayerProperties nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback, bool& aGeometryChanged) { - gfx3DMatrix transform = gfx::To3DMatrix(mLayer->GetTransform()); - bool transformChanged = !mTransform.FuzzyEqual(transform) || + bool transformChanged = !mTransform.FuzzyEqual(mLayer->GetTransform()) || mLayer->GetPostXScale() != mPostXScale || mLayer->GetPostYScale() != mPostYScale; Layer* otherMask = mLayer->GetMaskLayer(); @@ -184,8 +184,7 @@ struct LayerPropertiesBase : public LayerProperties nsIntRect NewTransformedBounds() { - return TransformRect(mLayer->GetVisibleRegion().GetBounds(), - gfx::To3DMatrix(mLayer->GetTransform())); + return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetTransform()); } nsIntRect OldTransformedBounds() @@ -203,7 +202,7 @@ struct LayerPropertiesBase : public LayerProperties nsAutoPtr mMaskLayer; nsIntRegion mVisibleRegion; nsIntRegion mInvalidRegion; - gfx3DMatrix mTransform; + Matrix4x4 mTransform; float mPostXScale; float mPostYScale; float mOpacity; @@ -292,8 +291,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase } if (invalidateChildsCurrentArea) { aGeometryChanged = true; - AddTransformedRegion(result, child->GetVisibleRegion(), - gfx::To3DMatrix(child->GetTransform())); + AddTransformedRegion(result, child->GetVisibleRegion(), child->GetTransform()); if (aCallback) { NotifySubdocumentInvalidationRecursive(child, aCallback); } else { @@ -442,8 +440,8 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu } else { ClearInvalidations(aRoot); } - gfx3DMatrix transform = gfx::To3DMatrix(aRoot->GetTransform()); - nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), transform); + nsIntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(), + aRoot->GetTransform()); result = result.Union(OldTransformedBounds()); if (aGeometryChanged != nullptr) { *aGeometryChanged = true; @@ -458,11 +456,11 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu return invalid; } } - -void + +void LayerPropertiesBase::MoveBy(const nsIntPoint& aOffset) { - mTransform.TranslatePost(gfxPoint3D(aOffset.x, aOffset.y, 0)); + mTransform.TranslatePost(aOffset.x, aOffset.y, 0); } } // namespace layers diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index a3278ab685a..90cd6094cec 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -7,7 +7,6 @@ #include "LayersLogging.h" #include // for uint8_t -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxColor.h" // for gfxRGBA #include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix #include "nsDebug.h" // for NS_ERROR diff --git a/gfx/layers/ReadbackProcessor.cpp b/gfx/layers/ReadbackProcessor.cpp index 7996eb35298..b534a07ccb1 100644 --- a/gfx/layers/ReadbackProcessor.cpp +++ b/gfx/layers/ReadbackProcessor.cpp @@ -7,7 +7,6 @@ #include // for int32_t #include "Layers.h" // for Layer, ThebesLayer, etc #include "ReadbackLayer.h" // for ReadbackLayer, ReadbackSink -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxColor.h" // for gfxRGBA #include "gfxContext.h" // for gfxContext #include "gfxRect.h" // for gfxRect diff --git a/gfx/layers/RenderTrace.cpp b/gfx/layers/RenderTrace.cpp index 15947e49feb..6ac1e8130c1 100644 --- a/gfx/layers/RenderTrace.cpp +++ b/gfx/layers/RenderTrace.cpp @@ -24,14 +24,14 @@ static gfx::Matrix4x4 GetRootTransform(Layer *aLayer) { return layerTrans; } -void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform, bool aReset) { +void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset) { if (!aLayer) return; - gfx3DMatrix trans = aRootTransform * aLayer->GetTransform(); + gfx::Matrix4x4 trans = aRootTransform * aLayer->GetTransform(); trans.ProjectTo2D(); nsIntRect clipRect = aLayer->GetEffectiveVisibleRegion().GetBounds(); - gfxRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); + Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); trans.TransformBounds(rect); if (strcmp(aLayer->Name(), "ContainerLayer") != 0 && diff --git a/gfx/layers/RenderTrace.h b/gfx/layers/RenderTrace.h index 335597f602f..01d1b213284 100644 --- a/gfx/layers/RenderTrace.h +++ b/gfx/layers/RenderTrace.h @@ -15,15 +15,15 @@ #ifndef GFX_RENDERTRACE_H #define GFX_RENDERTRACE_H -#include "gfx3DMatrix.h" #include "nsRect.h" +#include "mozilla/gfx/Matrix.h" namespace mozilla { namespace layers { class Layer; -void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform = gfx3DMatrix(), bool aReset = true); +void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform = gfx::Matrix4x4(), bool aReset = true); void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect); void RenderTraceInvalidateEnd(Layer *aLayer, const char *aColor); @@ -49,7 +49,7 @@ private: }; #ifndef MOZ_RENDERTRACE -inline void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx3DMatrix aRootTransform, bool aReset) +inline void RenderTraceLayers(Layer *aLayer, const char *aColor, const gfx::Matrix4x4 aRootTransform, bool aReset) {} inline void RenderTraceInvalidateStart(Layer *aLayer, const char *aColor, const nsIntRect aRect) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 6e931668d3d..f77fc5afdd8 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -8,7 +8,6 @@ #include "CompositorParent.h" // for CompositorParent, etc #include "InputData.h" // for InputData, etc #include "Layers.h" // for ContainerLayer, Layer, etc -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "mozilla/dom/Touch.h" // for Touch #include "mozilla/gfx/Point.h" // for Point #include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform @@ -32,6 +31,9 @@ namespace mozilla { namespace layers { +typedef mozilla::gfx::Point Point; +typedef mozilla::gfx::Matrix4x4 Matrix4x4; + float APZCTreeManager::sDPI = 160.0; APZCTreeManager::APZCTreeManager() @@ -139,7 +141,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, aRoot, // aCompositor is null in gtest scenarios aCompositor ? aCompositor->RootLayerTreeId() : 0, - gfx3DMatrix(), nullptr, nullptr, + Matrix4x4(), nullptr, nullptr, aIsFirstPaint, aOriginatingLayersId, paintLogger, &apzcsToDestroy, nsIntRegion()); mApzcTreeLog << "[end]\n"; @@ -154,7 +156,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, AsyncPanZoomController* APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Layer* aLayer, uint64_t aLayersId, - gfx3DMatrix aTransform, + Matrix4x4 aTransform, AsyncPanZoomController* aParent, AsyncPanZoomController* aNextSibling, bool aIsFirstPaint, @@ -165,7 +167,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, { mTreeLock.AssertCurrentThreadOwns(); - gfx3DMatrix transform = gfx::To3DMatrix(aLayer->GetTransform()); + Matrix4x4 transform = aLayer->GetTransform(); ContainerLayer* container = aLayer->AsContainerLayer(); AsyncPanZoomController* apzc = nullptr; @@ -320,7 +322,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // Accumulate the CSS transform between layers that have an APZC, but exclude any // any layers that do have an APZC, and reset the accumulation at those layers. if (apzc) { - aTransform = gfx3DMatrix(); + aTransform = Matrix4x4(); } else { // Multiply child layer transforms on the left so they get applied first aTransform = transform * aTransform; @@ -342,7 +344,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // have to check for mask layers and so on in order to properly handle // that case. obscured = aObscured; - obscured.Transform(transform.Inverse()); + obscured.Transform(To3DMatrix(transform).Inverse()); } // If there's no APZC at this level, any APZCs for our child layers will @@ -379,25 +381,25 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, } /*static*/ template void -ApplyTransform(gfx::PointTyped* aPoint, const gfx3DMatrix& aMatrix) +ApplyTransform(gfx::PointTyped* aPoint, const Matrix4x4& aMatrix) { - gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y)); + Point result = aMatrix * aPoint->ToUnknownPoint(); aPoint->x = result.x; aPoint->y = result.y; } /*static*/ template void -ApplyTransform(gfx::IntPointTyped* aPoint, const gfx3DMatrix& aMatrix) +ApplyTransform(gfx::IntPointTyped* aPoint, const Matrix4x4& aMatrix) { - gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y)); - aPoint->x = NS_lround(result.x); - aPoint->y = NS_lround(result.y); + Point result = aMatrix * aPoint->ToUnknownPoint(); + aPoint->x = result.x; + aPoint->y = result.y; } /*static*/ void -ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix) +ApplyTransform(nsIntPoint* aPoint, const Matrix4x4& aMatrix) { - gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y)); + Point result = aMatrix * Point(aPoint->x, aPoint->y); aPoint->x = NS_lround(result.x); aPoint->y = NS_lround(result.y); } @@ -405,7 +407,7 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix) /*static*/ template void TransformScreenToGecko(T* aPoint, AsyncPanZoomController* aApzc, APZCTreeManager* aApzcTm) { - gfx3DMatrix transformToApzc, transformToGecko; + Matrix4x4 transformToApzc, transformToGecko; aApzcTm->GetInputTransforms(aApzc, transformToApzc, transformToGecko); ApplyTransform(aPoint, transformToApzc * transformToGecko); } @@ -415,8 +417,8 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent, ScrollableLayerGuid* aOutTargetGuid) { nsEventStatus result = nsEventStatus_eIgnore; - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; switch (aEvent.mInputType) { case MULTITOUCH_INPUT: { MultiTouchInput& touchInput = aEvent.AsMultiTouchInput(); @@ -560,11 +562,11 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput, if (mApzcForInputBlock) { // Cache apz transform so it can be used for future events in this block. - gfx3DMatrix transformToGecko; + Matrix4x4 transformToGecko; GetInputTransforms(mApzcForInputBlock, mCachedTransformToApzcForInputBlock, transformToGecko); } else { // Reset the cached apz transform - mCachedTransformToApzcForInputBlock = gfx3DMatrix(); + mCachedTransformToApzcForInputBlock = Matrix4x4(); } } else if (mApzcForInputBlock) { APZCTM_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get()); @@ -597,7 +599,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput, // For computing the input for the APZC, used the cached transform. // This ensures that the sequence of touch points an APZC sees in an // input block are all in the same coordinate space. - gfx3DMatrix transformToApzc = mCachedTransformToApzcForInputBlock; + Matrix4x4 transformToApzc = mCachedTransformToApzcForInputBlock; MultiTouchInput inputForApzc(aInput); for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) { ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc); @@ -607,9 +609,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput, // For computing the event to pass back to Gecko, use the up-to-date transforms. // This ensures that transformToApzc and transformToGecko are in sync // (note that transformToGecko isn't cached). - gfx3DMatrix transformToGecko; + Matrix4x4 transformToGecko; GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko); - gfx3DMatrix outTransform = transformToApzc * transformToGecko; + Matrix4x4 outTransform = transformToApzc * transformToGecko; for (size_t i = 0; i < aInput.mTouches.Length(); i++) { ApplyTransform(&(aInput.mTouches[i].mScreenPoint), outTransform); } @@ -650,10 +652,10 @@ APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint, MOZ_ASSERT(aOutTransformedPoint); nsRefPtr apzc = GetTargetAPZC(aPoint, nullptr); if (apzc && aOutTransformedPoint) { - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; GetInputTransforms(apzc, transformToApzc, transformToGecko); - gfx3DMatrix outTransform = transformToApzc * transformToGecko; + Matrix4x4 outTransform = transformToApzc * transformToGecko; aOutTransformedPoint->x = aPoint.x; aOutTransformedPoint->y = aPoint.y; ApplyTransform(aOutTransformedPoint, outTransform); @@ -673,10 +675,10 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent, &inOverscrolledApzc); if (apzc) { apzc->GetGuid(aOutTargetGuid); - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; GetInputTransforms(apzc, transformToApzc, transformToGecko); - gfx3DMatrix outTransform = transformToApzc * transformToGecko; + Matrix4x4 outTransform = transformToApzc * transformToGecko; ApplyTransform(&(aEvent.refPoint), outTransform); } return inOverscrolledApzc ? nsEventStatus_eConsumeNoDefault @@ -805,13 +807,15 @@ TransformDisplacement(APZCTreeManager* aTreeManager, AsyncPanZoomController* aTarget, ScreenPoint& aStartPoint, ScreenPoint& aEndPoint) { - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; // ignored + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; // ignored // Convert start and end points to untransformed screen coordinates. aTreeManager->GetInputTransforms(aSource, transformToApzc, transformToGecko); - ApplyTransform(&aStartPoint, transformToApzc.Inverse()); - ApplyTransform(&aEndPoint, transformToApzc.Inverse()); + Matrix4x4 untransformToApzc = transformToApzc; + untransformToApzc.Invert(); + ApplyTransform(&aStartPoint, untransformToApzc); + ApplyTransform(&aEndPoint, untransformToApzc); // Convert start and end points to aTarget's transformed screen coordinates. aTreeManager->GetInputTransforms(aTarget, transformToApzc, transformToGecko); @@ -1183,12 +1187,13 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, // to aApzc's parent layer's layer coordinates. // It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L, // and RC.Inverse() * QC.Inverse() at recursion level for P. - gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse(); + Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform(); + ancestorUntransform.Invert(); // Hit testing for this layer takes place in our parent layer coordinates, // since the composition bounds (used to initialize the visible rect against // which we hit test are in those coordinates). - gfxPointH3D hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint); + gfxPointH3D hitTestPointForThisLayer = To3DMatrix(ancestorUntransform).ProjectPoint(aHitTestPoint); APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc); @@ -1197,10 +1202,12 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, // to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates). // It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L // and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P. - gfx3DMatrix childUntransform = ancestorUntransform - * aApzc->GetCSSTransform().Inverse() - * gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse(); - gfxPointH3D hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint); + Matrix4x4 cssUntransform = aApzc->GetCSSTransform(); + cssUntransform.Invert(); + Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform(); + asyncUntransform.Invert(); + Matrix4x4 childUntransform = ancestorUntransform * cssUntransform * asyncUntransform; + gfxPointH3D hitTestPointForChildLayers = To3DMatrix(childUntransform).ProjectPoint(aHitTestPoint); APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc); @@ -1333,8 +1340,8 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, required can be generated. */ void -APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut, - gfx3DMatrix& aTransformToGeckoOut) +APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, Matrix4x4& aTransformToApzcOut, + Matrix4x4& aTransformToGeckoOut) { MonitorAutoLock lock(mTreeLock); @@ -1345,26 +1352,36 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& // leftmost matrix in a multiplication is applied first. // ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse() - gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse(); + Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform(); + ancestorUntransform.Invert(); // asyncUntransform is LA.Inverse() - gfx3DMatrix asyncUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse(); + Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform(); + asyncUntransform.Invert(); // nontransientAsyncTransform is LN - gfx3DMatrix nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform(); + Matrix4x4 nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform(); // transientAsyncUntransform is LT.Inverse() - gfx3DMatrix transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform; + Matrix4x4 transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform; // aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() - aTransformToApzcOut = ancestorUntransform * aApzc->GetCSSTransform().Inverse() * nontransientAsyncTransform.Inverse(); + Matrix4x4 cssUntransform = aApzc->GetCSSTransform(); + cssUntransform.Invert(); + Matrix4x4 nontransientAsyncUntransform = nontransientAsyncTransform; + nontransientAsyncUntransform.Invert(); + aTransformToApzcOut = ancestorUntransform * cssUntransform * nontransientAsyncUntransform; // aTransformToGeckoOut is initialized to LT.Inverse() * LD * LC * MC * NC * OC aTransformToGeckoOut = transientAsyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetCSSTransform() * aApzc->GetAncestorTransform(); for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) { // ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P - ancestorUntransform = parent->GetAncestorTransform().Inverse(); + ancestorUntransform = parent->GetAncestorTransform(); + ancestorUntransform.Invert(); // asyncUntransform is updated to PA.Inverse() when parent == P - asyncUntransform = gfx3DMatrix(parent->GetCurrentAsyncTransform()).Inverse(); + asyncUntransform = parent->GetCurrentAsyncTransform(); + asyncUntransform.Invert(); // untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() - gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * parent->GetCSSTransform().Inverse() * asyncUntransform; + cssUntransform = parent->GetCSSTransform(); + cssUntransform.Invert(); + Matrix4x4 untransformSinceLastApzc = ancestorUntransform * cssUntransform * asyncUntransform; // aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut; diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index 449c52dc46d..530b5aa8268 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -10,10 +10,10 @@ #include "FrameMetrics.h" // for FrameMetrics, etc #include "Units.h" // for CSSPoint, CSSRect, etc #include "gfxPoint.h" // for gfxPoint -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "mozilla/EventForwards.h" // for WidgetInputEvent, nsEventStatus #include "mozilla/Monitor.h" // for Monitor +#include "mozilla/gfx/Matrix.h" // for Matrix4x4 #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMPtr.h" // for already_AddRefed #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc @@ -21,7 +21,6 @@ #include "nsTArrayForwardDeclare.h" // for nsTArray, nsTArray_Impl, etc #include "mozilla/gfx/Logging.h" // for gfx::TreeLog -class gfx3DMatrix; class nsIntRegion; namespace mozilla { @@ -327,8 +326,8 @@ public: already_AddRefed GetTargetAPZC(const ScrollableLayerGuid& aGuid); already_AddRefed GetTargetAPZC(const ScreenPoint& aPoint, bool* aOutInOverscrolledApzc); - void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut, - gfx3DMatrix& aTransformToGeckoOut); + void GetInputTransforms(AsyncPanZoomController *aApzc, gfx::Matrix4x4& aTransformToApzcOut, + gfx::Matrix4x4& aTransformToGeckoOut); private: /* Helpers */ AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, FrameMetrics::ViewID aScrollId); @@ -358,7 +357,7 @@ private: */ AsyncPanZoomController* UpdatePanZoomControllerTree(CompositorParent* aCompositor, Layer* aLayer, uint64_t aLayersId, - gfx3DMatrix aTransform, + gfx::Matrix4x4 aTransform, AsyncPanZoomController* aParent, AsyncPanZoomController* aNextSibling, bool aIsFirstPaint, @@ -401,7 +400,7 @@ private: * but for some operations we need to use the initial transform. * Meaningless if mApzcForInputBlock is nullptr. */ - gfx3DMatrix mCachedTransformToApzcForInputBlock; + gfx::Matrix4x4 mCachedTransformToApzcForInputBlock; /* The chain of APZCs that will handle pans for the current touch input * block, in the order in which they will be scrolled. When one APZC has * been scrolled as far as it can, any overscroll will be handed off to diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index 56128676ac7..fa5cdc1bc58 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -130,6 +130,8 @@ namespace layers { typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior; typedef GeckoContentController::APZStateChange APZStateChange; +typedef mozilla::gfx::Point Point; +typedef mozilla::gfx::Matrix4x4 Matrix4x4; /* * The following prefs are used to control the behaviour of the APZC. @@ -1293,10 +1295,10 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut { APZCTreeManager* treeManagerLocal = mTreeManager; if (treeManagerLocal) { - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; treeManagerLocal->GetInputTransforms(this, transformToApzc, transformToGecko); - gfxPoint result = transformToGecko.Transform(gfxPoint(aPoint.x, aPoint.y)); + Point result = transformToGecko * Point(aPoint.x, aPoint.y); // NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name // for this coordinate space and it maps the closest to LayoutDevicePoint. LayoutDevicePoint layoutPoint = LayoutDevicePoint(result.x, result.y); @@ -2300,20 +2302,20 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() { / mFrameMetrics.GetParentResolution()); } -gfx3DMatrix AsyncPanZoomController::GetNontransientAsyncTransform() { +Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() { ReentrantMonitorAutoEnter lock(mMonitor); - return gfx3DMatrix::ScalingMatrix(mLastContentPaintMetrics.mResolution.scale, - mLastContentPaintMetrics.mResolution.scale, - 1.0f); + return Matrix4x4().Scale(mLastContentPaintMetrics.mResolution.scale, + mLastContentPaintMetrics.mResolution.scale, + 1.0f); } -gfx3DMatrix AsyncPanZoomController::GetTransformToLastDispatchedPaint() { +Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() { ReentrantMonitorAutoEnter lock(mMonitor); LayerPoint scrollChange = (mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset()) * mLastContentPaintMetrics.LayersPixelsPerCSSPixel(); float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale; - return gfx3DMatrix::Translation(scrollChange.x, scrollChange.y, 0) * - gfx3DMatrix::ScalingMatrix(zoomChange, zoomChange, 1); + return Matrix4x4().Translate(scrollChange.x, scrollChange.y, 0) * + Matrix4x4().Scale(zoomChange, zoomChange, 1); } void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) { @@ -2861,16 +2863,16 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() { ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint) { - return TransformTo(GetNontransientAsyncTransform() * GetCSSTransform(), aPoint); + return TransformTo(To3DMatrix(GetNontransientAsyncTransform() * GetCSSTransform()), aPoint); } void AsyncPanZoomController::UpdateTransformScale() { - gfx3DMatrix nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform(); - if (!FuzzyEqualsMultiplicative(nontransientTransforms.GetXScale(), nontransientTransforms.GetYScale())) { + Matrix4x4 nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform(); + if (!FuzzyEqualsMultiplicative(nontransientTransforms._11, nontransientTransforms._22)) { NS_WARNING("The x- and y-scales of the nontransient transforms should be equal"); } - mFrameMetrics.mTransformScale.scale = nontransientTransforms.GetXScale(); + mFrameMetrics.mTransformScale.scale = nontransientTransforms._11; } } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index db09163d102..732a6c592b5 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -20,7 +20,7 @@ #include "InputData.h" #include "Axis.h" #include "TaskThrottler.h" -#include "gfx3DMatrix.h" +#include "mozilla/gfx/Matrix.h" #include "nsRegion.h" #include "base/message_loop.h" @@ -69,6 +69,7 @@ class AsyncPanZoomController { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController) typedef mozilla::MonitorAutoLock MonitorAutoLock; + typedef mozilla::gfx::Matrix4x4 Matrix4x4; typedef uint32_t TouchBehaviorFlags; public: @@ -221,9 +222,9 @@ public: /** * Returns the part of the async transform that will remain once Gecko does a * repaint at the desired metrics. That is, in the steady state: - * gfx3DMatrix(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform() + * Matrix4x4(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform() */ - gfx3DMatrix GetNontransientAsyncTransform(); + Matrix4x4 GetNontransientAsyncTransform(); /** * Returns the transform to take something from the coordinate space of the @@ -232,7 +233,7 @@ public: * processed, this is needed to transform input events properly into a space * gecko will understand. */ - gfx3DMatrix GetTransformToLastDispatchedPaint(); + Matrix4x4 GetTransformToLastDispatchedPaint(); /** * Recalculates the displayport. Ideally, this should paint an area bigger @@ -942,19 +943,19 @@ private: * hit-testing to see which APZC instance should handle touch events. */ public: - void SetLayerHitTestData(const nsIntRegion& aRegion, const gfx3DMatrix& aTransformToLayer, - const gfx3DMatrix& aTransformForLayer) { + void SetLayerHitTestData(const nsIntRegion& aRegion, const Matrix4x4& aTransformToLayer, + const Matrix4x4& aTransformForLayer) { mVisibleRegion = aRegion; mAncestorTransform = aTransformToLayer; mCSSTransform = aTransformForLayer; UpdateTransformScale(); } - gfx3DMatrix GetAncestorTransform() const { + Matrix4x4 GetAncestorTransform() const { return mAncestorTransform; } - gfx3DMatrix GetCSSTransform() const { + Matrix4x4 GetCSSTransform() const { return mCSSTransform; } @@ -974,9 +975,9 @@ private: nsIntRegion mVisibleRegion; /* This is the cumulative CSS transform for all the layers between the parent * APZC and this one (not inclusive) */ - gfx3DMatrix mAncestorTransform; + Matrix4x4 mAncestorTransform; /* This is the CSS transform for this APZC's layer. */ - gfx3DMatrix mCSSTransform; + Matrix4x4 mCSSTransform; /* =================================================================== diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp index 190b9518d5a..004c174d86e 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.cpp +++ b/gfx/layers/client/ClientTiledThebesLayer.cpp @@ -7,7 +7,6 @@ #include "Units.h" // for ScreenIntRect, CSSPoint, etc #include "UnitTransforms.h" // for TransformTo #include "ClientLayerManager.h" // for ClientLayerManager, etc -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxPlatform.h" // for gfxPlatform #include "gfxPrefs.h" // for gfxPrefs #include "gfxRect.h" // for gfxRect @@ -58,12 +57,12 @@ ClientTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) } static LayerRect -ApplyParentLayerToLayerTransform(const gfx3DMatrix& aTransform, const ParentLayerRect& aParentLayerRect) +ApplyParentLayerToLayerTransform(const gfx::Matrix4x4& aTransform, const ParentLayerRect& aParentLayerRect) { - return TransformTo(aTransform, aParentLayerRect); + return TransformTo(gfx::To3DMatrix(aTransform), aParentLayerRect); } -static gfx3DMatrix +static gfx::Matrix4x4 GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor) { gfx::Matrix4x4 transform; @@ -77,7 +76,7 @@ GetTransformToAncestorsParentLayer(Layer* aStart, Layer* aAncestor) } transform = transform * iter->GetTransform(); } - return gfx::To3DMatrix(transform); + return transform; } void @@ -145,8 +144,9 @@ ClientTiledThebesLayer::BeginPaint() // Calculate the transform required to convert ParentLayer space of our // display port ancestor to the Layer space of this layer. - gfx3DMatrix transformDisplayPortToLayer = - GetTransformToAncestorsParentLayer(this, displayPortAncestor).Inverse(); + gfx::Matrix4x4 transformDisplayPortToLayer = + GetTransformToAncestorsParentLayer(this, displayPortAncestor); + transformDisplayPortToLayer.Invert(); // Note that below we use GetZoomToParent() in a number of places. Because this // code runs on the client side, the mTransformScale field of the FrameMetrics @@ -171,8 +171,10 @@ ClientTiledThebesLayer::BeginPaint() // Store the applicable composition bounds in this layer's Layer units. mPaintData.mTransformToCompBounds = GetTransformToAncestorsParentLayer(this, scrollAncestor); + gfx::Matrix4x4 transformToBounds = mPaintData.mTransformToCompBounds; + transformToBounds.Invert(); mPaintData.mCompositionBounds = ApplyParentLayerToLayerTransform( - mPaintData.mTransformToCompBounds.Inverse(), scrollMetrics.mCompositionBounds); + transformToBounds, scrollMetrics.mCompositionBounds); TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str()); // Calculate the scroll offset since the last transaction diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 4e8f7e445a3..552e09284d8 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1126,30 +1126,31 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile, */ static LayerRect GetCompositorSideCompositionBounds(ContainerLayer* aScrollAncestor, - const gfx3DMatrix& aTransformToCompBounds, + const Matrix4x4& aTransformToCompBounds, const ViewTransform& aAPZTransform) { - gfx3DMatrix nonTransientAPZTransform = gfx3DMatrix::ScalingMatrix( + Matrix4x4 nonTransientAPZUntransform = Matrix4x4().Scale( aScrollAncestor->GetFrameMetrics().mResolution.scale, aScrollAncestor->GetFrameMetrics().mResolution.scale, 1.f); + nonTransientAPZUntransform.Invert(); - gfx3DMatrix layerTransform = gfx::To3DMatrix(aScrollAncestor->GetTransform()); + Matrix4x4 layerTransform = aScrollAncestor->GetTransform(); + Matrix4x4 layerUntransform = layerTransform; + layerUntransform.Invert(); // First take off the last two "terms" of aTransformToCompBounds, which // are the scroll ancestor's local transform and the APZ's nontransient async // transform. - gfx3DMatrix transform = aTransformToCompBounds; - transform = transform * layerTransform.Inverse(); - transform = transform * nonTransientAPZTransform.Inverse(); + Matrix4x4 transform = aTransformToCompBounds * layerUntransform * nonTransientAPZUntransform; // Next, apply the APZ's async transform (this includes the nontransient component // as well). - transform = transform * gfx3DMatrix(aAPZTransform); + transform = transform * Matrix4x4(aAPZTransform); // Finally, put back the scroll ancestor's local transform. transform = transform * layerTransform; - return TransformTo(transform.Inverse(), + return TransformTo(To3DMatrix(transform).Inverse(), aScrollAncestor->GetFrameMetrics().mCompositionBounds); } diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index 501eb375f8e..eabdef0d562 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -12,7 +12,6 @@ #include "Layers.h" // for LayerManager, etc #include "TiledLayerBuffer.h" // for TiledLayerBuffer #include "Units.h" // for CSSPoint -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxTypes.h" #include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/RefPtr.h" // for RefPtr @@ -289,7 +288,7 @@ struct BasicTiledLayerPaintData { * the closest ancestor layer which scrolls, and is used to obtain * the composition bounds that are relevant for this layer. */ - gfx3DMatrix mTransformToCompBounds; + gfx::Matrix4x4 mTransformToCompBounds; /* * The critical displayport of the content from the nearest ancestor layer diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index c6f4885047c..0462bffdb8d 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -509,9 +509,9 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint) } Matrix4x4 -AdjustAndCombineWithCSSTransform(const gfx3DMatrix& asyncTransform, Layer* aLayer) +AdjustAndCombineWithCSSTransform(const Matrix4x4& asyncTransform, Layer* aLayer) { - Matrix4x4 result = ToMatrix4x4(asyncTransform); + Matrix4x4 result = asyncTransform; // Container layers start at the origin, but they are clipped to where they // actually have content on the screen. The tree transform is meant to apply @@ -675,9 +675,11 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer apzc->SampleContentTransformForFrame(aCurrentFrame, &asyncTransform, scrollOffset); } - gfx3DMatrix asyncTransform = gfx3DMatrix(apzc->GetCurrentAsyncTransform()); - gfx3DMatrix nontransientTransform = apzc->GetNontransientAsyncTransform(); - gfx3DMatrix transientTransform = asyncTransform * nontransientTransform.Inverse(); + Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform(); + Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform(); + Matrix4x4 nontransientUntransform = nontransientTransform; + nontransientUntransform.Invert(); + Matrix4x4 transientTransform = asyncTransform * nontransientUntransform; // |transientTransform| represents the amount by which we have scrolled and // zoomed since the last paint. Because the scrollbar was sized and positioned based @@ -695,12 +697,12 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer Matrix4x4 scrollbarTransform; if (aScrollbar->GetScrollbarDirection() == Layer::VERTICAL) { float scale = metrics.CalculateCompositedSizeInCssPixels().height / metrics.mScrollableRect.height; - scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f, 1.f / transientTransform.GetYScale(), 1.f); + scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f, 1.f / transientTransform._22, 1.f); scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(0, -transientTransform._42 * scale, 0); } if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) { float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.mScrollableRect.width; - scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f / transientTransform.GetXScale(), 1.f, 1.f); + scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f / transientTransform._11, 1.f, 1.f); scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(-transientTransform._41 * scale, 0, 0); } @@ -712,7 +714,8 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer // the content. This is needed because otherwise that transient async transform is // part of the effective transform of this scrollbar, and the scrollbar will jitter // as the content scrolls. - transform = transform * ToMatrix4x4(transientTransform.Inverse()); + transientTransform.Invert(); + transform = transform * transientTransform; } // GetTransform already takes the pre- and post-scale into account. Since we @@ -780,11 +783,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) const FrameMetrics& metrics = container->GetFrameMetrics(); // We must apply the resolution scale before a pan/zoom transform, so we call // GetTransform here. - gfx3DMatrix currentTransform = To3DMatrix(aLayer->GetTransform()); Matrix4x4 oldTransform = aLayer->GetTransform(); - gfx3DMatrix treeTransform; - CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel(); LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.GetScrollOffset() * geckoZoom); @@ -842,22 +842,22 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) } LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll; - treeTransform = gfx3DMatrix(ViewTransform(-translation, + Matrix4x4 treeTransform = ViewTransform(-translation, userZoom / metrics.mDevPixelsPerCSSPixel - / metrics.GetParentResolution())); + / metrics.GetParentResolution()); // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. - gfx3DMatrix computedTransform = treeTransform * currentTransform; + Matrix4x4 computedTransform = treeTransform * oldTransform; computedTransform.Scale(1.0f/container->GetPreXScale(), 1.0f/container->GetPreYScale(), 1); computedTransform.ScalePost(1.0f/container->GetPostXScale(), 1.0f/container->GetPostYScale(), 1); - layerComposite->SetShadowTransform(ToMatrix4x4(computedTransform)); + layerComposite->SetShadowTransform(computedTransform); NS_ASSERTION(!layerComposite->GetShadowTransformSetByAnimation(), "overwriting animated transform!"); diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index e1c90cfffb0..becfe018814 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -8,12 +8,12 @@ #include "Units.h" // for LayerPoint, etc #include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "mozilla/Attributes.h" // for MOZ_DELETE, MOZ_FINAL, etc #include "mozilla/RefPtr.h" // for RefCounted #include "mozilla/TimeStamp.h" // for TimeStamp #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation #include "mozilla/gfx/BasePoint.h" // for BasePoint +#include "mozilla/gfx/Matrix.h" // for Matrix4x4 #include "mozilla/layers/LayersMessages.h" // for TargetConfig #include "nsAutoPtr.h" // for nsRefPtr #include "nsISupportsImpl.h" // for LayerManager::AddRef, etc @@ -34,17 +34,17 @@ struct ViewTransform { , mScale(aScale) {} - operator gfx3DMatrix() const + operator gfx::Matrix4x4() const { return - gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) * - gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1); + gfx::Matrix4x4().Translate(mTranslation.x, mTranslation.y, 0) * + gfx::Matrix4x4().Scale(mScale.scale, mScale.scale, 1); } // For convenience, to avoid writing the cumbersome - // "gfx3dMatrix(a) * gfx3DMatrix(b)". - friend gfx3DMatrix operator*(const ViewTransform& a, const ViewTransform& b) { - return gfx3DMatrix(a) * gfx3DMatrix(b); + // "gfx::Matrix4x4(a) * gfx::Matrix4x4(b)". + friend gfx::Matrix4x4 operator*(const ViewTransform& a, const ViewTransform& b) { + return gfx::Matrix4x4(a) * gfx::Matrix4x4(b); } bool operator==(const ViewTransform& rhs) const { diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 60b3768f29a..555d3907abd 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -8,7 +8,6 @@ #include "FrameMetrics.h" // for FrameMetrics #include "Units.h" // for LayerRect, LayerPixel, etc #include "gfx2DGlue.h" // for ToMatrix4x4 -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxPrefs.h" // for gfxPrefs #include "gfxUtils.h" // for gfxUtils, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 3f5455c14f0..62152fde854 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -22,7 +22,6 @@ #include "TiledLayerBuffer.h" // for TiledLayerComposer #include "Units.h" // for ScreenIntRect #include "gfx2DGlue.h" // for ToMatrix4x4 -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxPrefs.h" // for gfxPrefs #ifdef XP_MACOSX #include "gfxPlatformMac.h" @@ -564,7 +563,7 @@ LayerManagerComposite::WorldTransformRect(nsIntRect& aRect) static void SubtractTransformedRegion(nsIntRegion& aRegion, const nsIntRegion& aRegionToSubtract, - const gfx3DMatrix& aTransform) + const Matrix4x4& aTransform) { if (aRegionToSubtract.IsEmpty()) { return; @@ -574,7 +573,7 @@ SubtractTransformedRegion(nsIntRegion& aRegion, // subtract it from the screen region. nsIntRegionRectIterator it(aRegionToSubtract); while (const nsIntRect* rect = it.Next()) { - gfxRect incompleteRect = aTransform.TransformBounds(gfxRect(*rect)); + Rect incompleteRect = aTransform.TransformBounds(ToRect(*rect)); aRegion.Sub(aRegion, nsIntRect(incompleteRect.x, incompleteRect.y, incompleteRect.width, @@ -586,7 +585,7 @@ SubtractTransformedRegion(nsIntRegion& aRegion, LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer, nsIntRegion& aScreenRegion, nsIntRegion& aLowPrecisionScreenRegion, - const gfx3DMatrix& aTransform) + const Matrix4x4& aTransform) { if (aLayer->GetOpacity() <= 0.f || (aScreenRegion.IsEmpty() && aLowPrecisionScreenRegion.IsEmpty())) { @@ -597,10 +596,10 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer, ContainerLayer* container = aLayer->AsContainerLayer(); if (container) { // Accumulate the transform of intermediate surfaces - gfx3DMatrix transform = aTransform; + Matrix4x4 transform = aTransform; if (container->UseIntermediateSurface()) { - transform = gfx::To3DMatrix(aLayer->GetEffectiveTransform()); - transform.PreMultiply(aTransform); + transform = aLayer->GetEffectiveTransform(); + transform = aTransform * transform; } for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { @@ -621,8 +620,8 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer, if (!incompleteRegion.IsEmpty()) { // Calculate the transform to get between screen and layer space - gfx3DMatrix transformToScreen = To3DMatrix(aLayer->GetEffectiveTransform()); - transformToScreen.PreMultiply(aTransform); + Matrix4x4 transformToScreen = aLayer->GetEffectiveTransform(); + transformToScreen = aTransform * transformToScreen; SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen); @@ -650,14 +649,12 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer, #ifdef MOZ_ANDROID_OMTC static float GetDisplayportCoverage(const CSSRect& aDisplayPort, - const gfx3DMatrix& aTransformToScreen, + const Matrix4x4& aTransformToScreen, const nsIntRect& aScreenRect) { - gfxRect transformedDisplayport = - aTransformToScreen.TransformBounds(gfxRect(aDisplayPort.x, - aDisplayPort.y, - aDisplayPort.width, - aDisplayPort.height)); + Rect transformedDisplayport = + aTransformToScreen.TransformBounds(aDisplayPort.ToUnknownRect()); + transformedDisplayport.RoundOut(); nsIntRect displayport = nsIntRect(transformedDisplayport.x, transformedDisplayport.y, @@ -700,15 +697,15 @@ LayerManagerComposite::ComputeRenderIntegrity() // This is derived from the code in // AsyncCompositionManager::TransformScrollableLayer const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics(); - gfx3DMatrix transform = gfx::To3DMatrix(primaryScrollable->GetEffectiveTransform()); + Matrix4x4 transform = primaryScrollable->GetEffectiveTransform(); transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1); // Clip the screen rect to the document bounds - gfxRect documentBounds = - transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x, - metrics.mScrollableRect.y - metrics.GetScrollOffset().y, - metrics.mScrollableRect.width, - metrics.mScrollableRect.height)); + Rect documentBounds = + transform.TransformBounds(Rect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x, + metrics.mScrollableRect.y - metrics.GetScrollOffset().y, + metrics.mScrollableRect.width, + metrics.mScrollableRect.height)); documentBounds.RoundOut(); screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y, documentBounds.width, documentBounds.height)); @@ -747,7 +744,7 @@ LayerManagerComposite::ComputeRenderIntegrity() nsIntRegion screenRegion(screenRect); nsIntRegion lowPrecisionScreenRegion(screenRect); - gfx3DMatrix transform; + Matrix4x4 transform; ComputeRenderIntegrityInternal(root, screenRegion, lowPrecisionScreenRegion, transform); diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 34d498106cd..d5183186e55 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -252,7 +252,7 @@ private: static void ComputeRenderIntegrityInternal(Layer* aLayer, nsIntRegion& aScreenRegion, nsIntRegion& aLowPrecisionScreenRegion, - const gfx3DMatrix& aTransform); + const gfx::Matrix4x4& aTransform); /** * Render the current layer tree to the active target. diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 364820ecafd..4a66fced30d 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -11,7 +11,6 @@ #include "ImageLayers.h" // for ImageLayer #include "Layers.h" // for Layer, ContainerLayer, etc #include "ShadowLayerParent.h" // for ShadowLayerParent -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxPoint3D.h" // for gfxPoint3D #include "CompositableTransactionParent.h" // for EditReplyVector #include "ShadowLayersManager.h" // for ShadowLayersManager @@ -631,7 +630,7 @@ LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent, // from the shadow transform by undoing the translations in // AsyncCompositionManager::SampleValue. - gfx3DMatrix transform = gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform()); + Matrix4x4 transform = layer->AsLayerComposite()->GetShadowTransform(); if (ContainerLayer* c = layer->AsContainerLayer()) { // Undo the scale transform applied by AsyncCompositionManager::SampleValue transform.ScalePost(1.0f/c->GetInheritedXScale(), @@ -658,11 +657,12 @@ LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent, // Undo the translation to the origin of the reference frame applied by // AsyncCompositionManager::SampleValue - transform.Translate(-scaledOrigin); + transform.Translate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z); // Undo the rebasing applied by // nsDisplayTransform::GetResultingTransformMatrixInternal - transform.ChangeBasis(-scaledOrigin - transformOrigin); + gfxPoint3D basis = -scaledOrigin - transformOrigin; + transform.ChangeBasis(basis.x, basis.y, basis.z); // Convert to CSS pixels (this undoes the operations performed by // nsStyleTransformMatrix::ProcessTranslatePart which is called from diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 8e8f5b99d62..dd428127e5f 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -17,8 +17,6 @@ #include "nsAutoPtr.h" // for nsRefPtr #include "nsTArrayForwardDeclare.h" // for InfallibleTArray -class gfx3DMatrix; - namespace mozilla { namespace ipc { diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 3fd29c8bad7..3433c3ec8a3 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -20,7 +20,6 @@ using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h"; using struct gfxRGBA from "gfxColor.h"; using struct gfxPoint3D from "gfxPoint3D.h"; using class mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h"; -using class gfx3DMatrix from "gfx3DMatrix.h"; using nscoord from "nsCoord.h"; using struct nsIntPoint from "nsPoint.h"; using struct nsRect from "nsRect.h"; @@ -151,7 +150,7 @@ struct AnimationSegment { }; // Transforms need extra information to correctly convert the list of transform -// functions to a gfx3DMatrix that can be applied directly to the layer. +// functions to a Matrix4x4 that can be applied directly to the layer. struct TransformData { // the origin of the frame being transformed in app units nsPoint origin; diff --git a/gfx/layers/ipc/PLayerTransaction.ipdl b/gfx/layers/ipc/PLayerTransaction.ipdl index 21acbbf6c59..0db98bb48ce 100644 --- a/gfx/layers/ipc/PLayerTransaction.ipdl +++ b/gfx/layers/ipc/PLayerTransaction.ipdl @@ -32,7 +32,7 @@ namespace mozilla { namespace layers { union MaybeTransform { - gfx3DMatrix; + Matrix4x4; void_t; }; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 2b6f8960c08..aff372271f7 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -13,7 +13,6 @@ #include "Layers.h" // for WriteSnapshotToDumpFile #include "LayerScope.h" // for LayerScope #include "gfx2DGlue.h" // for ThebesFilter -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter #include "GraphicsFilter.h" // for GraphicsFilter #include "gfxPlatform.h" // for gfxPlatform diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 35d1c882e4c..86edc021992 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -35,7 +35,6 @@ #include #endif -class gfx3DMatrix; class nsIWidget; namespace mozilla { diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index 456b8ddeea7..097869c56b8 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -7,7 +7,6 @@ #define GFX_OGLSHADERPROGRAM_H #include "GLContext.h" // for fast inlines of glUniform* -#include "gfx3DMatrix.h" // for gfx3DMatrix #include "gfxTypes.h" #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/RefPtr.h" // for RefPtr @@ -471,10 +470,6 @@ protected: } } - void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx3DMatrix& aMatrix) { - SetMatrixUniform(aKnownUniform, &aMatrix._11); - } - void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Matrix4x4& aMatrix) { SetMatrixUniform(aKnownUniform, &aMatrix._11); } diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 9fbdb5f6103..906b27d9242 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -711,9 +711,9 @@ TEST_F(APZCBasicTester, ComplexTransform) { nsIntRegion(nsIntRect(0, 0, 300, 300)), nsIntRegion(nsIntRect(0, 0, 150, 300)), }; - gfx3DMatrix transforms[] = { - gfx3DMatrix(), - gfx3DMatrix(), + Matrix4x4 transforms[] = { + Matrix4x4(), + Matrix4x4(), }; transforms[0].ScalePost(0.5f, 0.5f, 1.0f); // this results from the 2.0 resolution on the root layer transforms[1].ScalePost(2.0f, 1.0f, 1.0f); // this is the 2.0 x-axis CSS transform on the child layer @@ -1451,12 +1451,12 @@ CreateTestLayerTree1(nsRefPtr& aLayerManager, nsTArray& aLayerManager, nsTArray GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint, - gfx3DMatrix& aTransformToApzcOut, gfx3DMatrix& aTransformToGeckoOut) + Matrix4x4& aTransformToApzcOut, Matrix4x4& aTransformToGeckoOut) { nsRefPtr hit = manager->GetTargetAPZC(aPoint, nullptr); if (hit) { @@ -1521,15 +1521,15 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { ScopedLayerTreeRegistration controller(0, root, mcc); nsRefPtr manager = new TestAPZCTreeManager(); - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; // No APZC attached so hit testing will return no APZC at (20,20) nsRefPtr hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToGecko); AsyncPanZoomController* nullAPZC = nullptr; EXPECT_EQ(nullAPZC, hit.get()); - EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToGecko); + EXPECT_EQ(Matrix4x4(), transformToApzc); + EXPECT_EQ(Matrix4x4(), transformToGecko); uint32_t paintSequenceNumber = 0; @@ -1539,8 +1539,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) - EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15))); - EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15))); + EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15)); + EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15)); // Now we have a sub APZC with a better fit SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1); @@ -1549,8 +1549,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(25, 25) - EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25))); - EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25))); + EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); + EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25)); // At this point, layers[4] obscures layers[3] at the point (15, 15) so // hitting there should hit the root APZC @@ -1563,25 +1563,25 @@ TEST_F(APZCTreeManagerTester, HitTesting1) { hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) - EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15))); - EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15))); + EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15)); + EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15)); // Hit test ouside the reach of layer[3,4] but inside root hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(90, 90) - EXPECT_EQ(gfxPoint(90, 90), transformToApzc.Transform(gfxPoint(90, 90))); - EXPECT_EQ(gfxPoint(90, 90), transformToGecko.Transform(gfxPoint(90, 90))); + EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90)); + EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90)); // Hit test ouside the reach of any layer hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToGecko); EXPECT_EQ(nullAPZC, hit.get()); - EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToGecko); + EXPECT_EQ(Matrix4x4(), transformToApzc); + EXPECT_EQ(Matrix4x4(), transformToGecko); hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToGecko); EXPECT_EQ(nullAPZC, hit.get()); - EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToGecko); + EXPECT_EQ(Matrix4x4(), transformToApzc); + EXPECT_EQ(Matrix4x4(), transformToGecko); manager->ClearTree(); } @@ -1599,8 +1599,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { nsRefPtr manager = new TestAPZCTreeManager(); nsRefPtr hit; - gfx3DMatrix transformToApzc; - gfx3DMatrix transformToGecko; + Matrix4x4 transformToApzc; + Matrix4x4 transformToGecko; // Set a CSS transform on one of the layers. Matrix4x4 transform; @@ -1627,8 +1627,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { // Hit an area that's clearly on the root layer but not any of the child layers. hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); - EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25))); - EXPECT_EQ(gfxPoint(75, 25), transformToGecko.Transform(gfxPoint(75, 25))); + EXPECT_EQ(Point(75, 25), transformToApzc * Point(75, 25)); + EXPECT_EQ(Point(75, 25), transformToGecko * Point(75, 25)); // Hit an area on the root that would be on layers[3] if layers[2] // weren't transformed. @@ -1639,31 +1639,31 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { // start at x=10 but its content at x=20). hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); - EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75))); - EXPECT_EQ(gfxPoint(15, 75), transformToGecko.Transform(gfxPoint(15, 75))); + EXPECT_EQ(Point(15, 75), transformToApzc * Point(15, 75)); + EXPECT_EQ(Point(15, 75), transformToGecko * Point(15, 75)); // Hit an area on layers[1]. hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzc1, hit.get()); - EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25))); - EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25))); + EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); + EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25)); // Hit an area on layers[3]. hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform - EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75))); + EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 75)); // and transformToGecko should reapply it - EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(12.5, 75))); + EXPECT_EQ(Point(25, 75), transformToGecko * Point(12.5, 75)); // Hit an area on layers[3] that would be on the root if layers[2] // weren't transformed. hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform - EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75))); + EXPECT_EQ(Point(37.5, 75), transformToApzc * Point(75, 75)); // and transformToGecko should reapply it - EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(37.5, 75))); + EXPECT_EQ(Point(75, 75), transformToGecko * Point(37.5, 75)); // Pan the root layer upward by 50 pixels. // This causes layers[1] to scroll out of view, and an async transform @@ -1685,21 +1685,21 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform - EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75))); + EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75)); // and transformToGecko unapplies it and then reapplies it, because by the // time the event being transformed reaches Gecko the new paint request will // have been handled. - EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(75, 75))); + EXPECT_EQ(Point(75, 75), transformToGecko * Point(75, 75)); // Hit where layers[1] used to be and where layers[3] should now be. hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc unapplies both layers[2]'s css transform and the root's // async transform - EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25))); + EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 25)); // transformToGecko reapplies both the css transform and the async transform // because we have already issued a paint request with it. - EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(12.5, 75))); + EXPECT_EQ(Point(25, 25), transformToGecko * Point(12.5, 75)); // This second pan will move the APZC by another 50 pixels but since the paint // request dispatched above has not "completed", we will not dispatch another @@ -1713,19 +1713,19 @@ TEST_F(APZCTreeManagerTester, HitTesting2) { hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform - EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75))); + EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75)); // transformToGecko unapplies the full async transform of -100 pixels, and then // reapplies the "D" transform of -50 leading to an overall adjustment of +50 - EXPECT_EQ(gfxPoint(75, 125), transformToGecko.Transform(gfxPoint(75, 75))); + EXPECT_EQ(Point(75, 125), transformToGecko * Point(75, 75)); // Hit where layers[1] used to be. It should now hit the root. hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform - EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25))); + EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25)); // transformToGecko unapplies the full async transform of -100 pixels, and then // reapplies the "D" transform of -50 leading to an overall adjustment of +50 - EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(25, 25))); + EXPECT_EQ(Point(25, 75), transformToGecko * Point(25, 25)); manager->ClearTree(); } diff --git a/gfx/tests/gtest/TestLayers.cpp b/gfx/tests/gtest/TestLayers.cpp index 6f3ffaf6743..65ceecddef7 100644 --- a/gfx/tests/gtest/TestLayers.cpp +++ b/gfx/tests/gtest/TestLayers.cpp @@ -162,7 +162,7 @@ already_AddRefed CreateLayer(char aLayerType, LayerManager* aManager) { already_AddRefed CreateLayerTree( const char* aLayerTreeDescription, nsIntRegion* aVisibleRegions, - const gfx3DMatrix* aTransforms, + const Matrix4x4* aTransforms, nsRefPtr& manager, nsTArray >& aLayersOut) { @@ -194,7 +194,7 @@ already_AddRefed CreateLayerTree( layer->SetVisibleRegion(aVisibleRegions[layerNumber]); } if (aTransforms) { - layer->SetBaseTransform(ToMatrix4x4(aTransforms[layerNumber])); + layer->SetBaseTransform(aTransforms[layerNumber]); } aLayersOut.AppendElement(layer); layerNumber++; @@ -225,11 +225,11 @@ TEST(Layers, LayerTree) { nsIntRegion(nsIntRect(0,0,100,100)), nsIntRegion(nsIntRect(10,10,20,20)), }; - gfx3DMatrix transforms[] = { - gfx3DMatrix(), - gfx3DMatrix(), - gfx3DMatrix(), - gfx3DMatrix(), + Matrix4x4 transforms[] = { + Matrix4x4(), + Matrix4x4(), + Matrix4x4(), + Matrix4x4(), }; nsTArray > layers; diff --git a/gfx/tests/gtest/TestLayers.h b/gfx/tests/gtest/TestLayers.h index c1a16268852..f918ef6c31d 100644 --- a/gfx/tests/gtest/TestLayers.h +++ b/gfx/tests/gtest/TestLayers.h @@ -27,7 +27,7 @@ already_AddRefed CreateLayerTree( const char* aLayerTreeDescription, nsIntRegion* aVisibleRegions, - const gfx3DMatrix* aTransforms, + const mozilla::gfx::Matrix4x4* aTransforms, nsRefPtr& aLayerManager, nsTArray >& aLayersOut); diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index de8ce944a6f..35d5a75b0cc 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2031,15 +2031,16 @@ gfxPlatform::UsesOffMainThreadCompositing() gfxPrefs::LayersOffMainThreadCompositionEnabled() || gfxPrefs::LayersOffMainThreadCompositionForceEnabled() || gfxPrefs::LayersOffMainThreadCompositionTestingEnabled(); -#if defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD) +#if defined(MOZ_WIDGET_GTK) // Linux users who chose OpenGL are being grandfathered in to OMTC - result |= - gfxPrefs::LayersAccelerationForceEnabled() || - PR_GetEnv("MOZ_USE_OMTC") || - PR_GetEnv("MOZ_OMTC_ENABLED"); // yeah, these two env vars do the same thing. - // I'm told that one of them is enabled on some test slaves config. - // so be slightly careful if you think you can - // remove one of them. + result |= gfxPrefs::LayersAccelerationForceEnabled(); + +#if !defined(NIGHTLY_BUILD) + // Yeah, these two env vars do the same thing. + // I'm told that one of them is enabled on some test slaves config, + // so be slightly careful if you think you can remove one of them. + result &= PR_GetEnv("MOZ_USE_OMTC") || PR_GetEnv("MOZ_OMTC_ENABLED"); +#endif #endif firstTime = false; } diff --git a/hal/Hal.h b/hal/Hal.h index 47eb54de29c..26eaff07ba9 100644 --- a/hal/Hal.h +++ b/hal/Hal.h @@ -49,6 +49,7 @@ class WindowIdentifier; extern PRLogModuleInfo *GetHalLog(); #define HAL_LOG(msg) PR_LOG(mozilla::hal::GetHalLog(), PR_LOG_DEBUG, msg) +#define HAL_ERR(msg) PR_LOG(mozilla::hal::GetHalLog(), PR_LOG_ERROR, msg) typedef Observer SystemClockChangeObserver; typedef Observer SystemTimezoneChangeObserver; diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index 4f2e71ff139..d60c9b49870 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -68,8 +68,8 @@ #include "UeventPoller.h" #include "nsIWritablePropertyBag2.h" #include +#include "PowerWakeLock.h" -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) #define NsecPerMsec 1000000LL #define NsecPerSec 1000000000 @@ -667,6 +667,7 @@ void SetScreenEnabled(bool aEnabled) { GetGonkDisplay()->SetEnabled(aEnabled); + gPowerWakelock = nullptr; sScreenEnabled = aEnabled; } @@ -1397,15 +1398,15 @@ SetNiceForPid(int aPid, int aNice) errno = 0; int origProcPriority = getpriority(PRIO_PROCESS, aPid); if (errno) { - LOG("Unable to get nice for pid=%d; error %d. SetNiceForPid bailing.", - aPid, errno); + HAL_LOG(("Unable to get nice for pid=%d; error %d. SetNiceForPid bailing.", + aPid, errno)); return; } int rv = setpriority(PRIO_PROCESS, aPid, aNice); if (rv) { - LOG("Unable to set nice for pid=%d; error %d. SetNiceForPid bailing.", - aPid, errno); + HAL_LOG(("Unable to set nice for pid=%d; error %d. SetNiceForPid bailing.", + aPid, errno)); return; } @@ -1419,7 +1420,7 @@ SetNiceForPid(int aPid, int aNice) DIR* tasksDir = opendir(nsPrintfCString("/proc/%d/task/", aPid).get()); if (!tasksDir) { - LOG("Unable to open /proc/%d/task. SetNiceForPid bailing.", aPid); + HAL_LOG(("Unable to open /proc/%d/task. SetNiceForPid bailing.", aPid)); return; } @@ -1452,9 +1453,9 @@ SetNiceForPid(int aPid, int aNice) // Get and set the task's new priority. int origtaskpriority = getpriority(PRIO_PROCESS, tid); if (errno) { - LOG("Unable to get nice for tid=%d (pid=%d); error %d. This isn't " - "necessarily a problem; it could be a benign race condition.", - tid, aPid, errno); + HAL_LOG(("Unable to get nice for tid=%d (pid=%d); error %d. This isn't " + "necessarily a problem; it could be a benign race condition.", + tid, aPid, errno)); continue; } @@ -1472,15 +1473,15 @@ SetNiceForPid(int aPid, int aNice) rv = setpriority(PRIO_PROCESS, tid, newtaskpriority); if (rv) { - LOG("Unable to set nice for tid=%d (pid=%d); error %d. This isn't " - "necessarily a problem; it could be a benign race condition.", - tid, aPid, errno); + HAL_LOG(("Unable to set nice for tid=%d (pid=%d); error %d. This isn't " + "necessarily a problem; it could be a benign race condition.", + tid, aPid, errno)); continue; } } - LOG("Changed nice for pid %d from %d to %d.", - aPid, origProcPriority, aNice); + HAL_LOG(("Changed nice for pid %d from %d to %d.", + aPid, origProcPriority, aNice)); closedir(tasksDir); } @@ -1514,11 +1515,11 @@ SetProcessPriority(int aPid, int clampedOomScoreAdj = clamped(oomScoreAdj, OOM_SCORE_ADJ_MIN, OOM_SCORE_ADJ_MAX); if(clampedOomScoreAdj != oomScoreAdj) { - HAL_LOG(("Clamping OOM adjustment for pid %d to %d", - aPid, clampedOomScoreAdj)); + HAL_LOG(("Clamping OOM adjustment for pid %d to %d", aPid, + clampedOomScoreAdj)); } else { - HAL_LOG(("Setting OOM adjustment for pid %d to %d", - aPid, clampedOomScoreAdj)); + HAL_LOG(("Setting OOM adjustment for pid %d to %d", aPid, + clampedOomScoreAdj)); } // We try the newer interface first, and fall back to the older interface @@ -1533,9 +1534,8 @@ SetProcessPriority(int aPid, nsPrintfCString("%d", oomAdj).get()); } } else { - LOG("Unable to read oom_score_adj pref for priority %s; " - "are the prefs messed up?", - ProcessPriorityToString(aPriority)); + HAL_ERR(("Unable to read oom_score_adj pref for priority %s; " + "are the prefs messed up?", ProcessPriorityToString(aPriority))); MOZ_ASSERT(false); } @@ -1550,15 +1550,14 @@ SetProcessPriority(int aPid, rv = Preferences::GetInt("hal.processPriorityManager.gonk.LowCPUNice", &nice); } else { - LOG("Unable to read niceness pref for priority %s; " - "are the prefs messed up?", - ProcessPriorityToString(aPriority)); + HAL_ERR(("Unable to read niceness pref for priority %s; " + "are the prefs messed up?", ProcessPriorityToString(aPriority))); MOZ_ASSERT(false); rv = NS_ERROR_FAILURE; } if (NS_SUCCEEDED(rv)) { - LOG("Setting nice for pid %d to %d", aPid, nice); + HAL_LOG(("Setting nice for pid %d to %d", aPid, nice)); SetNiceForPid(aPid, nice); } } @@ -1576,13 +1575,13 @@ SetThreadNiceValue(pid_t aTid, ThreadPriority aThreadPriority, int aValue) MOZ_ASSERT(aThreadPriority < NUM_THREAD_PRIORITY); MOZ_ASSERT(aThreadPriority >= 0); - LOG("Setting thread %d to priority level %s; nice level %d", - aTid, ThreadPriorityToString(aThreadPriority), aValue); + HAL_LOG(("Setting thread %d to priority level %s; nice level %d", + aTid, ThreadPriorityToString(aThreadPriority), aValue)); int rv = setpriority(PRIO_PROCESS, aTid, aValue); if (rv) { - LOG("Failed to set thread %d to priority level %s; error %s", - aTid, ThreadPriorityToString(aThreadPriority), strerror(errno)); + HAL_LOG(("Failed to set thread %d to priority level %s; error %s", aTid, + ThreadPriorityToString(aThreadPriority), strerror(errno))); } } @@ -1598,15 +1597,16 @@ SetRealTimeThreadPriority(pid_t aTid, MOZ_ASSERT(IsValidRealTimePriority(aValue, policy), "Invalid real time priority"); // Setting real time priorities requires using sched_setscheduler - LOG("Setting thread %d to priority level %s; Real Time priority %d, Schedule FIFO", - aTid, ThreadPriorityToString(aThreadPriority), aValue); + HAL_LOG(("Setting thread %d to priority level %s; Real Time priority %d, " + "Schedule FIFO", aTid, ThreadPriorityToString(aThreadPriority), + aValue)); sched_param schedParam; schedParam.sched_priority = aValue; int rv = sched_setscheduler(aTid, policy, &schedParam); if (rv) { - LOG("Failed to set thread %d to real time priority level %s; error %s", - aTid, ThreadPriorityToString(aThreadPriority), strerror(errno)); + HAL_LOG(("Failed to set thread %d to real time priority level %s; error %s", + aTid, ThreadPriorityToString(aThreadPriority), strerror(errno))); } } @@ -1624,7 +1624,8 @@ SetThreadPriority(pid_t aTid, hal::ThreadPriority aThreadPriority) threadPriorityStr = ThreadPriorityToString(aThreadPriority); break; default: - LOG("Unrecognized thread priority %d; Doing nothing", aThreadPriority); + HAL_ERR(("Unrecognized thread priority %d; Doing nothing", + aThreadPriority)); return; } @@ -1686,7 +1687,8 @@ SetCurrentThreadPriority(ThreadPriority aThreadPriority) break; } default: - LOG("Unrecognized thread priority %d; Doing nothing", aThreadPriority); + HAL_LOG(("Unrecognized thread priority %d; Doing nothing", + aThreadPriority)); return; } } diff --git a/ipc/app/Makefile.in b/ipc/app/Makefile.in index 5cc4d7a2b41..6c18864b702 100644 --- a/ipc/app/Makefile.in +++ b/ipc/app/Makefile.in @@ -37,6 +37,10 @@ include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/rules.mk +ifneq ($(MOZ_WIDGET_TOOLKIT),android) +#LIBS += ../contentproc/$(LIB_PREFIX)plugin-container.$(LIB_SUFFIX) +endif + ifeq ($(OS_ARCH),WINNT) #{ # Note the manifest file exists in the tree, so we use the explicit filename # here. diff --git a/ipc/app/MozillaRuntimeMain.cpp b/ipc/app/MozillaRuntimeMain.cpp index 4bdb6a56dd8..67b63633314 100644 --- a/ipc/app/MozillaRuntimeMain.cpp +++ b/ipc/app/MozillaRuntimeMain.cpp @@ -4,148 +4,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "nsXPCOM.h" -#include "nsXULAppAPI.h" - -// FIXME/cjones testing -#if !defined(OS_WIN) -#include -#endif - -#ifdef XP_WIN -#include -// we want a wmain entry point -// but we don't want its DLL load protection, because we'll handle it here -#define XRE_DONT_PROTECT_DLL_LOAD -#include "nsWindowsWMain.cpp" -#include "nsSetDllDirectory.h" -#endif - -#if defined(XP_WIN) -#include "sandbox/chromium/base/basictypes.h" -#include "sandbox/win/src/sandbox.h" -#include "sandbox/win/src/sandbox_factory.h" -#include "mozilla/sandboxTarget.h" -#endif - -#ifdef MOZ_WIDGET_GONK -# include -# include - -# include - -# ifdef LOGE_IF -# undef LOGE_IF -# endif - -# include -# define LOGE_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)__android_log_print(ANDROID_LOG_ERROR, \ - "Gecko:MozillaRntimeMain", __VA_ARGS__)) \ - : (void)0 ) - -#endif - -#ifdef MOZ_NUWA_PROCESS -#include -#include "ipc/Nuwa.h" -#endif - -#ifdef MOZ_WIDGET_GONK -static void -InitializeBinder(void *aDummy) { - // Change thread priority to 0 only during calling ProcessState::self(). - // The priority is registered to binder driver and used for default Binder - // Thread's priority. - // To change the process's priority to small value need's root permission. - int curPrio = getpriority(PRIO_PROCESS, 0); - int err = setpriority(PRIO_PROCESS, 0, 0); - MOZ_ASSERT(!err); - LOGE_IF(err, "setpriority failed. Current process needs root permission."); - android::ProcessState::self()->startThreadPool(); - setpriority(PRIO_PROCESS, 0, curPrio); -} -#endif - -#if defined(XP_WIN) -static bool gIsSandboxEnabled = false; -void StartSandboxCallback() -{ - if (gIsSandboxEnabled) { - sandbox::TargetServices* target_service = - sandbox::SandboxFactory::GetTargetServices(); - target_service->LowerToken(); - } -} -#endif - +#include "../contentproc/plugin-container.cpp" + int -main(int argc, char* argv[]) -{ - bool isNuwa = false; - for (int i = 1; i < argc; i++) { - isNuwa |= strcmp(argv[i], "-nuwa") == 0; -#if defined(XP_WIN) - gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0; -#endif - } - -#ifdef MOZ_NUWA_PROCESS - if (isNuwa) { - PrepareNuwaProcess(); - } -#endif - -#ifdef MOZ_WIDGET_GONK - // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to - // receive binder calls, though not necessary to send binder calls. - // ProcessState::Self() also needs to be called once on the main thread to - // register the main thread with the binder driver. - -#ifdef MOZ_NUWA_PROCESS - if (!isNuwa) { - InitializeBinder(nullptr); - } else { - NuwaAddFinalConstructor(&InitializeBinder, nullptr); - } -#else - InitializeBinder(nullptr); -#endif -#endif - - // Check for the absolute minimum number of args we need to move - // forward here. We expect the last arg to be the child process type. - if (argc < 1) - return 3; - GeckoProcessType proctype = XRE_StringToChildProcessType(argv[--argc]); - -#ifdef XP_WIN - // For plugins, this is done in PluginProcessChild::Init, as we need to - // avoid it for unsupported plugins. See PluginProcessChild::Init for - // the details. - if (proctype != GeckoProcessType_Plugin) { - mozilla::SanitizeEnvironmentVariables(); - SetDllDirectory(L""); - } - - if (gIsSandboxEnabled) { - sandbox::TargetServices* target_service = - sandbox::SandboxFactory::GetTargetServices(); - if (!target_service) { - return 1; - } - - sandbox::ResultCode result = target_service->Init(); - if (result != sandbox::SBOX_ALL_OK) { - return 2; - } - mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback); - } -#endif - - nsresult rv = XRE_InitChildProcess(argc, argv, proctype); - NS_ENSURE_SUCCESS(rv, 1); - - return 0; +main(int argc, char *argv[]) { + return content_process_main(argc, argv); } diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc index 0be1b7edd77..741e912b8d9 100644 --- a/ipc/chromium/src/base/process_util_linux.cc +++ b/ipc/chromium/src/base/process_util_linux.cc @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 autoindent cindent expandtab: */ // Copyright (c) 2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,6 +20,13 @@ #include "base/logging.h" #include "base/string_tokenizer.h" #include "base/string_util.h" +#include "nsLiteralString.h" + +#ifdef MOZ_B2G_LOADER +#include "ProcessUtils.h" + +using namespace mozilla::ipc; +#endif // MOZ_B2G_LOADER #ifdef MOZ_WIDGET_GONK /* @@ -188,12 +197,71 @@ bool LaunchApp(const std::vector& argv, wait, process_handle); } +#ifdef MOZ_B2G_LOADER +/** + * Launch an app using B2g Loader. + */ +static bool +LaunchAppProcLoader(const std::vector& argv, + const file_handle_mapping_vector& fds_to_remap, + const environment_map& env_vars_to_set, + ChildPrivileges privs, + ProcessHandle* process_handle) { + size_t i; + scoped_array argv_cstr(new char*[argv.size() + 1]); + for (i = 0; i < argv.size(); i++) { + argv_cstr[i] = const_cast(argv[i].c_str()); + } + argv_cstr[argv.size()] = nullptr; + + scoped_array env_cstr(new char*[env_vars_to_set.size() + 1]); + i = 0; + for (environment_map::const_iterator it = env_vars_to_set.begin(); + it != env_vars_to_set.end(); ++it) { + env_cstr[i++] = strdup((it->first + "=" + it->second).c_str()); + } + env_cstr[env_vars_to_set.size()] = nullptr; + + bool ok = ProcLoaderLoad((const char **)argv_cstr.get(), + (const char **)env_cstr.get(), + fds_to_remap, privs, + process_handle); + MOZ_ASSERT(ok, "ProcLoaderLoad() failed"); + + for (size_t i = 0; i < env_vars_to_set.size(); i++) { + free(env_cstr[i]); + } + + return ok; +} + +static bool +IsLaunchingNuwa(const std::vector& argv) { + std::vector::const_iterator it; + for (it = argv.begin(); it != argv.end(); ++it) { + if (*it == std::string("-nuwa")) { + return true; + } + } + return false; +} +#endif // MOZ_B2G_LOADER + bool LaunchApp(const std::vector& argv, const file_handle_mapping_vector& fds_to_remap, const environment_map& env_vars_to_set, ChildPrivileges privs, bool wait, ProcessHandle* process_handle, ProcessArchitecture arch) { +#ifdef MOZ_B2G_LOADER + static bool beforeFirstNuwaLaunch = true; + if (!wait && beforeFirstNuwaLaunch && IsLaunchingNuwa(argv)) { + beforeFirstNuwaLaunch = false; + return LaunchAppProcLoader(argv, fds_to_remap, env_vars_to_set, + privs, process_handle); + } +#endif // MOZ_B2G_LOADER + scoped_array argv_cstr(new char*[argv.size() + 1]); // Illegal to allocate memory after fork and before execvp InjectiveMultimap fd_shuffle1, fd_shuffle2; diff --git a/ipc/contentproc/moz.build b/ipc/contentproc/moz.build new file mode 100644 index 00000000000..39b5d327379 --- /dev/null +++ b/ipc/contentproc/moz.build @@ -0,0 +1,29 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +LIBRARY_NAME = 'plugin-container' +if CONFIG['MOZ_B2G_LOADER']: + FINAL_LIBRARY = 'xul' + +SOURCES += [ + 'plugin-container.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +if CONFIG['OS_ARCH'] == 'WINNT': + LOCAL_INCLUDES += [ + '/toolkit/xre', + '/xpcom/base', + ] + +if CONFIG['OS_ARCH'] == 'WINNT': + # For sandbox includes and the include dependencies those have + LOCAL_INCLUDES += [ + '/security', + '/security/sandbox', + '/security/sandbox/chromium', + ] diff --git a/ipc/contentproc/plugin-container.cpp b/ipc/contentproc/plugin-container.cpp new file mode 100644 index 00000000000..e8fe2cc2549 --- /dev/null +++ b/ipc/contentproc/plugin-container.cpp @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: sw=4 ts=4 et : + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsXPCOM.h" +#include "nsXULAppAPI.h" + +// FIXME/cjones testing +#if !defined(OS_WIN) +#include +#endif + +#ifdef XP_WIN +#include +// we want a wmain entry point +// but we don't want its DLL load protection, because we'll handle it here +#define XRE_DONT_PROTECT_DLL_LOAD +#include "nsWindowsWMain.cpp" +#include "nsSetDllDirectory.h" +#endif + +#if defined(XP_WIN) +#include "sandbox/chromium/base/basictypes.h" +#include "sandbox/win/src/sandbox.h" +#include "sandbox/win/src/sandbox_factory.h" +#include "mozilla/sandboxTarget.h" +#endif + +#ifdef MOZ_WIDGET_GONK +# include +# include + +# include + +# ifdef LOGE_IF +# undef LOGE_IF +# endif + +# include +# define LOGE_IF(cond, ...) \ + ( (CONDITION(cond)) \ + ? ((void)__android_log_print(ANDROID_LOG_ERROR, \ + "Gecko:MozillaRntimeMain", __VA_ARGS__)) \ + : (void)0 ) + +#endif + +#ifdef MOZ_NUWA_PROCESS +#include +#include "ipc/Nuwa.h" +#endif + +#ifdef MOZ_WIDGET_GONK +static void +InitializeBinder(void *aDummy) { + // Change thread priority to 0 only during calling ProcessState::self(). + // The priority is registered to binder driver and used for default Binder + // Thread's priority. + // To change the process's priority to small value need's root permission. + int curPrio = getpriority(PRIO_PROCESS, 0); + int err = setpriority(PRIO_PROCESS, 0, 0); + MOZ_ASSERT(!err); + LOGE_IF(err, "setpriority failed. Current process needs root permission."); + android::ProcessState::self()->startThreadPool(); + setpriority(PRIO_PROCESS, 0, curPrio); +} +#endif + +#if defined(XP_WIN) +static bool gIsSandboxEnabled = false; +void StartSandboxCallback() +{ + if (gIsSandboxEnabled) { + sandbox::TargetServices* target_service = + sandbox::SandboxFactory::GetTargetServices(); + target_service->LowerToken(); + } +} +#endif + +int +content_process_main(int argc, char* argv[]) +{ + bool isNuwa = false; + for (int i = 1; i < argc; i++) { + isNuwa |= strcmp(argv[i], "-nuwa") == 0; +#if defined(XP_WIN) + gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0; +#endif + } + +#ifdef MOZ_NUWA_PROCESS + if (isNuwa) { + PrepareNuwaProcess(); + } +#endif + +#ifdef MOZ_WIDGET_GONK + // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to + // receive binder calls, though not necessary to send binder calls. + // ProcessState::Self() also needs to be called once on the main thread to + // register the main thread with the binder driver. + +#ifdef MOZ_NUWA_PROCESS + if (!isNuwa) { + InitializeBinder(nullptr); + } else { + NuwaAddFinalConstructor(&InitializeBinder, nullptr); + } +#else + InitializeBinder(nullptr); +#endif +#endif + + // Check for the absolute minimum number of args we need to move + // forward here. We expect the last arg to be the child process type. + if (argc < 1) + return 3; + GeckoProcessType proctype = XRE_StringToChildProcessType(argv[--argc]); + +#ifdef XP_WIN + // For plugins, this is done in PluginProcessChild::Init, as we need to + // avoid it for unsupported plugins. See PluginProcessChild::Init for + // the details. + if (proctype != GeckoProcessType_Plugin) { + mozilla::SanitizeEnvironmentVariables(); + SetDllDirectory(L""); + } + + if (gIsSandboxEnabled) { + sandbox::TargetServices* target_service = + sandbox::SandboxFactory::GetTargetServices(); + if (!target_service) { + return 1; + } + + sandbox::ResultCode result = target_service->Init(); + if (result != sandbox::SBOX_ALL_OK) { + return 2; + } + mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback); + } +#endif + + nsresult rv = XRE_InitChildProcess(argc, argv, proctype); + NS_ENSURE_SUCCESS(rv, 1); + + return 0; +} diff --git a/ipc/glue/PProcLoader.ipdl b/ipc/glue/PProcLoader.ipdl new file mode 100644 index 00000000000..d295d8b7221 --- /dev/null +++ b/ipc/glue/PProcLoader.ipdl @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 autoindent cindent expandtab: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +namespace mozilla { +namespace ipc { + +struct FDRemap { + FileDescriptor fd; + int mapto; +}; + +protocol PProcLoader +{ +child: + /** + * Request B2G loader service to load content process. + * + * It actually calls the main() function of plugin-container. + */ + async Load(nsCString[] argv, nsCString[] env, + FDRemap[] fdsRemap, uint32_t privs, + int32_t cookie); + +parent: + /** + * The acknowledgement of Load(). + */ + async LoadComplete(int32_t pid, int32_t cookie); +}; + +} +} diff --git a/ipc/glue/ProcessUtils.h b/ipc/glue/ProcessUtils.h index fc17609dcad..99d0f532dd8 100644 --- a/ipc/glue/ProcessUtils.h +++ b/ipc/glue/ProcessUtils.h @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 autoindent cindent expandtab: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -5,6 +7,10 @@ #ifndef mozilla_ipc_ProcessUtils_h #define mozilla_ipc_ProcessUtils_h +#ifdef MOZ_B2G_LOADER +#include "base/process_util.h" +#endif + namespace mozilla { namespace ipc { @@ -12,6 +18,17 @@ namespace ipc { // this directly. void SetThisProcessName(const char *aName); +#ifdef MOZ_B2G_LOADER +// see ProcessUtils_linux.cpp for explaination. +void ProcLoaderClientGeckoInit(); + +bool ProcLoaderLoad(const char *aArgv[], + const char *aEnvp[], + const base::file_handle_mapping_vector &aFdsRemap, + const base::ChildPrivileges aPrivs, + base::ProcessHandle *aProcessHandle); +#endif /* MOZ_B2G_LOADER */ + } // namespace ipc } // namespace mozilla diff --git a/ipc/glue/ProcessUtils_linux.cpp b/ipc/glue/ProcessUtils_linux.cpp index d5b8c092e0f..42998991bd7 100644 --- a/ipc/glue/ProcessUtils_linux.cpp +++ b/ipc/glue/ProcessUtils_linux.cpp @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=2 autoindent cindent expandtab: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -8,6 +10,37 @@ #include +#ifdef MOZ_B2G_LOADER + +#include +#include + +#include "nsAutoPtr.h" + +#include "mozilla/Assertions.h" +#include "mozilla/ipc/PProcLoaderParent.h" +#include "mozilla/ipc/PProcLoaderChild.h" +#include "mozilla/ipc/Transport.h" +#include "mozilla/ipc/FileDescriptorUtils.h" +#include "mozilla/ipc/IOThreadChild.h" +#include "mozilla/dom/ContentProcess.h" +#include "base/file_descriptor_shuffle.h" +#include "mozilla/BackgroundHangMonitor.h" +#include "mozilla/DebugOnly.h" +#include "base/process_util.h" + +#include "prenv.h" + +#include "nsXULAppAPI.h" // export XRE_* functions + +#include "nsAppRunner.h" + +int content_process_main(int argc, char *argv[]); + +extern bool gDisableAndroidLog; + +#endif /* MOZ_B2G_LOADER */ + namespace mozilla { namespace ipc { @@ -16,5 +49,522 @@ void SetThisProcessName(const char *aName) prctl(PR_SET_NAME, (unsigned long)aName, 0uL, 0uL, 0uL); } +#ifdef MOZ_B2G_LOADER +/** + * How does B2G Loader Work? + * + * <> <> + * ProcLoaderParent -----> ProcLoaderChild + * ^ | + * | load() | content_process_main() + * | V + * ProcLoaderClient Nuwa/plugin-container + * ^ + * | ProcLoaderLoad() + * ... + * ContentParent + * + * + * B2G loader includes an IPC protocol PProcLoader for communication + * between client (parent) and server (child). The b2g process is the + * client. It requests the server to load/start the Nuwa process with + * the given arguments, env variables, and file descriptors. + * + * ProcLoaderClientInit() is called by B2G loader to initialize the + * client side, the b2g process. Then the b2g_main() is called to + * start b2g process. + * + * ProcLoaderClientGeckoInit() is called by XRE_main() to create the + * parent actor, |ProcLoaderParent|, of PProcLoader for servicing the + * request to run Nuwa process later once Gecko has been initialized. + * + * ProcLoaderServiceRun() is called by the server process. It starts + * an IOThread and event loop to serve the |ProcLoaderChild| + * implmentation of PProcLoader protocol as the child actor. Once it + * recieves a load() request, it stops the IOThread and event loop, + * then starts running the main function of the content process with + * the given arguments. + * + * NOTE: The server process serves at most one load() request. + */ + +using namespace base; +using namespace mozilla::dom; + +static bool sProcLoaderClientOnDeinit = false; +static DebugOnly sProcLoaderClientInitialized = false; +static DebugOnly sProcLoaderClientGeckoInitialized = false; +static pid_t sProcLoaderPid = 0; +static int sProcLoaderChannelFd = -1; +static PProcLoaderParent *sProcLoaderParent = nullptr; +static MessageLoop *sProcLoaderLoop = nullptr; + +static void ProcLoaderClientDeinit(); + + +class ProcLoaderParent : public PProcLoaderParent +{ +private: + nsAutoPtr mChannelFd; // To keep a reference. + +public: + ProcLoaderParent(FileDescriptor *aFd) : mChannelFd(aFd) {} + + virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool RecvLoadComplete(const int32_t &aPid, + const int32_t &aCookie) MOZ_OVERRIDE; + + virtual void OnChannelError() MOZ_OVERRIDE; +}; + +void +ProcLoaderParent::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +static void +_ProcLoaderParentDestroy(PProcLoaderParent *aLoader) +{ + aLoader->Close(); + delete aLoader; + sProcLoaderClientOnDeinit = false; +} + +bool +ProcLoaderParent::RecvLoadComplete(const int32_t &aPid, + const int32_t &aCookie) +{ + ProcLoaderClientDeinit(); + return true; +} + +void +ProcLoaderParent::OnChannelError() +{ + if (sProcLoaderClientOnDeinit) { + // Get error for closing while the channel is already error. + return; + } + NS_WARNING("ProcLoaderParent is in channel error"); + ProcLoaderClientDeinit(); +} + +/** + * Initialize the client of B2G loader for loader itself. + * + * The initialization of B2G loader are divided into two stages. First + * stage is to collect child info passed from the main program of the + * loader. Second stage is to initialize Gecko according to info from the + * first stage and make the client of loader service ready. + * + * \param aPeerPid is the pid of the child. + * \param aChannelFd is the file descriptor of the socket used for IPC. + */ +static void +ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd) +{ + MOZ_ASSERT(!sProcLoaderClientInitialized, "call ProcLoaderClientInit() more than once"); + MOZ_ASSERT(aPeerPid != 0 && aChannelFd != -1, "invalid argument"); + sProcLoaderPid = aPeerPid; + sProcLoaderChannelFd = aChannelFd; + sProcLoaderClientInitialized = true; +} + +/** + * Initialize the client of B2G loader for Gecko. + */ +void +ProcLoaderClientGeckoInit() +{ + MOZ_ASSERT(sProcLoaderClientInitialized, "call ProcLoaderClientInit() at first"); + MOZ_ASSERT(!sProcLoaderClientGeckoInitialized, + "call ProcLoaderClientGeckoInit() more than once"); + + sProcLoaderClientGeckoInitialized = true; + + FileDescriptor *fd = new FileDescriptor(sProcLoaderChannelFd); + close(sProcLoaderChannelFd); + sProcLoaderChannelFd = -1; + Transport *transport = OpenDescriptor(*fd, Transport::MODE_CLIENT); + sProcLoaderParent = new ProcLoaderParent(fd); + sProcLoaderParent->Open(transport, + sProcLoaderPid, + XRE_GetIOMessageLoop(), + ParentSide); + sProcLoaderLoop = MessageLoop::current(); +} + +/** + * Shutdown and destroy the client of B2G loader service. + */ +static void +ProcLoaderClientDeinit() +{ + MOZ_ASSERT(sProcLoaderClientGeckoInitialized && sProcLoaderClientInitialized); + sProcLoaderClientGeckoInitialized = false; + sProcLoaderClientInitialized = false; + + sProcLoaderClientOnDeinit = true; + + MOZ_ASSERT(sProcLoaderParent != nullptr); + PProcLoaderParent *procLoaderParent = sProcLoaderParent; + sProcLoaderParent = nullptr; + sProcLoaderLoop = nullptr; + + MessageLoop::current()-> + PostTask(FROM_HERE, + NewRunnableFunction(&_ProcLoaderParentDestroy, + procLoaderParent)); +} + +struct AsyncSendLoadData +{ + nsTArray mArgv; + nsTArray mEnv; + nsTArray mFdsremap; + ChildPrivileges mPrivs; + int mCookie; +}; + +static void +AsyncSendLoad(AsyncSendLoadData *aLoad) +{ + PProcLoaderParent *loader = sProcLoaderParent; + DebugOnly ok = + loader->SendLoad(aLoad->mArgv, aLoad->mEnv, aLoad->mFdsremap, + aLoad->mPrivs, aLoad->mCookie); + MOZ_ASSERT(ok); + delete aLoad; +} + +/** + * Request the loader service, the server, to load Nuwa. + */ +bool +ProcLoaderLoad(const char *aArgv[], + const char *aEnvp[], + const file_handle_mapping_vector &aFdsRemap, + const ChildPrivileges aPrivs, + ProcessHandle *aProcessHandle) +{ + static int cookie=0; + int i; + + if (sProcLoaderParent == nullptr || sProcLoaderPid == 0) { + return false; + } + + AsyncSendLoadData *load = new AsyncSendLoadData(); + nsTArray &argv = load->mArgv; + for (i = 0; aArgv[i] != nullptr; i++) { + argv.AppendElement(nsCString(aArgv[i])); + } + nsTArray &env = load->mEnv; + for (i = 0; aEnvp[i] != nullptr; i++) { + env.AppendElement(nsCString(aEnvp[i])); + } + nsTArray &fdsremap = load->mFdsremap; + for (file_handle_mapping_vector::const_iterator fdmap = + aFdsRemap.begin(); + fdmap != aFdsRemap.end(); + fdmap++) { + fdsremap.AppendElement(FDRemap(FileDescriptor(fdmap->first), fdmap->second)); + } + load->mPrivs = aPrivs; + load->mCookie = cookie++; + + *aProcessHandle = sProcLoaderPid; + sProcLoaderPid = 0; + + sProcLoaderLoop->PostTask(FROM_HERE, + NewRunnableFunction(AsyncSendLoad, load)); + return true; +} + + +class ProcLoaderRunnerBase; + +static bool sProcLoaderServing = false; +static ProcLoaderRunnerBase *sProcLoaderDispatchedTask = nullptr; + +class ProcLoaderRunnerBase +{ +public: + virtual int DoWork() = 0; +}; + + +class ProcLoaderNoopRunner : public ProcLoaderRunnerBase { +public: + virtual int DoWork(); +}; + +int +ProcLoaderNoopRunner::DoWork() { + return 0; +} + + +/** + * The runner to load Nuwa at the current process. + */ +class ProcLoaderLoadRunner : public ProcLoaderRunnerBase { +private: + const nsTArray mArgv; + const nsTArray mEnv; + const nsTArray mFdsRemap; + const ChildPrivileges mPrivs; + + void ShuffleFds(); + +public: + ProcLoaderLoadRunner(const InfallibleTArray& aArgv, + const InfallibleTArray& aEnv, + const InfallibleTArray& aFdsRemap, + const ChildPrivileges aPrivs) + : mArgv(aArgv) + , mEnv(aEnv) + , mFdsRemap(aFdsRemap) + , mPrivs(aPrivs) {} + + int DoWork(); +}; + +void +ProcLoaderLoadRunner::ShuffleFds() +{ + unsigned int i; + + InjectiveMultimap fd_shuffle1, fd_shuffle2; + fd_shuffle1.reserve(mFdsRemap.Length()); + fd_shuffle2.reserve(mFdsRemap.Length()); + for (i = 0; i < mFdsRemap.Length(); i++) { + const FDRemap *map = &mFdsRemap[i]; + int fd = map->fd().PlatformHandle(); + int tofd = map->mapto(); + + fd_shuffle1.push_back(InjectionArc(fd, tofd, false)); + fd_shuffle2.push_back(InjectionArc(fd, tofd, false)); + } + + DebugOnly ok = ShuffleFileDescriptors(&fd_shuffle1); + MOZ_ASSERT(ok, "ShuffleFileDescriptors failed"); + + CloseSuperfluousFds(fd_shuffle2); +} + +int +ProcLoaderLoadRunner::DoWork() +{ + unsigned int i; + + ShuffleFds(); + + unsigned int argc = mArgv.Length(); + char **argv = new char *[argc + 1]; + for (i = 0; i < argc; i++) { + argv[i] = ::strdup(mArgv[i].get()); + } + argv[argc] = nullptr; + + unsigned int envc = mEnv.Length(); + for (i = 0; i < envc; i++) { + PR_SetEnv(mEnv[i].get()); + } + + SetCurrentProcessPrivileges(mPrivs); + + MOZ_ASSERT(content_process_main != nullptr, + "content_process_main not found"); + // Start Nuwa (main function) + int ret = content_process_main(argc, argv); + + for (i = 0; i < argc; i++) { + free(argv[i]); + } + delete[] argv; + + return ret; +} + + +class ProcLoaderChild : public PProcLoaderChild +{ + pid_t mPeerPid; + +public: + ProcLoaderChild(pid_t aPeerPid) : mPeerPid(aPeerPid) {} + + virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; + + virtual bool RecvLoad(const InfallibleTArray& aArgv, + const InfallibleTArray& aEnv, + const InfallibleTArray& aFdsremap, + const uint32_t& aPrivs, + const int32_t& aCookie); + + virtual void OnChannelError(); +}; + +void +ProcLoaderChild::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +static void +_ProcLoaderChildDestroy(ProcLoaderChild *aChild) +{ + aChild->Close(); + delete aChild; + MessageLoop::current()->Quit(); +} + +bool +ProcLoaderChild::RecvLoad(const InfallibleTArray& aArgv, + const InfallibleTArray& aEnv, + const InfallibleTArray& aFdsRemap, + const uint32_t& aPrivs, + const int32_t& aCookie) { + if (!sProcLoaderServing) { + return true; + } + sProcLoaderServing = false; + + MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr); + ChildPrivileges privs = static_cast(aPrivs); + sProcLoaderDispatchedTask = + new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); + + SendLoadComplete(mPeerPid, aCookie); + + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(_ProcLoaderChildDestroy, + this)); + return true; +} + +void +ProcLoaderChild::OnChannelError() +{ + if (!sProcLoaderServing) { + return; + } + sProcLoaderServing = false; + + PProcLoaderChild::OnChannelError(); + + MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr); + sProcLoaderDispatchedTask = new ProcLoaderNoopRunner(); + + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(_ProcLoaderChildDestroy, + this)); +} + +/** + * A helper class which calls NS_LogInit/NS_LogTerm in its scope. + */ +class ScopedLogging +{ +public: + ScopedLogging() { NS_LogInit(); } + ~ScopedLogging() { NS_LogTerm(); } +}; + +/** + * Run service of ProcLoader. + * + * \param aPeerPid is the pid of the parent. + * \param aFd is the file descriptor of the socket for IPC. + * + * See the comment near the head of this file. + */ +static int +ProcLoaderServiceRun(pid_t aPeerPid, int aFd, + int aArgc, const char *aArgv[]) +{ + ScopedLogging logging; + + char **_argv; + _argv = new char *[aArgc + 1]; + for (int i = 0; i < aArgc; i++) { + _argv[i] = ::strdup(aArgv[i]); + MOZ_ASSERT(_argv[i] != nullptr); + } + _argv[aArgc] = nullptr; + + gArgv = _argv; + gArgc = aArgc; + + { + gDisableAndroidLog = true; + + nsresult rv = XRE_InitCommandLine(aArgc, _argv); + if (NS_FAILED(rv)) { + gDisableAndroidLog = false; + MOZ_CRASH(); + } + + FileDescriptor fd(aFd); + close(aFd); + + MOZ_ASSERT(!sProcLoaderServing); + MessageLoop loop; + + nsAutoPtr process; + process = new ContentProcess(aPeerPid); + ChildThread *iothread = process->child_thread(); + + Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT); + ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid); + // Pass a message loop to initialize (connect) the channel + // (connection). + loaderChild->Open(transport, aPeerPid, iothread->message_loop()); + + BackgroundHangMonitor::Prohibit(); + + sProcLoaderServing = true; + loop.Run(); + + BackgroundHangMonitor::Allow(); + + XRE_DeinitCommandLine(); + + gDisableAndroidLog = false; + } + + MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr); + ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask; + sProcLoaderDispatchedTask = nullptr; + int ret = task->DoWork(); + delete task; + + for (int i = 0; i < aArgc; i++) { + free(_argv[i]); + } + delete[] _argv; + + return ret; +} + +#endif /* MOZ_B2G_LOADER */ + } // namespace ipc } // namespace mozilla + +#ifdef MOZ_B2G_LOADER +void +XRE_ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd) +{ + mozilla::ipc::ProcLoaderClientInit(aPeerPid, aChannelFd); +} + +int +XRE_ProcLoaderServiceRun(pid_t aPeerPid, int aFd, + int aArgc, const char *aArgv[]) +{ + return mozilla::ipc::ProcLoaderServiceRun(aPeerPid, aFd, + aArgc, aArgv); +} +#endif /* MOZ_B2G_LOADER */ diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index 08e50d92cfc..af3e146b629 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -130,12 +130,14 @@ IPDL_SOURCES = [ 'PBackground.ipdl', 'PBackgroundSharedTypes.ipdlh', 'PBackgroundTest.ipdl', + 'PProcLoader.ipdl', 'ProtocolTypes.ipdlh', 'URIParams.ipdlh', ] LOCAL_INCLUDES += [ + '/toolkit/xre', '/xpcom/threads', ] diff --git a/ipc/moz.build b/ipc/moz.build index 00273f514f5..53433dc2365 100644 --- a/ipc/moz.build +++ b/ipc/moz.build @@ -26,4 +26,7 @@ if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT'] or CONFIG['MOZ_NFC'] or CONFIG[ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': DIRS += ['keystore', 'netd'] +if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android': + DIRS += ['contentproc'] + DIRS += ['app'] diff --git a/js/src/jit/AsmJSFrameIterator.cpp b/js/src/asmjs/AsmJSFrameIterator.cpp similarity index 98% rename from js/src/jit/AsmJSFrameIterator.cpp rename to js/src/asmjs/AsmJSFrameIterator.cpp index c6ce830ca93..7baba1511b1 100644 --- a/js/src/jit/AsmJSFrameIterator.cpp +++ b/js/src/asmjs/AsmJSFrameIterator.cpp @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "jit/AsmJSFrameIterator.h" +#include "asmjs/AsmJSFrameIterator.h" -#include "jit/AsmJS.h" -#include "jit/AsmJSModule.h" +#include "asmjs/AsmJSModule.h" +#include "asmjs/AsmJSValidate.h" #include "jit/IonMacroAssembler.h" using namespace js; @@ -109,6 +109,10 @@ static const unsigned StoredFP = 11; static const unsigned PushedRetAddr = 4; static const unsigned PushedFP = 16; static const unsigned StoredFP = 20; +#elif defined(JS_CODEGEN_MIPS) +static const unsigned PushedRetAddr = 8; +static const unsigned PushedFP = 24; +static const unsigned StoredFP = 28; #elif defined(JS_CODEGEN_NONE) static const unsigned PushedRetAddr = 0; static const unsigned PushedFP = 1; @@ -294,7 +298,12 @@ js::GenerateAsmJSFunctionEpilogue(MacroAssembler &masm, unsigned framePushed, masm.bind(&labels->profilingJump); #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) masm.twoByteNop(); -#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS) +#elif defined(JS_CODEGEN_ARM) + masm.nop(); +#elif defined(JS_CODEGEN_MIPS) + masm.nop(); + masm.nop(); + masm.nop(); masm.nop(); #endif } diff --git a/js/src/jit/AsmJSFrameIterator.h b/js/src/asmjs/AsmJSFrameIterator.h similarity index 98% rename from js/src/jit/AsmJSFrameIterator.h rename to js/src/asmjs/AsmJSFrameIterator.h index 1dcf3f284d7..6ab4f5790d0 100644 --- a/js/src/jit/AsmJSFrameIterator.h +++ b/js/src/asmjs/AsmJSFrameIterator.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jit_AsmJSFrameIterator_h -#define jit_AsmJSFrameIterator_h +#ifndef asmjs_AsmJSFrameIterator_h +#define asmjs_AsmJSFrameIterator_h #include "mozilla/NullPtr.h" @@ -159,4 +159,4 @@ GenerateAsmJSExitEpilogue(jit::MacroAssembler &masm, unsigned framePushed, AsmJS } // namespace js -#endif // jit_AsmJSFrameIterator_h +#endif // asmjs_AsmJSFrameIterator_h diff --git a/js/src/jit/AsmJSLink.cpp b/js/src/asmjs/AsmJSLink.cpp similarity index 98% rename from js/src/jit/AsmJSLink.cpp rename to js/src/asmjs/AsmJSLink.cpp index e06b076e862..d1fef0f53ef 100644 --- a/js/src/jit/AsmJSLink.cpp +++ b/js/src/asmjs/AsmJSLink.cpp @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "jit/AsmJSLink.h" +#include "asmjs/AsmJSLink.h" #include "mozilla/PodOperations.h" @@ -17,8 +17,8 @@ #include "jsprf.h" #include "jswrapper.h" +#include "asmjs/AsmJSModule.h" #include "frontend/BytecodeCompiler.h" -#include "jit/AsmJSModule.h" #include "jit/Ion.h" #include "jit/JitCommon.h" #ifdef JS_ION_PERF @@ -185,11 +185,11 @@ ValidateMathBuiltinFunction(JSContext *cx, AsmJSModule::Global &global, HandleVa case AsmJSMathBuiltin_floor: native = math_floor; break; case AsmJSMathBuiltin_exp: native = math_exp; break; case AsmJSMathBuiltin_log: native = math_log; break; - case AsmJSMathBuiltin_pow: native = js_math_pow; break; - case AsmJSMathBuiltin_sqrt: native = js_math_sqrt; break; - case AsmJSMathBuiltin_min: native = js_math_min; break; - case AsmJSMathBuiltin_max: native = js_math_max; break; - case AsmJSMathBuiltin_abs: native = js_math_abs; break; + case AsmJSMathBuiltin_pow: native = math_pow; break; + case AsmJSMathBuiltin_sqrt: native = math_sqrt; break; + case AsmJSMathBuiltin_min: native = math_min; break; + case AsmJSMathBuiltin_max: native = math_max; break; + case AsmJSMathBuiltin_abs: native = math_abs; break; case AsmJSMathBuiltin_atan2: native = math_atan2; break; case AsmJSMathBuiltin_imul: native = math_imul; break; case AsmJSMathBuiltin_fround: native = math_fround; break; diff --git a/js/src/jit/AsmJSLink.h b/js/src/asmjs/AsmJSLink.h similarity index 95% rename from js/src/jit/AsmJSLink.h rename to js/src/asmjs/AsmJSLink.h index 7fa847ae75b..bcc0eb7140a 100644 --- a/js/src/jit/AsmJSLink.h +++ b/js/src/asmjs/AsmJSLink.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jit_AsmJSLink_h -#define jit_AsmJSLink_h +#ifndef asmjs_AsmJSLink_h +#define asmjs_AsmJSLink_h #include "NamespaceImports.h" @@ -47,4 +47,4 @@ AsmJSFunctionToString(JSContext *cx, HandleFunction fun); } // namespace js -#endif // jit_AsmJS_h +#endif // asmjs_AsmJSLink_h diff --git a/js/src/jit/AsmJSModule.cpp b/js/src/asmjs/AsmJSModule.cpp similarity index 98% rename from js/src/jit/AsmJSModule.cpp rename to js/src/asmjs/AsmJSModule.cpp index ba6bb99e049..dd4a93742f4 100644 --- a/js/src/jit/AsmJSModule.cpp +++ b/js/src/asmjs/AsmJSModule.cpp @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "jit/AsmJSModule.h" +#include "asmjs/AsmJSModule.h" #include @@ -1583,6 +1583,9 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext *cx) BOffImm calleeOffset; callerInsn->as()->extractImm(&calleeOffset); void *callee = calleeOffset.getDest(callerInsn); +#elif defined(JS_CODEGEN_MIPS) + Instruction *instr = (Instruction *)(callerRetAddr - 4 * sizeof(uint32_t)); + void *callee = (void *)Assembler::ExtractLuiOriValue(instr, instr->next()); #elif defined(JS_CODEGEN_NONE) MOZ_CRASH(); void *callee = nullptr; @@ -1604,6 +1607,10 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext *cx) JSC::X86Assembler::setRel32(callerRetAddr, newCallee); #elif defined(JS_CODEGEN_ARM) new (caller) InstBLImm(BOffImm(newCallee - caller), Assembler::Always); +#elif defined(JS_CODEGEN_MIPS) + Assembler::WriteLuiOriInstructions(instr, instr->next(), + ScratchRegister, (uint32_t)newCallee); + instr[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr); #elif defined(JS_CODEGEN_NONE) MOZ_CRASH(); #else @@ -1663,6 +1670,17 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext *cx) JS_ASSERT(reinterpret_cast(jump)->is()); new (jump) InstNOP(); } +#elif defined(JS_CODEGEN_MIPS) + Instruction *instr = (Instruction *)jump; + if (enabled) { + Assembler::WriteLuiOriInstructions(instr, instr->next(), + ScratchRegister, (uint32_t)profilingEpilogue); + instr[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr); + } else { + instr[0].makeNop(); + instr[1].makeNop(); + instr[2].makeNop(); + } #elif defined(JS_CODEGEN_NONE) MOZ_CRASH(); #else diff --git a/js/src/jit/AsmJSModule.h b/js/src/asmjs/AsmJSModule.h similarity index 99% rename from js/src/jit/AsmJSModule.h rename to js/src/asmjs/AsmJSModule.h index 5ed85cc8f4c..5c45e8ece08 100644 --- a/js/src/jit/AsmJSModule.h +++ b/js/src/asmjs/AsmJSModule.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jit_AsmJSModule_h -#define jit_AsmJSModule_h +#ifndef asmjs_AsmJSModule_h +#define asmjs_AsmJSModule_h #include "mozilla/Maybe.h" #include "mozilla/Move.h" @@ -13,9 +13,9 @@ #include "jsscript.h" +#include "asmjs/AsmJSFrameIterator.h" +#include "asmjs/AsmJSValidate.h" #include "gc/Marking.h" -#include "jit/AsmJS.h" -#include "jit/AsmJSFrameIterator.h" #include "jit/IonMacroAssembler.h" #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" @@ -1223,4 +1223,4 @@ class AsmJSModuleObject : public JSObject } // namespace js -#endif /* jit_AsmJSModule_h */ +#endif /* asmjs_AsmJSModule_h */ diff --git a/js/src/jit/AsmJSSignalHandlers.cpp b/js/src/asmjs/AsmJSSignalHandlers.cpp similarity index 99% rename from js/src/jit/AsmJSSignalHandlers.cpp rename to js/src/asmjs/AsmJSSignalHandlers.cpp index 33d33c5ec35..8727949cc28 100644 --- a/js/src/jit/AsmJSSignalHandlers.cpp +++ b/js/src/asmjs/AsmJSSignalHandlers.cpp @@ -4,12 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "jit/AsmJSSignalHandlers.h" +#include "asmjs/AsmJSSignalHandlers.h" #include "mozilla/DebugOnly.h" +#include "asmjs/AsmJSModule.h" #include "assembler/assembler/MacroAssembler.h" -#include "jit/AsmJSModule.h" #include "vm/Runtime.h" using namespace js; @@ -969,7 +969,7 @@ AsmJSFaultHandler(int signum, siginfo_t *info, void *context) #endif #if !defined(XP_MACOSX) -static bool sHandlersInstalled = false; +static bool sInstalledHandlers = false; #endif bool @@ -989,7 +989,7 @@ js::EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt) #else // Assume Windows or Unix. For these platforms, there is a single, // process-wide signal handler installed. Take care to only install it once. - if (sHandlersInstalled) + if (sInstalledHandlers) return true; # if defined(XP_WIN) @@ -1007,7 +1007,7 @@ js::EnsureAsmJSSignalHandlersInstalled(JSRuntime *rt) return false; # endif - sHandlersInstalled = true; + sInstalledHandlers = true; #endif return true; } diff --git a/js/src/jit/AsmJSSignalHandlers.h b/js/src/asmjs/AsmJSSignalHandlers.h similarity index 93% rename from js/src/jit/AsmJSSignalHandlers.h rename to js/src/asmjs/AsmJSSignalHandlers.h index 3150d6bf055..dea8f6fb645 100644 --- a/js/src/jit/AsmJSSignalHandlers.h +++ b/js/src/asmjs/AsmJSSignalHandlers.h @@ -4,8 +4,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef jit_AsmJSSignalHandlers_h -#define jit_AsmJSSignalHandlers_h +#ifndef asmjs_AsmJSSignalHandlers_h +#define asmjs_AsmJSSignalHandlers_h struct JSRuntime; @@ -52,4 +52,4 @@ class AsmJSMachExceptionHandler } // namespace js -#endif // jit_AsmJSSignalHandlers_h +#endif // asmjs_AsmJSSignalHandlers_h diff --git a/js/src/jit/AsmJS.cpp b/js/src/asmjs/AsmJSValidate.cpp similarity index 99% rename from js/src/jit/AsmJS.cpp rename to js/src/asmjs/AsmJSValidate.cpp index 709f82fbe2a..011e9bfc598 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "jit/AsmJS.h" +#include "asmjs/AsmJSValidate.h" #include "mozilla/Move.h" #include "mozilla/UniquePtr.h" @@ -17,10 +17,10 @@ #include "jsprf.h" #include "prmjtime.h" +#include "asmjs/AsmJSLink.h" +#include "asmjs/AsmJSModule.h" +#include "asmjs/AsmJSSignalHandlers.h" #include "frontend/Parser.h" -#include "jit/AsmJSLink.h" -#include "jit/AsmJSModule.h" -#include "jit/AsmJSSignalHandlers.h" #include "jit/CodeGenerator.h" #include "jit/CompileWrappers.h" #include "jit/MIR.h" @@ -6373,6 +6373,14 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit masm.storePtr(reg2, Address(reg0, offsetOfJitJSContext)); } + JS_ASSERT(masm.framePushed() == framePushed); +#if defined(JS_CODEGEN_X64) + masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg); +#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS) + masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg); + masm.loadPtr(Address(StackPointer, savedGlobalOffset), GlobalReg); +#endif + masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel); Label oolConvert; @@ -6394,14 +6402,6 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit Label done; masm.bind(&done); - JS_ASSERT(masm.framePushed() == framePushed); -#if defined(JS_CODEGEN_X64) - masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg); -#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS) - masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg); - masm.loadPtr(Address(StackPointer, savedGlobalOffset), GlobalReg); -#endif - Label profilingReturn; GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::FFI, &profilingReturn); diff --git a/js/src/jit/AsmJS.h b/js/src/asmjs/AsmJSValidate.h similarity index 100% rename from js/src/jit/AsmJS.h rename to js/src/asmjs/AsmJSValidate.h diff --git a/js/src/assembler/assembler/AssemblerBuffer.h b/js/src/assembler/assembler/AssemblerBuffer.h index b66b3826bf4..5f8a644880c 100644 --- a/js/src/assembler/assembler/AssemblerBuffer.h +++ b/js/src/assembler/assembler/AssemblerBuffer.h @@ -36,14 +36,13 @@ #include #include -#include "assembler/jit/ExecutableAllocator.h" -#include "assembler/wtf/Assertions.h" - #include + #include "jsfriendapi.h" #include "jsopcode.h" #include "jsutil.h" +#include "jit/ExecutableAllocator.h" #include "jit/IonSpewer.h" #include "js/RootingAPI.h" @@ -88,7 +87,7 @@ namespace JSC { void putByteUnchecked(int value) { - ASSERT(!(m_size > m_capacity - 4)); + MOZ_ASSERT(!(m_size > m_capacity - 4)); m_buffer[m_size] = char(value); m_size++; } @@ -102,7 +101,7 @@ namespace JSC { void putShortUnchecked(int value) { - ASSERT(!(m_size > m_capacity - 4)); + MOZ_ASSERT(!(m_size > m_capacity - 4)); *reinterpret_cast(&m_buffer[m_size]) = short(value); m_size += 2; } @@ -116,14 +115,14 @@ namespace JSC { void putIntUnchecked(int value) { - ASSERT(!(m_size > m_capacity - 4)); + MOZ_ASSERT(!(m_size > m_capacity - 4)); *reinterpret_cast(&m_buffer[m_size]) = value; m_size += 4; } void putInt64Unchecked(int64_t value) { - ASSERT(!(m_size > m_capacity - 8)); + MOZ_ASSERT(!(m_size > m_capacity - 8)); *reinterpret_cast(&m_buffer[m_size]) = value; m_size += 8; } @@ -181,7 +180,7 @@ namespace JSC { } unsigned char *buffer() const { - ASSERT(!m_oom); + MOZ_ASSERT(!m_oom); return reinterpret_cast(m_buffer); } diff --git a/js/src/assembler/assembler/MacroAssemblerX86Common.h b/js/src/assembler/assembler/MacroAssemblerX86Common.h index da75678b391..eb9c385d683 100644 --- a/js/src/assembler/assembler/MacroAssemblerX86Common.h +++ b/js/src/assembler/assembler/MacroAssemblerX86Common.h @@ -59,7 +59,7 @@ public: MacroAssemblerX86Common::setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState; } @@ -80,7 +80,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSE; #endif @@ -95,7 +95,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSE2; #endif @@ -120,7 +120,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSE3; #endif @@ -135,7 +135,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSSE3; #endif @@ -150,7 +150,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSE4_1; #endif @@ -165,7 +165,7 @@ private: setSSECheckState(); } // Only check once. - ASSERT(s_sseCheckState != NotCheckedSSE); + MOZ_ASSERT(s_sseCheckState != NotCheckedSSE); return s_sseCheckState >= HasSSE4_2; #endif diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index f6cdb99867f..62f86e969f4 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -37,7 +37,6 @@ #if ENABLE_ASSEMBLER && (WTF_CPU_X86 || WTF_CPU_X86_64) #include "assembler/assembler/AssemblerBuffer.h" -#include "assembler/wtf/Assertions.h" #include "js/Vector.h" namespace JSC { @@ -430,7 +429,7 @@ public: : m_offset(offset) , m_used(false) { - ASSERT(m_offset == offset); + MOZ_ASSERT(m_offset == offset); } int offset() const { return m_offset; @@ -3266,8 +3265,8 @@ public: void linkJump(JmpSrc from, JmpDst to) { - ASSERT(from.m_offset != -1); - ASSERT(to.m_offset != -1); + MOZ_ASSERT(from.m_offset != -1); + MOZ_ASSERT(to.m_offset != -1); // Sanity check - if the assembler has OOM'd, it will start overwriting // its internal buffer and thus our links could be garbage. @@ -3282,7 +3281,7 @@ public: static void linkJump(void* code, JmpSrc from, void* to) { - ASSERT(from.m_offset != -1); + MOZ_ASSERT(from.m_offset != -1); staticSpew("##link ((%d)) jumps to ((%p))", from.m_offset, to); @@ -3291,7 +3290,7 @@ public: static void linkCall(void* code, JmpSrc from, void* to) { - ASSERT(from.m_offset != -1); + MOZ_ASSERT(from.m_offset != -1); staticSpew("##linkCall"); setRel32(reinterpret_cast(code) + from.m_offset, to); @@ -3299,7 +3298,7 @@ public: static void linkPointer(void* code, JmpDst where, void* value) { - ASSERT(where.m_offset != -1); + MOZ_ASSERT(where.m_offset != -1); staticSpew("##linkPointer"); setPointer(reinterpret_cast(code) + where.m_offset, value); @@ -3366,20 +3365,20 @@ public: static unsigned getCallReturnOffset(JmpSrc call) { - ASSERT(call.m_offset >= 0); + MOZ_ASSERT(call.m_offset >= 0); return call.m_offset; } static void* getRelocatedAddress(void* code, JmpSrc jump) { - ASSERT(jump.m_offset != -1); + MOZ_ASSERT(jump.m_offset != -1); return reinterpret_cast(reinterpret_cast(code) + jump.m_offset); } static void* getRelocatedAddress(void* code, JmpDst destination) { - ASSERT(destination.m_offset != -1); + MOZ_ASSERT(destination.m_offset != -1); return reinterpret_cast(reinterpret_cast(code) + destination.m_offset); } @@ -3412,7 +3411,7 @@ public: static void setRel32(void* from, void* to) { intptr_t offset = reinterpret_cast(to) - reinterpret_cast(from); - ASSERT(offset == static_cast(offset)); + MOZ_ASSERT(offset == static_cast(offset)); #define JS_CRASH(x) *(int *)x = 0 if (offset != static_cast(offset)) JS_CRASH(0xC0DE); @@ -3459,7 +3458,7 @@ public: static int32_t addressImmediate(const void *address) { #if WTF_CPU_X86_64 // x64's 64-bit addresses don't all fit in the 32-bit immediate. - ASSERT(isAddressImmediate(address)); + MOZ_ASSERT(isAddressImmediate(address)); #endif return static_cast(reinterpret_cast(address)); } @@ -3759,7 +3758,7 @@ private: void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm) { #if !WTF_CPU_X86_64 - ASSERT(!byteRegRequiresRex(rm)); + MOZ_ASSERT(!byteRegRequiresRex(rm)); #endif m_buffer.ensureSpace(maxInstructionSize); emitRexIf(byteRegRequiresRex(rm), 0, 0, rm); @@ -3770,7 +3769,7 @@ private: // Like oneByteOp8, but never emits a REX prefix. void oneByteOp8_norex(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm) { - ASSERT(!regRequiresRex(rm)); + MOZ_ASSERT(!regRequiresRex(rm)); m_buffer.ensureSpace(maxInstructionSize); m_buffer.putByteUnchecked(opcode); registerModRM(groupOp, rm); @@ -3779,7 +3778,7 @@ private: void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) { #if !WTF_CPU_X86_64 - ASSERT(!byteRegRequiresRex(reg)); + MOZ_ASSERT(!byteRegRequiresRex(reg)); #endif m_buffer.ensureSpace(maxInstructionSize); emitRexIf(byteRegRequiresRex(reg), reg, 0, base); @@ -3790,7 +3789,7 @@ private: void oneByteOp8_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) { #if !WTF_CPU_X86_64 - ASSERT(!byteRegRequiresRex(reg)); + MOZ_ASSERT(!byteRegRequiresRex(reg)); #endif m_buffer.ensureSpace(maxInstructionSize); emitRexIf(byteRegRequiresRex(reg), reg, 0, base); @@ -3801,7 +3800,7 @@ private: void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset) { #if !WTF_CPU_X86_64 - ASSERT(!byteRegRequiresRex(reg)); + MOZ_ASSERT(!byteRegRequiresRex(reg)); #endif m_buffer.ensureSpace(maxInstructionSize); emitRexIf(byteRegRequiresRex(reg), reg, index, base); @@ -3996,7 +3995,7 @@ private: void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale) { - ASSERT(mode != ModRmRegister); + MOZ_ASSERT(mode != ModRmRegister); putModRm(mode, reg, hasSib); m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7)); @@ -4061,7 +4060,7 @@ private: void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset) { - ASSERT(index != noIndex); + MOZ_ASSERT(index != noIndex); #if WTF_CPU_X86_64 if (!offset && (base != noBase) && (base != noBase2)) @@ -4080,7 +4079,7 @@ private: void memoryModRM_disp32(int reg, RegisterID index, int scale, int offset) { - ASSERT(index != noIndex); + MOZ_ASSERT(index != noIndex); // NB: the base-less memoryModRM overloads generate different code // then the base-full memoryModRM overloads in the base == noBase diff --git a/js/src/assembler/wtf/Assertions.cpp b/js/src/assembler/wtf/Assertions.cpp deleted file mode 100644 index a460ce16df0..00000000000 --- a/js/src/assembler/wtf/Assertions.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "assembler/wtf/Assertions.h" - -#include -#include -#include - -#if WTF_COMPILER_MSVC -#ifndef WINVER -#define WINVER 0x0500 -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif -#include "jswin.h" -#include -#endif - -extern "C" { - -WTF_ATTRIBUTE_PRINTF(1, 0) -static void vprintf_stderr_common(const char* format, va_list args) -{ - vfprintf(stderr, format, args); -} - -WTF_ATTRIBUTE_PRINTF(1, 2) -static void printf_stderr_common(const char* format, ...) -{ - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); -} - -static void printCallSite(const char* file, int line, const char* function) -{ -#if WTF_COMPILER_MSVC && defined _DEBUG - _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function); -#else - printf_stderr_common("(%s:%d %s)\n", file, line, function); -#endif -} - -void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion) -{ - if (assertion) - printf_stderr_common("Assertion failure: %s\n", assertion); - else - printf_stderr_common("Should never be reached\n"); - printCallSite(file, line, function); -} - -void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) -{ - printf_stderr_common("Assertion failure: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n%s\n", assertion); - printCallSite(file, line, function); -} - -void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion) -{ - printf_stderr_common("Argument bad: %s, %s\n", argName, assertion); - printCallSite(file, line, function); -} - -void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) -{ - printf_stderr_common("Fatal error: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -void WTFReportError(const char* file, int line, const char* function, const char* format, ...) -{ - printf_stderr_common("Error: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -void WTFLog(WTFLogChannel* channel, const char* format, ...) -{ - if (channel->state != WTFLogChannelOn) - return; - - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - if (format[strlen(format) - 1] != '\n') - printf_stderr_common("\n"); -} - -void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) -{ - if (channel->state != WTFLogChannelOn) - return; - - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - if (format[strlen(format) - 1] != '\n') - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -} // extern "C" diff --git a/js/src/assembler/wtf/Assertions.h b/js/src/assembler/wtf/Assertions.h deleted file mode 100644 index d8158bfc95f..00000000000 --- a/js/src/assembler/wtf/Assertions.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef assembler_wtf_Assertions_h -#define assembler_wtf_Assertions_h - -#include "assembler/wtf/Platform.h" -#include "mozilla/Assertions.h" - -#ifndef DEBUG - /* - * Prevent unused-variable warnings by defining the macro WTF uses to test - * for assertions taking effect. - */ -# define ASSERT_DISABLED 1 -#endif - -#ifndef ASSERT -#define ASSERT(assertion) MOZ_ASSERT(assertion) -#endif -#define ASSERT_UNUSED(variable, assertion) do { \ - (void)variable; \ - ASSERT(assertion); \ -} while (0) -#define ASSERT_NOT_REACHED() MOZ_ASSUME_UNREACHABLE("wtf/Assertions.h") -#define CRASH() MOZ_CRASH() -#define COMPILE_ASSERT(exp, name) static_assert(exp, #name) - -#endif /* assembler_wtf_Assertions_h */ diff --git a/js/src/assembler/wtf/VMTags.h b/js/src/assembler/wtf/VMTags.h deleted file mode 100644 index 4e3a4789f85..00000000000 --- a/js/src/assembler/wtf/VMTags.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef assembler_wtf_VMTags_h -#define assembler_wtf_VMTags_h - -// On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map -// in order to aid tools that inspect system memory use. -#if WTF_PLATFORM_DARWIN - -#include - -#if !defined(TARGETING_TIGER) - -#if defined(VM_MEMORY_TCMALLOC) -#define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(VM_MEMORY_TCMALLOC) -#else -#define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(53) -#endif // defined(VM_MEMORY_TCMALLOC) - -#if defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) -#else -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(64) -#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) - -#if defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) -#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) -#else -#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65) -#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) - -#else // !defined(TARGETING_TIGER) - -// mmap on Tiger fails with tags that work on Leopard, so fall -// back to Tiger-compatible tags (that also work on Leopard) -// when targeting Tiger. -#define VM_TAG_FOR_TCMALLOC_MEMORY -1 -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1 -#define VM_TAG_FOR_REGISTERFILE_MEMORY -1 - -#endif // !defined(TARGETING_TIGER) - -// Tags for vm_map and vm_allocate work on both Tiger and Leopard. - -#if defined(VM_MEMORY_JAVASCRIPT_CORE) -#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_CORE) -#else -#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63) -#endif // defined(VM_MEMORY_JAVASCRIPT_CORE) - -#if defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) -#else -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69) -#endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) - -#else // OS(DARWIN) - -#define VM_TAG_FOR_TCMALLOC_MEMORY -1 -#define VM_TAG_FOR_COLLECTOR_MEMORY -1 -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1 -#define VM_TAG_FOR_REGISTERFILE_MEMORY -1 -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1 - -#endif // OS(DARWIN) - -#endif /* assembler_wtf_VMTags_h */ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 4917c5ac261..644e4164ec9 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -19,8 +19,8 @@ #endif #include "jswrapper.h" -#include "jit/AsmJS.h" -#include "jit/AsmJSLink.h" +#include "asmjs/AsmJSLink.h" +#include "asmjs/AsmJSValidate.h" #include "js/HashTable.h" #include "js/StructuredClone.h" #include "js/UbiNode.h" diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index e3398374ad6..3bb5f9e3097 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -36,7 +36,7 @@ function indirectCallCannotGC(fullCaller, fullVariable) if (name == "op" && /GetWeakmapKeyDelegate/.test(caller)) return true; - var CheckCallArgs = "AsmJS.cpp:uint8 CheckCallArgs(FunctionCompiler*, js::frontend::ParseNode*, (uint8)(FunctionCompiler*,js::frontend::ParseNode*,Type)*, FunctionCompiler::Call*)"; + var CheckCallArgs = "AsmJSValidate.cpp:uint8 CheckCallArgs(FunctionCompiler*, js::frontend::ParseNode*, (uint8)(FunctionCompiler*,js::frontend::ParseNode*,Type)*, FunctionCompiler::Call*)"; if (name == "checkArg" && caller == CheckCallArgs) return true; diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 6dbd7c84886..2c29a13918b 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -9,11 +9,11 @@ #include "jscntxt.h" #include "jsscript.h" +#include "asmjs/AsmJSLink.h" #include "frontend/BytecodeEmitter.h" #include "frontend/FoldConstants.h" #include "frontend/NameFunctions.h" #include "frontend/Parser.h" -#include "jit/AsmJSLink.h" #include "vm/GlobalObject.h" #include "vm/TraceLogging.h" diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index d738d244247..7b0f16aeae2 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -27,9 +27,9 @@ #include "jstypes.h" #include "jsutil.h" +#include "asmjs/AsmJSLink.h" #include "frontend/Parser.h" #include "frontend/TokenStream.h" -#include "jit/AsmJSLink.h" #include "vm/Debugger.h" #include "jsatominlines.h" diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 34d24ee20e3..c6f17ed968f 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -28,11 +28,11 @@ #include "jsscript.h" #include "jstypes.h" +#include "asmjs/AsmJSValidate.h" #include "frontend/BytecodeCompiler.h" #include "frontend/FoldConstants.h" #include "frontend/ParseMaps.h" #include "frontend/TokenStream.h" -#include "jit/AsmJS.h" #include "vm/Shape.h" #include "jsatominlines.h" diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 15bcd0aa264..c0b0c409b0e 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -16,12 +16,12 @@ #include "jsnum.h" #include "jsprf.h" +#include "asmjs/AsmJSModule.h" #include "builtin/Eval.h" #include "builtin/TypedObject.h" #ifdef JSGC_GENERATIONAL # include "gc/Nursery.h" #endif -#include "jit/AsmJSModule.h" #include "jit/IonCaches.h" #include "jit/IonLinker.h" #include "jit/IonOptimizationLevels.h" diff --git a/js/src/assembler/jit/ExecutableAllocator.cpp b/js/src/jit/ExecutableAllocator.cpp similarity index 98% rename from js/src/assembler/jit/ExecutableAllocator.cpp rename to js/src/jit/ExecutableAllocator.cpp index 19378a17b84..4d44b87f708 100644 --- a/js/src/assembler/jit/ExecutableAllocator.cpp +++ b/js/src/jit/ExecutableAllocator.cpp @@ -25,7 +25,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "assembler/jit/ExecutableAllocator.h" +#include "jit/ExecutableAllocator.h" #include "js/MemoryMetrics.h" diff --git a/js/src/assembler/jit/ExecutableAllocator.h b/js/src/jit/ExecutableAllocator.h similarity index 100% rename from js/src/assembler/jit/ExecutableAllocator.h rename to js/src/jit/ExecutableAllocator.h index 7ec50d3570a..b4c034e0734 100644 --- a/js/src/assembler/jit/ExecutableAllocator.h +++ b/js/src/jit/ExecutableAllocator.h @@ -26,8 +26,8 @@ #ifndef assembler_jit_ExecutableAllocator_h #define assembler_jit_ExecutableAllocator_h -#include // for ptrdiff_t #include +#include // for ptrdiff_t #include "jsalloc.h" diff --git a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp b/js/src/jit/ExecutableAllocatorPosix.cpp similarity index 92% rename from js/src/assembler/jit/ExecutableAllocatorPosix.cpp rename to js/src/jit/ExecutableAllocatorPosix.cpp index 3b3e49bda17..ecf14cecdda 100644 --- a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp +++ b/js/src/jit/ExecutableAllocatorPosix.cpp @@ -23,17 +23,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "assembler/jit/ExecutableAllocator.h" +#include "jit/ExecutableAllocator.h" #if ENABLE_ASSEMBLER && WTF_OS_UNIX && !WTF_OS_SYMBIAN +#include "mozilla/DebugOnly.h" +#include "mozilla/TaggedAnonymousMemory.h" + #include #include -#include "mozilla/TaggedAnonymousMemory.h" - -#include "assembler/wtf/Assertions.h" -#include "assembler/wtf/VMTags.h" #include "js/Utility.h" namespace JSC { @@ -45,7 +44,7 @@ size_t ExecutableAllocator::determinePageSize() ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) { - void *allocation = MozTaggedAnonymousMmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0, "js-jit-code"); + void *allocation = MozTaggedAnonymousMmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, -1, 0, "js-jit-code"); if (allocation == MAP_FAILED) allocation = NULL; ExecutablePool::Allocation alloc = { reinterpret_cast(allocation), n }; @@ -54,8 +53,8 @@ ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) { - int result = munmap(alloc.pages, alloc.size); - ASSERT_UNUSED(result, !result); + mozilla::DebugOnly result = munmap(alloc.pages, alloc.size); + MOZ_ASSERT(!result); } #if WTF_ENABLE_ASSEMBLER_WX_EXCLUSIVE diff --git a/js/src/assembler/jit/ExecutableAllocatorWin.cpp b/js/src/jit/ExecutableAllocatorWin.cpp similarity index 98% rename from js/src/assembler/jit/ExecutableAllocatorWin.cpp rename to js/src/jit/ExecutableAllocatorWin.cpp index 427bb11f881..2f92b6d8ed3 100644 --- a/js/src/assembler/jit/ExecutableAllocatorWin.cpp +++ b/js/src/jit/ExecutableAllocatorWin.cpp @@ -23,7 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "assembler/jit/ExecutableAllocator.h" +#include "jit/ExecutableAllocator.h" #if ENABLE_ASSEMBLER && WTF_OS_WINDOWS diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index d106c1a720b..8be39c006c5 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -12,9 +12,9 @@ #include "jscompartment.h" #include "jsprf.h" +#include "asmjs/AsmJSModule.h" #include "gc/Marking.h" #include "jit/AliasAnalysis.h" -#include "jit/AsmJSModule.h" #include "jit/BacktrackingAllocator.h" #include "jit/BaselineDebugModeOSR.h" #include "jit/BaselineFrame.h" diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index 19d77f36288..1ef83378174 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -14,8 +14,8 @@ #include "jsinfer.h" #include "jstypes.h" -#include "assembler/jit/ExecutableAllocator.h" #include "gc/Heap.h" +#include "jit/ExecutableAllocator.h" #include "jit/IonOptimizationLevels.h" #include "jit/IonTypes.h" diff --git a/js/src/jit/IonLinker.h b/js/src/jit/IonLinker.h index 7b86a91207e..de044c002b9 100644 --- a/js/src/jit/IonLinker.h +++ b/js/src/jit/IonLinker.h @@ -11,7 +11,7 @@ #include "jscompartment.h" #include "jsgc.h" -#include "assembler/jit/ExecutableAllocator.h" +#include "jit/ExecutableAllocator.h" #include "jit/IonCode.h" #include "jit/IonMacroAssembler.h" #include "jit/JitCompartment.h" diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 9b6f8ab56c6..6e4b2639b95 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -46,7 +46,7 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) return inlineArraySplice(callInfo); // Math natives. - if (native == js_math_abs) + if (native == js::math_abs) return inlineMathAbs(callInfo); if (native == js::math_floor) return inlineMathFloor(callInfo); @@ -54,19 +54,19 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) return inlineMathCeil(callInfo); if (native == js::math_round) return inlineMathRound(callInfo); - if (native == js_math_sqrt) + if (native == js::math_sqrt) return inlineMathSqrt(callInfo); - if (native == math_atan2) + if (native == js::math_atan2) return inlineMathAtan2(callInfo); if (native == js::math_hypot) return inlineMathHypot(callInfo); - if (native == js_math_max) + if (native == js::math_max) return inlineMathMinMax(callInfo, true /* max */); - if (native == js_math_min) + if (native == js::math_min) return inlineMathMinMax(callInfo, false /* max */); - if (native == js_math_pow) + if (native == js::math_pow) return inlineMathPow(callInfo); - if (native == js_math_random) + if (native == js::math_random) return inlineMathRandom(callInfo); if (native == js::math_imul) return inlineMathImul(callInfo); diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 32584fdbc75..fd85f536b2e 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -6,7 +6,7 @@ #include "jit/MIRGraph.h" -#include "jit/AsmJS.h" +#include "asmjs/AsmJSValidate.h" #include "jit/BytecodeAnalysis.h" #include "jit/Ion.h" #include "jit/IonSpewer.h" diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index aa4e9dc0281..e898691fb7d 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -697,7 +697,7 @@ RPow::recover(JSContext *cx, SnapshotIterator &iter) const RootedValue result(cx); MOZ_ASSERT(base.isNumber() && power.isNumber()); - if (!js_math_pow_handle(cx, base, power, &result)) + if (!js::math_pow_handle(cx, base, power, &result)) return false; iter.storeInstructionResult(result); @@ -724,7 +724,7 @@ RPowHalf::recover(JSContext *cx, SnapshotIterator &iter) const power.setNumber(0.5); MOZ_ASSERT(base.isNumber()); - if (!js_math_pow_handle(cx, base, power, &result)) + if (!js::math_pow_handle(cx, base, power, &result)) return false; iter.storeInstructionResult(result); @@ -752,7 +752,7 @@ RMinMax::recover(JSContext *cx, SnapshotIterator &iter) const RootedValue b(cx, iter.read()); RootedValue result(cx); - if (!js_minmax_impl(cx, isMax_, a, b, &result)) + if (!js::minmax_impl(cx, isMax_, a, b, &result)) return false; iter.storeInstructionResult(result); @@ -776,7 +776,7 @@ RAbs::recover(JSContext *cx, SnapshotIterator &iter) const RootedValue v(cx, iter.read()); RootedValue result(cx); - if (!js_math_abs_handle(cx, v, &result)) + if (!js::math_abs_handle(cx, v, &result)) return false; iter.storeInstructionResult(result); diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 116c031026d..75f54835065 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -12,9 +12,9 @@ #include "jscompartment.h" #include "jsutil.h" -#include "assembler/jit/ExecutableAllocator.h" #include "gc/Marking.h" #include "jit/arm/MacroAssembler-arm.h" +#include "jit/ExecutableAllocator.h" #include "jit/JitCompartment.h" using namespace js; diff --git a/js/src/jit/arm/Simulator-arm.cpp b/js/src/jit/arm/Simulator-arm.cpp index 2c2e8b3145e..68930a6a9e5 100644 --- a/js/src/jit/arm/Simulator-arm.cpp +++ b/js/src/jit/arm/Simulator-arm.cpp @@ -33,8 +33,8 @@ #include "mozilla/Likely.h" #include "mozilla/MathAlgorithms.h" +#include "asmjs/AsmJSValidate.h" #include "jit/arm/Assembler-arm.h" -#include "jit/AsmJS.h" #include "vm/Runtime.h" extern "C" { diff --git a/js/src/jit/mips/Architecture-mips.cpp b/js/src/jit/mips/Architecture-mips.cpp index fb78d763088..d722c5b3188 100644 --- a/js/src/jit/mips/Architecture-mips.cpp +++ b/js/src/jit/mips/Architecture-mips.cpp @@ -9,6 +9,8 @@ #include #include +#include "jit/RegisterSets.h" + #define HWCAP_MIPS (1 << 31) #define HWCAP_FPU (1 << 0) diff --git a/js/src/jit/mips/Architecture-mips.h b/js/src/jit/mips/Architecture-mips.h index 0fa3ed93f2b..bc949d43dae 100644 --- a/js/src/jit/mips/Architecture-mips.h +++ b/js/src/jit/mips/Architecture-mips.h @@ -7,6 +7,8 @@ #ifndef jit_mips_Architecture_mips_h #define jit_mips_Architecture_mips_h +#include "mozilla/MathAlgorithms.h" + #include #include diff --git a/js/src/jit/mips/Assembler-mips.cpp b/js/src/jit/mips/Assembler-mips.cpp index 045ec433268..58a077255fc 100644 --- a/js/src/jit/mips/Assembler-mips.cpp +++ b/js/src/jit/mips/Assembler-mips.cpp @@ -12,8 +12,8 @@ #include "jscompartment.h" #include "jsutil.h" -#include "assembler/jit/ExecutableAllocator.h" #include "gc/Marking.h" +#include "jit/ExecutableAllocator.h" #include "jit/JitCompartment.h" using mozilla::DebugOnly; diff --git a/js/src/jit/mips/MacroAssembler-mips.cpp b/js/src/jit/mips/MacroAssembler-mips.cpp index 5cc9747e6a4..60fab33e2b8 100644 --- a/js/src/jit/mips/MacroAssembler-mips.cpp +++ b/js/src/jit/mips/MacroAssembler-mips.cpp @@ -939,6 +939,18 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label *label, JumpKind jumpKind if (label->bound()) { int32_t offset = label->offset() - m_buffer.nextOffset().getOffset(); + // Generate the long jump for calls because return address has to be + // the address after the reserved block. + if (code.encode() == inst_bgezal.encode()) { + MOZ_ASSERT(jumpKind != ShortJump); + // Handle long call + addLongJump(nextOffset()); + ma_liPatchable(ScratchRegister, Imm32(label->offset())); + as_jalr(ScratchRegister); + as_nop(); + return; + } + if (BOffImm16::IsInRange(offset)) jumpKind = ShortJump; @@ -950,15 +962,6 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label *label, JumpKind jumpKind return; } - // Generate long jump because target is out of range of short jump. - if (code.encode() == inst_bgezal.encode()) { - // Handle long call - addLongJump(nextOffset()); - ma_liPatchable(ScratchRegister, Imm32(label->offset())); - as_jalr(ScratchRegister); - as_nop(); - return; - } if (code.encode() == inst_beq.encode()) { // Handle long jump addLongJump(nextOffset()); @@ -1526,7 +1529,7 @@ MacroAssemblerMIPSCompat::callIon(Register callee) void MacroAssemblerMIPSCompat::callIonFromAsmJS(Register callee) { - ma_callIonNoPush(reg); + ma_callIonNoPush(callee); // The Ion ABI has the callee pop the return address off the stack. // The asm.js caller assumes that the call leaves sp unchanged, so bump @@ -3504,7 +3507,7 @@ MacroAssemblerMIPSCompat::toggledCall(JitCode *target, bool enabled) as_nop(); as_nop(); } - MOZ_ASSERT(nextOffset().getOffset() - offset.offset() == ToggledCallSize()); + MOZ_ASSERT(nextOffset().getOffset() - offset.offset() == ToggledCallSize(nullptr)); return offset; } diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index 11a6f4bab4b..217f7c3bd08 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -485,7 +485,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS // this instruction. CodeOffsetLabel toggledCall(JitCode *target, bool enabled); - static size_t ToggledCallSize() { + static size_t ToggledCallSize(uint8_t *code) { // Four instructions used in: MacroAssemblerMIPSCompat::toggledCall return 4 * sizeof(uint32_t); } @@ -1092,6 +1092,12 @@ public: void store32(Imm32 src, const Address &address); void store32(Imm32 src, const BaseIndex &address); + // NOTE: This will use second scratch on MIPS. Only ARM needs the + // implementation without second scratch. + void store32_NoSecondScratch(Imm32 src, const Address &address) { + store32(src, address); + } + void storePtr(ImmWord imm, const Address &address); void storePtr(ImmPtr imm, const Address &address); void storePtr(ImmGCPtr imm, const Address &address); diff --git a/js/src/jit/mips/Simulator-mips.cpp b/js/src/jit/mips/Simulator-mips.cpp index 05123a8e3df..899dc87c8ed 100644 --- a/js/src/jit/mips/Simulator-mips.cpp +++ b/js/src/jit/mips/Simulator-mips.cpp @@ -35,7 +35,7 @@ #include -#include "jit/AsmJS.h" +#include "asmjs/AsmJSValidate.h" #include "jit/mips/Assembler-mips.h" #include "vm/Runtime.h" @@ -3310,7 +3310,7 @@ Simulator::execute() int32_t rpc = resume_pc_; if (MOZ_UNLIKELY(rpc != 0)) { // AsmJS signal handler ran and we have to adjust the pc. - activation->setInterrupted((void *)get_pc()); + activation->setResumePC((void *)get_pc()); set_pc(rpc); resume_pc_ = 0; } diff --git a/js/src/jit/none/BaseMacroAssembler-none.h b/js/src/jit/none/BaseMacroAssembler-none.h index b4fa53301e3..b9126cacee5 100644 --- a/js/src/jit/none/BaseMacroAssembler-none.h +++ b/js/src/jit/none/BaseMacroAssembler-none.h @@ -17,6 +17,7 @@ namespace JSC { class MacroAssemblerNone { + public: static bool supportsFloatingPoint() { return false; } }; diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index 9055e8aff37..ee879a98f41 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -11,7 +11,7 @@ #include -#include "jit/AsmJSFrameIterator.h" +#include "asmjs/AsmJSFrameIterator.h" #include "jit/IonAllocPolicy.h" #include "jit/Label.h" #include "jit/Registers.h" diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index a610b39d978..362995fb2e0 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -45,6 +45,7 @@ #include "jswrapper.h" #include "prmjtime.h" +#include "asmjs/AsmJSLink.h" #include "builtin/Eval.h" #include "builtin/Intl.h" #include "builtin/MapObject.h" @@ -58,7 +59,6 @@ #include "frontend/FullParseHandler.h" // for JS_BufferIsCompileableUnit #include "frontend/Parser.h" // for JS_BufferIsCompileableUnit #include "gc/Marking.h" -#include "jit/AsmJSLink.h" #include "jit/JitCommon.h" #include "js/CharacterEncoding.h" #include "js/SliceBudget.h" diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp index 40204183326..9e144e770a4 100644 --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -89,7 +89,7 @@ const Class js::MathClass = { }; bool -js_math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r) +js::math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r) { double x; if (!ToNumber(cx, v, &x)) @@ -102,7 +102,7 @@ js_math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r) } bool -js_math_abs(JSContext *cx, unsigned argc, Value *vp) +js::math_abs(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -111,7 +111,7 @@ js_math_abs(JSContext *cx, unsigned argc, Value *vp) return true; } - return js_math_abs_handle(cx, args[0], args.rval()); + return math_abs_handle(cx, args[0], args.rval()); } #if defined(SOLARIS) && defined(__GNUC__) @@ -575,7 +575,7 @@ max_double(double x, double y) } bool -js_math_max(JSContext *cx, unsigned argc, Value *vp) +js::math_max(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -600,7 +600,7 @@ min_double(double x, double y) } bool -js_math_min(JSContext *cx, unsigned argc, Value *vp) +js::math_min(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -616,7 +616,7 @@ js_math_min(JSContext *cx, unsigned argc, Value *vp) } bool -js_minmax_impl(JSContext *cx, bool max, HandleValue a, HandleValue b, MutableHandleValue res) +js::minmax_impl(JSContext *cx, bool max, HandleValue a, HandleValue b, MutableHandleValue res) { double x, y; @@ -715,7 +715,7 @@ js::ecmaPow(double x, double y) # pragma optimize("g", off) #endif bool -js_math_pow_handle(JSContext *cx, HandleValue base, HandleValue power, MutableHandleValue result) +js::math_pow_handle(JSContext *cx, HandleValue base, HandleValue power, MutableHandleValue result) { double x; if (!ToNumber(cx, base, &x)) @@ -731,11 +731,11 @@ js_math_pow_handle(JSContext *cx, HandleValue base, HandleValue power, MutableHa } bool -js_math_pow(JSContext *cx, unsigned argc, Value *vp) +js::math_pow(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - return js_math_pow_handle(cx, args.get(0), args.get(1), args.rval()); + return math_pow_handle(cx, args.get(0), args.get(1), args.rval()); } #if defined(_MSC_VER) # pragma optimize("", on) @@ -819,14 +819,14 @@ random_nextDouble(JSContext *cx) } double -math_random_no_outparam(JSContext *cx) +js::math_random_no_outparam(JSContext *cx) { /* Calculate random without memory traffic, for use in the JITs. */ return random_nextDouble(cx); } bool -js_math_random(JSContext *cx, unsigned argc, Value *vp) +js::math_random(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); double z = random_nextDouble(cx); @@ -884,7 +884,7 @@ js::math_round(JSContext *cx, unsigned argc, Value *vp) return true; } - return js::math_round_handle(cx, args[0], args.rval()); + return math_round_handle(cx, args[0], args.rval()); } double @@ -939,7 +939,7 @@ js::math_sqrt_handle(JSContext *cx, HandleValue number, MutableHandleValue resul } bool -js_math_sqrt(JSContext *cx, unsigned argc, Value *vp) +js::math_sqrt(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -1525,7 +1525,7 @@ static const JSFunctionSpec math_static_methods[] = { #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, math_toSource, 0, 0), #endif - JS_FN("abs", js_math_abs, 1, 0), + JS_FN("abs", math_abs, 1, 0), JS_FN("acos", math_acos, 1, 0), JS_FN("asin", math_asin, 1, 0), JS_FN("atan", math_atan, 1, 0), @@ -1538,13 +1538,13 @@ static const JSFunctionSpec math_static_methods[] = { JS_FN("imul", math_imul, 2, 0), JS_FN("fround", math_fround, 1, 0), JS_FN("log", math_log, 1, 0), - JS_FN("max", js_math_max, 2, 0), - JS_FN("min", js_math_min, 2, 0), - JS_FN("pow", js_math_pow, 2, 0), - JS_FN("random", js_math_random, 0, 0), + JS_FN("max", math_max, 2, 0), + JS_FN("min", math_min, 2, 0), + JS_FN("pow", math_pow, 2, 0), + JS_FN("random", math_random, 0, 0), JS_FN("round", math_round, 1, 0), JS_FN("sin", math_sin, 1, 0), - JS_FN("sqrt", js_math_sqrt, 1, 0), + JS_FN("sqrt", math_sqrt, 1, 0), JS_FN("tan", math_tan, 1, 0), JS_FN("log10", math_log10, 1, 0), JS_FN("log2", math_log2, 1, 0), diff --git a/js/src/jsmath.h b/js/src/jsmath.h index 81b00686dfd..c04e337f51e 100644 --- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -92,39 +92,39 @@ class MathCache extern JSObject * js_InitMathClass(JSContext *cx, js::HandleObject obj); +namespace js { + extern double math_random_no_outparam(JSContext *cx); extern bool -js_math_random(JSContext *cx, unsigned argc, js::Value *vp); +math_random(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r); +math_abs_handle(JSContext *cx, js::HandleValue v, js::MutableHandleValue r); extern bool -js_math_abs(JSContext *cx, unsigned argc, js::Value *vp); +math_abs(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_math_max(JSContext *cx, unsigned argc, js::Value *vp); +math_max(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_math_min(JSContext *cx, unsigned argc, js::Value *vp); +math_min(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_math_sqrt(JSContext *cx, unsigned argc, js::Value *vp); +math_sqrt(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_math_pow_handle(JSContext *cx, js::HandleValue base, js::HandleValue power, - js::MutableHandleValue result); +math_pow_handle(JSContext *cx, js::HandleValue base, js::HandleValue power, + js::MutableHandleValue result); extern bool -js_math_pow(JSContext *cx, unsigned argc, js::Value *vp); +math_pow(JSContext *cx, unsigned argc, js::Value *vp); extern bool -js_minmax_impl(JSContext *cx, bool max, js::HandleValue a, js::HandleValue b, - js::MutableHandleValue res); - -namespace js { +minmax_impl(JSContext *cx, bool max, js::HandleValue a, js::HandleValue b, + js::MutableHandleValue res); extern bool math_sqrt_handle(JSContext *cx, js::HandleValue number, js::MutableHandleValue result); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 36236513b38..6ca7836084a 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -37,12 +37,12 @@ #include "jswatchpoint.h" #include "jswrapper.h" +#include "asmjs/AsmJSModule.h" #include "builtin/Eval.h" #include "builtin/Object.h" #include "builtin/SymbolObject.h" #include "frontend/BytecodeCompiler.h" #include "gc/Marking.h" -#include "jit/AsmJSModule.h" #include "jit/BaselineJIT.h" #include "js/MemoryMetrics.h" #include "js/OldDebugAPI.h" diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index c5d5ac88fc9..886af82501d 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -9,7 +9,7 @@ #include "jsscript.h" -#include "jit/AsmJSLink.h" +#include "asmjs/AsmJSLink.h" #include "jit/BaselineJIT.h" #include "jit/IonAnalysis.h" #include "vm/ScopeObject.h" diff --git a/js/src/moz.build b/js/src/moz.build index 22d6892c6ce..5da83e6a2a9 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -97,7 +97,11 @@ EXPORTS.js += [ ] UNIFIED_SOURCES += [ - 'assembler/jit/ExecutableAllocator.cpp', + 'asmjs/AsmJSFrameIterator.cpp', + 'asmjs/AsmJSLink.cpp', + 'asmjs/AsmJSModule.cpp', + 'asmjs/AsmJSSignalHandlers.cpp', + 'asmjs/AsmJSValidate.cpp', 'builtin/Eval.cpp', 'builtin/Intl.cpp', 'builtin/MapObject.cpp', @@ -137,11 +141,6 @@ UNIFIED_SOURCES += [ 'irregexp/RegExpParser.cpp', 'irregexp/RegExpStack.cpp', 'jit/AliasAnalysis.cpp', - 'jit/AsmJS.cpp', - 'jit/AsmJSFrameIterator.cpp', - 'jit/AsmJSLink.cpp', - 'jit/AsmJSModule.cpp', - 'jit/AsmJSSignalHandlers.cpp', 'jit/BacktrackingAllocator.cpp', 'jit/Bailouts.cpp', 'jit/BaselineBailouts.cpp', @@ -159,6 +158,7 @@ UNIFIED_SOURCES += [ 'jit/CompileWrappers.cpp', 'jit/EdgeCaseAnalysis.cpp', 'jit/EffectiveAddressAnalysis.cpp', + 'jit/ExecutableAllocator.cpp', 'jit/Ion.cpp', 'jit/IonAnalysis.cpp', 'jit/IonBuilder.cpp', @@ -363,13 +363,13 @@ elif CONFIG['JS_CODEGEN_ARM']: if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ - 'assembler/jit/ExecutableAllocatorWin.cpp', + 'jit/ExecutableAllocatorWin.cpp', ] # _CRT_RAND_S must be #defined before #including stdlib.h to get rand_s() DEFINES['_CRT_RAND_S'] = True else: SOURCES += [ - 'assembler/jit/ExecutableAllocatorPosix.cpp', + 'jit/ExecutableAllocatorPosix.cpp', ] if CONFIG['ENABLE_ION']: diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index d646b632aa4..b30cd5e7c50 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -33,11 +33,11 @@ #endif #include "jswrapper.h" +#include "asmjs/AsmJSModule.h" +#include "asmjs/AsmJSValidate.h" #include "gc/Barrier.h" #include "gc/Marking.h" #include "gc/Memory.h" -#include "jit/AsmJS.h" -#include "jit/AsmJSModule.h" #include "js/MemoryMetrics.h" #include "vm/GlobalObject.h" #include "vm/Interpreter.h" diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index 0466b3fd4a1..ae97a23528b 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -22,8 +22,8 @@ #include "jsstr.h" #include "jstypes.h" +#include "asmjs/AsmJSModule.h" #include "frontend/SourceNotes.h" -#include "jit/AsmJSModule.h" #include "vm/Debugger.h" #include "vm/Shape.h" diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 890e372df3f..c33c6414407 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -29,9 +29,9 @@ #include "jswatchpoint.h" #include "jswrapper.h" +#include "asmjs/AsmJSSignalHandlers.h" #include "assembler/assembler/MacroAssembler.h" #include "jit/arm/Simulator-arm.h" -#include "jit/AsmJSSignalHandlers.h" #include "jit/JitCompartment.h" #include "jit/mips/Simulator-mips.h" #include "jit/PcScriptCache.h" diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 0e3ece70cb3..5ddf85ff510 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -25,14 +25,14 @@ #endif #include "jsscript.h" +#ifdef XP_MACOSX +# include "asmjs/AsmJSSignalHandlers.h" +#endif #include "ds/FixedSizeHash.h" #include "frontend/ParseMaps.h" #include "gc/GCRuntime.h" #include "gc/Tracer.h" #include "irregexp/RegExpStack.h" -#ifdef XP_MACOSX -# include "jit/AsmJSSignalHandlers.h" -#endif #include "js/HashTable.h" #include "js/Vector.h" #include "vm/CommonPropertyNames.h" diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp index 8cdc8b00b69..09775f89b5a 100644 --- a/js/src/vm/SharedArrayObject.cpp +++ b/js/src/vm/SharedArrayObject.cpp @@ -20,7 +20,8 @@ #endif #include "mozilla/Atomics.h" -#include "jit/AsmJS.h" + +#include "asmjs/AsmJSValidate.h" using namespace js; diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index df9d629de7a..560cead695b 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -10,9 +10,9 @@ #include "jscntxt.h" +#include "asmjs/AsmJSFrameIterator.h" +#include "asmjs/AsmJSModule.h" #include "gc/Marking.h" -#include "jit/AsmJSFrameIterator.h" -#include "jit/AsmJSModule.h" #include "jit/BaselineFrame.h" #include "jit/JitCompartment.h" #include "js/GCAPI.h" diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index cb06acb2014..04a8e6d6f55 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -12,7 +12,7 @@ #include "jsfun.h" #include "jsscript.h" -#include "jit/AsmJSFrameIterator.h" +#include "asmjs/AsmJSFrameIterator.h" #include "jit/JitFrameIterator.h" #ifdef CHECK_OSIPOINT_REGISTERS #include "jit/Registers.h" // for RegisterDump diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index c0d657019c9..2c60496887d 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -28,10 +28,10 @@ #endif #include "jswrapper.h" +#include "asmjs/AsmJSModule.h" +#include "asmjs/AsmJSValidate.h" #include "gc/Barrier.h" #include "gc/Marking.h" -#include "jit/AsmJS.h" -#include "jit/AsmJSModule.h" #include "vm/ArrayBufferObject.h" #include "vm/GlobalObject.h" #include "vm/Interpreter.h" diff --git a/js/xpconnect/src/nsCxPusher.cpp b/js/xpconnect/src/nsCxPusher.cpp index 34d2e4d1b03..b19b3b41333 100644 --- a/js/xpconnect/src/nsCxPusher.cpp +++ b/js/xpconnect/src/nsCxPusher.cpp @@ -254,11 +254,4 @@ ThreadsafeAutoSafeJSContext::operator JSContext*() const } } -AutoPushJSContext::AutoPushJSContext(JSContext *aCx) : mCx(aCx) -{ - if (mCx && mCx != nsXPConnect::XPConnect()->GetCurrentJSContext()) { - mPusher.construct(mCx); - } -} - } // namespace mozilla diff --git a/js/xpconnect/src/nsCxPusher.h b/js/xpconnect/src/nsCxPusher.h index 1ee654b999c..9b6e67274fd 100644 --- a/js/xpconnect/src/nsCxPusher.h +++ b/js/xpconnect/src/nsCxPusher.h @@ -155,29 +155,6 @@ private: MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; -/** - * Use AutoPushJSContext when you want to use a specific JSContext that may or - * may not be already on the stack. This differs from nsCxPusher in that it only - * pushes in the case that the given cx is not the active cx on the JSContext - * stack, which avoids an expensive JS_SaveFrameChain in the common case. - * - * Most consumers of this should probably just use AutoJSContext. But the goal - * here is to preserve the existing behavior while ensure proper cx-stack - * semantics in edge cases where the context being used doesn't match the active - * context. - * - * NB: This will not push a null cx even if aCx is null. Make sure you know what - * you're doing. - */ -class MOZ_STACK_CLASS AutoPushJSContext { - Maybe mPusher; - JSContext* mCx; - -public: - explicit AutoPushJSContext(JSContext* aCx); - operator JSContext*() { return mCx; } -}; - } // namespace mozilla #endif /* nsCxPusher_h */ diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 0e10f657c1d..1d31c0236be 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -3567,7 +3567,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, nsDisplayListBuilder* aDisplayListBuilder, nsIFrame* aContainerFrame, const nsRect& aVisibleRect, - const gfx3DMatrix* aTransform, + const Matrix4x4* aTransform, const ContainerLayerParameters& aIncomingScale, ContainerLayer* aLayer, LayerState aState, @@ -3575,8 +3575,8 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, { nsIntPoint offset; - gfx3DMatrix transform = - gfx3DMatrix::ScalingMatrix(aIncomingScale.mXScale, aIncomingScale.mYScale, 1.0); + Matrix4x4 transform = + Matrix4x4().Scale(aIncomingScale.mXScale, aIncomingScale.mYScale, 1.0); if (aTransform) { // aTransform is applied first, then the scale is applied to the result transform = (*aTransform)*transform; @@ -3587,7 +3587,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, // to depend on the scroll position. transform.NudgeToIntegersFixedEpsilon(); } - gfxMatrix transform2d; + Matrix transform2d; if (aContainerFrame && (aState == LAYER_INACTIVE || aState == LAYER_SVG_EFFECTS) && (!aTransform || (aTransform->Is2D(&transform2d) && @@ -3605,7 +3605,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.x, appUnitsPerDevPixel)*aIncomingScale.mXScale), NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.y, appUnitsPerDevPixel)*aIncomingScale.mYScale)); } - transform = transform * gfx3DMatrix::Translation(offset.x + aIncomingScale.mOffset.x, offset.y + aIncomingScale.mOffset.y, 0); + transform = transform * Matrix4x4().Translate(offset.x + aIncomingScale.mOffset.x, offset.y + aIncomingScale.mOffset.y, 0); if (transform.IsSingular()) { return false; @@ -3623,14 +3623,14 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(aContainerFrame->GetContent()); } else { // Scale factors are normalized to a power of 2 to reduce the number of resolution changes - scale = RoundToFloatPrecision(transform2d.ScaleFactors(true)); + scale = RoundToFloatPrecision(ThebesMatrix(transform2d).ScaleFactors(true)); // For frames with a changing transform that's not just a translation, // round scale factors up to nearest power-of-2 boundary so that we don't // keep having to redraw the content as it scales up and down. Rounding up to nearest // power-of-2 boundary ensures we never scale up, only down --- avoiding // jaggies. It also ensures we never scale down by more than a factor of 2, // avoiding bad downscaling quality. - gfxMatrix frameTransform; + Matrix frameTransform; if (ActiveLayerTracker::IsStyleAnimated(aContainerFrame, eCSSProperty_transform) && aTransform && (!aTransform->Is2D(&frameTransform) || frameTransform.HasNonTranslationOrFlip())) { @@ -3668,7 +3668,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, } // Store the inverse of our resolution-scale on the layer - aLayer->SetBaseTransform(ToMatrix4x4(transform)); + aLayer->SetBaseTransform(transform); aLayer->SetPreScale(1.0f/float(scale.width), 1.0f/float(scale.height)); aLayer->SetInheritedScale(aIncomingScale.mXScale, @@ -3731,7 +3731,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, nsDisplayItem* aContainerItem, nsDisplayList* aChildren, const ContainerLayerParameters& aParameters, - const gfx3DMatrix* aTransform, + const Matrix4x4* aTransform, uint32_t aFlags) { uint32_t containerDisplayItemKey = diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 0f0f54deba2..b3f2b88a329 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -29,6 +29,10 @@ class BasicLayerManager; class ThebesLayer; } +namespace gfx { +class Matrix4x4; +} + class FrameLayerBuilder; class LayerManagerData; class ThebesLayerData; @@ -229,7 +233,7 @@ public: nsDisplayItem* aContainerItem, nsDisplayList* aChildren, const ContainerLayerParameters& aContainerParameters, - const gfx3DMatrix* aTransform, + const gfx::Matrix4x4* aTransform, uint32_t aFlags = 0); /** diff --git a/layout/base/nsCSSColorUtils.h b/layout/base/nsCSSColorUtils.h index c89193fb1a1..f2106a7a283 100644 --- a/layout/base/nsCSSColorUtils.h +++ b/layout/base/nsCSSColorUtils.h @@ -15,7 +15,8 @@ // See http://www.w3.org/TR/AERT#color-contrast #define NS_SUFFICIENT_LUMINOSITY_DIFFERENCE 125000 #define NS_LUMINOSITY_DIFFERENCE(a, b) \ - int32_t(mozilla::Abs(NS_GetLuminosity(a) - NS_GetLuminosity(b))) + int32_t(mozilla::Abs( \ + NS_GetLuminosity(a | 0xff000000) - NS_GetLuminosity(b | 0xff000000))) // To determine colors based on the background brightness and border color void NS_GetSpecial3DColors(nscolor aResult[2], diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 0e152a0ecec..46c6125346d 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -63,6 +63,8 @@ using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::dom; using namespace mozilla::layout; +using namespace mozilla::gfx; + typedef FrameMetrics::ViewID ViewID; #ifdef DEBUG @@ -4596,7 +4598,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp gfx3DMatrix result; // Call IsSVGTransformed() regardless of the value of // disp->mSpecifiedTransform, since we still need any transformFromSVGParent. - mozilla::gfx::Matrix svgTransform, transformFromSVGParent; + Matrix svgTransform, transformFromSVGParent; bool hasSVGTransforms = frame && frame->IsSVGTransformed(&svgTransform, &transformFromSVGParent); /* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */ @@ -4759,7 +4761,7 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui } /* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */ -static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix) +static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix) { if (aMatrix.IsSingular()) { return false; @@ -4771,7 +4773,7 @@ static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix) return true; } -const gfx3DMatrix& +const Matrix4x4& nsDisplayTransform::GetTransform() { if (mTransform.IsIdentity()) { @@ -4782,7 +4784,7 @@ nsDisplayTransform::GetTransform() 0.0f); if (mTransformGetter) { mTransform = mTransformGetter(mFrame, scale); - mTransform.ChangeBasis(newOrigin); + mTransform.ChangeBasis(newOrigin.x, newOrigin.y, newOrigin.z); } else { /** * Passing true as the final argument means that we want to shift the @@ -4792,9 +4794,9 @@ nsDisplayTransform::GetTransform() * to be an ancestor of the preserve-3d chain, so we only need to do * this once. */ - mTransform = + mTransform = ToMatrix4x4( GetResultingTransformMatrix(mFrame, ToReferenceFrame(), scale, - nullptr, nullptr, true); + nullptr, nullptr, true)); } } return mTransform; @@ -4810,7 +4812,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu LayerManager *aManager, const ContainerLayerParameters& aContainerParameters) { - const gfx3DMatrix& newTransformMatrix = GetTransform(); + const Matrix4x4& newTransformMatrix = GetTransform(); if (mFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && newTransformMatrix.IsBackfaceVisible()) { @@ -4923,7 +4925,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder, */ // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); - gfx3DMatrix matrix = GetTransform(); + Matrix4x4 matrix = GetTransform(); if (!IsFrameVisible(mFrame, matrix)) { return; @@ -4938,7 +4940,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder, nsRect resultingRect; if (aRect.width == 1 && aRect.height == 1) { // Magic width/height indicating we're hit testing a point, not a rect - gfxPointH3D point = matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor), + gfxPointH3D point = To3DMatrix(matrix).Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor), NSAppUnitsToFloatPixels(aRect.y, factor))); if (!point.HasPositiveWCoord()) { return; @@ -4956,7 +4958,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder, NSAppUnitsToFloatPixels(aRect.width, factor), NSAppUnitsToFloatPixels(aRect.height, factor)); - gfxRect rect = matrix.Inverse().ProjectRectBounds(originalRect); + gfxRect rect = To3DMatrix(matrix).Inverse().ProjectRectBounds(originalRect); bool snap; nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap); @@ -4999,17 +5001,17 @@ nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsP { // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); - gfx3DMatrix matrix = GetTransform(); + Matrix4x4 matrix = GetTransform(); NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!"); - gfxPointH3D point = matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor), + gfxPointH3D point = To3DMatrix(matrix).Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor), NSAppUnitsToFloatPixels(aPoint.y, factor))); NS_ASSERTION(point.HasPositiveWCoord(), "Why are we trying to get the depth for a point we didn't hit?"); gfxPoint point2d = point.As2DPoint(); - gfxPoint3D transformed = matrix.Transform3D(gfxPoint3D(point2d.x, point2d.y, 0)); + Point3D transformed = matrix * Point3D(point2d.x, point2d.y, 0); return transformed.z; } @@ -5025,7 +5027,7 @@ nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap // GetTransform always operates in dev pixels. float factor = mFrame->PresContext()->AppUnitsPerDevPixel(); return nsLayoutUtils::MatrixTransformRect(untransformedBounds, - GetTransform(), + To3DMatrix(GetTransform()), factor); } @@ -5061,10 +5063,10 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, return nsRegion(); } - const gfx3DMatrix& matrix = GetTransform(); + const Matrix4x4& matrix = GetTransform(); nsRegion result; - gfxMatrix matrix2d; + Matrix matrix2d; bool tmpSnap; if (matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && @@ -5084,9 +5086,9 @@ bool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aCol if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) { return false; } - const gfx3DMatrix& matrix = GetTransform(); + const Matrix4x4& matrix = GetTransform(); - gfxMatrix matrix2d; + Matrix matrix2d; return matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && mStoredList.GetVisibleRect().Contains(untransformedVisible) && @@ -5211,7 +5213,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aTransformedBounds, bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder, nsRect *aOutRect) { - const gfx3DMatrix& matrix = GetTransform(); + const gfx3DMatrix& matrix = To3DMatrix(GetTransform()); if (matrix.IsSingular()) return false; @@ -5243,7 +5245,7 @@ void nsDisplayTransform::WriteDebugInfo(nsACString& aTo) { std::stringstream ss; - AppendToString(ss, gfx::ToMatrix4x4(GetTransform())); + AppendToString(ss, GetTransform()); aTo += ss.str().c_str(); } #endif diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index b7ae22899be..c29918e5fad 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3157,6 +3157,7 @@ private: */ class nsDisplayTransform: public nsDisplayItem { + typedef mozilla::gfx::Matrix4x4 Matrix4x4; public: /** * Returns a matrix (in pixels) for the current frame. The matrix should be relative to @@ -3165,7 +3166,7 @@ public: * @param aFrame The frame to compute the transform for. * @param aAppUnitsPerPixel The number of app units per graphics unit. */ - typedef gfx3DMatrix (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel); + typedef Matrix4x4 (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel); /* Constructor accepts a display list, empties it, and wraps it up. It also * ferries the underlying frame to the nsDisplayItem constructor. @@ -3244,7 +3245,7 @@ public: INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS }; - const gfx3DMatrix& GetTransform(); + const Matrix4x4& GetTransform(); float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint); @@ -3387,7 +3388,7 @@ private: bool aOffsetByOrigin); nsDisplayWrapList mStoredList; - gfx3DMatrix mTransform; + Matrix4x4 mTransform; ComputeTransformFunction mTransformGetter; nsRect mChildrenVisibleRect; uint32_t mIndex; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 023cecbe2c1..20d6d71c9e4 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2416,7 +2416,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame, new (&builder) nsDisplayTransform(&builder, aFrame, &list, nsRect()); *aTransform = - item->GetTransform(); + To3DMatrix(item->GetTransform()); item->~nsDisplayTransform(); return true; diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index 0233e06e26f..fed2b393738 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -462,10 +462,10 @@ static void PaintHeaderFooter(nsIFrame* aFrame, nsRenderingContext* aCtx, static_cast(aFrame)->PaintHeaderFooter(*aCtx, aPt); } -static gfx3DMatrix ComputePageTransform(nsIFrame* aFrame, float aAppUnitsPerPixel) +static gfx::Matrix4x4 ComputePageTransform(nsIFrame* aFrame, float aAppUnitsPerPixel) { float scale = aFrame->PresContext()->GetPageScale(); - return gfx3DMatrix::ScalingMatrix(scale, scale, 1); + return gfx::Matrix4x4().Scale(scale, scale, 1); } //------------------------------------------------------------------------------ diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 1e8b1d74f92..5fb154e044b 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -766,11 +766,11 @@ nsSimplePageSequenceFrame::DoPageEnd() return rv; } -static gfx3DMatrix +static gfx::Matrix4x4 ComputePageSequenceTransform(nsIFrame* aFrame, float aAppUnitsPerPixel) { float scale = aFrame->PresContext()->GetPrintPreviewScale(); - return gfx3DMatrix::ScalingMatrix(scale, scale, 1); + return gfx::Matrix4x4().Scale(scale, scale, 1); } void diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 3ea88ce2ed0..58ac4252b8f 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -8,7 +8,6 @@ #include "base/basictypes.h" #include "BasicLayers.h" -#include "gfx3DMatrix.h" #ifdef MOZ_ENABLE_D3D9_LAYER # include "LayerManagerD3D9.h" #endif //MOZ_ENABLE_D3D9_LAYER @@ -31,6 +30,7 @@ typedef nsContentView::ViewConfig ViewConfig; using namespace mozilla::dom; +using namespace mozilla::gfx; using namespace mozilla::layers; namespace mozilla { @@ -47,11 +47,11 @@ struct ViewTransform { , mYScale(aYScale) {} - operator gfx3DMatrix() const + operator Matrix4x4() const { return - gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) * - gfx3DMatrix::ScalingMatrix(mXScale, mYScale, 1); + Matrix4x4().Translate(mTranslation.x, mTranslation.y, 0) * + Matrix4x4().Scale(mXScale, mYScale, 1); } nsIntPoint mTranslation; @@ -65,23 +65,23 @@ struct ViewTransform { // much easier because we only expect the diagonals and the translation // coordinates of the matrix to be non-zero. -static double GetXScale(const gfx3DMatrix& aTransform) +static double GetXScale(const Matrix4x4& aTransform) { return aTransform._11; } -static double GetYScale(const gfx3DMatrix& aTransform) +static double GetYScale(const Matrix4x4& aTransform) { return aTransform._22; } -static void Scale(gfx3DMatrix& aTransform, double aXScale, double aYScale) +static void Scale(Matrix4x4& aTransform, double aXScale, double aYScale) { aTransform._11 *= aXScale; aTransform._22 *= aYScale; } -static void ReverseTranslate(gfx3DMatrix& aTransform, const gfxPoint& aOffset) +static void ReverseTranslate(Matrix4x4& aTransform, const gfxPoint& aOffset) { aTransform._41 -= aOffset.x; aTransform._42 -= aOffset.y; @@ -89,7 +89,7 @@ static void ReverseTranslate(gfx3DMatrix& aTransform, const gfxPoint& aOffset) static void ApplyTransform(nsRect& aRect, - gfx3DMatrix& aTransform, + Matrix4x4& aTransform, nscoord auPerDevPixel) { aRect.x = aRect.x * aTransform._11 + aTransform._41 * auPerDevPixel; @@ -203,14 +203,14 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame, static void BuildListForLayer(Layer* aLayer, nsFrameLoader* aRootFrameLoader, - const gfx3DMatrix& aTransform, + const Matrix4x4& aTransform, nsDisplayListBuilder* aBuilder, nsDisplayList& aShadowTree, nsIFrame* aSubdocFrame) { const FrameMetrics* metrics = GetFrameMetrics(aLayer); - gfx3DMatrix transform; + Matrix4x4 transform; if (metrics && metrics->IsScrollable()) { const ViewID scrollId = metrics->GetScrollId(); @@ -225,14 +225,14 @@ BuildListForLayer(Layer* aLayer, aRootFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId); // XXX why don't we include aLayer->GetTransform() in the inverse-scale here? // This seems wrong, but it doesn't seem to cause bugs! - gfx3DMatrix applyTransform = ComputeShadowTreeTransform( + Matrix4x4 applyTransform = ComputeShadowTreeTransform( aSubdocFrame, aRootFrameLoader, metrics, view->GetViewConfig(), 1 / GetXScale(aTransform), 1 / GetYScale(aTransform)); - transform = applyTransform * To3DMatrix(aLayer->GetTransform()) * aTransform; + transform = applyTransform * aLayer->GetTransform() * aTransform; // As mentioned above, bounds calculation also depends on the scale // of this layer. - gfx3DMatrix tmpTransform = aTransform; + Matrix4x4 tmpTransform = aTransform; Scale(tmpTransform, GetXScale(applyTransform), GetYScale(applyTransform)); // Calculate rect for this layer based on aTransform. @@ -247,7 +247,7 @@ BuildListForLayer(Layer* aLayer, new (aBuilder) nsDisplayRemoteShadow(aBuilder, aSubdocFrame, bounds, scrollId)); } else { - transform = To3DMatrix(aLayer->GetTransform()) * aTransform; + transform = aLayer->GetTransform() * aTransform; } for (Layer* child = aLayer->GetFirstChild(); child; @@ -272,7 +272,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, const FrameMetrics* metrics = GetFrameMetrics(aLayer); - gfx3DMatrix shadowTransform = To3DMatrix(aLayer->GetTransform()); + Matrix4x4 shadowTransform = aLayer->GetTransform(); ViewTransform layerTransform = aTransform; if (metrics && metrics->IsScrollable()) { @@ -280,7 +280,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, const nsContentView* view = aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId); NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree"); - gfx3DMatrix currentTransform = To3DMatrix(aLayer->GetTransform()); + Matrix4x4 currentTransform = aLayer->GetTransform(); const ViewConfig& config = view->GetViewConfig(); // With temporary scale we should compensate translation @@ -293,14 +293,14 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, ); // Apply the layer's own transform *before* the view transform - shadowTransform = gfx3DMatrix(viewTransform) * currentTransform; + shadowTransform = Matrix4x4(viewTransform) * currentTransform; layerTransform = viewTransform; if (metrics->IsRootScrollable()) { // Apply the translation *before* we do the rest of the transforms. nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder); shadowTransform = shadowTransform * - gfx3DMatrix::Translation(float(offset.x), float(offset.y), 0.0); + Matrix4x4().Translate(float(offset.x), float(offset.y), 0.0); } } @@ -332,7 +332,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, 1.0f/aLayer->GetPostYScale(), 1); - shadow->SetShadowTransform(gfx::ToMatrix4x4(shadowTransform)); + shadow->SetShadowTransform(shadowTransform); for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform, @@ -376,7 +376,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews, return; const FrameMetrics metrics = container->GetFrameMetrics(); const ViewID scrollId = metrics.GetScrollId(); - gfx3DMatrix transform = To3DMatrix(aLayer->GetTransform()); + Matrix4x4 transform = aLayer->GetTransform(); aXScale *= GetXScale(transform); aYScale *= GetYScale(transform); diff --git a/layout/tools/layout-debug/src/Makefile.in b/layout/tools/layout-debug/src/Makefile.in deleted file mode 100644 index ee2043dc2a7..00000000000 --- a/layout/tools/layout-debug/src/Makefile.in +++ /dev/null @@ -1,11 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/rules.mk - -libs:: - -clobber:: - rm -f $(DIST)\lib\library diff --git a/media/libcubeb/src/cubeb_audiounit.c b/media/libcubeb/src/cubeb_audiounit.c index 00d50c9ba47..2945637e5f9 100644 --- a/media/libcubeb/src/cubeb_audiounit.c +++ b/media/libcubeb/src/cubeb_audiounit.c @@ -286,7 +286,7 @@ audiounit_install_device_changed_callback(cubeb_stream * stm) } static int -audiounit_uninstall_device_changed_callback() +audiounit_uninstall_device_changed_callback(cubeb_stream * stm) { OSStatus r; AudioDeviceID id; @@ -303,7 +303,7 @@ audiounit_uninstall_device_changed_callback() r = AudioObjectRemovePropertyListener(id, &datasource_address, &audiounit_property_listener_callback, - NULL); + stm); if (r != noErr) { return CUBEB_ERROR; } @@ -317,7 +317,7 @@ audiounit_uninstall_device_changed_callback() r = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_device_address, &audiounit_property_listener_callback, - NULL); + stm); if (r != noErr) { return CUBEB_ERROR; } @@ -661,7 +661,7 @@ audiounit_stream_destroy(cubeb_stream * stm) #endif } - audiounit_uninstall_device_changed_callback(); + audiounit_uninstall_device_changed_callback(stm); r = pthread_mutex_destroy(&stm->mutex); assert(r == 0); diff --git a/media/mtransport/test/ice_unittest.cpp b/media/mtransport/test/ice_unittest.cpp index 9683218ca6c..8905651557d 100644 --- a/media/mtransport/test/ice_unittest.cpp +++ b/media/mtransport/test/ice_unittest.cpp @@ -41,6 +41,10 @@ #include "stun_udp_socket_filter.h" #include "mozilla/net/DNS.h" +#include "ice_ctx.h" +#include "ice_peer_ctx.h" +#include "ice_media_stream.h" + #define GTEST_HAS_RTTI 0 #include "gtest/gtest.h" #include "gtest_utils.h" @@ -232,7 +236,8 @@ class IceTestPeer : public sigslot::has_slots<> { expected_local_transport_(kNrIceTransportUdp), expected_remote_type_(NrIceCandidate::ICE_HOST), trickle_mode_(TRICKLE_NONE), - trickled_(0) { + trickled_(0), + simulate_ice_lite_(false) { ice_ctx_->SignalGatheringStateChange.connect( this, &IceTestPeer::GatheringStateChange); @@ -329,7 +334,11 @@ class IceTestPeer : public sigslot::has_slots<> { // Get various pieces of state std::vector GetGlobalAttributes() { - return ice_ctx_->GetGlobalAttributes(); + std::vector attrs(ice_ctx_->GetGlobalAttributes()); + if (simulate_ice_lite_) { + attrs.push_back("ice-lite"); + } + return attrs; } std::vector GetCandidates(size_t stream) { @@ -792,6 +801,34 @@ class IceTestPeer : public sigslot::has_slots<> { int trickled() { return trickled_; } + void SetControlling(NrIceCtx::Controlling controlling) { + nsresult res; + test_utils->sts_target()->Dispatch( + WrapRunnableRet(ice_ctx_, + &NrIceCtx::SetControlling, + controlling, + &res), + NS_DISPATCH_SYNC); + ASSERT_TRUE(NS_SUCCEEDED(res)); + } + + void SetTiebreaker(uint64_t tiebreaker) { + test_utils->sts_target()->Dispatch( + WrapRunnable(this, + &IceTestPeer::SetTiebreaker_s, + tiebreaker), + NS_DISPATCH_SYNC); + } + + void SetTiebreaker_s(uint64_t tiebreaker) { + ice_ctx_->peer()->tiebreaker = tiebreaker; + } + + void SimulateIceLite() { + simulate_ice_lite_ = true; + SetControlling(NrIceCtx::ICE_CONTROLLED); + } + private: std::string name_; nsRefPtr ice_ctx_; @@ -814,6 +851,7 @@ class IceTestPeer : public sigslot::has_slots<> { NrIceCandidate::Type expected_remote_type_; TrickleMode trickle_mode_; int trickled_; + bool simulate_ice_lite_; }; void SchedulableTrickleCandidate::Trickle() { @@ -932,8 +970,12 @@ class IceConnectTest : public ::testing::Test { } void Connect() { - p1_->Connect(p2_, TRICKLE_NONE); + // IceTestPeer::Connect grabs attributes from the first arg, and gives them + // to |this|, meaning that p2_->Connect(p1_, ...) simulates p1 sending an + // offer to p2. Order matters here because it determines which peer is + // controlling. p2_->Connect(p1_, TRICKLE_NONE); + p1_->Connect(p2_, TRICKLE_NONE); ASSERT_TRUE_WAIT(p1_->ready_ct() == 1 && p2_->ready_ct() == 1, kDefaultTimeout); @@ -977,8 +1019,8 @@ class IceConnectTest : public ::testing::Test { } void ConnectTrickle(TrickleMode trickle = TRICKLE_SIMULATE) { - p1_->Connect(p2_, trickle); p2_->Connect(p1_, trickle); + p1_->Connect(p2_, trickle); } void SimulateTrickle(size_t stream) { @@ -1004,8 +1046,8 @@ class IceConnectTest : public ::testing::Test { } void ConnectThenDelete() { - p1_->Connect(p2_, TRICKLE_NONE, true); p2_->Connect(p1_, TRICKLE_NONE, false); + p1_->Connect(p2_, TRICKLE_NONE, true); test_utils->sts_target()->Dispatch(WrapRunnable(this, &IceConnectTest::CloseP1), NS_DISPATCH_SYNC); @@ -1261,6 +1303,69 @@ TEST_F(IceConnectTest, TestConnect) { Connect(); } +TEST_F(IceConnectTest, TestConnectBothControllingP1Wins) { + AddStream("first", 1); + p1_->SetTiebreaker(1); + p2_->SetTiebreaker(0); + ASSERT_TRUE(Gather()); + p1_->SetControlling(NrIceCtx::ICE_CONTROLLING); + p2_->SetControlling(NrIceCtx::ICE_CONTROLLING); + Connect(); +} + +TEST_F(IceConnectTest, TestConnectBothControllingP2Wins) { + AddStream("first", 1); + p1_->SetTiebreaker(0); + p2_->SetTiebreaker(1); + ASSERT_TRUE(Gather()); + p1_->SetControlling(NrIceCtx::ICE_CONTROLLING); + p2_->SetControlling(NrIceCtx::ICE_CONTROLLING); + Connect(); +} + +TEST_F(IceConnectTest, TestConnectIceLiteOfferer) { + AddStream("first", 1); + ASSERT_TRUE(Gather()); + p1_->SimulateIceLite(); + Connect(); +} + +TEST_F(IceConnectTest, TestTrickleBothControllingP1Wins) { + AddStream("first", 1); + p1_->SetTiebreaker(1); + p2_->SetTiebreaker(0); + ASSERT_TRUE(Gather()); + p1_->SetControlling(NrIceCtx::ICE_CONTROLLING); + p2_->SetControlling(NrIceCtx::ICE_CONTROLLING); + ConnectTrickle(); + SimulateTrickle(0); + ASSERT_TRUE_WAIT(p1_->ice_complete(), 1000); + ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000); +} + +TEST_F(IceConnectTest, TestTrickleBothControllingP2Wins) { + AddStream("first", 1); + p1_->SetTiebreaker(0); + p2_->SetTiebreaker(1); + ASSERT_TRUE(Gather()); + p1_->SetControlling(NrIceCtx::ICE_CONTROLLING); + p2_->SetControlling(NrIceCtx::ICE_CONTROLLING); + ConnectTrickle(); + SimulateTrickle(0); + ASSERT_TRUE_WAIT(p1_->ice_complete(), 1000); + ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000); +} + +TEST_F(IceConnectTest, TestTrickleIceLiteOfferer) { + AddStream("first", 1); + ASSERT_TRUE(Gather()); + p1_->SimulateIceLite(); + ConnectTrickle(); + SimulateTrickle(0); + ASSERT_TRUE_WAIT(p1_->ice_complete(), 1000); + ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000); +} + TEST_F(IceConnectTest, TestConnectTwoComponents) { AddStream("first", 2); ASSERT_TRUE(Gather()); @@ -1601,8 +1706,8 @@ TEST_F(IceConnectTest, TestPollCandPairsDuringConnect) { AddStream("first", 1); ASSERT_TRUE(Gather()); - p1_->Connect(p2_, TRICKLE_NONE, false); p2_->Connect(p1_, TRICKLE_NONE, false); + p1_->Connect(p2_, TRICKLE_NONE, false); std::vector pairs1; std::vector pairs2; @@ -1627,8 +1732,8 @@ TEST_F(IceConnectTest, TestRLogRingBuffer) { AddStream("first", 1); ASSERT_TRUE(Gather()); - p1_->Connect(p2_, TRICKLE_NONE, false); p2_->Connect(p1_, TRICKLE_NONE, false); + p1_->Connect(p2_, TRICKLE_NONE, false); std::vector pairs1; std::vector pairs2; diff --git a/media/mtransport/third_party/moz.build b/media/mtransport/third_party/moz.build index f954024902e..7cb5a1656f3 100644 --- a/media/mtransport/third_party/moz.build +++ b/media/mtransport/third_party/moz.build @@ -50,7 +50,6 @@ nrappkit_non_unified_sources = [ 'nrappkit/src/util/hex.c', 'nrappkit/src/util/libekr/debug.c', 'nrappkit/src/util/libekr/r_assoc.c', - 'nrappkit/src/util/libekr/r_bitfield.c', 'nrappkit/src/util/libekr/r_crc32.c', 'nrappkit/src/util/libekr/r_data.c', 'nrappkit/src/util/libekr/r_errors.c', diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.c b/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.c index cee3d32f767..c9f9c0f7873 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.c @@ -45,7 +45,7 @@ static char *RCSSTRING __UNUSED__="$Id: ice_candidate_pair.c,v 1.2 2008/04/28 17 static char *nr_ice_cand_pair_states[]={"UNKNOWN","FROZEN","WAITING","IN_PROGRESS","FAILED","SUCCEEDED","CANCELLED"}; -static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg); +static void nr_ice_candidate_pair_restart_stun_role_change_cb(NR_SOCKET s, int how, void *cb_arg); static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair, nr_ice_candidate *lcand, nr_ice_candidate *rcand); @@ -159,7 +159,7 @@ int nr_ice_candidate_pair_destroy(nr_ice_cand_pair **pairp) } NR_async_timer_cancel(pair->stun_cb_timer); - NR_async_timer_cancel(pair->restart_controlled_cb_timer); + NR_async_timer_cancel(pair->restart_role_change_cb_timer); NR_async_timer_cancel(pair->restart_nominated_cb_timer); RFREE(pair); @@ -202,13 +202,12 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg) case NR_STUN_CLIENT_STATE_FAILED: sres=pair->stun_client->response; if(sres && nr_stun_message_has_attribute(sres,NR_STUN_ATTR_ERROR_CODE,&attr)&&attr->u.error_code.number==487){ - r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/CAND-PAIR(%s): detected role conflict. Switching to controlled",pair->pctx->label,pair->codeword); - pair->pctx->controlling=0; - - /* Only restart if we haven't tried this already */ - if(!pair->restart_controlled_cb_timer) - NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_restart_stun_controlled_cb,pair,&pair->restart_controlled_cb_timer); + /* + * Flip the controlling bit; subsequent 487s for other pairs will be + * ignored, since we abandon their STUN transactions. + */ + nr_ice_peer_ctx_switch_controlling_role(pair->pctx); return; } @@ -340,23 +339,21 @@ static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg) return; } -int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair) +static void nr_ice_candidate_pair_restart(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair) { int r,_status; UINT4 mode; nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_IN_PROGRESS); - /* Register the stun ctx for when responses come in*/ - if(r=nr_ice_socket_register_stun_client(pair->local->isock,pair->stun_client,&pair->stun_client_handle)) - ABORT(r); - /* Start STUN */ if(pair->pctx->controlling && (pair->pctx->ctx->flags & NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION)) mode=NR_ICE_CLIENT_MODE_USE_CANDIDATE; else mode=NR_ICE_CLIENT_MODE_BINDING_REQUEST; + nr_stun_client_reset(pair->stun_client); + if(r=nr_stun_client_start(pair->stun_client,mode,nr_ice_candidate_pair_stun_cb,pair)) ABORT(r); @@ -375,6 +372,21 @@ int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair) NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_stun_cb,pair, &pair->stun_cb_timer); _status=0; } + } + +int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair) + { + int r,_status; + UINT4 mode; + + /* Register the stun ctx for when responses come in*/ + if(r=nr_ice_socket_register_stun_client(pair->local->isock,pair->stun_client,&pair->stun_client_handle)) + ABORT(r); + + nr_ice_candidate_pair_restart(pctx, pair); + + _status=0; + abort: return(_status); } @@ -548,30 +560,29 @@ void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void return; } -static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg) - { +static void nr_ice_candidate_pair_restart_stun_role_change_cb(NR_SOCKET s, int how, void *cb_arg) + { nr_ice_cand_pair *pair=cb_arg; - int r,_status; - pair->restart_controlled_cb_timer=0; + pair->restart_role_change_cb_timer=0; - r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/STREAM(%s)/CAND-PAIR(%s):COMP(%d): Restarting pair as CONTROLLED: %s",pair->pctx->label,pair->local->stream->label,pair->codeword,pair->remote->component->component_id,pair->as_string); + r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/STREAM(%s)/CAND-PAIR(%s):COMP(%d): Restarting pair as %s: %s",pair->pctx->label,pair->local->stream->label,pair->codeword,pair->remote->component->component_id,pair->pctx->controlling ? "CONTROLLING" : "CONTROLLED",pair->as_string); - nr_stun_client_reset(pair->stun_client); - pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLED; - - if(r=nr_stun_client_start(pair->stun_client,NR_ICE_CLIENT_MODE_BINDING_REQUEST,nr_ice_candidate_pair_stun_cb,pair)) - ABORT(r); - - if(r=nr_ice_ctx_remember_id(pair->pctx->ctx, pair->stun_client->request)) - ABORT(r); - - _status=0; - abort: - return; + nr_ice_candidate_pair_restart(pair->pctx, pair); } +void nr_ice_candidate_pair_role_change(nr_ice_cand_pair *pair) + { + pair->stun_client->params.ice_binding_request.control = pair->pctx->controlling ? NR_ICE_CONTROLLING : NR_ICE_CONTROLLED; + if(pair->state == NR_ICE_PAIR_STATE_IN_PROGRESS) { + /* We could try only restarting in-progress pairs when they receive their + * 487, but this ends up being simpler, because any extra 487 are dropped. + */ + if(!pair->restart_role_change_cb_timer) + NR_ASYNC_TIMER_SET(0,nr_ice_candidate_pair_restart_stun_role_change_cb,pair,&pair->restart_role_change_cb_timer); + } + } static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair, nr_ice_candidate *lcand, nr_ice_candidate *rcand) diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h b/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h index bb6f26bafbb..a995669231f 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate_pair.h @@ -65,7 +65,7 @@ struct nr_ice_cand_pair_ { void *stun_client_handle; void *stun_cb_timer; - void *restart_controlled_cb_timer; + void *restart_role_change_cb_timer; void *restart_nominated_cb_timer; TAILQ_ENTRY(nr_ice_cand_pair_) entry; @@ -82,6 +82,7 @@ int nr_ice_candidate_pair_do_triggered_check(nr_ice_peer_ctx *pctx, nr_ice_cand_ int nr_ice_candidate_pair_insert(nr_ice_cand_pair_head *head,nr_ice_cand_pair *pair); void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void *cb_arg); int nr_ice_candidate_pair_destroy(nr_ice_cand_pair **pairp); +void nr_ice_candidate_pair_role_change(nr_ice_cand_pair *pair); #ifdef __cplusplus } diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_component.c b/media/mtransport/third_party/nICEr/src/ice/ice_component.c index 4a85900994a..ff05fca30da 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c @@ -529,10 +529,9 @@ static int nr_ice_component_process_incoming_check(nr_ice_component *comp, nr_tr r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): role conflict, both controlling",comp->stream->pctx->label); if(attr->u.ice_controlling > comp->stream->pctx->tiebreaker){ - /* They are: switch */ - r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): switching to controlled",comp->stream->pctx->label); - - comp->stream->pctx->controlling=0; + /* Update the peer ctx. This will propagate to all candidate pairs + in the context. */ + nr_ice_peer_ctx_switch_controlling_role(comp->stream->pctx); } else { /* We are: throw an error */ @@ -549,10 +548,9 @@ static int nr_ice_component_process_incoming_check(nr_ice_component *comp, nr_tr r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): role conflict, both controlled",comp->stream->pctx->label); if(attr->u.ice_controlling < comp->stream->pctx->tiebreaker){ - r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): switching to controlling",comp->stream->pctx->label); - - /* They are: switch */ - comp->stream->pctx->controlling=1; + /* Update the peer ctx. This will propagate to all candidate pairs + in the context. */ + nr_ice_peer_ctx_switch_controlling_role(comp->stream->pctx); } else { /* We are: throw an error */ diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c index e3fb61b11af..3d56b010c7f 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c @@ -538,7 +538,7 @@ int nr_ice_media_stream_unfreeze_pairs_foundation(nr_ice_media_stream *stream, c str=STAILQ_NEXT(str,entry); } -// nr_ice_media_stream_dump_state(stream->pctx,stream,stderr); +/* nr_ice_media_stream_dump_state(stream->pctx,stream,stderr); */ _status=0; @@ -551,7 +551,7 @@ int nr_ice_media_stream_dump_state(nr_ice_peer_ctx *pctx, nr_ice_media_stream *s { nr_ice_cand_pair *pair; - //r_log(LOG_ICE,LOG_DEBUG,"MEDIA-STREAM(%s): state dump", stream->label); + /* r_log(LOG_ICE,LOG_DEBUG,"MEDIA-STREAM(%s): state dump", stream->label); */ pair=TAILQ_FIRST(&stream->check_list); while(pair){ nr_ice_candidate_pair_dump_state(pair,out); @@ -874,3 +874,15 @@ int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int compo return(_status); } +void nr_ice_media_stream_role_change(nr_ice_media_stream *stream) + { + nr_ice_cand_pair *pair; + assert(stream->ice_state != NR_ICE_MEDIA_STREAM_UNPAIRED); + + pair=TAILQ_FIRST(&stream->check_list); + while(pair){ + nr_ice_candidate_pair_role_change(pair); + pair=TAILQ_NEXT(pair,entry); + } + } + diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h index 1a4bb2b24a1..28f6ccd30a1 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.h @@ -65,7 +65,7 @@ struct nr_ice_media_stream_ { nr_ice_cand_pair_head check_list; void *timer; /* Check list periodic timer */ -// nr_ice_cand_pair_head valid_list; +/* nr_ice_cand_pair_head valid_list; */ STAILQ_ENTRY(nr_ice_media_stream_) entry; }; @@ -96,6 +96,7 @@ int nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr); int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int component_id); int nr_ice_media_stream_pair_new_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *pstream, nr_ice_candidate *cand); +void nr_ice_media_stream_role_change(nr_ice_media_stream *stream); #ifdef __cplusplus } diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c index 1b03f5e01fb..9413cd676fd 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.c @@ -68,15 +68,10 @@ int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, /* Decide controlling vs. controlled */ if(ctx->flags & NR_ICE_CTX_FLAGS_LITE){ - if(pctx->peer_lite){ - r_log(LOG_ICE,LOG_ERR,"Both sides are ICE-Lite"); - ABORT(R_BAD_DATA); - } - pctx->controlling=0; } else{ - if(pctx->peer_lite || (ctx->flags & NR_ICE_CTX_FLAGS_OFFERER)) + if(ctx->flags & NR_ICE_CTX_FLAGS_OFFERER) pctx->controlling=1; else if(ctx->flags & NR_ICE_CTX_FLAGS_ANSWERER) pctx->controlling=0; @@ -364,6 +359,13 @@ int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx) nr_ice_media_stream *stream; int r,_status; + if(pctx->peer_lite && !pctx->controlling) { + if(pctx->ctx->flags & NR_ICE_CTX_FLAGS_LITE){ + r_log(LOG_ICE,LOG_ERR,"Both sides are ICE-Lite"); + ABORT(R_BAD_DATA); + } + nr_ice_peer_ctx_switch_controlling_role(pctx); + } r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): peer (%s) pairing candidates",pctx->ctx->label,pctx->label); @@ -723,4 +725,31 @@ int nr_ice_peer_ctx_deliver_packet_maybe(nr_ice_peer_ctx *pctx, nr_ice_component return(_status); } +void nr_ice_peer_ctx_switch_controlling_role(nr_ice_peer_ctx *pctx) + { + int controlling = !(pctx->controlling); + if(pctx->controlling_conflict_resolved) { + r_log(LOG_ICE,LOG_WARNING,"ICE(%s): peer (%s) %s called more than once; " + "this probably means the peer is confused. Not switching roles.", + pctx->ctx->label,pctx->label,__FUNCTION__); + return; + } + + r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): detected " + "role conflict. Switching to %s", + pctx->label, + controlling ? "controlling" : "controlled"); + + pctx->controlling = controlling; + pctx->controlling_conflict_resolved = 1; + + if(pctx->state == NR_ICE_PEER_STATE_PAIRED) { + /* We have formed candidate pairs. We need to inform them. */ + nr_ice_media_stream *pstream=STAILQ_FIRST(&pctx->peer_streams); + while(pstream) { + nr_ice_media_stream_role_change(pstream); + pstream = STAILQ_NEXT(pstream, entry); + } + } + } diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h index 24b2daecaf6..279e9ec145f 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_peer_ctx.h @@ -49,6 +49,7 @@ struct nr_ice_peer_ctx_ { nr_ice_handler *handler; UCHAR controlling; /* 1 for controlling, 0 for controlled */ + UCHAR controlling_conflict_resolved; UINT8 tiebreaker; char *peer_ufrag; @@ -86,6 +87,7 @@ int nr_ice_peer_ctx_find_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *s int nr_ice_peer_ctx_deliver_packet_maybe(nr_ice_peer_ctx *pctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len); int nr_ice_peer_ctx_disable_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *lstream, int component_id); int nr_ice_peer_ctx_pair_new_trickle_candidate(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx, nr_ice_candidate *cand); +void nr_ice_peer_ctx_switch_controlling_role(nr_ice_peer_ctx *pctx); #ifdef __cplusplus } diff --git a/media/mtransport/third_party/nrappkit/IMPORT_FILES b/media/mtransport/third_party/nrappkit/IMPORT_FILES index 66f9d18f826..0f80a52e33d 100644 --- a/media/mtransport/third_party/nrappkit/IMPORT_FILES +++ b/media/mtransport/third_party/nrappkit/IMPORT_FILES @@ -10,8 +10,6 @@ src/util/libekr/debug.h src/util/libekr/r_assoc.c src/util/libekr/r_assoc.h - src/util/libekr/r_bitfield.c - src/util/libekr/r_bitfield.h src/util/libekr/r_common.h src/util/libekr/r_crc32.c src/util/libekr/r_crc32.h diff --git a/media/mtransport/third_party/nrappkit/nrappkit.gyp b/media/mtransport/third_party/nrappkit/nrappkit.gyp index b22923838f0..136f470392e 100644 --- a/media/mtransport/third_party/nrappkit/nrappkit.gyp +++ b/media/mtransport/third_party/nrappkit/nrappkit.gyp @@ -42,8 +42,6 @@ './src/util/libekr/r_assoc.c', './src/util/libekr/r_assoc.h', # './src/util/libekr/r_assoc_test.c', - './src/util/libekr/r_bitfield.c', - './src/util/libekr/r_bitfield.h', './src/util/libekr/r_common.h', './src/util/libekr/r_crc32.c', './src/util/libekr/r_crc32.h', diff --git a/media/mtransport/third_party/nrappkit/src/util/libekr/r_bitfield.c b/media/mtransport/third_party/nrappkit/src/util/libekr/r_bitfield.c deleted file mode 100644 index ed01b45aa5c..00000000000 --- a/media/mtransport/third_party/nrappkit/src/util/libekr/r_bitfield.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - r_bitfield.c - - - Copyright (C) 2002-2003, Network Resonance, Inc. - Copyright (C) 2006, Network Resonance, Inc. - All Rights Reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. Neither the name of Network Resonance, Inc. nor the name of any - contributors to this software may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - - */ - -/** - r_bitfield.c - - Copyright (C) 2001 RTFM, Inc. - All Rights Reserved. - - ekr@rtfm.com Wed Oct 3 11:15:23 2001 - */ - - -static char *RCSSTRING __UNUSED__ ="$Id: r_bitfield.c,v 1.2 2006/08/16 19:39:17 adamcain Exp $"; - -#include -#include -#include -#include "r_bitfield.h" - -int r_bitfield_create(setp,size) - r_bitfield **setp; - UINT4 size; - { - r_bitfield *set=0; - int _status; - int num_words=size/32+!!(size%32); - - if(!(set=(r_bitfield *)RMALLOC(sizeof(r_bitfield)))) - ABORT(R_NO_MEMORY); - - if(!(set->data=(UINT4 *)RMALLOC(num_words*4))) - ABORT(R_NO_MEMORY); - memset(set->data,0,4*num_words); - - set->base=0; - set->len=num_words; - - *setp=set; - - _status=0; - abort: - if(_status){ - r_bitfield_destroy(&set); - } - return(_status); - } - -int r_bitfield_destroy(setp) - r_bitfield **setp; - { - r_bitfield *set; - - if(!setp || !*setp) - return(0); - - set=*setp; - - RFREE(set->data); - RFREE(set); - - *setp=0; - return(0); - } - -int r_bitfield_set(set,bit) - r_bitfield *set; - int bit; - { - int word=(bit-set->base)/32; - int bbit=(bit-set->base)%32; - int _status; - - /* Resize? */ - if(word>set->len){ - UINT4 newlen=set->len; - UINT4 *tmp; - - while(newlendata,set->len*4); - memset(tmp+set->len*4,0,(newlen-set->len)*4); - - RFREE(set->data); - set->data=tmp; - } - - set->data[word]|=1<base)/32; - int bbit=(bit-set->base)%32; - int _status; - - if(bitbase) - return(0); - - /* Resize? */ - if(word>set->len) - return(0); - - return(set->data[word]&(1<(aClosure); + if (aTimeStamp < *now) { + return PL_DHASH_REMOVE; + } + + return PL_DHASH_NEXT; +} + +} // anon + +// Cleans out the old entries in mForcedValidEntries +void CacheStorageService::ForcedValidEntriesPrune(TimeStamp &now) +{ + static TimeDuration const oneMinute = TimeDuration::FromSeconds(60); + static TimeStamp dontPruneUntil = now + oneMinute; + if (now < dontPruneUntil) + return; + + mForcedValidEntries.Enumerate(PruneForcedValidEntries, &now); + dontPruneUntil = now + oneMinute; +} + void CacheStorageService::OnMemoryConsumptionChange(CacheMemoryConsumer* aConsumer, uint32_t aCurrentMemoryConsumption) diff --git a/netwerk/cache2/CacheStorageService.h b/netwerk/cache2/CacheStorageService.h index e1540302890..379deb4e753 100644 --- a/netwerk/cache2/CacheStorageService.h +++ b/netwerk/cache2/CacheStorageService.h @@ -91,8 +91,9 @@ public: already_AddRefed Thread() const; mozilla::Mutex& Lock() { return mLock; } - // Tracks entries that may be forced valid. + // Tracks entries that may be forced valid in a pruned hashtable. nsDataHashtable mForcedValidEntries; + void ForcedValidEntriesPrune(TimeStamp &now); // Helper thread-safe interface to pass entry info, only difference from // nsICacheStorageVisitor is that instead of nsIURI only the uri spec is diff --git a/netwerk/protocol/rtsp/rtsp/APacketSource.cpp b/netwerk/protocol/rtsp/rtsp/APacketSource.cpp index e0f460d6903..f8c18c60167 100644 --- a/netwerk/protocol/rtsp/rtsp/APacketSource.cpp +++ b/netwerk/protocol/rtsp/rtsp/APacketSource.cpp @@ -215,12 +215,21 @@ static sp MakeAVCCodecSpecificData( } sp MakeAACCodecSpecificData(const char *params) { + if (!params || !strlen(params)) { + return NULL; + } AString val; - CHECK(GetAttribute(params, "config", &val)); + if (!GetAttribute(params, "config", &val)) { + return NULL; + } sp config = decodeHex(val); - CHECK(config != NULL); - CHECK_GE(config->size(), 4u); + if (!config.get()) { + return NULL; + } + if (config->size() < 4u) { + return NULL; + } const uint8_t *data = config->data(); uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; @@ -476,6 +485,10 @@ APacketSource::APacketSource( sp codecSpecificData = MakeAACCodecSpecificData(params.c_str()); + if (!codecSpecificData.get()) { + mInitCheck = ERROR_UNSUPPORTED; + return; + } mFormat->setData( kKeyESDS, 0, diff --git a/security/manager/ssl/src/nsCrypto.cpp b/security/manager/ssl/src/nsCrypto.cpp index bf560bb105e..f656eeeadbc 100644 --- a/security/manager/ssl/src/nsCrypto.cpp +++ b/security/manager/ssl/src/nsCrypto.cpp @@ -15,6 +15,7 @@ #include "nsServiceManagerUtils.h" #ifndef MOZ_DISABLE_CRYPTOLEGACY +#include "mozilla/dom/ScriptSettings.h" #include "nsKeygenHandler.h" #include "nsKeygenThread.h" #include "nsNSSCertificate.h" @@ -33,7 +34,7 @@ #include "nsIDocument.h" #include "nsIScriptObjectPrincipal.h" #include "nsIScriptContext.h" -#include "nsIScriptGlobalObject.h" +#include "nsIGlobalObject.h" #include "nsContentUtils.h" #include "nsCxPusher.h" #include "nsDOMJSUtils.h" @@ -167,10 +168,8 @@ typedef struct nsKeyPairInfoStr { //to the nsCryptoRunnable event. class nsCryptoRunArgs : public nsISupports { public: - nsCryptoRunArgs(JSContext *aCx); - nsCOMPtr m_kungFuDeathGrip; - JSContext *m_cx; - JS::PersistentRooted m_scope; + nsCryptoRunArgs(); + nsCOMPtr m_globalObject; nsXPIDLCString m_jsCallback; NS_DECL_ISUPPORTS protected: @@ -1842,15 +1841,6 @@ loser: return nullptr; } -static nsISupports * -GetISupportsFromContext(JSContext *cx) -{ - if (JS::ContextOptionsRef(cx).privateIsNSISupports()) - return static_cast(JS_GetContextPrivate(cx)); - - return nullptr; -} - //The top level method which is a member of nsIDOMCrypto //for generate a base64 encoded CRMF request. CRMFObject* @@ -1888,8 +1878,8 @@ nsCrypto::GenerateCRMFRequest(JSContext* aContext, return nullptr; } - JS::RootedObject script_obj(aContext, GetWrapper()); - if (MOZ_UNLIKELY(!script_obj)) { + nsCOMPtr globalObject = do_QueryInterface(GetParentObject()); + if (MOZ_UNLIKELY(!globalObject)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } @@ -2036,10 +2026,9 @@ nsCrypto::GenerateCRMFRequest(JSContext* aContext, // MOZ_ASSERT(nsContentUtils::GetCurrentJSContext()); - nsCryptoRunArgs *args = new nsCryptoRunArgs(aContext); + nsCryptoRunArgs *args = new nsCryptoRunArgs(); - args->m_kungFuDeathGrip = GetISupportsFromContext(aContext); - args->m_scope = JS_GetParent(script_obj); + args->m_globalObject = globalObject; if (!aJsCallback.IsVoid()) { args->m_jsCallback = aJsCallback; } @@ -2148,7 +2137,7 @@ nsP12Runnable::Run() return NS_OK; } -nsCryptoRunArgs::nsCryptoRunArgs(JSContext *cx) : m_cx(cx), m_scope(cx) {} +nsCryptoRunArgs::nsCryptoRunArgs() {} nsCryptoRunArgs::~nsCryptoRunArgs() {} @@ -2172,10 +2161,12 @@ NS_IMETHODIMP nsCryptoRunnable::Run() { nsNSSShutDownPreventionLock locker; - AutoPushJSContext cx(m_args->m_cx); - JSAutoRequest ar(cx); - JS::Rooted scope(cx, m_args->m_scope); - JSAutoCompartment ac(cx, scope); + + // We're going to run script via JS_EvaluateScript, so we need an + // AutoEntryScript. This is Gecko specific and not on a standards track. + AutoEntryScript aes(m_args->m_globalObject); + JSContext* cx = aes.cx(); + JS::RootedObject scope(cx, JS::CurrentGlobalOrNull(cx)); bool ok = JS_EvaluateScript(cx, scope, m_args->m_jsCallback, diff --git a/services/sync/tps/extensions/tps/resource/tps.jsm b/services/sync/tps/extensions/tps/resource/tps.jsm index 7809f355b02..6ca526e9a96 100644 --- a/services/sync/tps/extensions/tps/resource/tps.jsm +++ b/services/sync/tps/extensions/tps/resource/tps.jsm @@ -300,7 +300,12 @@ let TPS = { Logger.logInfo("tab for " + taburi + " finished loading"); if (that._tabsFinished == that._tabsAdded) { Logger.logInfo("all tabs loaded, continuing..."); - that.FinishAsyncOperation(); + + // Wait a second before continuing to be sure tabs can be synced, + // otherwise we can get 'error locating tab' + Utils.namedTimer(function () { + that.FinishAsyncOperation(); + }, 1000, this, "postTabsOpening"); } }); break; diff --git a/toolkit/components/captivedetect/captivedetect.js b/toolkit/components/captivedetect/captivedetect.js index b332a89c247..b9dc20afb12 100644 --- a/toolkit/components/captivedetect/captivedetect.js +++ b/toolkit/components/captivedetect/captivedetect.js @@ -121,7 +121,7 @@ function LoginObserver(captivePortalDetector) { // Public interface of LoginObserver let observer = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIHttpActivityOberver, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIHttpActivityObserver, Ci.nsITimerCallback]), attach: function attach() { @@ -228,7 +228,7 @@ function CaptivePortalDetector() { this._requestQueue = []; // Maintain a progress table, store callbacks and the ongoing XHR this._interfaceNames = {}; // Maintain names of the requested network interfaces - debug('CaptiveProtalDetector initiated, waitng for network connection established'); + debug('CaptiveProtalDetector initiated, waiting for network connection established'); } CaptivePortalDetector.prototype = { @@ -247,7 +247,7 @@ CaptivePortalDetector.prototype = { // Prevent multiple requests on a single network interface if (this._interfaceNames[aInterfaceName]) { - throw Components.Exception('Do not allow multiple request on one interface: ' + aInterface); + throw Components.Exception('Do not allow multiple request on one interface: ' + aInterfaceName); } let request = {interfaceName: aInterfaceName}; diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build index 5e8c4eddc17..85e38b4c0da 100644 --- a/toolkit/xre/moz.build +++ b/toolkit/xre/moz.build @@ -160,6 +160,8 @@ if CONFIG['MOZ_ENABLE_XREMOTE']: '/widget/xremoteclient', ] +if CONFIG['MOZ_B2G_LOADER']: + DEFINES['OMNIJAR_NAME'] = CONFIG['OMNIJAR_NAME'] CXXFLAGS += CONFIG['TK_CFLAGS'] CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS'] CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 36e7aea2bc5..fe8ed3c449e 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -185,6 +185,10 @@ #include "GTestRunner.h" #endif +#ifdef MOZ_B2G_LOADER +#include "ProcessUtils.h" +#endif + #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" #endif @@ -3772,6 +3776,10 @@ XREMain::XRE_mainRun() nsresult rv = NS_OK; NS_ASSERTION(mScopedXPCom, "Scoped xpcom not initialized."); +#ifdef MOZ_B2G_LOADER + mozilla::ipc::ProcLoaderClientGeckoInit(); +#endif + #ifdef NS_FUNCTION_TIMER // initialize some common services, so we don't pay the cost for these at odd times later on; // SetWindowCreator -> ChromeRegistry -> IOService -> SocketTransportService -> (nspr wspm init), Prefs diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index 3a7f5b9780f..4857abdf5f5 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -81,6 +81,11 @@ using mozilla::_ipdltest::IPDLUnitTestProcessChild; #endif // ifdef MOZ_IPDL_TESTS +#ifdef MOZ_B2G_LOADER +#include "nsLocalFile.h" +#include "nsXREAppData.h" +#endif + using namespace mozilla; using mozilla::ipc::BrowserProcessSubThread; @@ -815,3 +820,38 @@ XRE_GetWindowsEnvironment() } #endif // XP_WIN +#ifdef MOZ_B2G_LOADER +extern const nsXREAppData* gAppData; + +/** + * Preload static data of Gecko for B2G loader. + * + * This function is supposed to be called before XPCOM is initialized. + * For now, this function preloads + * - XPT interface Information + */ +void +XRE_ProcLoaderPreload(const char* aProgramDir, const nsXREAppData* aAppData) +{ + void PreloadXPT(nsIFile *); + + nsresult rv; + nsCOMPtr omnijarFile; + rv = NS_NewNativeLocalFile(nsCString(aProgramDir), + true, + getter_AddRefs(omnijarFile)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + rv = omnijarFile->AppendNative(NS_LITERAL_CSTRING(NS_STRINGIFY(OMNIJAR_NAME))); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + /* + * gAppData is required by nsXULAppInfo. The manifest parser + * evaluate flags with the information from nsXULAppInfo. + */ + gAppData = aAppData; + + PreloadXPT(omnijarFile); + + gAppData = nullptr; +} +#endif /* MOZ_B2G_LOADER */ diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index d84ef0478c2..a4bac142f5e 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -878,6 +878,10 @@ void mozilla_sampler_unlock() bool mozilla_sampler_register_thread(const char* aName, void* stackTop) { + if (sInitCount == 0) { + return false; + } + #if defined(MOZ_WIDGET_GONK) && !defined(MOZ_PROFILING) // The only way to profile secondary threads on b2g // is to build with profiling OR have the profiler @@ -895,6 +899,10 @@ bool mozilla_sampler_register_thread(const char* aName, void* stackTop) void mozilla_sampler_unregister_thread() { + if (sInitCount == 0) { + return; + } + Sampler::UnregisterCurrentThread(); PseudoStack *stack = tlsPseudoStack.get(); @@ -906,6 +914,10 @@ void mozilla_sampler_unregister_thread() } void mozilla_sampler_sleep_start() { + if (sInitCount == 0) { + return; + } + PseudoStack *stack = tlsPseudoStack.get(); if (stack == nullptr) { return; @@ -914,6 +926,10 @@ void mozilla_sampler_sleep_start() { } void mozilla_sampler_sleep_end() { + if (sInitCount == 0) { + return; + } + PseudoStack *stack = tlsPseudoStack.get(); if (stack == nullptr) { return; diff --git a/widget/gonk/PowerWakeLock.cpp b/widget/gonk/PowerWakeLock.cpp new file mode 100644 index 00000000000..7e4d0e1a1b2 --- /dev/null +++ b/widget/gonk/PowerWakeLock.cpp @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "PowerWakeLock.h" +#include + +const char* kPower_WAKE_LOCK_ID = "PowerKeyEvent"; + +namespace mozilla { +namespace hal_impl { +StaticRefPtr gPowerWakelock; +PowerWakelock::PowerWakelock() +{ + acquire_wake_lock(PARTIAL_WAKE_LOCK, kPower_WAKE_LOCK_ID); +} + +PowerWakelock::~PowerWakelock() +{ + release_wake_lock(kPower_WAKE_LOCK_ID); +} +} // hal_impl +} // mozilla diff --git a/widget/gonk/PowerWakeLock.h b/widget/gonk/PowerWakeLock.h new file mode 100644 index 00000000000..becf73969ec --- /dev/null +++ b/widget/gonk/PowerWakeLock.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __POWERWAKELOCK_H_ +#define __POWERWAKELOCK_H_ + +#include "mozilla/StaticPtr.h" +#include "nsISupportsImpl.h" + +namespace mozilla { +namespace hal_impl { +class PowerWakelock +{ +public: + NS_INLINE_DECL_REFCOUNTING(PowerWakelock); + PowerWakelock(); +private: + ~PowerWakelock(); +}; +extern StaticRefPtr gPowerWakelock; +} // hal_impl +} // mozilla +#endif /* __POWERWAKELOCK_H_ */ diff --git a/widget/gonk/libui/EventHub.cpp b/widget/gonk/libui/EventHub.cpp index 89581bcef01..9b318a41b43 100644 --- a/widget/gonk/libui/EventHub.cpp +++ b/widget/gonk/libui/EventHub.cpp @@ -51,6 +51,12 @@ #include #include +#include "PowerWakeLock.h" +#include "mozilla/Hal.h" +using namespace mozilla; +using namespace mozilla::hal; +using namespace mozilla::hal_impl; + /* this macro is used to tell if "bit" is set in "array" * it selects a byte from the array, and does a boolean AND * operation with a byte that only has the relevant bit set. @@ -855,6 +861,10 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz event->type = iev.type; event->code = iev.code; event->value = iev.value; + if (event->code == KEY_POWER && event->value + && !hal::GetScreenEnabled()) { + gPowerWakelock = new PowerWakelock(); + } event += 1; capacity -= 1; } diff --git a/widget/gonk/moz.build b/widget/gonk/moz.build index 14f9d128d7c..6fff3421b9d 100644 --- a/widget/gonk/moz.build +++ b/widget/gonk/moz.build @@ -17,6 +17,7 @@ EXPORTS += [ 'GonkPermission.h', 'OrientationObserver.h', + 'PowerWakeLock.h', ] DIRS += ['libdisplay', 'nativewindow'] @@ -57,6 +58,7 @@ SOURCES += [ 'nsWindow.cpp', 'OrientationObserver.cpp', 'ParentProcessController.cpp', + 'PowerWakeLock.cpp', 'ProcessOrientation.cpp', 'WidgetTraceEvent.cpp' ] diff --git a/widget/gonk/nsLookAndFeel.cpp b/widget/gonk/nsLookAndFeel.cpp index a89ead051e8..3aae4eae86e 100644 --- a/widget/gonk/nsLookAndFeel.cpp +++ b/widget/gonk/nsLookAndFeel.cpp @@ -92,6 +92,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) aColor = TEXT_NORMAL_COLOR; break; case eColorID_TextSelectBackground: + aColor = NS_RGBA(0x33,0xb5,0xe5,0x66); + break; case eColorID_IMESelectedRawTextBackground: case eColorID_IMESelectedConvertedTextBackground: // still used diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp index 0befeeece87..10735b25d5b 100644 --- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -101,6 +101,13 @@ Break(const char* aMsg); #include #endif +#ifdef MOZ_B2G_LOADER +/* Avoid calling Android logger/logd temporarily while running + * B2GLoader to start the child process. + */ +bool gDisableAndroidLog = false; +#endif + using namespace mozilla; static const char* sMultiprocessDescription = nullptr; @@ -392,6 +399,9 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr, #endif #ifdef ANDROID +#ifdef MOZ_B2G_LOADER + if (!gDisableAndroidLog) +#endif __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buf.buffer); #endif diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp index cdbd40e1e4e..28a85ac568c 100644 --- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -6,19 +6,23 @@ #include "nsTraceRefcnt.h" #include "mozilla/IntegerPrintfMacros.h" +#include "mozilla/StaticPtr.h" #include "nsXPCOMPrivate.h" #include "nscore.h" #include "nsISupports.h" #include "nsTArray.h" +#include "nsTHashtable.h" #include "prenv.h" #include "plstr.h" #include "prlink.h" #include "nsCRT.h" #include +#include "nsHashKeys.h" #include "nsStackWalkPrivate.h" #include "nsStackWalk.h" #include "nsString.h" #include "nsThreadUtils.h" +#include "CodeAddressService.h" #include "nsXULAppAPI.h" #ifdef XP_WIN @@ -206,6 +210,78 @@ static const PLHashAllocOps typesToLogHashAllocOps = { //////////////////////////////////////////////////////////////////////////////// +#ifdef STACKWALKING_AVAILABLE + +class CodeAddressServiceStringTable MOZ_FINAL +{ +public: + CodeAddressServiceStringTable() + : mSet(64) + { + } + + const char* Intern(const char* aString) + { + nsCharPtrHashKey* e = mSet.PutEntry(aString); + return e->GetKey(); + } + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return mSet.SizeOfExcludingThis(aMallocSizeOf); + } + +private: + typedef nsTHashtable StringSet; + StringSet mSet; +}; + +struct CodeAddressServiceStringAlloc MOZ_FINAL +{ + static char* copy(const char* aStr) { return strdup(aStr); } + static void free(char* aPtr) { free(aPtr); } +}; + +class CodeAddressServiceWriter MOZ_FINAL +{ +public: + explicit CodeAddressServiceWriter(FILE* aFile) + : mFile(aFile) + { + } + + void Write(const char* aFmt, ...) const + { + va_list ap; + va_start(ap, aFmt); + vfprintf(mFile, aFmt, ap); + va_end(ap); + } + +private: + FILE* mFile; +}; + +// WalkTheStack does not hold any locks needed by NS_DescribeCodeAddress, so +// this class does not need to do anything. +struct CodeAddressServiceLock MOZ_FINAL +{ + static void Unlock() {} + static void Lock() {} + static bool IsLocked() { return true; } +}; + +typedef mozilla::CodeAddressService WalkTheStackCodeAddressService; + +mozilla::StaticAutoPtr gCodeAddressService; + +#endif // STACKWALKING_AVAILABLE + +//////////////////////////////////////////////////////////////////////////////// + class BloatEntry { public: @@ -883,6 +959,13 @@ PrintStackFrame(void* aPC, void* aSP, void* aClosure) NS_FormatCodeAddressDetails(aPC, &details, buf, sizeof(buf)); fputs(buf, stream); } + +static void +PrintStackFrameCached(void* aPC, void* aSP, void* aClosure) +{ + CodeAddressServiceWriter *writer = static_cast(aClosure); + gCodeAddressService->WriteLocation(*writer, aPC); +} #endif } @@ -896,6 +979,19 @@ nsTraceRefcnt::WalkTheStack(FILE* aStream) #endif } +void +nsTraceRefcnt::WalkTheStackCached(FILE* aStream) +{ +#ifdef STACKWALKING_AVAILABLE + if (!gCodeAddressService) { + gCodeAddressService = new WalkTheStackCodeAddressService(); + } + CodeAddressServiceWriter writer(aStream); + NS_StackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0, &writer, + 0, nullptr); +#endif +} + //---------------------------------------------------------------------- // This thing is exported by libstdc++ @@ -1038,14 +1134,14 @@ NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt, if (aRefcnt == 1 && gAllocLog && loggingThisType && loggingThisObject) { fprintf(gAllocLog, "\n<%s> 0x%08X %" PRIdPTR " Create\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno); - nsTraceRefcnt::WalkTheStack(gAllocLog); + nsTraceRefcnt::WalkTheStackCached(gAllocLog); } if (gRefcntsLog && loggingThisType && loggingThisObject) { // Can't use PR_LOG(), b/c it truncates the line fprintf(gRefcntsLog, "\n<%s> 0x%08X %" PRIuPTR " AddRef %" PRIuPTR "\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno, aRefcnt); - nsTraceRefcnt::WalkTheStack(gRefcntsLog); + nsTraceRefcnt::WalkTheStackCached(gRefcntsLog); fflush(gRefcntsLog); } UNLOCK_TRACELOG(); @@ -1090,7 +1186,7 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClazz) // Can't use PR_LOG(), b/c it truncates the line fprintf(gRefcntsLog, "\n<%s> 0x%08X %" PRIuPTR " Release %" PRIuPTR "\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno, aRefcnt); - nsTraceRefcnt::WalkTheStack(gRefcntsLog); + nsTraceRefcnt::WalkTheStackCached(gRefcntsLog); fflush(gRefcntsLog); } @@ -1101,7 +1197,7 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClazz) fprintf(gAllocLog, "\n<%s> 0x%08X %" PRIdPTR " Destroy\n", aClazz, NS_PTR_TO_INT32(aPtr), serialno); - nsTraceRefcnt::WalkTheStack(gAllocLog); + nsTraceRefcnt::WalkTheStackCached(gAllocLog); } if (aRefcnt == 0 && gSerialNumbers && loggingThisType) { @@ -1142,7 +1238,7 @@ NS_LogCtor(void* aPtr, const char* aType, uint32_t aInstanceSize) if (gAllocLog && loggingThisType && loggingThisObject) { fprintf(gAllocLog, "\n<%s> 0x%08X %" PRIdPTR " Ctor (%d)\n", aType, NS_PTR_TO_INT32(aPtr), serialno, aInstanceSize); - nsTraceRefcnt::WalkTheStack(gAllocLog); + nsTraceRefcnt::WalkTheStackCached(gAllocLog); } UNLOCK_TRACELOG(); @@ -1184,7 +1280,7 @@ NS_LogDtor(void* aPtr, const char* aType, uint32_t aInstanceSize) if (gAllocLog && loggingThisType && loggingThisObject) { fprintf(gAllocLog, "\n<%s> 0x%08X %" PRIdPTR " Dtor (%d)\n", aType, NS_PTR_TO_INT32(aPtr), serialno, aInstanceSize); - nsTraceRefcnt::WalkTheStack(gAllocLog); + nsTraceRefcnt::WalkTheStackCached(gAllocLog); } UNLOCK_TRACELOG(); @@ -1228,7 +1324,7 @@ NS_LogCOMPtrAddRef(void* aCOMPtr, nsISupports* aObject) fprintf(gCOMPtrLog, "\n 0x%08X %" PRIdPTR " nsCOMPtrAddRef %d 0x%08X\n", NS_PTR_TO_INT32(object), serialno, count ? (*count) : -1, NS_PTR_TO_INT32(aCOMPtr)); - nsTraceRefcnt::WalkTheStack(gCOMPtrLog); + nsTraceRefcnt::WalkTheStackCached(gCOMPtrLog); } UNLOCK_TRACELOG(); @@ -1272,7 +1368,7 @@ NS_LogCOMPtrRelease(void* aCOMPtr, nsISupports* aObject) fprintf(gCOMPtrLog, "\n 0x%08X %" PRIdPTR " nsCOMPtrRelease %d 0x%08X\n", NS_PTR_TO_INT32(object), serialno, count ? (*count) : -1, NS_PTR_TO_INT32(aCOMPtr)); - nsTraceRefcnt::WalkTheStack(gCOMPtrLog); + nsTraceRefcnt::WalkTheStackCached(gCOMPtrLog); } UNLOCK_TRACELOG(); @@ -1289,7 +1385,9 @@ void nsTraceRefcnt::Shutdown() { #ifdef NS_IMPL_REFCNT_LOGGING - +#ifdef STACKWALKING_AVAILABLE + gCodeAddressService = nullptr; +#endif if (gBloatView) { PL_HashTableDestroy(gBloatView); gBloatView = nullptr; diff --git a/xpcom/base/nsTraceRefcnt.h b/xpcom/base/nsTraceRefcnt.h index 1d27e83affe..19898a1d7a7 100644 --- a/xpcom/base/nsTraceRefcnt.h +++ b/xpcom/base/nsTraceRefcnt.h @@ -28,6 +28,17 @@ public: static void DemangleSymbol(const char* aSymbol, char* aBuffer, int aBufLen); static void WalkTheStack(FILE* aStream); + + /** + * This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache + * the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being + * called frequently, it will be a few orders of magnitude faster than + * |WalkTheStack|. However, the cache uses a lot of memory, which can cause + * OOM crashes. Therefore, this should only be used for things like refcount + * logging which walk the stack extremely frequently. + */ + static void WalkTheStackCached(FILE* aStream); + /** * Tell nsTraceRefcnt whether refcounting, allocation, and destruction * activity is legal. This is used to trigger assertions for any such diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 6f320744fd6..33329e33b23 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -467,6 +467,16 @@ XRE_API(WindowsEnvironmentType, XRE_GetWindowsEnvironment, ()) #endif // XP_WIN +#ifdef MOZ_B2G_LOADER +XRE_API(int, + XRE_ProcLoaderServiceRun, (pid_t, int, int argc, const char *argv[])); +XRE_API(void, + XRE_ProcLoaderClientInit, (pid_t, int)); +XRE_API(void, + XRE_ProcLoaderPreload, (const char* aProgramDir, + const nsXREAppData* aAppData)); +#endif // MOZ_B2G_LOADER + XRE_API(int, XRE_XPCShellMain, (int argc, char** argv, char** envp)) diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp index 28ac2681488..00a2d471407 100644 --- a/xpcom/components/ManifestParser.cpp +++ b/xpcom/components/ManifestParser.cpp @@ -36,6 +36,18 @@ #include "nsIScriptError.h" #include "nsIXULAppInfo.h" #include "nsIXULRuntime.h" +#ifdef MOZ_B2G_LOADER +#include "mozilla/XPTInterfaceInfoManager.h" +#endif + +#ifdef MOZ_B2G_LOADER +#define XPTONLY_MANIFEST &nsComponentManagerImpl::XPTOnlyManifestManifest +#define XPTONLY_XPT &nsComponentManagerImpl::XPTOnlyManifestXPT +#else +#define XPTONLY_MANIFEST nullptr +#define XPTONLY_XPT nullptr +#endif + using namespace mozilla; @@ -64,36 +76,43 @@ struct ManifestDirective (nsChromeRegistry::ManifestProcessingContext& cx, int lineno, char *const *argv, bool platform, bool contentaccessible); +#ifdef MOZ_B2G_LOADER + // The function to handle the directive for XPT Only parsing. + void (*xptonlyfunc)(nsComponentManagerImpl::XPTOnlyManifestProcessingContext& cx, + int lineno, char *const * argv); +#else + void *xptonlyfunc; +#endif bool isContract; }; static const ManifestDirective kParsingTable[] = { { "manifest", 1, false, true, true, false, - &nsComponentManagerImpl::ManifestManifest, nullptr }, + &nsComponentManagerImpl::ManifestManifest, nullptr, XPTONLY_MANIFEST }, { "binary-component", 1, true, false, false, false, - &nsComponentManagerImpl::ManifestBinaryComponent, nullptr }, + &nsComponentManagerImpl::ManifestBinaryComponent, nullptr, nullptr }, { "interfaces", 1, true, false, false, false, - &nsComponentManagerImpl::ManifestXPT, nullptr }, + &nsComponentManagerImpl::ManifestXPT, nullptr, XPTONLY_XPT }, { "component", 2, true, false, false, false, - &nsComponentManagerImpl::ManifestComponent, nullptr }, + &nsComponentManagerImpl::ManifestComponent, nullptr, nullptr }, { "contract", 2, true, false, false, false, - &nsComponentManagerImpl::ManifestContract, nullptr, true}, + &nsComponentManagerImpl::ManifestContract, nullptr, nullptr, true}, { "category", 3, true, false, false, false, - &nsComponentManagerImpl::ManifestCategory, nullptr }, + &nsComponentManagerImpl::ManifestCategory, nullptr, nullptr }, { "content", 2, true, true, true, true, - nullptr, &nsChromeRegistry::ManifestContent }, + nullptr, &nsChromeRegistry::ManifestContent, nullptr }, { "locale", 3, true, true, true, false, - nullptr, &nsChromeRegistry::ManifestLocale }, + nullptr, &nsChromeRegistry::ManifestLocale, nullptr }, { "skin", 3, false, true, true, false, - nullptr, &nsChromeRegistry::ManifestSkin }, + nullptr, &nsChromeRegistry::ManifestSkin, nullptr }, { "overlay", 2, true, true, false, false, - nullptr, &nsChromeRegistry::ManifestOverlay }, + nullptr, &nsChromeRegistry::ManifestOverlay, nullptr }, { "style", 2, false, true, false, false, - nullptr, &nsChromeRegistry::ManifestStyle }, + nullptr, &nsChromeRegistry::ManifestStyle, nullptr }, { "override", 2, true, true, true, false, - nullptr, &nsChromeRegistry::ManifestOverride }, + nullptr, &nsChromeRegistry::ManifestOverride, nullptr }, { "resource", 2, true, true, false, false, - nullptr, &nsChromeRegistry::ManifestResource } + nullptr, &nsChromeRegistry::ManifestResource, nullptr } }; static const char kWhitespace[] = "\t "; @@ -126,8 +145,16 @@ struct AutoPR_smprintf_free } // anonymous namespace +/** + * If we are pre-loading XPTs, this method may do nothing because the + * console service is not initialized. + */ void LogMessage(const char* aMsg, ...) { + if (!nsComponentManagerImpl::gComponentManager) { + return; + } + nsCOMPtr console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); if (!console) @@ -143,6 +170,10 @@ void LogMessage(const char* aMsg, ...) console->LogMessage(error); } +/** + * If we are pre-loading XPTs, this method may do nothing because the + * console service is not initialized. + */ void LogMessageWithContext(FileLocation &aFile, uint32_t aLineNumber, const char* aMsg, ...) { @@ -153,6 +184,10 @@ void LogMessageWithContext(FileLocation &aFile, if (!formatted) return; + if (!nsComponentManagerImpl::gComponentManager) { + return; + } + nsCString file; aFile.GetURIString(file); @@ -388,11 +423,23 @@ struct CachedDirective } // anonymous namespace +/** + * For XPT-Only mode, the parser handles only directives of "manifest" + * and "interfaces", and always call the function given by |xptonlyfunc| + * variable of struct |ManifestDirective|. + * + * This function is safe to be called before the component manager is + * ready if aXPTOnly is true for it don't invoke any component during + * parsing. + */ void -ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly) +ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly, bool aXPTOnly) { nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly); nsChromeRegistry::ManifestProcessingContext chromecx(type, file); +#ifdef MOZ_B2G_LOADER + nsComponentManagerImpl::XPTOnlyManifestProcessingContext xptonlycx(file); +#endif nsresult rv; NS_NAMED_LITERAL_STRING(kPlatform, "platform"); @@ -416,7 +463,12 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn nsAutoString osTarget; nsAutoString abi; - nsCOMPtr xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID)); + nsCOMPtr xapp; + if (!aXPTOnly) { + // Avoid to create any component for XPT only mode. + // No xapp means no ID, version, ..., modifiers checking. + xapp = do_GetService(XULAPPINFO_SERVICE_CONTRACTID); + } if (xapp) { nsAutoCString s; rv = xapp->GetID(s); @@ -516,9 +568,10 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn for (const ManifestDirective* d = kParsingTable; d < ArrayEnd(kParsingTable); ++d) { - if (!strcmp(d->directive, token)) { - directive = d; - break; + if (!strcmp(d->directive, token) && + (!aXPTOnly || d->xptonlyfunc)) { + directive = d; + break; } } @@ -577,8 +630,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn CheckStringFlag(kABI, wtoken, abi, stABI) || CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || - CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) + CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion)) { continue; + } #if defined(MOZ_WIDGET_ANDROID) bool tablet = false; @@ -619,6 +673,11 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn stABI == eBad) continue; +#ifdef MOZ_B2G_LOADER + if (aXPTOnly) { + directive->xptonlyfunc(xptonlycx, line, argv); + } else +#endif /* MOZ_B2G_LOADER */ if (directive->regfunc) { if (GeckoProcessType_Default != XRE_GetProcessType()) continue; @@ -636,7 +695,7 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn (nsChromeRegistry::gChromeRegistry->*(directive->regfunc)) (chromecx, line, argv, platform, contentAccessible); } - else if (directive->ischrome || !aChromeOnly) { + else if (directive->mgrfunc && (directive->ischrome || !aChromeOnly)) { if (directive->isContract) { CachedDirective* cd = contracts.AppendElement(); cd->lineno = line; @@ -646,6 +705,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn else (nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc)) (mgrcx, line, argv); + } else { + LogMessageWithContext(file, line, + "No valid manifest directive."); } } diff --git a/xpcom/components/ManifestParser.h b/xpcom/components/ManifestParser.h index 5dc98602bdf..61f70182dee 100644 --- a/xpcom/components/ManifestParser.h +++ b/xpcom/components/ManifestParser.h @@ -13,7 +13,7 @@ class nsIFile; void ParseManifest(NSLocationType type, mozilla::FileLocation &file, - char* buf, bool aChromeOnly); + char* buf, bool aChromeOnly, bool aXPTOnly=false); void LogMessage(const char* aMsg, ...); diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 8a5c0955ebc..61f670636ee 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -69,6 +69,7 @@ #include "nsStringEnumerator.h" #include "mozilla/FileUtils.h" #include "nsNetUtil.h" +#include "nsDataHashtable.h" #include // for placement new @@ -104,6 +105,36 @@ NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID); #define UID_STRING_LENGTH 39 +#ifdef MOZ_B2G_LOADER +typedef nsDataHashtable XPTIInfosBookType; +static XPTIInfosBookType *sXPTIInfosBook = nullptr; + +static XPTIInfosBookType * +GetXPTIInfosBook() +{ + if (sXPTIInfosBook == nullptr) { + sXPTIInfosBook = new XPTIInfosBookType; + } + return sXPTIInfosBook; +} + +static bool +IsRegisteredXPTIInfo(FileLocation &aFile) +{ + nsAutoCString uri; + aFile.GetURIString(uri); + return GetXPTIInfosBook()->Get(uri); +} + +static void +MarkRegisteredXPTIInfo(FileLocation &aFile) +{ + nsAutoCString uri; + aFile.GetURIString(uri); + GetXPTIInfosBook()->Put(uri, true); +} +#endif /* MOZ_B2G_LOADER */ + nsresult nsGetServiceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) const { @@ -524,11 +555,14 @@ CutExtension(nsCString& path) path.Cut(0, dotPos + 1); } -void -nsComponentManagerImpl::RegisterManifest(NSLocationType aType, - FileLocation &aFile, - bool aChromeOnly) +static void +DoRegisterManifest(NSLocationType aType, + FileLocation &aFile, + bool aChromeOnly, + bool aXPTOnly) { + MOZ_ASSERT(!aXPTOnly || + nsComponentManagerImpl::gComponentManager == nullptr); uint32_t len; FileLocation::Data data; nsAutoArrayPtr buf; @@ -542,7 +576,7 @@ nsComponentManagerImpl::RegisterManifest(NSLocationType aType, } if (NS_SUCCEEDED(rv)) { buf[len] = '\0'; - ParseManifest(aType, aFile, buf, aChromeOnly); + ParseManifest(aType, aFile, buf, aChromeOnly, aXPTOnly); } else if (NS_BOOTSTRAPPED_LOCATION != aType) { nsCString uri; aFile.GetURIString(uri); @@ -550,6 +584,14 @@ nsComponentManagerImpl::RegisterManifest(NSLocationType aType, } } +void +nsComponentManagerImpl::RegisterManifest(NSLocationType aType, + FileLocation &aFile, + bool aChromeOnly) +{ + DoRegisterManifest(aType, aFile, aChromeOnly, false); +} + void nsComponentManagerImpl::ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv) { @@ -587,14 +629,19 @@ nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, i RegisterModule(m, &f); } -void -nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv) +static void +DoRegisterXPT(FileLocation &aFile) { - FileLocation f(cx.mFile, argv[0]); +#ifdef MOZ_B2G_LOADER + if (IsRegisteredXPTIInfo(aFile)) { + return; + } +#endif + uint32_t len; FileLocation::Data data; nsAutoArrayPtr buf; - nsresult rv = f.GetData(data); + nsresult rv = aFile.GetData(data); if (NS_SUCCEEDED(rv)) { rv = data.GetSize(&len); } @@ -604,13 +651,23 @@ nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, c } if (NS_SUCCEEDED(rv)) { XPTInterfaceInfoManager::GetSingleton()->RegisterBuffer(buf, len); +#ifdef MOZ_B2G_LOADER + MarkRegisteredXPTIInfo(aFile); +#endif } else { nsCString uri; - f.GetURIString(uri); + aFile.GetURIString(uri); LogMessage("Could not read '%s'.", uri.get()); } } +void +nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv) +{ + FileLocation f(cx.mFile, argv[0]); + DoRegisterXPT(f); +} + void nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv) { @@ -794,6 +851,10 @@ nsresult nsComponentManagerImpl::Shutdown(void) delete sStaticModules; delete sModuleLocations; +#ifdef MOZ_B2G_LOADER + delete sXPTIInfosBook; + sXPTIInfosBook = nullptr; +#endif // Unload libraries mNativeModuleLoader.UnloadLibraries(); @@ -1942,6 +2003,54 @@ nsComponentManagerImpl::GetManifestLocations(nsIArray **aLocations) return NS_OK; } +#ifdef MOZ_B2G_LOADER + +/* static */ +void +nsComponentManagerImpl::XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext &aCx, + int aLineno, + char * const * aArgv) +{ + char* file = aArgv[0]; + FileLocation f(aCx.mFile, file); + + DoRegisterManifest(NS_COMPONENT_LOCATION, f, false, true); +} + +/* static */ +void +nsComponentManagerImpl::XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext &aCx, + int aLineno, + char * const * aArgv) +{ + FileLocation f(aCx.mFile, aArgv[0]); + DoRegisterXPT(f); +} + +/** + * To load XPT Interface Information before the component manager is ready. + * + * With this function, B2G loader could XPT interface info. as earier + * as possible to gain benefit of shared memory model of the kernel. + */ +/* static */ void +nsComponentManagerImpl::PreloadXPT(nsIFile *aFile) +{ + MOZ_ASSERT(nsComponentManagerImpl::gComponentManager == nullptr); + FileLocation location(aFile, "chrome.manifest"); + + DoRegisterManifest(NS_COMPONENT_LOCATION, location, + false, true /* aXPTOnly */); +} + +void +PreloadXPT(nsIFile *aOmnijarFile) +{ + nsComponentManagerImpl::PreloadXPT(aOmnijarFile); +} + +#endif /* MOZ_B2G_LOADER */ + EXPORT_XPCOM_API(nsresult) XRE_AddManifestLocation(NSLocationType aType, nsIFile* aLocation) { diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index 7eb903f0d1e..e0d3d159687 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -38,6 +38,10 @@ #include "mozilla/Omnijar.h" #include "mozilla/Attributes.h" +#ifdef MOZ_B2G_LOADER +#include "mozilla/FileLocation.h" +#endif + struct nsFactoryEntry; class nsIServiceManager; struct PRThread; @@ -316,6 +320,30 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); +#ifdef MOZ_B2G_LOADER + // Preload XPT interface info for B2G loader. + // This function is called before XPCOM has been initialized. + static void PreloadXPT(nsIFile *aFile); +#endif + +#ifdef MOZ_B2G_LOADER + // Parsing functions of directives of manifest for XPT only parsing. + struct XPTOnlyManifestProcessingContext + { + XPTOnlyManifestProcessingContext(mozilla::FileLocation &aFile) + : mFile(aFile) + { } + + ~XPTOnlyManifestProcessingContext() { } + + mozilla::FileLocation mFile; + }; + static void XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext& aCx, + int aLineno, char * const *aArgv); + static void XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext& aCx, + int aLineno, char * const *aArgv); +#endif + private: ~nsComponentManagerImpl(); }; diff --git a/xpcom/threads/BackgroundHangMonitor.cpp b/xpcom/threads/BackgroundHangMonitor.cpp index 72b64dd5306..73aa2533833 100644 --- a/xpcom/threads/BackgroundHangMonitor.cpp +++ b/xpcom/threads/BackgroundHangMonitor.cpp @@ -65,6 +65,7 @@ private: public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundHangManager) static StaticRefPtr sInstance; + static bool sProhibited; // Lock for access to members of this class Monitor mLock; @@ -162,6 +163,7 @@ public: StaticRefPtr BackgroundHangManager::sInstance; +bool BackgroundHangManager::sProhibited = false; ThreadLocal BackgroundHangThread::sTlsKey; @@ -413,8 +415,16 @@ BackgroundHangThread* BackgroundHangThread::FindThread() { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + if (BackgroundHangManager::sInstance == nullptr) { + MOZ_ASSERT(BackgroundHangManager::sProhibited, + "BackgroundHandleManager is not initialized"); + return nullptr; + } + if (sTlsKey.initialized()) { // Use TLS if available + MOZ_ASSERT(!BackgroundHangManager::sProhibited, + "BackgroundHandleManager is not initialized"); return sTlsKey.get(); } // If TLS is unavailable, we can search through the thread list @@ -440,6 +450,7 @@ void BackgroundHangMonitor::Startup() { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited"); MOZ_ASSERT(!BackgroundHangManager::sInstance, "Already initialized"); ThreadStackHelper::Startup(); BackgroundHangThread::Startup(); @@ -451,6 +462,7 @@ void BackgroundHangMonitor::Shutdown() { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + MOZ_ASSERT(!BackgroundHangManager::sProhibited, "Prohibited"); MOZ_ASSERT(BackgroundHangManager::sInstance, "Not initialized"); /* Scope our lock inside Shutdown() because the sInstance object can be destroyed as soon as we set sInstance to nullptr below, and @@ -467,7 +479,8 @@ BackgroundHangMonitor::BackgroundHangMonitor(const char* aName, : mThread(BackgroundHangThread::FindThread()) { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR - if (!mThread) { + if (!BackgroundHangManager::sProhibited && !mThread) { + // If sProhibit is true, mThread would be null, and no monitoring. mThread = new BackgroundHangThread(aName, aTimeoutMs, aMaxTimeoutMs); } #endif @@ -477,7 +490,8 @@ BackgroundHangMonitor::BackgroundHangMonitor() : mThread(BackgroundHangThread::FindThread()) { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR - MOZ_ASSERT(mThread, "Thread not initialized for hang monitoring"); + MOZ_ASSERT(!BackgroundHangManager::sProhibited || mThread, + "This thread is not initialized for hang monitoring"); #endif } @@ -489,6 +503,11 @@ void BackgroundHangMonitor::NotifyActivity() { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + if (mThread == nullptr) { + MOZ_ASSERT(BackgroundHangManager::sProhibited, + "This thread is not initialized for hang monitoring"); + return; + } mThread->NotifyActivity(); #endif } @@ -497,18 +516,49 @@ void BackgroundHangMonitor::NotifyWait() { #ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + if (mThread == nullptr) { + MOZ_ASSERT(BackgroundHangManager::sProhibited, + "This thread is not initialized for hang monitoring"); + return; + } mThread->NotifyWait(); #endif } +void +BackgroundHangMonitor::Prohibit() +{ +#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + MOZ_ASSERT(BackgroundHangManager::sInstance == nullptr, + "The background hang monitor is already initialized"); + BackgroundHangManager::sProhibited = true; +#endif +} + +void +BackgroundHangMonitor::Allow() +{ +#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + MOZ_ASSERT(BackgroundHangManager::sInstance == nullptr, + "The background hang monitor is already initialized"); + BackgroundHangManager::sProhibited = false; +#endif +} + /* Because we are iterating through the BackgroundHangThread linked list, we need to take a lock. Using MonitorAutoLock as a base class makes sure all of that is taken care of for us. */ BackgroundHangMonitor::ThreadHangStatsIterator::ThreadHangStatsIterator() : MonitorAutoLock(BackgroundHangManager::sInstance->mLock) - , mThread(BackgroundHangManager::sInstance->mHangThreads.getFirst()) + , mThread(BackgroundHangManager::sInstance ? + BackgroundHangManager::sInstance->mHangThreads.getFirst() : + nullptr) { +#ifdef MOZ_ENABLE_BACKGROUND_HANG_MONITOR + MOZ_ASSERT(BackgroundHangManager::sInstance || BackgroundHangManager::sProhibited, + "Inconsistent state"); +#endif } Telemetry::ThreadHangStats* diff --git a/xpcom/threads/BackgroundHangMonitor.h b/xpcom/threads/BackgroundHangMonitor.h index 76d517fce4d..059fb0a08ff 100644 --- a/xpcom/threads/BackgroundHangMonitor.h +++ b/xpcom/threads/BackgroundHangMonitor.h @@ -107,6 +107,8 @@ class BackgroundHangThread; * } * } * + * Prohibit() and Allow() make the background hang monitor work safely + * before Startup(). */ class BackgroundHangMonitor { @@ -204,6 +206,27 @@ public: * NotifyActivity when subsequently exiting the wait state. */ void NotifyWait(); + + /** + * Prohibit the hang monitor from activating. + * + * Startup() should not be called between Prohibit() and Allow(). + * This function makes the background hang monitor stop monitoring + * threads. + * + * Prohibit() and Allow() can be called before XPCOM is ready. If + * we don't stop monitoring threads it could case errors. + */ + static void Prohibit(); + + /** + * Allow the hang monitor to run. + * + * Allow() and Prohibit() should be called in pair. + * + * \see Prohibit() + */ + static void Allow(); }; } // namespace mozilla diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/directory/nsDirectoryViewer.cpp index 350083a0e49..f3f7c4ec25f 100644 --- a/xpfe/components/directory/nsDirectoryViewer.cpp +++ b/xpfe/components/directory/nsDirectoryViewer.cpp @@ -25,8 +25,6 @@ #include "nsIRDFService.h" #include "nsRDFCID.h" #include "rdf.h" -#include "nsIScriptContext.h" -#include "nsIScriptGlobalObject.h" #include "nsIServiceManager.h" #include "nsISupportsArray.h" #include "nsIXPConnect.h" @@ -50,7 +48,7 @@ #include "nsXPCOMCID.h" #include "nsIDocument.h" #include "mozilla/Preferences.h" -#include "nsCxPusher.h" +#include "mozilla/dom/ScriptSettings.h" using namespace mozilla; @@ -150,14 +148,13 @@ nsHTTPIndex::OnFTPControlLog(bool server, const char *msg) { NS_ENSURE_TRUE(mRequestor, NS_OK); - nsCOMPtr scriptGlobal(do_GetInterface(mRequestor)); - NS_ENSURE_TRUE(scriptGlobal, NS_OK); + nsCOMPtr globalObject = do_GetInterface(mRequestor); + NS_ENSURE_TRUE(globalObject, NS_OK); - nsIScriptContext *context = scriptGlobal->GetContext(); - NS_ENSURE_TRUE(context, NS_OK); - - AutoPushJSContext cx(context->GetNativeContext()); - NS_ENSURE_TRUE(cx, NS_OK); + // We're going to run script via JS_CallFunctionName, so we need an + // AutoEntryScript. This is Gecko specific and not in any spec. + dom::AutoEntryScript aes(globalObject); + JSContext* cx = aes.cx(); JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); NS_ENSURE_TRUE(global, NS_OK); @@ -224,14 +221,14 @@ nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext) if (mBindToGlobalObject && mRequestor) { mBindToGlobalObject = false; - // Now get the content viewer container's script object. - nsCOMPtr scriptGlobal(do_GetInterface(mRequestor)); - NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_FAILURE); + nsCOMPtr globalObject = do_GetInterface(mRequestor); + NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE); - nsIScriptContext *context = scriptGlobal->GetContext(); - NS_ENSURE_TRUE(context, NS_ERROR_FAILURE); + // We might run script via JS_SetProperty, so we need an AutoEntryScript. + // This is Gecko specific and not in any spec. + dom::AutoEntryScript aes(globalObject); + JSContext* cx = aes.cx(); - AutoPushJSContext cx(context->GetNativeContext()); JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); // Using XPConnect, wrap the HTTP index object...