From 6300af091bb8d4985ee6a59c7320b5ef87fef144 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 6 Jan 2015 14:59:04 -0800 Subject: [PATCH 001/224] Bug 1014341 (part 0) - Don't use trace-malloc in devtools automation files. r=sfink. --HG-- extra : rebase_source : 415426282b0fd4684be1221caeee163dbbde5b3e --- js/src/devtools/automation/arm-sim | 1 - js/src/devtools/automation/generational | 1 - js/src/devtools/automation/rootanalysis | 1 - 3 files changed, 3 deletions(-) diff --git a/js/src/devtools/automation/arm-sim b/js/src/devtools/automation/arm-sim index 0553b428a72a..f2dbbaff736c 100644 --- a/js/src/devtools/automation/arm-sim +++ b/js/src/devtools/automation/arm-sim @@ -1,7 +1,6 @@ --enable-optimize --enable-debug --enable-stdcxx-compat ---enable-trace-malloc --disable-shared-js --enable-threadsafe --enable-arm-simulator diff --git a/js/src/devtools/automation/generational b/js/src/devtools/automation/generational index b98b8d17cd19..36187614bcde 100644 --- a/js/src/devtools/automation/generational +++ b/js/src/devtools/automation/generational @@ -2,7 +2,6 @@ --enable-debug --enable-stdcxx-compat --enable-ctypes ---enable-trace-malloc --disable-shared-js --enable-exact-rooting --enable-gccompacting diff --git a/js/src/devtools/automation/rootanalysis b/js/src/devtools/automation/rootanalysis index ed0c6d52e329..36ad6771ac76 100644 --- a/js/src/devtools/automation/rootanalysis +++ b/js/src/devtools/automation/rootanalysis @@ -2,7 +2,6 @@ --enable-debug --enable-stdcxx-compat --enable-ctypes ---enable-trace-malloc --disable-shared-js --enable-exact-rooting --enable-gcgenerational From e9f49ca06a7f1f6f03ebc40bdac0c8f0c107a121 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2015 16:12:31 -0800 Subject: [PATCH 002/224] Bug 1014341 (part 0b) - Remove trace-malloc mentions from diff-talos.py. r=jmaher. --HG-- extra : rebase_source : 439076b23b4cd28bf8dc64c0444968c4847aab01 --- testing/talos/diff-talos.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/testing/talos/diff-talos.py b/testing/talos/diff-talos.py index 10e8b83c57e9..4bfd3a8a7955 100755 --- a/testing/talos/diff-talos.py +++ b/testing/talos/diff-talos.py @@ -40,11 +40,9 @@ smaller_is_better = frozenset(('tdhtmlr_paint', 'tp5n_main_rss_paint', 'tresize', 'trobopan', 'tcheckerboard', 'tcheck3', 'tcheck2', 'tprovider', 'tp5n_modlistbytes_paint', - 'trace_malloc_maxheap', 'tp4m_nochrome', - 'trace_malloc_leaks', 'tp4m_main_rss_nochrome', + 'tp4m_nochrome', 'tp4m_main_rss_nochrome', 'tp4m_shutdown_nochrome', 'tdhtml_nochrome', - 'ts_shutdown', 'tp5n_%cpu_paint', - 'trace_malloc_allocs', 'ts', + 'ts_shutdown', 'tp5n_%cpu_paint', 'ts', 'tsvg_nochrome', 'tp5n_content_rss_paint', 'tp5n_main_startup_fileio_paint', 'tp5n_nonmain_normal_netio_paint', From 97b5d348cc8e2a3e9c3c1b6b1b1e8c0d2c37714a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 7 Jan 2015 16:13:03 -0800 Subject: [PATCH 003/224] Bug 1014341 (part 1) - Remove trace-malloc. r=dbaron,glandium. --HG-- extra : rebase_source : 771710c5427141d738eef112fab00951eb8e20e3 --- .../source/python-lib/cuddlefish/runner.py | 1 - build/automation.py.in | 1 - build/automationutils.py | 1 - config/config.mk | 14 +- configure.in | 35 +- dom/base/nsJSEnvironment.cpp | 178 - gfx/thebes/gfxPlatform.cpp | 2 +- js/src/configure.in | 28 +- testing/xpcshell/runxpcshelltests.py | 3 - .../aboutmemory/tests/test_aboutmemory.xul | 2 +- .../tests/test_memoryReporters.xul | 2 +- toolkit/toolkit.mozbuild | 6 - toolkit/xre/nsAppRunner.cpp | 11 +- tools/trace-malloc/Makefile.in | 39 - tools/trace-malloc/README | 177 - tools/trace-malloc/TraceMalloc.pm | 156 - tools/trace-malloc/adreader.cpp | 132 - tools/trace-malloc/adreader.h | 97 - tools/trace-malloc/allocation-stacks.c | 92 - tools/trace-malloc/blame.css | 14 - tools/trace-malloc/blame.pl | 219 - tools/trace-malloc/bloatblame.cpp | 722 -- tools/trace-malloc/diffbloatdump.pl | 207 - tools/trace-malloc/formdata.c | 204 - tools/trace-malloc/formdata.h | 64 - tools/trace-malloc/getopt.c | 107 - tools/trace-malloc/histogram-diff.sh | 76 - tools/trace-malloc/histogram-pretty.sh | 63 - tools/trace-malloc/histogram.pl | 64 - tools/trace-malloc/leak-soup.pl | 1180 --- tools/trace-malloc/leaksoup.cpp | 416 -- tools/trace-malloc/leakstats.c | 161 - tools/trace-malloc/lib/moz.build | 34 - tools/trace-malloc/lib/nsDebugHelpWin32.cpp | 372 - tools/trace-malloc/lib/nsDebugHelpWin32.h | 133 - tools/trace-malloc/lib/nsTraceMalloc.c | 2063 ------ tools/trace-malloc/lib/nsTraceMalloc.h | 226 - .../trace-malloc/lib/nsTraceMallocCallbacks.h | 64 - tools/trace-malloc/lib/nsTypeInfo.cpp | 279 - tools/trace-malloc/lib/nsTypeInfo.h | 22 - tools/trace-malloc/lib/nsWinTraceMalloc.cpp | 242 - tools/trace-malloc/lib/tm.def | 19 - tools/trace-malloc/live-bloat.html | 12 - tools/trace-malloc/merge.pl | 57 - tools/trace-malloc/moz.build | 34 - tools/trace-malloc/rules.txt | 442 -- tools/trace-malloc/spacecategory.c | 959 --- tools/trace-malloc/spacetrace.c | 6352 ----------------- tools/trace-malloc/spacetrace.css | 170 - tools/trace-malloc/spacetrace.h | 694 -- tools/trace-malloc/stoptions.h | 302 - tools/trace-malloc/tmfrags.c | 950 --- tools/trace-malloc/tmreader.c | 892 --- tools/trace-malloc/tmreader.h | 191 - tools/trace-malloc/tmstats.c | 830 --- tools/trace-malloc/types.dat | 5842 --------------- tools/trace-malloc/uncategorized.pl | 117 - xpcom/base/nsTraceRefcnt.cpp | 12 - xpcom/base/nscore.h | 2 +- xpcom/glue/standalone/nsXPCOMGlue.cpp | 84 - 60 files changed, 18 insertions(+), 25852 deletions(-) delete mode 100644 tools/trace-malloc/Makefile.in delete mode 100644 tools/trace-malloc/README delete mode 100644 tools/trace-malloc/TraceMalloc.pm delete mode 100644 tools/trace-malloc/adreader.cpp delete mode 100644 tools/trace-malloc/adreader.h delete mode 100644 tools/trace-malloc/allocation-stacks.c delete mode 100644 tools/trace-malloc/blame.css delete mode 100755 tools/trace-malloc/blame.pl delete mode 100644 tools/trace-malloc/bloatblame.cpp delete mode 100755 tools/trace-malloc/diffbloatdump.pl delete mode 100644 tools/trace-malloc/formdata.c delete mode 100644 tools/trace-malloc/formdata.h delete mode 100644 tools/trace-malloc/getopt.c delete mode 100755 tools/trace-malloc/histogram-diff.sh delete mode 100755 tools/trace-malloc/histogram-pretty.sh delete mode 100755 tools/trace-malloc/histogram.pl delete mode 100755 tools/trace-malloc/leak-soup.pl delete mode 100644 tools/trace-malloc/leaksoup.cpp delete mode 100644 tools/trace-malloc/leakstats.c delete mode 100644 tools/trace-malloc/lib/moz.build delete mode 100644 tools/trace-malloc/lib/nsDebugHelpWin32.cpp delete mode 100644 tools/trace-malloc/lib/nsDebugHelpWin32.h delete mode 100644 tools/trace-malloc/lib/nsTraceMalloc.c delete mode 100644 tools/trace-malloc/lib/nsTraceMalloc.h delete mode 100644 tools/trace-malloc/lib/nsTraceMallocCallbacks.h delete mode 100644 tools/trace-malloc/lib/nsTypeInfo.cpp delete mode 100644 tools/trace-malloc/lib/nsTypeInfo.h delete mode 100644 tools/trace-malloc/lib/nsWinTraceMalloc.cpp delete mode 100644 tools/trace-malloc/lib/tm.def delete mode 100644 tools/trace-malloc/live-bloat.html delete mode 100755 tools/trace-malloc/merge.pl delete mode 100644 tools/trace-malloc/moz.build delete mode 100644 tools/trace-malloc/rules.txt delete mode 100644 tools/trace-malloc/spacecategory.c delete mode 100644 tools/trace-malloc/spacetrace.c delete mode 100644 tools/trace-malloc/spacetrace.css delete mode 100644 tools/trace-malloc/spacetrace.h delete mode 100644 tools/trace-malloc/stoptions.h delete mode 100644 tools/trace-malloc/tmfrags.c delete mode 100644 tools/trace-malloc/tmreader.c delete mode 100644 tools/trace-malloc/tmreader.h delete mode 100644 tools/trace-malloc/tmstats.c delete mode 100644 tools/trace-malloc/types.dat delete mode 100755 tools/trace-malloc/uncategorized.pl diff --git a/addon-sdk/source/python-lib/cuddlefish/runner.py b/addon-sdk/source/python-lib/cuddlefish/runner.py index 868b08e4a6c9..6527eca14fe1 100644 --- a/addon-sdk/source/python-lib/cuddlefish/runner.py +++ b/addon-sdk/source/python-lib/cuddlefish/runner.py @@ -492,7 +492,6 @@ def run_app(harness_root_dir, manifest_rdf, harness_options, env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1' env['MOZ_NO_REMOTE'] = '1' env['XPCOM_DEBUG_BREAK'] = 'stack' - env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1' env.update(extra_environment) if norun: cmdargs.append("-no-remote") diff --git a/build/automation.py.in b/build/automation.py.in index f2a2103e2a68..2d46460ce542 100644 --- a/build/automation.py.in +++ b/build/automation.py.in @@ -504,7 +504,6 @@ class Automation(object): env['GNOME_DISABLE_CRASH_DIALOG'] = '1' env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1' - env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1' # Set WebRTC logging in case it is not set yet env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5') diff --git a/build/automationutils.py b/build/automationutils.py index a9ed760bdf4c..ec892b669b5f 100644 --- a/build/automationutils.py +++ b/build/automationutils.py @@ -330,7 +330,6 @@ def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=N # crashreporter env['GNOME_DISABLE_CRASH_DIALOG'] = '1' env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1' - env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1' if crashreporter and not debugger: env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' diff --git a/config/config.mk b/config/config.mk index 141dda16fa5f..e03b31a22ab9 100644 --- a/config/config.mk +++ b/config/config.mk @@ -228,17 +228,17 @@ endif endif # -# Handle trace-malloc and DMD in optimized builds. +# Handle DMD in optimized builds. # No opt to give sane callstacks. # -ifneq (,$(NS_TRACE_MALLOC)$(MOZ_DMD)) +ifdef MOZ_DMD MOZ_OPTIMIZE_FLAGS=-Zi -Od -UDEBUG -DNDEBUG ifdef HAVE_64BIT_BUILD OS_LDFLAGS = -DEBUG -OPT:REF,ICF else OS_LDFLAGS = -DEBUG -OPT:REF endif -endif # NS_TRACE_MALLOC || MOZ_DMD +endif # MOZ_DMD endif # MOZ_DEBUG @@ -421,20 +421,20 @@ ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_) #//------------------------------------------------------------------------ ifdef USE_STATIC_LIBS RTL_FLAGS=-MT # Statically linked multithreaded RTL -ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC)) +ifdef MOZ_DEBUG ifndef MOZ_NO_DEBUG_RTL RTL_FLAGS=-MTd # Statically linked multithreaded MSVC4.0 debug RTL endif -endif # MOZ_DEBUG || NS_TRACE_MALLOC +endif # MOZ_DEBUG else # !USE_STATIC_LIBS RTL_FLAGS=-MD # Dynamically linked, multithreaded RTL -ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC)) +ifdef MOZ_DEBUG ifndef MOZ_NO_DEBUG_RTL RTL_FLAGS=-MDd # Dynamically linked, multithreaded MSVC4.0 debug RTL endif -endif # MOZ_DEBUG || NS_TRACE_MALLOC +endif # MOZ_DEBUG endif # USE_STATIC_LIBS endif # WINNT && !GNU_CC diff --git a/configure.in b/configure.in index 9d1af15d8231..8b9dce5b454c 100644 --- a/configure.in +++ b/configure.in @@ -7046,21 +7046,6 @@ if test -n "$MOZ_DEBUG"; then AC_DEFINE(MOZ_DUMP_PAINTING) fi -dnl ======================================================== -dnl = Enable trace malloc -dnl ======================================================== -NS_TRACE_MALLOC=${MOZ_TRACE_MALLOC} -MOZ_ARG_ENABLE_BOOL(trace-malloc, -[ --enable-trace-malloc Enable malloc tracing; also disables DMD and jemalloc], - NS_TRACE_MALLOC=1, - NS_TRACE_MALLOC= ) -if test "$NS_TRACE_MALLOC"; then - # Please, Mr. Linker Man, don't take away our symbol names - MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS= - AC_DEFINE(NS_TRACE_MALLOC) -fi -AC_SUBST(NS_TRACE_MALLOC) - dnl ======================================================== dnl = Enable DMD dnl ======================================================== @@ -7070,11 +7055,6 @@ MOZ_ARG_ENABLE_BOOL(dmd, MOZ_DMD=1, MOZ_DMD= ) -dnl The two options are conflicting. Fails the configure to alert the user. -if test "$NS_TRACE_MALLOC" -a "$MOZ_DMD"; then - AC_MSG_ERROR([--enable-trace-malloc and --enable-dmd are conflicting options]) -fi - if test "$MOZ_DMD"; then AC_DEFINE(MOZ_DMD) @@ -7096,10 +7076,6 @@ MOZ_ARG_ENABLE_BOOL(jemalloc, MOZ_MEMORY=1, MOZ_MEMORY=) -if test "$NS_TRACE_MALLOC"; then - MOZ_MEMORY= -fi - case "${OS_TARGET}" in Android|WINNT|Darwin) MOZ_GLUE_IN_PROGRAM= @@ -7122,11 +7098,6 @@ MOZ_ARG_ENABLE_BOOL(replace-malloc, MOZ_REPLACE_MALLOC=1, MOZ_REPLACE_MALLOC= ) -dnl The two options are conflicting. Fails the configure to alert the user. -if test "$NS_TRACE_MALLOC" -a "$MOZ_REPLACE_MALLOC"; then - AC_MSG_ERROR([--enable-trace-malloc and --enable-replace-malloc are conflicting options]) -fi - if test -n "$MOZ_REPLACE_MALLOC" -a -z "$MOZ_MEMORY"; then dnl We don't want to enable jemalloc unconditionally because it may be a dnl deliberate choice not to enable it (bug 702250, for instance) @@ -7601,9 +7572,9 @@ if test -z "$SKIP_LIBRARY_CHECKS"; then AC_LANG_RESTORE fi -# Demangle only for debug or trace-malloc or DMD builds +# Demangle only for debug or DMD builds MOZ_DEMANGLE_SYMBOLS= -if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then +if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$MOZ_DMD"; then MOZ_DEMANGLE_SYMBOLS=1 AC_DEFINE(MOZ_DEMANGLE_SYMBOLS) fi @@ -8423,7 +8394,7 @@ if test -n "$MOZ_DEVICES"; then fi dnl ======================================================== -if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then +if test "$MOZ_DEBUG" -o "$MOZ_DMD"; then MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS= fi diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 23a490e577cf..edf7a29ad16e 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1087,177 +1087,6 @@ nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv) return NS_OK; } -#ifdef NS_TRACE_MALLOC - -#include // XXX assume Linux if NS_TRACE_MALLOC -#include -#ifdef XP_UNIX -#include -#endif -#ifdef XP_WIN32 -#include -#endif -#include "nsTraceMalloc.h" - -static bool -CheckUniversalXPConnectForTraceMalloc(JSContext *cx) -{ - if (nsContentUtils::IsCallerChrome()) - return true; - JS_ReportError(cx, "trace-malloc functions require UniversalXPConnect"); - return false; -} - -static bool -TraceMallocDisable(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - NS_TraceMallocDisable(); - args.rval().setUndefined(); - return true; -} - -static bool -TraceMallocEnable(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - NS_TraceMallocEnable(); - args.rval().setUndefined(); - return true; -} - -static bool -TraceMallocOpenLogFile(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - int fd; - if (argc == 0) { - fd = -1; - } else { - JSString *str = JS::ToString(cx, args[0]); - if (!str) - return false; - JSAutoByteString filename(cx, str); - if (!filename) - return false; - fd = open(filename.ptr(), O_CREAT | O_WRONLY | O_TRUNC, 0644); - if (fd < 0) { - JS_ReportError(cx, "can't open %s: %s", filename.ptr(), strerror(errno)); - return false; - } - } - args.rval().setInt32(fd); - return true; -} - -static bool -TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = CallArgsFromVp(argc, vp); - - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - int32_t fd, oldfd; - if (args.length() == 0) { - oldfd = -1; - } else { - if (!JS::ToInt32(cx, args[0], &fd)) - return false; - oldfd = NS_TraceMallocChangeLogFD(fd); - if (oldfd == -2) { - JS_ReportOutOfMemory(cx); - return false; - } - } - args.rval().setInt32(oldfd); - return true; -} - -static bool -TraceMallocCloseLogFD(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = CallArgsFromVp(argc, vp); - - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - int32_t fd; - if (args.length() == 0) { - args.rval().setUndefined(); - return true; - } - if (!JS::ToInt32(cx, args[0], &fd)) - return false; - NS_TraceMallocCloseLogFD((int) fd); - args.rval().setInt32(fd); - return true; -} - -static bool -TraceMallocLogTimestamp(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - JSString *str = JS::ToString(cx, args.get(0)); - if (!str) - return false; - JSAutoByteString caption(cx, str); - if (!caption) - return false; - NS_TraceMallocLogTimestamp(caption.ptr()); - args.rval().setUndefined(); - return true; -} - -static bool -TraceMallocDumpAllocations(JSContext *cx, unsigned argc, JS::Value *vp) -{ - JS::CallArgs args = JS::CallArgsFromVp(argc, vp); - if (!CheckUniversalXPConnectForTraceMalloc(cx)) - return false; - - JSString *str = JS::ToString(cx, args.get(0)); - if (!str) - return false; - JSAutoByteString pathname(cx, str); - if (!pathname) - return false; - if (NS_TraceMallocDumpAllocations(pathname.ptr()) < 0) { - JS_ReportError(cx, "can't dump to %s: %s", pathname.ptr(), strerror(errno)); - return false; - } - args.rval().setUndefined(); - return true; -} - -static const JSFunctionSpec TraceMallocFunctions[] = { - JS_FS("TraceMallocDisable", TraceMallocDisable, 0, 0), - JS_FS("TraceMallocEnable", TraceMallocEnable, 0, 0), - JS_FS("TraceMallocOpenLogFile", TraceMallocOpenLogFile, 1, 0), - JS_FS("TraceMallocChangeLogFD", TraceMallocChangeLogFD, 1, 0), - JS_FS("TraceMallocCloseLogFD", TraceMallocCloseLogFD, 1, 0), - JS_FS("TraceMallocLogTimestamp", TraceMallocLogTimestamp, 1, 0), - JS_FS("TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0), - JS_FS_END -}; - -#endif /* NS_TRACE_MALLOC */ - #ifdef MOZ_JPROF #include @@ -1374,13 +1203,6 @@ nsJSContext::InitClasses(JS::Handle aGlobalObj) // Attempt to initialize profiling functions ::JS_DefineProfilingFunctions(cx, aGlobalObj); -#ifdef NS_TRACE_MALLOC - if (nsContentUtils::IsCallerChrome()) { - // Attempt to initialize TraceMalloc functions - ::JS_DefineFunctions(cx, aGlobalObj, TraceMallocFunctions); - } -#endif - #ifdef MOZ_JPROF // Attempt to initialize JProf functions ::JS_DefineFunctions(cx, aGlobalObj, JProfFunctions); diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index c9aee1a284f9..548d8914c8af 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -702,7 +702,7 @@ gfxPlatform::~gfxPlatform() // cairo_debug_* function unconditionally. // // because cairo can assert and thus crash on shutdown, don't do this in release builds -#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(NS_TRACE_MALLOC) || defined(MOZ_VALGRIND) +#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(MOZ_VALGRIND) #ifdef USE_SKIA // must do Skia cleanup before Cairo cleanup, because Skia may be referencing // Cairo objects e.g. through SkCairoFTTypeface diff --git a/js/src/configure.in b/js/src/configure.in index a0bb06cef79e..709ed9622093 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2988,21 +2988,6 @@ elif test "$GNU_CC"; then fi fi -dnl ======================================================== -dnl = Enable trace malloc -dnl ======================================================== -NS_TRACE_MALLOC=${MOZ_TRACE_MALLOC} -MOZ_ARG_ENABLE_BOOL(trace-malloc, -[ --enable-trace-malloc Enable malloc tracing], - NS_TRACE_MALLOC=1, - NS_TRACE_MALLOC= ) -if test "$NS_TRACE_MALLOC"; then - # Please, Mr. Linker Man, don't take away our symbol names - MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS= - AC_DEFINE(NS_TRACE_MALLOC) -fi -AC_SUBST(NS_TRACE_MALLOC) - dnl ======================================================== dnl = Enable DMD dnl ======================================================== @@ -3012,9 +2997,6 @@ MOZ_ARG_ENABLE_BOOL(dmd, MOZ_DMD=1, MOZ_DMD= ) -if test "$NS_TRACE_MALLOC"; then # trace-malloc disables DMD - MOZ_DMD= -fi if test "$MOZ_DMD"; then AC_DEFINE(MOZ_DMD) @@ -3032,10 +3014,6 @@ MOZ_ARG_ENABLE_BOOL(jemalloc, MOZ_MEMORY=1, MOZ_MEMORY=) -if test "$NS_TRACE_MALLOC"; then - MOZ_MEMORY= -fi - if test "$MOZ_MEMORY"; then AC_DEFINE(MOZ_MEMORY) if test "x$MOZ_DEBUG" = "x1"; then @@ -3429,9 +3407,9 @@ if test -z "$SKIP_LIBRARY_CHECKS"; then AC_LANG_RESTORE fi -# Demangle only for debug or trace-malloc or DMD builds +# Demangle only for debug or DMD builds MOZ_DEMANGLE_SYMBOLS= -if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then +if test "$HAVE_DEMANGLE" && test "$MOZ_DEBUG" -o "$MOZ_DMD"; then MOZ_DEMANGLE_SYMBOLS=1 AC_DEFINE(MOZ_DEMANGLE_SYMBOLS) fi @@ -3671,7 +3649,7 @@ if test "$JS_HAS_CTYPES"; then AC_DEFINE(JS_HAS_CTYPES) fi -if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then +if test "$MOZ_DEBUG" -o "$MOZ_DMD"; then MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS= fi diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py index 21e9422bf895..4cd6a65632b4 100755 --- a/testing/xpcshell/runxpcshelltests.py +++ b/testing/xpcshell/runxpcshelltests.py @@ -836,9 +836,6 @@ class XPCShellTests(object): self.env["MOZ_CRASHREPORTER"] = "1" # Don't launch the crash reporter client self.env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" - # Capturing backtraces is very slow on some platforms, and it's - # disabled by automation.py too - self.env["NS_TRACE_MALLOC_DISABLE_STACKS"] = "1" # Don't permit remote connections by default. # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily # enable non-local connections for the purposes of local testing. diff --git a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul index ff1b881833af..3e1ac901d921 100644 --- a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul @@ -126,7 +126,7 @@ // and subsequent processes. // // Nb: mgr.explicit will throw NS_ERROR_NOT_AVAILABLE if this is a - // --enable-trace-malloc build. Allow for that exception, but *only* that + // --disable-jemalloc build. Allow for that exception, but *only* that // exception. try { is(mgr.explicit, 500*MB + (100 + 13 + 10)*MB + 599*KB, "mgr.explicit"); diff --git a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul index aaadc6f265b5..28096b4b69de 100644 --- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul @@ -139,7 +139,7 @@ // non-deterministic. // // Nb: mgr.explicit will throw NS_ERROR_NOT_AVAILABLE if this is a - // --enable-trace-malloc build. Allow for that exception, but *only* that + // --disable-jemalloc build. Allow for that exception, but *only* that // exception. let dummy; let haveExplicit = true; diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index 2dcea0d5122c..b0bd02d149aa 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -21,9 +21,6 @@ DIRS += [ if CONFIG['MOZ_UPDATER']: DIRS += ['/modules/libmar'] -if CONFIG['NS_TRACE_MALLOC']: - DIRS += ['/tools/trace-malloc/lib'] - DIRS += [ '/config/external/freetype2', '/xpcom', @@ -163,9 +160,6 @@ DIRS += [ '/toolkit/library', ] -if CONFIG['NS_TRACE_MALLOC']: - DIRS += ['/tools/trace-malloc'] - if CONFIG['MOZ_ENABLE_GNOME_COMPONENT']: DIRS += ['/toolkit/system/gnome'] diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index aff17ea511f2..b23b3edb79d4 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -160,10 +160,6 @@ #include "nsIRemoteService.h" #endif -#ifdef NS_TRACE_MALLOC -#include "nsTraceMalloc.h" -#endif - #if defined(DEBUG) && defined(XP_WIN32) #include #endif @@ -224,8 +220,7 @@ static char **gQtOnlyArgv; #endif #if defined(MOZ_WIDGET_GTK) -#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) \ - || defined(NS_TRACE_MALLOC) +#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) #define CLEANUP_MEMORY 1 #define PANGO_ENABLE_BACKEND #include @@ -3327,10 +3322,6 @@ XREMain::XRE_mainInit(bool* aExitFlag) *aExitFlag = true; return 0; } - -#ifdef NS_TRACE_MALLOC - gArgc = NS_TraceMallocStartupArgs(gArgc, gArgv); -#endif rv = XRE_InitCommandLine(gArgc, gArgv); NS_ENSURE_SUCCESS(rv, 1); diff --git a/tools/trace-malloc/Makefile.in b/tools/trace-malloc/Makefile.in deleted file mode 100644 index 1f715db93d5f..000000000000 --- a/tools/trace-malloc/Makefile.in +++ /dev/null @@ -1,39 +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/. - -EXTRACSRCS = tmreader.c -EXTRACPPSRCS = adreader.cpp - -ifndef MOZ_PROFILE_GENERATE - -PROGCSRCS = \ - spacetrace.c \ - spacecategory.c \ - formdata.c \ - $(NULL) - -PROGOBJS = $(PROGCSRCS:.c=.$(OBJ_SUFFIX)) -endif - -CPPSRCS += $(EXTRACPPSRCS) - -include $(topsrcdir)/config/config.mk - -# This is the last use of EXTRA_LIBS, and it would be sad to not have an -# error if it's used in other Makefiles just because of it. So hack around -# the check. -_DEPRECATED_VARIABLES := $(filter-out EXTRA_LIBS,$(_DEPRECATED_VARIABLES)) -EXTRA_LIBS += \ - tmreader.$(OBJ_SUFFIX) \ - adreader.$(OBJ_SUFFIX) \ - $(NULL) - -EXTRA_DEPS = $(EXTRACSRCS:.c=.$(OBJ_SUFFIX)) $(EXTRACPPSRCS:.cpp=.$(OBJ_SUFFIX)) - -include $(topsrcdir)/config/rules.mk - -# install rules.txt along with spacetrace executable -libs:: rules.txt - $(INSTALL) $< $(DIST)/bin diff --git a/tools/trace-malloc/README b/tools/trace-malloc/README deleted file mode 100644 index ff2f00209e17..000000000000 --- a/tools/trace-malloc/README +++ /dev/null @@ -1,177 +0,0 @@ - Trace Malloc Tools - Chris Waterson - November 27, 2000 - -This is a short primer on how to use the `trace malloc' tools -contained in this directory. - - -WHAT IS TRACE MALLOC? -===================== - -Trace malloc is an optional facility that is built in to XPCOM. It -uses `weak linking' to intercept all calls to malloc(), calloc(), -realloc() and free(). It does two things: - -1. Writes information about allocations to a filehandle that you -specify. As each call to malloc(), et. al. is made, a record is logged -to the filehandle. - -2. Maintains a table of all `live objects' -- that is, objects that -have been allocated by malloc(), calloc() or realloc(), but have not -yet been free()'d. The contents of this table can be called by making -a `secret' call to JavaScript. - - -MAKING A TRACE MALLOC BUILD -=========================== - -As of this writing, trace malloc only works on Linux, but work is -underway to port it to Windows. - -On Linux, start with a clean tree, and configure your build with the -following flags: - - --enable-trace-malloc - --enable-cpp-rtti - -Be sure that `--enable-boehm' is *not* set. I don't think that the -values for `--enable-debug' and `--enable-optimize' matter, but I've -typically had debug on and optimize off. - - -COLLECTING LIVE OBJECT DATA -=========================== - -To collect `live object' data from `mozilla' using a build that has -trace malloc enabled, - - 1. Run `mozilla' as follows: - - % mozilla --trace-malloc /dev/null - - 2. Do whatever operations in mozilla you'd like to test. - - 3. Open the `live-bloat.html' file contained in this directory. - - 4. Press the button that says `Dump to /tmp/dump.log' - -An enormous file (typically 300MB) called `dump.log' will be dropped -in your `/tmp' directory. - -To collect live object data from `gtkEmbed' using a build that has -trace malloc enabled: - - 1. Run `gtkEmbed' as follows: - - % gtkEmbed --trace-malloc /dev/null - - 2. Do whatever operations in gtkEmbed that you'd like to test. - - 3. Press the `Dump Memory' button at the bottom of gtkEmbed. - -The enormous file will be dropped in the current directory, and is -called `allocations.log'. - - -About Live Object Logs ----------------------- - -A typical entry from the `live object' dump file will look like: - - Address Type Size - | | | - v v v - 0x40008080 16 - 0x00000001 <- Fields - 0x40008084 - 0x80004001 - 0x00000036 - __builtin_new[./libxpcom.so +0x10E9DC] <- Stack at allocation time - nsFooBar::CreateFooBar(nsFooBar **)[./libfoobar.so +0x408C] - main+C7E5AFB5[(null) +0xC7E5AFB5] - -One will be printed for each object that was allocated. - - -TOOLS TO PARSE LIVE OBJECT LOGS -=============================== - -This directory is meant to house the tools that you can use to parse -live-object logs. - -Object Histograms - histogram.pl --------------------------------- - -This program parses a `live object' dump and produces a histogram of -the objects, sorted from objects that take the most memory to objects -that take the least. The output of this program is rather spartan: on -each line, it prints the object type, the number of objects of that -type, and the total number of bytes that the objects consume. - -There are a two simple programs to `pretty print' the output from -histogram.pl: - - 1. histogram-pretty.sh takes a single histogram and produces a table - of objects. - - Type Count Bytes %Total - TOTAL 67348 4458127 100.00 - nsImageGTK 76 679092 15.23 - void* 8956 563572 12.64 - ... - PRLock 732 61488 1.38 - OTHER 24419 940235 21.09 - - 2. histogram-diff.sh takes two histograms and computes the difference - between them. - - ---- Base ---- ---- Incr ---- ----- Difference ---- - Type Count Bytes Count Bytes Count Bytes %Total - TOTAL 40241 1940945 73545 5315142 33304 3374197 100.00 - nsImageGTK 16 106824 151 832816 135 725992 21.52 - PresShell 16 51088 198 340706 182 289618 8.58 - ... - OTHER 27334 1147033 38623 1493385 11289 346352 10.26 - -Both of these scripts accept `-c' parameter that specifies how many -rows you'd like to see (by default, twenty). Any rows past the first -`n' rows are lumped into a single `OTHER' row. This allows you to keep -your reports short n' sweet. - -Stack-based Type Inference - types.dat --------------------------------------- - -Trace malloc uses `speculative RTTI' to determine the types of objects -as it dumps them. Unfortunately, RTTI can only deduce the type name -for C++ objects with a virtual destructor. - -This leaves: - - . C++ object without a virtual destructor - . array allocated C++ objects, and - . objects allocated with the C runtime function (malloc - and friends) - -out in the cold. Trace malloc reports objects allocated this was as -having type `void*'. - -The good news is that you can almost always determine the object's -type by looking at the stack trace that's taken at the time the object -is allocated. - -The file `types.dat' consists of rules to classify objects based on -stack trace. - - -Uncategorized Objects - uncategorized.pl ----------------------------------------- - -Categorizing objects in `types.dat' is sweaty work, and the -`uncategorized.pl' script is a tool that makes it a bit -easier. Specifically, it reads a `live object' dump file and sorts the -stack traces. Stack traces that account for the most uncategorized -objects are placed first. - -Using this tool, you can add the `most effective' rules to -`types.dat': rules that account for most of the uncategorized data. diff --git a/tools/trace-malloc/TraceMalloc.pm b/tools/trace-malloc/TraceMalloc.pm deleted file mode 100644 index 096ce71becf5..000000000000 --- a/tools/trace-malloc/TraceMalloc.pm +++ /dev/null @@ -1,156 +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/. -package TraceMalloc; - -use strict; - -# Read in the type inference file and construct a network that we can -# use to match stack prefixes to types. -sub init_type_inference($) { - my ($file) = @_; - - $::Fingerprints = { }; - - open(TYPES, "<$file") || die "unable to open $::opt_types, $!"; - - TYPE: while () { - next TYPE unless /<(.*)>/; - my $type = $1; - - my $link = \%::Fingerprints; - - FRAME: while () { - chomp; - last FRAME if /^$/; - - my $next = $link->{$_}; - if (! $next) { - $next = $link->{$_} = {}; - } - $link = $next; - } - - $link->{'#type#'} = $type; - - last TYPE if eof; - } -} - -# Infer the type, trying to find the most specific type possible. -sub infer_type($) { - my ($stack) = @_; - - my $link = \%::Fingerprints; - my $last; - my $type = 'void*'; - FRAME: foreach my $frame (@$stack) { - last FRAME unless $link; - - $frame =~ s/\[.*\]$//; # ignore exact addresses, as they'll drift - - $last = $link; - - # - # Remember this type, but keep going. We use the longest match - # we find, but substacks of longer matches will also match. - # - if ($last->{'#type#'}) { - $type = $last->{'#type#'}; - } - - $link = $link->{$frame}; - - if (! $link) { - CHILD: foreach my $child (keys %$last) { - next CHILD unless $child =~ /^~/; - - $child =~ s/^~//; - - if ($frame =~ $child) { - $link = $last->{'~' . $child}; - last CHILD; - } - } - } - } - - return $type; -} - - -#---------------------------------------------------------------------- -# -# Read in the output a trace malloc's dump. -# -sub read { - my ($callback, $noslop) = @_; - - OBJECT: while (<>) { - # e.g., 0x0832FBD0 (80) - next OBJECT unless /^0x(\S+) <(.*)> \((\d+)\)/; - my ($addr, $type, $size) = (hex $1, $2, $3); - - my $object = { 'type' => $type, 'size' => $size }; - - # Record the object's slots - my @slots; - - SLOT: while (<>) { - # e.g., 0x00000000 - last SLOT unless /^\t0x(\S+)/; - my $value = hex $1; - - # Ignore low bits, unless they've specified --noslop - $value &= ~0x7 unless $noslop; - - $slots[$#slots + 1] = $value; - } - - $object->{'slots'} = \@slots; - - # Record the stack by which the object was allocated - my @stack; - - while (/^(.*)\[(.*) \+0x(\S+)\]$/) { - # e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858] - my ($func, $lib, $off) = ($1, $2, hex $3); - - chomp; - $stack[$#stack + 1] = $_; - - $_ = <>; - } - - $object->{'stack'} = \@stack; - - $object->{'type'} = infer_type(\@stack) - if $object->{'type'} eq 'void*'; - - &$callback($object) if $callback; - - # Gotta check EOF explicitly... - last OBJECT if eof; - } -} - -1; -__END__ - -=head1 NAME - -TraceMalloc - Perl routines to deal with output from ``trace malloc'' -and the Boehm GC - -=head1 SYNOPSIS - - use TraceMalloc; - - TraceMalloc::init_type_inference("types.dat"); - TraceMalloc::read(0); - -=head1 DESCRIPTION - -=head1 EXAMPLES - -=cut diff --git a/tools/trace-malloc/adreader.cpp b/tools/trace-malloc/adreader.cpp deleted file mode 100644 index 27cc7f495e00..000000000000 --- a/tools/trace-malloc/adreader.cpp +++ /dev/null @@ -1,132 +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 "adreader.h" - -#include -#include -#include - -ADLog::ADLog() - : mEntryCount(0) -{ - mEntries.mNext = static_cast(&mEntries); - mEntries.mPrev = static_cast(&mEntries); -} - -ADLog::~ADLog() -{ - for (const_iterator entry = begin(), entry_end = end(); - entry != entry_end; ++entry) { - free((void*) (*entry)->type); - free((char*) (*entry)->data); - free((char*) (*entry)->allocation_stack); - } - - for (EntryBlock *b = mEntries.mNext, *next; b != &mEntries; b = next) { - next = b->mNext; - delete b; - } -} - -bool -ADLog::Read(const char* aFileName) -{ - FILE *in = fopen(aFileName, "r"); - if (!in) { - return false; - } - - while (!feof(in)) { - unsigned int ptr; - char typebuf[256]; - int datasize; - int res = fscanf(in, "%x %s (%d)\n", &ptr, typebuf, &datasize); - if (res == EOF) - break; - if (res != 3) { - return false; - } - - size_t data_mem_size = ((datasize + sizeof(unsigned long) - 1) / - sizeof(unsigned long)) * sizeof(unsigned long); - char *data = (char*)malloc(data_mem_size); - - for (size_t *cur_data = (size_t*) data, - *cur_data_end = (size_t*) ((char*)data + data_mem_size); - cur_data != cur_data_end; ++cur_data) { - res = fscanf(in, " %zX\n", cur_data); - if (res != 1) { - return false; - } - } - - char stackbuf[100000]; - stackbuf[0] = '\0'; - - char *stack = stackbuf; - int len; - do { - fgets(stack, sizeof(stackbuf) - (stack - stackbuf), in); - len = strlen(stack); - stack += len; - } while (len > 1); - - if (mEntryCount % ADLOG_ENTRY_BLOCK_SIZE == 0) { - EntryBlock *new_block = new EntryBlock(); - new_block->mNext = static_cast(&mEntries); - new_block->mPrev = mEntries.mPrev; - mEntries.mPrev->mNext = new_block; - mEntries.mPrev = new_block; - } - - size_t typelen = strlen(typebuf); - char *type = (char*)malloc(typelen-1); - strncpy(type, typebuf+1, typelen-2); - type[typelen-2] = '\0'; - - Entry *entry = - &mEntries.mPrev->entries[mEntryCount % ADLOG_ENTRY_BLOCK_SIZE]; - entry->address = (Pointer) (uintptr_t) ptr; - entry->type = type; - entry->datasize = datasize; - entry->data = data; - entry->allocation_stack = strdup(stackbuf); - - ++mEntryCount; - } - - return true; -} - -ADLog::const_iterator::const_iterator(ADLog::EntryBlock *aBlock, - size_t aOffset) -{ - SetBlock(aBlock); - mCur = mBlockStart + aOffset; -} - -ADLog::const_iterator& -ADLog::const_iterator::operator++() -{ - ++mCur; - if (mCur == mBlockEnd) { - SetBlock(mBlock->mNext); - mCur = mBlockStart; - } - - return *this; -} - -ADLog::const_iterator& -ADLog::const_iterator::operator--() -{ - if (mCur == mBlockStart) { - SetBlock(mBlock->mPrev); - mCur = mBlockEnd; - } - --mCur; - - return *this; -} diff --git a/tools/trace-malloc/adreader.h b/tools/trace-malloc/adreader.h deleted file mode 100644 index a7f9b64de060..000000000000 --- a/tools/trace-malloc/adreader.h +++ /dev/null @@ -1,97 +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 - -#define ADLOG_ENTRY_BLOCK_SIZE 4096 - -class ADLog { - -public: - - // Use typedef in case somebody wants to process 64-bit output on a - // 32-bit machine someday. - typedef const char* Pointer; - - struct Entry { - Pointer address; - const char *type; - - const char *data; // The contents of the memory. - size_t datasize; - - const char *allocation_stack; - }; - - ADLog(); - ~ADLog(); - - /* - * Returns false on failure and true on success. - */ - bool Read(const char *aFilename); - -private: - // Link structure for a circularly linked list. - struct EntryBlock; - struct EntryBlockLink { - EntryBlock *mPrev; - EntryBlock *mNext; - }; - - struct EntryBlock : public EntryBlockLink { - Entry entries[ADLOG_ENTRY_BLOCK_SIZE]; - }; - - size_t mEntryCount; - EntryBlockLink mEntries; - -public: - - class const_iterator { - private: - // Only |ADLog| member functions can construct iterators. - friend class ADLog; - const_iterator(EntryBlock *aBlock, size_t aOffset); - - public: - const Entry* operator*() { return mCur; } - const Entry* operator->() { return mCur; } - - const_iterator& operator++(); - const_iterator& operator--(); - - bool operator==(const const_iterator& aOther) const { - return mCur == aOther.mCur; - } - - bool operator!=(const const_iterator& aOther) const { - return mCur != aOther.mCur; - } - - private: - void SetBlock(EntryBlock *aBlock) { - mBlock = aBlock; - mBlockStart = aBlock->entries; - mBlockEnd = aBlock->entries + ADLOG_ENTRY_BLOCK_SIZE; - } - - EntryBlock *mBlock; - Entry *mCur, *mBlockStart, *mBlockEnd; - - // Not to be implemented. - const_iterator operator++(int); - const_iterator operator--(int); - }; - - const_iterator begin() { - return const_iterator(mEntries.mNext, 0); - } - const_iterator end() { - return const_iterator(mEntries.mPrev, - mEntryCount % ADLOG_ENTRY_BLOCK_SIZE); - } - - size_t count() { return mEntryCount; } -}; diff --git a/tools/trace-malloc/allocation-stacks.c b/tools/trace-malloc/allocation-stacks.c deleted file mode 100644 index 7bbbf431424f..000000000000 --- a/tools/trace-malloc/allocation-stacks.c +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#else -extern int getopt(int argc, char *const *argv, const char *shortopts); -extern char *optarg; -extern int optind; -#ifdef XP_WIN32 -int optind=1; -#endif -#endif -#include -#include "nsTraceMalloc.h" -#include "tmreader.h" - -static char *program; - -static void my_tmevent_handler(tmreader *tmr, tmevent *event) -{ - tmcallsite *callsite; - - switch (event->type) { - case TM_EVENT_REALLOC: - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - for (callsite = tmreader_callsite(tmr, event->serial); - callsite != &tmr->calltree_root; callsite = callsite->parent) { - fprintf(stdout, "%s +%08X (%s:%d)\n", - (const char*)callsite->method->graphnode.entry.value, - callsite->offset, - callsite->method->sourcefile, - callsite->method->linenumber); - } - fprintf(stdout, "\n"); - } -} - -int main(int argc, char **argv) -{ - int i, j, rv; - tmreader *tmr; - FILE *fp; - time_t start; - - program = *argv; - - tmr = tmreader_new(program, NULL); - if (!tmr) { - perror(program); - exit(1); - } - - start = time(NULL); - fprintf(stdout, "%s starting at %s", program, ctime(&start)); - fflush(stdout); - - argc -= optind; - argv += optind; - if (argc == 0) { - if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0) - exit(1); - } else { - for (i = j = 0; i < argc; i++) { - fp = fopen(argv[i], "r"); - if (!fp) { - fprintf(stderr, "%s: can't open %s: %s\n", - program, argv[i], strerror(errno)); - exit(1); - } - rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler); - if (rv < 0) - exit(1); - if (rv > 0) - j++; - fclose(fp); - } - if (j == 0) - exit(1); - } - - tmreader_destroy(tmr); - - exit(0); -} diff --git a/tools/trace-malloc/blame.css b/tools/trace-malloc/blame.css deleted file mode 100644 index 58339fb9b4ae..000000000000 --- a/tools/trace-malloc/blame.css +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C; tab-width: 8; 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/. */ - -td { - font: x-small sans-serif; - vertical-align: top; -} - -thead td { - font-weight: bold; -} diff --git a/tools/trace-malloc/blame.pl b/tools/trace-malloc/blame.pl deleted file mode 100755 index 36afcad4ebd1..000000000000 --- a/tools/trace-malloc/blame.pl +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/perl -w -# -# 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/. - -# -# Process output of TraceMallocDumpAllocations() to produce a table -# that attributes memory to the allocators using call stack. -# - -use 5.004; -use strict; - -# A table of all ancestors. Key is function name, value is an -# array of ancestors, each attributed with a number of calls and -# the amount of memory allocated. -my %Ancestors; - -# Ibid, for descendants. -my %Descendants; - -# A table that keeps the total amount of memory allocated by each -# function -my %Totals; -$Totals{".root"} = { "#memory#" => 0, "#calls#" => 0 }; - -# A table that maps the long ugly function name to a unique number so -# that the HTML we generate isn't too fat -my %Ids; -my $NextId = 0; - -$Ids{".root"} = ++$NextId; - - -LINE: while (<>) { - # The line'll look like: - # - # 0x4000a008 16 PR_Malloc+16; nsMemoryImpl::Alloc(unsigned int)+12; ... - - # Ignore any lines that don't start with an address - next LINE unless /^0x/; - - # Parse it - my ($address, $size, $rest) = /^(0x\S*)\s*(\d+)\s*(.*)$/; - my @stack = reverse(split /; /, $rest); - - # Accumulate at the root - $Totals{".root"}->{"#memory#"} += $size; - ++$Totals{".root"}->{"#calls#"}; - - my $caller = ".root"; - foreach my $callee (@stack) { - # Strip the offset from the callsite information. I don't - # think we care. - $callee =~ s/\+\d+$//g; - - # Accumulate the total for the callee - if (! $Totals{$callee}) { - $Totals{$callee} = { "#memory#" => 0, "#calls#" => 0 }; - } - - $Totals{$callee}->{"#memory#"} += $size; - ++$Totals{$callee}->{"#calls#"}; - - # Descendants - my $descendants = $Descendants{$caller}; - if (! $descendants) { - $descendants = $Descendants{$caller} = [ ]; - } - - # Manage the list of descendants - { - my $wasInserted = 0; - DESCENDANT: foreach my $item (@$descendants) { - if ($item->{"#name#"} eq $callee) { - $item->{"#memory#"} += $size; - ++$item->{"#calls#"}; - $wasInserted = 1; - last DESCENDANT; - } - } - - if (! $wasInserted) { - $descendants->[@$descendants] = { - "#name#" => $callee, - "#memory#" => $size, - "#calls#" => 1 - }; - } - } - - # Ancestors - my $ancestors = $Ancestors{$callee}; - if (! $ancestors) { - $ancestors = $Ancestors{$callee} = [ ]; - } - - # Manage the list of ancestors - { - my $wasInserted = 0; - ANCESTOR: foreach my $item (@$ancestors) { - if ($item->{"#name#"} eq $caller) { - $item->{"#memory#"} += $size; - ++$item->{"#calls#"}; - $wasInserted = 1; - last ANCESTOR; - } - } - - if (! $wasInserted) { - $ancestors->[@$ancestors] = { - "#name#" => $caller, - "#memory#" => $size, - "#calls#" => 1 - }; - } - } - - # Make a new "id", if necessary - if (! $Ids{$callee}) { - $Ids{$callee} = ++$NextId; - } - - # On to the next one... - $caller = $callee; - } -} - - -# Change the manky looking callsite into a pretty function; strip argument -# types and offset information. -sub pretty($) { - $_ = $_[0]; - s/&/&/g; - s//>/g; - - if (/([^\(]*)(\(.*\))/) { - return $1 . "()"; - } - else { - return $_[0]; - } -} - -# Dump a web page! -print "\n"; -print "\n"; -print "Live Bloat Blame\n"; -print "\n"; -print "\n"; -print "\n"; - -# At most 100 rows per table so as not to kill the browser. -my $maxrows = 100; - -print "\n"; -print "\n"; - -foreach my $node (sort(keys(%Ids))) { - print "\n"; - - # Print the current node - { - my ($memory, $calls) = - ($Totals{$node}->{"#memory#"}, - $Totals{$node}->{"#calls#"}); - - my $pretty = pretty($node); - print " \n"; - } - - # Ancestors, sorted descending by amount of memory allocated - print " \n"; - - # Descendants, sorted descending by amount of memory allocated - print " \n"; - - if (--$maxrows == 0) { - print "
FunctionAncestorsDescendants
$pretty $memory ($calls)\n"; - my $ancestors = $Ancestors{$node}; - if ($ancestors) { - foreach my $ancestor (sort { $b->{"#memory#"} <=> $a->{"#memory#"} } @$ancestors) { - my ($name, $memory, $calls) = - ($ancestor->{"#name#"}, - $ancestor->{"#memory#"}, - $ancestor->{"#calls#"}); - - my $pretty = pretty($name); - - print " $pretty $memory ($calls)
\n"; - } - } - - print "
\n"; - my $descendants = $Descendants{$node}; - if ($descendants) { - foreach my $descendant (sort { $b->{"#memory#"} <=> $a->{"#memory#"} } @$descendants) { - my ($name, $memory, $calls) = - ($descendant->{"#name#"}, - $descendant->{"#memory#"}, - $descendant->{"#calls#"}); - - my $pretty = pretty($name); - - print " $pretty $memory ($calls)
\n"; - } - } - print "
\n"; - print "\n"; - print "\n"; - $maxrows = 100; - } -} - -# Footer -print "
FunctionAncestorsDescendants
\n"; -print "\n"; diff --git a/tools/trace-malloc/bloatblame.cpp b/tools/trace-malloc/bloatblame.cpp deleted file mode 100644 index 3772119dabfe..000000000000 --- a/tools/trace-malloc/bloatblame.cpp +++ /dev/null @@ -1,722 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#else -#ifdef XP_WIN -#include "getopt.c" -#else -extern int getopt(int argc, char *const *argv, const char *shortopts); -extern char *optarg; -extern int optind; -#endif -#endif -#include -#include -#include -#include "prlog.h" -#include "prprf.h" -#include "plhash.h" -#include "pldhash.h" -#include "nsTraceMalloc.h" -#include "tmreader.h" - -static char *program; -static int sort_by_direct = 0; -static int js_mode = 0; -static int do_tree_dump = 0; -static int unified_output = 0; -static char *function_dump = NULL; -static uint32_t min_subtotal = 0; - -static void compute_callsite_totals(tmcallsite *site) -{ - tmcallsite *kid; - - site->allocs.bytes.total += site->allocs.bytes.direct; - site->allocs.calls.total += site->allocs.calls.direct; - for (kid = site->kids; kid; kid = kid->siblings) { - compute_callsite_totals(kid); - site->allocs.bytes.total += kid->allocs.bytes.total; - site->allocs.calls.total += kid->allocs.calls.total; - } -} - -static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp) -{ - tmcallsite *parent; - tmgraphnode *comp, *pcomp, *lib, *plib; - tmmethodnode *meth, *pmeth; - int old_meth_low, old_comp_low, old_lib_low, nkids; - tmcallsite *kid; - - parent = site->parent; - comp = lib = NULL; - meth = NULL; - if (parent) { - meth = site->method; - if (meth) { - pmeth = parent->method; - if (pmeth && pmeth != meth) { - if (!meth->graphnode.low) { - meth->graphnode.allocs.bytes.total += site->allocs.bytes.total; - meth->graphnode.allocs.calls.total += site->allocs.calls.total; - } - if (!tmgraphnode_connect(&(pmeth->graphnode), &(meth->graphnode), site)) - goto bad; - - comp = meth->graphnode.up; - if (comp) { - pcomp = pmeth->graphnode.up; - if (pcomp && pcomp != comp) { - if (!comp->low) { - comp->allocs.bytes.total - += site->allocs.bytes.total; - comp->allocs.calls.total - += site->allocs.calls.total; - } - if (!tmgraphnode_connect(pcomp, comp, site)) - goto bad; - - lib = comp->up; - if (lib) { - plib = pcomp->up; - if (plib && plib != lib) { - if (!lib->low) { - lib->allocs.bytes.total - += site->allocs.bytes.total; - lib->allocs.calls.total - += site->allocs.calls.total; - } - if (!tmgraphnode_connect(plib, lib, site)) - goto bad; - } - old_lib_low = lib->low; - if (!old_lib_low) - lib->low = level; - } - } - old_comp_low = comp->low; - if (!old_comp_low) - comp->low = level; - } - } - old_meth_low = meth->graphnode.low; - if (!old_meth_low) - meth->graphnode.low = level; - } - } - - if (do_tree_dump) { - fprintf(fp, "%c%*s%3d %3d %s %lu %ld\n", - site->kids ? '+' : '-', level, "", level, kidnum, - meth ? tmmethodnode_name(meth) : "???", - (unsigned long)site->allocs.bytes.direct, - (long)site->allocs.bytes.total); - } - nkids = 0; - level++; - for (kid = site->kids; kid; kid = kid->siblings) { - walk_callsite_tree(kid, level, nkids, fp); - nkids++; - } - - if (meth) { - if (!old_meth_low) - meth->graphnode.low = 0; - if (comp) { - if (!old_comp_low) - comp->low = 0; - if (lib) { - if (!old_lib_low) - lib->low = 0; - } - } - } - return; - -bad: - perror(program); - exit(1); -} - -/* - * Linked list bubble-sort (waterson and brendan went bald hacking this). - * - * Sort the list in non-increasing order, using the expression passed as the - * 'lessthan' formal macro parameter. This expression should use 'curr' as - * the pointer to the current node (of type nodetype) and 'next' as the next - * node pointer. It should return true if curr is less than next, and false - * otherwise. - */ -#define BUBBLE_SORT_LINKED_LIST(listp, nodetype, lessthan) \ - PR_BEGIN_MACRO \ - nodetype *curr, **currp, *next, **nextp, *tmp; \ - \ - currp = listp; \ - while ((curr = *currp) != NULL && curr->next) { \ - nextp = &curr->next; \ - while ((next = *nextp) != NULL) { \ - if (lessthan) { \ - tmp = curr->next; \ - *currp = tmp; \ - if (tmp == next) { \ - PR_ASSERT(nextp == &curr->next); \ - curr->next = next->next; \ - next->next = curr; \ - } else { \ - *nextp = next->next; \ - curr->next = next->next; \ - next->next = tmp; \ - *currp = next; \ - *nextp = curr; \ - nextp = &curr->next; \ - } \ - curr = next; \ - continue; \ - } \ - nextp = &next->next; \ - } \ - currp = &curr->next; \ - } \ - PR_END_MACRO - -static int tabulate_node(PLHashEntry *he, int i, void *arg) -{ - tmgraphnode *node = (tmgraphnode*) he; - tmgraphnode **table = (tmgraphnode**) arg; - - table[i] = node; - BUBBLE_SORT_LINKED_LIST(&node->down, tmgraphnode, - (curr->allocs.bytes.total < next->allocs.bytes.total)); - return HT_ENUMERATE_NEXT; -} - -/* Sort in reverse size order, so biggest node comes first. */ -static int node_table_compare(const void *p1, const void *p2) -{ - const tmgraphnode *node1, *node2; - uint32_t key1, key2; - - node1 = *(const tmgraphnode**) p1; - node2 = *(const tmgraphnode**) p2; - if (sort_by_direct) { - key1 = node1->allocs.bytes.direct; - key2 = node2->allocs.bytes.direct; - } else { - key1 = node1->allocs.bytes.total; - key2 = node2->allocs.bytes.total; - } - return (key2 < key1) ? -1 : (key2 > key1) ? 1 : 0; -} - -static int mean_size_compare(const void *p1, const void *p2) -{ - const tmgraphnode *node1, *node2; - double div1, div2, key1, key2; - - node1 = *(const tmgraphnode**) p1; - node2 = *(const tmgraphnode**) p2; - div1 = (double)node1->allocs.calls.direct; - div2 = (double)node2->allocs.calls.direct; - if (div1 == 0 || div2 == 0) - return (int)(div2 - div1); - key1 = (double)node1->allocs.bytes.direct / div1; - key2 = (double)node2->allocs.bytes.direct / div2; - if (key1 < key2) - return 1; - if (key1 > key2) - return -1; - return 0; -} - -static const char *prettybig(uint32_t num, char *buf, size_t limit) -{ - if (num >= 1000000000) - PR_snprintf(buf, limit, "%1.2fG", (double) num / 1e9); - else if (num >= 1000000) - PR_snprintf(buf, limit, "%1.2fM", (double) num / 1e6); - else if (num >= 1000) - PR_snprintf(buf, limit, "%1.2fK", (double) num / 1e3); - else - PR_snprintf(buf, limit, "%lu", (unsigned long) num); - return buf; -} - -static double percent(uint32_t num, uint32_t total) -{ - if (num == 0) - return 0.0; - return ((double) num * 100) / (double) total; -} - -static void sort_graphlink_list(tmgraphlink **listp, int which) -{ - BUBBLE_SORT_LINKED_LIST(listp, tmgraphlink, - (TM_LINK_TO_EDGE(curr, which)->allocs.bytes.total - < TM_LINK_TO_EDGE(next, which)->allocs.bytes.total)); -} - -static void dump_graphlink_list(tmgraphlink *list, int which, const char *name, - FILE *fp) -{ - tmcounts bytes; - tmgraphlink *link; - tmgraphedge *edge; - char buf[16]; - - bytes.direct = bytes.total = 0; - for (link = list; link; link = link->next) { - edge = TM_LINK_TO_EDGE(link, which); - bytes.direct += edge->allocs.bytes.direct; - bytes.total += edge->allocs.bytes.total; - } - - if (js_mode) { - fprintf(fp, - " %s:{dbytes:%ld, tbytes:%ld, edges:[\n", - name, (long) bytes.direct, (long) bytes.total); - for (link = list; link; link = link->next) { - edge = TM_LINK_TO_EDGE(link, which); - fprintf(fp, - " {node:%d, dbytes:%ld, tbytes:%ld},\n", - link->node->sort, - (long) edge->allocs.bytes.direct, - (long) edge->allocs.bytes.total); - } - fputs(" ]},\n", fp); - } else { - fputs("", fp); - for (link = list; link; link = link->next) { - edge = TM_LINK_TO_EDGE(link, which); - fprintf(fp, - "%s (%1.2f%%)\n", - tmgraphnode_name(link->node), - prettybig(edge->allocs.bytes.total, buf, sizeof buf), - percent(edge->allocs.bytes.total, bytes.total)); - } - fputs("", fp); - } -} - -static void dump_graph(tmreader *tmr, PLHashTable *hashtbl, const char *varname, - const char *title, FILE *fp) -{ - uint32_t i, count; - tmgraphnode **table, *node; - char *name; - size_t namelen; - char buf1[16], buf2[16], buf3[16], buf4[16]; - - count = hashtbl->nentries; - table = (tmgraphnode**) malloc(count * sizeof(tmgraphnode*)); - if (!table) { - perror(program); - exit(1); - } - PL_HashTableEnumerateEntries(hashtbl, tabulate_node, table); - qsort(table, count, sizeof(tmgraphnode*), node_table_compare); - for (i = 0; i < count; i++) - table[i]->sort = i; - - if (js_mode) { - fprintf(fp, - "var %s = {\n name:'%s', title:'%s', nodes:[\n", - varname, varname, title); - } else { - fprintf(fp, - "\n" - "" - "" - "" - "" - "" - "" - "" - "" - "\n", - title); - } - - for (i = 0; i < count; i++) { - /* Don't bother with truly puny nodes. */ - node = table[i]; - if (node->allocs.bytes.total < min_subtotal) - break; - - name = tmgraphnode_name(node); - if (js_mode) { - fprintf(fp, - " {name:'%s', dbytes:%ld, tbytes:%ld," - " dallocs:%ld, tallocs:%ld,\n", - name, - (long) node->allocs.bytes.direct, - (long) node->allocs.bytes.total, - (long) node->allocs.calls.direct, - (long) node->allocs.calls.total); - } else { - namelen = strlen(name); - fprintf(fp, - "" - "", - name, - (namelen > 40) ? 40 : (int)namelen, name, - (namelen > 40) ? "..." : ""); - if (node->down) { - fprintf(fp, - "", - tmgraphnode_name(node->down)); - } else { - fputs("", fp); - } - if (node->next) { - fprintf(fp, - "", - tmgraphnode_name(node->next)); - } else { - fputs("", fp); - } - fprintf(fp, - "" - "", - prettybig(node->allocs.bytes.total, buf1, sizeof buf1), - prettybig(node->allocs.bytes.direct, buf2, sizeof buf2), - percent(node->allocs.bytes.total, - tmr->calltree_root.allocs.bytes.total), - percent(node->allocs.bytes.direct, - tmr->calltree_root.allocs.bytes.total), - prettybig(node->allocs.calls.total, buf3, sizeof buf3), - prettybig(node->allocs.calls.direct, buf4, sizeof buf4), - percent(node->allocs.calls.total, - tmr->calltree_root.allocs.calls.total), - percent(node->allocs.calls.direct, - tmr->calltree_root.allocs.calls.total)); - } - - /* NB: we must use 'fin' because 'in' is a JS keyword! */ - sort_graphlink_list(&node->in, TM_EDGE_IN_LINK); - dump_graphlink_list(node->in, TM_EDGE_IN_LINK, "fin", fp); - sort_graphlink_list(&node->out, TM_EDGE_OUT_LINK); - dump_graphlink_list(node->out, TM_EDGE_OUT_LINK, "out", fp); - - if (js_mode) - fputs(" },\n", fp); - else - fputs("\n", fp); - } - - if (js_mode) { - fputs("]};\n", fp); - } else { - fputs("
%sDownNextTotal/Direct (percents)AllocationsFan-inFan-out
%.*s%sdownnext%s/%s (%1.2f%%/%1.2f%%)%s/%s (%1.2f%%/%1.2f%%)
\n
\n", fp); - - qsort(table, count, sizeof(tmgraphnode*), mean_size_compare); - - fprintf(fp, - "\n" - "\n" - "" - "" - "" - "" - "\n", - title); - - for (i = 0; i < count; i++) { - double allocs, bytes, mean, variance, sigma; - - node = table[i]; - allocs = (double)node->allocs.calls.direct; - if (!allocs) - continue; - - /* Compute direct-size mean and standard deviation. */ - bytes = (double)node->allocs.bytes.direct; - mean = bytes / allocs; - variance = allocs * node->sqsum - bytes * bytes; - if (variance < 0 || allocs == 1) - variance = 0; - else - variance /= allocs * (allocs - 1); - sigma = sqrt(variance); - - name = tmgraphnode_name(node); - namelen = strlen(name); - fprintf(fp, - "" - "" - "" - "" - "" - "\n", - (namelen > 65) ? 45 : (int)namelen, name, - (namelen > 65) ? "..." : "", - prettybig((uint32_t)mean, buf1, sizeof buf1), - prettybig((uint32_t)sigma, buf2, sizeof buf2), - prettybig(node->allocs.calls.direct, buf3, sizeof buf3)); - } - fputs("
Direct Allocators
%sMean SizeStdDevAllocations" - "
%.*s%s%s%s%s
\n", fp); - } - - free((void*) table); -} - -static void my_tmevent_handler(tmreader *tmr, tmevent *event) -{ - switch (event->type) { - case TM_EVENT_STATS: - if (js_mode) - break; - fprintf(stdout, - "

" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "
CounterValue
maximum actual stack depth%lu
maximum callsite tree depth%lu
number of parent callsites%lu
maximum kids per parent%lu
hits looking for a kid%lu
misses looking for a kid%lu
steps over other kids%lu
callsite recurrences%lu
number of stack backtraces%lu
backtrace failures%lu
backtrace malloc failures%lu
backtrace dladdr failures%lu
malloc calls%lu
malloc failures%lu
calloc calls%lu
calloc failures%lu
realloc calls%lu
realloc failures%lu
free calls%lu
free(null) calls%lu
", - (unsigned long) event->u.stats.tmstats.calltree_maxstack, - (unsigned long) event->u.stats.tmstats.calltree_maxdepth, - (unsigned long) event->u.stats.tmstats.calltree_parents, - (unsigned long) event->u.stats.tmstats.calltree_maxkids, - (unsigned long) event->u.stats.tmstats.calltree_kidhits, - (unsigned long) event->u.stats.tmstats.calltree_kidmisses, - (unsigned long) event->u.stats.tmstats.calltree_kidsteps, - (unsigned long) event->u.stats.tmstats.callsite_recurrences, - (unsigned long) event->u.stats.tmstats.backtrace_calls, - (unsigned long) event->u.stats.tmstats.backtrace_failures, - (unsigned long) event->u.stats.tmstats.btmalloc_failures, - (unsigned long) event->u.stats.tmstats.dladdr_failures, - (unsigned long) event->u.stats.tmstats.malloc_calls, - (unsigned long) event->u.stats.tmstats.malloc_failures, - (unsigned long) event->u.stats.tmstats.calloc_calls, - (unsigned long) event->u.stats.tmstats.calloc_failures, - (unsigned long) event->u.stats.tmstats.realloc_calls, - (unsigned long) event->u.stats.tmstats.realloc_failures, - (unsigned long) event->u.stats.tmstats.free_calls, - (unsigned long) event->u.stats.tmstats.null_free_calls); - - if (event->u.stats.calltree_maxkids_parent) { - tmcallsite *site = - tmreader_callsite(tmr, event->u.stats.calltree_maxkids_parent); - if (site && site->method) { - fprintf(stdout, "

callsite with the most kids: %s

", - tmmethodnode_name(site->method)); - } - } - - if (event->u.stats.calltree_maxstack_top) { - tmcallsite *site = - tmreader_callsite(tmr, event->u.stats.calltree_maxstack_top); - fputs("

deepest callsite tree path:\n" - "\n" - "\n", - stdout); - while (site) { - fprintf(stdout, - "\n", - site->method ? tmmethodnode_name(site->method) : "???", - (unsigned long) site->offset); - site = site->parent; - } - fputs("
MethodOffset
%s0x%08lX
\n


\n", stdout); - } - break; - } -} - -int main(int argc, char **argv) -{ - int c, i, j, rv; - tmreader *tmr; - FILE *fp; - - program = *argv; - tmr = tmreader_new(program, NULL); - if (!tmr) { - perror(program); - exit(1); - } - - while ((c = getopt(argc, argv, "djtuf:m:")) != EOF) { - switch (c) { - case 'd': - sort_by_direct = 1; - break; - case 'j': - js_mode = 1; - break; - case 't': - do_tree_dump = 1; - break; - case 'u': - unified_output = 1; - break; - case 'f': - function_dump = optarg; - break; - case 'm': - min_subtotal = atoi(optarg); - break; - default: - fprintf(stderr, - "usage: %s [-dtu] [-f function-dump-filename] [-m min] [output.html]\n", - program); - exit(2); - } - } - - if (!js_mode) { - time_t start = time(NULL); - - fprintf(stdout, - "\n"); - fprintf(stdout, "%s starting at %s", program, ctime(&start)); - fflush(stdout); - } - - argc -= optind; - argv += optind; - if (argc == 0) { - if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0) - exit(1); - } else { - for (i = j = 0; i < argc; i++) { - fp = fopen(argv[i], "r"); - if (!fp) { - fprintf(stderr, "%s: can't open %s: %s\n", - program, argv[i], strerror(errno)); - exit(1); - } - rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler); - if (rv < 0) - exit(1); - if (rv > 0) - j++; - fclose(fp); - } - if (j == 0) - exit(1); - } - - compute_callsite_totals(&tmr->calltree_root); - walk_callsite_tree(&tmr->calltree_root, 0, 0, stdout); - - if (js_mode) { - fprintf(stdout, - "\n" - "\n" - " \n" - " \n" - "\n", - stdout); - } - } - - exit(0); -} diff --git a/tools/trace-malloc/diffbloatdump.pl b/tools/trace-malloc/diffbloatdump.pl deleted file mode 100755 index 06759b3a10a0..000000000000 --- a/tools/trace-malloc/diffbloatdump.pl +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/perl -w -# vim:cindent:ts=8:et:sw=4: -# 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/. - -# This script produces a diff between two files that are the result of -# calling NS_TraceMallocDumpAllocations. Such files can be created -# through the command-line option --shutdown-leaks= or through -# the DOM function window.TraceMallocDumpAllocations(). Both -# methods will work only if --trace-malloc= is also given on -# the command line. - -use 5.004; -use strict; -use Getopt::Long; - -$::opt_help = 0; -$::opt_depth = 6; -$::opt_include_zero = 0; -$::opt_allocation_count = 0; -$::opt_use_address = 0; - -# XXX Change --use-address to be the default and remove the option -# once tinderbox is no longer using it without --use-address. - -Getopt::Long::Configure("pass_through"); -Getopt::Long::GetOptions("help", "allocation-count", "depth=i", - "include-zero", "use-address"); - -if ($::opt_help) { - die "usage: diffbloatdump.pl [options] - --help Display this message - - --allocation-count Use allocation count rather than size (i.e., treat - all sizes as 1). - --depth= Only display frames at top of allocation stack. - --include-zero Display subtrees totalling zero. - --use-address Don't ignore the address part of the stack trace - (can make comparison more accurate when comparing - results from the same build) - - The input files ( and above) are either trace-malloc - memory dumps OR this script's output. (If this script's output, - --allocation-count and --use-address are ignored.) If the input files - have .gz or .bz2 extension, they are uncompressed. -"; -} - -my $calltree = { count => 0 }; # leave children undefined - -sub get_child($$) { - my ($node, $frame) = @_; - if (!defined($node->{children})) { - $node->{children} = {}; - } - if (!defined($node->{children}->{$frame})) { - $node->{children}->{$frame} = { count => 0 }; - } - return $node->{children}->{$frame}; -} - -sub add_tree_file($$$) { - my ($infile, $firstline, $factor) = @_; - - my @nodestack; - $nodestack[1] = $calltree; - $firstline =~ /^(-?\d+) malloc$/; - $calltree->{count} += $1 * $factor; - - my $lineno = 1; - while (!eof($infile)) { - my $line = <$infile>; - ++$lineno; - $line =~ /^( *)(-?\d+) (.*)$/ || die "malformed input, line $lineno"; - my $depth = length($1); - my $count = $2; - my $frame = $3; - die "malformed input, line $lineno" if ($depth % 2 != 0); - $depth /= 2; - die "malformed input, line $lineno" if ($depth > $#nodestack); - $#nodestack = $depth; - my $node = get_child($nodestack[$depth], $frame); - push @nodestack, $node; - $node->{count} += $count * $factor; - } -} - -sub add_file($$) { - # Takes (1) a reference to a file descriptor for input and (2) the - # factor to multiply the stacks by (generally +1 or -1). - # Returns a reference to an array representing the stack, allocation - # site in array[0]. - sub read_stack($) { - my ($infile) = @_; - my $line; - my @stack; - - # read the data at the memory location - while ( defined($infile) && ($line = <$infile>) && substr($line,0,1) eq "\t" ) { - # do nothing - } - - # read the stack - do { - chomp($line); - if ( ! $::opt_use_address && - $line =~ /(.*)\[(.*)\]/) { - $line = $1; - } - $stack[$#stack+1] = $line; - } while ( defined($infile) && ($line = <$infile>) && $line ne "\n" && $line ne "\r\n" ); - - return \@stack; - } - - # adds the stack given as a parameter (reference to array, $stack[0] is - # allocator) to $calltree, with the call count multiplied by $factor - # (typically +1 or -1). - sub add_stack($$) { - my @stack = @{$_[0]}; - my $factor = $_[1]; - - my $i = 0; - my $node = $calltree; - while ($i < $#stack && $i < $::opt_depth) { - $node->{count} += $factor; - $node = get_child($node, $stack[$i]); - ++$i; - } - $node->{count} += $factor; - } - - my ($infile, $factor) = @_; - - if ($infile =~ /\.bz2$/) { - # XXX This doesn't propagate errors from bzip2. - open (INFILE, "bzip2 -cd '$infile' |") || die "Can't open input \"$infile\""; - } elsif ($infile =~ /\.gz$/) { - # XXX This doesn't propagate errors from gzip. - open (INFILE, "gzip -cd '$infile' |") || die "Can't open input \"$infile\""; - } else { - open (INFILE, "<$infile") || die "Can't open input \"$infile\""; - } - my $first = 1; - while ( ! eof(INFILE) ) { - # read the type and address - my $line = ; - if ($first) { - $first = 0; - if ($line =~ /^-?\d+ malloc$/) { - # We're capable of reading in our own output as well. - add_tree_file(\*INFILE, $line, $factor); - close INFILE; - return; - } - } - unless ($line =~ /.*\((\d*)\)[\r|\n]/) { - die "badly formed allocation header in $infile"; - } - my $size; - if ($::opt_allocation_count) { - $size = 1; - } else { - $size = $1; - } - - add_stack(read_stack(\*INFILE), $size * $factor); - } - close INFILE; -} - -sub print_node_indent($$$); - -sub print_calltree() { - sub print_indent($) { - my ($i) = @_; - while (--$i >= 0) { - print " "; - } - } - - sub print_node_indent($$$) { - my ($nodename, $node, $indent) = @_; - - if (!$::opt_include_zero && $node->{count} == 0) { - return; - } - - print_indent($indent); - print "$node->{count} $nodename\n"; - if (defined($node->{children})) { - my %kids = %{$node->{children}}; - ++$indent; - foreach my $kid (sort { $kids{$b}->{count} <=> $kids{$a}->{count} } - keys (%kids)) { - print_node_indent($kid, $kids{$kid}, $indent); - } - } - } - - print_node_indent("malloc", $calltree, 0); -} - -add_file($ARGV[0], -1); -add_file($ARGV[1], 1); -print_calltree(); diff --git a/tools/trace-malloc/formdata.c b/tools/trace-malloc/formdata.c deleted file mode 100644 index f4660d0db185..000000000000 --- a/tools/trace-malloc/formdata.c +++ /dev/null @@ -1,204 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* -** formdata.c -** -** Play utility to parse up form get data into name value pairs. -*/ - -#include "formdata.h" - -#include -#include -#include - - -static void unhexcape(char* inPlace) -/* -** Real low tech unhexcaper.... -** -** inPlace string to decode, in place as it were. -*/ -{ - if(NULL != inPlace) - { - int index1 = 0; - int index2 = 0; - int theLen = strlen(inPlace); - - for(; index1 <= theLen; index1++) - { - if('%' == inPlace[index1] && '\0' != inPlace[index1 + 1] && '\0' != inPlace[index1 + 2]) - { - int unhex = 0; - - if('9' >= inPlace[index1 + 1]) - { - unhex |= ((inPlace[index1 + 1] - '0') << 4); - } - else - { - unhex |= ((toupper(inPlace[index1 + 1]) - 'A' + 10) << 4); - } - - if('9' >= inPlace[index1 + 2]) - { - unhex |= (inPlace[index1 + 2] - '0'); - } - else - { - unhex |= (toupper(inPlace[index1 + 2]) - 'A' + 10); - } - - index1 += 2; - inPlace[index1] = unhex; - } - - inPlace[index2++] = inPlace[index1]; - } - } -} - - -FormData* FormData_Create(const char* inFormData) -{ - FormData* retval = NULL; - - if(NULL != inFormData) - { - FormData* container = NULL; - - /* - ** Allocate form data container. - */ - container = (FormData*)calloc(1, sizeof(FormData)); - if(NULL != container) - { - /* - ** Dup the incoming form data. - */ - container->mStorage = strdup(inFormData); - if(NULL != container->mStorage) - { - char* traverse = NULL; - unsigned nvpairs = 1; - unsigned storeLen = 0; - - /* - ** Count the number of pairs we are going to have. - ** We do this by counting '&' + 1. - */ - for(traverse = container->mStorage; '\0' != *traverse; traverse++) - { - if('&' == *traverse) - { - nvpairs++; - } - } - storeLen = (unsigned)(traverse - container->mStorage); - - /* - ** Allocate space for our names and values. - */ - container->mNArray = (char**)calloc(nvpairs * 2, sizeof(char*)); - if(NULL != container->mNArray) - { - char* amp = NULL; - char* equ = NULL; - - container->mVArray = &container->mNArray[nvpairs]; - - /* - ** Go back over the storage. - ** Fill in the names and values as we go. - ** Terminate on dividing '=' and '&' characters. - ** Increase the count of items as we go. - */ - for(traverse = container->mStorage; NULL != traverse; container->mNVCount++) - { - container->mNArray[container->mNVCount] = traverse; - - amp = strchr(traverse, '&'); - equ = strchr(traverse, '='); - traverse = NULL; - - if(NULL != equ && (NULL == amp || equ < amp)) - { - *equ++ = '\0'; - - container->mVArray[container->mNVCount] = equ; - } - else - { - container->mVArray[container->mNVCount] = (container->mStorage + storeLen); - } - - if(NULL != amp) - { - *amp++ = '\0'; - - traverse = amp; - } - - unhexcape(container->mNArray[container->mNVCount]); - unhexcape(container->mVArray[container->mNVCount]); - } - - retval = container; - } - } - } - - /* - ** If we failed, cleanup. - */ - if(NULL == retval) - { - FormData_Destroy(container); - } - } - - return retval; -} - - -void FormData_Destroy(FormData* inDestroy) -{ - if(NULL != inDestroy) - { - unsigned traverse = 0; - - for(traverse = 0; traverse < inDestroy->mNVCount; traverse++) - { - if(NULL != inDestroy->mNArray) - { - inDestroy->mNArray[traverse] = NULL; - } - if(NULL != inDestroy->mVArray) - { - inDestroy->mVArray[traverse] = NULL; - } - } - inDestroy->mNVCount = 0; - - if(NULL != inDestroy->mStorage) - { - free(inDestroy->mStorage); - inDestroy->mStorage = NULL; - } - - if(NULL != inDestroy->mNArray) - { - free(inDestroy->mNArray); - inDestroy->mNArray = NULL; - inDestroy->mVArray = NULL; - } - - free(inDestroy); - inDestroy = NULL; - } -} diff --git a/tools/trace-malloc/formdata.h b/tools/trace-malloc/formdata.h deleted file mode 100644 index 0ef937b73a40..000000000000 --- a/tools/trace-malloc/formdata.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -#if !defined(__formdata_H__) -#define __formdata_H__ - -/* -** formdata.h -** -** Play (quick and dirty) utility API to parse up form get data into -** name value pairs. -*/ - -typedef struct __struct_FormData -/* -** Structure to hold the breakdown of any form data. -** -** mNArray Each form datum is a name value pair. -** This array holds the names. -** You can find the corresponding value at the same index in -** mVArray. -** Never NULL, but perhpas an empty string. -** mVArray Each form datum is a name value pair. -** This array holds the values. -** You can find the corresponding name at the same index in -** mNArray. -** Never NULL, but perhpas an empty string. -** mNVCount Count of array items in both mNArray and mVArray. -** mStorage Should be ignored by users of this API. -** In reality holds the duped and decoded form data. -*/ -{ - char** mNArray; - char** mVArray; - unsigned mNVCount; - char* mStorage; -} -FormData; - -FormData* FormData_Create(const char* inFormData) -/* -** Take a contiguous string of form data, possibly hex encoded, and return -** the name value pairs parsed up and decoded. -** A caller of this routine should call FormData_Destroy at some point. -** -** inFormData The form data to parse up and decode. -** returns FormData* The result of our effort. -** This should be passed to FormData_Destroy at some -** point of the memory will be leaked. -*/ -; - -void FormData_Destroy(FormData* inDestroy) -/* -** Release to the heap the structure previously created via FormData_Create. -** -** inDestroy The object to free off. -*/ -; - -#endif /* __formdata_H__ */ diff --git a/tools/trace-malloc/getopt.c b/tools/trace-malloc/getopt.c deleted file mode 100644 index a7619e9c7b72..000000000000 --- a/tools/trace-malloc/getopt.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that: (1) source distributions retain this entire copyright - * notice and comment, and (2) distributions including binaries display - * the following acknowledgement: ``This product includes software - * developed by the University of California, Berkeley and its contributors'' - * in the documentation or other materials provided with the distribution - * and in all advertising materials mentioning features or use of this - * software. Neither the name of the University nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 4.12 (Berkeley) 6/1/90"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#define index strchr -#define rindex strrchr - -/* - * get option letter from argument vector - */ -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define EMSG "" - -int getopt(int nargc, char **nargv, char *ostr) -{ - static char *place = EMSG; /* option letter processing */ - register char *oli; /* option letter list index */ - char *p; - - if (!*place) { /* update scanning pointer */ - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return(EOF); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++optind; - place = EMSG; - return(EOF); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = index(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means EOF. - */ - if (optopt == (int)'-') - return(EOF); - if (!*place) - ++optind; - if (opterr) { - if (!(p = rindex(*nargv, '/'))) - p = *nargv; - else - ++p; - (void)fprintf(stderr, "%s: illegal option -- %c\n", - p, optopt); - } - return(BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (!(p = rindex(*nargv, '/'))) - p = *nargv; - else - ++p; - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - p, optopt); - return(BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return(optopt); /* dump back option letter */ -} diff --git a/tools/trace-malloc/histogram-diff.sh b/tools/trace-malloc/histogram-diff.sh deleted file mode 100755 index 275de2a9844e..000000000000 --- a/tools/trace-malloc/histogram-diff.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# -# 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/. - -# histogram-diff.sh [-c ] -# -# Compute incremental memory growth from histogram in file to -# histogram in file , displaying at most rows. - -# How many rows are we gonna show? -COUNT=20 - -# Read arguments -while [ $# -gt 0 ]; do - case "$1" in - -c) COUNT=$2 - shift 2 - ;; - *) break - ;; - esac -done - -BASE=$1 -INCR=$2 - -# Sort the base and incremental files so that we can `join' them on -# the type name -sort $BASE > /tmp/$$.left -sort $INCR > /tmp/$$.right - -# Do the join. The `awk' script computes the difference between -# the base and the incremental files. -join /tmp/$$.left /tmp/$$.right \ - | awk '{ print $1, $2, $3, $4, $5, $4 - $2, $5 - $3; }' \ - > /tmp/$$.joined - -rm -f /tmp/$$.left /tmp/$$.right - -# Now compute a `TOTAL' row. -awk '{ tobj1 += $2; tbytes1 += $3; tobj2 += $4; tbytes2 += $5; tdobj += $6; tdbytes += $7; } END { print "TOTAL", tobj1, tbytes1, tobj2, tbytes2, tdobj, tdbytes; }' /tmp/$$.joined \ - > /tmp/$$.sorted - -# Then, we sort by the largest delta in bytes. -sort -nr +6 /tmp/$$.joined >> /tmp/$$.sorted - -rm -f /tmp/$$.joined - -# Pretty-print, including percentages -cat < /tmp/$$.awk -BEGIN { - print " ---- Base ---- ---- Incr ---- ----- Difference ----"; - print "Type Count Bytes Count Bytes Count Bytes %Total"; - } -\$1 == "TOTAL" { - tbytes = \$7; - } -NR <= $COUNT { - printf "%-22s %6d %8d %6d %8d %6d %8d %6.2lf\n", \$1, \$2, \$3, \$4, \$5, \$6, \$7, 100.0 * \$7 / tbytes; - } -NR > $COUNT { - oobjs1 += \$2; obytes1 += \$3; - oobjs2 += \$4; obytes2 += \$5; - odobjs += \$6; odbytes += \$7; - } -END { - printf "%-22s %6d %8d %6d %8d %6d %8d %6.2lf\n", "OTHER", oobjs1, obytes1, oobjs2, obytes2, odobjs, odbytes, odbytes * 100.0 / tbytes; - } -EOF - -# Now pretty print the file, and spit it out on stdout. -awk -f /tmp/$$.awk /tmp/$$.sorted - -rm -f /tmp/$$.awk /tmp/$$.sorted diff --git a/tools/trace-malloc/histogram-pretty.sh b/tools/trace-malloc/histogram-pretty.sh deleted file mode 100755 index 36e90151033b..000000000000 --- a/tools/trace-malloc/histogram-pretty.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh -# -# 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/. - -# histogram-pretty.sh [-c ] [-w ] -# -# Pretty-print the histogram in file , displaying at most -# rows. - -# How many rows are we gonna show? -COUNT=20 -WIDTH=22 - -# Read arguments -while [ $# -gt 0 ]; do - case "$1" in - -c) COUNT=$2 - shift 2 - ;; - -w) WIDTH=$2 - shift 2 - ;; - *) break - ;; - esac -done - -FILE=$1 - -# The first `awk' script computes a `TOTAL' row. Then, we sort by the -# larges delta in bytes. -awk '{ tobj += $2; tbytes += $3; } END { print "TOTAL", tobj, tbytes; }' ${FILE} > /tmp/$$.sorted - -sort -nr +2 ${FILE} >> /tmp/$$.sorted - -# Pretty-print, including percentages -cat < /tmp/$$.awk -BEGIN { - printf "%-${WIDTH}s Count Bytes %Total %Cov\n", "Type"; - } -\$1 == "TOTAL" { - tbytes = \$3; - } -NR <= $COUNT { - if (\$1 != "TOTAL") { - covered += \$3; - } - printf "%-${WIDTH}s %6d %8d %6.2lf %6.2lf\n", \$1, \$2, \$3, 100.0 * \$3 / tbytes, 100.0 * covered / tbytes; - } -NR > $COUNT { - oobjs += \$2; obytes += \$3; covered += \$3; - } -END { - printf "%-${WIDTH}s %6d %8d %6.2lf %6.2lf\n", "OTHER", oobjs, obytes, obytes * 100.0 / tbytes, covered * 100.0 / tbytes; - } -EOF - -# Now pretty print the file, and spit it out on stdout. -awk -f /tmp/$$.awk /tmp/$$.sorted - -rm -f /tmp/$$.awk /tmp/$$.sorted diff --git a/tools/trace-malloc/histogram.pl b/tools/trace-malloc/histogram.pl deleted file mode 100755 index 9cdb8bcc5995..000000000000 --- a/tools/trace-malloc/histogram.pl +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/perl -w -# -# 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/. - -# This program produces a ``class histogram'' of the live objects, one -# line per class, with the total number of objects allocated, and -# total number of bytes attributed to those objects. - -use 5.004; -use strict; -use Getopt::Long; - -# So we can find TraceMalloc.pm -use FindBin; -use lib "$FindBin::Bin"; - -use TraceMalloc; - -# Collect program options -$::opt_help = 0; -$::opt_types = "${FindBin::Bin}/types.dat"; - -GetOptions("help", "types=s"); - -if ($::opt_help) { - die "usage: histogram.pl [options] - --help Display this message - --types= Read type heuristics from "; -} - -# Initialize type inference juju from the type file specified by -# ``--types''. -if ($::opt_types) { - TraceMalloc::init_type_inference($::opt_types); -} - -# Read the dump file, collecting count and size information for each -# object that's detected. - -# This'll hold a record for each class that we detect -$::Classes = { }; - -sub collect_objects($) { - my ($object) = @_; - my $type = $object->{'type'}; - - my $entry = $::Classes{$type}; - if (! $entry) { - $entry = $::Classes{$type} = { '#count#' => 0, '#bytes#' => 0 }; - } - - $entry->{'#count#'} += 1; - $entry->{'#bytes#'} += $object->{'size'}; -} - -TraceMalloc::read(\&collect_objects); - -# Print one line per class, sorted with the classes that accumulated -# the most bytes first. -foreach my $class (sort { $::Classes{$b}->{'#bytes#'} <=> $::Classes{$a}->{'#bytes#'} } keys %::Classes) { - print "$class $::Classes{$class}->{'#count#'} $::Classes{$class}->{'#bytes#'}\n"; -} diff --git a/tools/trace-malloc/leak-soup.pl b/tools/trace-malloc/leak-soup.pl deleted file mode 100755 index b6e20d0aef49..000000000000 --- a/tools/trace-malloc/leak-soup.pl +++ /dev/null @@ -1,1180 +0,0 @@ -#!/usr/bin/perl -w -# -# 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/. - -# A perl version of Patrick Beard's ``Leak Soup'', which processes the -# stack crawls from the Boehm GC into a graph. - -use 5.004; -use strict; -use Getopt::Long; -use FileHandle; -use IPC::Open2; - -# Collect program options -$::opt_help = 0; -$::opt_detail = 0; -$::opt_fragment = 1.0; # Default to no fragment analysis -$::opt_nostacks = 0; -$::opt_nochildstacks = 0; -$::opt_depth = 9999; -$::opt_noentrained = 0; -$::opt_noslop = 0; -$::opt_showtype = -1; # default to listing all types -$::opt_stackrefine = "C"; -@::opt_stackretype = (); -@::opt_stackskipclass = (); -@::opt_stackskipfunc = (); -@::opt_typedivide = (); - -GetOptions("help", "detail", "format=s", "fragment=f", "nostacks", - "nochildstacks", "depth=i", "noentrained", "noslop", "showtype=i", - "stackrefine=s", "stackretype=s@", "stackskipclass=s@", "stackskipfunc=s@", - "typedivide=s@" - ); - -if ($::opt_help) { - die "usage: leak-soup.pl [options] - --help Display this message - --detail Provide details of memory sweeping from child to parents - --fragment=ratio Histogram bucket ratio for fragmentation analysis -# --nostacks Do not compute stack traces -# --nochildstacks Do not compute stack traces for entrained objects -# --depth= Only compute stack traces to depth of -# --noentrained Do not compute amount of memory entrained by root objects - --noslop Don't ignore low bits when searching for pointers - --showtype= Show memory usage histogram for most-significant types - --stackrefine={F|C} During stack based refinement, use 'F'ull name name or just 'C'lass - --stackretype=type Use allocation stack to refine vague types like void* - --stackskipclass=class When refining types, ignore stack frames from 'class' - --stackskipfunc=func When refining types, ignore stack frames for 'func' - --typedivide=type Subdivide 'type' based on objects pointing to each instance -"; -} - -# This is the table that keeps a graph of objects. It's indexed by the -# object's address (as an integer), and refers to a simple hash that -# has information about the object's type, size, slots, and allocation -# stack. -%::Objects = %{0}; - -# This will be a list of keys to (addresses in) Objects, that is sorted -# It gets used to evaluate overlaps, calculate fragmentation, and chase -# parent->child (interior) pointers. -@::SortedAddresses = []; - -# This is the table that keeps track of memory usage on a per-type basis. -# It is indexed by the type name (string), and keeps a tally of the -# total number of such objects, and the memory usage of such objects. -%::Types = %{0}; -$::TotalSize = 0; # sum of sizes of all objects included $::Types{} - -# This is an array of leaf node addresses. A leaf node has no children -# with memory allocations. We traverse them sweeping memory -# tallies into parents. Note that after all children have -# been swept into a parent, that parent may also become a leaf node. -@::Leafs = @{0}; - - - - -#---------------------------------------------------------------------- -# -# Decode arguments to override default values for doing call-stack-based -# refinement of typename based on contents of the stack at allocation time. -# - -# List the types that we need to refine (if any) based on allocation stack -$::VagueType = { - 'void*' => 1, -}; - -# With regard to the stack, ignore stack frames in the following -# overly vague classes. -$::VagueClasses = { -# 'nsStr' => 1, - 'nsVoidArray' => 1, -}; - -# With regard to stack, ignore stack frames with the following vague -# function names -$::VagueFunctions = { - 'PL_ArenaAllocate' => 1, - 'PL_HashTableFinalize(PLHashTable *)' => 1, - 'PL_HashTableInit__FP11PLHashTableUiPFPCv_UiPFPCvPCv_iT3PC14PLHashAllocOpsPv' => 1, - 'PL_HashTableRawAdd' => 1, - '__builtin_vec_new' => 1, - '_init' => 1, - 'il_get_container(_IL_GroupContext *, ImgCachePolicy, char const *, _NI_IRGB *, IL_DitherMode, int, int, int)' => 1, - 'nsCStringKey::Clone(void) const' => 1, - 'nsCppSharedAllocator::allocate(unsigned int, void const *)' => 1, - 'nsHashtable::Put(nsHashKey *, void *)' => 1, - 'nsHashtable::nsHashtable(unsigned int, int)' => 1, - 'nsMemory::Alloc(unsigned int)' => 1, - 'nsMemoryImpl::Alloc(unsigned int)' => 1, -}; - -sub init_stack_based_type_refinement() { - # Move across stackretype options, or use default values - if ($#::opt_stackretype < 0) { - print "Default --stackretype options will be used (since none were specified)\n"; - print " use --stackretype='nothing' to disable re-typing activity\n"; - } else { - foreach my $type (keys %{$::VagueType}) { - delete ($::VagueType->{$type}); - } - if ($#::opt_stackretype == 0 && $::opt_stackretype[0] eq 'nothing') { - print "Types will not be refined based on call stack\n"; - } else { - foreach my $type (@::opt_stackretype) { - $::VagueType->{$type} = 1; - } - } - } - - - if (keys %{$::VagueType}) { - print "The following type(s) will be refined based on call stacks:\n"; - foreach my $type (sort keys %{$::VagueType}) { - print " $type\n"; - } - print "Equivalent command line argument(s):\n"; - foreach my $type (sort keys %{$::VagueType}) { - print " --stackretype='$type'"; - } - print "\n\n"; - - if ($#::opt_stackskipclass < 0) { - print "Default --stackskipclass options will be used (since none were specified)\n"; - print " use --stackskipclass='nothing' to disable skipping stack frames based on class names\n"; - } else { - foreach my $type (keys %{$::VagueClasses}) { - delete ($::VagueClasses->{$type}); - } - if ($#::opt_stackskipclass == 0 && $::opt_stackskipclass[0] eq 'nothing') { - print "Types will not be refined based on call stack\n"; - } else { - foreach my $type (@::opt_stackskipclass) { - $::VagueClasses->{$type} = 1; - } - } - } - - if (keys %{$::VagueClasses}) { - print "Stack frames from the following class(es) will not be used to refine types:\n"; - foreach my $class (sort keys %{$::VagueClasses}) { - print " $class\n"; - } - print "Equivalent command line argument(s):\n"; - foreach my $class (sort keys %{$::VagueClasses}) { - print " --stackskipclass='$class'"; - } - print "\n\n"; - } - - - if ($#::opt_stackskipfunc < 0) { - print "Default --stackskipfunc options will be used (since none were specified)\n"; - print " use --stackskipfunc='nothing' to disable skipping stack frames based on function names\n"; - } else { - foreach my $type (keys %{$::VagueFunctions}) { - delete ($::VagueFunctions->{$type}); - } - if ($#::opt_stackskipfunc == 0 && $::opt_stackskipfunc[0] eq 'nothing') { - print "Types will not be refined based on call stack\n"; - } else { - foreach my $type (@::opt_stackskipfunc) { - $::VagueFunctions->{$type} = 1; - } - } - } - - if (keys %{$::VagueFunctions}) { - print "Stack frames from the following function(s) will not be used to refine types:\n"; - foreach my $func (sort keys %{$::VagueFunctions}) { - print " $func\n"; - } - print "Equivalent command line argument(s):\n"; - foreach my $func (sort keys %{$::VagueFunctions}) { - print " --stackskipfunc='$func'"; - } - print "\n\n"; - } - } -} - - -#---------------------------------------------------------------------- -# -# Read in the output from the Boehm GC or Trace-malloc. -# -sub read_boehm() { - OBJECT: while (<>) { - # e.g., 0x0832FBD0 (80) - next OBJECT unless /^0x(\S+) <(.*)> \((\d+)\)/; - my ($addr, $type, $size) = (hex $1, $2, $3); - - my $object = $::Objects{$addr}; - if (! $object) { - # Found a new object entry. Record its type and size - $::Objects{$addr} = - $object = - { 'type' => $type, 'size' => $size }; - } else { - print "Duplicate address $addr contains $object->{'type'} and $type\n"; - $object->{'dup_addr_count'}++; - } - - # Record the object's slots - my @slots; - - SLOT: while (<>) { - # e.g., 0x00000000 - last SLOT unless /^\t0x(\S+)/; - my $value = hex $1; - - # Ignore low bits, unless they've specified --noslop - $value &= ~0x7 unless $::opt_noslop; - - $slots[$#slots + 1] = $value; - } - - $object->{'slots'} = \@slots; - - if (@::opt_stackretype && (defined $::VagueType->{$type})) { - # Change the value of type of the object based on stack - # if we can find an interesting calling function - VAGUEFRAME: while (<>) { - # e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858] - last VAGUEFRAMEFRAME unless /^(.*)\[(.*) \+0x(\S+)\]$/; - my ($func, $lib, $off) = ($1, $2, hex $3); - chomp; - - my ($class,,$fname) = split(/:/, $func); - next VAGUEFRAME if (defined $::VagueFunctions->{$func} || - defined $::VagueClasses->{$class}); - - # Refine typename and exit stack scan - $object->{'type'} = $type . ":" . - (('C' eq $::opt_stackrefine) ? - $class : - $func); - last VAGUEFRAME; - } - } else { - # Save all stack info if requested - if (! $::opt_nostacks) { - # Record the stack by which the object was allocated - my @stack; - - FRAME: while (<>) { - # e.g., _dl_debug_message[/lib/ld-linux.so.2 +0x0000B858] - last FRAME unless /^(.*)\[(.*) \+0x(\S+)\]$/; - my ($func, $lib, $off) = ($1, $2, hex $3); - chomp; - - $stack[$#stack + 1] = $_; - } - - $object->{'stack'} = \@stack; - } - } - - # Gotta check EOF explicitly... - last OBJECT if eof; - } -} - - -#---------------------------------------------------------------------- -# -# Read input -# -init_stack_based_type_refinement(); -read_boehm; - - - -#---------------------------------------------------------------------- -# -# Do basic initialization of the type hash table. Accumulate -# total counts, and basic memory usage (not including children) -sub load_type_table() { - # Reset global counter and hash table - $::TotalSize = 0; - %::Types = %{0}; - - OBJECT: foreach my $addr (keys %::Objects) { - my $obj = $::Objects{$addr}; - my ($type, $size, $swept_in, $overlap_count, $dup_addr_count) = - ($obj->{'type'}, $obj->{'size'}, - $obj->{'swept_in'}, - $obj->{'overlap_count'},$obj->{'dup_addr_count'}); - - my $type_data = $::Types{$type}; - if (! defined $type_data) { - $::Types{$type} = - $type_data = {'count' => 0, 'size' => 0, - 'max' => $size, 'min' => $size, - 'swept_in' => 0, 'swept' => 0, - 'overlap_count' => 0, - 'dup_addr_count' => 0}; - } - - if (!$size) { - $type_data->{'swept'}++; - next OBJECT; - } - $::TotalSize += $size; - - $type_data->{'count'}++; - $type_data->{'size'} += $size; - if (defined $swept_in) { - $type_data->{'swept_in'} += $swept_in; - - if ($::opt_detail) { - my $type_detail_sizes = $type_data->{'sweep_details_size'}; - my $type_detail_counts; - if (!defined $type_detail_sizes) { - $type_detail_sizes = $type_data->{'sweep_details_size'} = {}; - $type_detail_counts = $type_data->{'sweep_details_count'} = {}; - } else { - $type_detail_counts = $type_data->{'sweep_details_count'}; - } - - my $sweep_details = $obj->{'sweep_details'}; - for my $swept_addr (keys (%{$sweep_details})) { - my $swept_obj = $::Objects{$swept_addr}; - my $swept_type = $swept_obj->{'type'}; - $type_detail_sizes->{$swept_type} += $sweep_details->{$swept_addr}; - $type_detail_counts->{$swept_type}++; - } - } - } - if (defined $overlap_count) { - $type_data->{'overlap_count'} += $overlap_count; - } - - if (defined $dup_addr_count) { - $type_data->{'dup_addr_count'} += $dup_addr_count; - } - - if ($type_data->{'max'} < $size) { - $type_data->{'max'} = $size; - } - # Watch out for case where min is produced by a swept object - if (!$type_data->{'min'} || $type_data->{'min'} > $size) { - $type_data->{'min'} = $size; - } - } -} - - -#---------------------------------------------------------------------- -sub print_type_table(){ - if (!$::opt_showtype) { - return; - } - my $line_count = 0; - my $bytes_printed_tally = 0; - - # Display type summary information - my @sorted_types = keys (%::Types); - print "There are ", 1 + $#sorted_types, " types containing ", $::TotalSize, " bytes\n"; - @sorted_types = sort {$::Types{$b}->{'size'} - <=> $::Types{$a}->{'size'} } @sorted_types; - - foreach my $type (@sorted_types) { - last if ($line_count++ == $::opt_showtype); - - my $type_data = $::Types{$type}; - $bytes_printed_tally += $type_data->{'size'}; - - if ($type_data->{'count'}) { - printf "%.2f%% ", $type_data->{'size'} * 100.0/$::TotalSize; - print $type_data->{'size'}, - "\t(", - $type_data->{'min'}, "/", - int($type_data->{'size'} / $type_data->{'count'}),"/", - $type_data->{'max'}, ")"; - print "\t", $type_data->{'count'}, - " x "; - } - print $type; - - if ($type_data->{'swept_in'}) { - print ", $type_data->{'swept_in'} sub-objs absorbed"; - } - if ($type_data->{'swept'}) { - print ", $type_data->{'swept'} swept away"; - } - if ($type_data->{'overlap_count'}) { - print ", $type_data->{'overlap_count'} range overlaps"; - } - if ($type_data->{'dup_addr_count'}) { - print ", $type_data->{'dup_addr_count'} duplicated addresses"; - } - - print "\n" ; - if (defined $type_data->{'sweep_details_size'}) { - my $sizes = $type_data->{'sweep_details_size'}; - my $counts = $type_data->{'sweep_details_count'}; - my @swept_types = sort {$sizes->{$b} <=> $sizes->{$a}} keys (%{$sizes}); - - for my $type (@swept_types) { - printf " %.2f%% ", $sizes->{$type} * 100.0/$::TotalSize; - print "$sizes->{$type} (", int($sizes->{$type}/$counts->{$type}) , ") $counts->{$type} x $type\n"; - } - print " ---------------\n"; - } - } - if ($bytes_printed_tally != $::TotalSize) { - printf "%.2f%% ", ($::TotalSize- $bytes_printed_tally) * 100.0/$::TotalSize; - print $::TotalSize - $bytes_printed_tally, "\t not shown due to truncation of type list\n"; - print "Currently only data on $::opt_showtype types are displayed, due to command \n", - "line argument '--showtype=$::opt_showtype'\n\n"; - } - -} - -#---------------------------------------------------------------------- -# -# Check for duplicate address ranges is Objects table, and -# create list of sorted addresses for doing pointer-chasing - -sub validate_address_ranges() { - # Build sorted list of address for validating interior pointers - @::SortedAddresses = sort {$a <=> $b} keys %::Objects; - - # Validate non-overlap of memory - my $prev_addr_end = -1; - my $prev_addr = -1; - my $index = 0; - my $overlap_tally = 0; # overlapping object memory - my $unused_tally = 0; # unused memory between blocks - while ($index <= $#::SortedAddresses) { - my $address = $::SortedAddresses[$index]; - if ($prev_addr_end > $address) { - print "Object overlap from $::Objects{$prev_addr}->{'type'}:$prev_addr-$prev_addr_end into"; - my $test_index = $index; - my $prev_addr_overlap_tally = 0; - - while ($test_index <= $#::SortedAddresses) { - my $test_address = $::SortedAddresses[$test_index]; - last if ($prev_addr_end < $test_address); - print " $::Objects{$test_address}->{'type'}:$test_address"; - - $::Objects{$prev_addr}->{'overlap_count'}++; - $::Objects{$test_address}->{'overlap_count'}++; - my $overlap = $prev_addr_end - $test_address; - if ($overlap > $::Objects{$test_address}->{'size'}) { - $overlap = $::Objects{$test_address}->{'size'}; - } - print "($overlap bytes)"; - $prev_addr_overlap_tally += $overlap; - - $test_index++; - } - print " [total $prev_addr_overlap_tally bytes]"; - $overlap_tally += $prev_addr_overlap_tally; - print "\n"; - } - - $prev_addr = $address; - $prev_addr_end = $prev_addr + $::Objects{$prev_addr}->{'size'} - 1; - $index++; - } #end while - if ($overlap_tally) { - print "Total overlap of $overlap_tally bytes\n"; - } -} - -#---------------------------------------------------------------------- -# -# Evaluate sizes of interobject spacing (fragmentation loss?) -# Gather the sizes into histograms for analysis -# This function assumes a sorted list of addresses is present globally - -sub generate_and_print_unused_memory_histogram() { - print "\nInterobject spacing (fragmentation waste) Statistics\n"; - if ($::opt_fragment <= 1) { - print "Statistics are not being gathered. Use '--fragment=10' to get stats\n"; - return; - } - print "Ratio of histogram buckets will be a factor of $::opt_fragment\n"; - - my $prev_addr_end = -1; - my $prev_addr = -1; - my $index = 0; - - my @fragment_count; - my @fragment_tally; - my $power; - my $bucket_size; - - my $max_power = 0; - - my $tally_sizes = 0; - - while ($index <= $#::SortedAddresses) { - my $address = $::SortedAddresses[$index]; - - my $unused = $address - $prev_addr_end; - - # handle overlaps gracefully - if ($unused < 0) { - $unused = 0; - } - - $power = 0; - $bucket_size = 1; - while ($bucket_size < $unused) { - $bucket_size *= $::opt_fragment; - $power++; - } - $fragment_count[$power]++; - $fragment_tally[$power] += $unused; - if ($power > $max_power) { - $max_power = $power; - } - my $size = $::Objects{$address}->{'size'}; - $tally_sizes += $size; - $prev_addr_end = $address + $size - 1; - $index++; - } - - - $power = 0; - $bucket_size = 1; - print "Basic gap histogram is (max_size:count):\n"; - while ($power <= $max_power) { - if (! defined $fragment_count[$power]) { - $fragment_count[$power] = $fragment_tally[$power] = 0; - } - printf " %.1f:", $bucket_size; - print $fragment_count[$power]; - $power++; - $bucket_size *= $::opt_fragment; - } - print "\n"; - - print "Summary gap analysis:\n"; - - $power = 0; - $bucket_size = 1; - my $tally = 0; - my $count = 0; - while ($power <= $max_power) { - $count += $fragment_count[$power]; - $tally += $fragment_tally[$power]; - print "$count gaps, totaling $tally bytes, were under "; - printf "%.1f bytes each", $bucket_size; - if ($count) { - printf ", for an average of %.1f bytes per gap", $tally/$count, ; - } - print "\n"; - $power++; - $bucket_size *= $::opt_fragment; - } - - print "Total allocation was $tally_sizes bytes, or "; - printf "%.0f bytes per allocation block\n\n", $tally_sizes/($count+1); - -} - -#---------------------------------------------------------------------- -# -# Now thread the parents and children together by looking through the -# slots for each object. -# -sub create_parent_links(){ - my $min_addr = $::SortedAddresses[0]; - my $max_addr = $::SortedAddresses[ $#::SortedAddresses]; #allow one beyond each object - $max_addr += $::Objects{$max_addr}->{'size'}; - - print "Viable addresses range from $min_addr to $max_addr for a total of ", - $max_addr-$min_addr, " bytes\n\n"; - - # Gather stats as we try to convert slots to children - my $slot_count = 0; # total slots examined - my $fixed_addr_count = 0; # slots into interiors that were adjusted - my $parent_child_count = 0; # Number of parent-child links - my $child_count = 0; # valid slots, discounting sibling twins - my $child_dup_count = 0; # number of duplicate child pointers - my $self_pointer_count = 0; # count of discarded self-pointers - - foreach my $parent (keys %::Objects) { - # We'll collect a list of this parent object's children - # by iterating through its slots. - my @children; - my %children_hash; - my $self_pointer = 0; - - my @slots = @{$::Objects{$parent}->{'slots'}}; - $slot_count += $#slots + 1; - SLOT: foreach my $child (@slots) { - - # We only care about pointers that refer to other objects - if (! defined $::Objects{$child}) { - # check to see if we are an interior pointer - - # Punt if we are completely out of range - next SLOT unless ($max_addr >= $child && - $child >= $min_addr); - - # Do binary search to find object below this address - my ($min_index, $beyond_index) = (0, $#::SortedAddresses + 1); - my $test_index; - while ($min_index != - ($test_index = int (($beyond_index+$min_index)/2))) { - if ($child >= $::SortedAddresses[$test_index]) { - $min_index = $test_index; - } else { - $beyond_index = $test_index; - } - } - # See if pointer is within extent of this object - my $address = $::SortedAddresses[$test_index]; - next SLOT unless ($child < - $address + $::Objects{$address}->{'size'}); - - # Make adjustment so we point to the actual child precisely - $child = $address; - $fixed_addr_count++; - } - - if ($child == $parent) { - $self_pointer_count++; - next SLOT; # Discard self-pointers - } - - # Avoid creating duplicate child-parent links - if (! defined $children_hash{$child}) { - $parent_child_count++; - # Add the parent to the child's list of parents - my $parents = $::Objects{$child}->{'parents'}; - if (! $parents) { - $parents = $::Objects{$child}->{'parents'} = []; - } - - $parents->[scalar(@$parents)] = $parent; - - # Add the child to the parent's list of children - $children_hash{$child} = 1; - } else { - $child_dup_count++; - } - } - @children = keys %children_hash; - # Track tally of unique children linked - $child_count += $#children + 1; - - $::Objects{$parent}->{'children'} = \@children; - - if (! @children) { - $::Leafs[$#::Leafs + 1] = $parent; - } - } - print "Scanning $#::SortedAddresses objects, we found $parent_child_count parents-to-child connections by chasing $slot_count pointers.\n", - "This required $fixed_addr_count interior pointer fixups, skipping $child_dup_count duplicate pointers, ", - "and $self_pointer_count self pointers\nAlso discarded ", - $slot_count - $parent_child_count -$self_pointer_count - $child_dup_count, - " out-of-range pointers\n\n"; -} - - -#---------------------------------------------------------------------- -# For every leaf, if a leaf has only one parent, then sweep the memory -# cost into the parent from the leaf -sub sweep_leaf_memory () { - my $sweep_count = 0; - my $leaf_counter = 0; - LEAF: while ($leaf_counter <= $#::Leafs) { - my $leaf_addr = $::Leafs[$leaf_counter++]; - my $leaf_obj = $::Objects{$leaf_addr}; - my $parents = $leaf_obj->{'parents'}; - - next LEAF if (! defined($parents) || 1 != scalar(@$parents)); - - # We have only one parent, so we'll try to sweep upwards - my $parent_addr = @$parents[0]; - my $parent_obj = $::Objects{$parent_addr}; - - # watch out for self-pointers - next LEAF if ($parent_addr == $leaf_addr); - - if ($::opt_detail) { - foreach my $obj ($parent_obj, $leaf_obj) { - if (!defined $obj->{'original_size'}) { - $obj->{'original_size'} = $obj->{'size'}; - } - } - if (defined $leaf_obj->{'sweep_details'}) { - if (defined $parent_obj->{'sweep_details'}) { # merge details - foreach my $swept_obj (keys (%{$leaf_obj->{'sweep_details'}})) { - %{$parent_obj->{'sweep_details'}}->{$swept_obj} = - %{$leaf_obj->{'sweep_details'}}->{$swept_obj}; - } - } else { # No parent info - $parent_obj->{'sweep_details'} = \%{$leaf_obj->{'sweep_details'}}; - } - delete $leaf_obj->{'sweep_details'}; - } else { # no leaf detail - if (!defined $parent_obj->{'sweep_details'}) { - $parent_obj->{'sweep_details'} = {}; - } - } - %{$parent_obj->{'sweep_details'}}->{$leaf_addr} = $leaf_obj->{'original_size'}; - } - - $parent_obj->{'size'} += $leaf_obj->{'size'}; - $leaf_obj->{'size'} = 0; - - if (defined ($leaf_obj->{'swept_in'})) { - $parent_obj->{'swept_in'} += $leaf_obj->{'swept_in'}; - $leaf_obj->{'swept_in'} = 0; # sweep has been handed off to parent - } - $parent_obj->{'swept_in'} ++; # tally swept in leaf_obj - - $sweep_count++; - - # See if we created another leaf - my $consumed_children = $parent_obj->{'consumed'}++; - my @children = $parent_obj->{'children'}; - if ($consumed_children == $#children) { - $::Leafs[$#::Leafs + 1] = @$parents[0]; - } - } - print "Processed ", $leaf_counter, " leaves sweeping memory to parents in ", $sweep_count, " objects\n"; -} - - -#---------------------------------------------------------------------- -# -# Subdivide the types of objects that are in our "expand" list -# List types that should be sub-divided based on parents, and possibly -# children -# The argument supplied is a hash table with keys selecting types that -# need to be "refined" by including the types of the parent objects, -# and (when we are desparate) the types of the children objects. - -sub expand_type_names($) { - my %TypeExpand = %{$_[0]}; - - my @retype; # array of addrs that get extended type names - foreach my $child (keys %::Objects) { - my $child_obj = $::Objects{$child}; - next unless (defined ($TypeExpand{$child_obj->{'type'}})); - - foreach my $relation ('parents','children') { - my $relatives = $child_obj->{$relation}; - next unless defined @$relatives; - - # Sort out the names of the types of the relatives - my %names; - foreach my $relative (@$relatives) { - %names->{$::Objects{$relative}->{'type'}} = 1; - } - my $related_type_names = join(',' , sort(keys(%names))); - - - $child_obj->{'name' . $relation} = $related_type_names; - - # Don't bother with children if we have significant parent types - last if (!defined ($TypeExpand{$related_type_names})); - } - $retype[$#retype + 1] = $child; - } - - # Revisit all addresses we've marked - foreach my $child (@retype) { - my $child_obj = $::Objects{$child}; - $child_obj->{'type'} = $TypeExpand{$child_obj->{'type'}}; - my $extended_type = $child_obj->{'namechildren'}; - if (defined $extended_type) { - $child_obj->{'type'}.= "->(" . $extended_type . ")"; - delete ($child_obj->{'namechildren'}); - } - $extended_type = $child_obj->{'nameparents'}; - if (defined $extended_type) { - $child_obj->{'type'} = "(" . $extended_type . ")->" . $::Objects{$child}->{'type'}; - delete ($child_obj->{'nameparents'}); - } - } -} - -#---------------------------------------------------------------------- -# -# Print out a type histogram - -sub print_type_histogram() { - load_type_table(); - print_type_table(); - print "\n\n"; -} - - -#---------------------------------------------------------------------- -# Provide a nice summary of the types during the process -validate_address_ranges(); -create_parent_links(); - -print "\nBasic memory use histogram is:\n"; -print_type_histogram(); - -generate_and_print_unused_memory_histogram(); - -sweep_leaf_memory (); -print "After doing basic leaf-sweep processing of instances:\n"; -print_type_histogram(); - -{ - foreach my $typename (@::opt_typedivide) { - my %expansion_table; - $expansion_table{$typename} = $typename; - expand_type_names(\%expansion_table); - print "After subdividing <$typename> based on inbound (and somtimes outbound) pointers:\n"; - print_type_histogram(); - } -} - -exit(); # Don't bother with SCCs yet. - - -#---------------------------------------------------------------------- -# -# Determine objects that entrain equivalent sets, using the strongly -# connected component algorithm from Cormen, Leiserson, and Rivest, -# ``An Introduction to Algorithms'', MIT Press 1990, pp. 488-493. -# -sub compute_post_order($$$) { -# This routine produces a post-order of the call graph (what CLR call -# ``ordering the nodes by f[u]'') - my ($parent, $visited, $finish) = @_; - - # Bail if we've already seen this node - return if $visited->{$parent}; - - # We have now! - $visited->{$parent} = 1; - - # Walk the children - my $children = $::Objects{$parent}->{'children'}; - - foreach my $child (@$children) { - compute_post_order($child, $visited, $finish); - } - - # Now that we've walked all the kids, we can append the parent to - # the post-order - @$finish[scalar(@$finish)] = $parent; -} - -sub compute_equivalencies($$$) { -# This routine recursively computes equivalencies by walking the -# transpose of the callgraph. - my ($child, $table, $equivalencies) = @_; - - # Bail if we've already seen this node - return if $table->{$child}; - - # Otherwise, append ourself to the list of equivalencies... - @$equivalencies[scalar(@$equivalencies)] = $child; - - # ...and note our other equivalents in the table - $table->{$child} = $equivalencies; - - my $parents = $::Objects{$child}->{'parents'}; - - foreach my $parent (@$parents) { - compute_equivalencies($parent, $table, $equivalencies); - } -} - -sub compute_equivalents() { -# Here's the strongly connected components algorithm. (Step 2 has been -# done implictly by our object graph construction.) - my %visited; - my @finish; - - # Step 1. Compute a post-ordering of the object graph - foreach my $parent (keys %::Objects) { - compute_post_order($parent, \%visited, \@finish); - } - - # Step 3. Traverse the transpose of the object graph in reverse - # post-order, collecting vertices into %equivalents - my %equivalents; - foreach my $child (reverse @finish) { - compute_equivalencies($child, \%equivalents, []); - } - - # Now, we'll trim the %equivalents table, arbitrarily removing - # ``redundant'' entries. - EQUIVALENT: foreach my $node (keys %equivalents) { - my $equivalencies = $equivalents{$node}; - next EQUIVALENT unless $equivalencies; - - foreach my $equivalent (@$equivalencies) { - delete $equivalents{$equivalent} unless $equivalent == $node; - } - } - - # Note the equivalent objects in a way that will yield the most - # interesting order as we do depth-first traversal later to - # output them. - ROOT: foreach my $equivalent (reverse @finish) { - next ROOT unless $equivalents{$equivalent}; - $::Equivalents[$#::Equivalents + 1] = $equivalent; - - # XXX Lame! Should figure out function refs. - $::Objects{$equivalent}->{'entrained-size'} = 0; - } -} - -# Do it! -compute_equivalents(); - - -#---------------------------------------------------------------------- -# -# Compute the size of each node's transitive closure. -# -sub compute_entrained($$) { - my ($parent, $visited) = @_; - - $visited->{$parent} = 1; - - $::Objects{$parent}->{'entrained-size'} = $::Objects{$parent}->{'size'}; - - my $children = $::Objects{$parent}->{'children'}; - CHILD: foreach my $child (@$children) { - next CHILD if $visited->{$child}; - - compute_entrained($child, $visited); - $::Objects{$parent}->{'entrained-size'} += $::Objects{$child}->{'entrained-size'}; - } -} - -if (! $::opt_noentrained) { - my %visited; - - PARENT: foreach my $parent (@::Equivalents) { - next PARENT if $visited{$parent}; - compute_entrained($parent, \%visited); - } -} - - -#---------------------------------------------------------------------- -# -# Converts a shared library and an address into a file and line number -# using a bunch of addr2line processes. -# -sub addr2line($$) { - my ($dso, $addr) = @_; - - # $::Addr2Lines is a global table that maps a DSO's name to a pair - # of filehandles that are talking to an addr2line process. - my $fhs = $::Addr2Lines{$dso}; - if (! $fhs) { - if (!(-r $dso)) { - # bogus filename (that happens sometimes), so bail - return { 'dso' => $dso, 'addr' => $addr }; - } - my ($in, $out) = (new FileHandle, new FileHandle); - open2($in, $out, "addr2line --exe=$dso") || die "unable to open addr2line --exe=$dso"; - $::Addr2Lines{$dso} = $fhs = { 'in' => $in, 'out' => $out }; - } - - # addr2line takes a hex address as input... - $fhs->{'out'}->print($addr . "\n"); - - # ...and'll return file:lineno as output - if ($fhs->{'in'}->getline() =~ /([^:]+):(.+)/) { - return { 'file' => $1, 'line' => $2 }; - } - else { - return { 'dso' => $dso, 'addr' => $addr }; - } -} - - -#---------------------------------------------------------------------- -# -# Dump the objects, using a depth-first traversal. -# -sub dump_objects($$$) { - my ($parent, $visited, $depth) = @_; - - # Have we already seen this? - my $already_visited = $visited->{$parent}; - return if ($depth == 0 && $already_visited); - - if (! $already_visited) { - $visited->{$parent} = 1; - $::Total += $::Objects{$parent}->{'size'}; - } - - my $parententry = $::Objects{$parent}; - - # Make an ``object'' div, which'll contain an ``object'' span, two - # ``toggle'' spans, an invisible ``stack'' div, and the invisible - # ``children'' div. - print "
"; - - if ($already_visited) { - print ""; - } - else { - print ""; - } - - printf "0x%x<%s>[%d]", $parent, $parententry->{'type'}, $parententry->{'size'}; - - if ($already_visited) { - print ""; - goto DONE; - } - - if ($depth == 0) { - print "($parententry->{'entrained-size'})" - if $parententry->{'entrained-size'}; - - print " Children" - if @{$parententry->{'children'}} > 0; - } - - if (($depth == 0 || !$::opt_nochildstacks) && !$::opt_nostacks) { - print " Stack"; - } - - print ""; - - # Print stack traces - print "
\n"; - - if (($depth == 0 || !$::opt_nochildstacks) && !$::opt_nostacks) { - my $depth = $::opt_depth; - - FRAME: foreach my $frame (@{$parententry->{'stack'}}) { - # Only go as deep as they've asked us to. - last FRAME unless --$depth >= 0; - - # Stack frames look like ``mangled_name[dso address]'' - $frame =~ /([^\]]+)\[(.*) \+0x([0-9A-Fa-f]+)\]/; - - # Convert address to file and line number - my $mangled = $1; - my $result = addr2line($2, $3); - - if ($result->{'file'}) { - # It's mozilla source! Clean up refs to dist/include - if (($result->{'file'} =~ s/.*\.\.\/\.\.\/dist\/include\//http:\/\/bonsai.mozilla.org\/cvsguess.cgi\?file=/) || - ($result->{'file'} =~ s/.*\/mozilla/http:\/\/bonsai.mozilla.org\/cvsblame.cgi\?file=mozilla/)) { - my $prevline = $result->{'line'} - 10; - print "{'file'}\&mark=$result->{'line'}#$prevline\">$mangled
\n"; - } - else { - print "$mangled ($result->{'file'}, line $result->{'line'})
\n"; - } - } - else { - print "$result->{'dso'} ($result->{'addr'})
\n"; - } - } - - } - - print "
"; - - # Recurse to children - if (@{$parententry->{'children'}} >= 0) { - print "
\n" if $depth == 0; - - foreach my $child (@{$parententry->{'children'}}) { - dump_objects($child, $visited, $depth + 1); - } - - print "
" if $depth == 0; - } - - DONE: - print "
\n"; -} - - -#---------------------------------------------------------------------- -# -# Do the output. -# - -# Force flush on STDOUT. We get funky output unless we do this. -$| = 1; - -# Header -print " - -Object Graph - - - - -"; - -{ -# Body. Display ``roots'', sorted by the amount of memory they -# entrain. Because of the way we've sorted @::Equivalents, we should -# get a nice ordering that sorts things with a lot of kids early -# on. This should yield a fairly "deep" depth-first traversal, with -# most of the objects appearing as children. -# -# XXX I sure hope that Perl implements a stable sort! - my %visited; - - foreach my $parent (sort { $::Objects{$b}->{'entrained-size'} - <=> $::Objects{$a}->{'entrained-size'} } - @::Equivalents) { - dump_objects($parent, \%visited, 0); - print "\n"; - } -} - -# Footer -print "
$::Total total bytes\n" if $::Total; -print " - -"; - diff --git a/tools/trace-malloc/leaksoup.cpp b/tools/trace-malloc/leaksoup.cpp deleted file mode 100644 index c555bd585152..000000000000 --- a/tools/trace-malloc/leaksoup.cpp +++ /dev/null @@ -1,416 +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 "adreader.h" - -#include -#include "plhash.h" - -#include "nsTArray.h" -#include "nsQuickSort.h" -#include "nsXPCOM.h" - -const uint32_t kPointersDefaultSize = 8; - -/* - * Read in an allocation dump, presumably one taken at shutdown (using - * the --shutdown-leaks=file option, which must be used along with - * --trace-malloc=tmlog), and treat the memory in the dump as leaks. - * Find the leak roots, including cycles that are roots, by finding the - * strongly connected components in the graph. Print output to stdout - * as HTML. - */ - -struct AllocationNode { - const ADLog::Entry *entry; - - // Other |AllocationNode| objects whose memory has a pointer to - // this object. - nsAutoTArray pointers_to; - - // The reverse. - nsAutoTArray pointers_from; - - // Early on in the algorithm, the pre-order index from a DFS. - // Later on, set to the index of the strongly connected component to - // which this node belongs. - uint32_t index; - - bool reached; - bool is_root; -}; - -static PLHashNumber hash_pointer(const void *key) -{ - return (PLHashNumber) NS_PTR_TO_INT32(key); -} - -static int sort_by_index(const void* e1, const void* e2, void*) -{ - const AllocationNode *n1 = *static_cast(e1); - const AllocationNode *n2 = *static_cast(e2); - return n1->index - n2->index; -} - -static int sort_by_reverse_index(const void* e1, const void* e2, void*) -{ - const AllocationNode *n1 = *static_cast(e1); - const AllocationNode *n2 = *static_cast(e2); - return n2->index - n1->index; -} - -static void print_escaped(FILE *aStream, const char* aData) -{ - char c; - char buf[1000]; - char *p = buf; - while ((c = *aData++)) { - switch (c) { -#define CH(char) *p++ = char - case '<': - CH('&'); CH('l'); CH('t'); CH(';'); - break; - case '>': - CH('&'); CH('g'); CH('t'); CH(';'); - break; - case '&': - CH('&'); CH('a'); CH('m'); CH('p'); CH(';'); - break; - default: - CH(c); - break; -#undef CH - } - if (p + 10 > buf + sizeof(buf)) { - *p = '\0'; - fputs(buf, aStream); - p = buf; - } - } - *p = '\0'; - fputs(buf, aStream); -} - -static const char *allocation_format = - (sizeof(ADLog::Pointer) == 4) ? "0x%08zX" : - (sizeof(ADLog::Pointer) == 8) ? "0x%016zX" : - "UNEXPECTED sizeof(void*)"; - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, - "Expected usage: %s \n" - " sd-leak-file: Output of --shutdown-leaks= option.\n", - argv[0]); - return 1; - } - - NS_InitXPCOM2(nullptr, nullptr, nullptr); - - ADLog log; - if (!log.Read(argv[1])) { - fprintf(stderr, - "%s: Error reading input file %s.\n", argv[0], argv[1]); - } - - const size_t count = log.count(); - - PLHashTable *memory_map = - PL_NewHashTable(count * 8, hash_pointer, PL_CompareValues, - PL_CompareValues, 0, 0); - if (!memory_map) { - fprintf(stderr, "%s: Out of memory.\n", argv[0]); - return 1; - } - - // Create one |AllocationNode| object for each log entry, and create - // entries in the hashtable pointing to it for each byte it occupies. - AllocationNode *nodes = new AllocationNode[count]; - if (!nodes) { - fprintf(stderr, "%s: Out of memory.\n", argv[0]); - return 1; - } - - { - AllocationNode *cur_node = nodes; - for (ADLog::const_iterator entry = log.begin(), entry_end = log.end(); - entry != entry_end; ++entry, ++cur_node) { - const ADLog::Entry *e = cur_node->entry = *entry; - cur_node->reached = false; - - for (ADLog::Pointer p = e->address, - p_end = e->address + e->datasize; - p != p_end; ++p) { - PLHashEntry *he = PL_HashTableAdd(memory_map, p, cur_node); - if (!he) { - fprintf(stderr, "%s: Out of memory.\n", argv[0]); - return 1; - } - } - } - } - - // Construct graph based on pointers. - for (AllocationNode *node = nodes, *node_end = nodes + count; - node != node_end; ++node) { - const ADLog::Entry *e = node->entry; - for (const char *d = e->data, *d_end = e->data + e->datasize - - e->datasize % sizeof(ADLog::Pointer); - d != d_end; d += sizeof(ADLog::Pointer)) { - AllocationNode *target = (AllocationNode*) - PL_HashTableLookup(memory_map, *(void**)d); - if (target) { - target->pointers_from.AppendElement(node); - node->pointers_to.AppendElement(target); - } - } - } - - // Do a depth-first search on the graph (i.e., by following - // |pointers_to|) and assign the post-order index to |index|. - { - uint32_t dfs_index = 0; - nsTArray stack; - - for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) { - if (n->reached) { - continue; - } - stack.AppendElement(n); - - do { - uint32_t pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; - if (n->reached) { - n->index = dfs_index++; - stack.RemoveElementAt(pos); - } else { - n->reached = true; - - // When doing post-order processing, we have to be - // careful not to put reached nodes into the stack. - for (int32_t i = n->pointers_to.Length() - 1; i >= 0; --i) { - AllocationNode* e = n->pointers_to[i]; - if (!e->reached) { - stack.AppendElement(e); - } - } - } - } while (stack.Length() > 0); - } - } - - // Sort the nodes by their DFS index, in reverse, so that the first - // node is guaranteed to be in a root SCC. - AllocationNode **sorted_nodes = new AllocationNode*[count]; - if (!sorted_nodes) { - fprintf(stderr, "%s: Out of memory.\n", argv[0]); - return 1; - } - - { - for (size_t i = 0; i < count; ++i) { - sorted_nodes[i] = nodes + i; - } - NS_QuickSort(sorted_nodes, count, sizeof(AllocationNode*), - sort_by_reverse_index, 0); - } - - // Put the nodes into their strongly-connected components. - uint32_t num_sccs = 0; - { - for (size_t i = 0; i < count; ++i) { - nodes[i].reached = false; - } - nsTArray stack; - for (AllocationNode **sn = sorted_nodes, - **sn_end = sorted_nodes + count; sn != sn_end; ++sn) { - if ((*sn)->reached) { - continue; - } - - // We found a new strongly connected index. - stack.AppendElement(*sn); - do { - uint32_t pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; - stack.RemoveElementAt(pos); - - if (!n->reached) { - n->reached = true; - n->index = num_sccs; - stack.AppendElements(n->pointers_from); - } - } while (stack.Length() > 0); - ++num_sccs; - } - } - - // Identify which nodes are leak roots by using DFS, and watching - // for component transitions. - uint32_t num_root_nodes = count; - { - for (size_t i = 0; i < count; ++i) { - nodes[i].is_root = true; - } - - nsTArray stack; - for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) { - if (!n->is_root) { - continue; - } - - // Loop through pointers_to, and add any that are in a - // different SCC to stack: - for (int i = n->pointers_to.Length() - 1; i >= 0; --i) { - AllocationNode *target = n->pointers_to[i]; - if (n->index != target->index) { - stack.AppendElement(target); - } - } - - while (stack.Length() > 0) { - uint32_t pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; - stack.RemoveElementAt(pos); - - if (n->is_root) { - n->is_root = false; - --num_root_nodes; - stack.AppendElements(n->pointers_to); - } - } - } - } - - // Sort the nodes by their SCC index. - NS_QuickSort(sorted_nodes, count, sizeof(AllocationNode*), - sort_by_index, 0); - - // Print output. - { - printf("\n" - "\n" - "\n" - "Leak analysis\n" - "\n" - "\n"); - printf("\n\n" - "

Generated %zd entries (%d in root SCCs) and %d SCCs.

\n\n", - count, num_root_nodes, num_sccs); - - for (size_t i = 0; i < count; ++i) { - nodes[i].reached = false; - } - - // Loop over the sorted nodes twice, first printing the roots - // and then the non-roots. - for (int32_t root_type = true; - root_type == true || root_type == false; --root_type) { - if (root_type) { - printf("\n\n" - "
\n" - "

Root components

\n"); - } else { - printf("\n\n" - "
\n" - "

Non-root components

\n"); - } - uint32_t component = (uint32_t)-1; - bool one_object_component; - for (const AllocationNode *const* sn = sorted_nodes, - *const* sn_end = sorted_nodes + count; - sn != sn_end; ++sn) { - const AllocationNode *n = *sn; - if (n->is_root != root_type) - continue; - const ADLog::Entry *e = n->entry; - - if (n->index != component) { - component = n->index; - one_object_component = - sn + 1 == sn_end || (*(sn+1))->index != component; - if (!one_object_component) - printf("\n\n

Component %d

\n", - component, component); - } - - if (one_object_component) { - printf("\n\n
\n", component); - printf("

Object %td " - "(single-object component %d)

\n", - n-nodes, n-nodes, component); - } else { - printf("\n\n

Object %td

\n", - n-nodes, n-nodes); - } - printf("
\n");
-                printf("%p <%s> (%zd)\n",
-                       e->address, e->type, e->datasize);
-                for (size_t d = 0; d < e->datasize;
-                     d += sizeof(ADLog::Pointer)) {
-                    AllocationNode *target = (AllocationNode*)
-                        PL_HashTableLookup(memory_map, *(void**)(e->data + d));
-                    if (target) {
-                        printf("        ",
-                               target - nodes);
-                        printf(allocation_format,
-                               *(size_t*)(e->data + d));
-                        printf(" <%s>",
-                               target->entry->type);
-                        if (target->index != n->index) {
-                            printf(", component %d", target->index);
-                        }
-                        printf("\n");
-                    } else {
-                        printf("        ");
-                        printf(allocation_format,
-                               *(size_t*)(e->data + d));
-                        printf("\n");
-                    }
-                }
-
-                if (n->pointers_from.Length()) {
-                    printf("\nPointers from:\n");
-                    for (uint32_t i = 0, i_end = n->pointers_from.Length();
-                         i != i_end; ++i) {
-                        AllocationNode *t = n->pointers_from[i];
-                        const ADLog::Entry *te = t->entry;
-                        printf("    %s (Object %td, ",
-                               t - nodes, te->type, t - nodes);
-                        if (t->index != n->index) {
-                            printf("component %d, ", t->index);
-                        }
-                        if (t == n) {
-                            printf("self)\n");
-                        } else {
-                            printf("%p)\n", te->address);
-                        }
-                    }
-                }
-
-                print_escaped(stdout, e->allocation_stack);
-
-                printf("
\n"); - if (one_object_component) { - printf("
\n"); - } - } - printf("
\n"); - } - printf("\n" - "\n"); - } - - delete [] sorted_nodes; - delete [] nodes; - - NS_ShutdownXPCOM(nullptr); - - return 0; -} diff --git a/tools/trace-malloc/leakstats.c b/tools/trace-malloc/leakstats.c deleted file mode 100644 index 4291e104e066..000000000000 --- a/tools/trace-malloc/leakstats.c +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#ifdef HAVE_GETOPT_H -#include -#else -extern int getopt(int argc, char *const *argv, const char *shortopts); -extern char *optarg; -extern int optind; -#ifdef XP_WIN32 -int optind=1; -#endif -#endif -#include -#include "nsTraceMalloc.h" -#include "tmreader.h" -#include "prlog.h" - -static char *program; - -typedef struct handler_data { - uint32_t current_heapsize; - uint32_t max_heapsize; - uint32_t bytes_allocated; - uint32_t current_allocations; - uint32_t total_allocations; - uint32_t unmatched_frees; - int finished; -} handler_data; - -static void handler_data_init(handler_data *data) -{ - data->current_heapsize = 0; - data->max_heapsize = 0; - data->bytes_allocated = 0; - data->current_allocations = 0; - data->total_allocations = 0; - data->unmatched_frees = 0; - data->finished = 0; -} - -static void handler_data_finish(handler_data *data) -{ -} - -static void my_tmevent_handler(tmreader *tmr, tmevent *event) -{ - handler_data *data = (handler_data*) tmr->data; - - switch (event->type) { - case TM_EVENT_REALLOC: - /* On Windows, original allocation could be before we overrode malloc */ - if (event->u.alloc.oldserial != 0) { - data->current_heapsize -= event->u.alloc.oldsize; - --data->current_allocations; - } else { - ++data->unmatched_frees; - PR_ASSERT(event->u.alloc.oldsize == 0); - } - /* fall-through intentional */ - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - ++data->current_allocations; - ++data->total_allocations; - data->bytes_allocated += event->u.alloc.size; - data->current_heapsize += event->u.alloc.size; - if (data->current_heapsize > data->max_heapsize) - data->max_heapsize = data->current_heapsize; - break; - case TM_EVENT_FREE: - /* On Windows, original allocation could be before we overrode malloc */ - if (event->serial != 0) { - --data->current_allocations; - data->current_heapsize -= event->u.alloc.size; - } else { - ++data->unmatched_frees; - PR_ASSERT(event->u.alloc.size == 0); - } - break; - case TM_EVENT_STATS: - data->finished = 1; - break; - } -} - - -int main(int argc, char **argv) -{ - int i, j, rv; - tmreader *tmr; - FILE *fp; - time_t start; - handler_data data; - - program = *argv; - - handler_data_init(&data); - tmr = tmreader_new(program, &data); - if (!tmr) { - perror(program); - exit(1); - } - - start = time(NULL); - fprintf(stdout, "%s starting at %s", program, ctime(&start)); - fflush(stdout); - - argc -= optind; - argv += optind; - if (argc == 0) { - if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0) - exit(1); - } else { - for (i = j = 0; i < argc; i++) { - fp = fopen(argv[i], "r"); - if (!fp) { - fprintf(stderr, - "TEST-UNEXPECTED-FAIL | leakstats | can't open %s: %s\n", - argv[i], strerror(errno)); - exit(1); - } - rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler); - if (rv < 0) - exit(1); - if (rv > 0) - j++; - fclose(fp); - } - if (j == 0) - exit(1); - } - - if (!data.finished) { - fprintf(stderr, "TEST-UNEXPECTED-FAIL | leakstats | log file incomplete\n"); - exit(1); - } - - fprintf(stdout, - "Leaks: %u bytes, %u allocations\n" - "Maximum Heap Size: %u bytes\n" - "%u bytes were allocated in %u allocations.\n", - data.current_heapsize, data.current_allocations, - data.max_heapsize, - data.bytes_allocated, data.total_allocations); - if (data.unmatched_frees != 0) - fprintf(stdout, - "Logged %u free (or realloc) calls for which we missed the " - "original malloc.\n", - data.unmatched_frees); - - handler_data_finish(&data); - tmreader_destroy(tmr); - - exit(0); -} diff --git a/tools/trace-malloc/lib/moz.build b/tools/trace-malloc/lib/moz.build deleted file mode 100644 index 281c9beb39f1..000000000000 --- a/tools/trace-malloc/lib/moz.build +++ /dev/null @@ -1,34 +0,0 @@ -# -*- 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/. - -EXPORTS += [ - 'nsTraceMalloc.h', -] - -SOURCES += [ - 'nsTraceMalloc.c', -] - -SOURCES += [ - 'nsTypeInfo.cpp', -] - -if CONFIG['OS_ARCH'] == 'WINNT': - SOURCES += [ - 'nsDebugHelpWin32.cpp', - 'nsWinTraceMalloc.cpp', - ] - -FINAL_LIBRARY = 'xul' - -if CONFIG['WRAP_SYSTEM_INCLUDES']: - DEFINES['WRAP_SYSTEM_INCLUDES'] = True - -DEFINES['MOZ_NO_MOZALLOC'] = True - -DEFFILE = SRCDIR + '/tm.def' - -DISABLE_STL_WRAPPING = True diff --git a/tools/trace-malloc/lib/nsDebugHelpWin32.cpp b/tools/trace-malloc/lib/nsDebugHelpWin32.cpp deleted file mode 100644 index 5aa11920ccf9..000000000000 --- a/tools/trace-malloc/lib/nsDebugHelpWin32.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - - -#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) -// This is the .cpp file where the globals live -#define DHW_IMPLEMENT_GLOBALS -#include -#include "prprf.h" -#include "prlog.h" -#include "plstr.h" -#include "prlock.h" -#include "nscore.h" -#include "nsDebugHelpWin32.h" -#else -#error "nsDebugHelpWin32.cpp should only be built in Win32 x86/x64 builds" -#endif - - - -/***************************************************************************/ - - -PRLock* DHWImportHooker::gLock = nullptr; -DHWImportHooker* DHWImportHooker::gHooks = nullptr; -decltype(GetProcAddress)* DHWImportHooker::gRealGetProcAddress = nullptr; - - -static bool -dhwEnsureImageHlpInitialized() -{ - static bool gInitialized = false; - static bool gTried = false; - - if (!gInitialized && !gTried) { - gTried = true; - HMODULE module = ::LoadLibrary("DBGHELP.DLL"); - if (!module) { - DWORD dw = GetLastError(); - printf("DumpStack Error: DBGHELP.DLL wasn't found. GetLastError() returned 0x%8.8X\n" - " This DLL is needed for succeessfully implementing trace-malloc.\n" - " This dll ships by default on Win2k. Disabling trace-malloc functionality.\n" - , dw); - return false; - } - -#define INIT_PROC(typename_, name_) \ - dhw##name_ = (decltype(name_)*) ::GetProcAddress(module, #name_); \ - if(!dhw##name_) return false; - -#ifdef _WIN64 - INIT_PROC(ENUMERATELOADEDMODULES64, EnumerateLoadedModules64); -#else - INIT_PROC(ENUMERATELOADEDMODULES, EnumerateLoadedModules); -#endif - INIT_PROC(IMAGEDIRECTORYENTRYTODATA, ImageDirectoryEntryToData); - -#undef INIT_PROC - - gInitialized = true; - } - - return gInitialized; -} - - -DHWImportHooker& -DHWImportHooker::getGetProcAddressHooker() -{ - static DHWImportHooker gGetProcAddress("Kernel32.dll", "GetProcAddress", - (PROC)DHWImportHooker::GetProcAddress); - return gGetProcAddress; -} - - -DHWImportHooker& -DHWImportHooker::getLoadLibraryWHooker() -{ - static DHWImportHooker gLoadLibraryW("Kernel32.dll", "LoadLibraryW", - (PROC)DHWImportHooker::LoadLibraryW); - return gLoadLibraryW; -} - -DHWImportHooker& -DHWImportHooker::getLoadLibraryExWHooker() -{ - static DHWImportHooker gLoadLibraryExW("Kernel32.dll", "LoadLibraryExW", - (PROC)DHWImportHooker::LoadLibraryExW); - return gLoadLibraryExW; -} - -DHWImportHooker& -DHWImportHooker::getLoadLibraryAHooker() -{ - static DHWImportHooker gLoadLibraryA("Kernel32.dll", "LoadLibraryA", - (PROC)DHWImportHooker::LoadLibraryA); - return gLoadLibraryA; -} - -DHWImportHooker& -DHWImportHooker::getLoadLibraryExAHooker() -{ - static DHWImportHooker gLoadLibraryExA("Kernel32.dll", "LoadLibraryExA", - (PROC)DHWImportHooker::LoadLibraryExA); - return gLoadLibraryExA; -} - - -static HMODULE ThisModule() -{ - MEMORY_BASIC_INFORMATION info; - return VirtualQuery(ThisModule, &info, sizeof(info)) ? - (HMODULE) info.AllocationBase : nullptr; -} - -DHWImportHooker::DHWImportHooker(const char* aModuleName, - const char* aFunctionName, - PROC aHook, - bool aExcludeOurModule /* = false */) - : mNext(nullptr), - mModuleName(aModuleName), - mFunctionName(aFunctionName), - mOriginal(nullptr), - mHook(aHook), - mIgnoreModule(aExcludeOurModule ? ThisModule() : nullptr), - mHooking(true) -{ - //printf("DHWImportHooker hooking %s, function %s\n",aModuleName, aFunctionName); - - if(!gLock) - gLock = PR_NewLock(); - PR_Lock(gLock); - - dhwEnsureImageHlpInitialized(); // for the extra ones we care about. - - if(!gRealGetProcAddress) - gRealGetProcAddress = ::GetProcAddress; - - mOriginal = gRealGetProcAddress(::GetModuleHandleA(aModuleName), - aFunctionName), - - mNext = gHooks; - gHooks = this; - - PatchAllModules(); - - PR_Unlock(gLock); -} - -DHWImportHooker::~DHWImportHooker() -{ - PR_Lock(gLock); - - mHooking = false; - PatchAllModules(); - - for (DHWImportHooker **cur = &gHooks; - (PR_ASSERT(*cur), *cur); /* assert that we find this */ - cur = &(*cur)->mNext) - { - if (*cur == this) - { - *cur = mNext; - break; - } - } - - if(!gHooks) - { - PRLock* theLock = gLock; - gLock = nullptr; - PR_Unlock(theLock); - PR_DestroyLock(theLock); - } - if (gLock) - PR_Unlock(gLock); -} - -#ifdef _WIN64 -static BOOL CALLBACK ModuleEnumCallback(PCSTR ModuleName, - DWORD64 ModuleBase, - ULONG ModuleSize, - PVOID UserContext) -#else -static BOOL CALLBACK ModuleEnumCallback(PCSTR ModuleName, - ULONG ModuleBase, - ULONG ModuleSize, - PVOID UserContext) -#endif -{ - //printf("Module Name %s\n",ModuleName); - DHWImportHooker* self = (DHWImportHooker*) UserContext; - HMODULE aModule = (HMODULE) ModuleBase; - return self->PatchOneModule(aModule, ModuleName); -} - -bool -DHWImportHooker::PatchAllModules() -{ - // Need to cast to PENUMLOADED_MODULES_CALLBACK because the - // constness of the first parameter of PENUMLOADED_MODULES_CALLBACK - // varies over SDK versions (from non-const to const over time). - // See bug 391848 and bug 415426. -#ifdef _WIN64 - return dhwEnumerateLoadedModules64(::GetCurrentProcess(), - (PENUMLOADED_MODULES_CALLBACK64)ModuleEnumCallback, this); -#else - return dhwEnumerateLoadedModules(::GetCurrentProcess(), - (PENUMLOADED_MODULES_CALLBACK)ModuleEnumCallback, this); -#endif -} - -bool -DHWImportHooker::PatchOneModule(HMODULE aModule, const char* name) -{ - if(aModule == mIgnoreModule) - { - return true; - } - - // do the fun stuff... - - PIMAGE_IMPORT_DESCRIPTOR desc; - ULONG size; - - desc = (PIMAGE_IMPORT_DESCRIPTOR) - dhwImageDirectoryEntryToData(aModule, true, - IMAGE_DIRECTORY_ENTRY_IMPORT, &size); - - if(!desc) - { - return true; - } - - for(; desc->Name; desc++) - { - const char* entryModuleName = (const char*) - ((char*)aModule + desc->Name); - if(!lstrcmpi(entryModuleName, mModuleName)) - break; - } - - if(!desc->Name) - { - return true; - } - - PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA) - ((char*) aModule + desc->FirstThunk); - - for(; thunk->u1.Function; thunk++) - { - PROC original; - PROC replacement; - - if(mHooking) - { - original = mOriginal; - replacement = mHook; - } - else - { - original = mHook; - replacement = mOriginal; - } - - PROC* ppfn = (PROC*) &thunk->u1.Function; - if(*ppfn == original) - { - DWORD dwDummy; - VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy); - BOOL result = WriteProcessMemory(GetCurrentProcess(), - ppfn, &replacement, sizeof(replacement), nullptr); - if (!result) //failure - { - printf("failure name %s func %x\n",name,*ppfn); - DWORD error = GetLastError(); - return true; - } - else - { - // printf("success name %s func %x\n",name,*ppfn); - DWORD filler = result+1; - return result; - } - } - - } - return true; -} - -bool -DHWImportHooker::ModuleLoaded(HMODULE aModule, DWORD flags) -{ - //printf("ModuleLoaded\n"); - if(aModule && !(flags & LOAD_LIBRARY_AS_DATAFILE)) - { - PR_Lock(gLock); - // We don't know that the newly loaded module didn't drag in implicitly - // linked modules, so we patch everything in sight. - for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext) - cur->PatchAllModules(); - PR_Unlock(gLock); - } - return true; -} - -// static -HMODULE WINAPI -DHWImportHooker::LoadLibraryW(PCWSTR path) -{ - //wprintf(L"LoadLibraryW %s\n",path); - HMODULE hmod = DHW_ORIGINAL(::LoadLibraryW, getLoadLibraryWHooker())(path); - ModuleLoaded(hmod, 0); - return hmod; -} - - -// static -HMODULE WINAPI -DHWImportHooker::LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags) -{ - //wprintf(L"LoadLibraryExW %s\n",path); - HMODULE hmod = DHW_ORIGINAL(::LoadLibraryExW, getLoadLibraryExWHooker())(path, file, flags); - ModuleLoaded(hmod, flags); - return hmod; -} - -// static -HMODULE WINAPI -DHWImportHooker::LoadLibraryA(PCSTR path) -{ - //printf("LoadLibraryA %s\n",path); - HMODULE hmod = DHW_ORIGINAL(::LoadLibraryA, getLoadLibraryAHooker())(path); - ModuleLoaded(hmod, 0); - return hmod; -} - -// static -HMODULE WINAPI -DHWImportHooker::LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags) -{ - //printf("LoadLibraryExA %s\n",path); - HMODULE hmod = DHW_ORIGINAL(::LoadLibraryExA, getLoadLibraryExAHooker())(path, file, flags); - ModuleLoaded(hmod, flags); - return hmod; -} -// static -FARPROC WINAPI -DHWImportHooker::GetProcAddress(HMODULE aModule, PCSTR aFunctionName) -{ - FARPROC pfn = gRealGetProcAddress(aModule, aFunctionName); - - if(pfn) - { - PR_Lock(gLock); - for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext) - { - if(pfn == cur->mOriginal) - { - pfn = cur->mHook; - break; - } - } - PR_Unlock(gLock); - } - return pfn; -} - - diff --git a/tools/trace-malloc/lib/nsDebugHelpWin32.h b/tools/trace-malloc/lib/nsDebugHelpWin32.h deleted file mode 100644 index eef1597b2034..000000000000 --- a/tools/trace-malloc/lib/nsDebugHelpWin32.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* Win32 x86/x64 code for stack walking, symbol resolution, and function hooking */ - -#ifndef __nsDebugHelpWin32_h__ -#define __nsDebugHelpWin32_h__ - -#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #include - #include - #include -#else - #error "nsDebugHelpWin32.h should only be included in Win32 x86/x64 builds" -#endif - -// XXX temporary hack... -//#include "hacky_defines.h" - - -/***************************************************************************/ -// useful macros... - -#ifdef DHW_IMPLEMENT_GLOBALS -#define DHW_DECLARE_FUN_GLOBAL(name_) decltype(name_)* dhw##name_ -#else -#define DHW_DECLARE_FUN_GLOBAL(name_) extern decltype(name_)* dhw##name_ -#endif - - -/**********************************************************/ -// This is used to get 'original' function addresses from DHWImportHooker. - -#define DHW_ORIGINAL(name_, hooker_) \ - ((decltype(name_)*) hooker_ . GetOriginalFunction()) - -/***************************************************************************/ -// Global declarations of entry points into ImgHelp functions - -#ifndef _WIN64 -DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules); -#else -DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules64); -#endif - -DHW_DECLARE_FUN_GLOBAL(ImageDirectoryEntryToData); - -/***************************************************************************/ - -extern bool -dhwEnsureImageHlpInitialized(); - -/***************************************************************************/ - -class DHWImportHooker -{ -public: - - DHWImportHooker(const char* aModuleName, - const char* aFunctionName, - PROC aHook, - bool aExcludeOurModule = false); - - ~DHWImportHooker(); - - PROC GetOriginalFunction() {return mOriginal;} - - bool PatchAllModules(); - bool PatchOneModule(HMODULE aModule, const char* name); - static bool ModuleLoaded(HMODULE aModule, DWORD flags); - - - // I think that these should be made not static members, but allocated - // things created in an explicit static 'init' method and cleaned up in - // an explicit static 'finish' method. This would allow the application - // to have proper lifetime control over all the hooks. - - static DHWImportHooker &getLoadLibraryWHooker(); - static DHWImportHooker &getLoadLibraryExWHooker(); - static DHWImportHooker &getLoadLibraryAHooker(); - static DHWImportHooker &getLoadLibraryExAHooker(); - static DHWImportHooker &getGetProcAddressHooker(); - - static HMODULE WINAPI LoadLibraryA(PCSTR path); - -private: - DHWImportHooker* mNext; - const char* mModuleName; - const char* mFunctionName; - PROC mOriginal; - PROC mHook; - HMODULE mIgnoreModule; - bool mHooking; - -private: - static PRLock* gLock; - static DHWImportHooker* gHooks; - static decltype(GetProcAddress)* gRealGetProcAddress; - - static HMODULE WINAPI LoadLibraryW(PCWSTR path); - static HMODULE WINAPI LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags); - static HMODULE WINAPI LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags); - - static FARPROC WINAPI GetProcAddress(HMODULE aModule, PCSTR aFunctionName); -}; - -/***************************************************************************/ -// This supports the _CrtSetAllocHook based hooking. -// This system sucks because you don't get to see the allocated pointer. I -// don't think it appropriate for nsTraceMalloc, but is useful as a means to make -// malloc fail for testing purposes. -#if 0 //comment out this stuff. not necessary - -class DHWAllocationSizeDebugHook -{ -public: - virtual bool AllocHook(size_t size) = 0; - virtual bool ReallocHook(size_t size, size_t sizeOld) = 0; - virtual bool FreeHook(size_t size) = 0; -}; - -extern bool dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook); -extern bool dhwClearAllocationSizeDebugHook(); - -/***************************************************************************/ -#endif //0 - -#endif /* __nsDebugHelpWin32_h__ */ diff --git a/tools/trace-malloc/lib/nsTraceMalloc.c b/tools/trace-malloc/lib/nsTraceMalloc.c deleted file mode 100644 index 459b56d7d3e8..000000000000 --- a/tools/trace-malloc/lib/nsTraceMalloc.c +++ /dev/null @@ -1,2063 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim:cindent:ts=8:et:sw=4: - * - * 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/. */ -#ifdef NS_TRACE_MALLOC - /* - * TODO: - * - FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=392008 - * - extend logfile so 'F' record tells free stack - */ -#include -#include -#include -#include -#ifdef XP_UNIX -#include -#include -#include -#endif -#include "plhash.h" -#include "pratom.h" -#include "prlog.h" -#include "prlock.h" -#include "prmon.h" -#include "prprf.h" -#include "prenv.h" -#include "prnetdb.h" -#include "nsTraceMalloc.h" -#include "nscore.h" -#include "prinit.h" -#include "prthread.h" -#include "plstr.h" -#include "nsStackWalk.h" -#include "nsTraceMallocCallbacks.h" -#include "nsTypeInfo.h" -#include "mozilla/PoisonIOInterposer.h" - -#if defined(XP_MACOSX) - -#include - -#define WRITE_FLAGS "w" - -#define __libc_malloc(x) malloc(x) -#define __libc_realloc(x, y) realloc(x, y) -#define __libc_free(x) free(x) - -#elif defined(XP_UNIX) - -#include - -#define WRITE_FLAGS "w" - -#ifdef WRAP_SYSTEM_INCLUDES -#pragma GCC visibility push(default) -#endif -extern __ptr_t __libc_malloc(size_t); -extern __ptr_t __libc_calloc(size_t, size_t); -extern __ptr_t __libc_realloc(__ptr_t, size_t); -extern void __libc_free(__ptr_t); -extern __ptr_t __libc_memalign(size_t, size_t); -extern __ptr_t __libc_valloc(size_t); -#ifdef WRAP_SYSTEM_INCLUDES -#pragma GCC visibility pop -#endif - -#elif defined(XP_WIN32) - -#include /* for timeb */ -#include /* for fstat */ - -#include /*for write*/ - -#define WRITE_FLAGS "w" - -#define __libc_malloc(x) dhw_orig_malloc(x) -#define __libc_realloc(x, y) dhw_orig_realloc(x,y) -#define __libc_free(x) dhw_orig_free(x) - -#else /* not XP_MACOSX, XP_UNIX, or XP_WIN32 */ - -# error "Unknown build configuration!" - -#endif - -typedef struct logfile logfile; - -#define STARTUP_TMBUFSIZE (64 * 1024) -#define LOGFILE_TMBUFSIZE (16 * 1024) - -struct logfile { - int fd; - int lfd; /* logical fd, dense among all logfiles */ - char *buf; - int bufsize; - int pos; - uint32_t size; - uint32_t simsize; - logfile *next; - logfile **prevp; -}; - -static char default_buf[STARTUP_TMBUFSIZE]; -static logfile default_logfile = - {-1, 0, default_buf, STARTUP_TMBUFSIZE, 0, 0, 0, NULL, NULL}; -static logfile *logfile_list = NULL; -static logfile **logfile_tail = &logfile_list; -static logfile *logfp = &default_logfile; -static PRLock *tmlock = NULL; -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif -static char sdlogname[PATH_MAX] = ""; /* filename for shutdown leak log */ - -/* - * This enables/disables trace-malloc logging. - * - * It is separate from suppress_tracing so that we do not have to pay - * the performance cost of repeated TM_TLS_GET_DATA calls when - * trace-malloc is disabled (which is not as bad as the locking we used - * to have). - * - * It must default to zero, since it can be tested by the Linux malloc - * hooks before NS_TraceMallocStartup sets it. - */ -static uint32_t tracing_enabled = 0; - -/* - * Control whether we should log stacks - */ -static uint32_t stacks_enabled = 1; - -/* - * This lock must be held while manipulating the calltree, the - * allocations table, the log, or the tmstats. - * - * Callers should not *enter* the lock without checking suppress_tracing - * first; otherwise they risk trying to re-enter on the same thread. - */ -#define TM_ENTER_LOCK(t) \ - PR_BEGIN_MACRO \ - PR_ASSERT(t->suppress_tracing != 0); \ - if (tmlock) \ - PR_Lock(tmlock); \ - PR_END_MACRO - -#define TM_EXIT_LOCK(t) \ - PR_BEGIN_MACRO \ - PR_ASSERT(t->suppress_tracing != 0); \ - if (tmlock) \ - PR_Unlock(tmlock); \ - PR_END_MACRO - -#define TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t) \ - PR_BEGIN_MACRO \ - t->suppress_tracing++; \ - TM_ENTER_LOCK(t); \ - PR_END_MACRO - -#define TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t) \ - PR_BEGIN_MACRO \ - TM_EXIT_LOCK(t); \ - t->suppress_tracing--; \ - PR_END_MACRO - - -/* - * Thread-local storage. - * - * We can't use NSPR thread-local storage for this because it mallocs - * within PR_GetThreadPrivate (the first time) and PR_SetThreadPrivate - * (which can be worked around by protecting all uses of those functions - * with a monitor, ugh) and because it calls malloc/free when the - * thread-local storage is in an inconsistent state within - * PR_SetThreadPrivate (when expanding the thread-local storage array) - * and _PRI_DetachThread (when and after deleting the thread-local - * storage array). - */ - -#ifdef XP_WIN32 - -#include - -#define TM_TLS_INDEX_TYPE DWORD -#define TM_CREATE_TLS_INDEX(i_) PR_BEGIN_MACRO \ - (i_) = TlsAlloc(); \ - PR_END_MACRO -#define TM_DESTROY_TLS_INDEX(i_) TlsFree((i_)) -#define TM_GET_TLS_DATA(i_) TlsGetValue((i_)) -#define TM_SET_TLS_DATA(i_, v_) TlsSetValue((i_), (v_)) - -#else - -#include - -#define TM_TLS_INDEX_TYPE pthread_key_t -#define TM_CREATE_TLS_INDEX(i_) pthread_key_create(&(i_), NULL) -#define TM_DESTROY_TLS_INDEX(i_) pthread_key_delete((i_)) -#define TM_GET_TLS_DATA(i_) pthread_getspecific((i_)) -#define TM_SET_TLS_DATA(i_, v_) pthread_setspecific((i_), (v_)) - -#endif - -static TM_TLS_INDEX_TYPE tls_index; -static PRBool tls_index_initialized = PR_FALSE; - -/* FIXME (maybe): This is currently unused; we leak the thread-local data. */ -#if 0 -static void -free_tm_thread(void *priv) -{ - tm_thread *t = (tm_thread*) priv; - - PR_ASSERT(t->suppress_tracing == 0); - - if (t->in_heap) { - t->suppress_tracing = 1; - if (t->backtrace_buf.buffer) - __libc_free(t->backtrace_buf.buffer); - - __libc_free(t); - } -} -#endif - -tm_thread * -tm_get_thread(void) -{ - tm_thread *t; - tm_thread stack_tm_thread; - - if (!tls_index_initialized) { - /** - * Assume that the first call to |malloc| will occur before - * there are multiple threads. (If that's not the case, we - * probably need to do the necessary synchronization without - * using NSPR primitives. See discussion in - * https://bugzilla.mozilla.org/show_bug.cgi?id=442192 - */ - TM_CREATE_TLS_INDEX(tls_index); - tls_index_initialized = PR_TRUE; - } - - t = TM_GET_TLS_DATA(tls_index); - - if (!t) { - /* - * First, store a tm_thread on the stack to suppress for the - * malloc below - */ - stack_tm_thread.suppress_tracing = 1; - stack_tm_thread.backtrace_buf.buffer = NULL; - stack_tm_thread.backtrace_buf.size = 0; - stack_tm_thread.backtrace_buf.entries = 0; - TM_SET_TLS_DATA(tls_index, &stack_tm_thread); - - t = (tm_thread*) __libc_malloc(sizeof(tm_thread)); - t->suppress_tracing = 0; - t->backtrace_buf = stack_tm_thread.backtrace_buf; - TM_SET_TLS_DATA(tls_index, t); - - PR_ASSERT(stack_tm_thread.suppress_tracing == 1); /* balanced */ - } - - return t; -} - -/* We don't want more than 32 logfiles open at once, ok? */ -typedef uint32_t lfd_set; - -#define LFD_SET_STATIC_INITIALIZER 0 -#define LFD_SET_SIZE 32 - -#define LFD_ZERO(s) (*(s) = 0) -#define LFD_BIT(i) ((uint32_t)1 << (i)) -#define LFD_TEST(i,s) (LFD_BIT(i) & *(s)) -#define LFD_SET(i,s) (*(s) |= LFD_BIT(i)) -#define LFD_CLR(i,s) (*(s) &= ~LFD_BIT(i)) - -static logfile *get_logfile(int fd) -{ - logfile *fp; - int lfd; - - for (fp = logfile_list; fp; fp = fp->next) { - if (fp->fd == fd) - return fp; - } - lfd = 0; -retry: - for (fp = logfile_list; fp; fp = fp->next) { - if (fp->fd == lfd) { - if (++lfd >= LFD_SET_SIZE) - return NULL; - goto retry; - } - } - fp = __libc_malloc(sizeof(logfile) + LOGFILE_TMBUFSIZE); - if (!fp) - return NULL; - fp->fd = fd; - fp->lfd = lfd; - fp->buf = (char*) (fp + 1); - fp->bufsize = LOGFILE_TMBUFSIZE; - fp->pos = 0; - fp->size = fp->simsize = 0; - fp->next = NULL; - fp->prevp = logfile_tail; - *logfile_tail = fp; - logfile_tail = &fp->next; - return fp; -} - -static void flush_logfile(logfile *fp) -{ - int len, cnt, fd; - char *bp; - - len = fp->pos; - if (len == 0) - return; - fp->pos = 0; - fd = fp->fd; - if (fd >= 0) { - fp->size += len; - bp = fp->buf; - do { - cnt = write(fd, bp, len); - if (cnt <= 0) { - printf("### nsTraceMalloc: write failed or wrote 0 bytes!\n"); - return; - } - bp += cnt; - len -= cnt; - } while (len > 0); - } - fp->simsize += len; -} - -static void log_byte(logfile *fp, char byte) -{ - if (fp->pos == fp->bufsize) - flush_logfile(fp); - fp->buf[fp->pos++] = byte; -} - -static void log_string(logfile *fp, const char *str) -{ - int len, rem, cnt; - - len = strlen(str) + 1; /* include null terminator */ - while ((rem = fp->pos + len - fp->bufsize) > 0) { - cnt = len - rem; - memcpy(&fp->buf[fp->pos], str, cnt); - str += cnt; - fp->pos += cnt; - flush_logfile(fp); - len = rem; - } - memcpy(&fp->buf[fp->pos], str, len); - fp->pos += len; -} - -static void log_filename(logfile* fp, const char* filename) -{ - if (strlen(filename) < 512) { - char *bp, *cp, buf[512]; - - bp = strstr(strcpy(buf, filename), "mozilla"); - if (!bp) - bp = buf; - - for (cp = bp; *cp; cp++) { - if (*cp == '\\') - *cp = '/'; - } - - filename = bp; - } - log_string(fp, filename); -} - -static void log_uint32(logfile *fp, uint32_t ival) -{ - if (ival < 0x80) { - /* 0xxx xxxx */ - log_byte(fp, (char) ival); - } else if (ival < 0x4000) { - /* 10xx xxxx xxxx xxxx */ - log_byte(fp, (char) ((ival >> 8) | 0x80)); - log_byte(fp, (char) (ival & 0xff)); - } else if (ival < 0x200000) { - /* 110x xxxx xxxx xxxx xxxx xxxx */ - log_byte(fp, (char) ((ival >> 16) | 0xc0)); - log_byte(fp, (char) ((ival >> 8) & 0xff)); - log_byte(fp, (char) (ival & 0xff)); - } else if (ival < 0x10000000) { - /* 1110 xxxx xxxx xxxx xxxx xxxx xxxx xxxx */ - log_byte(fp, (char) ((ival >> 24) | 0xe0)); - log_byte(fp, (char) ((ival >> 16) & 0xff)); - log_byte(fp, (char) ((ival >> 8) & 0xff)); - log_byte(fp, (char) (ival & 0xff)); - } else { - /* 1111 0000 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx */ - log_byte(fp, (char) 0xf0); - log_byte(fp, (char) ((ival >> 24) & 0xff)); - log_byte(fp, (char) ((ival >> 16) & 0xff)); - log_byte(fp, (char) ((ival >> 8) & 0xff)); - log_byte(fp, (char) (ival & 0xff)); - } -} - -static void log_event1(logfile *fp, char event, uint32_t serial) -{ - log_byte(fp, event); - log_uint32(fp, (uint32_t) serial); -} - -static void log_event2(logfile *fp, char event, uint32_t serial, size_t size) -{ - log_event1(fp, event, serial); - log_uint32(fp, (uint32_t) size); -} - -static void log_event3(logfile *fp, char event, uint32_t serial, size_t oldsize, - size_t size) -{ - log_event2(fp, event, serial, oldsize); - log_uint32(fp, (uint32_t) size); -} - -static void log_event4(logfile *fp, char event, uint32_t serial, uint32_t ui2, - uint32_t ui3, uint32_t ui4) -{ - log_event3(fp, event, serial, ui2, ui3); - log_uint32(fp, ui4); -} - -static void log_event5(logfile *fp, char event, uint32_t serial, uint32_t ui2, - uint32_t ui3, uint32_t ui4, uint32_t ui5) -{ - log_event4(fp, event, serial, ui2, ui3, ui4); - log_uint32(fp, ui5); -} - -static void log_event6(logfile *fp, char event, uint32_t serial, uint32_t ui2, - uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6) -{ - log_event5(fp, event, serial, ui2, ui3, ui4, ui5); - log_uint32(fp, ui6); -} - -static void log_event7(logfile *fp, char event, uint32_t serial, uint32_t ui2, - uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6, - uint32_t ui7) -{ - log_event6(fp, event, serial, ui2, ui3, ui4, ui5, ui6); - log_uint32(fp, ui7); -} - -static void log_event8(logfile *fp, char event, uint32_t serial, uint32_t ui2, - uint32_t ui3, uint32_t ui4, uint32_t ui5, uint32_t ui6, - uint32_t ui7, uint32_t ui8) -{ - log_event7(fp, event, serial, ui2, ui3, ui4, ui5, ui6, ui7); - log_uint32(fp, ui8); -} - -typedef struct callsite callsite; - -struct callsite { - void* pc; - uint32_t serial; - lfd_set lfdset; - const char *name; /* pointer to string owned by methods table */ - const char *library; /* pointer to string owned by libraries table */ - int offset; - callsite *parent; - callsite *siblings; - callsite *kids; -}; - -/* NB: these counters are incremented and decremented only within tmlock. */ -static uint32_t library_serial_generator = 0; -static uint32_t method_serial_generator = 0; -static uint32_t callsite_serial_generator = 0; -static uint32_t tmstats_serial_generator = 0; -static uint32_t filename_serial_generator = 0; - -/* Root of the tree of callsites, the sum of all (cycle-compressed) stacks. */ -static callsite calltree_root = - {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, NULL, 0, NULL, NULL, NULL}; - -/* a fake pc for when stacks are disabled; must be different from the - pc in calltree_root */ -#define STACK_DISABLED_PC ((void*)1) - -/* Basic instrumentation. */ -static nsTMStats tmstats = NS_TMSTATS_STATIC_INITIALIZER; - -/* Parent with the most kids (tmstats.calltree_maxkids). */ -static callsite *calltree_maxkids_parent; - -/* Calltree leaf for path with deepest stack backtrace. */ -static callsite *calltree_maxstack_top; - -/* Last site (i.e., calling pc) that recurred during a backtrace. */ -static callsite *last_callsite_recurrence; - -static void log_tmstats(logfile *fp) -{ - log_event1(fp, TM_EVENT_STATS, ++tmstats_serial_generator); - log_uint32(fp, tmstats.calltree_maxstack); - log_uint32(fp, tmstats.calltree_maxdepth); - log_uint32(fp, tmstats.calltree_parents); - log_uint32(fp, tmstats.calltree_maxkids); - log_uint32(fp, tmstats.calltree_kidhits); - log_uint32(fp, tmstats.calltree_kidmisses); - log_uint32(fp, tmstats.calltree_kidsteps); - log_uint32(fp, tmstats.callsite_recurrences); - log_uint32(fp, tmstats.backtrace_calls); - log_uint32(fp, tmstats.backtrace_failures); - log_uint32(fp, tmstats.btmalloc_failures); - log_uint32(fp, tmstats.dladdr_failures); - log_uint32(fp, tmstats.malloc_calls); - log_uint32(fp, tmstats.malloc_failures); - log_uint32(fp, tmstats.calloc_calls); - log_uint32(fp, tmstats.calloc_failures); - log_uint32(fp, tmstats.realloc_calls); - log_uint32(fp, tmstats.realloc_failures); - log_uint32(fp, tmstats.free_calls); - log_uint32(fp, tmstats.null_free_calls); - log_uint32(fp, calltree_maxkids_parent ? calltree_maxkids_parent->serial - : 0); - log_uint32(fp, calltree_maxstack_top ? calltree_maxstack_top->serial : 0); -} - -static void *generic_alloctable(void *pool, size_t size) -{ - return __libc_malloc(size); -} - -static void generic_freetable(void *pool, void *item) -{ - __libc_free(item); -} - -typedef struct lfdset_entry { - PLHashEntry base; - lfd_set lfdset; -} lfdset_entry; - -static PLHashEntry *lfdset_allocentry(void *pool, const void *key) -{ - lfdset_entry *le = __libc_malloc(sizeof *le); - if (le) - LFD_ZERO(&le->lfdset); - return &le->base; -} - -static void lfdset_freeentry(void *pool, PLHashEntry *he, unsigned flag) -{ - lfdset_entry *le; - - if (flag != HT_FREE_ENTRY) - return; - le = (lfdset_entry*) he; - __libc_free((void*) le); -} - -static PLHashAllocOps lfdset_hashallocops = { - generic_alloctable, generic_freetable, - lfdset_allocentry, lfdset_freeentry -}; - -/* Table of library pathnames mapped to to logged 'L' record serial numbers. */ -static PLHashTable *libraries = NULL; - -/* Table of filename pathnames mapped to logged 'G' record serial numbers. */ -static PLHashTable *filenames = NULL; - -/* Table mapping method names to logged 'N' record serial numbers. */ -static PLHashTable *methods = NULL; - -/* - * Presumes that its caller is holding tmlock, but may temporarily exit - * the lock. - */ -static callsite * -calltree(void **stack, size_t num_stack_entries, tm_thread *t) -{ - logfile *fp = logfp; - void *pc; - uint32_t nkids; - callsite *parent, *site, **csp, *tmp; - int maxstack; - uint32_t library_serial, method_serial, filename_serial; - const char *library, *method, *filename; - char *slash; - PLHashNumber hash; - PLHashEntry **hep, *he; - lfdset_entry *le; - size_t stack_index; - nsCodeAddressDetails details; - nsresult rv; - - maxstack = (num_stack_entries > tmstats.calltree_maxstack); - if (maxstack) { - /* these two are the same, although that used to be less clear */ - tmstats.calltree_maxstack = num_stack_entries; - tmstats.calltree_maxdepth = num_stack_entries; - } - - /* Reverse the stack again, finding and building a path in the tree. */ - parent = &calltree_root; - stack_index = num_stack_entries; - do { - --stack_index; - pc = stack[stack_index]; - - csp = &parent->kids; - while ((site = *csp) != NULL) { - if (site->pc == pc) { - tmstats.calltree_kidhits++; - - /* Put the most recently used site at the front of siblings. */ - *csp = site->siblings; - site->siblings = parent->kids; - parent->kids = site; - - /* Check whether we've logged for this site and logfile yet. */ - if (!LFD_TEST(fp->lfd, &site->lfdset)) { - /* - * Some other logfile put this site in the calltree. We - * must log an event for site, and possibly first for its - * method and/or library. Note the code after the while - * loop that tests if (!site). - */ - break; - } - - /* Site already built and logged to fp -- go up the stack. */ - goto upward; - } - tmstats.calltree_kidsteps++; - csp = &site->siblings; - } - - if (!site) { - tmstats.calltree_kidmisses++; - - /* Check for recursion: see if pc is on our ancestor line. */ - for (site = parent; site; site = site->parent) { - if (site->pc == pc) { - tmstats.callsite_recurrences++; - last_callsite_recurrence = site; - goto upward; - } - } - } - - /* - * Not in tree at all, or not logged to fp: let's find our symbolic - * callsite info. - */ - - if (!stacks_enabled) { - /* - * Fake the necessary information for our single fake stack - * frame. - */ - PL_strncpyz(details.library, "stacks_disabled", - sizeof(details.library)); - details.loffset = 0; - details.filename[0] = '\0'; - details.lineno = 0; - details.function[0] = '\0'; - details.foffset = 0; - } else { - /* - * NS_DescribeCodeAddress can (on Linux) acquire a lock inside - * the shared library loader. Another thread might call malloc - * while holding that lock (when loading a shared library). So - * we have to exit tmlock around this call. For details, see - * https://bugzilla.mozilla.org/show_bug.cgi?id=363334#c3 - * - * We could be more efficient by building the nodes in the - * calltree, exiting the monitor once to describe all of them, - * and then filling in the descriptions for any that hadn't been - * described already. But this is easier for now. - */ - TM_EXIT_LOCK(t); - rv = NS_DescribeCodeAddress(pc, &details); - TM_ENTER_LOCK(t); - if (NS_FAILED(rv)) { - tmstats.dladdr_failures++; - goto fail; - } - } - - /* Check whether we need to emit a library trace record. */ - library_serial = 0; - library = NULL; - if (details.library[0]) { - if (!libraries) { - libraries = PL_NewHashTable(100, PL_HashString, - PL_CompareStrings, PL_CompareValues, - &lfdset_hashallocops, NULL); - if (!libraries) { - tmstats.btmalloc_failures++; - goto fail; - } - } - hash = PL_HashString(details.library); - hep = PL_HashTableRawLookup(libraries, hash, details.library); - he = *hep; - if (he) { - library = (char*) he->key; - library_serial = (uint32_t) NS_PTR_TO_INT32(he->value); - le = (lfdset_entry *) he; - if (LFD_TEST(fp->lfd, &le->lfdset)) { - /* We already logged an event on fp for this library. */ - le = NULL; - } - } else { - library = strdup(details.library); - if (library) { - library_serial = ++library_serial_generator; - he = PL_HashTableRawAdd(libraries, hep, hash, library, - NS_INT32_TO_PTR(library_serial)); - } - if (!he) { - tmstats.btmalloc_failures++; - goto fail; - } - le = (lfdset_entry *) he; - } - if (le) { - /* Need to log an event to fp for this lib. */ - slash = strrchr(library, '/'); - log_event1(fp, TM_EVENT_LIBRARY, library_serial); - log_string(fp, slash ? slash + 1 : library); - LFD_SET(fp->lfd, &le->lfdset); - } - } - - /* For compatibility with current log format, always emit a - * filename trace record, using "noname" / 0 when no file name - * is available. */ - filename_serial = 0; - filename = details.filename[0] ? details.filename : "noname"; - if (!filenames) { - filenames = PL_NewHashTable(100, PL_HashString, - PL_CompareStrings, PL_CompareValues, - &lfdset_hashallocops, NULL); - if (!filenames) { - tmstats.btmalloc_failures++; - return NULL; - } - } - hash = PL_HashString(filename); - hep = PL_HashTableRawLookup(filenames, hash, filename); - he = *hep; - if (he) { - filename = (char*) he->key; - filename_serial = (uint32_t) NS_PTR_TO_INT32(he->value); - le = (lfdset_entry *) he; - if (LFD_TEST(fp->lfd, &le->lfdset)) { - /* We already logged an event on fp for this filename. */ - le = NULL; - } - } else { - filename = strdup(filename); - if (filename) { - filename_serial = ++filename_serial_generator; - he = PL_HashTableRawAdd(filenames, hep, hash, filename, - NS_INT32_TO_PTR(filename_serial)); - } - if (!he) { - tmstats.btmalloc_failures++; - return NULL; - } - le = (lfdset_entry *) he; - } - if (le) { - /* Need to log an event to fp for this filename. */ - log_event1(fp, TM_EVENT_FILENAME, filename_serial); - log_filename(fp, filename); - LFD_SET(fp->lfd, &le->lfdset); - } - - if (!details.function[0]) { - PR_snprintf(details.function, sizeof(details.function), - "%s+%X", library ? library : "main", details.loffset); - } - - /* Emit an 'N' (for New method, 'M' is for malloc!) event if needed. */ - method_serial = 0; - if (!methods) { - methods = PL_NewHashTable(10000, PL_HashString, - PL_CompareStrings, PL_CompareValues, - &lfdset_hashallocops, NULL); - if (!methods) { - tmstats.btmalloc_failures++; - goto fail; - } - } - hash = PL_HashString(details.function); - hep = PL_HashTableRawLookup(methods, hash, details.function); - he = *hep; - if (he) { - method = (char*) he->key; - method_serial = (uint32_t) NS_PTR_TO_INT32(he->value); - le = (lfdset_entry *) he; - if (LFD_TEST(fp->lfd, &le->lfdset)) { - /* We already logged an event on fp for this method. */ - le = NULL; - } - } else { - method = strdup(details.function); - if (method) { - method_serial = ++method_serial_generator; - he = PL_HashTableRawAdd(methods, hep, hash, method, - NS_INT32_TO_PTR(method_serial)); - } - if (!he) { - tmstats.btmalloc_failures++; - return NULL; - } - le = (lfdset_entry *) he; - } - if (le) { - log_event4(fp, TM_EVENT_METHOD, method_serial, library_serial, - filename_serial, details.lineno); - log_string(fp, method); - LFD_SET(fp->lfd, &le->lfdset); - } - - /* Create a new callsite record. */ - if (!site) { - site = __libc_malloc(sizeof(callsite)); - if (!site) { - tmstats.btmalloc_failures++; - goto fail; - } - - /* Update parent and max-kids-per-parent stats. */ - if (!parent->kids) - tmstats.calltree_parents++; - nkids = 1; - for (tmp = parent->kids; tmp; tmp = tmp->siblings) - nkids++; - if (nkids > tmstats.calltree_maxkids) { - tmstats.calltree_maxkids = nkids; - calltree_maxkids_parent = parent; - } - - /* Insert the new site into the tree. */ - site->pc = pc; - site->serial = ++callsite_serial_generator; - LFD_ZERO(&site->lfdset); - site->name = method; - site->library = library; - site->offset = details.loffset; - site->parent = parent; - site->siblings = parent->kids; - parent->kids = site; - site->kids = NULL; - } - - /* Log the site with its parent, method, and offset. */ - log_event4(fp, TM_EVENT_CALLSITE, site->serial, parent->serial, - method_serial, details.foffset); - LFD_SET(fp->lfd, &site->lfdset); - - upward: - parent = site; - } while (stack_index > 0); - - if (maxstack) - calltree_maxstack_top = site; - - return site; - - fail: - return NULL; -} - -/* - * Buffer the stack from top at low index to bottom at high, so that we can - * reverse it in calltree. - */ -static void -stack_callback(uint32_t frameNumber, void *pc, void *sp, void *closure) -{ - stack_buffer_info *info = (stack_buffer_info*) closure; - - /* - * If we run out of buffer, keep incrementing entries so that - * backtrace can call us again with a bigger buffer. - */ - if (info->entries < info->size) - info->buffer[info->entries] = pc; - ++info->entries; -} - -/* - * The caller MUST NOT be holding tmlock when calling backtrace. - * On return, if *immediate_abort is set, then the return value is NULL - * and the thread is in a very dangerous situation (e.g. holding - * sem_pool_lock in Mac OS X pthreads); the caller should bail out - * without doing anything (such as acquiring locks). - */ -static callsite * -backtrace(tm_thread *t, int skipFrames, int *immediate_abort) -{ - callsite *site; - stack_buffer_info *info = &t->backtrace_buf; - void ** new_stack_buffer; - size_t new_stack_buffer_size; - nsresult rv; - - t->suppress_tracing++; - - if (!stacks_enabled) { -#if defined(XP_MACOSX) - /* Walk the stack, even if stacks_enabled is false. We do this to - check if we must set immediate_abort. */ - info->entries = 0; - rv = NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info, - 0, NULL); - *immediate_abort = rv == NS_ERROR_UNEXPECTED; - if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) { - t->suppress_tracing--; - return NULL; - } -#endif - - /* - * Create a single fake stack frame so that all the tools get - * data in the correct format. - */ - *immediate_abort = 0; - if (info->size < 1) { - PR_ASSERT(!info->buffer); /* !info->size == !info->buffer */ - info->buffer = __libc_malloc(1 * sizeof(void*)); - if (!info->buffer) - return NULL; - info->size = 1; - } - - info->entries = 1; - info->buffer[0] = STACK_DISABLED_PC; - } else { - /* - * NS_StackWalk can (on Windows) acquire a lock the shared library - * loader. Another thread might call malloc while holding that lock - * (when loading a shared library). So we can't be in tmlock during - * this call. For details, see - * https://bugzilla.mozilla.org/show_bug.cgi?id=374829#c8 - */ - - /* - * skipFrames == 0 means |backtrace| should show up, so don't use - * skipFrames + 1. - * NB: this call is repeated below if the buffer is too small. - */ - info->entries = 0; - rv = NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info, - 0, NULL); - *immediate_abort = rv == NS_ERROR_UNEXPECTED; - if (rv == NS_ERROR_UNEXPECTED || info->entries == 0) { - t->suppress_tracing--; - return NULL; - } - - /* - * To avoid allocating in stack_callback (which, on Windows, is - * called on a different thread from the one we're running on here), - * reallocate here if it didn't have a big enough buffer (which - * includes the first call on any thread), and call it again. - */ - if (info->entries > info->size) { - new_stack_buffer_size = 2 * info->entries; - new_stack_buffer = __libc_realloc(info->buffer, - new_stack_buffer_size * sizeof(void*)); - if (!new_stack_buffer) - return NULL; - info->buffer = new_stack_buffer; - info->size = new_stack_buffer_size; - - /* and call NS_StackWalk again */ - info->entries = 0; - NS_StackWalk(stack_callback, skipFrames, /* maxFrames */ 0, info, - 0, NULL); - - /* same stack */ - PR_ASSERT(info->entries * 2 == new_stack_buffer_size); - } - } - - TM_ENTER_LOCK(t); - - site = calltree(info->buffer, info->entries, t); - - tmstats.backtrace_calls++; - if (!site) { - tmstats.backtrace_failures++; - PR_ASSERT(tmstats.backtrace_failures < 100); - } - TM_EXIT_LOCK(t); - - t->suppress_tracing--; - return site; -} - -typedef struct allocation { - PLHashEntry entry; - size_t size; - FILE *trackfp; /* for allocation tracking */ -} allocation; - -#define ALLOC_HEAP_SIZE 150000 - -static allocation alloc_heap[ALLOC_HEAP_SIZE]; -static allocation *alloc_freelist = NULL; -static int alloc_heap_initialized = 0; - -static PLHashEntry *alloc_allocentry(void *pool, const void *key) -{ - allocation **listp, *alloc; - int n; - - if (!alloc_heap_initialized) { - n = ALLOC_HEAP_SIZE; - listp = &alloc_freelist; - for (alloc = alloc_heap; --n >= 0; alloc++) { - *listp = alloc; - listp = (allocation**) &alloc->entry.next; - } - *listp = NULL; - alloc_heap_initialized = 1; - } - - listp = &alloc_freelist; - alloc = *listp; - if (!alloc) - return __libc_malloc(sizeof(allocation)); - *listp = (allocation*) alloc->entry.next; - return &alloc->entry; -} - -static void alloc_freeentry(void *pool, PLHashEntry *he, unsigned flag) -{ - allocation *alloc; - - if (flag != HT_FREE_ENTRY) - return; - alloc = (allocation*) he; - if ((ptrdiff_t)(alloc - alloc_heap) < (ptrdiff_t)ALLOC_HEAP_SIZE) { - alloc->entry.next = &alloc_freelist->entry; - alloc_freelist = alloc; - } else { - __libc_free((void*) alloc); - } -} - -static PLHashAllocOps alloc_hashallocops = { - generic_alloctable, generic_freetable, - alloc_allocentry, alloc_freeentry -}; - -static PLHashNumber hash_pointer(const void *key) -{ - return (PLHashNumber) key; -} - -static PLHashTable *allocations = NULL; - -static PLHashTable *new_allocations(void) -{ - allocations = PL_NewHashTable(200000, hash_pointer, - PL_CompareValues, PL_CompareValues, - &alloc_hashallocops, NULL); - return allocations; -} - -#define get_allocations() (allocations ? allocations : new_allocations()) - -#if defined(XP_MACOSX) - -/* from malloc.c in Libc */ -typedef void -malloc_logger_t(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, - uintptr_t result, uint32_t num_hot_frames_to_skip); - -extern malloc_logger_t *malloc_logger; - -#define MALLOC_LOG_TYPE_ALLOCATE 2 -#define MALLOC_LOG_TYPE_DEALLOCATE 4 -#define MALLOC_LOG_TYPE_HAS_ZONE 8 -#define MALLOC_LOG_TYPE_CLEARED 64 - -static void -my_malloc_logger(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, - uintptr_t result, uint32_t num_hot_frames_to_skip) -{ - uintptr_t all_args[3] = { arg1, arg2, arg3 }; - uintptr_t *args = all_args + ((type & MALLOC_LOG_TYPE_HAS_ZONE) ? 1 : 0); - - uint32_t alloc_type = - type & (MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE); - tm_thread *t = tm_get_thread(); - - if (alloc_type == (MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE)) { - ReallocCallback((void*)args[0], (void*)result, args[1], 0, 0, t); - } else if (alloc_type == MALLOC_LOG_TYPE_ALLOCATE) { - /* - * We don't get size/count information for calloc, so just use - * MallocCallback. - */ - MallocCallback((void*)result, args[0], 0, 0, t); - } else if (alloc_type == MALLOC_LOG_TYPE_DEALLOCATE) { - FreeCallback((void*)args[0], 0, 0, t); - } -} - -static void -StartupHooker(void) -{ - PR_ASSERT(!malloc_logger); - malloc_logger = my_malloc_logger; -} - -static void -ShutdownHooker(void) -{ - PR_ASSERT(malloc_logger == my_malloc_logger); - malloc_logger = NULL; -} - -#elif defined(XP_UNIX) - -/* - * We can't use glibc's malloc hooks because they can't be used in a - * threadsafe manner. They require unsetting the hooks to call into the - * original malloc implementation, and then resetting them when the - * original implementation returns. If another thread calls the same - * allocation function while the hooks are unset, we have no chance to - * intercept the call. - */ - -NS_EXTERNAL_VIS_(__ptr_t) -malloc(size_t size) -{ - uint32_t start, end; - __ptr_t ptr; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - return __libc_malloc(size); - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - ptr = __libc_malloc(size); - end = PR_IntervalNow(); - t->suppress_tracing--; - - MallocCallback(ptr, size, start, end, t); - - return ptr; -} - -NS_EXTERNAL_VIS_(__ptr_t) -calloc(size_t count, size_t size) -{ - uint32_t start, end; - __ptr_t ptr; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - return __libc_calloc(count, size); - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - ptr = __libc_calloc(count, size); - end = PR_IntervalNow(); - t->suppress_tracing--; - - CallocCallback(ptr, count, size, start, end, t); - - return ptr; -} - -NS_EXTERNAL_VIS_(__ptr_t) -realloc(__ptr_t oldptr, size_t size) -{ - uint32_t start, end; - __ptr_t ptr; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - return __libc_realloc(oldptr, size); - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - ptr = __libc_realloc(oldptr, size); - end = PR_IntervalNow(); - t->suppress_tracing--; - - /* FIXME bug 392008: We could race with reallocation of oldptr. */ - ReallocCallback(oldptr, ptr, size, start, end, t); - - return ptr; -} - -NS_EXTERNAL_VIS_(void*) -valloc(size_t size) -{ - uint32_t start, end; - __ptr_t ptr; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - return __libc_valloc(size); - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - ptr = __libc_valloc(size); - end = PR_IntervalNow(); - t->suppress_tracing--; - - MallocCallback(ptr, size, start, end, t); - - return ptr; -} - -NS_EXTERNAL_VIS_(void*) -memalign(size_t boundary, size_t size) -{ - uint32_t start, end; - __ptr_t ptr; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - return __libc_memalign(boundary, size); - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - ptr = __libc_memalign(boundary, size); - end = PR_IntervalNow(); - t->suppress_tracing--; - - MallocCallback(ptr, size, start, end, t); - - return ptr; -} - -NS_EXTERNAL_VIS_(int) -posix_memalign(void **memptr, size_t alignment, size_t size) -{ - __ptr_t ptr = memalign(alignment, size); - if (!ptr) - return ENOMEM; - *memptr = ptr; - return 0; -} - -NS_EXTERNAL_VIS_(void) -free(__ptr_t ptr) -{ - uint32_t start, end; - tm_thread *t; - - if (!tracing_enabled || !PR_Initialized() || - (t = tm_get_thread())->suppress_tracing != 0) { - __libc_free(ptr); - return; - } - - t->suppress_tracing++; - start = PR_IntervalNow(); - __libc_free(ptr); - end = PR_IntervalNow(); - t->suppress_tracing--; - - /* FIXME bug 392008: We could race with reallocation of ptr. */ - - FreeCallback(ptr, start, end, t); -} - -NS_EXTERNAL_VIS_(void) -cfree(void *ptr) -{ - free(ptr); -} - -#define StartupHooker() PR_BEGIN_MACRO PR_END_MACRO -#define ShutdownHooker() PR_BEGIN_MACRO PR_END_MACRO - -#elif defined(XP_WIN32) - -/* See nsWinTraceMalloc.cpp. */ - -#endif - -static const char magic[] = NS_TRACE_MALLOC_MAGIC; - -static void -log_header(int logfd) -{ - uint32_t ticksPerSec = PR_htonl(PR_TicksPerSecond()); - (void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE); - (void) write(logfd, &ticksPerSec, sizeof ticksPerSec); -} - -PR_IMPLEMENT(void) -NS_TraceMallocStartup(int logfd) -{ - const char* stack_disable_env; - - /* We must be running on the primordial thread. */ - PR_ASSERT(tracing_enabled == 0); - PR_ASSERT(logfp == &default_logfile); - tracing_enabled = (logfd >= 0); - - if (logfd >= 3) - MozillaRegisterDebugFD(logfd); - - /* stacks are disabled if this env var is set to a non-empty value */ - stack_disable_env = PR_GetEnv("NS_TRACE_MALLOC_DISABLE_STACKS"); - stacks_enabled = !stack_disable_env || !*stack_disable_env; - - if (tracing_enabled) { - PR_ASSERT(logfp->simsize == 0); /* didn't overflow startup buffer */ - - /* Log everything in logfp (aka default_logfile)'s buffer to logfd. */ - logfp->fd = logfd; - logfile_list = &default_logfile; - logfp->prevp = &logfile_list; - logfile_tail = &logfp->next; - log_header(logfd); - } - - RegisterTraceMallocShutdown(); - - tmlock = PR_NewLock(); - (void) tm_get_thread(); /* ensure index initialization while it's easy */ - - if (tracing_enabled) - StartupHooker(); -} - -/* - * Options for log files, with the log file name either as the next option - * or separated by '=' (e.g. "./mozilla --trace-malloc * malloc.log" or - * "./mozilla --trace-malloc=malloc.log"). - */ -static const char TMLOG_OPTION[] = "--trace-malloc"; -static const char SDLOG_OPTION[] = "--shutdown-leaks"; - -#define SHOULD_PARSE_ARG(name_, log_, arg_) \ - (0 == strncmp(arg_, name_, sizeof(name_) - 1)) - -#define PARSE_ARG(name_, log_, argv_, i_, consumed_) \ - PR_BEGIN_MACRO \ - char _nextchar = argv_[i_][sizeof(name_) - 1]; \ - if (_nextchar == '=') { \ - log_ = argv_[i_] + sizeof(name_); \ - consumed_ = 1; \ - } else if (_nextchar == '\0') { \ - log_ = argv_[i_+1]; \ - consumed_ = 2; \ - } \ - PR_END_MACRO - -PR_IMPLEMENT(int) -NS_TraceMallocStartupArgs(int argc, char **argv) -{ - int i, logfd = -1, consumed, logflags; - char *tmlogname = NULL, *sdlogname_local = NULL; - - /* - * Look for the --trace-malloc option early, to avoid missing - * early mallocs (we miss static constructors whose output overflows the - * log file's static 16K output buffer). - */ - for (i = 1; i < argc; i += consumed) { - consumed = 0; - if (SHOULD_PARSE_ARG(TMLOG_OPTION, tmlogname, argv[i])) - PARSE_ARG(TMLOG_OPTION, tmlogname, argv, i, consumed); - else if (SHOULD_PARSE_ARG(SDLOG_OPTION, sdlogname_local, argv[i])) - PARSE_ARG(SDLOG_OPTION, sdlogname_local, argv, i, consumed); - - if (consumed) { -#ifndef XP_WIN32 /* If we don't comment this out, it will crash Windows. */ - int j; - /* Now remove --trace-malloc and its argument from argv. */ - argc -= consumed; - for (j = i; j < argc; ++j) - argv[j] = argv[j+consumed]; - argv[argc] = NULL; - consumed = 0; /* don't advance next iteration */ -#endif - } else { - consumed = 1; - } - } - - if (tmlogname) { -#ifdef XP_UNIX - int pipefds[2]; -#endif - - switch (*tmlogname) { -#ifdef XP_UNIX - case '|': - if (pipe(pipefds) == 0) { - pid_t pid = fork(); - if (pid == 0) { - /* In child: set up stdin, parse args, and exec. */ - int maxargc, nargc; - char **nargv, *token; - - if (pipefds[0] != 0) { - dup2(pipefds[0], 0); - close(pipefds[0]); - } - close(pipefds[1]); - - tmlogname = strtok(tmlogname + 1, " \t"); - maxargc = 3; - nargv = (char **) malloc((maxargc+1) * sizeof(char *)); - if (!nargv) exit(1); - nargc = 0; - nargv[nargc++] = tmlogname; - while ((token = strtok(NULL, " \t")) != NULL) { - if (nargc == maxargc) { - maxargc *= 2; - nargv = (char**) - realloc(nargv, (maxargc+1) * sizeof(char*)); - if (!nargv) exit(1); - } - nargv[nargc++] = token; - } - nargv[nargc] = NULL; - - (void) setsid(); - execvp(tmlogname, nargv); - exit(127); - } - - if (pid > 0) { - /* In parent: set logfd to the pipe's write side. */ - close(pipefds[0]); - logfd = pipefds[1]; - } - } - if (logfd < 0) { - fprintf(stderr, - "%s: can't pipe to trace-malloc child process %s: %s\n", - argv[0], tmlogname, strerror(errno)); - exit(1); - } - break; -#endif /*XP_UNIX*/ - case '-': - /* Don't log from startup, but do prepare to log later. */ - /* XXX traditional meaning of '-' as option argument is "stdin" or "stdout" */ - if (tmlogname[1] == '\0') - break; - /* FALL THROUGH */ - - default: - logflags = O_CREAT | O_WRONLY | O_TRUNC; -#if defined(XP_WIN32) - /* - * Avoid translations on WIN32. - */ - logflags |= O_BINARY; -#endif - logfd = open(tmlogname, logflags, 0644); - if (logfd < 0) { - fprintf(stderr, - "%s: can't create trace-malloc log named %s: %s\n", - argv[0], tmlogname, strerror(errno)); - exit(1); - } - break; - } - } - - if (sdlogname_local) { - strncpy(sdlogname, sdlogname_local, sizeof(sdlogname)); - sdlogname[sizeof(sdlogname) - 1] = '\0'; - } - - NS_TraceMallocStartup(logfd); - return argc; -} - -PR_IMPLEMENT(PRBool) -NS_TraceMallocHasStarted(void) -{ - return tmlock ? PR_TRUE : PR_FALSE; -} - -PR_IMPLEMENT(void) -NS_TraceMallocShutdown(void) -{ - logfile *fp; - - if (sdlogname[0]) - NS_TraceMallocDumpAllocations(sdlogname); - - if (tmstats.backtrace_failures) { - fprintf(stderr, - "TraceMalloc backtrace failures: %lu (malloc %lu dladdr %lu)\n", - (unsigned long) tmstats.backtrace_failures, - (unsigned long) tmstats.btmalloc_failures, - (unsigned long) tmstats.dladdr_failures); - } - while ((fp = logfile_list) != NULL) { - logfile_list = fp->next; - log_tmstats(fp); - flush_logfile(fp); - if (fp->fd >= 0) { - MozillaUnRegisterDebugFD(fp->fd); - close(fp->fd); - fp->fd = -1; - } - if (fp != &default_logfile) { - if (fp == logfp) - logfp = &default_logfile; - free((void*) fp); - } - } - if (tmlock) { - PRLock *lock = tmlock; - tmlock = NULL; - PR_DestroyLock(lock); - } - if (tracing_enabled) { - tracing_enabled = 0; - ShutdownHooker(); - } -} - -PR_IMPLEMENT(void) -NS_TraceMallocDisable(void) -{ - tm_thread *t = tm_get_thread(); - logfile *fp; - uint32_t sample; - - /* Robustify in case of duplicate call. */ - PR_ASSERT(tracing_enabled); - if (tracing_enabled == 0) - return; - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - for (fp = logfile_list; fp; fp = fp->next) - flush_logfile(fp); - sample = --tracing_enabled; - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - if (sample == 0) - ShutdownHooker(); -} - -PR_IMPLEMENT(void) -NS_TraceMallocEnable(void) -{ - tm_thread *t = tm_get_thread(); - uint32_t sample; - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - sample = ++tracing_enabled; - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - if (sample == 1) - StartupHooker(); -} - -PR_IMPLEMENT(int) -NS_TraceMallocChangeLogFD(int fd) -{ - logfile *oldfp, *fp; - struct stat sb; - tm_thread *t = tm_get_thread(); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - oldfp = logfp; - if (oldfp->fd != fd) { - flush_logfile(oldfp); - fp = get_logfile(fd); - if (!fp) { - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - return -2; - } - if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0) - log_header(fd); - logfp = fp; - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - return oldfp->fd; -} - -static int -lfd_clr_enumerator(PLHashEntry *he, int i, void *arg) -{ - lfdset_entry *le = (lfdset_entry*) he; - logfile *fp = (logfile*) arg; - - LFD_CLR(fp->lfd, &le->lfdset); - return HT_ENUMERATE_NEXT; -} - -static void -lfd_clr_walk(callsite *site, logfile *fp) -{ - callsite *kid; - - LFD_CLR(fp->lfd, &site->lfdset); - for (kid = site->kids; kid; kid = kid->siblings) - lfd_clr_walk(kid, fp); -} - -PR_IMPLEMENT(void) -NS_TraceMallocCloseLogFD(int fd) -{ - logfile *fp; - tm_thread *t = tm_get_thread(); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - - fp = get_logfile(fd); - if (fp) { - flush_logfile(fp); - if (fp == &default_logfile) { - /* Leave default_logfile in logfile_list with an fd of -1. */ - fp->fd = -1; - - /* NB: we can never free lfd 0, it belongs to default_logfile. */ - PR_ASSERT(fp->lfd == 0); - } else { - /* Clear fp->lfd in all possible lfdsets. */ - PL_HashTableEnumerateEntries(libraries, lfd_clr_enumerator, fp); - PL_HashTableEnumerateEntries(methods, lfd_clr_enumerator, fp); - lfd_clr_walk(&calltree_root, fp); - - /* Unlink fp from logfile_list, freeing lfd for reallocation. */ - *fp->prevp = fp->next; - if (!fp->next) { - PR_ASSERT(logfile_tail == &fp->next); - logfile_tail = fp->prevp; - } - - /* Reset logfp if we must, then free fp. */ - if (fp == logfp) - logfp = &default_logfile; - free((void*) fp); - } - } - - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - MozillaUnRegisterDebugFD(fd); - close(fd); -} - -PR_IMPLEMENT(void) -NS_TraceMallocLogTimestamp(const char *caption) -{ - logfile *fp; -#ifdef XP_UNIX - struct timeval tv; -#endif -#ifdef XP_WIN32 - struct _timeb tb; -#endif - tm_thread *t = tm_get_thread(); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - - fp = logfp; - log_byte(fp, TM_EVENT_TIMESTAMP); - -#ifdef XP_UNIX - gettimeofday(&tv, NULL); - log_uint32(fp, (uint32_t) tv.tv_sec); - log_uint32(fp, (uint32_t) tv.tv_usec); -#endif -#ifdef XP_WIN32 - _ftime(&tb); - log_uint32(fp, (uint32_t) tb.time); - log_uint32(fp, (uint32_t) tb.millitm); -#endif - log_string(fp, caption); - - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -static void -print_stack(FILE *ofp, callsite *site) -{ - while (site) { - if (site->name || site->parent) { - fprintf(ofp, "%s[%s +0x%X]\n", - site->name, site->library, site->offset); - } - site = site->parent; - } -} - -static const char *allocation_format = - (sizeof(void*) == 4) ? "\t0x%08zX\n" : - (sizeof(void*) == 8) ? "\t0x%016zX\n" : - "UNEXPECTED sizeof(void*)"; - -static int -allocation_enumerator(PLHashEntry *he, int i, void *arg) -{ - allocation *alloc = (allocation*) he; - FILE *ofp = (FILE*) arg; - callsite *site = (callsite*) he->value; - - size_t *p, *end; - - fprintf(ofp, "%p <%s> (%lu)\n", - he->key, - nsGetTypeName(he->key), - (unsigned long) alloc->size); - - for (p = (size_t*) he->key, - end = (size_t*) ((char*)he->key + alloc->size); - p < end; ++p) { - fprintf(ofp, allocation_format, *p); - } - - print_stack(ofp, site); - fputc('\n', ofp); - return HT_ENUMERATE_NEXT; -} - -PR_IMPLEMENT(void) -NS_TraceStack(int skip, FILE *ofp) -{ - callsite *site; - tm_thread *t = tm_get_thread(); - int immediate_abort; - - site = backtrace(t, skip + 1, &immediate_abort); - while (site) { - if (site->name || site->parent) { - fprintf(ofp, "%s[%s +0x%X]\n", - site->name, site->library, site->offset); - } - site = site->parent; - } -} - -PR_IMPLEMENT(int) -NS_TraceMallocDumpAllocations(const char *pathname) -{ - FILE *ofp; - int rv; - int fd; - - tm_thread *t = tm_get_thread(); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - - ofp = fopen(pathname, WRITE_FLAGS); - if (ofp) { - MozillaRegisterDebugFD(fileno(ofp)); - if (allocations) { - PL_HashTableEnumerateEntries(allocations, allocation_enumerator, - ofp); - } - rv = ferror(ofp) ? -1 : 0; - MozillaUnRegisterDebugFILE(ofp); - fclose(ofp); - } else { - rv = -1; - } - - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); - - return rv; -} - -PR_IMPLEMENT(void) -NS_TraceMallocFlushLogfiles(void) -{ - logfile *fp; - tm_thread *t = tm_get_thread(); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - - for (fp = logfile_list; fp; fp = fp->next) - flush_logfile(fp); - - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(void) -NS_TrackAllocation(void* ptr, FILE *ofp) -{ - allocation *alloc; - tm_thread *t = tm_get_thread(); - - fprintf(ofp, "Trying to track %p\n", (void*) ptr); - setlinebuf(ofp); - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - if (get_allocations()) { - alloc = (allocation*) - *PL_HashTableRawLookup(allocations, hash_pointer(ptr), ptr); - if (alloc) { - fprintf(ofp, "Tracking %p\n", (void*) ptr); - alloc->trackfp = ofp; - } else { - fprintf(ofp, "Not tracking %p\n", (void*) ptr); - } - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(void) -MallocCallback(void *ptr, size_t size, uint32_t start, uint32_t end, tm_thread *t) -{ - callsite *site; - PLHashEntry *he; - allocation *alloc; - int immediate_abort; - - if (!tracing_enabled || t->suppress_tracing != 0) - return; - - site = backtrace(t, 2, &immediate_abort); - if (immediate_abort) - return; - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - tmstats.malloc_calls++; - if (!ptr) { - tmstats.malloc_failures++; - } else { - if (site) { - log_event5(logfp, TM_EVENT_MALLOC, - site->serial, start, end - start, - (uint32_t)NS_PTR_TO_INT32(ptr), size); - } - if (get_allocations()) { - he = PL_HashTableAdd(allocations, ptr, site); - if (he) { - alloc = (allocation*) he; - alloc->size = size; - alloc->trackfp = NULL; - } - } - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(void) -CallocCallback(void *ptr, size_t count, size_t size, uint32_t start, uint32_t end, tm_thread *t) -{ - callsite *site; - PLHashEntry *he; - allocation *alloc; - int immediate_abort; - - if (!tracing_enabled || t->suppress_tracing != 0) - return; - - site = backtrace(t, 2, &immediate_abort); - if (immediate_abort) - return; - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - tmstats.calloc_calls++; - if (!ptr) { - tmstats.calloc_failures++; - } else { - size *= count; - if (site) { - log_event5(logfp, TM_EVENT_CALLOC, - site->serial, start, end - start, - (uint32_t)NS_PTR_TO_INT32(ptr), size); - } - if (get_allocations()) { - he = PL_HashTableAdd(allocations, ptr, site); - if (he) { - alloc = (allocation*) he; - alloc->size = size; - alloc->trackfp = NULL; - } - } - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(void) -ReallocCallback(void * oldptr, void *ptr, size_t size, - uint32_t start, uint32_t end, tm_thread *t) -{ - callsite *oldsite, *site; - size_t oldsize; - PLHashNumber hash; - PLHashEntry **hep, *he; - allocation *alloc; - FILE *trackfp = NULL; - int immediate_abort; - - if (!tracing_enabled || t->suppress_tracing != 0) - return; - - site = backtrace(t, 2, &immediate_abort); - if (immediate_abort) - return; - - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - tmstats.realloc_calls++; - oldsite = NULL; - oldsize = 0; - hep = NULL; - he = NULL; - if (oldptr && get_allocations()) { - hash = hash_pointer(oldptr); - hep = PL_HashTableRawLookup(allocations, hash, oldptr); - he = *hep; - if (he) { - oldsite = (callsite*) he->value; - alloc = (allocation*) he; - oldsize = alloc->size; - trackfp = alloc->trackfp; - if (trackfp) { - fprintf(alloc->trackfp, - "\nrealloc(%p, %lu), oldsize %lu, alloc site %p\n", - (void*) ptr, (unsigned long) size, - (unsigned long) oldsize, (void*) oldsite); - NS_TraceStack(1, trackfp); - } - } - } - if (!ptr && size) { - /* - * When realloc() fails, the original block is not freed or moved, so - * we'll leave the allocation entry untouched. - */ - tmstats.realloc_failures++; - } else { - if (site) { - log_event8(logfp, TM_EVENT_REALLOC, - site->serial, start, end - start, - (uint32_t)NS_PTR_TO_INT32(ptr), size, - oldsite ? oldsite->serial : 0, - (uint32_t)NS_PTR_TO_INT32(oldptr), oldsize); - } - if (ptr && allocations) { - if (ptr != oldptr) { - /* - * If we're reallocating (not allocating new space by passing - * null to realloc) and realloc moved the block, free oldptr. - */ - if (he) - PL_HashTableRawRemove(allocations, hep, he); - - /* Record the new allocation now, setting he. */ - he = PL_HashTableAdd(allocations, ptr, site); - } else { - /* - * If we haven't yet recorded an allocation (possibly due to a - * temporary memory shortage), do it now. - */ - if (!he) - he = PL_HashTableAdd(allocations, ptr, site); - } - if (he) { - alloc = (allocation*) he; - alloc->size = size; - alloc->trackfp = trackfp; - } - } - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(void) -FreeCallback(void * ptr, uint32_t start, uint32_t end, tm_thread *t) -{ - PLHashEntry **hep, *he; - callsite *site; - allocation *alloc; - - if (!tracing_enabled || t->suppress_tracing != 0) - return; - - /* - * FIXME: Perhaps we should call backtrace() so we can check for - * immediate_abort. However, the only current contexts where - * immediate_abort will be true do not call free(), so for now, - * let's avoid the cost of backtrace(). See bug 478195. - */ - TM_SUPPRESS_TRACING_AND_ENTER_LOCK(t); - tmstats.free_calls++; - if (!ptr) { - tmstats.null_free_calls++; - } else { - if (get_allocations()) { - hep = PL_HashTableRawLookup(allocations, hash_pointer(ptr), ptr); - he = *hep; - if (he) { - site = (callsite*) he->value; - if (site) { - alloc = (allocation*) he; - if (alloc->trackfp) { - fprintf(alloc->trackfp, "\nfree(%p), alloc site %p\n", - (void*) ptr, (void*) site); - NS_TraceStack(1, alloc->trackfp); - } - log_event5(logfp, TM_EVENT_FREE, - site->serial, start, end - start, - (uint32_t)NS_PTR_TO_INT32(ptr), alloc->size); - } - PL_HashTableRawRemove(allocations, hep, he); - } - } - } - TM_EXIT_LOCK_AND_UNSUPPRESS_TRACING(t); -} - -PR_IMPLEMENT(nsTMStackTraceID) -NS_TraceMallocGetStackTrace(void) -{ - callsite *site; - int dummy; - tm_thread *t = tm_get_thread(); - - PR_ASSERT(t->suppress_tracing == 0); - - site = backtrace(t, 2, &dummy); - return (nsTMStackTraceID) site; -} - -PR_IMPLEMENT(void) -NS_TraceMallocPrintStackTrace(FILE *ofp, nsTMStackTraceID id) -{ - print_stack(ofp, (callsite *)id); -} - -#endif /* NS_TRACE_MALLOC */ diff --git a/tools/trace-malloc/lib/nsTraceMalloc.h b/tools/trace-malloc/lib/nsTraceMalloc.h deleted file mode 100644 index 4d1a89214a91..000000000000 --- a/tools/trace-malloc/lib/nsTraceMalloc.h +++ /dev/null @@ -1,226 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 nsTraceMalloc_h___ -#define nsTraceMalloc_h___ - -#include -#include /* for FILE */ -#include "prtypes.h" - -#ifdef XP_WIN -#define setlinebuf(stream) setvbuf((stream), (char *)NULL, _IOLBF, 0) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Magic "number" at start of a trace-malloc log file. Inspired by the PNG - * magic string, which inspired XPCOM's typelib (.xpt) file magic. See the - * NS_TraceMallocStartup comment (below) for magic number differences in log - * file structure. - */ -#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog08\r\n\032" -#define NS_TRACE_MALLOC_MAGIC_SIZE 16 - -/** - * Trace-malloc stats, traced via the 'Z' event at the end of a log file. - */ -typedef struct nsTMStats { - uint32_t calltree_maxstack; - uint32_t calltree_maxdepth; - uint32_t calltree_parents; - uint32_t calltree_maxkids; - uint32_t calltree_kidhits; - uint32_t calltree_kidmisses; - uint32_t calltree_kidsteps; - uint32_t callsite_recurrences; - uint32_t backtrace_calls; - uint32_t backtrace_failures; - uint32_t btmalloc_failures; - uint32_t dladdr_failures; - uint32_t malloc_calls; - uint32_t malloc_failures; - uint32_t calloc_calls; - uint32_t calloc_failures; - uint32_t realloc_calls; - uint32_t realloc_failures; - uint32_t free_calls; - uint32_t null_free_calls; -} nsTMStats; - -#define NS_TMSTATS_STATIC_INITIALIZER {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} - -/** - * Call NS_TraceMallocStartup with a valid file descriptor to enable logging - * of compressed malloc traces, including callsite chains. Integers may be - * unsigned serial numbers, sizes, or offsets, and require at most 32 bits. - * They're encoded as follows: - * 0-127 0xxxxxxx (binary, one byte) - * 128-16383 10xxxxxx xxxxxxxx - * 16384-0x1fffff 110xxxxx xxxxxxxx xxxxxxxx - * 0x200000-0xfffffff 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx - * 0x10000000-0xffffffff 11110000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx - * Strings are NUL-terminated ASCII. - * - * Event Operands (magic TMLog01) - * 'L' library serial, shared object filename string - * 'N' method serial, library serial, demangled name string - * 'S' site serial, parent serial, method serial, calling pc offset - * 'M' site serial, malloc size - * 'C' site serial, calloc size - * 'R' site serial, realloc oldsize, realloc size - * 'F' site serial, free size - * - * Event Operands (magic TMLog02) - * 'Z' serialized struct tmstats (20 unsigned integers), - * maxkids parent callsite serial, - * maxstack top callsite serial - * - * Event Operands (magic TMLog03) - * 'T' seconds, microseconds, caption - * - * Event Operands (magic TMLog04) - * 'R' site serial, realloc size, old site serial, realloc oldsize - * - * Event Operands (magic TMLog05) - * 'M' site serial, address, malloc size - * 'C' site serial, address, calloc size - * 'R' site serial, address, realloc size, old site serial, - * old address, old size - * 'F' site serial, address, free size - * - * Event Operands (magic TMLog06) - * 'M' site serial, interval time (end), address, malloc size - * 'C' site serial, interval time (end), address, calloc size - * 'R' site serial, interval time (end), address, realloc size, - * old site serial, old address, old size - * 'F' site serial, interval time (end), address, free size - * - * Event Operands (magic TMLog07) - * 'M' site serial, interval time (start), duration, address, malloc size - * 'C' site serial, interval time (start), duration, address, calloc size - * 'R' site serial, interval time (start), duration, address, realloc size, - * old site serial, old address, old size - * 'F' site serial, interval time (start), duration, address, free size - * - * Event Operands (magic TMLog08) - * 'G' filename serial, source filename string. - * 'N' method serial, library serial, source filename serial, - * source file linenumber, demangled name string - * - * See tools/trace-malloc/bloatblame.c for an example log-file reader. - */ -#define TM_EVENT_LIBRARY 'L' -#define TM_EVENT_FILENAME 'G' -#define TM_EVENT_METHOD 'N' -#define TM_EVENT_CALLSITE 'S' -#define TM_EVENT_MALLOC 'M' -#define TM_EVENT_CALLOC 'C' -#define TM_EVENT_REALLOC 'R' -#define TM_EVENT_FREE 'F' -#define TM_EVENT_STATS 'Z' -#define TM_EVENT_TIMESTAMP 'T' - -PR_EXTERN(void) NS_TraceMallocStartup(int logfd); - -/** - * Initialize malloc tracing, using the ``standard'' startup arguments. - */ -PR_EXTERN(int) NS_TraceMallocStartupArgs(int argc, char* argv[]); - -/** - * Return PR_TRUE iff |NS_TraceMallocStartup[Args]| has been successfully called. - */ -PR_EXTERN(PRBool) NS_TraceMallocHasStarted(void); - -/** - * Stop all malloc tracing, flushing any buffered events to the logfile. - */ -PR_EXTERN(void) NS_TraceMallocShutdown(void); - -/** - * Disable malloc tracing. - */ -PR_EXTERN(void) NS_TraceMallocDisable(void); - -/** - * Enable malloc tracing. - */ -PR_EXTERN(void) NS_TraceMallocEnable(void); - -/** - * Change the log file descriptor, flushing any buffered output to the old - * fd, and writing NS_TRACE_MALLOC_MAGIC to the new file if it is zero length. - * Return the old fd, so the caller can swap open fds. Return -2 on failure, - * which means malloc failure. - */ -PR_EXTERN(int) NS_TraceMallocChangeLogFD(int fd); - -/** - * Close the file descriptor fd and forget any bookkeeping associated with it. - * Do nothing if fd is -1. - */ -PR_EXTERN(void) NS_TraceMallocCloseLogFD(int fd); - -/** - * Emit a timestamp event with the given caption to the current log file. - */ -PR_EXTERN(void) NS_TraceMallocLogTimestamp(const char *caption); - -/** - * Walk the stack, dumping frames in standard form to ofp. If skip is 0, - * exclude the frames for NS_TraceStack and anything it calls to do the walk. - * If skip is less than 0, include -skip such frames. If skip is positive, - * exclude that many frames leading to the call to NS_TraceStack. - */ -PR_EXTERN(void) -NS_TraceStack(int skip, FILE *ofp); - -/** - * Dump a human-readable listing of current allocations and their compressed - * stack backtraces to the file named by pathname. Beware this file may have - * very long lines. - * - * Return -1 on error with errno set by the system, 0 on success. - */ -PR_EXTERN(int) -NS_TraceMallocDumpAllocations(const char *pathname); - -/** - * Flush all logfile buffers. - */ -PR_EXTERN(void) -NS_TraceMallocFlushLogfiles(void); - -/** - * Track all realloc and free calls operating on a given allocation. - */ -PR_EXTERN(void) -NS_TrackAllocation(void* ptr, FILE *ofp); - -/* opaque type for API */ -typedef struct nsTMStackTraceIDStruct *nsTMStackTraceID; - -/** - * Get an identifier for the stack trace of the current thread (to this - * function's callsite) that can be used to print that stack trace later. - */ -PR_EXTERN(nsTMStackTraceID) -NS_TraceMallocGetStackTrace(void); - -/** - * Print the stack trace identified. - */ -PR_EXTERN(void) -NS_TraceMallocPrintStackTrace(FILE *ofp, nsTMStackTraceID id); - -#ifdef __cplusplus -} -#endif - -#endif /* nsTraceMalloc_h___ */ diff --git a/tools/trace-malloc/lib/nsTraceMallocCallbacks.h b/tools/trace-malloc/lib/nsTraceMallocCallbacks.h deleted file mode 100644 index 7e97cb273c0d..000000000000 --- a/tools/trace-malloc/lib/nsTraceMallocCallbacks.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* declarations needed by both nsTraceMalloc.c and nsWinTraceMalloc.cpp */ - -#ifndef NSTRACEMALLOCCALLBACKS_H -#define NSTRACEMALLOCCALLBACKS_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Used by backtrace. */ -typedef struct stack_buffer_info { - void **buffer; - size_t size; - size_t entries; -} stack_buffer_info; - -typedef struct tm_thread tm_thread; -struct tm_thread { - /* - * This counter suppresses tracing, in case any tracing code needs - * to malloc. - */ - uint32_t suppress_tracing; - - /* buffer for backtrace, below */ - stack_buffer_info backtrace_buf; -}; - -/* implemented in nsTraceMalloc.c */ -tm_thread * tm_get_thread(void); - -/* implemented in nsTraceMalloc.c */ -PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, uint32_t start, uint32_t end, tm_thread *t); -PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, uint32_t start, uint32_t end, tm_thread *t); -PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, uint32_t start, uint32_t end, tm_thread *t); -PR_EXTERN(void) FreeCallback(void *aPtr, uint32_t start, uint32_t end, tm_thread *t); - -#ifdef XP_WIN32 -/* implemented in nsTraceMalloc.c */ -PR_EXTERN(void) StartupHooker(); -PR_EXTERN(void) ShutdownHooker(); - -/* implemented in nsWinTraceMalloc.cpp */ -void* dhw_orig_malloc(size_t); -void* dhw_orig_calloc(size_t, size_t); -void* dhw_orig_realloc(void*, size_t); -void dhw_orig_free(void*); - -#endif /* defined(XP_WIN32) */ - -#ifdef __cplusplus -} -#endif - -#endif /* !defined(NSTRACEMALLOCCALLBACKS_H) */ diff --git a/tools/trace-malloc/lib/nsTypeInfo.cpp b/tools/trace-malloc/lib/nsTypeInfo.cpp deleted file mode 100644 index 2a4ae4bb7ef1..000000000000 --- a/tools/trace-malloc/lib/nsTypeInfo.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* - typeinfo.cpp - - Speculatively use RTTI on a random object. If it contains a pointer at offset 0 - that is in the current process' address space, and that so on, then attempt to - use C++ RTTI's typeid operation to obtain the name of the type. - - by Patrick C. Beard. - */ - -#include /* Needed for MSVC2010 due to bug 1055675 */ -#include -#include - -#include "nsTypeInfo.h" - -extern "C" void NS_TraceMallocShutdown(); - -struct TraceMallocShutdown { - TraceMallocShutdown() {} - ~TraceMallocShutdown() { - NS_TraceMallocShutdown(); - } -}; - -extern "C" void RegisterTraceMallocShutdown() { - // This instanciates the dummy class above, and will trigger the class - // destructor when libxul is unloaded. This is equivalent to atexit(), - // but gracefully handles dlclose(). - static TraceMallocShutdown t; -} - -class IUnknown { -public: - virtual long QueryInterface() = 0; - virtual long AddRef() = 0; - virtual long Release() = 0; -}; - -#if defined(MACOS) - -#include - -class AddressSpace { -public: - AddressSpace(); - Boolean contains(void* ptr); -private: - ProcessInfoRec mInfo; -}; - -AddressSpace::AddressSpace() -{ - ProcessSerialNumber psn = { 0, kCurrentProcess }; - mInfo.processInfoLength = sizeof(mInfo); - ::GetProcessInformation(&psn, &mInfo); -} - -Boolean AddressSpace::contains(void* ptr) -{ - UInt32 start = UInt32(mInfo.processLocation); - return (UInt32(ptr) >= start && UInt32(ptr) < (start + mInfo.processSize)); -} - -const char* nsGetTypeName(void* ptr) -{ - // construct only one of these per process. - static AddressSpace space; - - // sanity check the vtable pointer, before trying to use RTTI on the object. - void** vt = *(void***)ptr; - if (vt && !(unsigned(vt) & 0x3) && space.contains(vt) && space.contains(*vt)) { - IUnknown* u = static_cast(ptr); - const char* type = typeid(*u).name(); - // make sure it looks like a C++ identifier. - if (type && (isalnum(type[0]) || type[0] == '_')) - return type; - } - return "void*"; -} - -#endif - -// New, more "portable" Linux code is below, but this might be a useful -// model for other platforms, so keeping. -//#if defined(linux) -#if 0 - -#include -#include - -static jmp_buf context; - -static void handler(int signum) -{ - longjmp(context, signum); -} - -#define attempt() setjmp(context) - -class Signaller { -public: - Signaller(int signum); - ~Signaller(); - -private: - typedef void (*handler_t) (int signum); - int mSignal; - handler_t mOldHandler; -}; - -Signaller::Signaller(int signum) - : mSignal(signum), mOldHandler(signal(signum, &handler)) -{ -} - -Signaller::~Signaller() -{ - signal(mSignal, mOldHandler); -} - -// The following are pointers that bamboozle our otherwise feeble -// attempts to "safely" collect type names. -// -// XXX this kind of sucks because it means that anyone trying to use -// this without NSPR will get unresolved symbols when this library -// loads. It's also not very extensible. Oh well: FIX ME! -extern "C" { - // from nsprpub/pr/src/io/priometh.c (libnspr4.so) - extern void* _pr_faulty_methods; -}; - -static inline int -sanity_check_vtable_i386(void** vt) -{ - // Now that we're "safe" inside the signal handler, we can - // start poking around. If we're really an object with - // RTTI, then the second entry in the vtable should point - // to a function. - // - // Let's see if the second entry: - // - // 1) looks like a 4-byte aligned pointer - // - // 2) points to something that looks like the following - // i386 instructions: - // - // 55 push %ebp - // 89e5 mov %esp,%ebp - // 53 push %ebx - // - // or - // - // 55 push %ebp - // 89e5 mov %esp,%ebp - // 56 push %esi - // - // (which is the standard function prologue generated - // by egcs, plus a ``signature'' instruction that appears - // in the typeid() function's implementation). - unsigned char** fp1 = reinterpret_cast(vt) + 1; - - // Does it look like an address? - unsigned char* ip = *fp1; - if ((unsigned(ip) & 3) != 0) - return 0; - - // Does it look like it refers to the standard prologue? - static unsigned char prologue[] = { 0x55, 0x89, 0xE5 }; - for (unsigned i = 0; i < sizeof(prologue); ++i) - if (*ip++ != prologue[i]) - return 0; - - // Is the next instruction a `push %ebx' or `push %esi'? - if (*ip == 0x53 || *ip == 0x56) { - return 1; - } - - // Nope. There's another variant that has a `sub' instruction, - // followed by a `cmpl' and a `jne'. Check for that. - if (ip[0] == 0x83 && ip[1] == 0xec // sub - && ip[3] == 0x83 && ip[4] == 0x3d // cmpl - && ip[10] == 0x75 // jne - ) { - return 1; - } - - return 0; -} - -static inline int -sanity_check_vtable_ppc(void** vt) -{ - // XXX write me! - return 1; -} - -#if defined(__i386) -# define SANITY_CHECK_VTABLE(vt) (sanity_check_vtable_i386(vt)) -#elif defined(PPC) -# define SANITY_CHECK_VTABLE(vt) (sanity_check_vtable_ppc(vt)) -#else -# define SANITY_CHECK_VTABLE(vt) (1) -#endif - -const char* nsGetTypeName(void* ptr) -{ - // sanity check the vtable pointer, before trying to use RTTI on the object. - void** vt = *(void***)ptr; - if (vt && !(unsigned(vt) & 3) && (vt != &_pr_faulty_methods)) { - Signaller s1(SIGSEGV); - if (attempt() == 0) { - if (SANITY_CHECK_VTABLE(vt)) { - // Looks like a function: what the hell, let's call it. - IUnknown* u = static_cast(ptr); - const char* type = typeid(*u).name(); - // EGCS seems to prefix a length string. - while (isdigit(*type)) ++type; - return type; - } - } - } - return "void*"; -} - -#endif - -#if defined(linux) || defined(XP_MACOSX) - -#define __USE_GNU -#include -#include -#include - -const char* nsGetTypeName(void* ptr) -{ -#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */ - const int expected_offset = 8; - const char vtable_sym_start[] = "_ZTV"; - const int vtable_sym_start_length = sizeof(vtable_sym_start) - 1; -#else - const int expected_offset = 0; - const char vtable_sym_start[] = "__vt_"; - const int vtable_sym_start_length = sizeof(vtable_sym_start) - 1; -#endif - void* vt = *(void**)ptr; - Dl_info info; - // If dladdr fails, if we're not at the expected offset in the vtable, - // or if the symbol name isn't a vtable symbol name, return "void*". - if ( !dladdr(vt, &info) || - ((char*)info.dli_saddr) + expected_offset != vt || - !info.dli_sname || - strncmp(info.dli_sname, vtable_sym_start, vtable_sym_start_length)) - return "void*"; - - // skip the garbage at the beginning of things like - // __vt_14nsRootBoxFrame (gcc 2.96) or _ZTV14nsRootBoxFrame (gcc 3.0) - const char* rv = info.dli_sname + vtable_sym_start_length; - while (*rv && isdigit(*rv)) - ++rv; - return rv; -} - -#endif - -#ifdef XP_WIN32 -const char* nsGetTypeName(void* ptr) -{ - //TODO: COMPLETE THIS - return "void*"; -} - -#endif //XP_WIN32 diff --git a/tools/trace-malloc/lib/nsTypeInfo.h b/tools/trace-malloc/lib/nsTypeInfo.h deleted file mode 100644 index 55af69f03273..000000000000 --- a/tools/trace-malloc/lib/nsTypeInfo.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 trace_malloc_nsTypeInfo_h_ -#define trace_malloc_nsTypeInfo_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char* nsGetTypeName(void* ptr); - -extern void RegisterTraceMallocShutdown(); - -#ifdef __cplusplus -} -#endif - -#endif /* trace_malloc_nsTypeInfo_h_ */ diff --git a/tools/trace-malloc/lib/nsWinTraceMalloc.cpp b/tools/trace-malloc/lib/nsWinTraceMalloc.cpp deleted file mode 100644 index 84a42ffbbcf7..000000000000 --- a/tools/trace-malloc/lib/nsWinTraceMalloc.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include - -#include "prinrval.h" -#include "prlock.h" -#include "nscore.h" - -#include "nsDebugHelpWin32.h" -#include "nsTraceMallocCallbacks.h" - -/***************************************************************************/ -// shows how to use the dhw stuff to hook imported functions - -#if _MSC_VER == 1600 -#define NS_DEBUG_CRT "msvcr100d.dll" -#elif _MSC_VER == 1700 -#define NS_DEBUG_CRT "msvcr110d.dll" -#elif _MSC_VER == 1800 -#define NS_DEBUG_CRT "msvcr120d.dll" -#else -#error "Don't know filename of MSVC debug library." -#endif - -decltype(malloc) dhw_malloc; - -DHWImportHooker &getMallocHooker() -{ - static DHWImportHooker gMallocHooker(NS_DEBUG_CRT, "malloc", (PROC) dhw_malloc); - return gMallocHooker; -} - -void * __cdecl dhw_malloc( size_t size ) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - void* result = DHW_ORIGINAL(malloc, getMallocHooker())(size); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - MallocCallback(result, size, start, end, t); - return result; -} - -decltype(calloc) dhw_calloc; - -DHWImportHooker &getCallocHooker() -{ - static DHWImportHooker gCallocHooker(NS_DEBUG_CRT, "calloc", (PROC) dhw_calloc); - return gCallocHooker; -} - -void * __cdecl dhw_calloc( size_t count, size_t size ) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - void* result = DHW_ORIGINAL(calloc, getCallocHooker())(count,size); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - CallocCallback(result, count, size, start, end, t); - return result; -} - -decltype(free) dhw_free; -DHWImportHooker &getFreeHooker() -{ - static DHWImportHooker gFreeHooker(NS_DEBUG_CRT, "free", (PROC) dhw_free); - return gFreeHooker; -} - -void __cdecl dhw_free( void* p ) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - DHW_ORIGINAL(free, getFreeHooker())(p); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - /* FIXME bug 392008: We could race with reallocation of p. */ - FreeCallback(p, start, end, t); -} - - -decltype(realloc) dhw_realloc; -DHWImportHooker &getReallocHooker() -{ - static DHWImportHooker gReallocHooker(NS_DEBUG_CRT, "realloc", (PROC) dhw_realloc); - return gReallocHooker; -} - -void * __cdecl dhw_realloc(void * pin, size_t size) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - void* pout = DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - /* FIXME bug 392008: We could race with reallocation of pin. */ - ReallocCallback(pin, pout, size, start, end, t); - return pout; -} - -// Note the mangled name! -void * __cdecl dhw_new(size_t size); -DHWImportHooker &getNewHooker() -{ - static DHWImportHooker gNewHooker(NS_DEBUG_CRT, "??2@YAPAXI@Z", (PROC) dhw_new); - return gNewHooker; -} - -void * __cdecl dhw_new(size_t size) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - void* result = DHW_ORIGINAL(dhw_new, getNewHooker())(size); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - MallocCallback(result, size, start, end, t);//do we need a different one for new? - return result; -} - -// Note the mangled name! -void __cdecl dhw_delete(void* p); -DHWImportHooker &getDeleteHooker() -{ - static DHWImportHooker gDeleteHooker(NS_DEBUG_CRT, "??3@YAXPAX@Z", (PROC) dhw_delete); - return gDeleteHooker; -} - -void __cdecl dhw_delete(void* p) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - DHW_ORIGINAL(dhw_delete, getDeleteHooker())(p); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - FreeCallback(p, start, end, t); -} - -// Note the mangled name! -void * __cdecl dhw_vec_new(size_t size); -DHWImportHooker &getVecNewHooker() -{ - static DHWImportHooker gVecNewHooker(NS_DEBUG_CRT, "??_U@YAPAXI@Z", (PROC) dhw_vec_new); - return gVecNewHooker; -} - -void * __cdecl dhw_vec_new(size_t size) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; // need to suppress since new[] calls new - uint32_t start = PR_IntervalNow(); - void* result = DHW_ORIGINAL(dhw_vec_new, getVecNewHooker())(size); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - MallocCallback(result, size, start, end, t);//do we need a different one for new[]? - return result; -} - -// Note the mangled name! -void __cdecl dhw_vec_delete(void* p); -DHWImportHooker &getVecDeleteHooker() -{ - static DHWImportHooker gVecDeleteHooker(NS_DEBUG_CRT, "??_V@YAXPAX@Z", (PROC) dhw_vec_delete); - return gVecDeleteHooker; -} - -void __cdecl dhw_vec_delete(void* p) -{ - tm_thread *t = tm_get_thread(); - ++t->suppress_tracing; - uint32_t start = PR_IntervalNow(); - DHW_ORIGINAL(dhw_vec_delete, getVecDeleteHooker())(p); - uint32_t end = PR_IntervalNow(); - --t->suppress_tracing; - FreeCallback(p, start, end, t); -} - -/*C Callbacks*/ -PR_IMPLEMENT(void) -StartupHooker() -{ - //run through get all hookers - DHWImportHooker &loadlibraryW = DHWImportHooker::getLoadLibraryWHooker(); - DHWImportHooker &loadlibraryExW = DHWImportHooker::getLoadLibraryExWHooker(); - DHWImportHooker &loadlibraryA = DHWImportHooker::getLoadLibraryAHooker(); - DHWImportHooker &loadlibraryExA = DHWImportHooker::getLoadLibraryExAHooker(); - DHWImportHooker &mallochooker = getMallocHooker(); - DHWImportHooker &reallochooker = getReallocHooker(); - DHWImportHooker &callochooker = getCallocHooker(); - DHWImportHooker &freehooker = getFreeHooker(); - DHWImportHooker &newhooker = getNewHooker(); - DHWImportHooker &deletehooker = getDeleteHooker(); - DHWImportHooker &vecnewhooker = getVecNewHooker(); - DHWImportHooker &vecdeletehooker = getVecDeleteHooker(); - printf("Startup Hooker\n"); -} - -PR_IMPLEMENT(void) -ShutdownHooker() -{ -} - -extern "C" { - void* dhw_orig_malloc(size_t); - void* dhw_orig_calloc(size_t, size_t); - void* dhw_orig_realloc(void*, size_t); - void dhw_orig_free(void*); -} - -void* -dhw_orig_malloc(size_t size) -{ - return DHW_ORIGINAL(malloc, getMallocHooker())(size); -} - -void* -dhw_orig_calloc(size_t count, size_t size) -{ - return DHW_ORIGINAL(calloc, getCallocHooker())(count,size); -} - -void* -dhw_orig_realloc(void* pin, size_t size) -{ - return DHW_ORIGINAL(realloc, getReallocHooker())(pin, size); -} - -void -dhw_orig_free(void* p) -{ - DHW_ORIGINAL(free, getFreeHooker())(p); -} diff --git a/tools/trace-malloc/lib/tm.def b/tools/trace-malloc/lib/tm.def deleted file mode 100644 index 9bd3b8cc61a9..000000000000 --- a/tools/trace-malloc/lib/tm.def +++ /dev/null @@ -1,19 +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/. - -LIBRARY tracemalloc.dll - -EXPORTS - -NS_TraceMallocStartup -NS_TraceMallocStartupArgs -NS_TraceMallocShutdown -NS_TraceMallocDisable -NS_TraceMallocEnable -NS_TraceMallocChangeLogFD -NS_TraceMallocCloseLogFD -NS_TraceMallocLogTimestamp -NS_TraceStack -NS_TraceMallocDumpAllocations -NS_TraceMallocFlushLogfiles diff --git a/tools/trace-malloc/live-bloat.html b/tools/trace-malloc/live-bloat.html deleted file mode 100644 index 73a881f806df..000000000000 --- a/tools/trace-malloc/live-bloat.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - -Live Bloat Dump - - - - - \ No newline at end of file diff --git a/tools/trace-malloc/merge.pl b/tools/trace-malloc/merge.pl deleted file mode 100755 index 4efef18ff54f..000000000000 --- a/tools/trace-malloc/merge.pl +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/perl -# 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/. - - -$argv = $ARGV[0]; -open( bloatFile, $argv ) or die "Can't open $argv: $!\n"; -while () { - if (/name=/) { - ($td,$name,$func,$a,$ntd) = split(/>/, $_); - ($fname, $memSize) = split( / /, $func ); - ($trash, $linkName) = split( /"/, $name ); - $namesLinks{$fname} = $linkName; - if ($namesSizes{$fname}) { - $namesSizes{$fname} = $namesSizes{$fname} + $memSize; - } - else { - $namesSizes{$fname} = $memSize; - } - } -} - -$argv = $ARGV[1]; -if ($argv) -{ - open( bloatFile, $argv ) or die "Can't open $argv: $!\n"; - while () { - if (/name=/) { - ($td,$name,$func,$a,$ntd) = split(/>/, $_); - ($fname, $memSize) = split( / /, $func ); - $namesSizes{$fname} = $namesSizes{$fname} - $memSize; - } - } -} - -sub byvalue { $namesSizes{$b} <=> $namesSizes{$a} } - - -print ''; -print "\n\n"; -print "Bloat Blame Delta\n"; -print ''; -print "\n\n\n\n"; -print "\n"; - -foreach $key (sort byvalue keys %namesSizes) { - if ($namesSizes{$key}) - { - print "\n"; - print ' \n"; - print " \n"; - print "\n" - } -} - -print "
Memory AllocatedFunction NameLink
', $namesSizes{$key}," ", $key, "
\n"; diff --git a/tools/trace-malloc/moz.build b/tools/trace-malloc/moz.build deleted file mode 100644 index cc3f78dc0317..000000000000 --- a/tools/trace-malloc/moz.build +++ /dev/null @@ -1,34 +0,0 @@ -# -*- 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/. - -if not CONFIG['MOZ_PROFILE_GENERATE']: - Program('spacetrace') - SOURCES += [ - 'formdata.c', - 'spacecategory.c', - 'spacetrace.c', - ] - -bin_suffix = CONFIG['BIN_SUFFIX'] - - -SOURCES += [ - 'tmreader.c', -] - -SimplePrograms([ - 'leakstats', - 'tmstats', -], ext='.c') - -GeckoSimplePrograms([ - 'bloatblame', - 'leaksoup', -]) - -RESOURCE_FILES += [ - 'spacetrace.css' -] diff --git a/tools/trace-malloc/rules.txt b/tools/trace-malloc/rules.txt deleted file mode 100644 index 95e55119ae4c..000000000000 --- a/tools/trace-malloc/rules.txt +++ /dev/null @@ -1,442 +0,0 @@ -# Categorization rules for spacetrace -# -# This file defines the stack frame rules that will categorize -# allocations that spacetrace processes. The format of this file is -# -# -# initial string match for stack frame n -# initial string match for stack frame n+1 -# initial string match for stack frame n+2 -# -# The key in the matching rule is that for every rule, we provide a -# snippet of the stack frame - contiguous substring matches. -# categorynames and rules substring matches are case sensitive -# -# Predefined Categories -# "All" - All allocations [default] -# "uncategorized" - All allocations that don't match any category -# -# -# Suresh Duddi -########################################################################### -# NOTE: This is still under definition -########################################################################### -# General principle of categorization: -# -# - Each category, in general, denotes a module or feature. -# -# - We assign each allocation to the module/feature that directly -# caused the allocation irrespective of which higher level module -# caused the allocation. There are very few exceptions usually when -# an allocation belongs both to a feature-category and to a -# module-category. -# -# bookmarks -# Bookmarks. Mainly initialization. Does not include menu cost. -# css -# Cascading style sheets -# dom -# Memory held by DOM. -# font -# All font stuff -# global-history -# html -# html parsing and layout -# layout -# reflow, frames, line, view -# images -# All images. -# jar -# jar, zip -# js -# javascript -# necko -# All protocol and uri stuff. All urls created accounted here -# preferences -# Preferences stuff. All js cost for preferences is included here. -## rdf -# Most of the rdf allocations. rdf cost from xul, chromeregistry, -# is assigned to xul. -# -# wallet -# Form cache. -# -# xbl -# xbl stuff. Includes js in xbl. -# xpcom -# xpcom, xpt. Allocations for creations of objects are assigned -# onto the respective modules -# xul -# XUL parsing and layout. Includes rdf overhead from xul like -# nsChromeRegistry -# - - -# - -# =========================================================================== -# Leaf rules. We categorize them out first. -# All allocations matching these rules DO belong to the category. -# =========================================================================== - - -nsXULPrototypeScript::Deserialize - - -XSupportsLocale - - -/usr/X11R6/lib/libX11.so - - -JS_Init - - -NS_NewPermanentAtom - - -gif_write - - -imgRequest::OnDataAvailable - - -imgLoader:: - - -jinit_master_decompress - - -jinit_marker_reader - - -jinit_marker_decompress - - -nsJPEGDecoder:: - - -nsGIFDecoder2:: - - -nsZipArchive::BuildFileList - - -nsZipArchive::ReadInit - - -nsJARChannel::Open - - -NS_InitXPCOM2 - -# xpt file loads - -xptiInterfaceInfoManager::LoadFile - - -nsGenericModule::Initialize - - -nsStringBundle - - -nsLocale:: - - -nsCharsetConverterManager:: - - -nsDiskCacheDevice::Init - - -nsCacheEntryDescriptor::nsTransportWrapper::OpenOutputStream - - -nsSocketTransport:: - - -nsCacheService:: - - -nsDiskCacheStreamIO:: - - -nsHttpResponseHead:: - - -WLLT - - -nsXULElement::Create - - -nsXULAttribute::Create - - -nsXULDocument::AddElementToMap - - -XULContentSinkImpl::AddAttributes - - -XULContentSinkImpl::CreateElement - - -nsXULElement::SetAttr - - -nsXULDocument::InsertElement - - -NS_NewXULContentBuilder - - -nsXULElement::AppendChildTo - - -nsXBLPrototypeHandler::AppendHandlerText( - - -FrameArena::AllocateFrame - - -nsGlobalHistory::OpenDB - - -nsFontCache:: - - -nsFont::nsFont - - -gtk_init - - -RDFServiceImpl::GetResource - - -RDFContentSinkImpl::AddProperties - - -RDFContainerImpl::AppendElement - - -RDFXMLDataSourceImpl::Assert - - -NS_NewRDFInMemoryDataSource - - -CSSLoaderImpl::ParseSheet - - -CSSParserImpl::Parse( - - -NS_NewCSS - - -RuleHash::AppendRule - - -nsRuleNode::GetStyleData - - -SelectorList:: - - -CSSRuleProcessor::RulesMatching - - -CSSStyleSheetImpl::Clone - - -nsHttpHeaderArray:: - - -nsScanner::Append - - -nsHTMLTokenizer:: - - -NS_NewHTMLTokenizer - - -nsSlidingString:: - - -nsParser:: - - -nsIParserService:: - - -nsCParserNode:: - - -CNavDTD::CNavDTD - - -nsHTMLDocument:: - - -IncrementalReflow::AddCommand - - -nsBlockFrame:: - - -nsBoxFrame:: - - -nsImageFrame:: - - -nsInlineFrame:: - - -nsLeafFrame:: - - -nsLineLayout:: - - -nsReflowPath::EnsureSubtreeFor - - -nsSliderFrame:: - - -nsScrollBoxFrame:: - - -nsTextFrame:: - - -nsTableRowFrame:: - - -nsTableRowGroupFrame:: - - -nsViewManager:: - - -PresShell::ProcessReflowCommands - - -# ====================================================================== -# Rules that match higher up on the stack -# These go later. -# ====================================================================== - - -PREF_ - - -nsBookmarksService:: - - -nsXBLService::LoadBindings - - -nsXBLBinding::ExecuteAttachedHandler - - -nsXULDocument::LoadScript - - -nsXULDocument::ExecuteScript - - -XULContentSinkImpl::Open - - -RDFContentSinkImpl::HandleEndElement - - -HTMLContentSink::AddAttributes - - -HTMLContentSink::OpenContainer - - -HTMLContentSink::CloseContainer - -# XXX whom to account LoadImage to? I am going with images. - -imgLoader::LoadImage - - -StackArena:: - -# ====================================================================== -# Even more genralized rules. There could be lots of activity that -# happens below them in the stack. But we are sure we have categorized -# a lot of them by using the rules above and know the category of the -# most of the rest. -# ====================================================================== - - -RDFContentSinkImpl:: - - -nsGenericDOMDataNode:: - - -nsDOMClassInfo:: - - -nsDOMSOFactory:: - - -nsXULTemplateBuilder:: - - -XULContentSinkImpl::HandleEndElement - - -nsChromeRegistry:: - - -nsJSContext::EvaluateString - -# Almost all of what is left with XULContentSink belongs to xul -# Also, this was roughly 0.3% of startup memory - -XULContentSinkImpl:: - -# XXX this is a wild guess -> html What remains here is about -# XXX 1.5% of startup footprint - -HTMLContentSink:: - - -nsXBLContentSink:: - - -nsXBLStreamListener::OnDataAvailable - - -nsIOService::NewURI - - -nsIOService::NewChannelFromURI - - -nsSegmentedBuffer::AppendNewSegment - - -nsHttpChannel:: - -# Catchalls to help categorize -# ---------------------------------------------------------------------- - -js_ - -# Everything else -# ---------------------------------------------------------------------- -# -# This is a predefined category. Don't create it yourself. diff --git a/tools/trace-malloc/spacecategory.c b/tools/trace-malloc/spacecategory.c deleted file mode 100644 index f3b518cec8ce..000000000000 --- a/tools/trace-malloc/spacecategory.c +++ /dev/null @@ -1,959 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* -** spacecategory.c -** -** Cagtegorizes each allocation using a predefined set of rules -** and presents a tree of categories for browsing. -*/ - -/* -** Required include files. -*/ -#include "spacetrace.h" -#include -#include - -#include "nsQuickSort.h" - -#if defined(HAVE_BOUTELL_GD) -/* -** See http://www.boutell.com/gd for the GD graphics library. -** Ports for many platorms exist. -** Your box may already have the lib (mine did, redhat 7.1 workstation). -*/ -#include -#include -#include -#include -#endif /* HAVE_BOUTELL_GD */ - -/* -** AddRule -** -** Add a rule into the list of rules maintainted in global -*/ -int -AddRule(STGlobals * g, STCategoryRule * rule) -{ - if (g->mNRules % ST_ALLOC_STEP == 0) { - /* Need more space */ - STCategoryRule **newrules; - - newrules = (STCategoryRule **) realloc(g->mCategoryRules, - (g->mNRules + - ST_ALLOC_STEP) * - sizeof(STCategoryRule *)); - if (!newrules) { - REPORT_ERROR(__LINE__, AddRule_No_Memory); - return -1; - } - g->mCategoryRules = newrules; - } - g->mCategoryRules[g->mNRules++] = rule; - return 0; -} - -/* -** AddChild -** -** Add the node as a child of the parent node -*/ -int -AddChild(STCategoryNode * parent, STCategoryNode * child) -{ - if (parent->nchildren % ST_ALLOC_STEP == 0) { - /* need more space */ - STCategoryNode **newnodes; - - newnodes = (STCategoryNode **) realloc(parent->children, - (parent->nchildren + - ST_ALLOC_STEP) * - sizeof(STCategoryNode *)); - if (!newnodes) { - REPORT_ERROR(__LINE__, AddChild_No_Memory); - return -1; - } - parent->children = newnodes; - } - parent->children[parent->nchildren++] = child; - return 0; -} - -int -Reparent(STCategoryNode * parent, STCategoryNode * child) -{ - uint32_t i; - - if (child->parent == parent) - return 0; - - /* Remove child from old parent */ - if (child->parent) { - for (i = 0; i < child->parent->nchildren; i++) { - if (child->parent->children[i] == child) { - /* Remove child from list */ - if (i + 1 < child->parent->nchildren) - memmove(&child->parent->children[i], - &child->parent->children[i + 1], - (child->parent->nchildren - i - - 1) * sizeof(STCategoryNode *)); - child->parent->nchildren--; - break; - } - } - } - - /* Add child into new parent */ - AddChild(parent, child); - - return 0; -} - -/* -** findCategoryNode -** -** Given a category name, finds the Node corresponding to the category -*/ -STCategoryNode * -findCategoryNode(const char *catName, STGlobals * g) -{ - uint32_t i; - - for (i = 0; i < g->mNCategoryMap; i++) { - if (!strcmp(g->mCategoryMap[i]->categoryName, catName)) - return g->mCategoryMap[i]->node; - } - - /* Check if we are looking for the root node */ - if (!strcmp(catName, ST_ROOT_CATEGORY_NAME)) - return &g->mCategoryRoot; - - return NULL; -} - -/* -** AddCategoryNode -** -** Adds a mapping between a category and its Node into the categoryMap -*/ -int -AddCategoryNode(STCategoryNode * node, STGlobals * g) -{ - if (g->mNCategoryMap % ST_ALLOC_STEP == 0) { - /* Need more space */ - STCategoryMapEntry **newmap = - (STCategoryMapEntry **) realloc(g->mCategoryMap, - (g->mNCategoryMap + - ST_ALLOC_STEP) * - sizeof(STCategoryMapEntry *)); - if (!newmap) { - REPORT_ERROR(__LINE__, AddCategoryNode_No_Memory); - return -1; - } - g->mCategoryMap = newmap; - - } - g->mCategoryMap[g->mNCategoryMap] = - (STCategoryMapEntry *) calloc(1, sizeof(STCategoryMapEntry)); - if (!g->mCategoryMap[g->mNCategoryMap]) { - REPORT_ERROR(__LINE__, AddCategoryNode_No_Memory); - return -1; - } - g->mCategoryMap[g->mNCategoryMap]->categoryName = node->categoryName; - g->mCategoryMap[g->mNCategoryMap]->node = node; - g->mNCategoryMap++; - return 0; -} - -/* -** NewCategoryNode -** -** Creates a new category node for category name 'catname' and makes -** 'parent' its parent. -*/ -STCategoryNode * -NewCategoryNode(const char *catName, STCategoryNode * parent, STGlobals * g) -{ - STCategoryNode *node; - - node = (STCategoryNode *) calloc(1, sizeof(STCategoryNode)); - if (!node) - return NULL; - - node->runs = - (STRun **) calloc(g->mCommandLineOptions.mContexts, sizeof(STRun *)); - if (NULL == node->runs) { - free(node); - return NULL; - } - - node->categoryName = catName; - - /* Set parent of child */ - node->parent = parent; - - /* Set child in parent */ - AddChild(parent, node); - - /* Add node into mapping table */ - AddCategoryNode(node, g); - - return node; -} - -/* -** ProcessCategoryLeafRule -** -** Add this into the tree as a leaf node. It doesn't know who its parent is. For now we make -** root as its parent -*/ -int -ProcessCategoryLeafRule(STCategoryRule * leafRule, STCategoryNode * root, - STGlobals * g) -{ - STCategoryRule *rule; - STCategoryNode *node; - - rule = (STCategoryRule *) calloc(1, sizeof(STCategoryRule)); - if (!rule) - return -1; - - /* Take ownership of all elements of rule */ - *rule = *leafRule; - - /* Find/Make a STCategoryNode and add it into the tree */ - node = findCategoryNode(rule->categoryName, g); - if (!node) - node = NewCategoryNode(rule->categoryName, root, g); - - /* Make sure rule knows which node to access */ - rule->node = node; - - /* Add rule into rulelist */ - AddRule(g, rule); - - return 0; -} - -/* -** ProcessCategoryParentRule -** -** Rule has all the children of category as patterns. Sets up the tree so that -** the parent child relationship is honored. -*/ -int -ProcessCategoryParentRule(STCategoryRule * parentRule, STCategoryNode * root, - STGlobals * g) -{ - STCategoryNode *node; - STCategoryNode *child; - uint32_t i; - - /* Find the parent node in the tree. If not make one and add it into the tree */ - node = findCategoryNode(parentRule->categoryName, g); - if (!node) { - node = NewCategoryNode(parentRule->categoryName, root, g); - if (!node) - return -1; - } - - /* For every child node, Find/Create it and make it the child of this node */ - for (i = 0; i < parentRule->npats; i++) { - child = findCategoryNode(parentRule->pats[i], g); - if (!child) { - child = NewCategoryNode(parentRule->pats[i], node, g); - if (!child) - return -1; - } - else { - /* Reparent child to node. This is because when we created the node - ** we would have created it as the child of root. Now we need to - ** remove it from root's child list and add it into this node - */ - Reparent(node, child); - } - } - - return 0; -} - -/* -** initCategories -** -** Initialize all categories. This reads in a file that says how to categorize -** each callsite, creates a tree of these categories and makes a list of these -** patterns in order for matching -*/ -int -initCategories(STGlobals * g) -{ - FILE *fp; - char buf[1024], *in; - int n; - PRBool inrule, leaf; - STCategoryRule rule; - - fp = fopen(g->mCommandLineOptions.mCategoryFile, "r"); - if (!fp) { - /* It isn't an error to not have a categories file */ - REPORT_INFO("No categories file."); - return -1; - } - - inrule = PR_FALSE; - leaf = PR_FALSE; - - memset(&rule, 0, sizeof(rule)); - - while (fgets(buf, sizeof(buf), fp) != NULL) { - /* Lose the \n */ - n = strlen(buf); - if (buf[n - 1] == '\n') - buf[--n] = '\0'; - in = buf; - - /* skip comments */ - if (*in == '#') - continue; - - /* skip empty lines. If we are in a rule, end the rule. */ - while (*in && isspace(*in)) - in++; - if (*in == '\0') { - if (inrule) { - /* End the rule : leaf or non-leaf */ - if (leaf) - ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g); - else - /* non-leaf */ - ProcessCategoryParentRule(&rule, &g->mCategoryRoot, g); - inrule = PR_FALSE; - memset(&rule, 0, sizeof(rule)); - } - continue; - } - - /* if we are in a rule acculumate */ - if (inrule) { - rule.pats[rule.npats] = strdup(in); - rule.patlen[rule.npats++] = strlen(in); - } - else if (*in == '<') { - /* Start a category */ - inrule = PR_TRUE; - leaf = PR_TRUE; - - /* Get the category name */ - in++; - n = strlen(in); - if (in[n - 1] == '>') - in[n - 1] = '\0'; - rule.categoryName = strdup(in); - } - else { - /* this is a non-leaf category. Should be of the form CategoryName - ** followed by list of child category names one per line - */ - inrule = PR_TRUE; - leaf = PR_FALSE; - rule.categoryName = strdup(in); - } - } - - /* If we were in a rule when processing the last line, end the rule */ - if (inrule) { - /* End the rule : leaf or non-leaf */ - if (leaf) - ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g); - else - /* non-leaf */ - ProcessCategoryParentRule(&rule, &g->mCategoryRoot, g); - } - - /* Add the final "uncategorized" category. We make new memory locations - ** for all these to conform to the general principle of all strings are allocated - ** so it makes release logic very simple. - */ - memset(&rule, 0, sizeof(rule)); - rule.categoryName = strdup("uncategorized"); - rule.pats[0] = strdup(""); - rule.patlen[0] = 0; - rule.npats = 1; - ProcessCategoryLeafRule(&rule, &g->mCategoryRoot, g); - - return 0; -} - -/* -** callsiteMatchesRule -** -** Returns the corresponding node if callsite matches the rule. Rule is a sequence -** of patterns that must match contiguously the callsite. -*/ -int -callsiteMatchesRule(tmcallsite * aCallsite, STCategoryRule * aRule) -{ - uint32_t patnum = 0; - const char *methodName = NULL; - - while (patnum < aRule->npats && aCallsite && aCallsite->method) { - methodName = tmmethodnode_name(aCallsite->method); - if (!methodName) - return 0; - if (!*aRule->pats[patnum] - || !strncmp(methodName, aRule->pats[patnum], - aRule->patlen[patnum])) { - /* We have matched so far. Proceed up the stack and to the next pattern */ - patnum++; - aCallsite = aCallsite->parent; - } - else { - /* Deal with mismatch */ - if (patnum > 0) { - /* contiguous mismatch. Stop */ - return 0; - } - /* We still haven't matched the first pattern. Proceed up the stack without - ** moving to the next pattern. - */ - aCallsite = aCallsite->parent; - } - } - - if (patnum == aRule->npats) { - /* all patterns matched. We have a winner. */ -#if defined(DEBUG_dp) && 0 - fprintf(stderr, "[%s] match\n", aRule->categoryName); -#endif - return 1; - } - - return 0; -} - -#ifdef DEBUG_dp -PRIntervalTime _gMatchTime = 0; -uint32_t _gMatchCount = 0; -uint32_t _gMatchRules = 0; -#endif - -/* -** matchAllocation -** -** Runs through all rules and returns the node corresponding to -** a match of the allocation. -*/ -STCategoryNode * -matchAllocation(STGlobals * g, STAllocation * aAllocation) -{ -#ifdef DEBUG_dp - PRIntervalTime start = PR_IntervalNow(); -#endif - uint32_t rulenum; - STCategoryNode *node = NULL; - STCategoryRule *rule; - - for (rulenum = 0; rulenum < g->mNRules; rulenum++) { -#ifdef DEBUG_dp - _gMatchRules++; -#endif - rule = g->mCategoryRules[rulenum]; - if (callsiteMatchesRule(aAllocation->mEvents[0].mCallsite, rule)) { - node = rule->node; - break; - } - } -#ifdef DEBUG_dp - _gMatchCount++; - _gMatchTime += PR_IntervalNow() - start; -#endif - return node; -} - -/* -** categorizeAllocation -** -** Given an allocation, it adds it into the category tree at the right spot -** by comparing the allocation to the rules and adding into the right node. -** Also, does propogation of cost upwards in the tree. -** The root of the tree is in the globls as the tree is dependent on the -** category file (options) rather than the run. -*/ -int -categorizeAllocation(STOptions * inOptions, STContext * inContext, - STAllocation * aAllocation, STGlobals * g) -{ - /* Run through the rules in order to see if this allcation matches - ** any of them. - */ - STCategoryNode *node; - - node = matchAllocation(g, aAllocation); - if (!node) { - /* ugh! it should atleast go into the "uncategorized" node. wierd! - */ - REPORT_ERROR(__LINE__, categorizeAllocation); - return -1; - } - - /* Create run for node if not already */ - if (!node->runs[inContext->mIndex]) { - /* - ** Create run with positive timestamp as we can harvest it later - ** for callsite details summarization - */ - node->runs[inContext->mIndex] = - createRun(inContext, PR_IntervalNow()); - if (!node->runs[inContext->mIndex]) { - REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory); - return -1; - } - } - - /* Add allocation into node. We expand the table of allocations in steps */ - if (node->runs[inContext->mIndex]->mAllocationCount % ST_ALLOC_STEP == 0) { - /* Need more space */ - STAllocation **allocs; - - allocs = - (STAllocation **) realloc(node->runs[inContext->mIndex]-> - mAllocations, - (node->runs[inContext->mIndex]-> - mAllocationCount + - ST_ALLOC_STEP) * - sizeof(STAllocation *)); - if (!allocs) { - REPORT_ERROR(__LINE__, categorizeAllocation_No_Memory); - return -1; - } - node->runs[inContext->mIndex]->mAllocations = allocs; - } - node->runs[inContext->mIndex]->mAllocations[node-> - runs[inContext->mIndex]-> - mAllocationCount++] = - aAllocation; - - /* - ** Make sure run's stats are calculated. We don't go update the parents of allocation - ** at this time. That will happen when we focus on this category. This updating of - ** stats will provide us fast categoryreports. - */ - recalculateAllocationCost(inOptions, inContext, - node->runs[inContext->mIndex], aAllocation, - PR_FALSE); - - /* Propagate upwards the statistics */ - /* XXX */ -#if defined(DEBUG_dp) && 0 - fprintf(stderr, "DEBUG: [%s] match\n", node->categoryName); -#endif - return 0; -} - -typedef PRBool STCategoryNodeProcessor(STRequest * inRequest, - STOptions * inOptions, - STContext * inContext, - void *clientData, - STCategoryNode * node); - -PRBool -freeNodeRunProcessor(STRequest * inRequest, STOptions * inOptions, - STContext * inContext, void *clientData, - STCategoryNode * node) -{ - if (node->runs && node->runs[inContext->mIndex]) { - freeRun(node->runs[inContext->mIndex]); - node->runs[inContext->mIndex] = NULL; - } - return PR_TRUE; -} - -PRBool -freeNodeRunsProcessor(STRequest * inRequest, STOptions * inOptions, - STContext * inContext, void *clientData, - STCategoryNode * node) -{ - if (node->runs) { - uint32_t loop = 0; - - for (loop = 0; loop < globals.mCommandLineOptions.mContexts; loop++) { - if (node->runs[loop]) { - freeRun(node->runs[loop]); - node->runs[loop] = NULL; - } - } - - free(node->runs); - node->runs = NULL; - } - - return PR_TRUE; -} - -#if defined(DEBUG_dp) -PRBool -printNodeProcessor(STRequest * inRequest, STOptions * inOptions, - STContext * inContext, void *clientData, - STCategoryNode * node) -{ - STCategoryNode *root = (STCategoryNode *) clientData; - - fprintf(stderr, "%-25s [ %9s size", node->categoryName, - FormatNumber(node->run ? node->run->mStats[inContext->mIndex]. - mSize : 0)); - fprintf(stderr, ", %5.1f%%", - node->run ? ((double) node->run->mStats[inContext->mIndex].mSize / - root->run->mStats[inContext->mIndex].mSize * - 100) : 0); - fprintf(stderr, ", %7s allocations ]\n", - FormatNumber(node->run ? node->run->mStats[inContext->mIndex]. - mCompositeCount : 0)); - return PR_TRUE; -} - -#endif - -typedef struct __struct_optcon -{ - STOptions *mOptions; - STContext *mContext; -} -optcon; - -/* -** compareNode -** -** qsort callback. -** Compare the nodes as specified by the options. -*/ -int -compareNode(const void *aNode1, const void *aNode2, void *aContext) -{ - int retval = 0; - STCategoryNode *node1, *node2; - uint32_t a, b; - optcon *oc = (optcon *) aContext; - - if (!aNode1 || !aNode2 || !oc->mOptions || !oc->mContext) - return 0; - - node1 = *((STCategoryNode **) aNode1); - node2 = *((STCategoryNode **) aNode2); - - if (node1 && node2) { - if (oc->mOptions->mOrderBy == ST_COUNT) { - a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc-> - mContext-> - mIndex]-> - mStats[oc->mContext->mIndex].mCompositeCount : 0; - b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc-> - mContext-> - mIndex]-> - mStats[oc->mContext->mIndex].mCompositeCount : 0; - } - else { - /* Default is by size */ - a = (node1->runs[oc->mContext->mIndex]) ? node1->runs[oc-> - mContext-> - mIndex]-> - mStats[oc->mContext->mIndex].mSize : 0; - b = (node2->runs[oc->mContext->mIndex]) ? node2->runs[oc-> - mContext-> - mIndex]-> - mStats[oc->mContext->mIndex].mSize : 0; - } - if (a < b) - retval = __LINE__; - else - retval = -__LINE__; - } - return retval; -} - -PRBool -sortNodeProcessor(STRequest * inRequest, STOptions * inOptions, - STContext * inContext, void *clientData, - STCategoryNode * node) -{ - if (node->nchildren) { - optcon context; - - context.mOptions = inOptions; - context.mContext = inContext; - - NS_QuickSort(node->children, node->nchildren, - sizeof(STCategoryNode *), compareNode, &context); - } - - return PR_TRUE; -} - - -/* -** walkTree -** -** General purpose tree walker. Issues callback for each node. -** If 'maxdepth' > 0, then stops after processing that depth. Root is -** depth 0, the nodes below it are depth 1 etc... -*/ -#define MODINC(n, mod) ((n+1) % mod) - -void -walkTree(STCategoryNode * root, STCategoryNodeProcessor func, - STRequest * inRequest, STOptions * inOptions, STContext * inContext, - void *clientData, int maxdepth) -{ - STCategoryNode *nodes[1024], *node; - uint32_t begin, end, i; - int ret = 0; - int curdepth = 0, ncurdepth = 0; - - nodes[0] = root; - begin = 0; - end = 1; - ncurdepth = 1; - while (begin != end) { - node = nodes[begin]; - ret = (*func) (inRequest, inOptions, inContext, clientData, node); - if (!ret) { - /* Abort */ - break; - } - begin = MODINC(begin, 1024); - for (i = 0; i < node->nchildren; i++) { - nodes[end] = node->children[i]; - end = MODINC(end, 1024); - } - /* Depth tracking. Do it only if walkTree is contrained by a maxdepth */ - if (maxdepth > 0 && --ncurdepth == 0) { - /* - ** No more children in current depth. The rest of the nodes - ** we have in our list should be nodes in the depth below us. - */ - ncurdepth = (begin < end) ? (end - begin) : (1024 - begin + end); - if (++curdepth > maxdepth) { - /* - ** Gone too deep. Stop. - */ - break; - } - } - } - return; -} - -int -freeRule(STCategoryRule * rule) -{ - uint32_t i; - char *p = (char *) rule->categoryName; - - PR_FREEIF(p); - - for (i = 0; i < rule->npats; i++) - free(rule->pats[i]); - - free(rule); - return 0; -} - -void -freeNodeRuns(STCategoryNode * root) -{ - walkTree(root, freeNodeRunsProcessor, NULL, NULL, NULL, NULL, 0); -} - -void -freeNodeMap(STGlobals * g) -{ - uint32_t i; - - /* all nodes are in the map table. Just delete all of those. */ - for (i = 0; i < g->mNCategoryMap; i++) { - free(g->mCategoryMap[i]->node); - free(g->mCategoryMap[i]); - } - free(g->mCategoryMap); -} - -int -freeCategories(STGlobals * g) -{ - uint32_t i; - - /* - ** walk the tree and free runs held in nodes - */ - freeNodeRuns(&g->mCategoryRoot); - - /* - ** delete nodemap. This is the where nodes get deleted. - */ - freeNodeMap(g); - - /* - ** delete rule stuff - */ - for (i = 0; i < g->mNRules; i++) { - freeRule(g->mCategoryRules[i]); - } - free(g->mCategoryRules); - - return 0; -} - - -/* -** categorizeRun -** -** categorize all the allocations of the run using the rules into -** a tree rooted at globls.mCategoryRoot -*/ -int -categorizeRun(STOptions * inOptions, STContext * inContext, - const STRun * aRun, STGlobals * g) -{ - uint32_t i; - -#if defined(DEBUG_dp) - PRIntervalTime start = PR_IntervalNow(); - - fprintf(stderr, "DEBUG: categorizing run...\n"); -#endif - - /* - ** First, cleanup our tree - */ - walkTree(&g->mCategoryRoot, freeNodeRunProcessor, NULL, inOptions, - inContext, NULL, 0); - - if (g->mNCategoryMap > 0) { - for (i = 0; i < aRun->mAllocationCount; i++) { - categorizeAllocation(inOptions, inContext, aRun->mAllocations[i], - g); - } - } - - /* - ** the run is always going to be the one corresponding to the root node - */ - g->mCategoryRoot.runs[inContext->mIndex] = (STRun *) aRun; - g->mCategoryRoot.categoryName = ST_ROOT_CATEGORY_NAME; - -#if defined(DEBUG_dp) - fprintf(stderr, - "DEBUG: categorizing ends: %dms [%d rules, %d allocations]\n", - PR_IntervalToMilliseconds(PR_IntervalNow() - start), g->mNRules, - aRun->mAllocationCount); - fprintf(stderr, "DEBUG: match : %dms [%d calls, %d rule-compares]\n", - PR_IntervalToMilliseconds(_gMatchTime), _gMatchCount, - _gMatchRules); -#endif - - /* - ** sort the tree based on our sort criterion - */ - walkTree(&g->mCategoryRoot, sortNodeProcessor, NULL, inOptions, inContext, - NULL, 0); - -#if defined(DEBUG_dp) - walkTree(&g->mCategoryRoot, printNodeProcessor, NULL, inOptions, - inContext, &g->mCategoryRoot, 0); -#endif - - return 0; -} - - -/* -** displayCategoryReport -** -** Generate the category report - a list of all categories and details about each -** depth parameter controls how deep we traverse the category tree. -*/ -PRBool -displayCategoryNodeProcessor(STRequest * inRequest, STOptions * inOptions, - STContext * inContext, void *clientData, - STCategoryNode * node) -{ - STCategoryNode *root = (STCategoryNode *) clientData; - uint32_t byteSize = 0, heapCost = 0, count = 0; - double percent = 0; - STOptions customOps; - - if (node->runs[inContext->mIndex]) { - /* - ** Byte size - */ - byteSize = - node->runs[inContext->mIndex]->mStats[inContext->mIndex].mSize; - - /* - ** Composite count - */ - count = - node->runs[inContext->mIndex]->mStats[inContext->mIndex]. - mCompositeCount; - - /* - ** Heap operation cost - **/ - heapCost = - node->runs[inContext->mIndex]->mStats[inContext->mIndex]. - mHeapRuntimeCost; - - /* - ** % of total size - */ - if (root->runs[inContext->mIndex]) { - percent = - ((double) byteSize) / - root->runs[inContext->mIndex]->mStats[inContext->mIndex]. - mSize * 100; - } - } - - PR_fprintf(inRequest->mFD, " \n" " "); - - /* a link to topcallsites report with focus on category */ - memcpy(&customOps, inOptions, sizeof(customOps)); - PR_snprintf(customOps.mCategoryName, sizeof(customOps.mCategoryName), - "%s", node->categoryName); - - htmlAnchor(inRequest, "top_callsites.html", node->categoryName, NULL, - "category-callsites", &customOps); - PR_fprintf(inRequest->mFD, - "\n" " %u\n" - " %4.1f%%\n" - " %u\n" " " - ST_MICROVAL_FORMAT "\n" " \n", byteSize, percent, - count, ST_MICROVAL_PRINTABLE(heapCost)); - - return PR_TRUE; -} - - -int -displayCategoryReport(STRequest * inRequest, STCategoryNode * root, int depth) -{ - PR_fprintf(inRequest->mFD, - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" " \n"); - - walkTree(root, displayCategoryNodeProcessor, inRequest, - &inRequest->mOptions, inRequest->mContext, root, depth); - - PR_fprintf(inRequest->mFD, "
CategoryComposite Byte Size%% of Total SizeHeap Object CountComposite Heap Operations Seconds
\n"); - - return 0; -} diff --git a/tools/trace-malloc/spacetrace.c b/tools/trace-malloc/spacetrace.c deleted file mode 100644 index f101ce9ce9e6..000000000000 --- a/tools/trace-malloc/spacetrace.c +++ /dev/null @@ -1,6352 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* -** spacetrace.c -** -** SpaceTrace is meant to take the output of trace-malloc and present -** a picture of allocations over the run of the application. -*/ - -/* -** Required include files. -*/ -#include "spacetrace.h" - -#include -#include -#include -#include -#if defined(XP_WIN32) -#include /* _heapMin */ -#endif - -#if defined(HAVE_BOUTELL_GD) -/* -** See http://www.boutell.com/gd for the GD graphics library. -** Ports for many platorms exist. -** Your box may already have the lib (mine did, redhat 7.1 workstation). -*/ -#include -#include -#include -#include -#endif /* HAVE_BOUTELL_GD */ - -#include "nsQuickSort.h" -/* -** strcasecmp API please. -*/ -#if defined(_MSC_VER) -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif - -/* -** the globals variables. happy joy. -*/ -STGlobals globals; - -/* -** have the heap cleanup at opportune times, if possible. -*/ -void -heapCompact(void) -{ -#if defined(XP_WIN32) - _heapmin(); -#endif -} - -#define ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) \ - PR_fprintf(PR_STDOUT, "--%s\nDisabled by default.\n%s\n", #option_name, option_help); -#define ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - PR_fprintf(PR_STDOUT, "--%s=\nDefault value is \"%s\".\n%s\n", #option_name, default_value, option_help); -#define ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - PR_fprintf(PR_STDOUT, "--%s=\nUp to %u occurrences allowed.\n%s\n", #option_name, array_size, option_help); -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) \ - PR_fprintf(PR_STDOUT, "--%s=\nUnlimited occurrences allowed.\n%s\n", #option_name, option_help); -#define ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - PR_fprintf(PR_STDOUT, "--%s=\nDefault value is %u.\n%s\n", #option_name, default_value, option_help); -#define ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - PR_fprintf(PR_STDOUT, "--%s=\nDefault value is %llu.\n%s\n", #option_name, default_value, option_help); - -/* -** showHelp -** -** Give simple command line help. -** Returns !0 if the help was showed. -*/ -int -showHelp(void) -{ - int retval = 0; - - if (PR_FALSE != globals.mCommandLineOptions.mHelp) { - PR_fprintf(PR_STDOUT, "Usage:\t%s [OPTION]... [-|filename]\n\n", - globals.mProgramName); - - -#include "stoptions.h" - - /* - ** Showed something. - */ - retval = __LINE__; - } - - return retval; -} - -/* -** ticks2xsec -** -** Convert platform specific ticks to second units -** Returns 0 on success. -*/ -uint32_t -ticks2xsec(tmreader * aReader, uint32_t aTicks, uint32_t aResolution) -{ - return (uint32_t)((aResolution * aTicks)/aReader->ticksPerSec); -} - -#define ticks2msec(reader, ticks) ticks2xsec((reader), (ticks), 1000) -#define ticks2usec(reader, ticks) ticks2xsec((reader), (ticks), 1000000) - -/* -** initOptions -** -** Determine global settings for the application. -** Returns 0 on success. -*/ -int -initOptions(int aArgCount, char **aArgArray) -{ - int retval = 0; - int traverse = 0; - - /* - ** Set the initial global default options. - */ -#define ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) globals.mCommandLineOptions.m##option_name = PR_FALSE; -#define ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) PR_snprintf(globals.mCommandLineOptions.m##option_name, sizeof(globals.mCommandLineOptions.m##option_name), "%s", default_value); -#define ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) { int loop; for(loop = 0; loop < array_size; loop++) { globals.mCommandLineOptions.m##option_name[loop][0] = '\0'; } } -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) globals.mCommandLineOptions.m##option_name = NULL; globals.mCommandLineOptions.m##option_name##Count = 0; -#define ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) globals.mCommandLineOptions.m##option_name = default_value * multiplier; -#define ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) { uint64_t def64 = default_value; uint64_t mul64 = multiplier; globals.mCommandLineOptions.m##option_name##64 = def64 * mul64; } - -#include "stoptions.h" - - /* - ** Go through all arguments. - ** Two dashes lead off an option. - ** Any single dash leads off help, unless it is a lone dash (stdin). - ** Anything else will be attempted as a file to be processed. - */ - for (traverse = 1; traverse < aArgCount; traverse++) { - if ('-' == aArgArray[traverse][0] && '-' == aArgArray[traverse][1]) { - const char *option = &aArgArray[traverse][2]; - - /* - ** Initial if(0) needed to make "else if"s valid. - */ - if (0) { - } - -#define ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) \ - else if(0 == strcasecmp(option, #option_name)) \ - { \ - globals.mCommandLineOptions.m##option_name = PR_TRUE; \ - } -#define ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - else if(0 == strncasecmp(option, #option_name "=", strlen(#option_name "="))) \ - { \ - PR_snprintf(globals.mCommandLineOptions.m##option_name, sizeof(globals.mCommandLineOptions.m##option_name), "%s", option + strlen(#option_name "=")); \ - } -#define ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - else if(0 == strncasecmp(option, #option_name "=", strlen(#option_name "="))) \ - { \ - int arrLoop = 0; \ - \ - for(arrLoop = 0; arrLoop < array_size; arrLoop++) \ - { \ - if('\0' == globals.mCommandLineOptions.m##option_name[arrLoop][0]) \ - { \ - break; \ - } \ - }\ - \ - if(arrLoop != array_size) \ - { \ - PR_snprintf(globals.mCommandLineOptions.m##option_name[arrLoop], sizeof(globals.mCommandLineOptions.m##option_name[arrLoop]), "%s", option + strlen(#option_name "=")); \ - } \ - else \ - { \ - REPORT_ERROR_MSG(__LINE__, option); \ - retval = __LINE__; \ - globals.mCommandLineOptions.mHelp = PR_TRUE; \ - } \ - } -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) \ - else if(0 == strncasecmp(option, #option_name "=", strlen(#option_name "="))) \ - { \ - const char** expand = NULL; \ - \ - expand = (const char**)realloc((void*)globals.mCommandLineOptions.m##option_name, sizeof(const char*) * (globals.mCommandLineOptions.m##option_name##Count + 1)); \ - if(NULL != expand) \ - { \ - globals.mCommandLineOptions.m##option_name = expand; \ - globals.mCommandLineOptions.m##option_name[globals.mCommandLineOptions.m##option_name##Count] = option + strlen(#option_name "="); \ - globals.mCommandLineOptions.m##option_name##Count++; \ - } \ - else \ - { \ - retval = __LINE__; \ - globals.mCommandLineOptions.mHelp = PR_TRUE; \ - } \ - } -#define ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - else if(0 == strncasecmp(option, #option_name "=", strlen(#option_name "="))) \ - { \ - int32_t scanRes = 0; \ - \ - scanRes = PR_sscanf(option + strlen(#option_name "="), "%u", &globals.mCommandLineOptions.m##option_name); \ - if(1 != scanRes) \ - { \ - REPORT_ERROR_MSG(__LINE__, option); \ - retval = __LINE__; \ - globals.mCommandLineOptions.mHelp = PR_TRUE; \ - } \ - } -#define ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - else if(0 == strncasecmp(option, #option_name "=", strlen(#option_name "="))) \ - { \ - int32_t scanRes = 0; \ - \ - scanRes = PR_sscanf(option + strlen(#option_name "="), "%llu", &globals.mCommandLineOptions.m##option_name##64); \ - if(1 != scanRes) \ - { \ - REPORT_ERROR_MSG(__LINE__, option); \ - retval = __LINE__; \ - globals.mCommandLineOptions.mHelp = PR_TRUE; \ - } \ - } - -#include "stoptions.h" - - /* - ** If no match on options, this else will get hit. - */ - else { - REPORT_ERROR_MSG(__LINE__, option); - retval = __LINE__; - globals.mCommandLineOptions.mHelp = PR_TRUE; - } - } - else if ('-' == aArgArray[traverse][0] - && '\0' != aArgArray[traverse][1]) { - /* - ** Show help, bad/legacy option. - */ - REPORT_ERROR_MSG(__LINE__, aArgArray[traverse]); - retval = __LINE__; - globals.mCommandLineOptions.mHelp = PR_TRUE; - } - else { - /* - ** Default is same as FileName option, the file to process. - */ - PR_snprintf(globals.mCommandLineOptions.mFileName, - sizeof(globals.mCommandLineOptions.mFileName), "%s", - aArgArray[traverse]); - } - } - - /* - ** initialize the categories - */ - initCategories(&globals); - - return retval; -} - -#if ST_WANT_GRAPHS -/* -** createGraph -** -** Create a GD image with the common properties of a graph. -** Upon return, you normally allocate legend colors, -** draw your graph inside the region -** STGD_MARGIN,STGD_MARGIN,STGD_WIDTH-STGD_MARGIN,STGD_HEIGH-STGD_MARGIN, -** and then call drawGraph to format the surrounding information. -** -** You should use the normal GD image release function, gdImageDestroy -** when done with it. -** -** Image attributes: -** STGD_WIDTHxSTGD_HEIGHT -** trasparent (white) background -** incremental display -*/ -gdImagePtr -createGraph(int *aTransparencyColor) -{ - gdImagePtr retval = NULL; - - if (NULL != aTransparencyColor) { - *aTransparencyColor = -1; - - retval = gdImageCreate(STGD_WIDTH, STGD_HEIGHT); - if (NULL != retval) { - /* - ** Background color (first one). - */ - *aTransparencyColor = gdImageColorAllocate(retval, 255, 255, 255); - if (-1 != *aTransparencyColor) { - /* - ** As transparency. - */ - gdImageColorTransparent(retval, *aTransparencyColor); - } - - /* - ** And to set interlacing. - */ - gdImageInterlace(retval, 1); - } - else { - REPORT_ERROR(__LINE__, gdImageCreate); - } - } - else { - REPORT_ERROR(__LINE__, createGraph); - } - - return retval; -} -#endif /* ST_WANT_GRAPHS */ - -#if ST_WANT_GRAPHS -/* -** drawGraph -** -** This function mainly exists to simplify putitng all the pretty lace -** around a home made graph. -*/ -void -drawGraph(gdImagePtr aImage, int aColor, - const char *aGraphTitle, - const char *aXAxisTitle, - const char *aYAxisTitle, - uint32_t aXMarkCount, - uint32_t * aXMarkPercents, - const char **aXMarkTexts, - uint32_t aYMarkCount, - uint32_t * aYMarkPercents, - const char **aYMarkTexts, - uint32_t aLegendCount, - int *aLegendColors, const char **aLegendTexts) -{ - if (NULL != aImage && NULL != aGraphTitle && - NULL != aXAxisTitle && NULL != aYAxisTitle && - (0 == aXMarkCount || (NULL != aXMarkPercents && NULL != aXMarkTexts)) - && (0 == aYMarkCount - || (NULL != aYMarkPercents && NULL != aYMarkTexts)) - && (0 == aLegendCount - || (NULL != aLegendColors && NULL != aLegendTexts))) { - int margin = 1; - uint32_t traverse = 0; - uint32_t target = 0; - const int markSize = 2; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - time_t theTimeT = time(NULL); - char *theTime = ctime(&theTimeT); - const char *logo = "SpaceTrace"; - gdFontPtr titleFont = gdFontMediumBold; - gdFontPtr markFont = gdFontTiny; - gdFontPtr dateFont = gdFontTiny; - gdFontPtr axisFont = gdFontSmall; - gdFontPtr legendFont = gdFontTiny; - gdFontPtr logoFont = gdFontTiny; - - /* - ** Fixup the color. - ** Black by default. - */ - if (-1 == aColor) { - aColor = gdImageColorAllocate(aImage, 0, 0, 0); - } - if (-1 == aColor) { - aColor = gdImageColorClosest(aImage, 0, 0, 0); - } - - /* - ** Output the box. - */ - x1 = STGD_MARGIN - margin; - y1 = STGD_MARGIN - margin; - x2 = STGD_WIDTH - x1; - y2 = STGD_HEIGHT - y1; - gdImageRectangle(aImage, x1, y1, x2, y2, aColor); - margin++; - - /* - ** Need to make small markings on the graph to indicate where the - ** labels line up exactly. - ** While we're at it, draw the label text. - */ - for (traverse = 0; traverse < aXMarkCount; traverse++) { - target = - ((STGD_WIDTH - - (STGD_MARGIN * 2)) * aXMarkPercents[traverse]) / 100; - - x1 = STGD_MARGIN + target; - y1 = STGD_MARGIN - margin; - x2 = x1; - y2 = y1 - markSize; - gdImageLine(aImage, x1, y1, x2, y2, aColor); - - y1 = STGD_HEIGHT - y1; - y2 = STGD_HEIGHT - y2; - gdImageLine(aImage, x1, y1, x2, y2, aColor); - - if (NULL != aXMarkTexts[traverse]) { - x1 = STGD_MARGIN + target - (markFont->h / 2); - y1 = STGD_HEIGHT - STGD_MARGIN + margin + markSize + - (strlen(aXMarkTexts[traverse]) * markFont->w); - gdImageStringUp(aImage, markFont, x1, y1, - (unsigned char *) aXMarkTexts[traverse], - aColor); - } - } - for (traverse = 0; traverse < aYMarkCount; traverse++) { - target = - ((STGD_HEIGHT - (STGD_MARGIN * 2)) * (100 - - aYMarkPercents - [traverse])) / 100; - - x1 = STGD_MARGIN - margin; - y1 = STGD_MARGIN + target; - x2 = x1 - markSize; - y2 = y1; - gdImageLine(aImage, x1, y1, x2, y2, aColor); - - x1 = STGD_WIDTH - x1; - x2 = STGD_WIDTH - x2; - gdImageLine(aImage, x1, y1, x2, y2, aColor); - - if (NULL != aYMarkTexts[traverse]) { - x1 = STGD_MARGIN - margin - markSize - - (strlen(aYMarkTexts[traverse]) * markFont->w); - y1 = STGD_MARGIN + target - (markFont->h / 2); - gdImageString(aImage, markFont, x1, y1, - (unsigned char *) aYMarkTexts[traverse], - aColor); - } - } - margin += markSize; - - /* - ** Title will be centered above the image. - */ - x1 = (STGD_WIDTH / 2) - ((strlen(aGraphTitle) * titleFont->w) / 2); - y1 = ((STGD_MARGIN - margin) / 2) - (titleFont->h / 2); - gdImageString(aImage, titleFont, x1, y1, - (unsigned char *) aGraphTitle, aColor); - - /* - ** Upper left will be the date. - */ - x1 = 0; - y1 = 0; - traverse = strlen(theTime) - 1; - if (isspace(theTime[traverse])) { - theTime[traverse] = '\0'; - } - gdImageString(aImage, dateFont, x1, y1, (unsigned char *) theTime, - aColor); - - /* - ** Lower right will be the logo. - */ - x1 = STGD_WIDTH - (strlen(logo) * logoFont->w); - y1 = STGD_HEIGHT - logoFont->h; - gdImageString(aImage, logoFont, x1, y1, (unsigned char *) logo, - aColor); - - /* - ** X and Y axis titles - */ - x1 = (STGD_WIDTH / 2) - ((strlen(aXAxisTitle) * axisFont->w) / 2); - y1 = STGD_HEIGHT - axisFont->h; - gdImageString(aImage, axisFont, x1, y1, (unsigned char *) aXAxisTitle, - aColor); - x1 = 0; - y1 = (STGD_HEIGHT / 2) + ((strlen(aYAxisTitle) * axisFont->w) / 2); - gdImageStringUp(aImage, axisFont, x1, y1, - (unsigned char *) aYAxisTitle, aColor); - - /* - ** The legend. - ** Centered on the right hand side, going up. - */ - x1 = STGD_WIDTH - STGD_MARGIN + margin + - (aLegendCount * legendFont->h) / 2; - x2 = STGD_WIDTH - (aLegendCount * legendFont->h); - if (x1 > x2) { - x1 = x2; - } - - y1 = 0; - for (traverse = 0; traverse < aLegendCount; traverse++) { - y2 = (STGD_HEIGHT / 2) + - ((strlen(aLegendTexts[traverse]) * legendFont->w) / 2); - if (y2 > y1) { - y1 = y2; - } - } - for (traverse = 0; traverse < aLegendCount; traverse++) { - gdImageStringUp(aImage, legendFont, x1, y1, - (unsigned char *) aLegendTexts[traverse], - aLegendColors[traverse]); - x1 += legendFont->h; - } - } -} - -#endif /* ST_WANT_GRAPHS */ - -#if defined(HAVE_BOUTELL_GD) -/* -** pngSink -** -** GD callback, used to write out the png. -*/ -int -pngSink(void *aContext, const char *aBuffer, int aLen) -{ - return PR_Write((PRFileDesc *) aContext, aBuffer, aLen); -} -#endif /* HAVE_BOUTELL_GD */ - -/* -** FormatNumber -** -** Formats a number with thousands separator. Don't free the result. Returns -** static data. -*/ -char * -FormatNumber(int32_t num) -{ - static char buf[64]; - char tmpbuf[64]; - int len = 0; - int bufindex = sizeof(buf) - 1; - int mod3; - - PR_snprintf(tmpbuf, sizeof(tmpbuf), "%d", num); - - /* now insert the thousands separator */ - mod3 = 0; - len = strlen(tmpbuf); - while (len >= 0) { - if (tmpbuf[len] >= '0' && tmpbuf[len] <= '9') { - if (mod3 == 3) { - buf[bufindex--] = ','; - mod3 = 0; - } - mod3++; - } - buf[bufindex--] = tmpbuf[len--]; - } - return buf + bufindex + 1; -} - -/* -** actualByteSize -** -** Apply alignment and overhead to size to figure out actual byte size -*/ -uint32_t -actualByteSize(STOptions * inOptions, uint32_t retval) -{ - /* - ** Need to bump the result by our alignment and overhead. - ** The idea here is that an allocation actually costs you more than you - ** thought. - ** - ** The msvcrt malloc has an alignment of 16 with an overhead of 8. - ** The win32 HeapAlloc has an alignment of 8 with an overhead of 8. - */ - if (0 != retval) { - uint32_t eval = 0; - uint32_t over = 0; - - eval = retval - 1; - if (0 != inOptions->mAlignBy) { - over = eval % inOptions->mAlignBy; - } - retval = eval + inOptions->mOverhead + inOptions->mAlignBy - over; - } - - return retval; -} - -/* -** byteSize -** -** Figuring the byte size of an allocation. -** Might expand in the future to report size at a given time. -** For now, just use last relevant event. -*/ -uint32_t -byteSize(STOptions * inOptions, STAllocation * aAlloc) -{ - uint32_t retval = 0; - - if (NULL != aAlloc && 0 != aAlloc->mEventCount) { - uint32_t index = aAlloc->mEventCount; - - /* - ** Generally, the size is the last event's size. - */ - do { - index--; - retval = aAlloc->mEvents[index].mHeapSize; - } - while (0 == retval && 0 != index); - } - return actualByteSize(inOptions, retval); -} - - -/* -** recalculateAllocationCost -** -** Given an allocation, does a recalculation of Cost - weight, heapcount etc. -** and does the right thing to propagate the cost upwards. -*/ -int -recalculateAllocationCost(STOptions * inOptions, STContext * inContext, - STRun * aRun, STAllocation * aAllocation, - PRBool updateParent) -{ - /* - ** Now, see if they desire a callsite update. - ** As mentioned previously, we decide if the run desires us to - ** manipulate the callsite data only if its stamp is set. - ** We change all callsites and parent callsites to have that - ** stamp as well, so as to mark them as being relevant to - ** the current run in question. - */ - if (NULL != inContext && 0 != aRun->mStats[inContext->mIndex].mStamp) { - uint32_t timeval = - aAllocation->mMaxTimeval - aAllocation->mMinTimeval; - uint32_t size = byteSize(inOptions, aAllocation); - uint32_t heapCost = aAllocation->mHeapRuntimeCost; - uint64_t timeval64 = timeval; - uint64_t size64 = size; - uint64_t weight64 = timeval64 * size64; - - /* - ** First, update this run. - */ - aRun->mStats[inContext->mIndex].mCompositeCount++; - aRun->mStats[inContext->mIndex].mHeapRuntimeCost += heapCost; - aRun->mStats[inContext->mIndex].mSize += size; - aRun->mStats[inContext->mIndex].mTimeval64 += timeval64; - aRun->mStats[inContext->mIndex].mWeight64 += weight64; - - /* - ** Use the first event of the allocation to update the parent - ** callsites. - ** This has positive effect of not updating realloc callsites - ** with the same data over and over again. - */ - if (updateParent && 0 < aAllocation->mEventCount) { - tmcallsite *callsite = aAllocation->mEvents[0].mCallsite; - STRun *callsiteRun = NULL; - - /* - ** Go up parents till we drop. - */ - while (NULL != callsite && NULL != callsite->method) { - callsiteRun = CALLSITE_RUN(callsite); - if (NULL != callsiteRun) { - /* - ** Do we init it? - */ - if (callsiteRun->mStats[inContext->mIndex].mStamp != - aRun->mStats[inContext->mIndex].mStamp) { - memset(&callsiteRun->mStats[inContext->mIndex], 0, - sizeof(STCallsiteStats)); - callsiteRun->mStats[inContext->mIndex].mStamp = - aRun->mStats[inContext->mIndex].mStamp; - } - - /* - ** Add the values. - ** Note that if the allocation was ever realloced, - ** we are actually recording the final size. - ** Also, the composite count does not include - ** calls to realloc (or free for that matter), - ** but rather is simply a count of actual heap - ** allocation objects, from which someone will - ** draw conclusions regarding number of malloc - ** and free calls. - ** It is possible to generate the exact number - ** of calls to free/malloc/realloc should the - ** absolute need arise to count them individually, - ** but I fear it will take mucho memory and this - ** is perhaps good enough for now. - */ - callsiteRun->mStats[inContext->mIndex].mCompositeCount++; - callsiteRun->mStats[inContext->mIndex].mHeapRuntimeCost += - heapCost; - callsiteRun->mStats[inContext->mIndex].mSize += size; - callsiteRun->mStats[inContext->mIndex].mTimeval64 += - timeval64; - callsiteRun->mStats[inContext->mIndex].mWeight64 += - weight64; - } - - callsite = callsite->parent; - } - } - } - - return 0; -} - - -/* -** appendAllocation -** -** Given a run, append the allocation to it. -** No DUP checks are done. -** Also, we might want to update the parent callsites with stats. -** We decide to do this heavy duty work only if the run we are appending -** to has a non ZERO mStats[].mStamp, meaning that it is asking to track -** such information when it was created. -** Returns !0 on success. -*/ -int -appendAllocation(STOptions * inOptions, STContext * inContext, - STRun * aRun, STAllocation * aAllocation) -{ - int retval = 0; - - if (NULL != aRun && NULL != aAllocation && NULL != inOptions) { - STAllocation **expand = NULL; - - /* - ** Expand the size of the array if needed. - */ - expand = (STAllocation **) realloc(aRun->mAllocations, - sizeof(STAllocation *) * - (aRun->mAllocationCount + 1)); - if (NULL != expand) { - /* - ** Reassign in case of pointer move. - */ - aRun->mAllocations = expand; - - /* - ** Stick the allocation in. - */ - aRun->mAllocations[aRun->mAllocationCount] = aAllocation; - - /* - ** If this is the global run, we need to let the allocation - ** track the index back to us. - */ - if (&globals.mRun == aRun) { - aAllocation->mRunIndex = aRun->mAllocationCount; - } - - /* - ** Increase the count. - */ - aRun->mAllocationCount++; - - /* - ** We're good. - */ - retval = __LINE__; - - /* - ** update allocation cost - */ - recalculateAllocationCost(inOptions, inContext, aRun, aAllocation, - PR_TRUE); - } - else { - REPORT_ERROR(__LINE__, appendAllocation); - } - } - else { - REPORT_ERROR(__LINE__, appendAllocation); - } - - return retval; -} - -/* -** hasCallsiteMatch -** -** Determine if the callsite or the other callsites has the matching text. -** -** Returns 0 if there is no match. -*/ -int -hasCallsiteMatch(tmcallsite * aCallsite, const char *aMatch, int aDirection) -{ - int retval = 0; - - if (NULL != aCallsite && NULL != aCallsite->method && - NULL != aMatch && '\0' != *aMatch) { - const char *methodName = NULL; - - do { - methodName = tmmethodnode_name(aCallsite->method); - if (NULL != methodName && NULL != strstr(methodName, aMatch)) { - /* - ** Contains the text. - */ - retval = __LINE__; - break; - } - else { - switch (aDirection) { - case ST_FOLLOW_SIBLINGS: - aCallsite = aCallsite->siblings; - break; - case ST_FOLLOW_PARENTS: - aCallsite = aCallsite->parent; - break; - default: - aCallsite = NULL; - REPORT_ERROR(__LINE__, hasCallsiteMatch); - break; - } - } - } - while (NULL != aCallsite && NULL != aCallsite->method); - } - else { - REPORT_ERROR(__LINE__, hasCallsiteMatch); - } - - return retval; -} - -/* -** harvestRun -** -** Provide a simply way to go over a run, and yield the relevant allocations. -** The restrictions are easily set via the options page or the command -** line switches. -** -** On any match, add the allocation to the provided run. -** -** This makes it much easier for all the code to respect the options in -** force. -** -** Returns !0 on error, though aOutRun may contain a partial data set. -*/ -int -harvestRun(const STRun * aInRun, STRun * aOutRun, - STOptions * aOptions, STContext * inContext) -{ - int retval = 0; - -#if defined(DEBUG_dp) - PRIntervalTime start = PR_IntervalNow(); - - fprintf(stderr, "DEBUG: harvesting run...\n"); -#endif - - if (NULL != aInRun && NULL != aOutRun && aInRun != aOutRun - && NULL != aOptions && NULL != inContext) { - uint32_t traverse = 0; - STAllocation *current = NULL; - - for (traverse = 0; - 0 == retval && traverse < aInRun->mAllocationCount; traverse++) { - current = aInRun->mAllocations[traverse]; - if (NULL != current) { - uint32_t lifetime = 0; - uint32_t bytesize = 0; - uint64_t weight64 = 0; - uint64_t bytesize64 = 0; - uint64_t lifetime64 = 0; - int appendRes = 0; - int looper = 0; - PRBool matched = PR_FALSE; - - /* - ** Use this as an opportune time to fixup a memory - ** leaked timeval, so as to not completely skew - ** the weights. - */ - if (ST_TIMEVAL_MAX == current->mMaxTimeval) { - current->mMaxTimeval = globals.mMaxTimeval; - } - - /* - ** Check allocation timeval restrictions. - ** We have to slide the recorded timevals to be zero - ** based, so that the comparisons make sense. - */ - if ((aOptions->mAllocationTimevalMin > - (current->mMinTimeval - globals.mMinTimeval)) || - (aOptions->mAllocationTimevalMax < - (current->mMinTimeval - globals.mMinTimeval))) { - continue; - } - - /* - ** Check timeval restrictions. - ** We have to slide the recorded timevals to be zero - ** based, so that the comparisons make sense. - */ - if ((aOptions->mTimevalMin > - (current->mMinTimeval - globals.mMinTimeval)) || - (aOptions->mTimevalMax < - (current->mMinTimeval - globals.mMinTimeval))) { - continue; - } - - /* - ** Check lifetime restrictions. - */ - lifetime = current->mMaxTimeval - current->mMinTimeval; - if ((lifetime < aOptions->mLifetimeMin) || - (lifetime > aOptions->mLifetimeMax)) { - continue; - } - - /* - ** Check byte size restrictions. - */ - bytesize = byteSize(aOptions, current); - if ((bytesize < aOptions->mSizeMin) || - (bytesize > aOptions->mSizeMax)) { - continue; - } - - /* - ** Check weight restrictions. - */ - weight64 = (uint64_t)(bytesize * lifetime); - if (weight64 < aOptions->mWeightMin64 || - weight64 > aOptions->mWeightMax64) { - continue; - } - - /* - ** Possibly restrict the callsite by text. - ** Do this last, as it is a heavier check. - ** - ** One day, we may need to expand the logic to check for - ** events beyond the initial allocation event. - */ - for (looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++) { - if ('\0' != aOptions->mRestrictText[looper][0]) { - if (0 == - hasCallsiteMatch(current->mEvents[0].mCallsite, - aOptions->mRestrictText[looper], - ST_FOLLOW_PARENTS)) { - break; - } - } - else { - matched = PR_TRUE; - break; - } - } - if (ST_SUBSTRING_MATCH_MAX == looper) { - matched = PR_TRUE; - } - if (PR_FALSE == matched) { - continue; - } - - /* - ** You get here, we add to the run. - */ - appendRes = - appendAllocation(aOptions, inContext, aOutRun, current); - if (0 == appendRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, appendAllocation); - } - } - } - } - -#if defined(DEBUG_dp) - fprintf(stderr, "DEBUG: harvesting ends: %dms [%d allocations]\n", - PR_IntervalToMilliseconds(PR_IntervalNow() - start), - aInRun->mAllocationCount); -#endif - return retval; -} - -/* -** recalculateRunCost -** -** Goes over all allocations of a run and recalculates and propagates -** the allocation costs - weight, heapcount, size -*/ -int -recalculateRunCost(STOptions * inOptions, STContext * inContext, STRun * aRun) -{ - uint32_t traverse = 0; - STAllocation *current = NULL; - -#if defined(DEBUG_dp) - PRIntervalTime start = PR_IntervalNow(); - - fprintf(stderr, "DEBUG: recalculateRunCost...\n"); -#endif - - if (NULL == aRun) - return -1; - - /* reset stats of this run to 0 to begin recalculation */ - memset(&aRun->mStats[inContext->mIndex], 0, sizeof(STCallsiteStats)); - - /* reset timestamp to force propogation of cost */ - aRun->mStats[inContext->mIndex].mStamp = PR_IntervalNow(); - - for (traverse = 0; traverse < aRun->mAllocationCount; traverse++) { - current = aRun->mAllocations[traverse]; - if (NULL != current) { - recalculateAllocationCost(inOptions, inContext, aRun, current, - PR_TRUE); - } - } - -#if defined(DEBUG_dp) - fprintf(stderr, "DEBUG: recalculateRunCost ends: %dms [%d allocations]\n", - PR_IntervalToMilliseconds(PR_IntervalNow() - start), - aRun->mAllocationCount); -#endif - - return 0; -} - - -/* -** compareAllocations -** -** qsort callback. -** Compare the allocations as specified by the options. -*/ -int -compareAllocations(const void *aAlloc1, const void *aAlloc2, void *aContext) -{ - int retval = 0; - STOptions *inOptions = (STOptions *) aContext; - - if (NULL != aAlloc1 && NULL != aAlloc2 && NULL != inOptions) { - STAllocation *alloc1 = *((STAllocation **) aAlloc1); - STAllocation *alloc2 = *((STAllocation **) aAlloc2); - - if (NULL != alloc1 && NULL != alloc2) { - /* - ** Logic determined by pref/option. - */ - switch (inOptions->mOrderBy) { - case ST_COUNT: - /* - ** "By count" on a single allocation means nothing, - ** fall through to weight. - */ - case ST_WEIGHT: - { - uint64_t weight164 = 0; - uint64_t weight264 = 0; - uint64_t bytesize164 = 0; - uint64_t bytesize264 = 0; - uint64_t timeval164 = 0; - uint64_t timeval264 = 0; - - bytesize164 = byteSize(inOptions, alloc1); - timeval164 = alloc1->mMaxTimeval - alloc1->mMinTimeval; - weight164 = bytesize164 * timeval164; - bytesize264 = byteSize(inOptions, alloc2); - timeval264 = alloc2->mMaxTimeval - alloc2->mMinTimeval; - weight264 = bytesize264 * timeval264; - - if (weight164 < weight264) { - retval = __LINE__; - } - else if (weight164 > weight264) { - retval = -__LINE__; - } - } - break; - - case ST_SIZE: - { - uint32_t size1 = byteSize(inOptions, alloc1); - uint32_t size2 = byteSize(inOptions, alloc2); - - if (size1 < size2) { - retval = __LINE__; - } - else if (size1 > size2) { - retval = -__LINE__; - } - } - break; - - case ST_TIMEVAL: - { - uint32_t timeval1 = - (alloc1->mMaxTimeval - alloc1->mMinTimeval); - uint32_t timeval2 = - (alloc2->mMaxTimeval - alloc2->mMinTimeval); - - if (timeval1 < timeval2) { - retval = __LINE__; - } - else if (timeval1 > timeval2) { - retval = -__LINE__; - } - } - break; - - case ST_HEAPCOST: - { - uint32_t cost1 = alloc1->mHeapRuntimeCost; - uint32_t cost2 = alloc2->mHeapRuntimeCost; - - if (cost1 < cost2) { - retval = __LINE__; - } - else if (cost1 > cost2) { - retval = -__LINE__; - } - } - break; - - default: - { - REPORT_ERROR(__LINE__, compareAllocations); - } - break; - } - } - } - - return retval; -} - -/* -** sortRun -** -** Given a run, sort it in the manner specified by the options. -** Returns !0 on failure. -*/ -int -sortRun(STOptions * inOptions, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun && NULL != inOptions) { - if (NULL != aRun->mAllocations && 0 < aRun->mAllocationCount) { - NS_QuickSort(aRun->mAllocations, aRun->mAllocationCount, - sizeof(STAllocation *), compareAllocations, - inOptions); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, sortRun); - } - - return retval; -} - -/* -** createRun -** -** Returns a newly allocated run, properly initialized. -** Must call freeRun() with the new STRun. -** -** ONLY PASS IN A NON_ZERO STAMP IF YOU KNOW WHAT YOU ARE DOING!!! -** A non zero stamp in a run has side effects all over the -** callsites of the allocations added to the run and their -** parents. -** -** Returns NULL on failure. -*/ -STRun * -createRun(STContext * inContext, uint32_t aStamp) -{ - STRun *retval = NULL; - - retval = (STRun *) calloc(1, sizeof(STRun)); - if (NULL != retval) { - retval->mStats = - (STCallsiteStats *) calloc(globals.mCommandLineOptions.mContexts, - sizeof(STCallsiteStats)); - if (NULL != retval->mStats) { - if (NULL != inContext) { - retval->mStats[inContext->mIndex].mStamp = aStamp; - } - } - else { - free(retval); - retval = NULL; - } - } - - return retval; -} - -/* -** freeRun -** -** Free off the run and the associated data. -*/ -void -freeRun(STRun * aRun) -{ - if (NULL != aRun) { - if (NULL != aRun->mAllocations) { - /* - ** We do not free the allocations themselves. - ** They are likely pointed to by at least 2 other existing - ** runs. - */ - free(aRun->mAllocations); - aRun->mAllocations = NULL; - } - - if (NULL != aRun->mStats) { - free(aRun->mStats); - aRun->mStats = NULL; - } - - free(aRun); - aRun = NULL; - } -} - -/* -** createRunFromGlobal -** -** Harvest the global run, then sort it. -** Returns NULL on failure. -** Must call freeRun() with the new STRun. -*/ -STRun * -createRunFromGlobal(STOptions * inOptions, STContext * inContext) -{ - STRun *retval = NULL; - - if (NULL != inOptions && NULL != inContext) { - /* - ** We stamp the run. - ** As things are appended to it, it realizes that it should stamp the - ** callsite backtrace with the information as well. - ** In this manner, we can provide meaningful callsite data. - */ - retval = createRun(inContext, PR_IntervalNow()); - - if (NULL != retval) { - STCategoryNode *node = NULL; - int failure = 0; - int harvestRes = - harvestRun(&globals.mRun, retval, inOptions, inContext); - if (0 == harvestRes) { - int sortRes = sortRun(inOptions, retval); - - if (0 != sortRes) { - failure = __LINE__; - } - } - else { - failure = __LINE__; - } - - - if (0 != failure) { - freeRun(retval); - retval = NULL; - - REPORT_ERROR(failure, createRunFromGlobal); - } - - /* - ** Categorize the run. - */ - failure = categorizeRun(inOptions, inContext, retval, &globals); - if (0 != failure) { - REPORT_ERROR(__LINE__, categorizeRun); - } - - /* - ** if we are focussing on a category, return that run instead of - ** the harvested run. Make sure to recalculate cost. - */ - node = findCategoryNode(inOptions->mCategoryName, &globals); - if (node) { - /* Recalculate cost of run */ - recalculateRunCost(inOptions, inContext, - node->runs[inContext->mIndex]); - - retval = node->runs[inContext->mIndex]; - } - } - } - else { - REPORT_ERROR(__LINE__, createRunFromGlobal); - } - - return retval; -} - -/* -** getLiveAllocationByHeapID -** -** Go through a run and find the right heap ID. -** At the time of the call to this function, the allocation must be LIVE, -** meaning that it can not be freed. -** Go through the run backwards, in hopes of finding it near the end. -** -** Returns the allocation on success, otherwise NULL. -*/ -STAllocation * -getLiveAllocationByHeapID(STRun * aRun, uint32_t aHeapID) -{ - STAllocation *retval = NULL; - - if (NULL != aRun && 0 != aHeapID) { - uint32_t traverse = aRun->mAllocationCount; - STAllocation *eval = NULL; - - /* - ** Go through in reverse order. - ** Stop when we have a return value. - */ - while (0 < traverse && NULL == retval) { - /* - ** Back up one to align with zero based index. - */ - traverse--; - - /* - ** Take the pointer math out of further operations. - */ - eval = aRun->mAllocations[traverse]; - - /* - ** Take a look at the events in reverse order. - ** Basically the last event must NOT be a free. - ** The last event must NOT be a realloc of size zero (free). - ** Otherwise, try to match up the heapID of the event. - */ - if (0 != eval->mEventCount) { - STAllocEvent *event = eval->mEvents + (eval->mEventCount - 1); - - switch (event->mEventType) { - case TM_EVENT_FREE: - { - /* - ** No freed allocation can match. - */ - } - break; - - case TM_EVENT_REALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_MALLOC: - { - /* - ** Heap IDs must match. - */ - if (aHeapID == event->mHeapID) { - retval = eval; - } - } - break; - - default: - { - REPORT_ERROR(__LINE__, getAllocationByHeapID); - } - break; - } - } - } - } - else { - REPORT_ERROR(__LINE__, getAllocationByHeapID); - } - - return retval; -} - -/* -** appendEvent -** -** Given an allocation, append a new event to its lifetime. -** Returns the new event on success, otherwise NULL. -*/ -STAllocEvent * -appendEvent(STAllocation * aAllocation, uint32_t aTimeval, char aEventType, - uint32_t aHeapID, uint32_t aHeapSize, tmcallsite * aCallsite) -{ - STAllocEvent *retval = NULL; - - if (NULL != aAllocation && NULL != aCallsite) { - STAllocEvent *expand = NULL; - - /* - ** Expand the allocation's event array. - */ - expand = - (STAllocEvent *) realloc(aAllocation->mEvents, - sizeof(STAllocEvent) * - (aAllocation->mEventCount + 1)); - if (NULL != expand) { - /* - ** Reassign in case of pointer move. - */ - aAllocation->mEvents = expand; - - /* - ** Remove the pointer math from rest of code. - */ - retval = aAllocation->mEvents + aAllocation->mEventCount; - - /* - ** Increase event array count. - */ - aAllocation->mEventCount++; - - /* - ** Fill in the event. - */ - retval->mTimeval = aTimeval; - retval->mEventType = aEventType; - retval->mHeapID = aHeapID; - retval->mHeapSize = aHeapSize; - retval->mCallsite = aCallsite; - - /* - ** Allocation may need to update idea of lifetime. - ** See allocationTracker to see mMinTimeval inited to ST_TIMEVAL_MAX. - */ - if (aAllocation->mMinTimeval > aTimeval) { - aAllocation->mMinTimeval = aTimeval; - } - - /* - ** This a free event? - ** Can only set max timeval on a free. - ** Otherwise, mMaxTimeval remains ST_TIMEVAL_MAX. - ** Set in allocationTracker. - */ - if (TM_EVENT_FREE == aEventType) { - aAllocation->mMaxTimeval = aTimeval; - } - } - else { - REPORT_ERROR(__LINE__, appendEvent); - } - } - else { - REPORT_ERROR(__LINE__, appendEvent); - } - - return retval; -} - -/* -** hasAllocation -** -** Determine if a given run has an allocation. -** This is really nothing more than a pointer comparison loop. -** Returns !0 if the run has the allocation. -*/ -int -hasAllocation(STRun * aRun, STAllocation * aTestFor) -{ - int retval = 0; - - if (NULL != aRun && NULL != aTestFor) { - uint32_t traverse = aRun->mAllocationCount; - - /* - ** Go through reverse, in the hopes it exists nearer the end. - */ - while (0 < traverse) { - /* - ** Back up. - */ - traverse--; - - if (aTestFor == aRun->mAllocations[traverse]) { - retval = __LINE__; - break; - } - } - } - else { - REPORT_ERROR(__LINE__, hasAllocation); - } - - return retval; -} - -/* -** allocationTracker -** -** Important to keep track of all allocations unique so as to determine -** their lifetimes. -** -** Returns a pointer to the allocation on success. -** Return NULL on failure. -*/ -STAllocation * -allocationTracker(uint32_t aTimeval, char aType, uint32_t aHeapRuntimeCost, - tmcallsite * aCallsite, uint32_t aHeapID, uint32_t aSize, - tmcallsite * aOldCallsite, uint32_t aOldHeapID, - uint32_t aOldSize) -{ - STAllocation *retval = NULL; - static int compactor = 1; - const int frequency = 10000; - uint32_t actualSize, actualOldSize = 0; - - actualSize = actualByteSize(&globals.mCommandLineOptions, aSize); - if (aOldSize) - actualOldSize = - actualByteSize(&globals.mCommandLineOptions, aOldSize); - - if (NULL != aCallsite) { - int newAllocation = 0; - tmcallsite *searchCallsite = NULL; - uint32_t searchHeapID = 0; - STAllocation *allocation = NULL; - - /* - ** Global operation ID increases. - */ - globals.mOperationCount++; - - /* - ** Fix up the timevals if needed. - */ - if (aTimeval < globals.mMinTimeval) { - globals.mMinTimeval = aTimeval; - } - if (aTimeval > globals.mMaxTimeval) { - globals.mMaxTimeval = aTimeval; - } - - switch (aType) { - case TM_EVENT_FREE: - { - /* - ** Update the global counter. - */ - globals.mFreeCount++; - - /* - ** Update our peak memory used counter - */ - globals.mMemoryUsed -= actualSize; - - /* - ** Not a new allocation, will need to search passed in site - ** for the original allocation. - */ - searchCallsite = aCallsite; - searchHeapID = aHeapID; - } - break; - - case TM_EVENT_MALLOC: - { - /* - ** Update the global counter. - */ - globals.mMallocCount++; - - /* - ** Update our peak memory used counter - */ - globals.mMemoryUsed += actualSize; - if (globals.mMemoryUsed > globals.mPeakMemoryUsed) { - globals.mPeakMemoryUsed = globals.mMemoryUsed; - } - - /* - ** This will be a new allocation. - */ - newAllocation = __LINE__; - } - break; - - case TM_EVENT_CALLOC: - { - /* - ** Update the global counter. - */ - globals.mCallocCount++; - - /* - ** Update our peak memory used counter - */ - globals.mMemoryUsed += actualSize; - if (globals.mMemoryUsed > globals.mPeakMemoryUsed) { - globals.mPeakMemoryUsed = globals.mMemoryUsed; - } - - /* - ** This will be a new allocation. - */ - newAllocation = __LINE__; - } - break; - - case TM_EVENT_REALLOC: - { - /* - ** Update the global counter. - */ - globals.mReallocCount++; - - /* - ** Update our peak memory used counter - */ - globals.mMemoryUsed += actualSize - actualOldSize; - if (globals.mMemoryUsed > globals.mPeakMemoryUsed) { - globals.mPeakMemoryUsed = globals.mMemoryUsed; - } - - /* - ** This might be a new allocation. - */ - if (NULL == aOldCallsite) { - newAllocation = __LINE__; - } - else { - /* - ** Need to search for the original callsite for the - ** index to the allocation. - */ - searchCallsite = aOldCallsite; - searchHeapID = aOldHeapID; - } - } - break; - - default: - { - REPORT_ERROR(__LINE__, allocationTracker); - } - break; - } - - /* - ** We are either modifying an existing allocation or we are creating - ** a new one. - */ - if (0 != newAllocation) { - allocation = (STAllocation *) calloc(1, sizeof(STAllocation)); - if (NULL != allocation) { - /* - ** Fixup the min timeval so if logic later will just work. - */ - allocation->mMinTimeval = ST_TIMEVAL_MAX; - allocation->mMaxTimeval = ST_TIMEVAL_MAX; - } - } - else if (NULL != searchCallsite - && NULL != CALLSITE_RUN(searchCallsite) - && 0 != searchHeapID) { - /* - ** We know what to search for, and we reduce what we search - ** by only looking for those allocations at a known callsite. - */ - allocation = - getLiveAllocationByHeapID(CALLSITE_RUN(searchCallsite), - searchHeapID); - } - else { - REPORT_ERROR(__LINE__, allocationTracker); - } - - if (NULL != allocation) { - STAllocEvent *appendResult = NULL; - - /* - ** Record the amount of time this allocation event took. - */ - allocation->mHeapRuntimeCost += aHeapRuntimeCost; - - /* - ** Now that we have an allocation, we need to make sure it has - ** the proper event. - */ - appendResult = - appendEvent(allocation, aTimeval, aType, aHeapID, aSize, - aCallsite); - if (NULL != appendResult) { - if (0 != newAllocation) { - int runAppendResult = 0; - int callsiteAppendResult = 0; - - /* - ** A new allocation needs to be added to the global run. - ** A new allocation needs to be added to the callsite. - */ - runAppendResult = - appendAllocation(&globals.mCommandLineOptions, NULL, - &globals.mRun, allocation); - callsiteAppendResult = - appendAllocation(&globals.mCommandLineOptions, NULL, - CALLSITE_RUN(aCallsite), allocation); - if (0 != runAppendResult && 0 != callsiteAppendResult) { - /* - ** Success. - */ - retval = allocation; - } - else { - REPORT_ERROR(__LINE__, appendAllocation); - } - } - else { - /* - ** An existing allocation, if a realloc situation, - ** may need to be added to the new callsite. - ** This can only occur if the new and old callsites - ** differ. - ** Even then, a brute force check will need to be made - ** to ensure the allocation was not added twice; - ** consider a realloc scenario where two different - ** call stacks bump the allocation back and forth. - */ - if (aCallsite != searchCallsite) { - int found = 0; - - found = - hasAllocation(CALLSITE_RUN(aCallsite), - allocation); - if (0 == found) { - int appendResult = 0; - - appendResult = - appendAllocation(&globals.mCommandLineOptions, - NULL, - CALLSITE_RUN(aCallsite), - allocation); - if (0 != appendResult) { - /* - ** Success. - */ - retval = allocation; - } - else { - REPORT_ERROR(__LINE__, appendAllocation); - } - } - else { - /* - ** Already there. - */ - retval = allocation; - } - } - else { - /* - ** Success. - */ - retval = allocation; - } - } - } - else { - REPORT_ERROR(__LINE__, appendEvent); - } - } - else { - REPORT_ERROR(__LINE__, allocationTracker); - } - } - else { - REPORT_ERROR(__LINE__, allocationTracker); - } - - /* - ** Compact the heap a bit if you can. - */ - compactor++; - if (0 == (compactor % frequency)) { - heapCompact(); - } - - return retval; -} - -/* -** trackEvent -** -** An allocation event has dropped in on us. -** We need to do the right thing and track it. -*/ -void -trackEvent(uint32_t aTimeval, char aType, uint32_t aHeapRuntimeCost, - tmcallsite * aCallsite, uint32_t aHeapID, uint32_t aSize, - tmcallsite * aOldCallsite, uint32_t aOldHeapID, uint32_t aOldSize) -{ - if (NULL != aCallsite) { - /* - ** Verify the old callsite just in case. - */ - if (NULL != CALLSITE_RUN(aCallsite) - && (NULL == aOldCallsite || NULL != CALLSITE_RUN(aOldCallsite))) { - STAllocation *allocation = NULL; - - /* - ** Add to the allocation tracking code. - */ - allocation = - allocationTracker(aTimeval, aType, aHeapRuntimeCost, - aCallsite, aHeapID, aSize, aOldCallsite, - aOldHeapID, aOldSize); - - if (NULL == allocation) { - REPORT_ERROR(__LINE__, allocationTracker); - } - } - else { - REPORT_ERROR(__LINE__, trackEvent); - } - } - else { - REPORT_ERROR(__LINE__, trackEvent); - } -} - -/* -** tmEventHandler -** -** Callback from the tmreader_eventloop function. -** Simply tries to sort out what we desire to know. -*/ - -static const char spinner_chars[] = { '/', '-', '\\', '|' }; - -#define SPINNER_UPDATE_FREQUENCY 4096 -#define SPINNER_CHAR_COUNT (sizeof(spinner_chars) / sizeof(spinner_chars[0])) -#define SPINNER_CHAR(_x) spinner_chars[(_x / SPINNER_UPDATE_FREQUENCY) % SPINNER_CHAR_COUNT] - -void -tmEventHandler(tmreader * aReader, tmevent * aEvent) -{ - static int event_count = 0; /* for spinner */ - if ((event_count++ % SPINNER_UPDATE_FREQUENCY) == 0) - printf("\rReading... %c", SPINNER_CHAR(event_count)); - - if (NULL != aReader && NULL != aEvent) { - switch (aEvent->type) { - /* - ** Events we ignore. - */ - case TM_EVENT_LIBRARY: - case TM_EVENT_METHOD: - case TM_EVENT_STATS: - case TM_EVENT_TIMESTAMP: - case TM_EVENT_FILENAME: - break; - - /* - ** Allocation events need to be tracked. - */ - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_REALLOC: - case TM_EVENT_FREE: - { - uint32_t oldptr = 0; - uint32_t oldsize = 0; - tmcallsite *callsite = NULL; - tmcallsite *oldcallsite = NULL; - - if (TM_EVENT_REALLOC == aEvent->type) { - /* - ** Only care about old arguments if there were any. - */ - if (0 != aEvent->u.alloc.oldserial) { - oldptr = aEvent->u.alloc.oldptr; - oldsize = aEvent->u.alloc.oldsize; - oldcallsite = - tmreader_callsite(aReader, - aEvent->u.alloc.oldserial); - if (NULL == oldcallsite) { - REPORT_ERROR(__LINE__, tmreader_callsite); - } - } - } - - callsite = tmreader_callsite(aReader, aEvent->serial); - if (NULL != callsite) { - /* - ** Verify a callsite run is there. - ** If not, we are ignoring this callsite. - */ - if (NULL != CALLSITE_RUN(callsite)) { - char eventType = aEvent->type; - uint32_t eventSize = aEvent->u.alloc.size; - - /* - ** Play a nasty trick on reallocs of size zero. - ** They are to become free events, adjust the size accordingly. - ** This allows me to avoid all types of special case code. - */ - if (0 == aEvent->u.alloc.size - && TM_EVENT_REALLOC == aEvent->type) { - eventType = TM_EVENT_FREE; - if (0 != aEvent->u.alloc.oldserial) { - eventSize = aEvent->u.alloc.oldsize; - } - } - trackEvent(ticks2msec - (aReader, aEvent->u.alloc.interval), - eventType, ticks2usec(aReader, - aEvent->u.alloc. - cost), callsite, - aEvent->u.alloc.ptr, eventSize, - oldcallsite, oldptr, oldsize); - } - } - else { - REPORT_ERROR(__LINE__, tmreader_callsite); - } - } - break; - - /* - ** Callsite, set up the callsite run if it does not exist. - */ - case TM_EVENT_CALLSITE: - { - tmcallsite *callsite = - tmreader_callsite(aReader, aEvent->serial); - - if (NULL != callsite) { - if (NULL == CALLSITE_RUN(callsite)) { - int createrun = __LINE__; - -#if defined(MOZILLA_CLIENT) - /* - ** For a mozilla spacetrace, ignore this particular - ** callsite as it is just noise, and causes us to - ** use a lot of memory. - ** - ** This callsite is present on the linux build, - ** not sure if the other platforms have it. - */ - if (0 != - hasCallsiteMatch(callsite, "g_main_is_running", - ST_FOLLOW_PARENTS)) { - createrun = 0; - } -#endif /* MOZILLA_CLIENT */ - - if (0 != createrun) { - callsite->data = createRun(NULL, 0); - } - } - } - else { - REPORT_ERROR(__LINE__, tmreader_callsite); - } - } - break; - - /* - ** Unhandled events should not be allowed. - */ - default: - { - REPORT_ERROR(__LINE__, tmEventHandler); - } - break; - } - } -} - -/* -** optionGetDataOut -** -** Output option get data. -*/ -void -optionGetDataOut(PRFileDesc * inFD, STOptions * inOptions) -{ - if (NULL != inFD && NULL != inOptions) { - int mark = 0; - -#define ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) \ - PR_fprintf(inFD, "%s%s=%d", (0 == mark++) ? "?" : "&", #option_name, inOptions->m##option_name); -#define ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - PR_fprintf(inFD, "%s%s=%s", (0 == mark++) ? "?" : "&", #option_name, inOptions->m##option_name); -#define ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - { \ - uint32_t loop = 0; \ - \ - for(loop = 0; loop < array_size; loop++) \ - { \ - PR_fprintf(inFD, "%s%s=%s", (0 == mark++) ? "?" : "&", #option_name, inOptions->m##option_name[loop]); \ - } \ - } -#define ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) /* no implementation */ -#define ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - PR_fprintf(inFD, "%s%s=%u", (0 == mark++) ? "?" : "&", #option_name, inOptions->m##option_name / multiplier); -#define ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - { \ - uint64_t def64 = default_value; \ - uint64_t mul64 = multiplier; \ - uint64_t div64; \ - \ - div64 = inOptions->m##option_name##64 / mul64; \ - PR_fprintf(inFD, "%s%s=%llu", (0 == mark++) ? "?" : "&", #option_name, div64); \ - } - -#include "stoptions.h" - } -} - -/* -** htmlAnchor -** -** Output an HTML anchor, or just the text depending on the mode. -*/ -void -htmlAnchor(STRequest * inRequest, - const char *aHref, - const char *aText, - const char *aTarget, const char *aClass, STOptions * inOptions) -{ - if (NULL != aHref && '\0' != *aHref && NULL != aText && '\0' != *aText) { - int anchorLive = 1; - - /* - ** In batch mode, we need to verify the anchor is live. - */ - if (0 != inRequest->mOptions.mBatchRequestCount) { - uint32_t loop = 0; - int comparison = 1; - - for (loop = 0; loop < inRequest->mOptions.mBatchRequestCount; - loop++) { - comparison = - strcmp(aHref, inRequest->mOptions.mBatchRequest[loop]); - if (0 == comparison) { - break; - } - } - - /* - ** Did we find it? - */ - if (0 == comparison) { - anchorLive = 0; - } - } - - /* - ** In any mode, don't make an href to the current page. - */ - if (0 != anchorLive && NULL != inRequest->mGetFileName) { - if (0 == strcmp(aHref, inRequest->mGetFileName)) { - anchorLive = 0; - } - } - - /* - ** Do the right thing. - */ - if (0 != anchorLive) { - PR_fprintf(inRequest->mFD, "mFD, "target=\"%s\" ", aTarget); - } - PR_fprintf(inRequest->mFD, "href=\"./%s", aHref); - - /* - ** The options, if desired, get appended as form data. - */ - optionGetDataOut(inRequest->mFD, inOptions); - - PR_fprintf(inRequest->mFD, "\">%s\n", aText); - } - else { - PR_fprintf(inRequest->mFD, "%s\n", - aClass, aText); - } - } - else { - REPORT_ERROR(__LINE__, htmlAnchor); - } -} - -/* -** htmlAllocationAnchor -** -** Output an html achor that will resolve to the allocation in question. -*/ -void -htmlAllocationAnchor(STRequest * inRequest, STAllocation * aAllocation, - const char *aText) -{ - if (NULL != aAllocation && NULL != aText && '\0' != *aText) { - char buffer[128]; - - /* - ** This is a total hack. - ** The filename contains the index of the allocation in globals.mRun. - ** Safer than using the raw pointer value.... - */ - PR_snprintf(buffer, sizeof(buffer), "allocation_%u.html", - aAllocation->mRunIndex); - - htmlAnchor(inRequest, buffer, aText, NULL, "allocation", - &inRequest->mOptions); - } - else { - REPORT_ERROR(__LINE__, htmlAllocationAnchor); - } -} - -/* -** resolveSourceFile -** -** Easy way to get a readable/short name. -** NULL if not present, not resolvable. -*/ -const char * -resolveSourceFile(tmmethodnode * aMethod) -{ - const char *retval = NULL; - - if (NULL != aMethod) { - const char *methodSays = NULL; - - methodSays = aMethod->sourcefile; - - if (NULL != methodSays && '\0' != methodSays[0] - && 0 != strcmp("noname", methodSays)) { - retval = strrchr(methodSays, '/'); - if (NULL != retval) { - retval++; - } - else { - retval = methodSays; - } - } - } - - return retval; -} - -/* -** htmlCallsiteAnchor -** -** Output an html anchor that will resolve to the callsite in question. -** If no text is provided, we provide our own. -** -** RealName determines whether or not we crawl our parents until the point -** we no longer match stats. -*/ -void -htmlCallsiteAnchor(STRequest * inRequest, tmcallsite * aCallsite, - const char *aText, int aRealName) -{ - if (NULL != aCallsite) { - char textBuf[512]; - char hrefBuf[128]; - tmcallsite *namesite = aCallsite; - - /* - ** Should we use a different name? - */ - if (0 == aRealName && NULL != namesite->parent - && NULL != namesite->parent->method) { - STRun *myRun = NULL; - STRun *upRun = NULL; - - do { - myRun = CALLSITE_RUN(namesite); - upRun = CALLSITE_RUN(namesite->parent); - - if (0 != - memcmp(&myRun->mStats[inRequest->mContext->mIndex], - &upRun->mStats[inRequest->mContext->mIndex], - sizeof(STCallsiteStats))) { - /* - ** Doesn't match, stop. - */ - break; - } - else { - /* - ** Matches, keep going up. - */ - namesite = namesite->parent; - } - } - while (NULL != namesite->parent - && NULL != namesite->parent->method); - } - - /* - ** If no text, provide our own. - */ - if (NULL == aText || '\0' == *aText) { - const char *methodName = NULL; - const char *sourceFile = NULL; - - if (NULL != namesite->method) { - methodName = tmmethodnode_name(namesite->method); - } - else { - methodName = "==NONAME=="; - } - - /* - ** Decide which format to use to identify the callsite. - ** If we can detect availability, hook up the filename with lxr information. - */ - sourceFile = resolveSourceFile(namesite->method); - if (NULL != sourceFile - && 0 == strncmp("mozilla/", namesite->method->sourcefile, - 8)) { - char lxrHREFBuf[512]; - - PR_snprintf(lxrHREFBuf, sizeof(lxrHREFBuf), - " [%s:%u]", - namesite->method->sourcefile + 8, - namesite->method->linenumber, sourceFile, - namesite->method->linenumber); - PR_snprintf(textBuf, sizeof(textBuf), - "%s%s", - methodName, lxrHREFBuf); - } - else if (NULL != sourceFile) { - PR_snprintf(textBuf, sizeof(textBuf), - "%s [%s:%u]", - methodName, sourceFile, - namesite->method->linenumber); - } - else { - PR_snprintf(textBuf, sizeof(textBuf), - "%s [+%u(%u)]", - methodName, namesite->offset, - (uint32_t) namesite->entry.key); - } - - aText = textBuf; - } - - PR_snprintf(hrefBuf, sizeof(hrefBuf), "callsite_%u.html", - (uint32_t) aCallsite->entry.key); - - htmlAnchor(inRequest, hrefBuf, aText, NULL, "callsite", - &inRequest->mOptions); - } - else { - REPORT_ERROR(__LINE__, htmlCallsiteAnchor); - } -} - -/* -** htmlHeader -** -** Output a standard header in the report files. -*/ -void -htmlHeader(STRequest * inRequest, const char *aTitle) -{ - PR_fprintf(inRequest->mFD, - "\n" - "\n" - "%s\n" - "\n" - "\n" - "
\n" - "Spacetrace" - "\n" - "Category:\n" - "%s\n", - aTitle, inRequest->mOptions.mCategoryName); - - PR_fprintf(inRequest->mFD, ""); - htmlAnchor(inRequest, "index.html", "Index", NULL, "header-menuitem", - &inRequest->mOptions); - PR_fprintf(inRequest->mFD, "\n"); - - PR_fprintf(inRequest->mFD, ""); - htmlAnchor(inRequest, "options.html", "Options", NULL, "header-menuitem", - &inRequest->mOptions); - PR_fprintf(inRequest->mFD, "\n"); - - PR_fprintf(inRequest->mFD, "\n"); /* class=navigate */ - - PR_fprintf(inRequest->mFD, - "
\n\n
\n\n"); -} - -/* -** htmlFooter -** -** Output a standard footer in the report file. -*/ -void -htmlFooter(STRequest * inRequest) -{ - PR_fprintf(inRequest->mFD, - "
\n\n" - "
\n" - "SpaceTrace\n" - "
\n\n" "\n" "\n"); -} - -/* -** htmlNotFound -** -** Not found message. -*/ -void -htmlNotFound(STRequest * inRequest) -{ - htmlHeader(inRequest, "File Not Found"); - PR_fprintf(inRequest->mFD, "File Not Found\n"); - htmlFooter(inRequest); -} - -void -htmlStartTable(STRequest* inRequest, - const char* table_class, - const char* id, - const char* caption, - const char * const headers[], uint32_t header_length) -{ - uint32_t i; - - PR_fprintf(inRequest->mFD, - "
\n" - " " - " \n" - " \n", id, - table_class ? table_class : "", - caption); - - for (i=0; i< header_length; i++) - PR_fprintf(inRequest->mFD, - " \n", headers[i]); - - PR_fprintf(inRequest->mFD, " \n"); -} - -/* -** callsiteArrayFromCallsite -** -** Simply return an array of the callsites divulged from the site passed in, -** including the site passed in. -** Do not worry about dups, or the order of the items. -** -** Returns the number of items in the array. -** If the same as aExistingCount, then nothing happened. -*/ -uint32_t -callsiteArrayFromCallsite(tmcallsite *** aArray, uint32_t aExistingCount, - tmcallsite * aSite, int aFollow) -{ - uint32_t retval = 0; - - if (NULL != aArray && NULL != aSite) { - tmcallsite **expand = NULL; - - /* - ** If we have an existing count, we just keep expanding this. - */ - retval = aExistingCount; - - /* - ** Go through every allocation. - */ - do { - /* - ** expand the array. - */ - expand = - (tmcallsite **) realloc(*aArray, - sizeof(tmcallsite *) * (retval + 1)); - if (NULL != expand) { - /* - ** Set the callsite in case of pointer move. - */ - *aArray = expand; - - /* - ** Assign the value. - */ - (*aArray)[retval] = aSite; - retval++; - } - else { - REPORT_ERROR(__LINE__, realloc); - break; - } - - - /* - ** What do we follow? - */ - switch (aFollow) { - case ST_FOLLOW_SIBLINGS: - aSite = aSite->siblings; - break; - case ST_FOLLOW_PARENTS: - aSite = aSite->parent; - break; - default: - aSite = NULL; - REPORT_ERROR(__LINE__, callsiteArrayFromCallsite); - break; - } - } - while (NULL != aSite && NULL != aSite->method); - } - - return retval; -} - -/* -** callsiteArrayFromRun -** -** Simply return an array of the callsites from the run allocations. -** We only pay attention to callsites that were not free callsites. -** Do not worry about dups, or the order of the items. -** -** Returns the number of items in the array. -** If the same as aExistingCount, then nothing happened. -*/ -uint32_t -callsiteArrayFromRun(tmcallsite *** aArray, uint32_t aExistingCount, - STRun * aRun) -{ - uint32_t retval = 0; - - if (NULL != aArray && NULL != aRun && 0 < aRun->mAllocationCount) { - uint32_t allocLoop = 0; - uint32_t eventLoop = 0; - int stopLoops = 0; - - /* - ** If we have an existing count, we just keep expanding this. - */ - retval = aExistingCount; - - /* - ** Go through every allocation. - */ - for (allocLoop = 0; - 0 == stopLoops && allocLoop < aRun->mAllocationCount; - allocLoop++) { - /* - ** Go through every event. - */ - for (eventLoop = 0; - 0 == stopLoops - && eventLoop < aRun->mAllocations[allocLoop]->mEventCount; - eventLoop++) { - /* - ** Skip the free events. - */ - if (TM_EVENT_FREE != - aRun->mAllocations[allocLoop]->mEvents[eventLoop]. - mEventType) { - tmcallsite **expand = NULL; - - /* - ** expand the array. - */ - expand = - (tmcallsite **) realloc(*aArray, - sizeof(tmcallsite *) * - (retval + 1)); - if (NULL != expand) { - /* - ** Set the callsite in case of pointer move. - */ - *aArray = expand; - - /* - ** Assign the value. - */ - (*aArray)[retval] = - aRun->mAllocations[allocLoop]->mEvents[eventLoop]. - mCallsite; - retval++; - } - else { - REPORT_ERROR(__LINE__, realloc); - stopLoops = __LINE__; - } - } - } - } - } - - return retval; -} - -/* -** getDataPRUint* -** -** Helper to avoid cut and paste code. -** Failure to find aCheckFor does not mean failure. -** In case of dups, specify an index on non "1" to get others. -** Do not touch storage space unless a find is made. -** Returns !0 on failure. -*/ -int -getDataPRUint32Base(const FormData * aGetData, const char *aCheckFor, - int inIndex, void *aStoreResult, uint32_t aBits) -{ - int retval = 0; - - if (NULL != aGetData && NULL != aCheckFor && 0 != inIndex - && NULL != aStoreResult) { - unsigned finder = 0; - - /* - ** Loop over the names, looking for an exact string match. - ** Skip over initial finds, decrementing inIndex, until "1". - */ - for (finder = 0; finder < aGetData->mNVCount; finder++) { - if (0 == strcmp(aCheckFor, aGetData->mNArray[finder])) { - inIndex--; - - if (0 == inIndex) { - int32_t scanRes = 0; - - if (64 == aBits) { - scanRes = - PR_sscanf(aGetData->mVArray[finder], "%llu", - aStoreResult); - } - else { - scanRes = - PR_sscanf(aGetData->mVArray[finder], "%u", - aStoreResult); - } - if (1 != scanRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_sscanf); - } - break; - } - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, getDataPRUint32Base); - } - - return retval; -} - -int -getDataPRUint32(const FormData * aGetData, const char *aCheckFor, int inIndex, - uint32_t * aStoreResult, uint32_t aConversion) -{ - int retval = 0; - - retval = - getDataPRUint32Base(aGetData, aCheckFor, inIndex, aStoreResult, 32); - *aStoreResult *= aConversion; - - return retval; -} - -int -getDataPRUint64(const FormData * aGetData, const char *aCheckFor, int inIndex, - uint64_t * aStoreResult64, uint64_t aConversion64) -{ - int retval = 0; - uint64_t value64 = 0; - - retval = getDataPRUint32Base(aGetData, aCheckFor, inIndex, &value64, 64); - *aStoreResult64 = value64 * aConversion64; - - return retval; -} - -/* -** getDataString -** -** Pull out the string data, if specified. -** In case of dups, specify an index on non "1" to get others. -** Do not touch storage space unless a find is made. -** Return !0 on failure. -*/ -int -getDataString(const FormData * aGetData, const char *aCheckFor, int inIndex, - char *aStoreResult, int inStoreResultLength) -{ - int retval = 0; - - if (NULL != aGetData && NULL != aCheckFor && 0 != inIndex - && NULL != aStoreResult && 0 != inStoreResultLength) { - unsigned finder = 0; - - /* - ** Loop over the names, looking for an exact string match. - ** Skip over initial finds, decrementing inIndex, until "1". - */ - for (finder = 0; finder < aGetData->mNVCount; finder++) { - if (0 == strcmp(aCheckFor, aGetData->mNArray[finder])) { - inIndex--; - - if (0 == inIndex) { - PR_snprintf(aStoreResult, inStoreResultLength, "%s", - aGetData->mVArray[finder]); - break; - } - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, getDataPRUint32); - } - - return retval; -} - -/* -** displayTopAllocations -** -** Present the top allocations. -** The run must be passed in, and it must be pre-sorted. -** -** Returns !0 on failure. -*/ -int -displayTopAllocations(STRequest * inRequest, STRun * aRun, - const char* id, - const char* caption, - int aWantCallsite) -{ - int retval = 0; - - if (NULL != aRun) { - if (0 < aRun->mAllocationCount) { - uint32_t loop = 0; - STAllocation *current = NULL; - - static const char* const headers[] = { - "Rank", "Index", "Byte Size", "Lifespan (sec)", - "Weight", "Heap Op (sec)" - }; - - static const char* const headers_callsite[] = { - "Rank", "Index", "Byte Size", "Lifespan (sec)", - "Weight", "Heap Op (sec)", "Origin Callsite" - }; - - if (aWantCallsite) - htmlStartTable(inRequest, NULL, id, - caption, - headers_callsite, - sizeof(headers_callsite) / sizeof(headers_callsite[0])); - else - htmlStartTable(inRequest, NULL, id, caption, - headers, - sizeof(headers) / sizeof(headers[0])); - /* - ** Loop over the items, up to some limit or until the end. - */ - for (loop = 0; - loop < inRequest->mOptions.mListItemMax - && loop < aRun->mAllocationCount; loop++) { - current = aRun->mAllocations[loop]; - if (NULL != current) { - uint32_t lifespan = - current->mMaxTimeval - current->mMinTimeval; - uint32_t size = byteSize(&inRequest->mOptions, current); - uint32_t heapCost = current->mHeapRuntimeCost; - uint64_t weight64 = 0; - char buffer[32]; - - weight64 =(uint64_t)(size * lifespan); - - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Rank. - */ - PR_fprintf(inRequest->mFD, "\n", - loop + 1); - - /* - ** Index. - */ - PR_snprintf(buffer, sizeof(buffer), "%u", - current->mRunIndex); - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Byte Size. - */ - PR_fprintf(inRequest->mFD, "\n", - size); - - /* - ** Lifespan. - */ - PR_fprintf(inRequest->mFD, - "\n", - ST_TIMEVAL_PRINTABLE(lifespan)); - - /* - ** Weight. - */ - PR_fprintf(inRequest->mFD, "\n", - weight64); - - /* - ** Heap operation cost. - */ - PR_fprintf(inRequest->mFD, - "\n", ST_MICROVAL_PRINTABLE(heapCost)); - - if (0 != aWantCallsite) { - /* - ** Callsite. - */ - PR_fprintf(inRequest->mFD, "\n"); - } - - PR_fprintf(inRequest->mFD, "\n"); - } - } - - PR_fprintf(inRequest->mFD, "\n
%s
%s
%u\n"); - htmlAllocationAnchor(inRequest, current, buffer); - PR_fprintf(inRequest->mFD, "%u" ST_TIMEVAL_FORMAT "%llu" ST_MICROVAL_FORMAT - ""); - htmlCallsiteAnchor(inRequest, - current->mEvents[0].mCallsite, - NULL, 0); - PR_fprintf(inRequest->mFD, "
\n\n"); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopAllocations); - } - - return retval; -} - -/* -** displayMemoryLeaks -** -** Present the top memory leaks. -** The run must be passed in, and it must be pre-sorted. -** -** Returns !0 on failure. -*/ -int -displayMemoryLeaks(STRequest * inRequest, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun) { - uint32_t loop = 0; - uint32_t displayed = 0; - STAllocation *current = NULL; - - static const char * headers[] = { - "Rank", "Index", "Byte Size", "Lifespan (sec)", - "Weight", "Heap Op (sec)", "Origin Callsite" - }; - - htmlStartTable(inRequest, NULL, "memory-leaks", "Memory Leaks", headers, - sizeof(headers) / sizeof(headers[0])); - - /* - ** Loop over all of the items, or until we've displayed enough. - */ - for (loop = 0; - displayed < inRequest->mOptions.mListItemMax - && loop < aRun->mAllocationCount; loop++) { - current = aRun->mAllocations[loop]; - if (NULL != current && 0 != current->mEventCount) { - /* - ** In order to be a leak, the last event of its life must - ** NOT be a free operation. - ** - ** A free operation is just that, a free. - */ - if (TM_EVENT_FREE != - current->mEvents[current->mEventCount - 1].mEventType) { - uint32_t lifespan = - current->mMaxTimeval - current->mMinTimeval; - uint32_t size = byteSize(&inRequest->mOptions, current); - uint32_t heapCost = current->mHeapRuntimeCost; - uint64_t weight64 = 0; - char buffer[32]; - - weight64 =(uint64_t)(size * lifespan); - - /* - ** One more shown. - */ - displayed++; - - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Rank. - */ - PR_fprintf(inRequest->mFD, "%u\n", - displayed); - - /* - ** Index. - */ - PR_snprintf(buffer, sizeof(buffer), "%u", - current->mRunIndex); - PR_fprintf(inRequest->mFD, "\n"); - htmlAllocationAnchor(inRequest, current, buffer); - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Byte Size. - */ - PR_fprintf(inRequest->mFD, "%u\n", - size); - - /* - ** Lifespan. - */ - PR_fprintf(inRequest->mFD, - "" ST_TIMEVAL_FORMAT "\n", - ST_TIMEVAL_PRINTABLE(lifespan)); - - /* - ** Weight. - */ - PR_fprintf(inRequest->mFD, "%llu\n", - weight64); - - /* - ** Heap Operation Seconds. - */ - PR_fprintf(inRequest->mFD, - "" ST_MICROVAL_FORMAT - "\n", ST_MICROVAL_PRINTABLE(heapCost)); - - /* - ** Callsite. - */ - PR_fprintf(inRequest->mFD, ""); - htmlCallsiteAnchor(inRequest, - current->mEvents[0].mCallsite, NULL, - 0); - PR_fprintf(inRequest->mFD, "\n"); - - PR_fprintf(inRequest->mFD, "\n"); - } - } - } - - PR_fprintf(inRequest->mFD, "
\n\n"); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayMemoryLeaks); - } - - return retval; -} - -/* -** displayCallsites -** -** Display a table of callsites. -** If the stamp is non zero, then must match that stamp. -** If the stamp is zero, then must match the global sorted run stamp. -** Return !0 on error. -*/ -int -displayCallsites(STRequest * inRequest, tmcallsite * aCallsite, int aFollow, - uint32_t aStamp, - const char* id, - const char* caption, - int aRealNames) -{ - int retval = 0; - - if (NULL != aCallsite && NULL != aCallsite->method) { - int headerDisplayed = 0; - STRun *run = NULL; - - /* - ** Correct the stamp if need be. - */ - if (0 == aStamp && NULL != inRequest->mContext->mSortedRun) { - aStamp = - inRequest->mContext->mSortedRun->mStats[inRequest->mContext-> - mIndex].mStamp; - } - - /* - ** Loop over the callsites looking for a stamp match. - ** A stamp guarantees there is something interesting to look at too. - ** If found, output it. - */ - while (NULL != aCallsite && NULL != aCallsite->method) { - run = CALLSITE_RUN(aCallsite); - if (NULL != run) { - if (aStamp == run->mStats[inRequest->mContext->mIndex].mStamp) { - /* - ** We got a header? - */ - if (0 == headerDisplayed) { - - static const char* const headers[] = { - "Callsite", - "C. Size", - "C. Seconds", - "C. Weight", - "H.O. Count", - "C.H. Operation (sec)" - }; - headerDisplayed = __LINE__; - htmlStartTable(inRequest, NULL, id, caption, headers, - sizeof(headers)/sizeof(headers[0])); - } - - /* - ** Output the information. - */ - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Method name. - */ - PR_fprintf(inRequest->mFD, ""); - htmlCallsiteAnchor(inRequest, aCallsite, NULL, - aRealNames); - PR_fprintf(inRequest->mFD, ""); - - /* - ** Byte Size. - */ - PR_fprintf(inRequest->mFD, - "%u\n", - run->mStats[inRequest->mContext->mIndex]. - mSize); - - /* - ** Seconds. - */ - PR_fprintf(inRequest->mFD, - "" ST_TIMEVAL_FORMAT - "\n", - ST_TIMEVAL_PRINTABLE64(run-> - mStats[inRequest-> - mContext-> - mIndex]. - mTimeval64)); - - /* - ** Weight. - */ - PR_fprintf(inRequest->mFD, - "%llu\n", - run->mStats[inRequest->mContext->mIndex]. - mWeight64); - - /* - ** Allocation object count. - */ - PR_fprintf(inRequest->mFD, - "%u\n", - run->mStats[inRequest->mContext->mIndex]. - mCompositeCount); - - /* - ** Heap Operation Seconds. - */ - PR_fprintf(inRequest->mFD, - "" - ST_MICROVAL_FORMAT "\n", - ST_MICROVAL_PRINTABLE(run-> - mStats[inRequest-> - mContext->mIndex]. - mHeapRuntimeCost)); - - PR_fprintf(inRequest->mFD, "\n"); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsites); - break; - } - - /* - ** What do we follow? - */ - switch (aFollow) { - case ST_FOLLOW_SIBLINGS: - aCallsite = aCallsite->siblings; - break; - case ST_FOLLOW_PARENTS: - aCallsite = aCallsite->parent; - break; - default: - aCallsite = NULL; - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsites); - break; - } - } - - /* - ** Terminate the table if we should. - */ - if (0 != headerDisplayed) { - PR_fprintf(inRequest->mFD, "\n\n"); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsites); - } - - return retval; -} - -/* -** displayAllocationDetails -** -** Report what we know about the allocation. -** -** Returns !0 on error. -*/ -int -displayAllocationDetails(STRequest * inRequest, STAllocation * aAllocation) -{ - int retval = 0; - - if (NULL != aAllocation) { - uint32_t traverse = 0; - uint32_t bytesize = byteSize(&inRequest->mOptions, aAllocation); - uint32_t timeval = - aAllocation->mMaxTimeval - aAllocation->mMinTimeval; - uint32_t heapCost = aAllocation->mHeapRuntimeCost; - uint64_t weight64 = 0; - uint32_t cacheval = 0; - int displayRes = 0; - - weight64 = (uint64_t)(bytesize * timeval); - - PR_fprintf(inRequest->mFD, "

Allocation %u Details:

\n", - aAllocation->mRunIndex); - - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, - "\n", - bytesize); - PR_fprintf(inRequest->mFD, - "\n", - ST_TIMEVAL_PRINTABLE(timeval)); - PR_fprintf(inRequest->mFD, - "\n", - weight64); - PR_fprintf(inRequest->mFD, - "\n", - ST_MICROVAL_PRINTABLE(heapCost)); - PR_fprintf(inRequest->mFD, "
Final Size:%u
Lifespan Seconds:" - ST_TIMEVAL_FORMAT "
Weight:%llu
Heap Operation Seconds:" - ST_MICROVAL_FORMAT "
\n"); - - /* - ** The events. - */ - - { - static const char* const headers[] = { - "Operation", "Size", "Seconds", "" - }; - - char caption[100]; - PR_snprintf(caption, sizeof(caption), "%u Life Event(s)", - aAllocation->mEventCount); - htmlStartTable(inRequest, NULL, "allocation-details", caption, headers, - sizeof(headers) / sizeof(headers[0])); - } - - for (traverse = 0; - traverse < aAllocation->mEventCount - && traverse < inRequest->mOptions.mListItemMax; traverse++) { - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** count. - */ - PR_fprintf(inRequest->mFD, - "%u.\n", traverse + 1); - - /* - ** Operation. - */ - PR_fprintf(inRequest->mFD, ""); - switch (aAllocation->mEvents[traverse].mEventType) { - case TM_EVENT_CALLOC: - PR_fprintf(inRequest->mFD, "calloc"); - break; - case TM_EVENT_FREE: - PR_fprintf(inRequest->mFD, "free"); - break; - case TM_EVENT_MALLOC: - PR_fprintf(inRequest->mFD, "malloc"); - break; - case TM_EVENT_REALLOC: - PR_fprintf(inRequest->mFD, "realloc"); - break; - default: - retval = __LINE__; - REPORT_ERROR(__LINE__, displayAllocationDetails); - break; - } - PR_fprintf(inRequest->mFD, ""); - - /* - ** Size. - */ - PR_fprintf(inRequest->mFD, "%u\n", - aAllocation->mEvents[traverse].mHeapSize); - - /* - ** Timeval. - */ - cacheval = - aAllocation->mEvents[traverse].mTimeval - globals.mMinTimeval; - PR_fprintf(inRequest->mFD, - "" ST_TIMEVAL_FORMAT - "\n", ST_TIMEVAL_PRINTABLE(cacheval)); - - /* - ** Callsite backtrace. - ** Only relevant backtrace is for event 0 for now until - ** trace-malloc outputs proper callsites for all others. - */ - PR_fprintf(inRequest->mFD, "\n"); - if (0 == traverse) { - displayRes = - displayCallsites(inRequest, - aAllocation->mEvents[traverse].mCallsite, - ST_FOLLOW_PARENTS, 0, "event-stack", "", __LINE__); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsite); - } - } - PR_fprintf(inRequest->mFD, "\n"); - - PR_fprintf(inRequest->mFD, "\n"); - } - PR_fprintf(inRequest->mFD, "\n"); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayAllocationDetails); - } - - return retval; -} - -/* -** compareCallsites -** -** qsort callback. -** Compare the callsites as specified by the options. -** There must be NO equal callsites, unless they really are duplicates, -** this is so that a duplicate detector loop can -** simply skip sorted items until the callsite is different. -*/ -int -compareCallsites(const void *aSite1, const void *aSite2, void *aContext) -{ - int retval = 0; - STRequest *inRequest = (STRequest *) aContext; - - if (NULL != aSite1 && NULL != aSite2) { - tmcallsite *site1 = *((tmcallsite **) aSite1); - tmcallsite *site2 = *((tmcallsite **) aSite2); - - if (NULL != site1 && NULL != site2) { - STRun *run1 = CALLSITE_RUN(site1); - STRun *run2 = CALLSITE_RUN(site2); - - if (NULL != run1 && NULL != run2) { - STCallsiteStats *stats1 = - &(run1->mStats[inRequest->mContext->mIndex]); - STCallsiteStats *stats2 = - &(run2->mStats[inRequest->mContext->mIndex]); - - /* - ** Logic determined by pref/option. - */ - switch (inRequest->mOptions.mOrderBy) { - case ST_WEIGHT: - { - uint64_t weight164 = stats1->mWeight64; - uint64_t weight264 = stats2->mWeight64; - - if (weight164 < weight264) { - retval = __LINE__; - } - else if (weight164 > weight264) { - retval = -__LINE__; - } - } - break; - - case ST_SIZE: - { - uint32_t size1 = stats1->mSize; - uint32_t size2 = stats2->mSize; - - if (size1 < size2) { - retval = __LINE__; - } - else if (size1 > size2) { - retval = -__LINE__; - } - } - break; - - case ST_TIMEVAL: - { - uint64_t timeval164 = stats1->mTimeval64; - uint64_t timeval264 = stats2->mTimeval64; - - if (timeval164 < timeval264) { - retval = __LINE__; - } - else if (timeval164 > timeval264) { - retval = -__LINE__; - } - } - break; - - case ST_COUNT: - { - uint32_t count1 = stats1->mCompositeCount; - uint32_t count2 = stats2->mCompositeCount; - - if (count1 < count2) { - retval = __LINE__; - } - else if (count1 > count2) { - retval = -__LINE__; - } - } - break; - - case ST_HEAPCOST: - { - uint32_t cost1 = stats1->mHeapRuntimeCost; - uint32_t cost2 = stats2->mHeapRuntimeCost; - - if (cost1 < cost2) { - retval = __LINE__; - } - else if (cost1 > cost2) { - retval = -__LINE__; - } - } - break; - - default: - { - REPORT_ERROR(__LINE__, compareAllocations); - } - break; - } - - /* - ** If the return value is still zero, do a pointer compare. - ** This makes sure we return zero, only iff the same object. - */ - if (0 == retval) { - if (stats1 < stats2) { - retval = __LINE__; - } - else if (stats1 > stats2) { - retval = -__LINE__; - } - } - } - } - } - - return retval; -} - -/* -** displayTopCallsites -** -** Given a list of callsites, sort it, and output skipping dups. -** The passed in callsite array is side effected, as in that it will come -** back sorted. This function will not release the array. -** -** Note: If the stamp passed in is non zero, then all callsites must match. -** If the stamp is zero, all callsites must match global sorted run stamp. -** -** Returns !0 on error. -*/ -int -displayTopCallsites(STRequest * inRequest, tmcallsite ** aCallsites, - uint32_t aCallsiteCount, uint32_t aStamp, - const char* id, - const char* caption, - int aRealName) -{ - int retval = 0; - - if (NULL != aCallsites && 0 < aCallsiteCount) { - uint32_t traverse = 0; - STRun *run = NULL; - tmcallsite *site = NULL; - int headerDisplayed = 0; - uint32_t displayed = 0; - - /* - ** Fixup the stamp. - */ - if (0 == aStamp && NULL != inRequest->mContext->mSortedRun) { - aStamp = - inRequest->mContext->mSortedRun->mStats[inRequest->mContext-> - mIndex].mStamp; - } - - /* - ** Sort the things. - */ - NS_QuickSort(aCallsites, aCallsiteCount, sizeof(tmcallsite *), - compareCallsites, inRequest); - - /* - ** Time for output. - */ - for (traverse = 0; - traverse < aCallsiteCount - && inRequest->mOptions.mListItemMax > displayed; traverse++) { - site = aCallsites[traverse]; - run = CALLSITE_RUN(site); - - /* - ** Only if the same stamp.... - */ - if (aStamp == run->mStats[inRequest->mContext->mIndex].mStamp) { - /* - ** We got a header yet? - */ - if (0 == headerDisplayed) { - static const char* const headers[] = { - "Rank", - "Callsite", - "Size", - "Seconds", - "Weight", - "Object Count", - "C.H. Operation (sec)" - }; - headerDisplayed = __LINE__; - - htmlStartTable(inRequest, NULL, id, caption, headers, - sizeof(headers) / sizeof(headers[0])); - } - - displayed++; - - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Rank. - */ - PR_fprintf(inRequest->mFD, - "%u\n", displayed); - - /* - ** Method. - */ - PR_fprintf(inRequest->mFD, ""); - htmlCallsiteAnchor(inRequest, site, NULL, aRealName); - PR_fprintf(inRequest->mFD, "\n"); - - /* - ** Size. - */ - PR_fprintf(inRequest->mFD, - "%u\n", - run->mStats[inRequest->mContext->mIndex].mSize); - - /* - ** Timeval. - */ - PR_fprintf(inRequest->mFD, - "" ST_TIMEVAL_FORMAT - "\n", - ST_TIMEVAL_PRINTABLE64(run-> - mStats[inRequest->mContext-> - mIndex].mTimeval64)); - - /* - ** Weight. - */ - PR_fprintf(inRequest->mFD, - "%llu\n", - run->mStats[inRequest->mContext->mIndex]. - mWeight64); - - /* - ** Allocation object count. - */ - PR_fprintf(inRequest->mFD, - "%u\n", - run->mStats[inRequest->mContext->mIndex]. - mCompositeCount); - - /* - ** Heap operation seconds. - */ - PR_fprintf(inRequest->mFD, - "" ST_MICROVAL_FORMAT - "\n", - ST_MICROVAL_PRINTABLE(run-> - mStats[inRequest->mContext-> - mIndex]. - mHeapRuntimeCost)); - - PR_fprintf(inRequest->mFD, "\n"); - - - if (inRequest->mOptions.mListItemMax > displayed) { - /* - ** Skip any dups. - */ - while (((traverse + 1) < aCallsiteCount) - && (site == aCallsites[traverse + 1])) { - traverse++; - } - } - } - } - - /* - ** We need to terminate anything? - */ - if (0 != headerDisplayed) { - PR_fprintf(inRequest->mFD, "\n"); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopCallsites); - } - - return retval; -} - -/* -** displayCallsiteDetails -** -** The callsite specific report. -** Try to report what we know. -** This one hits a little harder than the rest. -** -** Returns !0 on error. -*/ -int -displayCallsiteDetails(STRequest * inRequest, tmcallsite * aCallsite) -{ - int retval = 0; - - if (NULL != aCallsite && NULL != aCallsite->method) { - STRun *sortedRun = NULL; - STRun *thisRun = CALLSITE_RUN(aCallsite); - const char *sourceFile = NULL; - - sourceFile = resolveSourceFile(aCallsite->method); - - PR_fprintf(inRequest->mFD, "
\n"); - if (sourceFile) { - PR_fprintf(inRequest->mFD, "%s", - tmmethodnode_name(aCallsite->method)); - PR_fprintf(inRequest->mFD, - " [%s:%u]", - aCallsite->method->sourcefile, - aCallsite->method->linenumber, sourceFile, - aCallsite->method->linenumber); - } - else { - PR_fprintf(inRequest->mFD, - "

%s+%u(%u) Callsite Details:

\n", - tmmethodnode_name(aCallsite->method), - aCallsite->offset, (uint32_t) aCallsite->entry.key); - } - - PR_fprintf(inRequest->mFD, "
\n\n"); - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, - "\n", - thisRun->mStats[inRequest->mContext->mIndex].mSize); - PR_fprintf(inRequest->mFD, - "\n", - ST_TIMEVAL_PRINTABLE64(thisRun-> - mStats[inRequest->mContext->mIndex]. - mTimeval64)); - PR_fprintf(inRequest->mFD, - "\n", - thisRun->mStats[inRequest->mContext->mIndex].mWeight64); - PR_fprintf(inRequest->mFD, - "\n", - thisRun->mStats[inRequest->mContext->mIndex]. - mCompositeCount); - PR_fprintf(inRequest->mFD, - "\n", - ST_MICROVAL_PRINTABLE(thisRun-> - mStats[inRequest->mContext->mIndex]. - mHeapRuntimeCost)); - PR_fprintf(inRequest->mFD, "
Composite Byte Size:%u
Composite Seconds:" - ST_TIMEVAL_FORMAT "
Composite Weight:%llu
Heap Object Count:%u
Heap Operation Seconds:" - ST_MICROVAL_FORMAT "
\n\n"); - - /* - ** Kids (callsites we call): - */ - if (NULL != aCallsite->kids && NULL != aCallsite->kids->method) { - int displayRes = 0; - uint32_t siteCount = 0; - tmcallsite **sites = NULL; - - /* - ** Collect the kid sibling callsites. - ** Doing it this way sorts them for relevance. - */ - siteCount = - callsiteArrayFromCallsite(&sites, 0, aCallsite->kids, - ST_FOLLOW_SIBLINGS); - if (0 != siteCount && NULL != sites) { - /* - ** Got something to show. - */ - displayRes = - displayTopCallsites(inRequest, sites, siteCount, 0, - "callsites", - "Children Callsites", - __LINE__); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopCallsites); - } - - /* - ** Done with array. - */ - free(sites); - sites = NULL; - } - } - - /* - ** Parents (those who call us): - */ - if (NULL != aCallsite->parent && NULL != aCallsite->parent->method) { - int displayRes = 0; - - displayRes = - displayCallsites(inRequest, aCallsite->parent, - ST_FOLLOW_PARENTS, 0, "caller-stack", "Caller stack", - __LINE__); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsites); - } - } - - /* - ** Allocations we did. - ** Simply harvest our own run. - */ - sortedRun = createRun(inRequest->mContext, 0); - if (NULL != sortedRun) { - int harvestRes = 0; - - harvestRes = - harvestRun(CALLSITE_RUN(aCallsite), sortedRun, - &inRequest->mOptions, inRequest->mContext); - if (0 == harvestRes) { - if (0 != sortedRun->mAllocationCount) { - int sortRes = 0; - - sortRes = sortRun(&inRequest->mOptions, sortedRun); - if (0 == sortRes) { - int displayRes = 0; - - displayRes = - displayTopAllocations(inRequest, sortedRun, - "allocations", - "Allocations", - 0); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopAllocations); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, sortRun); - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, harvestRun); - } - - /* - ** Done with the run. - */ - freeRun(sortedRun); - sortedRun = NULL; - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, createRun); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsiteDetails); - } - - return retval; -} - -#if ST_WANT_GRAPHS -/* -** graphFootprint -** -** Output a PNG graph of the memory usage of the run. -** -** Draw the graph within these boundaries. -** STGD_MARGIN,STGD_MARGIN,STGD_WIDTH-STGD_MARGIN,STGD_HEIGHT-STGD_MARGIN -** -** Returns !0 on failure. -*/ -int -graphFootprint(STRequest * inRequest, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun) { - uint32_t *YData = NULL; - uint32_t YDataArray[STGD_SPACE_X]; - uint32_t traverse = 0; - uint32_t timeval = 0; - uint32_t loop = 0; - PRBool underLock = PR_FALSE; - - /* - ** Decide if this is custom or we should use the cache. - */ - if (aRun == inRequest->mContext->mSortedRun) { - YData = inRequest->mContext->mFootprintYData; - underLock = PR_TRUE; - } - else { - YData = YDataArray; - } - - /* - ** Protect the shared data so that only one client has access to it - ** at any given time. - */ - if (PR_FALSE != underLock) { - PR_Lock(inRequest->mContext->mImageLock); - } - - /* - ** Only do the computations if we aren't cached already. - */ - if (YData != inRequest->mContext->mFootprintYData - || PR_FALSE == inRequest->mContext->mFootprintCached) { - memset(YData, 0, sizeof(uint32_t) * STGD_SPACE_X); - - /* - ** Initialize our Y data. - ** Pretty brutal loop here.... - */ - for (traverse = 0; 0 == retval && traverse < STGD_SPACE_X; - traverse++) { - /* - ** Compute what timeval this Y data lands in. - */ - timeval = - ((traverse * - (globals.mMaxTimeval - - globals.mMinTimeval)) / STGD_SPACE_X) + - globals.mMinTimeval; - - /* - ** Loop over the run. - ** Should an allocation contain said Timeval, we're good. - */ - for (loop = 0; loop < aRun->mAllocationCount; loop++) { - if (timeval >= aRun->mAllocations[loop]->mMinTimeval - && timeval <= aRun->mAllocations[loop]->mMaxTimeval) { - YData[traverse] += - byteSize(&inRequest->mOptions, - aRun->mAllocations[loop]); - } - } - } - - /* - ** Did we cache this? - */ - if (YData == inRequest->mContext->mFootprintYData) { - inRequest->mContext->mFootprintCached = PR_TRUE; - } - } - - /* - ** Done with the lock. - */ - if (PR_FALSE != underLock) { - PR_Unlock(inRequest->mContext->mImageLock); - } - - if (0 == retval) { - uint32_t minMemory = (uint32_t) - 1; - uint32_t maxMemory = 0; - int transparent = 0; - gdImagePtr graph = NULL; - - /* - ** Go through and find the minimum and maximum sizes. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - if (YData[traverse] < minMemory) { - minMemory = YData[traverse]; - } - if (YData[traverse] > maxMemory) { - maxMemory = YData[traverse]; - } - } - - /* - ** We can now draw the graph. - */ - graph = createGraph(&transparent); - if (NULL != graph) { - gdSink theSink; - int red = 0; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - uint32_t percents[11] = - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; - char *timevals[11]; - char *bytes[11]; - char timevalSpace[11][32]; - char byteSpace[11][32]; - int legendColors[1]; - const char *legends[1] = { "Memory in Use" }; - uint32_t cached = 0; - - /* - ** Figure out what the labels will say. - */ - for (traverse = 0; traverse < 11; traverse++) { - timevals[traverse] = timevalSpace[traverse]; - bytes[traverse] = byteSpace[traverse]; - - cached = - ((globals.mMaxTimeval - - globals.mMinTimeval) * percents[traverse]) / 100; - PR_snprintf(timevals[traverse], 32, ST_TIMEVAL_FORMAT, - ST_TIMEVAL_PRINTABLE(cached)); - PR_snprintf(bytes[traverse], 32, "%u", - ((maxMemory - - minMemory) * percents[traverse]) / 100); - } - - red = gdImageColorAllocate(graph, 255, 0, 0); - legendColors[0] = red; - - drawGraph(graph, -1, "Memory Footprint Over Time", "Seconds", - "Bytes", 11, percents, (const char **) timevals, 11, - percents, (const char **) bytes, 1, legendColors, - legends); - - if (maxMemory != minMemory) { - int64_t in64 = 0; - int64_t ydata64 = 0; - int64_t spacey64 = 0; - int64_t mem64 = 0; - int32_t in32 = 0; - - /* - ** Go through our Y data and mark it up. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - x1 = traverse + STGD_MARGIN; - y1 = STGD_HEIGHT - STGD_MARGIN; - - /* - ** Need to do this math in 64 bits. - */ - ydata64 = (int64_t)YData[traverse]; - spacey64 = (int64_t)STGD_SPACE_Y; - mem64 = (int64_t)(maxMemory - minMemory); - - in64 = ydata64 * spacey64; - in64 /= mem64; - in32 = int32_t(in64); - - x2 = x1; - y2 = y1 - in32; - - gdImageLine(graph, x1, y1, x2, y2, red); - } - } - - - theSink.context = inRequest->mFD; - theSink.sink = pngSink; - gdImagePngToSink(graph, &theSink); - - gdImageDestroy(graph); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, createGraph); - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphFootprint); - } - - return retval; -} -#endif /* ST_WANT_GRAPHS */ - -#if ST_WANT_GRAPHS -/* -** graphTimeval -** -** Output a PNG graph of when the memory is allocated. -** -** Draw the graph within these boundaries. -** STGD_MARGIN,STGD_MARGIN,STGD_WIDTH-STGD_MARGIN,STGD_HEIGHT-STGD_MARGIN -** -** Returns !0 on failure. -*/ -int -graphTimeval(STRequest * inRequest, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun) { - uint32_t *YData = NULL; - uint32_t YDataArray[STGD_SPACE_X]; - uint32_t traverse = 0; - uint32_t timeval = globals.mMinTimeval; - uint32_t loop = 0; - PRBool underLock = PR_FALSE; - - /* - ** Decide if this is custom or we should use the global cache. - */ - if (aRun == inRequest->mContext->mSortedRun) { - YData = inRequest->mContext->mTimevalYData; - underLock = PR_TRUE; - } - else { - YData = YDataArray; - } - - /* - ** Protect the shared data so that only one client has access to it - ** at any given time. - */ - if (PR_FALSE != underLock) { - PR_Lock(inRequest->mContext->mImageLock); - } - - /* - ** Only do the computations if we aren't cached already. - */ - if (YData != inRequest->mContext->mTimevalYData - || PR_FALSE == inRequest->mContext->mTimevalCached) { - uint32_t prevTimeval = 0; - - memset(YData, 0, sizeof(uint32_t) * STGD_SPACE_X); - - /* - ** Initialize our Y data. - ** Pretty brutal loop here.... - */ - for (traverse = 0; 0 == retval && traverse < STGD_SPACE_X; - traverse++) { - /* - ** Compute what timeval this Y data lands in. - */ - prevTimeval = timeval; - timeval = - ((traverse * - (globals.mMaxTimeval - - globals.mMinTimeval)) / STGD_SPACE_X) + - globals.mMinTimeval; - - /* - ** Loop over the run. - ** Should an allocation have been allocated between - ** prevTimeval and timeval.... - */ - for (loop = 0; loop < aRun->mAllocationCount; loop++) { - if (prevTimeval < aRun->mAllocations[loop]->mMinTimeval - && timeval >= aRun->mAllocations[loop]->mMinTimeval) { - YData[traverse] += - byteSize(&inRequest->mOptions, - aRun->mAllocations[loop]); - } - } - } - - /* - ** Did we cache this? - */ - if (YData == inRequest->mContext->mTimevalYData) { - inRequest->mContext->mTimevalCached = PR_TRUE; - } - } - - /* - ** Done with the lock. - */ - if (PR_FALSE != underLock) { - PR_Unlock(inRequest->mContext->mImageLock); - } - - if (0 == retval) { - uint32_t minMemory = (uint32_t) - 1; - uint32_t maxMemory = 0; - int transparent = 0; - gdImagePtr graph = NULL; - - /* - ** Go through and find the minimum and maximum sizes. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - if (YData[traverse] < minMemory) { - minMemory = YData[traverse]; - } - if (YData[traverse] > maxMemory) { - maxMemory = YData[traverse]; - } - } - - /* - ** We can now draw the graph. - */ - graph = createGraph(&transparent); - if (NULL != graph) { - gdSink theSink; - int red = 0; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - uint32_t percents[11] = - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; - char *timevals[11]; - char *bytes[11]; - char timevalSpace[11][32]; - char byteSpace[11][32]; - int legendColors[1]; - const char *legends[1] = { "Memory Allocated" }; - uint32_t cached = 0; - - /* - ** Figure out what the labels will say. - */ - for (traverse = 0; traverse < 11; traverse++) { - timevals[traverse] = timevalSpace[traverse]; - bytes[traverse] = byteSpace[traverse]; - - cached = - ((globals.mMaxTimeval - - globals.mMinTimeval) * percents[traverse]) / 100; - PR_snprintf(timevals[traverse], 32, ST_TIMEVAL_FORMAT, - ST_TIMEVAL_PRINTABLE(cached)); - PR_snprintf(bytes[traverse], 32, "%u", - ((maxMemory - - minMemory) * percents[traverse]) / 100); - } - - red = gdImageColorAllocate(graph, 255, 0, 0); - legendColors[0] = red; - - drawGraph(graph, -1, "Allocation Times", "Seconds", "Bytes", - 11, percents, (const char **) timevals, 11, - percents, (const char **) bytes, 1, legendColors, - legends); - - if (maxMemory != minMemory) { - int64_t in64 = 0; - int64_t ydata64 = 0; - int64_t spacey64 = 0; - int64_t mem64 = 0; - int32_t in32 = 0; - - /* - ** Go through our Y data and mark it up. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - x1 = traverse + STGD_MARGIN; - y1 = STGD_HEIGHT - STGD_MARGIN; - - /* - ** Need to do this math in 64 bits. - */ - ydata64 = (int64_t)YData[traverse]; - spacey64 = (int64_t)STGD_SPACE_Y; - mem64 = (int64_t)(maxMemory - minMemory); - - in64 = ydata64 * spacey64; - in64 /= mem64; - in32 = int32_t(in64); - - x2 = x1; - y2 = y1 - in32; - - gdImageLine(graph, x1, y1, x2, y2, red); - } - } - - - theSink.context = inRequest->mFD; - theSink.sink = pngSink; - gdImagePngToSink(graph, &theSink); - - gdImageDestroy(graph); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, createGraph); - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphTimeval); - } - - return retval; -} -#endif /* ST_WANT_GRAPHS */ - -#if ST_WANT_GRAPHS -/* -** graphLifespan -** -** Output a PNG graph of how long memory lived. -** -** Draw the graph within these boundaries. -** STGD_MARGIN,STGD_MARGIN,STGD_WIDTH-STGD_MARGIN,STGD_HEIGHT-STGD_MARGIN -** -** Returns !0 on failure. -*/ -int -graphLifespan(STRequest * inRequest, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun) { - uint32_t *YData = NULL; - uint32_t YDataArray[STGD_SPACE_X]; - uint32_t traverse = 0; - uint32_t timeval = 0; - uint32_t loop = 0; - PRBool underLock = PR_FALSE; - - /* - ** Decide if this is custom or we should use the global cache. - */ - if (aRun == inRequest->mContext->mSortedRun) { - YData = inRequest->mContext->mLifespanYData; - underLock = PR_TRUE; - } - else { - YData = YDataArray; - } - - /* - ** Protect the shared data so that only one client has access to it - ** at any given time. - */ - if (PR_FALSE != underLock) { - PR_Lock(inRequest->mContext->mImageLock); - } - - /* - ** Only do the computations if we aren't cached already. - */ - if (YData != inRequest->mContext->mLifespanYData - || PR_FALSE == inRequest->mContext->mLifespanCached) { - uint32_t prevTimeval = 0; - uint32_t lifespan = 0; - - memset(YData, 0, sizeof(uint32_t) * STGD_SPACE_X); - - /* - ** Initialize our Y data. - ** Pretty brutal loop here.... - */ - for (traverse = 0; 0 == retval && traverse < STGD_SPACE_X; - traverse++) { - /* - ** Compute what timeval this Y data lands in. - */ - prevTimeval = timeval; - timeval = - (traverse * (globals.mMaxTimeval - globals.mMinTimeval)) / - STGD_SPACE_X; - - /* - ** Loop over the run. - ** Should an allocation have lived between - ** prevTimeval and timeval.... - */ - for (loop = 0; loop < aRun->mAllocationCount; loop++) { - lifespan = - aRun->mAllocations[loop]->mMaxTimeval - - aRun->mAllocations[loop]->mMinTimeval; - - if (prevTimeval < lifespan && timeval >= lifespan) { - YData[traverse] += - byteSize(&inRequest->mOptions, - aRun->mAllocations[loop]); - } - } - } - - /* - ** Did we cache this? - */ - if (YData == inRequest->mContext->mLifespanYData) { - inRequest->mContext->mLifespanCached = PR_TRUE; - } - } - - /* - ** Done with the lock. - */ - if (PR_FALSE != underLock) { - PR_Unlock(inRequest->mContext->mImageLock); - } - - if (0 == retval) { - uint32_t minMemory = (uint32_t) - 1; - uint32_t maxMemory = 0; - int transparent = 0; - gdImagePtr graph = NULL; - - /* - ** Go through and find the minimum and maximum sizes. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - if (YData[traverse] < minMemory) { - minMemory = YData[traverse]; - } - if (YData[traverse] > maxMemory) { - maxMemory = YData[traverse]; - } - } - - /* - ** We can now draw the graph. - */ - graph = createGraph(&transparent); - if (NULL != graph) { - gdSink theSink; - int red = 0; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - uint32_t percents[11] = - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; - char *timevals[11]; - char *bytes[11]; - char timevalSpace[11][32]; - char byteSpace[11][32]; - int legendColors[1]; - const char *legends[1] = { "Live Memory" }; - uint32_t cached = 0; - - /* - ** Figure out what the labels will say. - */ - for (traverse = 0; traverse < 11; traverse++) { - timevals[traverse] = timevalSpace[traverse]; - bytes[traverse] = byteSpace[traverse]; - - cached = - ((globals.mMaxTimeval - - globals.mMinTimeval) * percents[traverse]) / 100; - PR_snprintf(timevals[traverse], 32, ST_TIMEVAL_FORMAT, - ST_TIMEVAL_PRINTABLE(cached)); - PR_snprintf(bytes[traverse], 32, "%u", - ((maxMemory - - minMemory) * percents[traverse]) / 100); - } - - red = gdImageColorAllocate(graph, 255, 0, 0); - legendColors[0] = red; - - drawGraph(graph, -1, "Allocation Lifespans", "Lifespan", - "Bytes", 11, percents, (const char **) timevals, 11, - percents, (const char **) bytes, 1, legendColors, - legends); - - if (maxMemory != minMemory) { - int64_t in64 = 0; - int64_t ydata64 = 0; - int64_t spacey64 = 0; - int64_t mem64 = 0; - int32_t in32 = 0; - - /* - ** Go through our Y data and mark it up. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - x1 = traverse + STGD_MARGIN; - y1 = STGD_HEIGHT - STGD_MARGIN; - - /* - ** Need to do this math in 64 bits. - */ - ydata64 = (int64_t)YData[traverse]; - spacey64 = (int64_t)STGD_SPACE_Y; - mem64 = (int64_t)(maxMemory - minMemory); - - in64 = ydata64 * spacey64; - in64 /= mem64; - in32 = int32_t(in64); - - x2 = x1; - y2 = y1 - in32; - - gdImageLine(graph, x1, y1, x2, y2, red); - } - } - - - theSink.context = inRequest->mFD; - theSink.sink = pngSink; - gdImagePngToSink(graph, &theSink); - - gdImageDestroy(graph); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, createGraph); - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphLifespan); - } - - return retval; -} -#endif /* ST_WANT_GRAPHS */ - -#if ST_WANT_GRAPHS -/* -** graphWeight -** -** Output a PNG graph of Allocations by Weight -** -** Draw the graph within these boundaries. -** STGD_MARGIN,STGD_MARGIN,STGD_WIDTH-STGD_MARGIN,STGD_HEIGHT-STGD_MARGIN -** -** Returns !0 on failure. -*/ -int -graphWeight(STRequest * inRequest, STRun * aRun) -{ - int retval = 0; - - if (NULL != aRun) { - uint64_t *YData64 = NULL; - uint64_t YDataArray64[STGD_SPACE_X]; - uint32_t traverse = 0; - uint32_t timeval = globals.mMinTimeval; - uint32_t loop = 0; - PRBool underLock = PR_FALSE; - - /* - ** Decide if this is custom or we should use the global cache. - */ - if (aRun == inRequest->mContext->mSortedRun) { - YData64 = inRequest->mContext->mWeightYData64; - underLock = PR_TRUE; - } - else { - YData64 = YDataArray64; - } - - /* - ** Protect the shared data so that only one client has access to it - ** at any given time. - */ - if (PR_FALSE != underLock) { - PR_Lock(inRequest->mContext->mImageLock); - } - - /* - ** Only do the computations if we aren't cached already. - */ - if (YData64 != inRequest->mContext->mWeightYData64 - || PR_FALSE == inRequest->mContext->mWeightCached) { - uint32_t prevTimeval = 0; - - memset(YData64, 0, sizeof(uint64_t) * STGD_SPACE_X); - - /* - ** Initialize our Y data. - ** Pretty brutal loop here.... - */ - for (traverse = 0; 0 == retval && traverse < STGD_SPACE_X; - traverse++) { - /* - ** Compute what timeval this Y data lands in. - */ - prevTimeval = timeval; - timeval = - ((traverse * - (globals.mMaxTimeval - - globals.mMinTimeval)) / STGD_SPACE_X) + - globals.mMinTimeval; - - /* - ** Loop over the run. - ** Should an allocation have been allocated between - ** prevTimeval and timeval.... - */ - for (loop = 0; loop < aRun->mAllocationCount; loop++) { - if (prevTimeval < aRun->mAllocations[loop]->mMinTimeval - && timeval >= aRun->mAllocations[loop]->mMinTimeval) { - uint64_t size64 = 0; - uint64_t lifespan64 = 0; - uint64_t weight64 = 0; - - size64 = byteSize(&inRequest->mOptions, - aRun->mAllocations[loop]); - lifespan64 = aRun->mAllocations[loop]->mMaxTimeval - - aRun->mAllocations[loop]->mMinTimeval; - weight64 = size64 * lifespan64; - - YData64[traverse] += weight64; - } - } - } - - /* - ** Did we cache this? - */ - if (YData64 == inRequest->mContext->mWeightYData64) { - inRequest->mContext->mWeightCached = PR_TRUE; - } - } - - /* - ** Done with the lock. - */ - if (PR_FALSE != underLock) { - PR_Unlock(inRequest->mContext->mImageLock); - } - - if (0 == retval) { - uint64_t minWeight64 = (0xFFFFFFFFLL << 32) + 0xFFFFFFFFLL; - uint64_t maxWeight64 = 0; - int transparent = 0; - gdImagePtr graph = NULL; - - /* - ** Go through and find the minimum and maximum weights. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - if (YData64[traverse] < minWeight64) { - minWeight64 = YData64[traverse]; - } - if (YData64[traverse] > maxWeight64) { - maxWeight64 = YData64[traverse]; - } - } - - /* - ** We can now draw the graph. - */ - graph = createGraph(&transparent); - if (NULL != graph) { - gdSink theSink; - int red = 0; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - uint32_t percents[11] = - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; - char *timevals[11]; - char *bytes[11]; - char timevalSpace[11][32]; - char byteSpace[11][32]; - int legendColors[1]; - const char *legends[1] = { "Memory Weight" }; - uint64_t percent64 = 0; - uint64_t result64 = 0; - - uint32_t cached = 0; - uint64_t hundred64 = 100; - - /* - ** Figure out what the labels will say. - */ - for (traverse = 0; traverse < 11; traverse++) { - timevals[traverse] = timevalSpace[traverse]; - bytes[traverse] = byteSpace[traverse]; - - cached = - ((globals.mMaxTimeval - - globals.mMinTimeval) * percents[traverse]) / 100; - PR_snprintf(timevals[traverse], 32, ST_TIMEVAL_FORMAT, - ST_TIMEVAL_PRINTABLE(cached)); - - result64 = (maxWeight64 - minWeight64) * percents[traverse]; - result64 /= hundred64; - PR_snprintf(bytes[traverse], 32, "%llu", result64); - } - - red = gdImageColorAllocate(graph, 255, 0, 0); - legendColors[0] = red; - - drawGraph(graph, -1, "Allocation Weights", "Seconds", - "Weight", 11, percents, (const char **) timevals, - 11, percents, (const char **) bytes, 1, - legendColors, legends); - - if (maxWeight64 != minWeight64) { - int64_t in64 = 0; - int64_t spacey64 = 0; - int64_t weight64 = 0; - int32_t in32 = 0; - - /* - ** Go through our Y data and mark it up. - */ - for (traverse = 0; traverse < STGD_SPACE_X; traverse++) { - x1 = traverse + STGD_MARGIN; - y1 = STGD_HEIGHT - STGD_MARGIN; - - /* - ** Need to do this math in 64 bits. - */ - spacey64 = (int64_t)STGD_SPACE_Y; - weight64 = maxWeight64 - minWeight64; - - in64 = YData64[traverse] * spacey64; - in64 /= weight64; - in32 = int32_t(in64); - - x2 = x1; - y2 = y1 - in32; - - gdImageLine(graph, x1, y1, x2, y2, red); - } - } - - - theSink.context = inRequest->mFD; - theSink.sink = pngSink; - gdImagePngToSink(graph, &theSink); - - gdImageDestroy(graph); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, createGraph); - } - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphWeight); - } - - return retval; -} -#endif /* ST_WANT_GRAPHS */ - -#define ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) \ - { \ - uint32_t convert = (uint32_t)outOptions->m##option_name; \ - \ - getDataPRUint32(inFormData, #option_name, 1, &convert, 1); \ - outOptions->m##option_name = (PRBool)convert; \ - } -#define ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - getDataString(inFormData, #option_name, 1, outOptions->m##option_name, sizeof(outOptions->m##option_name)); -#define ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - { \ - uint32_t loop = 0; \ - uint32_t found = 0; \ - char buffer[ST_OPTION_STRING_MAX]; \ - \ - for(loop = 0; loop < array_size; loop++) \ - { \ - buffer[0] = '\0'; \ - getDataString(inFormData, #option_name, (loop + 1), buffer, sizeof(buffer)); \ - \ - if('\0' != buffer[0]) \ - { \ - PR_snprintf(outOptions->m##option_name[found], sizeof(outOptions->m##option_name[found]), "%s", buffer); \ - found++; \ - } \ - } \ - \ - for(; found < array_size; found++) \ - { \ - outOptions->m##option_name[found][0] = '\0'; \ - } \ - } -#define ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) /* no implementation */ -#define ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - getDataPRUint32(inFormData, #option_name, 1, &outOptions->m##option_name, multiplier); -#define ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - { \ - uint64_t mul64 = multiplier; \ - \ - getDataPRUint64(inFormData, #option_name, 1, &outOptions->m##option_name##64, mul64); \ - } -/* -** fillOptions -** -** Given an appropriate hexcaped string, distill the option values -** and fill the given STOption struct. -** -** Note that the options passed in are not touched UNLESS there is -** a replacement found in the form data. -*/ -void -fillOptions(STOptions * outOptions, const FormData * inFormData) -{ - if (NULL != outOptions && NULL != inFormData) { - -#include "stoptions.h" - - /* - ** Special sanity check here for some options that need data validation. - */ - if (!outOptions->mCategoryName[0] - || !findCategoryNode(outOptions->mCategoryName, &globals)) { - PR_snprintf(outOptions->mCategoryName, - sizeof(outOptions->mCategoryName), "%s", - ST_ROOT_CATEGORY_NAME); - } - } -} - - -void -displayOptionString(STRequest * inRequest, - const char *option_name, - const char *option_genre, - const char *default_value, - const char *option_help, const char *value) -{ -#if 0 - PR_fprintf(inRequest->mFD, "\n", option_name); -#endif - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, "

%s

\n", option_name); - PR_fprintf(inRequest->mFD, - "\n", - option_name, value); - PR_fprintf(inRequest->mFD, - "

Default value is \"%s\".

\n

%s

\n", - default_value, option_help); - PR_fprintf(inRequest->mFD, "
\n"); -} - -static void -displayOptionStringArray(STRequest * inRequest, - const char *option_name, - const char *option_genre, - uint32_t array_size, - const char *option_help, const char values[5] - [ST_OPTION_STRING_MAX]) -{ - /* values should not be a fixed length! */ - PR_ASSERT(array_size == 5); -#if 0 - PR_fprintf(inRequest->mFD, "\n", option_name); -#endif - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, "

%s

\n", option_name); { - uint32_t loop = 0; - - for (loop = 0; loop < array_size; loop++) { - PR_fprintf(inRequest->mFD, - "
\n", - option_name, values[loop]); - } - } - PR_fprintf(inRequest->mFD, - "

Up to %u occurrences allowed.

\n

%s

\n", - array_size, option_help); - PR_fprintf(inRequest->mFD, "
\n"); -} - -static void -displayOptionInt(STRequest * inRequest, - const char *option_name, - const char *option_genre, - uint32_t default_value, - uint32_t multiplier, const char *option_help, uint32_t value) -{ -#if 0 - PR_fprintf(inRequest->mFD, "\n", option_name); -#endif - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, "

%s

\n", option_name); - PR_fprintf(inRequest->mFD, - "\n", option_name, - value / multiplier); - PR_fprintf(inRequest->mFD, - "

Default value is %u.

\n

%s

\n", - default_value, option_help); - PR_fprintf(inRequest->mFD, "
\n"); -} - -static void -displayOptionInt64(STRequest * inRequest, - const char *option_name, - const char *option_genre, - uint64_t default_value, - uint64_t multiplier, - const char *option_help, uint64_t value) -{ -#if 0 - PR_fprintf(inRequest->mFD, "\n", option_name); -#endif - PR_fprintf(inRequest->mFD, "
\n"); - PR_fprintf(inRequest->mFD, "

%s

\n", option_name); { - uint64_t def64 = default_value; - uint64_t mul64 = multiplier; - uint64_t div64; - - div64 = value / mul64; - PR_fprintf(inRequest->mFD, - "\n", - option_name, div64); - PR_fprintf(inRequest->mFD, - "

Default value is %llu.

\n

%s

\n", - def64, option_help); - } - PR_fprintf(inRequest->mFD, "
\n"); -} - -/* -** displaySettings -** -** Present the settings for change during execution. -*/ -void -displaySettings(STRequest * inRequest) -{ - int applyRes = 0; - - /* - ** We've got a form to create. - */ - PR_fprintf(inRequest->mFD, "
\n"); - /* - ** Respect newlines in help text. - */ -#if 0 - PR_fprintf(inRequest->mFD, "
\n");
-#endif
-#define ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) \
-    displayOptionBool(option_name, option_genre, option_help)
-#define ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) \
-    displayOptionString(inRequest, #option_name, #option_genre, default_value, option_help, inRequest->mOptions.m##option_name);
-#define ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \
-    displayOptionStringArray(inRequest, #option_name, #option_genre, array_size, option_help, inRequest->mOptions.m##option_name);
-#define ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help)  /* no implementation */
-#define ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \
-    displayOptionInt(inRequest, #option_name, #option_genre, default_value, multiplier, option_help, inRequest->mOptions.m##option_name);
-#define ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \
-    displayOptionInt64(inRequest, #option_name, #option_genre, default_value, multiplier, option_help, inRequest->mOptions.m##option_name##64);
-#include "stoptions.h"
-    /*
-     **  Give a submit/reset button, obligatory.
-     **  Done respecting newlines in help text.
-     */
-    PR_fprintf(inRequest->mFD,
-               " \n");
-#if 0
-    PR_fprintf(inRequest->mFD, "
\n"); -#endif - /* - ** Done with form. - */ - PR_fprintf(inRequest->mFD, "
\n"); -} - -int -handleLocalFile(STRequest * inRequest, const char *aFilename) -{ - static const char *const local_files[] = { - "spacetrace.css", - }; - static const size_t local_file_count = - sizeof(local_files) / sizeof(local_files[0]); - size_t i; - - for (i = 0; i < local_file_count; i++) { - if (0 == strcmp(local_files[i], aFilename)) - return 1; - } - return 0; -} - -/* -** displayFile -** -** reads a file from disk, and streams it to the request -*/ -int -displayFile(STRequest * inRequest, const char *aFilename) -{ - PRFileDesc *inFd; - const char *filepath = - PR_smprintf("res%c%s", PR_GetDirectorySeparator(), aFilename); - char buffer[2048]; - int32_t readRes; - - inFd = PR_Open(filepath, PR_RDONLY, PR_IRUSR); - if (!inFd) - return -1; - while ((readRes = PR_Read(inFd, buffer, sizeof(buffer))) > 0) { - PR_Write(inRequest->mFD, buffer, readRes); - } - if (readRes != 0) - return -1; - PR_Close(inFd); - return 0; -} - -/* -** displayIndex -** -** Present a list of the reports you can drill down into. -** Returns !0 on failure. -*/ -int -displayIndex(STRequest * inRequest) -{ - int retval = 0; - STOptions *options = &inRequest->mOptions; - - /* - ** Present reports in a list format. - */ - PR_fprintf(inRequest->mFD, "
    "); - PR_fprintf(inRequest->mFD, "\n
  • "); - htmlAnchor(inRequest, "root_callsites.html", "Root Callsites", - NULL, "mainmenu", options); - PR_fprintf(inRequest->mFD, "\n
  • "); - htmlAnchor(inRequest, "categories_summary.html", - "Categories Report", NULL, "mainmenu", options); - PR_fprintf(inRequest->mFD, "\n
  • "); - htmlAnchor(inRequest, "top_callsites.html", - "Top Callsites Report", NULL, "mainmenu", options); - PR_fprintf(inRequest->mFD, "\n
  • "); - htmlAnchor(inRequest, "top_allocations.html", - "Top Allocations Report", NULL, "mainmenu", options); - PR_fprintf(inRequest->mFD, "\n
  • "); - htmlAnchor(inRequest, "memory_leaks.html", - "Memory Leak Report", NULL, "mainmenu", options); -#if ST_WANT_GRAPHS - PR_fprintf(inRequest->mFD, "\n
  • Graphs"); - PR_fprintf(inRequest->mFD, "
      "); - PR_fprintf(inRequest->mFD, "\n
    • "); - htmlAnchor(inRequest, "footprint_graph.html", "Footprint", - NULL, "mainmenu graph", options); - PR_fprintf(inRequest->mFD, "\n
    • "); - htmlAnchor(inRequest, "lifespan_graph.html", - "Allocation Lifespans", NULL, "mainmenu graph", options); - PR_fprintf(inRequest->mFD, "\n
    • "); - htmlAnchor(inRequest, "times_graph.html", "Allocation Times", - NULL, "mainmenu graph", options); - PR_fprintf(inRequest->mFD, "\n
    • "); - htmlAnchor(inRequest, "weight_graph.html", - "Allocation Weights", NULL, "mainmenu graph", options); - PR_fprintf(inRequest->mFD, "\n
    \n"); -#endif /* ST_WANT_GRAPHS */ - PR_fprintf(inRequest->mFD, "\n
\n"); - return retval; -} - -/* -** initRequestOptions -** -** Given the request, set the options that are specific to the request. -** These can generally be determined in the following manner: -** Copy over global options. -** If getData present, attempt to use options therein. -*/ -void -initRequestOptions(STRequest * inRequest) -{ - if (NULL != inRequest) { - /* - ** Copy of global options. - */ - memcpy(&inRequest->mOptions, &globals.mCommandLineOptions, - sizeof(globals.mCommandLineOptions)); - /* - ** Decide what will override global options if anything. - */ - if (NULL != inRequest->mGetData) { - fillOptions(&inRequest->mOptions, inRequest->mGetData); - } - } -} - -STContext * -contextLookup(STOptions * inOptions) -/* -** Lookup a context that matches the options. -** The lookup may block, especially if the context needs to be created. -** Callers of this API must eventually call contextRelease with the -** return value; failure to do so will cause this applications -** to eventually not work as advertised. -** -** inOptions The options determine which context is relevant. -** returns The fully completed context on success. -** The context is read only in practice, so please do not -** write to it or anything it points to. -** NULL on failure. -*/ -{ - STContext *retval = NULL; - STContextCache *inCache = &globals.mContextCache; - - if (NULL != inOptions && NULL != inCache) { - uint32_t loop = 0; - STContext *categoryException = NULL; - PRBool newContext = PR_FALSE; - PRBool evictContext = PR_FALSE; - PRBool changeCategoryContext = PR_FALSE; - - /* - ** Own the context cache while we are in here. - */ - PR_Lock(inCache->mLock); - /* - ** Loop until successful. - ** Waiting on the condition variable makes sure we don't hog the - ** lock below. - */ - while (1) { - /* - ** Go over the cache items. - ** At this point we are looking for a cache hit, with multiple - ** readers. - */ - for (loop = 0; loop < inCache->mItemCount; loop++) { - /* - ** Must be in use. - */ - if (PR_FALSE != inCache->mItems[loop].mInUse) { - int delta[(STOptionGenre) MaxGenres]; - - /* - ** Compare the relevant options, figure out if different - ** in any genre that we care about. - */ - memset(&delta, 0, sizeof(delta)); -#define ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) \ - if(inOptions->m##option_name != inCache->mItems[loop].mOptions.m##option_name) \ - { \ - delta[(STOptionGenre)option_genre]++; \ - } -#define ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - if(0 != strcmp(inOptions->m##option_name, inCache->mItems[loop].mOptions.m##option_name)) \ - { \ - delta[(STOptionGenre)option_genre]++; \ - } -#define ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - { \ - uint32_t macro_loop = 0; \ - \ - for(macro_loop = 0; macro_loop < array_size; macro_loop++) \ - { \ - if(0 != strcmp(inOptions->m##option_name[macro_loop], inCache->mItems[loop].mOptions.m##option_name[macro_loop])) \ - { \ - break; \ - } \ - } \ - \ - if(macro_loop != array_size) \ - { \ - delta[(STOptionGenre)option_genre]++; \ - } \ - } -#define ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) /* no implementation */ -#define ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - if(inOptions->m##option_name != inCache->mItems[loop].mOptions.m##option_name) \ - { \ - delta[(STOptionGenre)option_genre]++; \ - } -#define ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - if(inOptions->m##option_name##64 != inCache->mItems[loop].mOptions.m##option_name##64) \ - { \ - delta[(STOptionGenre)option_genre]++; \ - } -#include "stoptions.h" - /* - ** If there is no genre out of alignment, we accept this as the context. - */ - if (0 == delta[CategoryGenre] && - 0 == delta[DataSortGenre] && - 0 == delta[DataSetGenre] && 0 == delta[DataSizeGenre] - ) { - retval = &inCache->mItems[loop].mContext; - break; - } - - /* - ** A special exception to the rule here. - ** If all that is different is the category genre, and there - ** is no one looking at the context (zero ref count), - ** then there is some magic we can perform. - */ - if (NULL == retval && - 0 == inCache->mItems[loop].mReferenceCount && - 0 != delta[CategoryGenre] && - 0 == delta[DataSortGenre] && - 0 == delta[DataSetGenre] && 0 == delta[DataSizeGenre] - ) { - categoryException = &inCache->mItems[loop].mContext; - } - } - } - - /* - ** Pick up our category exception if relevant. - */ - if (NULL == retval && NULL != categoryException) { - retval = categoryException; - categoryException = NULL; - changeCategoryContext = PR_TRUE; - } - - /* - ** If we don't have a cache hit, then we need to check for an empty - ** spot to take over. - */ - if (NULL == retval) { - for (loop = 0; loop < inCache->mItemCount; loop++) { - /* - ** Must NOT be in use, then it will be the context. - */ - if (PR_FALSE == inCache->mItems[loop].mInUse) { - retval = &inCache->mItems[loop].mContext; - newContext = PR_TRUE; - break; - } - } - } - - /* - ** If we still don't have a return value, then we need to see if - ** there are any old items with zero ref counts that we - ** can take over. - */ - if (NULL == retval) { - for (loop = 0; loop < inCache->mItemCount; loop++) { - /* - ** Must be in use. - */ - if (PR_FALSE != inCache->mItems[loop].mInUse) { - /* - ** Must have a ref count of zero. - */ - if (0 == inCache->mItems[loop].mReferenceCount) { - /* - ** Must be older than any other we know of. - */ - if (NULL != retval) { - if (inCache->mItems[loop].mLastAccessed < - inCache->mItems[retval->mIndex]. - mLastAccessed) { - retval = &inCache->mItems[loop].mContext; - } - } - else { - retval = &inCache->mItems[loop].mContext; - } - } - } - } - - if (NULL != retval) { - evictContext = PR_TRUE; - } - } - - /* - ** If we still don't have a return value, then we can not avoid - ** waiting around until someone gives us the chance. - ** The chance, in specific, comes when a cache item reference - ** count returns to zero, upon which we can try to take - ** it over again. - */ - if (NULL == retval) { - /* - ** This has the side effect of release the context lock. - ** This is a good thing so that other clients can continue - ** to connect and hopefully have cache hits. - ** If they do not have cache hits, then we will end up - ** with a bunch of waiters here.... - */ - PR_WaitCondVar(inCache->mCacheMiss, PR_INTERVAL_NO_TIMEOUT); - } - - /* - ** If we have a return value, improve the reference count here. - */ - if (NULL != retval) { - /* - ** Decide if there are any changes to be made. - ** Do as little as possible, then fall through the context - ** cache lock to finish up. - ** This way, lengthy init operations will not block - ** other clients, only matches to this context. - */ - if (PR_FALSE != newContext || - PR_FALSE != evictContext || - PR_FALSE != changeCategoryContext) { - /* - ** Overwrite the prefs for this context. - ** They are changing. - */ - memcpy(&inCache->mItems[retval->mIndex].mOptions, - inOptions, - sizeof(inCache->mItems[retval->mIndex].mOptions)); - /* - ** As we are going to be changing the context, we need to write lock it. - ** This makes sure no readers are allowed while we are making our changes. - */ - PR_RWLock_Wlock(retval->mRWLock); - } - - /* - ** NOTE, ref count gets incremented here, inside content - ** cache lock so it can not be flushed once lock - ** released. - */ - inCache->mItems[retval->mIndex].mInUse = PR_TRUE; - inCache->mItems[retval->mIndex].mReferenceCount++; - /* - ** That's all folks. - */ - break; - } - - } /* while(1), try again */ - - /* - ** Done with context cache. - */ - PR_Unlock(inCache->mLock); - /* - ** Now that the context cached is free to continue accepting other - ** requests, we have a little more work to do. - */ - if (NULL != retval) { - PRBool unlock = PR_FALSE; - - /* - ** If evicting, we need to free off the old stuff. - */ - if (PR_FALSE != evictContext) { - unlock = PR_TRUE; - /* - ** We do not free the sorted run. - ** The category code takes care of this. - */ - retval->mSortedRun = NULL; -#if ST_WANT_GRAPHS - /* - ** There is no need to - ** PR_Lock(retval->mImageLock) - ** We are already under write lock for the entire structure. - */ - retval->mFootprintCached = PR_FALSE; - retval->mTimevalCached = PR_FALSE; - retval->mLifespanCached = PR_FALSE; - retval->mWeightCached = PR_FALSE; -#endif - } - - /* - ** If new or recently evicted, we need to fully init. - */ - if (PR_FALSE != newContext || PR_FALSE != evictContext) { - unlock = PR_TRUE; - retval->mSortedRun = - createRunFromGlobal(&inCache->mItems[retval->mIndex]. - mOptions, - &inCache->mItems[retval->mIndex]. - mContext); - } - - /* - ** If changing category, we need to do some sneaky stuff. - */ - if (PR_FALSE != changeCategoryContext) { - STCategoryNode *node = NULL; - - unlock = PR_TRUE; - /* - ** Just a category change. We don't need to harvest. Just find the - ** right node and set the cache.mSortedRun. We need to recompute - ** cost though. But that is cheap. - */ - node = - findCategoryNode(inCache->mItems[retval->mIndex].mOptions. - mCategoryName, &globals); - if (node) { - /* Recalculate cost of run */ - recalculateRunCost(&inCache->mItems[retval->mIndex]. - mOptions, retval, - node->runs[retval->mIndex]); - retval->mSortedRun = node->runs[retval->mIndex]; - } - -#if ST_WANT_GRAPHS - /* - ** There is no need to - ** PR_Lock(retval->mImageLock) - ** We are already under write lock for the entire structure. - */ - retval->mFootprintCached = PR_FALSE; - retval->mTimevalCached = PR_FALSE; - retval->mLifespanCached = PR_FALSE; - retval->mWeightCached = PR_FALSE; -#endif - } - - /* - ** Release the write lock if we took one to make changes. - */ - if (PR_FALSE != unlock) { - PR_RWLock_Unlock(retval->mRWLock); - } - - /* - ** Last thing possible, take a read lock on our return value. - ** This will cause us to block if the context is not fully - ** initialized in another thread holding the write lock. - */ - PR_RWLock_Rlock(retval->mRWLock); - } - } - - return retval; -} - -void -contextRelease(STContext * inContext) -/* -** After a successful call to contextLookup, one should call this API when -** done with the context. -** This effectively removes the usage of the client on a cached item. -*/ -{ - STContextCache *inCache = &globals.mContextCache; - - if (NULL != inContext && NULL != inCache) { - /* - ** Own the context cache while in here. - */ - PR_Lock(inCache->mLock); - /* - ** Give up the read lock on the context. - */ - PR_RWLock_Unlock(inContext->mRWLock); - /* - ** Decrement the reference count on the context. - ** If it was the last reference, notify that a new item is - ** available for eviction. - ** A waiting thread will wake up and eat it. - ** Also set when it was last accessed so the oldest unused item - ** can be targeted for eviction. - */ - inCache->mItems[inContext->mIndex].mReferenceCount--; - if (0 == inCache->mItems[inContext->mIndex].mReferenceCount) { - PR_NotifyCondVar(inCache->mCacheMiss); - inCache->mItems[inContext->mIndex].mLastAccessed = - PR_IntervalNow(); - } - - /* - ** Done with context cache. - */ - PR_Unlock(inCache->mLock); - } -} - - -/* -** handleRequest -** -** Based on what file they are asking for, perform some processing. -** Output the results to aFD. -** -** Returns !0 on error. -*/ -int -handleRequest(tmreader * aTMR, PRFileDesc * aFD, - const char *aFileName, const FormData * aGetData) -{ - int retval = 0; - - if (NULL != aTMR && NULL != aFD && NULL != aFileName - && '\0' != *aFileName) { - STRequest request; - - /* - ** Init the request. - */ - memset(&request, 0, sizeof(request)); - request.mFD = aFD; - request.mGetFileName = aFileName; - request.mGetData = aGetData; - /* - ** Set local options for this request. - */ - initRequestOptions(&request); - /* - ** Get our cached context for this client. - ** Simply based on the options. - */ - request.mContext = contextLookup(&request.mOptions); - if (NULL != request.mContext) { - /* - ** Attempt to find the file of interest. - */ - if (handleLocalFile(&request, aFileName)) { - displayFile(&request, aFileName); - } - else if (0 == strcmp("index.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Index"); - displayRes = displayIndex(&request); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayIndex); - } - - htmlFooter(&request); - } - else if (0 == strcmp("settings.html", aFileName) || - 0 == strcmp("options.html", aFileName)) { - htmlHeader(&request, "SpaceTrace Options"); - displaySettings(&request); - htmlFooter(&request); - } - else if (0 == strcmp("top_allocations.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Top Allocations Report"); - displayRes = - displayTopAllocations(&request, - request.mContext->mSortedRun, - "top-allocations", - "SpaceTrace Top Allocations Report", - 1); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopAllocations); - } - - htmlFooter(&request); - } - else if (0 == strcmp("top_callsites.html", aFileName)) { - int displayRes = 0; - tmcallsite **array = NULL; - uint32_t arrayCount = 0; - - /* - ** Display header after we figure out if we are going to focus - ** on a category. - */ - htmlHeader(&request, "SpaceTrace Top Callsites Report"); - if (NULL != request.mContext->mSortedRun - && 0 < request.mContext->mSortedRun->mAllocationCount) { - arrayCount = - callsiteArrayFromRun(&array, 0, - request.mContext->mSortedRun); - if (0 != arrayCount && NULL != array) { - displayRes = - displayTopCallsites(&request, array, arrayCount, - 0, - "top-callsites", - "Top Callsites Report", - 0); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayTopCallsites); - } - - /* - ** Done with the array. - */ - free(array); - array = NULL; - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, handleRequest); - } - - htmlFooter(&request); - } - else if (0 == strcmp("memory_leaks.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Memory Leaks Report"); - displayRes = - displayMemoryLeaks(&request, - request.mContext->mSortedRun); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayMemoryLeaks); - } - - htmlFooter(&request); - } - else if (0 == strncmp("allocation_", aFileName, 11)) { - int scanRes = 0; - uint32_t allocationIndex = 0; - - /* - ** Oh, what a hack.... - ** The index to the allocation structure in the global run - ** is in the filename. Better than the pointer value.... - */ - scanRes = PR_sscanf(aFileName + 11, "%u", &allocationIndex); - if (1 == scanRes - && globals.mRun.mAllocationCount > allocationIndex - && NULL != globals.mRun.mAllocations[allocationIndex]) { - STAllocation *allocation = - globals.mRun.mAllocations[allocationIndex]; - char buffer[128]; - int displayRes = 0; - - PR_snprintf(buffer, sizeof(buffer), - "SpaceTrace Allocation %u Details Report", - allocationIndex); - htmlHeader(&request, buffer); - displayRes = - displayAllocationDetails(&request, allocation); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayAllocationDetails); - } - - htmlFooter(&request); - } - else { - htmlNotFound(&request); - } - } - else if (0 == strncmp("callsite_", aFileName, 9)) { - int scanRes = 0; - uint32_t callsiteSerial = 0; - tmcallsite *resolved = NULL; - - /* - ** Oh, what a hack.... - ** The serial(key) to the callsite structure in the hash table - ** is in the filename. Better than the pointer value.... - */ - scanRes = PR_sscanf(aFileName + 9, "%u", &callsiteSerial); - if (1 == scanRes && 0 != callsiteSerial - && NULL != (resolved = - tmreader_callsite(aTMR, callsiteSerial))) { - char buffer[128]; - int displayRes = 0; - - PR_snprintf(buffer, sizeof(buffer), - "SpaceTrace Callsite %u Details Report", - callsiteSerial); - htmlHeader(&request, buffer); - displayRes = displayCallsiteDetails(&request, resolved); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayAllocationDetails); - } - - htmlFooter(&request); - } - else { - htmlNotFound(&request); - } - } - else if (0 == strcmp("root_callsites.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Root Callsites"); - displayRes = - displayCallsites(&request, aTMR->calltree_root.kids, - ST_FOLLOW_SIBLINGS, 0, - "callsites-root", - "SpaceTrace Root Callsites", - __LINE__); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayCallsites); - } - - htmlFooter(&request); - } -#if ST_WANT_GRAPHS - else if (0 == strcmp("footprint_graph.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Memory Footprint Report"); - PR_fprintf(request.mFD, "
\n"); - PR_fprintf(request.mFD, "\n"); - PR_fprintf(request.mFD, "
\n"); - htmlFooter(&request); - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("times_graph.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Allocation Times Report"); - PR_fprintf(request.mFD, "
\n"); - PR_fprintf(request.mFD, "\n"); - PR_fprintf(request.mFD, "
\n"); - htmlFooter(&request); - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("lifespan_graph.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, - "SpaceTrace Allocation Lifespans Report"); - PR_fprintf(request.mFD, "
\n"); - PR_fprintf(request.mFD, "\n"); - PR_fprintf(request.mFD, "
\n"); - htmlFooter(&request); - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("weight_graph.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "SpaceTrace Allocation Weights Report"); - PR_fprintf(request.mFD, "
\n"); - PR_fprintf(request.mFD, "\n"); - PR_fprintf(request.mFD, "
\n"); - htmlFooter(&request); - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("footprint.png", aFileName)) { - int graphRes = 0; - - graphRes = - graphFootprint(&request, request.mContext->mSortedRun); - if (0 != graphRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphFootprint); - } - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("times.png", aFileName)) { - int graphRes = 0; - - graphRes = - graphTimeval(&request, request.mContext->mSortedRun); - if (0 != graphRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphTimeval); - } - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("lifespan.png", aFileName)) { - int graphRes = 0; - - graphRes = - graphLifespan(&request, request.mContext->mSortedRun); - if (0 != graphRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphLifespan); - } - } -#endif /* ST_WANT_GRAPHS */ -#if ST_WANT_GRAPHS - else if (0 == strcmp("weight.png", aFileName)) { - int graphRes = 0; - - graphRes = - graphWeight(&request, request.mContext->mSortedRun); - if (0 != graphRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, graphWeight); - } - } -#endif /* ST_WANT_GRAPHS */ - else if (0 == strcmp("categories_summary.html", aFileName)) { - int displayRes = 0; - - htmlHeader(&request, "Category Report"); - displayRes = - displayCategoryReport(&request, &globals.mCategoryRoot, - 1); - if (0 != displayRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, displayMemoryLeaks); - } - - htmlFooter(&request); - } - else { - htmlNotFound(&request); - } - - /* - ** Release the context we obtained earlier. - */ - contextRelease(request.mContext); - request.mContext = NULL; - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, contextObtain); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, handleRequest); - } - - /* - ** Compact a little if you can after each request. - */ - heapCompact(); - return retval; -} - -/* -** handleClient -** -** main() of the new client thread. -** Read the fd for the request. -** Output the results. -*/ -void -handleClient(void *inArg) -{ - PRFileDesc *aFD = NULL; - - aFD = (PRFileDesc *) inArg; - if (NULL != aFD) { - PRStatus closeRes = PR_SUCCESS; - char aBuffer[2048]; - int32_t readRes = 0; - - readRes = PR_Read(aFD, aBuffer, sizeof(aBuffer)); - if (0 <= readRes) { - const char *sanityCheck = "GET /"; - - if (0 == strncmp(sanityCheck, aBuffer, 5)) { - char *eourl = NULL; - char *start = &aBuffer[5]; - char *getData = NULL; - int realFun = 0; - const char *crlf = "\015\012"; - char *eoline = NULL; - FormData *fdGet = NULL; - - /* - ** Truncate the line if possible. - ** Only want first one. - */ - eoline = strstr(aBuffer, crlf); - if (NULL != eoline) { - *eoline = '\0'; - } - - /* - ** Find the whitespace. - ** That is either end of line or the " HTTP/1.x" suffix. - ** We do not care. - */ - for (eourl = start; 0 == isspace(*eourl) && '\0' != *eourl; - eourl++) { - /* - ** No body. - */ - } - - /* - ** Cap it off. - ** Convert empty '/' to index.html. - */ - *eourl = '\0'; - if ('\0' == *start) { - strcpy(start, "index.html"); - } - - /* - ** Have we got any GET form data? - */ - getData = strchr(start, '?'); - if (NULL != getData) { - /* - ** Whack it off. - */ - *getData = '\0'; - getData++; - } - - /* - ** Convert get data into a more useful format. - */ - fdGet = FormData_Create(getData); - /* - ** This is totally a hack, but oh well.... - ** - ** Send that the request was OK, regardless. - ** - ** If we have any get data, then it is a set of options - ** we attempt to apply. - ** - ** Other code will tell the user they were wrong or if - ** there was an error. - ** If the filename contains a ".png", then send the image - ** mime type, otherwise, say it is text/html. - */ - PR_fprintf(aFD, "HTTP/1.1 200 OK%s", crlf); - PR_fprintf(aFD, "Server: %s%s", - "$Id: spacetrace.c,v 1.54 2006/11/01 23:02:17 timeless%mozdev.org Exp $", - crlf); - PR_fprintf(aFD, "Content-type: "); - if (NULL != strstr(start, ".png")) { - PR_fprintf(aFD, "image/png"); - } - else if (NULL != strstr(start, ".jpg")) { - PR_fprintf(aFD, "image/jpeg"); - } - else if (NULL != strstr(start, ".txt")) { - PR_fprintf(aFD, "text/plain"); - } - else if (NULL != strstr(start, ".css")) { - PR_fprintf(aFD, "text/css"); - } - else { - PR_fprintf(aFD, "text/html"); - } - PR_fprintf(aFD, crlf); - /* - ** One more to separate headers from content. - */ - PR_fprintf(aFD, crlf); - /* - ** Ready for the real fun. - */ - realFun = handleRequest(globals.mTMR, aFD, start, fdGet); - if (0 != realFun) { - REPORT_ERROR(__LINE__, handleRequest); - } - - /* - ** Free off get data if around. - */ - FormData_Destroy(fdGet); - fdGet = NULL; - } - else { - REPORT_ERROR(__LINE__, handleClient); - } - } - else { - REPORT_ERROR(__LINE__, lineReader); - } - - /* - ** Done with the connection. - */ - closeRes = PR_Close(aFD); - if (PR_SUCCESS != closeRes) { - REPORT_ERROR(__LINE__, PR_Close); - } - } - else { - REPORT_ERROR(__LINE__, handleClient); - } -} - -/* -** serverMode -** -** List on a port as a httpd. -** Output results interactively on demand. -** -** Returns !0 on error. -*/ -int -serverMode(void) -{ - int retval = 0; - PRFileDesc *socket = NULL; - - /* - ** Create a socket. - */ - socket = PR_NewTCPSocket(); - if (NULL != socket) { - PRStatus closeRes = PR_SUCCESS; - PRNetAddr bindAddr; - PRStatus bindRes = PR_SUCCESS; - - /* - ** Bind it to an interface/port. - ** Any interface. - */ - bindAddr.inet.family = PR_AF_INET; - bindAddr.inet.port = - PR_htons((uint16_t) globals.mCommandLineOptions.mHttpdPort); - bindAddr.inet.ip = PR_htonl(PR_INADDR_ANY); - bindRes = PR_Bind(socket, &bindAddr); - if (PR_SUCCESS == bindRes) { - PRStatus listenRes = PR_SUCCESS; - const int backlog = 0x20; - - /* - ** Start listening for clients. - ** Give a decent backlog, some of our processing will take - ** a bit. - */ - listenRes = PR_Listen(socket, backlog); - if (PR_SUCCESS == listenRes) { - PRFileDesc *connection = NULL; - int failureSum = 0; - char message[80]; - - /* - ** Output a little message saying we are receiving. - */ - PR_snprintf(message, sizeof(message), - "server accepting connections at http://localhost:%u/", - globals.mCommandLineOptions.mHttpdPort); - REPORT_INFO(message); - PR_fprintf(PR_STDOUT, "Peak memory used: %s bytes\n", - FormatNumber(globals.mPeakMemoryUsed)); - PR_fprintf(PR_STDOUT, "Allocations : %s total\n", - FormatNumber(globals.mMallocCount + - globals.mCallocCount + - globals.mReallocCount), - FormatNumber(globals.mFreeCount)); - PR_fprintf(PR_STDOUT, "Breakdown : %s malloc\n", - FormatNumber(globals.mMallocCount)); - PR_fprintf(PR_STDOUT, " %s calloc\n", - FormatNumber(globals.mCallocCount)); - PR_fprintf(PR_STDOUT, " %s realloc\n", - FormatNumber(globals.mReallocCount)); - PR_fprintf(PR_STDOUT, " %s free\n", - FormatNumber(globals.mFreeCount)); - PR_fprintf(PR_STDOUT, "Leaks : %s\n", - FormatNumber((globals.mMallocCount + - globals.mCallocCount + - globals.mReallocCount) - - globals.mFreeCount)); - /* - ** Keep accepting until we know otherwise. - ** - ** We do a thread per connection. - ** Up to the thread to close the connection when done. - ** - ** This is known by me to be suboptimal, and I would rather - ** do a thread pool if it ever becomes a resource issue. - ** Any issues would simply point to a need to get - ** more machines or a beefier machine to handle the - ** requests, as well as a need to do thread pooling and - ** avoid thread creation overhead. - ** The threads are not tracked, except possibly by NSPR - ** itself and PR_Cleanup will wait on them all to exit as - ** user threads so our shared data is valid. - */ - while (0 == retval) { - connection = - PR_Accept(socket, NULL, PR_INTERVAL_NO_TIMEOUT); - if (NULL != connection) { - PRThread *clientThread = NULL; - - /* - ** Thread per connection. - */ - clientThread = PR_CreateThread(PR_USER_THREAD, /* PR_Cleanup sync */ - handleClient, (void *) connection, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, /* IO enabled */ - PR_UNJOINABLE_THREAD, - 0); - if (NULL == clientThread) { - PRStatus closeRes = PR_SUCCESS; - - failureSum += __LINE__; - REPORT_ERROR(__LINE__, PR_Accept); - /* - ** Close the connection as well, no service - */ - closeRes = PR_Close(connection); - if (PR_FAILURE == closeRes) { - REPORT_ERROR(__LINE__, PR_Close); - } - } - } - else { - failureSum += __LINE__; - REPORT_ERROR(__LINE__, PR_Accept); - } - } - - if (0 != failureSum) { - retval = __LINE__; - } - - /* - ** Output a little message saying it is all over. - */ - REPORT_INFO("server no longer accepting connections...."); - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_Listen); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_Bind); - } - - /* - ** Done with socket. - */ - closeRes = PR_Close(socket); - if (PR_SUCCESS != closeRes) { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_Close); - } - socket = NULL; - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_NewTCPSocket); - } - - return retval; -} - -/* -** batchMode -** -** Perform whatever batch requests we were asked to do. -*/ -int -batchMode(void) -{ - int retval = 0; - - if (0 != globals.mCommandLineOptions.mBatchRequestCount) { - uint32_t loop = 0; - int failureSum = 0; - int handleRes = 0; - char aFileName[1024]; - uint32_t sprintfRes = 0; - - /* - ** Go through and process the various files requested. - ** We do not stop on failure, as it is too costly to rerun the - ** batch job. - */ - for (loop = 0; - loop < globals.mCommandLineOptions.mBatchRequestCount; loop++) { - sprintfRes = - PR_snprintf(aFileName, sizeof(aFileName), "%s%c%s", - globals.mCommandLineOptions.mOutputDir, - PR_GetDirectorySeparator(), - globals.mCommandLineOptions.mBatchRequest[loop]); - if ((uint32_t) - 1 != sprintfRes) { - PRFileDesc *outFile = NULL; - - outFile = PR_Open(aFileName, ST_FLAGS, ST_PERMS); - if (NULL != outFile) { - PRStatus closeRes = PR_SUCCESS; - - handleRes = - handleRequest(globals.mTMR, outFile, - globals.mCommandLineOptions. - mBatchRequest[loop], NULL); - if (0 != handleRes) { - failureSum += __LINE__; - REPORT_ERROR(__LINE__, handleRequest); - } - - closeRes = PR_Close(outFile); - if (PR_SUCCESS != closeRes) { - failureSum += __LINE__; - REPORT_ERROR(__LINE__, PR_Close); - } - } - else { - failureSum += __LINE__; - REPORT_ERROR(__LINE__, PR_Open); - } - } - else { - failureSum += __LINE__; - REPORT_ERROR(__LINE__, PR_snprintf); - } - } - - if (0 != failureSum) { - retval = __LINE__; - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, outputReports); - } - - return retval; -} - -/* -** doRun -** -** Perform the actual processing this program requires. -** Returns !0 on failure. -*/ -int -doRun(void) -{ - int retval = 0; - - /* - ** Create the new trace-malloc reader. - */ - globals.mTMR = tmreader_new(globals.mProgramName, NULL); - if (NULL != globals.mTMR) { - int tmResult = 0; - int outputResult = 0; - -#if defined(DEBUG_dp) - PRIntervalTime start = PR_IntervalNow(); - - fprintf(stderr, "DEBUG: reading tracemalloc data...\n"); -#endif - tmResult = - tmreader_eventloop(globals.mTMR, - globals.mCommandLineOptions.mFileName, - tmEventHandler); - printf("\rReading... Done.\n"); -#if defined(DEBUG_dp) - fprintf(stderr, - "DEBUG: reading tracemalloc data ends: %dms [%d allocations]\n", - PR_IntervalToMilliseconds(PR_IntervalNow() - start), - globals.mRun.mAllocationCount); -#endif - if (0 == tmResult) { - REPORT_ERROR(__LINE__, tmreader_eventloop); - retval = __LINE__; - } - - if (0 == retval) { - /* - ** Decide if we're going into batch mode or server mode. - */ - if (0 != globals.mCommandLineOptions.mBatchRequestCount) { - /* - ** Output in one big step while everything still exists. - */ - outputResult = batchMode(); - if (0 != outputResult) { - REPORT_ERROR(__LINE__, batchMode); - retval = __LINE__; - } - } - else { - int serverRes = 0; - - /* - ** httpd time. - */ - serverRes = serverMode(); - if (0 != serverRes) { - REPORT_ERROR(__LINE__, serverMode); - retval = __LINE__; - } - } - - /* - ** Clear our categorization tree - */ - freeCategories(&globals); - } - } - else { - REPORT_ERROR(__LINE__, tmreader_new); - retval = __LINE__; - } - - return retval; -} - -int -initCaches(void) -/* -** Initialize the global caches. -** More involved since we have to allocated/create some objects. -** -** returns Zero if all is well. -** Non-zero on error. -*/ -{ - int retval = 0; - STContextCache *inCache = &globals.mContextCache; - - if (NULL != inCache && 0 != globals.mCommandLineOptions.mContexts) { - inCache->mLock = PR_NewLock(); - if (NULL != inCache->mLock) { - inCache->mCacheMiss = PR_NewCondVar(inCache->mLock); - if (NULL != inCache->mCacheMiss) { - inCache->mItems = - (STContextCacheItem *) calloc(globals.mCommandLineOptions. - mContexts, - sizeof(STContextCacheItem)); - if (NULL != inCache->mItems) { - uint32_t loop = 0; - char buffer[64]; - - inCache->mItemCount = - globals.mCommandLineOptions.mContexts; - /* - ** Init each item as needed. - */ - for (loop = 0; loop < inCache->mItemCount; loop++) { - inCache->mItems[loop].mContext.mIndex = loop; - PR_snprintf(buffer, sizeof(buffer), - "Context Item %d RW Lock", loop); - inCache->mItems[loop].mContext.mRWLock = - PR_NewRWLock(PR_RWLOCK_RANK_NONE, buffer); - if (NULL == inCache->mItems[loop].mContext.mRWLock) { - break; - } -#if ST_WANT_GRAPHS - inCache->mItems[loop].mContext.mImageLock = - PR_NewLock(); - if (NULL == inCache->mItems[loop].mContext.mImageLock) { - break; - } -#endif - } - - if (loop != inCache->mItemCount) { - retval = __LINE__; - REPORT_ERROR(__LINE__, initCaches); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, calloc); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_NewCondVar); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, PR_NewLock); - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, initCaches); - } - - return retval; -} - -int -destroyCaches(void) -/* -** Clean up any global caches we have laying around. -** -** returns Zero if all is well. -** Non-zero on error. -*/ -{ - int retval = 0; - STContextCache *inCache = &globals.mContextCache; - - if (NULL != inCache) { - uint32_t loop = 0; - - /* - ** Uninit item data one by one. - */ - for (loop = 0; loop < inCache->mItemCount; loop++) { - if (NULL != inCache->mItems[loop].mContext.mRWLock) { - PR_DestroyRWLock(inCache->mItems[loop].mContext.mRWLock); - inCache->mItems[loop].mContext.mRWLock = NULL; - } -#if ST_WANT_GRAPHS - if (NULL != inCache->mItems[loop].mContext.mImageLock) { - PR_DestroyLock(inCache->mItems[loop].mContext.mImageLock); - inCache->mItems[loop].mContext.mImageLock = NULL; - } -#endif - } - - inCache->mItemCount = 0; - if (NULL != inCache->mItems) { - free(inCache->mItems); - inCache->mItems = NULL; - } - - if (NULL != inCache->mCacheMiss) { - PR_DestroyCondVar(inCache->mCacheMiss); - inCache->mCacheMiss = NULL; - } - - if (NULL != inCache->mLock) { - PR_DestroyLock(inCache->mLock); - inCache->mLock = NULL; - } - } - else { - retval = __LINE__; - REPORT_ERROR(__LINE__, destroyCaches); - } - - return retval; -} - -/* -** main -** -** Process entry and exit. -*/ -int -main(int aArgCount, char **aArgArray) -{ - int retval = 0; - int optionsResult = 0; - PRStatus prResult = PR_SUCCESS; - int showedHelp = 0; - int looper = 0; - int cacheResult = 0; - - /* - ** NSPR init. - */ - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - /* - ** Initialize globals - */ - memset(&globals, 0, sizeof(globals)); - /* - ** Set the program name. - */ - globals.mProgramName = aArgArray[0]; - /* - ** Set the minimum timeval really high so other code - ** that checks the timeval will get it right. - */ - globals.mMinTimeval = ST_TIMEVAL_MAX; - /* - ** Handle initializing options. - */ - optionsResult = initOptions(aArgCount, aArgArray); - if (0 != optionsResult) { - REPORT_ERROR(optionsResult, initOptions); - retval = __LINE__; - } - - /* - ** Initialize our caches. - */ - cacheResult = initCaches(); - if (0 != cacheResult) { - retval = __LINE__; - REPORT_ERROR(__LINE__, initCaches); - } - - /* - ** Small alloc code init. - */ - globals.mCategoryRoot.runs = - (STRun **) calloc(globals.mCommandLineOptions.mContexts, - sizeof(STRun *)); - if (NULL == globals.mCategoryRoot.runs) { - retval = __LINE__; - REPORT_ERROR(__LINE__, calloc); - } - - /* - ** Show help on usage if need be. - */ - showedHelp = showHelp(); - /* - ** Only perform the run if everything is checking out. - */ - if (0 == showedHelp && 0 == retval) { - int runResult = 0; - - runResult = doRun(); - if (0 != runResult) { - REPORT_ERROR(runResult, doRun); - retval = __LINE__; - } - } - - if (0 != retval) { - REPORT_ERROR(retval, main); - } - - /* - ** Have NSPR join all client threads we started. - */ - prResult = PR_Cleanup(); - if (PR_SUCCESS != prResult) { - REPORT_ERROR(retval, PR_Cleanup); - retval = __LINE__; - } - /* - ** All threads are joined/done by this line. - */ - - /* - ** Options allocated a little. - */ -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) \ - if(NULL != globals.mCommandLineOptions.m##option_name) \ - { \ - free((void*)globals.mCommandLineOptions.m##option_name); \ - globals.mCommandLineOptions.m##option_name = NULL; \ - globals.mCommandLineOptions.m##option_name##Count = 0; \ - } -#include "stoptions.h" - - /* - ** globals has a small modification to clear up. - */ - if (NULL != globals.mCategoryRoot.runs) { - free(globals.mCategoryRoot.runs); - globals.mCategoryRoot.runs = NULL; - } - - /* - ** Blow away our caches. - */ - cacheResult = destroyCaches(); - if (0 != cacheResult) { - retval = __LINE__; - REPORT_ERROR(__LINE__, initCaches); - } - - /* - ** We are safe to kill our tmreader data. - */ - if (NULL != globals.mTMR) { - tmreader_destroy(globals.mTMR); - globals.mTMR = NULL; - } - - return retval; -} diff --git a/tools/trace-malloc/spacetrace.css b/tools/trace-malloc/spacetrace.css deleted file mode 100644 index 43065cc21f08..000000000000 --- a/tools/trace-malloc/spacetrace.css +++ /dev/null @@ -1,170 +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/. */ - -body { - margin: 0px; - padding: 0px; - font: Arial, sans-serif; -} - -/* header stuff */ -.spacetrace-header { - color: white; - background: green; -/* min-height: 2em; */ -} - -.spacetrace-title { - font-size: x-large; - font-weight: bold; - padding: 0.5em; -} - -.navigate { -/* background: lightgrey; */ - color: black; - position: absolute; - right: 0px; - margin: 0px; - padding: 2px; -} - -.header-item { - border: 1px outset; - color: ButtonText; - background: ButtonFace; - margin: 0px; - padding: 2px; -} - -.header-item > a { - font-weight: bold; - text-decoration: none; -} - - -.header-item { - font-weight: bold; -} - -.category-title { - font-weight: bold; -} - -/* footer stuff */ -.footer-separator { - border: 1px inset; - display: none; -} - -.footer { - text-align: right; - display: none; -} - -.footer-text { - font-style: italic; -} - -.option-box { - border: solid black; - background: grey; - padding-left: .5em; - padding-right: .5em; - margin: .5em; -} - -.option-name { - font-weight: bold; - margin: 1em; -} - -.option-box input[type=text] -{ - border: inset thin; - padding: 2px; -} - -.option-help { - white-space: pre; - right: 0px; - background: white; - padding: 0.5em; - border: thin inset; -} - -.callsite-header { - padding: 10px; -} -/* data tables */ -#callsite-details { - position: absolute; - right: 1px; - top: 40px; - width: 20%; -} - -#callsites { - width: 75%; - height: 40%; - overflow: scroll; -} - -#caller-stack { - height: 45%; - width: 75%; - overflow: scroll; - padding-top: 5px; -} - -#allocations { - position: absolute; - right: 1px; - bottom: 1px; - height: 40%; - width: 20%; - overflow: scroll; -} - -/* headers at the top of specific call site pages */ - -table.summary { - border: 1px solid black; -} - -/* lists of callsites/etc */ -table.data td { - border-top: 1px solid; - padding: 5px; -} - -table.data { - clear: right; - border-collapse: collapse; -} - -tr.row-header { - background: #009090; - width: 100%; -} - -table.data th { - padding: 5px; - margin: 0px; - text-align: right; -} - -th.callsite { - text-align: left !important; -} - -/* links to source */ -.source-extra { - display: none; -} - -a.source, a.callsite { - text-decoration: none; -} - diff --git a/tools/trace-malloc/spacetrace.h b/tools/trace-malloc/spacetrace.h deleted file mode 100644 index 998be1304678..000000000000 --- a/tools/trace-malloc/spacetrace.h +++ /dev/null @@ -1,694 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 spacetrace_h__ -#define spacetrace_h__ - -/* -** spacetrace.h -** -** SpaceTrace is meant to take the output of trace-malloc and present -** a picture of allocations over the run of the application. -*/ - -/* -** Required includes. -*/ -#include -#include "nspr.h" -#include "prlock.h" -#include "prrwlock.h" -#include "nsTraceMalloc.h" -#include "tmreader.h" -#include "formdata.h" - -/* -** Turn on to attempt adding support for graphs on your platform. -*/ -#if defined(HAVE_BOUTELL_GD) -#define ST_WANT_GRAPHS 1 -#endif /* HAVE_BOUTELL_GD */ -#if !defined(ST_WANT_GRAPHS) -#define ST_WANT_GRAPHS 0 -#endif - -/* -** REPORT_ERROR -** REPORT_INFO -** -** Just report errors and stuff in a consistent manner. -*/ -#define REPORT_ERROR(code, function) \ - PR_fprintf(PR_STDERR, "error(%d):\t%s\n", code, #function) -#define REPORT_ERROR_MSG(code, msg) \ - PR_fprintf(PR_STDERR, "error(%d):\t%s\n", code, msg) -#define REPORT_INFO(msg) \ - PR_fprintf(PR_STDOUT, "%s: %s\n", globals.mProgramName, (msg)) - -#if defined(DEBUG_blythe) && 1 -#define REPORT_blythe(code, msg) \ - PR_fprintf(PR_STDOUT, "gab(%d):\t%s\n", code, msg) -#else -#define REPORT_blythe(code, msg) -#endif /* DEBUG_blythe */ - -/* -** CALLSITE_RUN -** -** How to get a callsite run. -** Allows for further indirection if needed later. -*/ -#define CALLSITE_RUN(callsite) \ - ((STRun*)((callsite)->data)) - -/* -** ST_PERMS -** ST_FLAGS -** -** File permissions we desire. -** 0644 -*/ -#define ST_PERMS (PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IROTH) -#define ST_FLAGS (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) - -/* -** Sorting order -*/ -#define ST_WEIGHT 0 /* size * timeval */ -#define ST_SIZE 1 -#define ST_TIMEVAL 2 -#define ST_COUNT 3 -#define ST_HEAPCOST 4 - -/* -** Callsite loop direction flags. -*/ -#define ST_FOLLOW_SIBLINGS 0 -#define ST_FOLLOW_PARENTS 1 - -/* -** Graph data. -*/ -#define STGD_WIDTH 640 -#define STGD_HEIGHT 480 -#define STGD_MARGIN 75 -#define STGD_SPACE_X (STGD_WIDTH - (2 * STGD_MARGIN)) -#define STGD_SPACE_Y (STGD_HEIGHT - (2 * STGD_MARGIN)) - -/* -** Minimum lifetime default, in seconds. -*/ -#define ST_DEFAULT_LIFETIME_MIN 10 - -/* -** Allocations fall to this boundry size by default. -** Overhead is taken after alignment. -** -** The msvcrt malloc has an alignment of 16 with an overhead of 8. -** The win32 HeapAlloc has an alignment of 8 with an overhead of 8. -*/ -#define ST_DEFAULT_ALIGNMENT_SIZE 16 -#define ST_DEFAULT_OVERHEAD_SIZE 8 - -/* -** Numer of substring match specifications to allow. -*/ -#define ST_SUBSTRING_MATCH_MAX 5 - -/* -** Max Number of patterns per rule -*/ -#define ST_MAX_PATTERNS_PER_RULE 16 - -/* -** Rule pointers and child pointers are allocated in steps of ST_ALLOC_STEP -*/ -#define ST_ALLOC_STEP 16 - -/* -** Name of the root category. Appears in UI. -*/ -#define ST_ROOT_CATEGORY_NAME "All" - -/* -** Size of our option string buffers. -*/ -#define ST_OPTION_STRING_MAX 256 - -/* -** Set the desired resolution of the timevals. -** The resolution is just mimicking what is recorded in the trace-malloc -** output, and that is currently milliseconds. -*/ -#define ST_TIMEVAL_RESOLUTION 1000 -#define ST_TIMEVAL_FORMAT "%.3f" -#define ST_TIMEVAL_PRINTABLE(timeval) ((double)(timeval) / (double)ST_TIMEVAL_RESOLUTION) -#define ST_TIMEVAL_PRINTABLE64(timeval) ((double)((int64_t)(timeval)) / (double)ST_TIMEVAL_RESOLUTION) -#define ST_TIMEVAL_MAX ((uint32_t)-1 - ((uint32_t)-1 % ST_TIMEVAL_RESOLUTION)) - -#define ST_MICROVAL_RESOLUTION 1000000 -#define ST_MICROVAL_FORMAT "%.6f" -#define ST_MICROVAL_PRINTABLE(timeval) ((double)(timeval) / (double)ST_MICROVAL_RESOLUTION) -#define ST_MICROVAL_PRINTABLE64(timeval) ((double)((int64_t)(timeval)) / (double)ST_MICROVAL_RESOLUTION) -#define ST_MICROVAL_MAX ((uint32_t)-1 - ((uint32_t)-1 % ST_MICROVAL_RESOLUTION)) - -/* -** Forward Declaration -*/ -typedef struct __struct_STCategoryNode STCategoryNode; -typedef struct __struct_STCategoryRule STCategoryRule; - - -/* -** STAllocEvent -** -** An event that happens to an allocation (malloc, free, et. al.) -*/ -typedef struct __struct_STAllocEvent -{ - /* - ** The type of allocation event. - ** This maps directly to the trace malloc events (i.e. TM_EVENT_MALLOC) - */ - char mEventType; - - /* - ** Each event, foremost, has a chronologically increasing ID in - ** relation to other allocation events. This is a time stamp - ** of sorts. - */ - uint32_t mTimeval; - - /* - ** Every event has a heap ID (pointer). - ** In the event of a realloc, this is the new heap ID. - ** In the event of a free, this is the previous heap ID value. - */ - uint32_t mHeapID; - - /* - ** Every event, along with the heap ID, tells of the size. - ** In the event of a realloc, this is the new size. - ** In th event of a free, this is the previous size. - */ - uint32_t mHeapSize; - - /* - ** Every event has a callsite/stack backtrace. - ** In the event of a realloc, this is the new callsite. - ** In the event of a free, this is the previous call site. - */ - tmcallsite* mCallsite; -} STAllocEvent; - -/* -** STAllocation -** -** An allocation is a temporal entity in the heap. -** It possibly lives under different heap IDs (pointers) and different -** sizes during its given time. -** An allocation is defined by the events during its lifetime. -** An allocation's lifetime is defined by the range of event IDs it holds. -*/ -typedef struct __struct_STAllocation -{ - /* - ** The array of events. - */ - uint32_t mEventCount; - STAllocEvent* mEvents; - - /* - ** The lifetime/lifespan of the allocation. - */ - uint32_t mMinTimeval; - uint32_t mMaxTimeval; - - /* - ** Index of this allocation in the global run. - */ - uint32_t mRunIndex; - - /* - ** The runtime cost of heap events in this allocation. - ** The cost is defined as the number of time units recorded as being - ** spent in heap code (time of malloc, free, et al.). - ** We do not track individual event cost in order to save space. - */ - uint32_t mHeapRuntimeCost; -} STAllocation; - -/* -** STCallsiteStats -** -** Stats regarding a run, kept mainly for callsite runs. -*/ -typedef struct __struct_STCallsiteStats -{ - /* - ** Sum timeval of the allocations. - ** Callsite runs total all allocations below the callsite. - */ - uint64_t mTimeval64; - - /* - ** Sum weight of the allocations. - ** Callsite runs total all allocations below the callsite. - */ - uint64_t mWeight64; - - /* - ** Sum size of the allocations. - ** Callsite runs total all allocations below the callsite. - */ - uint32_t mSize; - - /* - ** A stamp, indicated the relevance of the run. - ** If the stamp does not match the origin value, the - ** data contained here-in is considered invalid. - */ - uint32_t mStamp; - - /* - ** A sum total of allocations (note, not sizes) below the callsite. - ** This is NOT the same as STRun::mAllocationCount which - ** tracks the STRun::mAllocations array size. - */ - uint32_t mCompositeCount; - - /* - ** A sum total runtime cost of heap operations below the calliste. - ** The cost is defined as the number of time units recorded as being - ** spent in heap code (time of malloc, free, et al.). - */ - uint32_t mHeapRuntimeCost; -} STCallsiteStats; - -/* -** STRun -** -** A run is a closed set of allocations. -** Given a run, we can deduce information about the contained allocations. -** We can also determine if an allocation lives beyond a run (leak). -** -** A run might be used to represent allocations for an entire application. -** A run might also be used to represent allocations from a single callstack. -*/ -typedef struct __struct_STRun -{ - /* - ** The array of allocations. - */ - uint32_t mAllocationCount; - STAllocation** mAllocations; - - /* - ** Callsites like to keep some information. - ** As callsites are possibly shared between all contexts, each - ** different context needs to keep different stats. - */ - STCallsiteStats *mStats; - -} STRun; - -/* -** Categorize allocations -** -** The objective is to have a tree of categories with each leaf node of the tree -** matching a set of callsites that belong to the category. Each category can -** signify a functional area like say css and hence the user can browse this -** tree looking for how much of each of these are live at an instant. -*/ - -/* -** STCategoryNode -*/ - -struct __struct_STCategoryNode -{ - /* - ** Category name - */ - const char *categoryName; - - /* - ** Pointer to parent node. NULL for Root. - */ - STCategoryNode *parent; - - /* - ** For non-leaf nodes, an array of children node pointers. - ** NULL if leaf node. - */ - STCategoryNode** children; - uint32_t nchildren; - - /* - ** The Run(s). Valid for both leaf and parent nodes. - ** One run per --Context to handle multiple data sets. - ** The relevant index for the particular request will be - ** mIndex stored by the mContext of the request. - */ - STRun **runs; -}; - - -struct __struct_STCategoryRule -{ - /* - ** The pattern for the rule. Patterns are an array of strings. - ** A callsite needs to pass substring match for all the strings. - */ - char* pats[ST_MAX_PATTERNS_PER_RULE]; - uint32_t patlen[ST_MAX_PATTERNS_PER_RULE]; - uint32_t npats; - - /* - ** Category name that this rule belongs to - */ - const char* categoryName; - - /* - ** The node this should be categorized into - */ - STCategoryNode* node; -}; - - -/* -** CategoryName to Node mapping table -*/ -typedef struct __struct_STCategoryMapEntry { - STCategoryNode* node; - const char * categoryName; -} STCategoryMapEntry; - -/* -** Option genres. -** -** This helps to determine what functionality each option effects. -** In specific, this will help use determine when and when not to -** totally recaclulate the sorted run and categories. -** Be very aware that adding things to a particular genre, or adding a genre, -** may completely screw up the caching algorithms of SpaceTrace. -** See contextLookup() or ask someone that knows if you are in doubt. -*/ -typedef enum __enum_STOptionGenre -{ - CategoryGenre = 0, - DataSortGenre, - DataSetGenre, - DataSizeGenre, - UIGenre, - ServerGenre, - BatchModeGenre, - - /* - ** Last one please. - */ - MaxGenres -} -STOptionGenre; - -/* -** STOptions -** -** Structure containing the varios options for the code. -** The definition of these options exists in a different file. -** We access that definition via macros to inline our structure definition. -*/ -#define ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) PRBool m##option_name; -#define ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) char m##option_name[ST_OPTION_STRING_MAX]; -#define ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) char m##option_name[array_size][ST_OPTION_STRING_MAX]; -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) const char** m##option_name; uint32_t m##option_name##Count; -#define ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) uint32_t m##option_name; -#define ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) uint64_t m##option_name##64; - -typedef struct __struct_STOptions -{ -#include "stoptions.h" -} -STOptions; - -typedef struct __struct_STContext -/* -** A per request, thread safe, manner of accessing the contained members. -** A reader/writer lock ensures that the data is properly initialized before -** readers of the data begin their work. -** -** mRWLock reader/writer lock. -** writer lock is held to ensure initialization, though -** others can be attempting to acquire read locks -** at that time. -** writer lock is also used in destruction to make sure -** there are no more readers of data contained herein. -** reader lock is to allow multiple clients to read the -** data at the same time; implies is they must not -** write anything. -** mIndex Consider this much like thread private data or thread -** local storage in a few places. -** The index is specifically reserved for this context's -** usage in other data structure array's provided -** for the particular thread/client/context. -** This should not be modified after initialization. -** mSortedRun A pre sorted run taken from the global run, with our -** options applied. -** mImageLock An overly simplistic locking mechanism to protect the -** shared image cache. -** The proper implementation would have a reader/writer -** lock per cached image data. -** However, this will prove to be simpler for the time -** being. -** mFootprintCached Whether or not YData contains something useful. -** mTimevalCached Whether or not YData contains something useful. -** mLifespanCached Whether or not YData contains something useful. -** mWeightCached Whether or not YData contains something useful. -** mFootprintYData Precomputed cached graph data. -** mTimevalYData Precomputed cached graph data. -** mLifespanYData Precomputed cached graph data. -** mWeightYData Precomputed cached graph data. -*/ -{ - PRRWLock* mRWLock; - uint32_t mIndex; - STRun* mSortedRun; -#if ST_WANT_GRAPHS - PRLock* mImageLock; - PRBool mFootprintCached; - PRBool mTimevalCached; - PRBool mLifespanCached; - PRBool mWeightCached; - uint32_t mFootprintYData[STGD_SPACE_X]; - uint32_t mTimevalYData[STGD_SPACE_X]; - uint32_t mLifespanYData[STGD_SPACE_X]; - uint64_t mWeightYData64[STGD_SPACE_X]; -#endif -} -STContext; - - -typedef struct __struct_STContextCacheItem -/* -** This basically pools the common items that the context cache will -** want to track on a per context basis. -** -** mOptions What options this item represents. -** mContext State/data this cache item is wrapping. -** mReferenceCount A count of clients currently using this item. -** Should this item be 0, then the cache might -** decide to evict this context. -** Should this item not be 0, once it reaches -** zero a condition variable in the context cache -** will be signaled to notify the availability. -** mLastAccessed A timestamp of when this item was last accessed/released. -** Ignore this unless the reference count is 0, -** This is used to evict the oldest unused item from -** the context cache. -** mInUse Mainly PR_FALSE only at the beginning of the process, -** but this indicates that the item has not yet been -** used at all, and thus shouldn't be evaluated for -** a cache hit. -*/ -{ - STOptions mOptions; - STContext mContext; - int32_t mReferenceCount; - PRIntervalTime mLastAccessed; - PRBool mInUse; -} -STContextCacheItem; - - -typedef struct __struct_STContextCache -/* -** A thread safe, possibly blocking, cache of context items. -** -** mLock Must hold the lock to read/access/write to this struct, as -** well as any items it holds. -** mCacheMiss All items are busy and there were no cache matches. -** This condition variable is used to wait until an item becomes -** "available" to be evicted from the cache. -** mItems Array of items. -** mItemCount Number of items in array. -** This is generally the same as the global option's command line -** mContexts.... -*/ -{ - PRLock* mLock; - PRCondVar* mCacheMiss; - STContextCacheItem* mItems; - uint32_t mItemCount; -} -STContextCache; - - -/* -** STRequest -** -** Things specific to a request. -*/ -typedef struct __struct_STRequest -{ - /* - ** Sink/where to output. - */ - PRFileDesc* mFD; - - /* - ** The filename requested. - */ - const char* mGetFileName; - - /* - ** The GET form data, if any. - */ - const FormData* mGetData; - - /* - ** Options specific to this request. - */ - STOptions mOptions; - - /* - ** The context/data/state of the request. - */ - STContext* mContext; -} STRequest; - - -/* -** STGlobals -** -** Various globals we keep around. -*/ -typedef struct __struct_STGlobals -{ - /* - ** The string which identifies this program. - */ - const char* mProgramName; - - /* - ** Options derived from the command line. - ** These are used as defaults, and should remain static during - ** the run of the application. - */ - STOptions mCommandLineOptions; - - /* - ** Context cache. - ** As clients come in, based on their options, a different context - ** will be used to service them. - */ - STContextCache mContextCache; - - /* - ** Various counters for different types of events. - */ - uint32_t mMallocCount; - uint32_t mCallocCount; - uint32_t mReallocCount; - uint32_t mFreeCount; - - /* - ** Total events, operation counter. - */ - uint32_t mOperationCount; - - /* - ** The "run" of the input. - */ - STRun mRun; - - /* - ** Operation minimum/maximum timevals. - ** So that we can determine the overall timeval of the run. - ** NOTE: These are NOT the options to control the data set. - */ - uint32_t mMinTimeval; - uint32_t mMaxTimeval; - - /* - ** Calculates peak allocation overall for all allocations. - */ - uint32_t mPeakMemoryUsed; - uint32_t mMemoryUsed; - - /* - ** A list of rules for categorization read in from the mCategoryFile - */ - STCategoryRule** mCategoryRules; - uint32_t mNRules; - - /* - ** CategoryName to Node mapping table - */ - STCategoryMapEntry** mCategoryMap; - uint32_t mNCategoryMap; - - /* - ** Categorized allocations. For now we support only one tree. - */ - STCategoryNode mCategoryRoot; - - /* - ** tmreader hash tables. - ** Moved into globals since we need to destroy these only after all - ** client threads are finishes (after PR_Cleanup). - */ - tmreader* mTMR; -} STGlobals; - - -/* -** Function prototypes -*/ -extern STRun* createRun(STContext* inContext, uint32_t aStamp); -extern void freeRun(STRun* aRun); -extern int initCategories(STGlobals* g); -extern int categorizeRun(STOptions* inOptions, STContext* inContext, const STRun* aRun, STGlobals* g); -extern STCategoryNode* findCategoryNode(const char *catName, STGlobals *g); -extern int freeCategories(STGlobals* g); -extern int displayCategoryReport(STRequest* inRequest, STCategoryNode *root, int depth); - -extern int recalculateAllocationCost(STOptions* inOptions, STContext* inContext, STRun* aRun, STAllocation* aAllocation, PRBool updateParent); -extern void htmlHeader(STRequest* inRequest, const char* aTitle); -extern void htmlFooter(STRequest* inRequest); -extern void htmlAnchor(STRequest* inRequest, - const char* aHref, - const char* aText, - const char* aTarget, - const char* aClass, - STOptions* inOptions); -extern char *FormatNumber(int32_t num); - -/* -** shared globals -*/ -extern STGlobals globals; - -#endif /* spacetrace_h__ */ diff --git a/tools/trace-malloc/stoptions.h b/tools/trace-malloc/stoptions.h deleted file mode 100644 index f750ecba79b6..000000000000 --- a/tools/trace-malloc/stoptions.h +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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/. */ - -/* -** stoptions.h -** -** Abstract the spacetrace options into a reusable format, such that -** many different pieces of the code can utilize the common list. -*/ - -/* -** There are three types of options. -** The destinction is quite important. -** -** CMD options are accessible from only the comamnd line. -** Such options should be considered global/static for the entire -** run of the application. -** Once set, no one can change these options during the run. -** -** WEB options are accessible from the web server options page. -** Such options can and will be changed on a per user basis during -** the run of the application. -** You should NEVER make an option a WEB only option, as this will -** break batch mode processing, and will likely not correctly -** define the options structure itself. -** These options will control the data caching used in the application -** to match a client to a cache of data. -** -** ALL options are both CMD and WEB options, with the properties of WEB -** options (the user will change these on a per client basis). -** Most likely this is the type of option you will desire to create. -*/ - -/* -** All types of options have some combination of the following elements: -** -** option_name The name of the option. -** option_genre Area the option effects; STOptionGenre. -** default_value The default value for the option. -** array_size Used to size a string array. -** multiplier Some numbers prefer conversion. -** option_help Help text to explain the option. -** -** NOTE! that the multiplier should be applied to the default value if you -** are going to assign the default_value into anything. -** -** Be very aware that adding things to a particular genre, or adding a genre, -** may completely screw up the caching algorithms of SpaceTrace. -** See contextLookup() or ask someone that knows if you are in doubt. -** -** The actual definition of the WEB and CMD macros however is left to the -** end user. -** We cover those that you do not define herein. -*/ -#if !defined(ST_CMD_OPTION_BOOL) -#define ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) -#endif -#if !defined(ST_WEB_OPTION_BOOL) -#define ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) -#endif -#if !defined(ST_CMD_OPTION_STRING) -#define ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) -#endif -#if !defined(ST_WEB_OPTION_STRING) -#define ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) -#endif -#if !defined(ST_CMD_OPTION_STRING_ARRAY) -#define ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) -#endif -#if !defined(ST_WEB_OPTION_STRING_ARRAY) -#define ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) -#endif -#if !defined(ST_CMD_OPTION_STRING_PTR_ARRAY) -#define ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) -#endif -#if !defined(ST_WEB_OPTION_STRING_PTR_ARRAY) -#define ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) -#endif -#if !defined(ST_CMD_OPTION_UINT32) -#define ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) -#endif -#if !defined(ST_WEB_OPTION_UINT32) -#define ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) -#endif -#if !defined(ST_CMD_OPTION_UINT64) -#define ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) -#endif -#if !defined(ST_WEB_OPTION_UINT64) -#define ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) -#endif - -/* -** ALL macros expand to both CMD and WEB macros. -** This basically means such options are accessible from both the command -** line and from the web options. -*/ -#define ST_ALL_OPTION_BOOL(option_name, option_genre, option_help) \ - ST_CMD_OPTION_BOOL(option_name, option_genre, option_help) \ - ST_WEB_OPTION_BOOL(option_name, option_genre, option_help) -#define ST_ALL_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - ST_CMD_OPTION_STRING(option_name, option_genre, default_value, option_help) \ - ST_WEB_OPTION_STRING(option_name, option_genre, default_value, option_help) -#define ST_ALL_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - ST_CMD_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) \ - ST_WEB_OPTION_STRING_ARRAY(option_name, option_genre, array_size, option_help) -#define ST_ALL_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) \ - ST_CMD_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) \ - ST_WEB_OPTION_STRING_PTR_ARRAY(option_name, option_genre, option_help) -#define ST_ALL_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - ST_CMD_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) \ - ST_WEB_OPTION_UINT32(option_name, option_genre, default_value, multiplier, option_help) -#define ST_ALL_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - ST_CMD_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) \ - ST_WEB_OPTION_UINT64(option_name, option_genre, default_value, multiplier, option_help) - - - -/**************************************************************************** -** BEGIN, THE OPTIONS -** -** Order is somewhat relevant in that it will control 3 different things: -** 1) The order the members will be in the options structure. -** 2) The order the options are presented on the command line. -** 3) The order the options are presented on the web options page. -*/ - -ST_ALL_OPTION_STRING(CategoryName, - CategoryGenre, - ST_ROOT_CATEGORY_NAME, - "Specify a category for reports to focus upon.\n" - "See http://lxr.mozilla.org/mozilla/source/tools/trace-malloc/rules.txt\n") - -ST_ALL_OPTION_UINT32(OrderBy, - DataSortGenre, - ST_SIZE, /* for dp :-D */ - 1, - "Determine the sort order.\n" - "0 by weight (size * lifespan).\n" - "1 by size.\n" - "2 by lifespan.\n" - "3 by allocation count.\n" - "4 by performance cost.\n") - -ST_ALL_OPTION_STRING_ARRAY(RestrictText, - DataSetGenre, - ST_SUBSTRING_MATCH_MAX, - "Exclude allocations which do not have this text in their backtrace.\n" - "Multiple restrictions are treated as a logical AND operation.\n") - -ST_ALL_OPTION_UINT32(SizeMin, - DataSetGenre, - 0, - 1, - "Exclude allocations that are below this byte size.\n") - -ST_ALL_OPTION_UINT32(SizeMax, - DataSetGenre, - 0xFFFFFFFF, - 1, - "Exclude allocations that are above this byte size.\n") - -ST_ALL_OPTION_UINT32(LifetimeMin, - DataSetGenre, - ST_DEFAULT_LIFETIME_MIN, - ST_TIMEVAL_RESOLUTION, - "Allocations must live this number of seconds or be ignored.\n") - -ST_ALL_OPTION_UINT32(LifetimeMax, - DataSetGenre, - ST_TIMEVAL_MAX / ST_TIMEVAL_RESOLUTION, - ST_TIMEVAL_RESOLUTION, - "Allocations living longer than this number of seconds will be ignored.\n") - -ST_ALL_OPTION_UINT32(TimevalMin, - DataSetGenre, - 0, - ST_TIMEVAL_RESOLUTION, - "Allocations existing solely before this second will be ignored.\n" - "Live allocations at this second and after can be considered.\n") - -ST_ALL_OPTION_UINT32(TimevalMax, - DataSetGenre, - ST_TIMEVAL_MAX / ST_TIMEVAL_RESOLUTION, - ST_TIMEVAL_RESOLUTION, - "Allocations existing solely after this second will be ignored.\n" - "Live allocations at this second and before can be considered.\n") - -ST_ALL_OPTION_UINT32(AllocationTimevalMin, - DataSetGenre, - 0, - ST_TIMEVAL_RESOLUTION, - "Live and dead allocations created before this second will be ignored.\n") - -ST_ALL_OPTION_UINT32(AllocationTimevalMax, - DataSetGenre, - ST_TIMEVAL_MAX / ST_TIMEVAL_RESOLUTION, - ST_TIMEVAL_RESOLUTION, - "Live and dead allocations created after this second will be ignored.\n") - -ST_ALL_OPTION_UINT32(AlignBy, - DataSizeGenre, - ST_DEFAULT_ALIGNMENT_SIZE, - 1, - "All allocation sizes are made to be a multiple of this number.\n" - "Closer to actual heap conditions; set to 1 for true sizes.\n") - -ST_ALL_OPTION_UINT32(Overhead, - DataSizeGenre, - ST_DEFAULT_OVERHEAD_SIZE, - 1, - "After alignment, all allocations are made to increase by this number.\n" - "Closer to actual heap conditions; set to 0 for true sizes.\n") - -ST_ALL_OPTION_UINT32(ListItemMax, - UIGenre, - 500, - 1, - "Specifies the maximum number of list items to present in each list.\n") - -ST_ALL_OPTION_UINT64(WeightMin, - DataSetGenre, - 0, - 1, - "Exclude allocations that are below this weight (lifespan * size).\n") - -ST_ALL_OPTION_UINT64(WeightMax, - DataSetGenre, - (0xFFFFFFFFLL << 32) + 0xFFFFFFFFLL, - 1, - "Exclude allocations that are above this weight (lifespan * size).\n") - -ST_CMD_OPTION_STRING(FileName, - DataSetGenre, - "-", - "Specifies trace-malloc input file.\n" - "\"-\" indicates stdin will be used as input.\n") - -ST_CMD_OPTION_STRING(CategoryFile, - CategoryGenre, - "rules.txt", - "Specifies the category rules file.\n" - "This file contains rules about how to categorize allocations.\n") - - -ST_CMD_OPTION_UINT32(HttpdPort, - ServerGenre, - 1969, - 1, - "Specifies the default port the web server will listen on.\n") - -ST_CMD_OPTION_STRING(OutputDir, - BatchModeGenre, - ".", - "Specifies a directory to output batch mode requests.\n" - "The directory must exist and must not use a trailing slash.\n") - -ST_CMD_OPTION_STRING_PTR_ARRAY(BatchRequest, - BatchModeGenre, - "This implicitly turns on batch mode.\n" - "Save each requested file into the output dir, then exit.\n") - -ST_CMD_OPTION_UINT32(Contexts, - ServerGenre, - 1, - 1, - "How many configurations to cache at the cost of a lot of memory.\n" - "Dedicated servers can cache more client configurations for performance.\n") - -ST_CMD_OPTION_BOOL(Help, - UIGenre, - "Show command line help.\n" - "See http://www.mozilla.org/projects/footprint/spaceTrace.html\n") - -/* -** END, THE OPTIONS -****************************************************************************/ - -/* -** Everything is undefined after the header is included. -** This sets it up for multiple inclusion if so desired. -*/ -#undef ST_ALL_OPTION_BOOL -#undef ST_CMD_OPTION_BOOL -#undef ST_WEB_OPTION_BOOL -#undef ST_ALL_OPTION_STRING -#undef ST_CMD_OPTION_STRING -#undef ST_WEB_OPTION_STRING -#undef ST_ALL_OPTION_STRING_ARRAY -#undef ST_CMD_OPTION_STRING_ARRAY -#undef ST_WEB_OPTION_STRING_ARRAY -#undef ST_ALL_OPTION_STRING_PTR_ARRAY -#undef ST_CMD_OPTION_STRING_PTR_ARRAY -#undef ST_WEB_OPTION_STRING_PTR_ARRAY -#undef ST_ALL_OPTION_UINT32 -#undef ST_CMD_OPTION_UINT32 -#undef ST_WEB_OPTION_UINT32 -#undef ST_ALL_OPTION_UINT64 -#undef ST_CMD_OPTION_UINT64 -#undef ST_WEB_OPTION_UINT64 diff --git a/tools/trace-malloc/tmfrags.c b/tools/trace-malloc/tmfrags.c deleted file mode 100644 index 8dcfd453f541..000000000000 --- a/tools/trace-malloc/tmfrags.c +++ /dev/null @@ -1,950 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "nspr.h" -#include "tmreader.h" - - -#define ERROR_REPORT(num, val, msg) fprintf(stderr, "error(%d):\t\"%s\"\t%s\n", (num), (val), (msg)); -#define CLEANUP(ptr) do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while(0) - - -#define ticks2msec(reader, ticks) ticks2xsec((reader), (ticks), 1000) -#define ticks2usec(reader, ticks) ticks2xsec((reader), (ticks), 1000000) -#define TICK_RESOLUTION 1000 -#define TICK_PRINTABLE(timeval) ((double)(timeval) / (double)ST_TIMEVAL_RESOLUTION) - - -typedef struct __struct_Options -/* -** Options to control how we perform. -** -** mProgramName Used in help text. -** mInputName Name of the file. -** mOutput Output file, append. -** Default is stdout. -** mOutputName Name of the file. -** mHelp Whether or not help should be shown. -** mOverhead How much overhead an allocation will have. -** mAlignment What boundry will the end of an allocation line up on. -** mPageSize Controls the page size. A page containing only fragments -** is not fragmented. A page containing any life memory -** costs mPageSize in bytes. -*/ -{ - const char* mProgramName; - char* mInputName; - FILE* mOutput; - char* mOutputName; - int mHelp; - unsigned mOverhead; - unsigned mAlignment; - unsigned mPageSize; -} -Options; - - -typedef struct __struct_Switch -/* -** Command line options. -*/ -{ - const char* mLongName; - const char* mShortName; - int mHasValue; - const char* mValue; - const char* mDescription; -} -Switch; - -#define DESC_NEWLINE "\n\t\t" - -static Switch gInputSwitch = {"--input", "-i", 1, NULL, "Specify input file." DESC_NEWLINE "stdin is default."}; -static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." DESC_NEWLINE "Appends if file exists." DESC_NEWLINE "stdout is default."}; -static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."}; -static Switch gAlignmentSwitch = {"--alignment", "-al", 1, NULL, "All allocation sizes are made to be a multiple of this number." DESC_NEWLINE "Closer to actual heap conditions; set to 1 for true sizes." DESC_NEWLINE "Default value is 16."}; -static Switch gOverheadSwitch = {"--overhead", "-ov", 1, NULL, "After alignment, all allocations are made to increase by this number." DESC_NEWLINE "Closer to actual heap conditions; set to 0 for true sizes." DESC_NEWLINE "Default value is 8."}; -static Switch gPageSizeSwitch = {"--page-size", "-ps", 1, NULL, "Sets the page size which aids the identification of fragmentation." DESC_NEWLINE "Closer to actual heap conditions; set to 4294967295 for true sizes." DESC_NEWLINE "Default value is 4096."}; - -static Switch* gSwitches[] = { - &gInputSwitch, - &gOutputSwitch, - &gAlignmentSwitch, - &gOverheadSwitch, - &gPageSizeSwitch, - &gHelpSwitch -}; - - -typedef struct __struct_AnyArray -/* -** Variable sized item array. -** -** mItems The void pointer items. -** mItemSize Size of each different item. -** mCount The number of items in the array. -** mCapacity How many more items we can hold before reallocing. -** mGrowBy How many items we allocate when we grow. -*/ -{ - void* mItems; - unsigned mItemSize; - unsigned mCount; - unsigned mCapacity; - unsigned mGrowBy; -} -AnyArray; - - -typedef int (*arrayMatchFunc)(void* inContext, AnyArray* inArray, void* inItem, unsigned inItemIndex) -/* -** Callback function for the arrayIndexFn function. -** Used to determine an item match by customizable criteria. -** -** inContext The criteria and state of the search. -** User specified/created. -** inArray The array the item is in. -** inItem The item to evaluate for match. -** inItemIndex The index of this particular item in the array. -** -** return int 0 to specify a match. -** !0 to continue the search performed by arrayIndexFn. -*/ -; - - -typedef enum __enum_HeapEventType -/* -** Simple heap events are really one of two things. -*/ -{ - FREE, - ALLOC -} -HeapEventType; - - -typedef enum __enum_HeapObjectType -/* -** The various types of heap objects we track. -*/ -{ - ALLOCATION, - FRAGMENT -} -HeapObjectType; - - -typedef struct __struct_HeapObject HeapObject; -typedef struct __struct_HeapHistory -/* -** A marker as to what has happened. -** -** mTimestamp When history occurred. -** mTMRSerial The historical state as known to the tmreader. -** mObjectIndex Index to the object that was before or after this event. -** The index as in the index according to all heap objects -** kept in the TMState structure. -** We use an index instead of a pointer as the array of -** objects can change location in the heap. -*/ -{ - unsigned mTimestamp; - unsigned mTMRSerial; - unsigned mObjectIndex; -} -HeapHistory; - - -struct __struct_HeapObject -/* -** An object in the heap. -** -** A special case should be noted here. If either the birth or death -** history leads to an object of the same type, then this object -** is the same as that object, but was modified somehow. -** Also note that multiple objects may have the same birth object, -** as well as the same death object. -** -** mUniqueID Each object is unique. -** mType Either allocation or fragment. -** mHeapOffset Where in the heap the object is. -** mSize How much of the heap the object takes. -** mBirth History about the birth event. -** mDeath History about the death event. -*/ -{ - unsigned mUniqueID; - - HeapObjectType mType; - unsigned mHeapOffset; - unsigned mSize; - - HeapHistory mBirth; - HeapHistory mDeath; -}; - - -typedef struct __struct_TMState -/* -** State of our current operation. -** Stats we are trying to calculate. -** -** mOptions Obilgatory options pointer. -** mTMR The tmreader, used in tmreader API calls. -** mLoopExitTMR Set to non zero in order to quickly exit from tmreader -** input loop. This will also result in an error. -** uMinTicks Start of run, milliseconds. -** uMaxTicks End of run, milliseconds. -*/ -{ - Options* mOptions; - tmreader* mTMR; - - int mLoopExitTMR; - - unsigned uMinTicks; - unsigned uMaxTicks; -} -TMState; - - -int initOptions(Options* outOptions, int inArgc, char** inArgv) -/* -** returns int 0 if successful. -*/ -{ - int retval = 0; - int loop = 0; - int switchLoop = 0; - int match = 0; - const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]); - Switch* current = NULL; - - /* - ** Set any defaults. - */ - memset(outOptions, 0, sizeof(Options)); - outOptions->mProgramName = inArgv[0]; - outOptions->mInputName = strdup("-"); - outOptions->mOutput = stdout; - outOptions->mOutputName = strdup("stdout"); - outOptions->mAlignment = 16; - outOptions->mOverhead = 8; - - if(NULL == outOptions->mOutputName || NULL == outOptions->mInputName) - { - retval = __LINE__; - ERROR_REPORT(retval, "stdin/stdout", "Unable to strdup."); - } - - /* - ** Go through and attempt to do the right thing. - */ - for(loop = 1; loop < inArgc && 0 == retval; loop++) - { - match = 0; - current = NULL; - - for(switchLoop = 0; switchLoop < switchCount && 0 == retval; switchLoop++) - { - if(0 == strcmp(gSwitches[switchLoop]->mLongName, inArgv[loop])) - { - match = __LINE__; - } - else if(0 == strcmp(gSwitches[switchLoop]->mShortName, inArgv[loop])) - { - match = __LINE__; - } - - if(match) - { - if(gSwitches[switchLoop]->mHasValue) - { - /* - ** Attempt to absorb next option to fullfill value. - */ - if(loop + 1 < inArgc) - { - loop++; - - current = gSwitches[switchLoop]; - current->mValue = inArgv[loop]; - } - } - else - { - current = gSwitches[switchLoop]; - } - - break; - } - } - - if(0 == match) - { - outOptions->mHelp = __LINE__; - retval = __LINE__; - ERROR_REPORT(retval, inArgv[loop], "Unknown command line switch."); - } - else if(NULL == current) - { - outOptions->mHelp = __LINE__; - retval = __LINE__; - ERROR_REPORT(retval, inArgv[loop], "Command line switch requires a value."); - } - else - { - /* - ** Do something based on address/swtich. - */ - if(current == &gInputSwitch) - { - CLEANUP(outOptions->mInputName); - outOptions->mInputName = strdup(current->mValue); - if(NULL == outOptions->mInputName) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to strdup."); - } - } - else if(current == &gOutputSwitch) - { - CLEANUP(outOptions->mOutputName); - if(NULL != outOptions->mOutput && stdout != outOptions->mOutput) - { - fclose(outOptions->mOutput); - outOptions->mOutput = NULL; - } - - outOptions->mOutput = fopen(current->mValue, "a"); - if(NULL == outOptions->mOutput) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to open output file."); - } - else - { - outOptions->mOutputName = strdup(current->mValue); - if(NULL == outOptions->mOutputName) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to strdup."); - } - } - } - else if(current == &gHelpSwitch) - { - outOptions->mHelp = __LINE__; - } - else if(current == &gAlignmentSwitch) - { - unsigned arg = 0; - char* endScan = NULL; - - errno = 0; - arg = strtoul(current->mValue, &endScan, 0); - if(0 == errno && endScan != current->mValue) - { - outOptions->mAlignment = arg; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to convert to a number."); - } - } - else if(current == &gOverheadSwitch) - { - unsigned arg = 0; - char* endScan = NULL; - - errno = 0; - arg = strtoul(current->mValue, &endScan, 0); - if(0 == errno && endScan != current->mValue) - { - outOptions->mOverhead = arg; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to convert to a number."); - } - } - else if(current == &gPageSizeSwitch) - { - unsigned arg = 0; - char* endScan = NULL; - - errno = 0; - arg = strtoul(current->mValue, &endScan, 0); - if(0 == errno && endScan != current->mValue) - { - outOptions->mPageSize = arg; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to convert to a number."); - } - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mLongName, "No handler for command line switch."); - } - } - } - - return retval; -} - - -uint32_t ticks2xsec(tmreader* aReader, uint32_t aTicks, uint32_t aResolution) -/* -** Convert platform specific ticks to second units -*/ -{ - return (uint32)((aResolution * aTicks) / aReader->ticksPerSec); -} - - -void cleanOptions(Options* inOptions) -/* -** Clean up any open handles. -*/ -{ - unsigned loop = 0; - - CLEANUP(inOptions->mInputName); - CLEANUP(inOptions->mOutputName); - if(NULL != inOptions->mOutput && stdout != inOptions->mOutput) - { - fclose(inOptions->mOutput); - } - - memset(inOptions, 0, sizeof(Options)); -} - - -void showHelp(Options* inOptions) -/* -** Show some simple help text on usage. -*/ -{ - int loop = 0; - const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]); - const char* valueText = NULL; - - printf("usage:\t%s [arguments]\n", inOptions->mProgramName); - printf("\n"); - printf("arguments:\n"); - - for(loop = 0; loop < switchCount; loop++) - { - if(gSwitches[loop]->mHasValue) - { - valueText = " "; - } - else - { - valueText = ""; - } - - printf("\t%s%s\n", gSwitches[loop]->mLongName, valueText); - printf("\t %s%s", gSwitches[loop]->mShortName, valueText); - printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription); - } - - printf("This tool reports heap fragmentation stats from a trace-malloc log.\n"); -} - - -AnyArray* arrayCreate(unsigned inItemSize, unsigned inGrowBy) -/* -** Create an array container object. -*/ -{ - AnyArray* retval = NULL; - - if(0 != inGrowBy && 0 != inItemSize) - { - retval = (AnyArray*)calloc(1, sizeof(AnyArray)); - retval->mItemSize = inItemSize; - retval->mGrowBy = inGrowBy; - } - - return retval; -} - - -void arrayDestroy(AnyArray* inArray) -/* -** Release the memory the array contains. -** This will release the items as well. -*/ -{ - if(NULL != inArray) - { - if(NULL != inArray->mItems) - { - free(inArray->mItems); - } - free(inArray); - } -} - - -unsigned arrayAlloc(AnyArray* inArray, unsigned inItems) -/* -** Resize the item array capcity to a specific number of items. -** This could possibly truncate the array, so handle that as well. -** -** returns unsigned <= inArray->mCapacity on success. -*/ -{ - unsigned retval = (unsigned)-1; - - if(NULL != inArray) - { - void* moved = NULL; - - moved = realloc(inArray->mItems, inItems * inArray->mItemSize); - if(NULL != moved) - { - inArray->mItems = moved; - inArray->mCapacity = inItems; - if(inArray->mCount > inItems) - { - inArray->mCount = inItems; - } - - retval = inItems; - } - } - - return retval; -} - - -void* arrayItem(AnyArray* inArray, unsigned inIndex) -/* -** Return the array item at said index. -** Zero based index. -** -** returns void* NULL on failure. -*/ -{ - void* retval = NULL; - - if(NULL != inArray && inIndex < inArray->mCount) - { - retval = (void*)((char*)inArray->mItems + (inArray->mItemSize * inIndex)); - } - - return retval; -} - - -unsigned arrayIndex(AnyArray* inArray, void* inItem, unsigned inStartIndex) -/* -** Go through the array from the index specified looking for an item -** match based on byte for byte comparison. -** We allow specifying the start index in order to handle arrays with -** duplicate items. -** -** returns unsigned >= inArray->mCount on failure. -*/ -{ - unsigned retval = (unsigned)-1; - - if(NULL != inArray && NULL != inItem && inStartIndex < inArray->mCount) - { - void* curItem = NULL; - - for(retval = inStartIndex; retval < inArray->mCount; retval++) - { - curItem = arrayItem(inArray, retval); - if(0 == memcmp(inItem, curItem, inArray->mItemSize)) - { - break; - } - } - } - - - return retval; -} - - -unsigned arrayIndexFn(AnyArray* inArray, arrayMatchFunc inFunc, void* inFuncContext, unsigned inStartIndex) -/* -** Go through the array from the index specified looking for an item -** match based upon the return value of inFunc (0, Zero, is a match). -** We allow specifying the start index in order to facilitate looping over -** the array which could have multiple matches. -** -** returns unsigned >= inArray->mCount on failure. -*/ -{ - unsigned retval = (unsigned)-1; - - if(NULL != inArray && NULL != inFunc && inStartIndex < inArray->mCount) - { - void* curItem = NULL; - - for(retval = inStartIndex; retval < inArray->mCount; retval++) - { - curItem = arrayItem(inArray, retval); - if(0 == inFunc(inFuncContext, inArray, curItem, retval)) - { - break; - } - } - } - - return retval; -} - - -unsigned arrayAddItem(AnyArray* inArray, void* inItem) -/* -** Add a new item to the array. -** This is done by copying the item. -** -** returns unsigned < inArray->mCount on success. -*/ -{ - unsigned retval = (unsigned)-1; - - if(NULL != inArray && NULL != inItem) - { - int noCopy = 0; - - /* - ** See if the array should grow. - */ - if(inArray->mCount == inArray->mCapacity) - { - unsigned allocRes = 0; - - allocRes = arrayAlloc(inArray, inArray->mCapacity + inArray->mGrowBy); - if(allocRes > inArray->mCapacity) - { - noCopy = __LINE__; - } - } - - if(0 == noCopy) - { - retval = inArray->mCount; - - inArray->mCount++; - memcpy(arrayItem(inArray, retval), inItem, inArray->mItemSize); - } - } - - return retval; -} - - -HeapObject* initHeapObject(HeapObject* inObject) -/* -** Function to init the heap object just right. -** Sets the unique ID to something unique. -*/ -{ - HeapObject* retval = inObject; - - if(NULL != inObject) - { - static unsigned uniqueGenerator = 0; - - memset(inObject, -1, sizeof(HeapObject)); - - inObject->mUniqueID = uniqueGenerator; - uniqueGenerator++; - } - - return retval; -} - - -int simpleHeapEvent(TMState* inStats, HeapEventType inType, unsigned mTimestamp, unsigned inSerial, unsigned inHeapID, unsigned inSize) -/* -** A new heap event will cause the creation of a new heap object. -** The new heap object will displace, or replace, a heap object of a different type. -*/ -{ - int retval = 0; - HeapObject newObject; - - /* - ** Set the most basic object details. - */ - initHeapObject(&newObject); - newObject.mHeapOffset = inHeapID; - newObject.mSize = inSize; - if(FREE == inType) - { - newObject.mType = FRAGMENT; - } - else if(ALLOC == inType) - { - newObject.mType = ALLOCATION; - } - - /* - ** Add it to the heap object array. - */ - - /* - ** TODO GAB - ** - ** First thing to do is to add the new object to the heap in order to - ** obtain a valid index. - ** - ** Next, find all matches to this range of heap memory that this event - ** refers to, that are alive during this timestamp (no death yet). - ** Fill in the death event of those objects. - ** If the objects contain some portions outside of the range, then - ** new objects for those ranges need to be created that carry on - ** the same object type, have the index of the old object for birth, - ** and the serial of the old object, new timestamp of course. - ** The old object's death points to the new object, which tells why the - ** fragmentation took place. - ** The new object birth points to the old object only if a fragment. - ** An allocation only has a birth object when it is a realloc (complex) - ** heap event. - ** - ** I believe this give us enough information to look up particular - ** details of the heap at any given time. - */ - - return retval; -} - - -int complexHeapEvent(TMState* inStats, unsigned mTimestamp, unsigned inOldSerial, unsigned inOldHeapID, unsigned inOSize, unsigned inNewSerial, unsigned inNewHeapID, unsigned inNewSize) -/* -** Generally, this event intends to chain one old heap object to a newer heap object. -** Otherwise, the functionality should recognizable ala simpleHeapEvent. -*/ -{ - int retval = 0; - - /* - ** TODO GAB - */ - - return retval; -} - - -unsigned actualByteSize(Options* inOptions, unsigned retval) -/* -** Apply alignment and overhead to size to figure out actual byte size. -** This by default mimics spacetrace with default options (msvc crt heap). -*/ -{ - if(0 != retval) - { - unsigned eval = 0; - unsigned over = 0; - - eval = retval - 1; - if(0 != inOptions->mAlignment) - { - over = eval % inOptions->mAlignment; - } - retval = eval + inOptions->mOverhead + inOptions->mAlignment - over; - } - - return retval; -} - - -void tmEventHandler(tmreader* inReader, tmevent* inEvent) -/* -** Callback from the tmreader_eventloop. -** Build up our fragmentation information herein. -*/ -{ - char type = inEvent->type; - TMState* stats = (TMState*)inReader->data; - - /* - ** Only intersted in handling events of a particular type. - */ - switch(type) - { - default: - return; - - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_REALLOC: - case TM_EVENT_FREE: - break; - } - - /* - ** Should we even try to look? - ** Set mLoopExitTMR to non-zero to abort the read loop faster. - */ - if(0 == stats->mLoopExitTMR) - { - Options* options = (Options*)stats->mOptions; - unsigned timestamp = ticks2msec(stats->mTMR, inEvent->u.alloc.interval); - unsigned actualSize = actualByteSize(options, inEvent->u.alloc.size); - unsigned heapID = inEvent->u.alloc.ptr; - unsigned serial = inEvent->serial; - - /* - ** Check the timestamp range of our overall state. - */ - if(stats->uMinTicks > timestamp) - { - stats->uMinTicks = timestamp; - } - if(stats->uMaxTicks < timestamp) - { - stats->uMaxTicks = timestamp; - } - - /* - ** Realloc in general deserves some special attention if dealing - ** with an old allocation (not new memory). - */ - if(TM_EVENT_REALLOC == type && 0 != inEvent->u.alloc.oldserial) - { - unsigned oldActualSize = actualByteSize(options, inEvent->u.alloc.oldsize); - unsigned oldHeapID = inEvent->u.alloc.oldptr; - unsigned oldSerial = inEvent->u.alloc.oldserial; - - if(0 == actualSize) - { - /* - ** Reallocs of size zero are to become free events. - */ - stats->mLoopExitTMR = simpleHeapEvent(stats, FREE, timestamp, serial, oldHeapID, oldActualSize); - } - else if(heapID != oldHeapID || actualSize != oldActualSize) - { - /* - ** Reallocs which moved generate two events. - ** Reallocs which changed size generate two events. - ** - ** One event to free the old memory area. - ** Another event to allocate the new memory area. - ** They are to be linked to one another, so the history - ** and true origin can be tracked. - */ - stats->mLoopExitTMR = complexHeapEvent(stats, timestamp, oldSerial, oldHeapID, oldActualSize, serial, heapID, actualSize); - } - else - { - /* - ** The realloc is not considered an operation and is skipped. - ** It is not an operation, because it did not move or change - ** size; this can happen if a realloc falls within the - ** alignment of an allocation. - ** Say if you realloc a 1 byte allocation to 2 bytes, it will - ** not really change heap impact unless you have 1 set as - ** the alignment of your allocations. - */ - } - } - else if(TM_EVENT_FREE == type) - { - /* - ** Generate a free event to create a fragment. - */ - stats->mLoopExitTMR = simpleHeapEvent(stats, FREE, timestamp, serial, heapID, actualSize); - } - else - { - /* - ** Generate an allocation event to clear fragments. - */ - stats->mLoopExitTMR = simpleHeapEvent(stats, ALLOC, timestamp, serial, heapID, actualSize); - } - } -} - - -int tmfrags(Options* inOptions) -/* -** Load the input file and report stats. -*/ -{ - int retval = 0; - TMState stats; - - memset(&stats, 0, sizeof(stats)); - stats.mOptions = inOptions; - stats.uMinTicks = 0xFFFFFFFFU; - - /* - ** Need a tmreader. - */ - stats.mTMR = tmreader_new(inOptions->mProgramName, &stats); - if(NULL != stats.mTMR) - { - int tmResult = 0; - - tmResult = tmreader_eventloop(stats.mTMR, inOptions->mInputName, tmEventHandler); - if(0 == tmResult) - { - retval = __LINE__; - ERROR_REPORT(retval, inOptions->mInputName, "Problem reading trace-malloc data."); - } - if(0 != stats.mLoopExitTMR) - { - retval = stats.mLoopExitTMR; - ERROR_REPORT(retval, inOptions->mInputName, "Aborted trace-malloc input loop."); - } - - tmreader_destroy(stats.mTMR); - stats.mTMR = NULL; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, inOptions->mProgramName, "Unable to obtain tmreader."); - } - - return retval; -} - - -int main(int inArgc, char** inArgv) -{ - int retval = 0; - Options options; - - retval = initOptions(&options, inArgc, inArgv); - if(options.mHelp) - { - showHelp(&options); - } - else if(0 == retval) - { - retval = tmfrags(&options); - } - - cleanOptions(&options); - return retval; -} - diff --git a/tools/trace-malloc/tmreader.c b/tools/trace-malloc/tmreader.c deleted file mode 100644 index 71a58e92edba..000000000000 --- a/tools/trace-malloc/tmreader.c +++ /dev/null @@ -1,892 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#include /* XXX push error reporting out to clients? */ -#ifndef XP_WIN -#include -#else -#include -#endif -#include "prlog.h" -#include "plhash.h" -/* make sure this happens before tmreader.h */ -#define PL_ARENA_CONST_ALIGN_MASK 2 -#include "plarena.h" - -#include "prnetdb.h" -#include "nsTraceMalloc.h" -#include "tmreader.h" - -#undef DEBUG_tmreader - -static int accum_byte(FILE *fp, uint32_t *uip) -{ - int c = getc(fp); - if (c == EOF) - return 0; - *uip = (*uip << 8) | c; - return 1; -} - -static int get_uint32(FILE *fp, uint32_t *uip) -{ - int c; - uint32_t ui; - - c = getc(fp); - if (c == EOF) - return 0; - ui = 0; - if (c & 0x80) { - c &= 0x7f; - if (c & 0x40) { - c &= 0x3f; - if (c & 0x20) { - c &= 0x1f; - if (c & 0x10) { - if (!accum_byte(fp, &ui)) - return 0; - } else { - ui = (uint32_t) c; - } - if (!accum_byte(fp, &ui)) - return 0; - } else { - ui = (uint32_t) c; - } - if (!accum_byte(fp, &ui)) - return 0; - } else { - ui = (uint32_t) c; - } - if (!accum_byte(fp, &ui)) - return 0; - } else { - ui = (uint32_t) c; - } - *uip = ui; - return 1; -} - -static char *get_string(FILE *fp) -{ - char *cp; - int c; - static char buf[256]; - static char *bp = buf, *ep = buf + sizeof buf; - static size_t bsize = sizeof buf; - - cp = bp; - do { - c = getc(fp); - if (c == EOF) - return 0; - if (cp == ep) { - if (bp == buf) { - bp = malloc(2 * bsize); - if (bp) - memcpy(bp, buf, bsize); - } else { - bp = realloc(bp, 2 * bsize); - } - if (!bp) - return 0; - cp = bp + bsize; - bsize *= 2; - ep = bp + bsize; - } - *cp++ = c; - } while (c != '\0'); - return strdup(bp); -} - -static int get_tmevent(FILE *fp, tmevent *event) -{ - int c; - char *s; - - c = getc(fp); - if (c == EOF) - return 0; - event->type = (char) c; - if (!get_uint32(fp, &event->serial)) - return 0; - switch (c) { - case TM_EVENT_LIBRARY: - s = get_string(fp); - if (!s) - return 0; - event->u.libname = s; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u libname=\"%s\"\n", event->type, event->serial, - event->u.libname); -#endif - break; - - case TM_EVENT_FILENAME: - s = get_string(fp); - if (!s) - return 0; - event->u.srcname = s; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u srcname=\"%s\"\n", - event->type, event->serial, event->u.srcname); -#endif - break; - - case TM_EVENT_METHOD: - if (!get_uint32(fp, &event->u.method.library)) - return 0; - if (!get_uint32(fp, &event->u.method.filename)) - return 0; - if (!get_uint32(fp, &event->u.method.linenumber)) - return 0; - s = get_string(fp); - if (!s) - return 0; - event->u.method.name = s; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u library=%u filename=%u linenumber=%u " - "name=\"%s\"\n", - event->type, event->serial, - event->u.method.library, event->u.method.filename, - event->u.method.linenumber, event->u.method.name); -#endif - break; - - case TM_EVENT_CALLSITE: - if (!get_uint32(fp, &event->u.site.parent)) - return 0; - if (!get_uint32(fp, &event->u.site.method)) - return 0; - if (!get_uint32(fp, &event->u.site.offset)) - return 0; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u parent=%u method=%u offset=%u\n", - event->type, event->serial, - event->u.site.parent, event->u.site.method, - event->u.site.offset); -#endif - break; - - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_FREE: - if (!get_uint32(fp, &event->u.alloc.interval)) - return 0; - if (!get_uint32(fp, &event->u.alloc.cost)) - return 0; - if (!get_uint32(fp, &event->u.alloc.ptr)) - return 0; - if (!get_uint32(fp, &event->u.alloc.size)) - return 0; - event->u.alloc.oldserial = 0; - event->u.alloc.oldptr = 0; - event->u.alloc.oldsize = 0; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u interval=%u cost=%u ptr=0x%x size=%u\n", - event->type, event->serial, - event->u.alloc.interval, event->u.alloc.cost, - event->u.alloc.ptr, event->u.alloc.size); -#endif -#if defined(DEBUG_dp) - if (c == TM_EVENT_MALLOC) - printf("%d malloc %d 0x%p\n", event->u.alloc.cost, - event->u.alloc.size, event->u.alloc.ptr); - else if (c == TM_EVENT_CALLOC) - printf("%d calloc %d 0x%p\n", event->u.alloc.cost, - event->u.alloc.size, event->u.alloc.ptr); - else - printf("%d free %d 0x%p\n", event->u.alloc.cost, - event->u.alloc.size, event->u.alloc.ptr); -#endif - break; - - case TM_EVENT_REALLOC: - if (!get_uint32(fp, &event->u.alloc.interval)) - return 0; - if (!get_uint32(fp, &event->u.alloc.cost)) - return 0; - if (!get_uint32(fp, &event->u.alloc.ptr)) - return 0; - if (!get_uint32(fp, &event->u.alloc.size)) - return 0; - if (!get_uint32(fp, &event->u.alloc.oldserial)) - return 0; - if (!get_uint32(fp, &event->u.alloc.oldptr)) - return 0; - if (!get_uint32(fp, &event->u.alloc.oldsize)) - return 0; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u interval=%u cost=%u ptr=0x%x size=%u " - "oldserial=%u oldptr=0x%x oldsize=%u\n", - event->type, event->serial, - event->u.alloc.interval, event->u.alloc.cost, - event->u.alloc.ptr, event->u.alloc.size, - event->u.alloc.oldserial, event->u.alloc.oldptr, - event->u.alloc.oldsize); -#endif -#if defined(DEBUG_dp) - printf("%d realloc %d 0x%p %d\n", event->u.alloc.cost, - event->u.alloc.size, event->u.alloc.ptr, event->u.alloc.oldsize); -#endif - break; - - case TM_EVENT_STATS: - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxstack)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxdepth)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_parents)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_maxkids)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidhits)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidmisses)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calltree_kidsteps)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.callsite_recurrences)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.backtrace_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.backtrace_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.btmalloc_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.dladdr_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.malloc_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.malloc_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calloc_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.calloc_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.realloc_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.realloc_failures)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.free_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.tmstats.null_free_calls)) - return 0; - if (!get_uint32(fp, &event->u.stats.calltree_maxkids_parent)) - return 0; - if (!get_uint32(fp, &event->u.stats.calltree_maxstack_top)) - return 0; -#ifdef DEBUG_tmreader - fprintf(stderr, "tmevent %c %u\n", event->type, event->serial); -#endif - break; - default: - fprintf(stderr, "Unknown event type 0x%x\n", (unsigned int)event->type); - return 0; - } - return 1; -} - -static void *arena_alloc(void* pool, size_t size) -{ - PLArenaPool* arena = (PLArenaPool*)pool; - void* result; - PL_ARENA_ALLOCATE(result, arena, size); - memset(result, 0, size); - return result; -} - -static void *generic_alloctable(void *pool, size_t size) -{ - return arena_alloc(pool, size); -} - -static void generic_freetable(void *pool, void *item) -{ - /* do nothing - arena-allocated */ -} - -static PLHashEntry *filename_allocentry(void *pool, const void *key) -{ - return (PLHashEntry*)arena_alloc(pool, sizeof(PLHashEntry)); -} - -static PLHashEntry *callsite_allocentry(void *pool, const void *key) -{ - return (PLHashEntry*)arena_alloc(pool, sizeof(tmcallsite)); -} - -static void init_graphnode(tmgraphnode* node) -{ - node->in = node->out = NULL; - node->up = node->down = node->next = NULL; - node->low = 0; - node->allocs.bytes.direct = node->allocs.bytes.total = 0; - node->allocs.calls.direct = node->allocs.calls.total = 0; - node->frees.bytes.direct = node->frees.bytes.total = 0; - node->frees.calls.direct = node->frees.calls.total = 0; - node->sqsum = 0; - node->sort = -1; -} - -static PLHashEntry *graphnode_allocentry(void *pool, const void *key) -{ - tmgraphnode* node = (tmgraphnode*)arena_alloc(pool, sizeof(tmgraphnode)); - if (!node) - return NULL; - init_graphnode(node); - return &node->entry; -} - -static void init_method(tmmethodnode *node) -{ - node->graphnode.in = node->graphnode.out = NULL; - node->graphnode.up = node->graphnode.down = node->graphnode.next = NULL; - node->graphnode.low = 0; - node->graphnode.allocs.bytes.direct = node->graphnode.allocs.bytes.total = 0; - node->graphnode.allocs.calls.direct = node->graphnode.allocs.calls.total = 0; - node->graphnode.frees.bytes.direct = node->graphnode.frees.bytes.total = 0; - node->graphnode.frees.calls.direct = node->graphnode.frees.calls.total = 0; - node->graphnode.sqsum = 0; - node->graphnode.sort = -1; - node->sourcefile = NULL; - node->linenumber = 0; -} - -static PLHashEntry *method_allocentry(void *pool, const void *key) -{ - tmmethodnode *node = - (tmmethodnode*) arena_alloc(pool, sizeof(tmmethodnode)); - if (!node) - return NULL; - init_method(node); - return &node->graphnode.entry; -} - -static void graphnode_freeentry(void *pool, PLHashEntry *he, unsigned flag) -{ - /* Always free the value, which points to a strdup'd string. */ - free(he->value); -#if 0 /* using arenas now, no freeing! */ - /* Free the whole thing if we're told to. */ - if (flag == HT_FREE_ENTRY) - free((void*) he); -#endif -} - -static void component_freeentry(void *pool, PLHashEntry *he, unsigned flag) -{ - if (flag == HT_FREE_ENTRY) { - tmgraphnode *comp = (tmgraphnode*) he; - - /* Free the key, which was strdup'd (N.B. value also points to it). */ - free((void*) tmcomponent_name(comp)); -#if 0 /* using arenas now, no freeing! */ - free((void*) comp); -#endif - } -} - -static PLHashAllocOps filename_hashallocops = { - generic_alloctable, generic_freetable, - filename_allocentry, graphnode_freeentry -}; - -static PLHashAllocOps callsite_hashallocops = { - generic_alloctable, generic_freetable, - callsite_allocentry, graphnode_freeentry -}; - -static PLHashAllocOps graphnode_hashallocops = { - generic_alloctable, generic_freetable, - graphnode_allocentry, graphnode_freeentry -}; - -static PLHashAllocOps method_hashallocops = { - generic_alloctable, generic_freetable, - method_allocentry, graphnode_freeentry -}; - -static PLHashAllocOps component_hashallocops = { - generic_alloctable, generic_freetable, - graphnode_allocentry, component_freeentry -}; - -static PLHashNumber hash_serial(const void *key) -{ - return (PLHashNumber) key; -} - -tmreader *tmreader_new(const char *program, void *data) -{ - tmreader *tmr; - - tmr = calloc(1, sizeof *tmr); - if (!tmr) - return NULL; - tmr->program = program; - tmr->data = data; - PL_INIT_ARENA_POOL(&tmr->arena, "TMReader", 256*1024); - - tmr->libraries = PL_NewHashTable(100, hash_serial, PL_CompareValues, - PL_CompareStrings, &graphnode_hashallocops, - &tmr->arena); - tmr->filenames = PL_NewHashTable(100, hash_serial, PL_CompareValues, - PL_CompareStrings, &filename_hashallocops, - &tmr->arena); - tmr->components = PL_NewHashTable(10000, PL_HashString, PL_CompareStrings, - PL_CompareValues, &component_hashallocops, - &tmr->arena); - tmr->methods = PL_NewHashTable(10000, hash_serial, PL_CompareValues, - PL_CompareStrings, &method_hashallocops, - &tmr->arena); - tmr->callsites = PL_NewHashTable(200000, hash_serial, PL_CompareValues, - PL_CompareValues, &callsite_hashallocops, - &tmr->arena); - tmr->calltree_root.entry.value = (void*) strdup("root"); - - if (!tmr->libraries || !tmr->components || !tmr->methods || - !tmr->callsites || !tmr->calltree_root.entry.value || - !tmr->filenames) { - tmreader_destroy(tmr); - return NULL; - } - return tmr; -} - -void tmreader_destroy(tmreader *tmr) -{ - if (tmr->libraries) - PL_HashTableDestroy(tmr->libraries); - if (tmr->filenames) - PL_HashTableDestroy(tmr->filenames); - if (tmr->components) - PL_HashTableDestroy(tmr->components); - if (tmr->methods) - PL_HashTableDestroy(tmr->methods); - if (tmr->callsites) - PL_HashTableDestroy(tmr->callsites); - PL_FinishArenaPool(&tmr->arena); - free(tmr); -} - -int tmreader_eventloop(tmreader *tmr, const char *filename, - tmeventhandler eventhandler) -{ - FILE *fp; - char buf[NS_TRACE_MALLOC_MAGIC_SIZE]; - tmevent event; - static const char magic[] = NS_TRACE_MALLOC_MAGIC; - - if (strcmp(filename, "-") == 0) { - fp = stdin; - } else { -#if defined(XP_WIN32) - fp = fopen(filename, "rb"); -#else - fp = fopen(filename, "r"); -#endif - if (!fp) { - fprintf(stderr, "%s: can't open %s: %s.\n", - tmr->program, filename, strerror(errno)); - return 0; - } - } - - if (read(fileno(fp), buf, sizeof buf) != sizeof buf || - strncmp(buf, magic, sizeof buf) != 0) { - fprintf(stderr, "%s: bad magic string %s at start of %s.\n", - tmr->program, buf, filename); - fprintf(stderr, "either the data file is out of date,\nor your tools are out of date.\n"); - return 0; - } - - /* Read in ticks per second. Used to convert platform specific intervals to time values */ - if (read(fileno(fp), &tmr->ticksPerSec, sizeof tmr->ticksPerSec) != sizeof tmr->ticksPerSec) { - fprintf(stderr, "%s: Cannot read ticksPerSec. Log file read error.\n", - tmr->program); - return 0; - } - tmr->ticksPerSec = PR_ntohl(tmr->ticksPerSec); -#ifdef DEBUG_dp - printf("DEBUG: ticks per sec = %d\n", tmr->ticksPerSec); -#endif - while (get_tmevent(fp, &event)) { - switch (event.type) { - case TM_EVENT_LIBRARY: { - const void *key; - PLHashNumber hash; - PLHashEntry **hep, *he; - - key = (const void*) (uintptr_t) event.serial; - hash = hash_serial(key); - hep = PL_HashTableRawLookup(tmr->libraries, hash, key); - he = *hep; - PR_ASSERT(!he); - if (he) exit(2); - - he = PL_HashTableRawAdd(tmr->libraries, hep, hash, key, - event.u.libname); - if (!he) { - perror(tmr->program); - return -1; - } - break; - } - - case TM_EVENT_FILENAME: { - const void *key; - PLHashNumber hash; - PLHashEntry **hep, *he; - - key = (const void*) (uintptr_t) event.serial; - hash = hash_serial(key); - hep = PL_HashTableRawLookup(tmr->filenames, hash, key); - he = *hep; - PR_ASSERT(!he); - if (he) exit(2); - - he = PL_HashTableRawAdd(tmr->filenames, hep, hash, key, - event.u.srcname); - if (!he) { - perror(tmr->program); - return -1; - } - break; - } - - case TM_EVENT_METHOD: { - const void *key, *sourcekey; - PLHashNumber hash, sourcehash; - PLHashEntry **hep, *he, **sourcehep, *sourcehe; - char *name, *head, *mark, save; - tmgraphnode *comp, *lib; - tmmethodnode *meth; - - key = (const void*) (uintptr_t) event.serial; - hash = hash_serial(key); - hep = PL_HashTableRawLookup(tmr->methods, hash, key); - he = *hep; - PR_ASSERT(!he); - if (he) exit(2); - - name = event.u.method.name; - he = PL_HashTableRawAdd(tmr->methods, hep, hash, key, name); - if (!he) { - perror(tmr->program); - return -1; - } - meth = (tmmethodnode*) he; - - meth->linenumber = event.u.method.linenumber; - sourcekey = (const void*) (uintptr_t) event.u.method.filename; - sourcehash = hash_serial(sourcekey); - sourcehep = PL_HashTableRawLookup(tmr->filenames, sourcehash, sourcekey); - sourcehe = *sourcehep; - meth->sourcefile = filename_name(sourcehe); - - head = name; - mark = strchr(name, ':'); - if (!mark) { - mark = name; - while (*mark != '\0' && *mark == '_') - mark++; - head = mark; - mark = strchr(head, '_'); - if (!mark) { - mark = strchr(head, '+'); - if (!mark) - mark = head + strlen(head); - } - } - - save = *mark; - *mark = '\0'; - hash = PL_HashString(head); - hep = PL_HashTableRawLookup(tmr->components, hash, head); - he = *hep; - if (he) { - comp = (tmgraphnode*) he; - } else { - head = strdup(head); - if (head) { - he = PL_HashTableRawAdd(tmr->components, hep, hash, head, - head); - } - if (!he) { - perror(tmr->program); - return -1; - } - comp = (tmgraphnode*) he; - - key = (const void*) (uintptr_t) event.u.method.library; - hash = hash_serial(key); - lib = (tmgraphnode*) - *PL_HashTableRawLookup(tmr->libraries, hash, key); - if (lib) { - comp->up = lib; - comp->next = lib->down; - lib->down = comp; - } - } - *mark = save; - - meth->graphnode.up = comp; - meth->graphnode.next = comp->down; - comp->down = &(meth->graphnode); - break; - } - - case TM_EVENT_CALLSITE: { - const void *key, *mkey; - PLHashNumber hash, mhash; - PLHashEntry **hep, *he; - tmcallsite *site, *parent; - tmmethodnode *meth; - - key = (const void*) (uintptr_t) event.serial; - hash = hash_serial(key); - hep = PL_HashTableRawLookup(tmr->callsites, hash, key); - he = *hep; - - /* there should not be an entry here! */ - PR_ASSERT(!he); - if (he) exit(2); - - if (event.u.site.parent == 0) { - parent = &tmr->calltree_root; - } else { - parent = tmreader_callsite(tmr, event.u.site.parent); - if (!parent) { - fprintf(stderr, "%s: no parent for %lu (%lu)!\n", - tmr->program, (unsigned long) event.serial, - (unsigned long) event.u.site.parent); - continue; - } - } - - he = PL_HashTableRawAdd(tmr->callsites, hep, hash, key, NULL); - if (!he) { - perror(tmr->program); - return -1; - } - - site = (tmcallsite*) he; - site->parent = parent; - site->siblings = parent->kids; - parent->kids = site; - site->kids = NULL; - - mkey = (const void*) (uintptr_t) event.u.site.method; - mhash = hash_serial(mkey); - meth = (tmmethodnode*) - *PL_HashTableRawLookup(tmr->methods, mhash, mkey); - site->method = meth; - site->offset = event.u.site.offset; - site->allocs.bytes.direct = site->allocs.bytes.total = 0; - site->allocs.calls.direct = site->allocs.calls.total = 0; - site->frees.bytes.direct = site->frees.bytes.total = 0; - site->frees.calls.direct = site->frees.calls.total = 0; - break; - } - - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_REALLOC: { - tmcallsite *site; - uint32_t size, oldsize; - double delta, sqdelta, sqszdelta = 0; - tmgraphnode *comp, *lib; - tmmethodnode *meth; - - site = tmreader_callsite(tmr, event.serial); - if (!site) { - fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n", - tmr->program, event.type, (unsigned long) event.serial); - continue; - } - - size = event.u.alloc.size; - oldsize = event.u.alloc.oldsize; - delta = (double)size - (double)oldsize; - site->allocs.bytes.direct += (unsigned long)delta; - if (event.type != TM_EVENT_REALLOC) - site->allocs.calls.direct++; - meth = site->method; - if (meth) { - meth->graphnode.allocs.bytes.direct += (unsigned long)delta; - sqdelta = delta * delta; - if (event.type == TM_EVENT_REALLOC) { - sqszdelta = ((double)size * size) - - ((double)oldsize * oldsize); - meth->graphnode.sqsum += sqszdelta; - } else { - meth->graphnode.sqsum += sqdelta; - meth->graphnode.allocs.calls.direct++; - } - comp = meth->graphnode.up; - if (comp) { - comp->allocs.bytes.direct += (unsigned long)delta; - if (event.type == TM_EVENT_REALLOC) { - comp->sqsum += sqszdelta; - } else { - comp->sqsum += sqdelta; - comp->allocs.calls.direct++; - } - lib = comp->up; - if (lib) { - lib->allocs.bytes.direct += (unsigned long)delta; - if (event.type == TM_EVENT_REALLOC) { - lib->sqsum += sqszdelta; - } else { - lib->sqsum += sqdelta; - lib->allocs.calls.direct++; - } - } - } - } - break; - } - - case TM_EVENT_FREE: { - tmcallsite *site; - uint32_t size; - tmgraphnode *comp, *lib; - tmmethodnode *meth; - - site = tmreader_callsite(tmr, event.serial); - if (!site) { - fprintf(stderr, "%s: no callsite for '%c' (%lu)!\n", - tmr->program, event.type, (unsigned long) event.serial); - continue; - } - size = event.u.alloc.size; - site->frees.bytes.direct += size; - site->frees.calls.direct++; - meth = site->method; - if (meth) { - meth->graphnode.frees.bytes.direct += size; - meth->graphnode.frees.calls.direct++; - comp = meth->graphnode.up; - if (comp) { - comp->frees.bytes.direct += size; - comp->frees.calls.direct++; - lib = comp->up; - if (lib) { - lib->frees.bytes.direct += size; - lib->frees.calls.direct++; - } - } - } - break; - } - - case TM_EVENT_STATS: - break; - } - - eventhandler(tmr, &event); - } - - return 1; -} - -tmgraphnode *tmreader_library(tmreader *tmr, uint32_t serial) -{ - const void *key; - PLHashNumber hash; - - key = (const void*) (uintptr_t) serial; - hash = hash_serial(key); - return (tmgraphnode*) *PL_HashTableRawLookup(tmr->libraries, hash, key); -} - -tmgraphnode *tmreader_filename(tmreader *tmr, uint32_t serial) -{ - const void *key; - PLHashNumber hash; - - key = (const void*) (uintptr_t) serial; - hash = hash_serial(key); - return (tmgraphnode*) *PL_HashTableRawLookup(tmr->filenames, hash, key); -} - -tmgraphnode *tmreader_component(tmreader *tmr, const char *name) -{ - PLHashNumber hash; - - hash = PL_HashString(name); - return (tmgraphnode*) *PL_HashTableRawLookup(tmr->components, hash, name); -} - -tmmethodnode *tmreader_method(tmreader *tmr, uint32_t serial) -{ - const void *key; - PLHashNumber hash; - - key = (const void*) (uintptr_t) serial; - hash = hash_serial(key); - return (tmmethodnode*) *PL_HashTableRawLookup(tmr->methods, hash, key); -} - -tmcallsite *tmreader_callsite(tmreader *tmr, uint32_t serial) -{ - const void *key; - PLHashNumber hash; - - key = (const void*) (uintptr_t) serial; - hash = hash_serial(key); - return (tmcallsite*) *PL_HashTableRawLookup(tmr->callsites, hash, key); -} - -int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to, tmcallsite *site) -{ - tmgraphlink *outlink; - tmgraphedge *edge; - - for (outlink = from->out; outlink; outlink = outlink->next) { - if (outlink->node == to) { - /* - * Say the stack looks like this: ... => JS => js => JS => js. - * We must avoid overcounting JS=>js because the first edge total - * includes the second JS=>js edge's total (which is because the - * lower site's total includes all its kids' totals). - */ - edge = TM_LINK_TO_EDGE(outlink, TM_EDGE_OUT_LINK); - if (!to->low || to->low < from->low) { - /* Add the direct and total counts to edge->allocs. */ - edge->allocs.bytes.direct += site->allocs.bytes.direct; - edge->allocs.bytes.total += site->allocs.bytes.total; - edge->allocs.calls.direct += site->allocs.calls.direct; - edge->allocs.calls.total += site->allocs.calls.total; - - /* Now update the free counts. */ - edge->frees.bytes.direct += site->frees.bytes.direct; - edge->frees.bytes.total += site->frees.bytes.total; - edge->frees.calls.direct += site->frees.calls.direct; - edge->frees.calls.total += site->frees.calls.total; - } - return 1; - } - } - - edge = (tmgraphedge*) malloc(sizeof(tmgraphedge)); - if (!edge) - return 0; - edge->links[TM_EDGE_OUT_LINK].node = to; - edge->links[TM_EDGE_OUT_LINK].next = from->out; - from->out = &edge->links[TM_EDGE_OUT_LINK]; - edge->links[TM_EDGE_IN_LINK].node = from; - edge->links[TM_EDGE_IN_LINK].next = to->in; - to->in = &edge->links[TM_EDGE_IN_LINK]; - edge->allocs = site->allocs; - edge->frees = site->frees; - return 1; -} diff --git a/tools/trace-malloc/tmreader.h b/tools/trace-malloc/tmreader.h deleted file mode 100644 index 6e4dc757f607..000000000000 --- a/tools/trace-malloc/tmreader.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 tmreader_h___ -#define tmreader_h___ - -#include "plhash.h" -#include "nsTraceMalloc.h" -#include "plarena.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct tmreader tmreader; -typedef struct tmevent tmevent; -typedef struct tmcounts tmcounts; -typedef struct tmallcounts tmallcounts; -typedef struct tmgraphlink tmgraphlink; -typedef struct tmgraphedge tmgraphedge; -typedef struct tmgraphnode tmgraphnode; -typedef struct tmcallsite tmcallsite; -typedef struct tmmethodnode tmmethodnode; - -struct tmevent { - char type; - uint32_t serial; - union { - char *libname; - char *srcname; - struct { - uint32_t library; - uint32_t filename; - uint32_t linenumber; - char *name; - } method; - struct { - uint32_t parent; - uint32_t method; - uint32_t offset; - } site; - struct { - uint32_t interval; /* in ticks */ - uint32_t ptr; - uint32_t size; - uint32_t oldserial; - uint32_t oldptr; - uint32_t oldsize; - uint32_t cost; /* in ticks */ - } alloc; - struct { - nsTMStats tmstats; - uint32_t calltree_maxkids_parent; - uint32_t calltree_maxstack_top; - } stats; - } u; -}; - -struct tmcounts { - uint32_t direct; /* things allocated by this node's code */ - uint32_t total; /* direct + things from all descendents */ -}; - -struct tmallcounts { - tmcounts bytes; - tmcounts calls; -}; - -struct tmgraphnode { - PLHashEntry entry; /* key is serial or name, value must be name */ - tmgraphlink *in; - tmgraphlink *out; - tmgraphnode *up; /* parent in supergraph, e.g., JS for JS_*() */ - tmgraphnode *down; /* subgraph kids, declining bytes.total order */ - tmgraphnode *next; /* next kid in supergraph node's down list */ - int low; /* 0 or lowest current tree walk level */ - tmallcounts allocs; - tmallcounts frees; - double sqsum; /* sum of squared bytes.direct */ - int sort; /* sorted index in node table, -1 if no table */ -}; - -struct tmmethodnode { - tmgraphnode graphnode; - char *sourcefile; - uint32_t linenumber; -}; - -#define tmgraphnode_name(node) ((char*) (node)->entry.value) -#define tmmethodnode_name(node) ((char*) (node)->graphnode.entry.value) - -#define tmlibrary_serial(lib) ((uint32_t) (lib)->entry.key) -#define tmcomponent_name(comp) ((const char*) (comp)->entry.key) -#define filename_name(hashentry) ((char*)hashentry->value) - -/* Half a graphedge, not including per-edge allocation stats. */ -struct tmgraphlink { - tmgraphlink *next; /* next fanning out from or into a node */ - tmgraphnode *node; /* the other node (to if OUT, from if IN) */ -}; - -/* - * It's safe to downcast a "from" tmgraphlink (one linked from a node's out - * pointer) to tmgraphedge. To go from an "out" (linked via tmgraphedge.from) - * or "in" (linked via tmgraphedge.to) list link to its containing edge, use - * TM_LINK_TO_EDGE(link, which). - */ -struct tmgraphedge { - tmgraphlink links[2]; - tmallcounts allocs; - tmallcounts frees; -}; - -/* Indices into tmgraphedge.links -- out must come first. */ -#define TM_EDGE_OUT_LINK 0 -#define TM_EDGE_IN_LINK 1 - -#define TM_LINK_TO_EDGE(link,which) ((tmgraphedge*) &(link)[-(which)]) - -struct tmcallsite { - PLHashEntry entry; /* key is site serial number */ - tmcallsite *parent; /* calling site */ - tmcallsite *siblings; /* other sites reached from parent */ - tmcallsite *kids; /* sites reached from here */ - tmmethodnode *method; /* method node in tmr->methods graph */ - uint32_t offset; /* pc offset from start of method */ - tmallcounts allocs; - tmallcounts frees; - void *data; /* tmreader clients can stick arbitrary - * data onto a callsite. - */ -}; - -struct tmreader { - const char *program; - void *data; - PLHashTable *libraries; - PLHashTable *filenames; - PLHashTable *components; - PLHashTable *methods; - PLHashTable *callsites; - PLArenaPool arena; - tmcallsite calltree_root; - uint32_t ticksPerSec; -}; - -typedef void (*tmeventhandler)(tmreader *tmr, tmevent *event); - -/* The tmreader constructor and destructor. */ -extern tmreader *tmreader_new(const char *program, void *data); -extern void tmreader_destroy(tmreader *tmr); - -/* - * Return -1 on permanent fatal error, 0 if filename can't be opened or is not - * a trace-malloc logfile, and 1 on success. - */ -extern int tmreader_eventloop(tmreader *tmr, const char *filename, - tmeventhandler eventhandler); - -/* Map serial number or name to graphnode or callsite. */ -extern tmgraphnode *tmreader_library(tmreader *tmr, uint32_t serial); -extern tmgraphnode *tmreader_filename(tmreader *tmr, uint32_t serial); -extern tmgraphnode *tmreader_component(tmreader *tmr, const char *name); -extern tmmethodnode *tmreader_method(tmreader *tmr, uint32_t serial); -extern tmcallsite *tmreader_callsite(tmreader *tmr, uint32_t serial); - -/* - * Connect node 'from' to node 'to' with an edge, if there isn't one already - * connecting the nodes. Add site's allocation stats to the edge only if we - * create the edge, or if we find that it exists, but that to->low is zero or - * less than from->low. - * - * If the callsite tree already totals allocation costs (tmcounts.total for - * each site includes tmcounts.direct for that site, plus tmcounts.total for - * all kid sites), then the node->low watermarks should be set from the tree - * level when walking the callsite tree, and should be set to non-zero values - * only if zero (the root is at level 0). A low watermark should be cleared - * when the tree walk unwinds past the level at which it was set non-zero. - * - * Return 0 on error (malloc failure) and 1 on success. - */ -extern int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to, - tmcallsite *site); - -#ifdef __cplusplus -} -#endif - -#endif /* tmreader_h___ */ diff --git a/tools/trace-malloc/tmstats.c b/tools/trace-malloc/tmstats.c deleted file mode 100644 index f97a07dad0a3..000000000000 --- a/tools/trace-malloc/tmstats.c +++ /dev/null @@ -1,830 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "nspr.h" -#include "tmreader.h" - -#define ERROR_REPORT(num, val, msg) fprintf(stderr, "error(%d):\t\"%s\"\t%s\n", (num), (val), (msg)); -#define CLEANUP(ptr) do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while(0) - - -#define COST_RESOLUTION 1000 -#define COST_PRINTABLE(cost) ((double)(cost) / (double)COST_RESOLUTION) - - -typedef struct __struct_Options -/* -** Options to control how we perform. -** -** mProgramName Used in help text. -** mInputName Name of the file. -** mOutput Output file, append. -** Default is stdout. -** mOutputName Name of the file. -** mHelp Whether or not help should be shown. -** mOverhead How much overhead an allocation will have. -** mAlignment What boundry will the end of an allocation line up on. -** mAverages Whether or not to display averages. -** mDeviances Whether or not to display standard deviations. -** mRunLength Whether or not to display run length. -*/ -{ - const char* mProgramName; - char* mInputName; - FILE* mOutput; - char* mOutputName; - int mHelp; - unsigned mOverhead; - unsigned mAlignment; - int mAverages; - int mDeviances; - int mRunLength; -} -Options; - - -typedef struct __struct_Switch -/* -** Command line options. -*/ -{ - const char* mLongName; - const char* mShortName; - int mHasValue; - const char* mValue; - const char* mDescription; -} -Switch; - -#define DESC_NEWLINE "\n\t\t" - -static Switch gInputSwitch = {"--input", "-i", 1, NULL, "Specify input file." DESC_NEWLINE "stdin is default."}; -static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." DESC_NEWLINE "Appends if file exists." DESC_NEWLINE "stdout is default."}; -static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."}; -static Switch gAlignmentSwitch = {"--alignment", "-al", 1, NULL, "All allocation sizes are made to be a multiple of this number." DESC_NEWLINE "Closer to actual heap conditions; set to 1 for true sizes." DESC_NEWLINE "Default value is 16."}; -static Switch gOverheadSwitch = {"--overhead", "-ov", 1, NULL, "After alignment, all allocations are made to increase by this number." DESC_NEWLINE "Closer to actual heap conditions; set to 0 for true sizes." DESC_NEWLINE "Default value is 8."}; -static Switch gAveragesSwitch = {"--averages", "-avg", 0, NULL, "Display averages."}; -static Switch gDeviationsSwitch = {"--deviations", "-dev", 0, NULL, "Display standard deviations from the average." DESC_NEWLINE "Implies --averages."}; -static Switch gRunLengthSwitch = {"--run-length", "-rl", 0, NULL, "Display the run length in seconds."}; - -static Switch* gSwitches[] = { - &gInputSwitch, - &gOutputSwitch, - &gAlignmentSwitch, - &gOverheadSwitch, - &gAveragesSwitch, - &gDeviationsSwitch, - &gRunLengthSwitch, - &gHelpSwitch -}; - - -typedef struct _struct_VarianceState -/* -** State for a single pass variance calculation. -*/ -{ - unsigned mCount; - uint64_t mSum; - uint64_t mSquaredSum; -} -VarianceState; - - -typedef struct __struct_TMStats -/* -** Stats we are trying to calculate. -** -** mOptions Obilgatory options pointer. -** uMemoryInUse Current tally of memory in use. -** uPeakMemory Heap topped out at this byte level. -** uObjectsInUse Different allocations outstanding. -** uPeakObjects Highest object count. -** uMallocs Number of malloc calls. -** uCallocs Number of calloc calls. -** uReallocs Number of realloc calls. -** uFrees Number of free calls. -** uMallocSize Bytes from malloc. -** uCallocSize Bytes from calloc. -** uReallocSize Bytes from realloc. -** uFreeSize Bytes from free. -** mMallocSizeVar Variance of bytes. -** mCallocSizeVar Variance of bytes. -** mReallocSizeVar Variance of bytes. -** mFreeSizeVar Variance of bytes. -** uMallocCost Time of mallocs. -** uCallocCost Time of callocs. -** uReallocCost Time of reallocs. -** uFreeCost Time of frees. -** mMallocCostVar Variance of cost. -** mCallocCostVar Variance of cost. -** mReallocCostVar Variance of cost. -** mFreeCostVar Variance of cost. -** uMinTicks Start of run. -** uMaxTicks End of run. -*/ -{ - Options* mOptions; - unsigned uMemoryInUse; - unsigned uPeakMemory; - unsigned uObjectsInUse; - unsigned uPeakObjects; - unsigned uMallocs; - unsigned uCallocs; - unsigned uReallocs; - unsigned uFrees; - - unsigned uMallocSize; - unsigned uCallocSize; - unsigned uReallocSize; - unsigned uFreeSize; - VarianceState mMallocSizeVar; - VarianceState mCallocSizeVar; - VarianceState mReallocSizeVar; - VarianceState mFreeSizeVar; - - unsigned uMallocCost; - unsigned uCallocCost; - unsigned uReallocCost; - unsigned uFreeCost; - VarianceState mMallocCostVar; - VarianceState mCallocCostVar; - VarianceState mReallocCostVar; - VarianceState mFreeCostVar; - - unsigned uMinTicks; - unsigned uMaxTicks; -} -TMStats; - - -int initOptions(Options* outOptions, int inArgc, char** inArgv) -/* -** returns int 0 if successful. -*/ -{ - int retval = 0; - int loop = 0; - int switchLoop = 0; - int match = 0; - const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]); - Switch* current = NULL; - - /* - ** Set any defaults. - */ - memset(outOptions, 0, sizeof(Options)); - outOptions->mProgramName = inArgv[0]; - outOptions->mInputName = strdup("-"); - outOptions->mOutput = stdout; - outOptions->mOutputName = strdup("stdout"); - outOptions->mAlignment = 16; - outOptions->mOverhead = 8; - - if(NULL == outOptions->mOutputName || NULL == outOptions->mInputName) - { - retval = __LINE__; - ERROR_REPORT(retval, "stdin/stdout", "Unable to strdup."); - } - - /* - ** Go through and attempt to do the right thing. - */ - for(loop = 1; loop < inArgc && 0 == retval; loop++) - { - match = 0; - current = NULL; - - for(switchLoop = 0; switchLoop < switchCount && 0 == retval; switchLoop++) - { - if(0 == strcmp(gSwitches[switchLoop]->mLongName, inArgv[loop])) - { - match = __LINE__; - } - else if(0 == strcmp(gSwitches[switchLoop]->mShortName, inArgv[loop])) - { - match = __LINE__; - } - - if(match) - { - if(gSwitches[switchLoop]->mHasValue) - { - /* - ** Attempt to absorb next option to fullfill value. - */ - if(loop + 1 < inArgc) - { - loop++; - - current = gSwitches[switchLoop]; - current->mValue = inArgv[loop]; - } - } - else - { - current = gSwitches[switchLoop]; - } - - break; - } - } - - if(0 == match) - { - outOptions->mHelp = __LINE__; - retval = __LINE__; - ERROR_REPORT(retval, inArgv[loop], "Unknown command line switch."); - } - else if(NULL == current) - { - outOptions->mHelp = __LINE__; - retval = __LINE__; - ERROR_REPORT(retval, inArgv[loop], "Command line switch requires a value."); - } - else - { - /* - ** Do something based on address/swtich. - */ - if(current == &gInputSwitch) - { - CLEANUP(outOptions->mInputName); - outOptions->mInputName = strdup(current->mValue); - if(NULL == outOptions->mInputName) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to strdup."); - } - } - else if(current == &gOutputSwitch) - { - CLEANUP(outOptions->mOutputName); - if(NULL != outOptions->mOutput && stdout != outOptions->mOutput) - { - fclose(outOptions->mOutput); - outOptions->mOutput = NULL; - } - - outOptions->mOutput = fopen(current->mValue, "a"); - if(NULL == outOptions->mOutput) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to open output file."); - } - else - { - outOptions->mOutputName = strdup(current->mValue); - if(NULL == outOptions->mOutputName) - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to strdup."); - } - } - } - else if(current == &gHelpSwitch) - { - outOptions->mHelp = __LINE__; - } - else if(current == &gAlignmentSwitch) - { - unsigned arg = 0; - char* endScan = NULL; - - errno = 0; - arg = strtoul(current->mValue, &endScan, 0); - if(0 == errno && endScan != current->mValue) - { - outOptions->mAlignment = arg; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to convert to a number."); - } - } - else if(current == &gOverheadSwitch) - { - unsigned arg = 0; - char* endScan = NULL; - - errno = 0; - arg = strtoul(current->mValue, &endScan, 0); - if(0 == errno && endScan != current->mValue) - { - outOptions->mOverhead = arg; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mValue, "Unable to convert to a number."); - } - } - else if(current == &gAveragesSwitch) - { - outOptions->mAverages = __LINE__; - } - else if(current == &gDeviationsSwitch) - { - outOptions->mAverages = __LINE__; - outOptions->mDeviances = __LINE__; - } - else if(current == &gRunLengthSwitch) - { - outOptions->mRunLength = __LINE__; - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, current->mLongName, "No handler for command line switch."); - } - } - } - - return retval; -} - - -void cleanOptions(Options* inOptions) -/* -** Clean up any open handles. -*/ -{ - unsigned loop = 0; - - CLEANUP(inOptions->mInputName); - CLEANUP(inOptions->mOutputName); - if(NULL != inOptions->mOutput && stdout != inOptions->mOutput) - { - fclose(inOptions->mOutput); - } - - memset(inOptions, 0, sizeof(Options)); -} - - -void showHelp(Options* inOptions) -/* -** Show some simple help text on usage. -*/ -{ - int loop = 0; - const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]); - const char* valueText = NULL; - - printf("usage:\t%s [arguments]\n", inOptions->mProgramName); - printf("\n"); - printf("arguments:\n"); - - for(loop = 0; loop < switchCount; loop++) - { - if(gSwitches[loop]->mHasValue) - { - valueText = " "; - } - else - { - valueText = ""; - } - - printf("\t%s%s\n", gSwitches[loop]->mLongName, valueText); - printf("\t %s%s", gSwitches[loop]->mShortName, valueText); - printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription); - } - - printf("This tool reports simple heap usage and allocation call counts.\n"); - printf("Useful for eyeballing trace-malloc numbers quickly.\n"); -} - - -void addVariance(VarianceState* inVariance, unsigned inValue) -/* -** Add a value to a variance state. -*/ -{ - uint64_t squared; - uint64_t bigValue; - - bigValue = inValue; - inVariance->mSum += bigValue; - - squared = bigValue * bigValue; - inVariance->mSquaredSum += squared; - - inVariance->mCount++; -} - - -double getAverage(VarianceState* inVariance) -/* -** Determine the mean/average based on the given state. -*/ -{ - double retval = 0.0; - - if(NULL != inVariance && 0 < inVariance->mCount) - { - double count; - int64_t isum; - - /* - ** Avoids a compiler error (not impl) under MSVC. - */ - isum = inVariance->mSum; - - count = (double)inVariance->mCount; - - retval = (double)isum / count; - } - - return retval; -} - - -double getVariance(VarianceState* inVariance) -/* -** Determine the variance based on the given state. -*/ -{ - double retval = 0.0; - - if(NULL != inVariance && 1 < inVariance->mCount) - { - double count; - double avg; - double squaredAvg; - int64_t isquaredSum; - - /* - ** Avoids a compiler error (not impl) under MSVC. - */ - isquaredSum = inVariance->mSquaredSum; - - count = (double)inVariance->mCount; - - avg = getAverage(inVariance); - squaredAvg = avg * avg; - - retval = ((double)isquaredSum - (count * squaredAvg)) / (count - 1.0); - } - - return retval; -} - - -double getStdDev(VarianceState* inVariance) -/* -** Determine the standard deviation based on the given state. -*/ -{ - double retval = 0.0; - double variance; - - variance = getVariance(inVariance); - retval = sqrt(variance); - - return retval; -} - - -unsigned actualByteSize(Options* inOptions, unsigned retval) -/* -** Apply alignment and overhead to size to figure out actual byte size. -** This by default mimics spacetrace with default options (msvc crt heap). -*/ -{ - if(0 != retval) - { - unsigned eval = 0; - unsigned over = 0; - - eval = retval - 1; - if(0 != inOptions->mAlignment) - { - over = eval % inOptions->mAlignment; - } - retval = eval + inOptions->mOverhead + inOptions->mAlignment - over; - } - - return retval; -} - - -uint32_t ticks2xsec(tmreader* aReader, uint32_t aTicks, uint32_t aResolution) -/* -** Convert platform specific ticks to second units -** Returns 0 on success. -*/ -{ - return (uint32_t)((aResolution * aTicks) / aReader->ticksPerSec); -} -#define ticks2msec(reader, ticks) ticks2xsec((reader), (ticks), 1000) - - -void tmEventHandler(tmreader* inReader, tmevent* inEvent) -/* -** Callback from the tmreader_eventloop. -** Keep it simple in here, this is where we'll spend the most time. -** The goal is to be fast. -*/ -{ - TMStats* stats = (TMStats*)inReader->data; - Options* options = (Options*)stats->mOptions; - char type = inEvent->type; - unsigned size = inEvent->u.alloc.size; - unsigned actualSize = 0; - unsigned actualOldSize = 0; - uint32_t interval = 0; - - /* - ** To match spacetrace stats, reallocs of size zero are frees. - ** Adjust the size to match what free expects. - */ - if(TM_EVENT_REALLOC == type && 0 == size) - { - type = TM_EVENT_FREE; - if(0 != inEvent->u.alloc.oldserial) - { - size = inEvent->u.alloc.oldsize; - } - } - - /* - ** Adjust the size due to the options. - */ - actualSize = actualByteSize(options, size); - if(TM_EVENT_REALLOC == type && 0 != inEvent->u.alloc.oldserial) - { - actualOldSize = actualByteSize(options, inEvent->u.alloc.oldsize); - } - - /* - ** Modify event specific data. - */ - switch(type) - { - case TM_EVENT_MALLOC: - stats->uMallocs++; - stats->uMallocSize += actualSize; - stats->uMallocCost += ticks2msec(inReader, inEvent->u.alloc.cost); - stats->uMemoryInUse += actualSize; - stats->uObjectsInUse++; - - addVariance(&stats->mMallocSizeVar, actualSize); - addVariance(&stats->mMallocCostVar, inEvent->u.alloc.cost); - break; - - case TM_EVENT_CALLOC: - stats->uCallocs++; - stats->uCallocSize += actualSize; - stats->uCallocCost += ticks2msec(inReader, inEvent->u.alloc.cost); - stats->uMemoryInUse += actualSize; - stats->uObjectsInUse++; - - addVariance(&stats->mCallocSizeVar, actualSize); - addVariance(&stats->mCallocCostVar, inEvent->u.alloc.cost); - break; - - case TM_EVENT_REALLOC: - stats->uReallocs++; - stats->uReallocSize -= actualOldSize; - stats->uReallocSize += actualSize; - stats->uReallocCost += ticks2msec(inReader, inEvent->u.alloc.cost); - stats->uMemoryInUse -= actualOldSize; - stats->uMemoryInUse += actualSize; - if(0 == inEvent->u.alloc.oldserial) - { - stats->uObjectsInUse++; - } - - if(actualSize > actualOldSize) - { - addVariance(&stats->mReallocSizeVar, actualSize - actualOldSize); - } - else - { - addVariance(&stats->mReallocSizeVar, actualOldSize - actualSize); - } - addVariance(&stats->mReallocCostVar, inEvent->u.alloc.cost); - break; - - case TM_EVENT_FREE: - stats->uFrees++; - stats->uFreeSize += actualSize; - stats->uFreeCost += ticks2msec(inReader, inEvent->u.alloc.cost); - stats->uMemoryInUse -= actualSize; - stats->uObjectsInUse--; - - addVariance(&stats->mFreeSizeVar, actualSize); - addVariance(&stats->mFreeCostVar, inEvent->u.alloc.cost); - break; - - default: - /* - ** Don't care. - */ - break; - } - - switch(type) - { - case TM_EVENT_MALLOC: - case TM_EVENT_CALLOC: - case TM_EVENT_REALLOC: - /* - ** Check the peaks. - */ - if(stats->uMemoryInUse > stats->uPeakMemory) - { - stats->uPeakMemory = stats->uMemoryInUse; - } - if(stats->uObjectsInUse > stats->uPeakObjects) - { - stats->uPeakObjects = stats->uObjectsInUse; - } - - /* - ** Falling through. - */ - - case TM_EVENT_FREE: - /* - ** Check the overall time. - */ - interval = ticks2msec(inReader, inEvent->u.alloc.interval); - if(stats->uMinTicks > interval) - { - stats->uMinTicks = interval; - } - if(stats->uMaxTicks < interval) - { - stats->uMaxTicks = interval; - } - break; - - default: - /* - ** Don't care. - */ - break; - } - -} - -int report_stats(Options* inOptions, TMStats* inStats) -{ - int retval = 0; - - fprintf(inOptions->mOutput, "Peak Memory Usage: %11d\n", inStats->uPeakMemory); - fprintf(inOptions->mOutput, "Memory Leaked: %11d\n", inStats->uMemoryInUse); - fprintf(inOptions->mOutput, "\n"); - - fprintf(inOptions->mOutput, "Peak Object Count: %11d\n", inStats->uPeakObjects); - fprintf(inOptions->mOutput, "Objects Leaked: %11d\n", inStats->uObjectsInUse); - if(0 != inOptions->mAverages && 0 != inStats->uObjectsInUse) - { - fprintf(inOptions->mOutput, "Average Leaked Object Size: %11.4f\n", (double)inStats->uMemoryInUse / (double)inStats->uObjectsInUse); - } - fprintf(inOptions->mOutput, "\n"); - - fprintf(inOptions->mOutput, "Call Total: %11d\n", inStats->uMallocs + inStats->uCallocs + inStats->uReallocs + inStats->uFrees); - fprintf(inOptions->mOutput, " malloc: %11d\n", inStats->uMallocs); - fprintf(inOptions->mOutput, " calloc: %11d\n", inStats->uCallocs); - fprintf(inOptions->mOutput, " realloc: %11d\n", inStats->uReallocs); - fprintf(inOptions->mOutput, " free: %11d\n", inStats->uFrees); - fprintf(inOptions->mOutput, "\n"); - - fprintf(inOptions->mOutput, "Byte Total (sans free): %11d\n", inStats->uMallocSize + inStats->uCallocSize + inStats->uReallocSize); - fprintf(inOptions->mOutput, " malloc: %11d\n", inStats->uMallocSize); - fprintf(inOptions->mOutput, " calloc: %11d\n", inStats->uCallocSize); - fprintf(inOptions->mOutput, " realloc: %11d\n", inStats->uReallocSize); - fprintf(inOptions->mOutput, " free: %11d\n", inStats->uFreeSize); - if(0 != inOptions->mAverages) - { - fprintf(inOptions->mOutput, "Byte Averages:\n"); - fprintf(inOptions->mOutput, " malloc: %11.4f\n", getAverage(&inStats->mMallocSizeVar)); - fprintf(inOptions->mOutput, " calloc: %11.4f\n", getAverage(&inStats->mCallocSizeVar)); - fprintf(inOptions->mOutput, " realloc: %11.4f\n", getAverage(&inStats->mReallocSizeVar)); - fprintf(inOptions->mOutput, " free: %11.4f\n", getAverage(&inStats->mFreeSizeVar)); - } - if(0 != inOptions->mDeviances) - { - fprintf(inOptions->mOutput, "Byte Standard Deviations:\n"); - fprintf(inOptions->mOutput, " malloc: %11.4f\n", getStdDev(&inStats->mMallocSizeVar)); - fprintf(inOptions->mOutput, " calloc: %11.4f\n", getStdDev(&inStats->mCallocSizeVar)); - fprintf(inOptions->mOutput, " realloc: %11.4f\n", getStdDev(&inStats->mReallocSizeVar)); - fprintf(inOptions->mOutput, " free: %11.4f\n", getStdDev(&inStats->mFreeSizeVar)); - } - fprintf(inOptions->mOutput, "\n"); - - fprintf(inOptions->mOutput, "Overhead Total: %11.4f\n", COST_PRINTABLE(inStats->uMallocCost) + COST_PRINTABLE(inStats->uCallocCost) + COST_PRINTABLE(inStats->uReallocCost) + COST_PRINTABLE(inStats->uFreeCost)); - fprintf(inOptions->mOutput, " malloc: %11.4f\n", COST_PRINTABLE(inStats->uMallocCost)); - fprintf(inOptions->mOutput, " calloc: %11.4f\n", COST_PRINTABLE(inStats->uCallocCost)); - fprintf(inOptions->mOutput, " realloc: %11.4f\n", COST_PRINTABLE(inStats->uReallocCost)); - fprintf(inOptions->mOutput, " free: %11.4f\n", COST_PRINTABLE(inStats->uFreeCost)); - if(0 != inOptions->mAverages) - { - fprintf(inOptions->mOutput, "Overhead Averages:\n"); - fprintf(inOptions->mOutput, " malloc: %11.4f\n", COST_PRINTABLE(getAverage(&inStats->mMallocCostVar))); - fprintf(inOptions->mOutput, " calloc: %11.4f\n", COST_PRINTABLE(getAverage(&inStats->mCallocCostVar))); - fprintf(inOptions->mOutput, " realloc: %11.4f\n", COST_PRINTABLE(getAverage(&inStats->mReallocCostVar))); - fprintf(inOptions->mOutput, " free: %11.4f\n", COST_PRINTABLE(getAverage(&inStats->mFreeCostVar))); - } - if(0 != inOptions->mDeviances) - { - fprintf(inOptions->mOutput, "Overhead Standard Deviations:\n"); - fprintf(inOptions->mOutput, " malloc: %11.4f\n", COST_PRINTABLE(getStdDev(&inStats->mMallocCostVar))); - fprintf(inOptions->mOutput, " calloc: %11.4f\n", COST_PRINTABLE(getStdDev(&inStats->mCallocCostVar))); - fprintf(inOptions->mOutput, " realloc: %11.4f\n", COST_PRINTABLE(getStdDev(&inStats->mReallocCostVar))); - fprintf(inOptions->mOutput, " free: %11.4f\n", COST_PRINTABLE(getStdDev(&inStats->mFreeCostVar))); - } - fprintf(inOptions->mOutput, "\n"); - - if(0 != inOptions->mRunLength) - { - unsigned length = inStats->uMaxTicks - inStats->uMinTicks; - - fprintf(inOptions->mOutput, "Run Length: %11.4f\n", COST_PRINTABLE(length)); - fprintf(inOptions->mOutput, "\n"); - } - - return retval; -} - - -int tmstats(Options* inOptions) -/* -** As quick as possible, load the input file and report stats. -*/ -{ - int retval = 0; - tmreader* tmr = NULL; - TMStats stats; - - memset(&stats, 0, sizeof(stats)); - stats.mOptions = inOptions; - stats.uMinTicks = 0xFFFFFFFFU; - - /* - ** Need a tmreader. - */ - tmr = tmreader_new(inOptions->mProgramName, &stats); - if(NULL != tmr) - { - int tmResult = 0; - - tmResult = tmreader_eventloop(tmr, inOptions->mInputName, tmEventHandler); - if(0 == tmResult) - { - retval = __LINE__; - ERROR_REPORT(retval, inOptions->mInputName, "Problem reading trace-malloc data."); - } - - tmreader_destroy(tmr); - tmr = NULL; - - if(0 == retval) - { - retval = report_stats(inOptions, &stats); - } - } - else - { - retval = __LINE__; - ERROR_REPORT(retval, inOptions->mProgramName, "Unable to obtain tmreader."); - } - - return retval; -} - - -int main(int inArgc, char** inArgv) -{ - int retval = 0; - Options options; - - retval = initOptions(&options, inArgc, inArgv); - if(options.mHelp) - { - showHelp(&options); - } - else if(0 == retval) - { - retval = tmstats(&options); - } - - cleanOptions(&options); - return retval; -} - diff --git a/tools/trace-malloc/types.dat b/tools/trace-malloc/types.dat deleted file mode 100644 index ba0a0e4defe3..000000000000 --- a/tools/trace-malloc/types.dat +++ /dev/null @@ -1,5842 +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/. - -# This file contains type inference information that is intended to be -# used with TraceMalloc.pm. The format of the file is: -# -# -# Stack1 -# Stack2 -# ... -# StackN -# -# Where Stack1...StackN imply that the object's type is -# InferredType. Note that in many cases, we'll ``roll up'' storage -# that's part of an object's implementation into the object itself. - -# Here's a handy regexp for cleaning up strings copied from the -# uncategorized file: -# -# \(^ *([0-9]+) \|\[.*\]$\) -# - -#---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -nsDeque::GrowCapacity(void) -nsDeque::Push(void *) -nsStringRecycler::Recycle(nsString *) - -#---------------------------------------------------------------------- -# -# AtomImpl -# - -# Give AtomImpl objects the memory they allocate for storage - -__builtin_new -AtomImpl::operator new(unsigned int, basic_nsAReadableString const &) - -# Give AtomImpl objects the memory allocated for their table - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -NS_NewPermanentAtom(char const *) -NS_NewAtom(nsAString const &) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -NS_NewAtom(nsAString const &) -NS_NewAtom(char const *) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -NS_NewAtom(nsAString const &) -NS_NewAtom(unsigned short const *) - -#---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - - -__builtin_new -nsCSSRule::operator new(unsigned int) - -#---------------------------------------------------------------------- -# -# CSSLoaderImpl -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -CSSLoaderImpl::CSSLoaderImpl(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsString::AppendWithConversion(char const *, int) -nsString::AssignWithConversion(char const *) -CSSLoaderImpl::SetCharset(nsString const &) - - -PL_strdup -URLKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -CSSLoaderImpl::SheetComplete(nsICSSStyleSheet *, SheetLoadData *) - -#---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -CSSNameSpaceRuleImpl::SetURLSpec(nsString const &) - -#---------------------------------------------------------------------- -# -# nsFont -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -nsFont::nsFont(nsFont const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsString::AppendWithConversion(char const *, int) -nsString::AssignWithConversion(char const *) -nsFont::nsFont(char const *, unsigned char, unsigned char, unsigned short, unsigned char, int, float) - -#---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -CSSImportRuleImpl::SetURLSpec(nsString const &) - - -__builtin_new -nsClassList::ParseClasses(nsClassList **, basic_nsAReadableString const &) - -# ---------------------------------------------------------------------- -# -# nsLocalFile -# - - -__builtin_new -nsLocalFile::Clone(nsIFile **) - - -PR_Malloc -_PR_Getfd -PR_GetConnectStatus -PR_OpenFile -PR_Open -nsLocalFile::OpenNSPRFileDesc(int, int, PRFileDesc **) - - -PR_Calloc -PR_LoadLibrary -PR_LoadLibraryWithFlags -PR_LoadLibrary -nsLocalFile::Load(PRLibrary **) - - -__strdup -PR_LoadLibrary -PR_LoadLibraryWithFlags -PR_LoadLibrary -nsLocalFile::Load(PRLibrary **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsACString const &) -nsLocalFile::AppendRelativePath(char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Clone(void const *, unsigned int) -nsLocalFile::InitWithPath(char const *) - - -PL_strdup -nsLocalFile::ParseURL(char const *, char **, char **, char **, char **) - -# ---------------------------------------------------------------------- - - -__builtin_new -nsXULAttribute::operator new(unsigned int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsXULAttributeValue::SetValue(nsAString const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsXULAttributeValue::SetValue(nsAString const &, int) - - -__builtin_new -nsXULAttributes::Create(nsIContent *, nsXULAttributes **) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -NS_NewAtom(nsAString const &) -NS_NewAtom(unsigned short const *) -nsClassList::ParseClasses(nsClassList **, nsAString const &) -nsXULAttributes::UpdateClassList(nsAString const &) - - -__builtin_new -nsXULElement::Create(nsINodeInfo *, nsIContent **) - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULElement::EnsureSlots(void) - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULElement::AppendChildTo(nsIContent *, int, int) - - -__builtin_new -nsXULElement::EnsureSlots(void) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULElement::AppendChildTo(nsIContent *, int, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULElement::EnsureSlots(void) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULElement::AddBroadcastListener(nsAString const &, nsIDOMElement *) - - -iconv_close - - -tsearch - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -CSSDeclarationImpl::AppendValue(nsCSSProperty, nsCSSValue const &) - - -__builtin_new -CSSDeclarationImpl::AppendValue(nsCSSProperty, nsCSSValue const &) - - -__builtin_new -CSSDeclarationImpl::SetValueImportant(nsCSSProperty) - - -__builtin_new -CSSDeclarationImpl::operator new(unsigned int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -CSSDeclarationImpl::AppendValue(nsCSSProperty, nsCSSValue const &) - - -__builtin_new -__builtin_vec_new -nsVoidArray::InsertElementAt(void *, int) - - -__builtin_new -__builtin_vec_new -nsVoidArray::nsVoidArray(int) - - -__builtin_new -__builtin_vec_new -nsVoidArray::Compact(void) - - -__builtin_new -__builtin_vec_new -nsVoidArray::ReplaceElementAt(void *, int) - - -__builtin_new -nsCheapVoidArray::SwitchToVector(void) -nsCheapVoidArray::AppendElement(void *) -nsGenericHTMLContainerElement::AppendChildTo(nsIContent *, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::Compact(void) -nsAutoVoidArray::Compact(void) -nsCheapVoidArray::Compact(void) -nsGenericHTMLContainerElement::Compact(void) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsCheapVoidArray::AppendElement(void *) -nsGenericHTMLContainerElement::AppendChildTo(nsIContent *, int, int) - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsCheapVoidArray::AppendElement(void *) -nsGenericHTMLContainerElement::AppendChildTo(nsIContent *, int, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::nsString(basic_nsAReadableString const &) -nsGenericAttribute::nsGenericAttribute(nsINodeInfo *, basic_nsAReadableString const &) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) - - -__builtin_new -nsSupportsArray::Create(nsISupports *, nsID const &, void **) - - -__builtin_new -__builtin_vec_new -nsZipArchive::BuildFileList(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsZipReaderCache::GetZip(nsIFile *, nsIZipReader **) - - -__builtin_new -__builtin_vec_new -InMemoryDataSource::AllocTable(void *, unsigned int) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -InMemoryDataSource::LockedAssert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -InMemoryDataSource::InMemoryDataSource(nsISupports *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -InMemoryDataSource::AllocEntry(void *, void const *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -Assertion::operator new(unsigned int, nsFixedSizeAllocator &) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -InMemoryDataSource::AllocEntry(void *, void const *) -PL_HashTableRawAdd -PL_HashTableAdd -InMemoryDataSource::SetReverseArcs(nsIRDFNode *, Assertion *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -InMemoryDataSource::AllocEntry(void *, void const *) -PL_HashTableRawAdd -PL_HashTableAdd -InMemoryDataSource::SetForwardArcs(nsIRDFResource *, Assertion *) - - -PL_DHashAllocTable -PL_DHashTableInit -InMemoryDataSource::Init(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsString::nsString(nsAString const &) -nsNameSpaceMap::Put(nsAString const &, nsIAtom *) -RDFXMLDataSourceImpl::AddNameSpace(nsIAtom *, nsString const &) - - -__builtin_new -__builtin_vec_new -xptiTypelibGuts::xptiTypelibGuts(XPTHeader *) - -# ---------------------------------------------------------------------- -# -# nsPluginTag -# - - -__builtin_new -__builtin_vec_new -nsPluginTag::nsPluginTag(nsPluginInfo *) - - -__builtin_new -__builtin_vec_new -new_str(char const *) -nsPluginTag::nsPluginTag(nsPluginInfo *) - - -__builtin_new -__builtin_vec_new -nsPluginTag::nsPluginTag(char const *, char const *, char const *, char const *, char const *const *, char const *const *, char const *const *, int, long long) - - -__builtin_new -__builtin_vec_new -nsPluginTag::nsPluginTag(nsPluginTag *) - -#---------------------------------------------------------------------- -# -# nsXBLInsertionPoint -# - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsXBLInsertionPoint::AddChild(nsIContent *) - -#---------------------------------------------------------------------- -# -# nsXBLBinding -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLBinding::GetInsertionPointsFor(nsIContent *, nsISupportsArray **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLBinding::GetInsertionPointsFor(nsIContent *, nsISupportsArray **) - - -__builtin_new -nsXBLBinding::GetInsertionPointsFor(nsIContent *, nsISupportsArray **) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -NS_NewAtom(nsAString const &) -NS_NewAtom(char const *) -nsXBLBinding::nsXBLBinding(nsIXBLPrototypeBinding *) - -# ---------------------------------------------------------------------- -# -# nsXBLPrototypeBinding -# - - -__builtin_new -nsXBLPrototypeBinding::InitClass(nsCString const &, nsIScriptContext *, void *, void **) - - -__builtin_new -nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -js_LookupProperty -JS_DefinePropertyWithTinyId -JS_LookupProperty -nsXBLPrototypeBinding::InitClass(nsCString const &, nsIScriptContext *, void *, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsXBLPrototypeBinding::nsXBLPrototypeBinding(nsCString const &, nsIContent *, nsXBLDocumentInfo *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsXBLPrototypeBinding::nsXBLPrototypeBinding(basic_nsAReadableString const &, nsIContent *, nsXBLDocumentInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - - -__builtin_new -nsISupportsKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - - -__builtin_new -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsXBLPrototypeBinding::nsXBLPrototypeBinding(nsACString const &, nsXBLDocumentInfo *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsXBLPrototypeBinding::InitClass(nsCString const &, nsIScriptContext *, void *, void **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AssignFromReadable(nsACString const &) -nsACString::AssignFromReadable(nsACString const &) -nsCString::nsCString(nsACString const &) -nsXBLPrototypeBinding::nsXBLPrototypeBinding(nsACString const &, nsXBLDocumentInfo *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsACString const &) -nsXBLJSClass::nsXBLJSClass(nsCString const &) -nsXBLPrototypeBinding::InitClass(nsCString const &, nsIScriptContext *, void *, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLPrototypeBinding::ConstructInterfaceTable(nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsXBLPrototypeBinding::InitClass(nsCString const &, nsIScriptContext *, void *, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLPrototypeBinding::ConstructInterfaceTable(nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsXBLAttributeEntry::Create(nsIAtom *, nsIAtom *, nsIContent *) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - -#---------------------------------------------------------------------- -# -# -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsIAtom *&, nsAString &) const -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsAString &) const -nsXBLPrototypeProperty::ParseProperty(nsIScriptContext *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsIAtom *&, nsAString &) const -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsAString &) const -nsXBLPrototypeProperty::ParseMethod(nsIScriptContext *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsIAtom *&, nsAString &) const -nsGenericContainerElement::GetAttr(int, nsIAtom *, nsAString &) const -nsXBLPrototypeProperty::ParseField(nsIScriptContext *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AppendFromReadable(nsAString const &) -nsAString::AppendFromReadable(nsAString const &) -nsXBLPrototypeProperty::ParseField(nsIScriptContext *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AppendFromReadable(nsACString const &) -nsACString::do_AppendFromElementPtr(char const *) -nsXBLPrototypeBinding::GetBindingURI(nsCString &) -nsXBLPrototypeProperty::ConstructProperty(nsIContent *, nsIContent *) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -js_AddRootRT -JS_AddNamedRootRT -NS_NewXBLPrototypeBinding(nsACString const &, nsIContent *, nsXBLDocumentInfo *, nsIXBLPrototypeBinding **) -nsXBLPrototypeProperty::ParseMethod(nsIScriptContext *) - -# ---------------------------------------------------------------------- -# -# The frame arena -# - - -PR_Malloc -PL_ArenaAllocate -FrameArena::AllocateFrame(unsigned int, void **) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocLeafNode(void) -nsDST::Insert(void *, void *, void **) -PresShell::SetSubShellFor(nsIContent *, nsISupports *) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -PresShell::AppendReflowCommandInternal(nsIReflowCommand *, nsVoidArray &) - -# The anonymous content table in the PresShell - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -PresShell::SetAnonymousContentFor(nsIContent *, nsISupportsArray *) - - -__builtin_new -nsISupportsKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -PresShell::SetAnonymousContentFor(nsIContent *, nsISupportsArray *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -PresShell::SetAnonymousContentFor(nsIContent *, nsISupportsArray *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -PresShell::SetAnonymousContentFor(nsIContent *, nsISupportsArray *) - -# ---------------------------------------------------------------------- -# -# StackArena -# - - -PR_Malloc -StackArena::StackArena(void) - - -PR_Malloc -StackArena::Allocate(unsigned int, void **) - - -PR_Malloc -StackBlock::StackBlock(void) -StackArena::StackArena(void) - - -__builtin_new -__builtin_vec_new -StackArena::StackArena(void) - - -PR_Malloc -StackArena::Allocate(unsigned int, void **) - -# The following will only show up if you turn off the FrameArena - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsBoxLayoutState::Allocate(unsigned int, nsIPresShell *) - - -# ---------------------------------------------------------------------- -# -# nsFrameManager -# - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocLeafNode(void) -nsDST::LeafNode::operator new(unsigned int, nsDST::NodeArena *) -nsDST::Insert(void *, void *, void **) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocTwoNode(void) -nsDST::ConvertToTwoNode(nsDST::LeafNode **) -nsDST::Insert(void *, void *, void **) -FrameManager::SetFrameProperty(nsIFrame *, nsIAtom *, void *, void (*)(nsIPresContext *, nsIFrame *, nsIAtom *, void *)) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocTwoNode(void) -nsDST::TwoNode::operator new(unsigned int, nsDST::NodeArena *) -nsDST::ConvertToTwoNode(nsDST::LeafNode **) -nsDST::Insert(void *, void *, void **) -FrameManager::SetPrimaryFrameFor(nsIContent *, nsIFrame *) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocTwoNode(void) -nsDST::TwoNode::operator new(unsigned int, nsDST::NodeArena *) -nsDST::ConvertToTwoNode(nsDST::LeafNode **) -nsDST::Insert(void *, void *, void **) -FrameManager::SetFrameProperty(nsIFrame *, nsIAtom *, void *, void (*)(nsIPresContext *, nsIFrame *, nsIAtom *, void *)) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -FrameHashTable::Put(void *, void *) -FrameManager::SetPlaceholderFrameFor(nsIFrame *, nsIFrame *) - - -__builtin_new -nsDST::NewMemoryArena(unsigned int) -FrameManager::Init(nsIPresShell *, nsIStyleSet *) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocTwoNode(void) -nsDST::ConvertToTwoNode(nsDST::LeafNode **) -nsDST::Insert(void *, void *, void **) -FrameManager::SetPrimaryFrameFor(nsIContent *, nsIFrame *) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocLeafNode(void) -nsDST::Insert(void *, void *, void **) -FrameManager::SetFrameProperty(nsIFrame *, nsIAtom *, void *, void (*)(nsIPresContext *, nsIFrame *, nsIAtom *, void *)) - - -PR_Malloc -PL_ArenaAllocate -nsDST::NodeArena::AllocLeafNode(void) -nsDST::Insert(void *, void *, void **) -FrameManager::SetPrimaryFrameFor(nsIContent *, nsIFrame *) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -UndisplayedMap::AppendNodeFor(UndisplayedNode *, nsIContent *) - - -__builtin_new -UndisplayedMap::AddNodeFor(nsIContent *, nsIContent *, nsIStyleContext *) - - -PR_Malloc -PL_ArenaFinish -PL_NewHashTable -UndisplayedMap::UndisplayedMap(unsigned int) - - -PR_Calloc -PR_NewLock - - -PR_Calloc -PR_NewMonitor - -# ---------------------------------------------------------------------- -# -# RDFServiceImpl -# - - -PR_Malloc -PL_ArenaFinish -PL_NewHashTable -RDFServiceImpl::Init(void) - - -PR_Malloc -nsRDFParserUtils::GetQuotedAttributeValue(nsString const &, nsString const &, nsString &) -PL_HashTableRawAdd -PL_HashTableAdd -RDFServiceImpl::RegisterDataSource(nsIRDFDataSource *, int) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -RDFServiceImpl::RegisterResource(nsIRDFResource *, int) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -PL_HashTableAdd -RDFServiceImpl::RegisterLiteral(nsIRDFLiteral *, int) - - -PR_Malloc -nsRDFParserUtils::IsJavaScriptLanguage(nsString const &, char const **) -PL_NewHashTable -RDFServiceImpl::Init(void) - - -PR_Malloc -nsRDFParserUtils::IsJavaScriptLanguage(nsString const &, char const **) -PL_HashTableRawAdd -PL_HashTableAdd -RDFServiceImpl::RegisterDataSource(nsIRDFDataSource *, int) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawRemove -RDFServiceImpl::UnregisterResource(nsIRDFResource *) - - -PL_strdup -RDFServiceImpl::RegisterDataSource(nsIRDFDataSource *, int) - -# ---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsRDFResource::Init(char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::operator=(nsString const &) -nsHTMLImageLoader::SetURL(nsString const &) - - -__builtin_new -__builtin_vec_new -nsHTMLEntities::AddRefTable(void) - - -__builtin_new -nsAVLTree::AddItem(void *) -nsHTMLEntities::AddRefTable(void) - - -__builtin_new -__builtin_vec_new -nsStaticCaseInsensitiveNameTable::Init(char const **, int) - - -__builtin_new -CNavDTD::CNavDTD(void) - - -__builtin_new -__builtin_vec_new -InitializeElementTable(void) -CNavDTD::CNavDTD(void) - - -__builtin_new -__builtin_vec_new -nsDeque::GrowCapacity(void) -nsDeque::Push(void *) -CNodeRecycler::RecycleNode(nsCParserNode *) -CNavDTD::CloseContainersTo(int, nsHTMLTag, int) - - -__builtin_new -COtherDTD::COtherDTD(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsScanner::Append(char const *, unsigned int) - - -__builtin_new -nsSlidingString::AppendBuffer(unsigned short *, unsigned short *, unsigned short *) -nsScanner::AppendToBuffer(unsigned short *, unsigned short *, unsigned short *) - - -__builtin_new -nsScanner::AppendToBuffer(unsigned short *, unsigned short *, unsigned short *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(basic_nsAReadableString const &, unsigned short *) -ToNewUnicode(basic_nsAReadableString const &) -nsScanner::Append(basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -CopyUnicodeTo(nsReadingIterator const &, nsReadingIterator const &, basic_nsAWritableString &) -nsScanner::CopyUnusedData(nsString &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -nsScanner::nsScanner(nsString &, int, nsString const &, nsCharsetSource) - - -__builtin_new -__builtin_vec_new -nsDeque::GrowCapacity(void) -nsDeque::Push(void *) -nsHTMLTokenizer::ScanDocStructure(int) - - -__builtin_new -__builtin_vec_new -nsDeque::GrowCapacity(void) -nsDeque::Push(void *) -nsHTMLTokenizer::AddToken(CToken *&, unsigned int, nsDeque *, nsTokenAllocator *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -CToken::operator new(unsigned int, nsFixedSizeAllocator &) -nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes, nsHTMLTag) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsNodeAllocator::nsNodeAllocator(void) - -# ---------------------------------------------------------------------- -# -# xptiWorkingSet -# - - -__builtin_new -__builtin_vec_new -xptiWorkingSet::NewFileArray(unsigned int) - - -__builtin_new -__builtin_vec_new -xptiWorkingSet::ExtendFileArray(unsigned int) - -# ---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -HTMLContentSink::OnStreamComplete(nsIStreamLoader *, nsISupports *, unsigned int, unsigned int, char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -HTMLContentSink::SetTitle(nsString const &) - - -__builtin_new -__builtin_vec_new -DeviceContextImpl::DeviceContextImpl(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -DeviceContextImpl::CreateFontAliasTable(void) - - -__builtin_new -FontAliasKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -DeviceContextImpl::AliasFont(nsString const &, nsString const &, nsString const &, int) - - -__builtin_new -__builtin_vec_new -nsCompressedMap::nsCompressedMap(unsigned short *, unsigned int) - - -__builtin_new -__builtin_vec_new -nsHTMLDocument::nsHTMLDocument(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsHTMLDocument::nsHTMLDocument(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsHTMLDocument::InvalidateHashTables(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::nsString(basic_nsAReadableString const &) -nsHTMLDocument::SetReferrer(basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::nsString(basic_nsAReadableString const &) -nsHTMLDocument::SetLastModified(basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::nsString(basic_nsAReadableString const &) -nsHTMLDocument::SetTitle(basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsString::nsString(nsAString const &) -mozilla::dom::DocumentType::DocumentType(nsAString const &, nsIDOMNamedNodeMap *, nsIDOMNamedNodeMap *, nsAString const &, nsAString const &, nsAString const &) - -#---------------------------------------------------------------------- -# -# XPC stuff -# - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -Native2WrappedNativeMap::Native2WrappedNativeMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -IID2NativeInterfaceMap::IID2NativeInterfaceMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -IID2WrappedJSClassMap::IID2WrappedJSClassMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -IID2ThisTranslatorMap::IID2ThisTranslatorMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int) - - -__builtin_new -XPCNativeScriptableSharedMap::GetNewOrUsed(unsigned int, char *, XPCNativeScriptableInfo *) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -JSContext2XPCContextMap::JSContext2XPCContextMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -NativeSetMap::NativeSetMap(int) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -JSObject2WrappedJSMap::JSObject2WrappedJSMap(int) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -nsXPCWrappedJS::GetNewOrUsed(XPCCallContext &, JSObject *, nsID const &, nsISupports *, nsXPCWrappedJS **) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext &, XPCWrappedNativeScope *, nsIClassInfo *, XPCNativeScriptableCreateInfo const *, int) - - -__builtin_new -XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext &, XPCWrappedNativeScope *, nsIClassInfo *, XPCNativeScriptableCreateInfo const *, int) - - -__builtin_new -__builtin_vec_new -XPCNativeSet::NewInstance(XPCCallContext &, XPCNativeInterface **, unsigned short) -XPCNativeSet::GetNewOrUsed(XPCCallContext &, nsIClassInfo *) -XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext &, XPCWrappedNativeScope *, nsIClassInfo *, XPCNativeScriptableCreateInfo const *, int) - - -__builtin_new -XPCNativeScriptableInfo::Construct(XPCCallContext &, XPCNativeScriptableCreateInfo const *) -XPCWrappedNativeProto::Init(XPCCallContext &, XPCNativeScriptableCreateInfo const *) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCNativeSet::GetNewOrUsed(XPCCallContext &, nsIClassInfo *) -XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext &, XPCWrappedNativeScope *, nsIClassInfo *, XPCNativeScriptableCreateInfo const *, int) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCWrappedNative::~XPCWrappedNative(void) - - -__builtin_new -XPCWrappedNative::FindTearOff(XPCCallContext &, XPCNativeInterface *, int, unsigned int *) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCWrappedNative::GetNewOrUsed(XPCCallContext &, nsISupports *, XPCWrappedNativeScope *, XPCNativeInterface *, XPCWrappedNative **) - - -JS_DHashAllocTable -JS_DHashTableInit -JS_NewDHashTable -js_LookupProperty -js_GetProperty -XPCWrappedNativeScope::SetGlobal(XPCCallContext &, JSObject *) - - -__builtin_new -__builtin_vec_new -nsXPCWrappedNativeClass::BuildMemberDescriptors(XPCContext *) - -#---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -nsNetModRegEntry::nsNetModRegEntry(char const *, nsINetNotify *, unsigned int *) -nsNetModuleMgr::RegisterModule(char const *, nsINetNotify *) - - -__builtin_new -nsProxyObjectManager::nsProxyObjectManager(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsProxyObjectManager::nsProxyObjectManager(void) - - -__builtin_new -__builtin_vec_new -nsProxyEventClass::nsProxyEventClass(nsID const &, nsIInterfaceInfo *) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsProxyEventClass::nsProxyEventClass(nsID const &, nsIInterfaceInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsProxyEventClass::nsProxyEventClass(nsID const &, nsIInterfaceInfo *) - - -__builtin_new -nsProxyEventKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *, int, nsISupports *, nsID const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *, int, nsISupports *, nsID const &) - -# ---------------------------------------------------------------------- -# -# nsComponentManagerImpl -# - - -__builtin_new -nsComponentManagerImpl::Init(void) - - -__builtin_new -nsComponentManagerImpl::GetServiceByContractID(char const *, nsID const &, void **) - - -__builtin_new -nsComponentManagerImpl::GetService(nsID const &, nsID const &, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsComponentManagerImpl::Init(void) - - -__builtin_vec_new -nsComponentManagerImpl::Init(void) - - -__builtin_new -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -__builtin_new -nsComponentManagerImpl::RegisterFactory(nsID const &, char const *, char const *, nsIFactory *, int) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::HashContractID(char const *, nsID const &) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsComponentManagerImpl::Init(void) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsComponentManagerImpl::GetLoaderForType(char const *, nsIComponentLoader **) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::ContractIDToClassID(char const *, nsID *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsComponentManagerImpl::RegisterFactory(nsID const &, char const *, char const *, nsIFactory *, int) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::RegisterFactory(nsID const &, char const *, char const *, nsIFactory *, int) - - -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -PR_Malloc -bufio_SetBufferSize -nsXPTCStubBase::Sentinel9(void) -NR_RegSetBufferSize -nsRegistry::SetBufferSize(int) -nsComponentManagerImpl::AutoRegister(int, nsIFile *) - - -__builtin_new -nsComponentManagerImpl::HashContractID(char const *, nsID const &) - - -__builtin_new -nsComponentManagerImpl::RegisterComponentCommon(nsID const &, char const *, char const *, char const *, int, int, char const *) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::RegisterComponentCommon(nsID const &, char const *, char const *, char const *, int, int, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::HashContractID(char const *, nsID const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::RegisterFactory(nsID const &, char const *, char const *, nsIFactory *, int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::ContractIDToClassID(char const *, nsID *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::HashContractID(char const *, nsFactoryEntry *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsComponentManagerImpl::HashContractID(char const *, nsFactoryEntry *) - - -__builtin_new -nsComponentManagerImpl::GetService(char const *, nsID const &, nsISupports **, nsIShutdownListener *) - - -__builtin_new -nsComponentManagerImpl::GetService(nsID const &, nsID const &, nsISupports **, nsIShutdownListener *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AssignFromReadable(nsACString const &) -nsACString::do_AssignFromElementPtr(char const *) -nsCString::nsCString(char const *) -nsFactoryEntry::nsFactoryEntry(nsID const &, char const *, int) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -PL_strdup -nsComponentManagerImpl::HashContractID(char const *, nsFactoryEntry *) - - -PL_strdup -nsFactoryEntry::nsFactoryEntry(nsID const &, char const *, int) -nsComponentManagerImpl::PlatformPrePopulateRegistry(void) - - -PL_DHashAllocTable -PL_DHashTableInit -nsComponentManagerImpl::Init(void) - -# ---------------------------------------------------------------------- - - -__builtin_new -nsZipArchive::BuildFileList(void) - - -__builtin_new -nsStaticCaseInsensitiveNameTable::Init(char const **, int) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsStaticCaseInsensitiveNameTable::Init(char const **, int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsStaticCaseInsensitiveNameTable::Init(char const **, int) - -# ---------------------------------------------------------------------- -# -# nsDrawingSurfaceGTK -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsDrawingSurfaceGTK::Init(_GdkGC *, unsigned int, unsigned int, unsigned int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsDrawingSurfaceGTK::Init(_GdkGC *, unsigned int, unsigned int, unsigned int) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsDrawingSurfaceGTK type_info function - - -PR_Malloc -nsDrawingSurfaceGTK::Init(_GdkGC *, unsigned int, unsigned int, unsigned int) - -# ---------------------------------------------------------------------- -# -# nsNativeComponentLoader -# - - -__builtin_new -nsNativeComponentLoader::Init(nsIComponentManager *, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsNativeComponentLoader::Init(nsIComponentManager *, nsISupports *) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsNativeComponentLoader::CreateDll - - -__builtin_new -nsNativeComponentLoader::CreateDll(nsIFile *, char const *, long long *, long long *, nsDll **) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsNativeComponentLoader::CreateDll(nsIFile *, char const *, long long *, long long *, nsDll **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsNativeComponentLoader::CreateDll(nsIFile *, char const *, long long *, long long *, nsDll **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsNativeComponentLoader::CreateDll(nsIFile *, char const *, long long *, long long *, nsDll **) - - -PL_strdup -nsDll::nsDll(nsIFile *, char const *, long long *, long long *) -nsNativeComponentLoader::CreateDll(nsIFile *, char const *, long long *, long long *, nsDll **) - -# ---------------------------------------------------------------------- - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsDirectoryService::Set(char const *, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsDirectoryService::Init(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsDirectoryService::Set(char const *, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsDirectoryService::Init(char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsDirectoryService::Init(void) - -#---------------------------------------------------------------------- -# -# nsResProtocolHandler -# - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsResProtocolHandler::AppendSubstitution(char const *, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsResProtocolHandler::nsResProtocolHandler(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsResProtocolHandler::AppendSubstitution(char const *, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsResProtocolHandler::SetSubstitution(char const *, nsIURI *) - -# ---------------------------------------------------------------------- -# -# nsChromeRegistry -# - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsChromeRegistry::LoadDataSource(nsCString const &, nsIRDFDataSource **, int, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsChromeRegistry::LoadDataSource(nsCString const &, nsIRDFDataSource **, int, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsChromeRegistry::LoadDataSource(nsCString const &, nsIRDFDataSource **, int, char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsACString const &) -nsStdURL::GetSpec(char **) -RDFXMLDataSourceImpl::Init(char const *) -nsChromeRegistry::LoadDataSource(nsCString const &, nsIRDFDataSource **, int, char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsChromeRegistry::LoadDataSource(nsCString const &, nsIRDFDataSource **, int, char const *) - -# ---------------------------------------------------------------------- - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsZipReaderCache::GetZip(nsIFile *, nsIZipReader **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsZipReaderCache::GetZip(nsIFile *, nsIZipReader **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsZipReaderCache::nsZipReaderCache(void) - - -__builtin_new -nsZipReaderCache::GetZip(nsIFile *, nsIZipReader **) - -# ---------------------------------------------------------------------- -# -# nsXBLDocumentInfo -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLDocumentInfo::SetPrototypeBinding(nsACString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLDocumentInfo::SetPrototypeBinding(nsACString const &, nsIXBLPrototypeBinding *) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLDocumentInfo::SetPrototypeBinding(nsCString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLDocumentInfo::SetPrototypeBinding(basic_nsAReadableString const &, nsIXBLPrototypeBinding *) - - -__builtin_new -nsXBLDocumentInfo::SetPrototypeBinding(nsCString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLDocumentInfo::SetPrototypeBinding(nsCString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsXBLDocumentInfo::SetPrototypeBinding(basic_nsAReadableString const &, nsIXBLPrototypeBinding *) - - -__builtin_new -nsXBLDocumentInfo::SetPrototypeBinding(basic_nsAReadableString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(char const *) -nsCString::operator=(char const *) -nsXBLDocumentInfo::nsXBLDocumentInfo(char const *, nsIDocument *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXBLDocumentInfo::SetPrototypeBinding(nsACString const &, nsIXBLPrototypeBinding *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AssignFromReadable(nsACString const &) -nsACString::do_AssignFromElementPtr(char const *) -nsXBLDocumentInfo::nsXBLDocumentInfo(char const *, nsIDocument *) - - -__builtin_new -nsXBLDocumentInfo::SetPrototypeBinding(nsACString const &, nsIXBLPrototypeBinding *) - -# ---------------------------------------------------------------------- -# -# nsXULPrototypeCache -# - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULPrototypeCache::PutXBLDocumentInfo(nsXBLDocumentInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULPrototypeCache::PutPrototype(nsIXULPrototypeDocument *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXULPrototypeCache::nsXULPrototypeCache(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULPrototypeCache::PutXBLDocumentInfo(nsXBLDocumentInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsXULPrototypeCache::nsXULPrototypeCache(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULPrototypeCache::PutXBLDocumentInfo(nsXBLDocumentInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsXULPrototypeCache::PutScript(nsIURI *, void *) - -# nsXULPrototypeElement - -__builtin_new -XULContentSinkImpl::CreateElement(nsINodeInfo *, nsXULPrototypeElement **) - -# nsXULPrototypeNode - -__builtin_new -__builtin_vec_new -XULContentSinkImpl::CloseContainer(nsIParserNode const &) - -# nsXULPrototypeScript - -__builtin_new -XULContentSinkImpl::OpenScript(nsIParserNode const &) - -# ---------------------------------------------------------------------- -# -# nsExternalHelperAppService -# - - -__builtin_new -nsExternalHelperAppService::nsExternalHelperAppService(void) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsExternalHelperAppService::AddMimeInfoToCache(nsIMIMEInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsExternalHelperAppService::AddMimeInfoToCache(nsIMIMEInfo *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsExternalHelperAppService::AddMimeInfoToCache(nsIMIMEInfo *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsExternalHelperAppService::AddMimeInfoToCache(nsIMIMEInfo *) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsTArray::InsertElementAt(int, nsCString const &) -nsMIMEInfoImpl::SetFileExtensions(char const *) -nsExternalHelperAppService::AddDefaultMimeTypesToCache(void) - -# ---------------------------------------------------------------------- -# -# nsCategoryManager -# - - -__builtin_new -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -CategoryNode::CategoryNode(void) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -nsCategoryManager::nsCategoryManager(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -CategoryNode::CategoryNode(void) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -nsCategoryManager::nsCategoryManager(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AssignFromReadable(nsACString const &) -nsACString::do_AssignFromElementPtr(char const *) -nsCString::nsCString(char const *) -nsCategoryManager::AddCategoryEntry(char const *, char const *, char const *, int, int, char **) - -# ---------------------------------------------------------------------- -# -# nsScriptNameSpaceManager -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsScriptNameSpaceManager::RegisterClassName(char const *, int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsScriptNameSpaceManager::FillHashWithDOMInterfaces(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsScriptNameSpaceManager::FillHash(nsICategoryManager *, char const *, nsGlobalNameStruct::nametype) - - -__builtin_new -nsScriptNameSpaceManager::RegisterClassName(char const *, int) - -# ---------------------------------------------------------------------- -# -# nsScriptSecurityManager -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsScriptSecurityManager::InitPolicies(unsigned int, char const **, nsISecurityPref *) - - -__builtin_new -nsScriptSecurityManager::EnumeratePolicyCallback(char const *, void *) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsScriptSecurityManager::EnumeratePolicyCallback(char const *, void *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsScriptSecurityManager::InitPrefs(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -nsScriptSecurityManager::EnumeratePolicyCallback(char const *, void *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsScriptSecurityManager::InitPolicies(unsigned int, char const **, nsISecurityPref *) - -# ---------------------------------------------------------------------- -# -# nsStringBundleService -# - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsStringBundleService::insertIntoCache(nsIStringBundle *, nsCStringKey *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsStringBundleService::insertIntoCache(nsIStringBundle *, nsCStringKey *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsStringBundleService::nsStringBundleService(void) - - -PR_Malloc -PL_ArenaAllocate -nsStringBundleService::insertIntoCache(nsIStringBundle *, nsCStringKey *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsStringBundleService::insertIntoCache(nsIStringBundle *, nsCStringKey *) - -# ---------------------------------------------------------------------- - - -__builtin_new -CSSStyleSheetImpl::CSSStyleSheetImpl(void) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -CSSStyleSheetImpl::AppendStyleRule(nsICSSRule *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *) - - -__builtin_new -AtomKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -HTMLStyleSheetImpl::HTMLStyleSheetImpl(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawRemove -nsHashtable::Remove(nsHashKey *) -HTMLStyleSheetImpl::DropMappedAttributes(nsIHTMLMappedAttributes *) - - -__builtin_new -AttributeKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -HTMLStyleSheetImpl::UniqueMappedAttributes(nsIHTMLMappedAttributes *, nsIHTMLMappedAttributes *&) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -HTMLStyleSheetImpl::UniqueMappedAttributes(nsIHTMLMappedAttributes *, nsIHTMLMappedAttributes *&) - - -__builtin_new -nsStyleContextData::Create(nsIPresContext *) - - -__builtin_new -__builtin_vec_new -nsStyleContent::AllocateCounterResets(unsigned int) - - -__builtin_new -__builtin_vec_new -nsStyleContent::AllocateContents(unsigned int) - - -__builtin_new -xptiManifest::Read(xptiInterfaceInfoManager *, xptiWorkingSet *) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -PL_HashTableAdd -xptiManifest::Read(xptiInterfaceInfoManager *, xptiWorkingSet *) - - -__builtin_new -SelectorList::AddSelector(nsCSSSelector const &) -CSSParserImpl::ParseSelectorGroup(int &, SelectorList *&) - - -__builtin_new -CSSParserImpl::ParseContent(int &, nsICSSDeclaration *, int &) - -# ---------------------------------------------------------------------- -# -# RuleHash -# - - -__builtin_new -RuleHash::AppendRuleToTable(nsHashtable &, int, nsICSSStyleRule *) - - -__builtin_new -RuleHash::AppendRuleToTable(nsHashtable &, nsIAtom *, nsICSSStyleRule *) - - -__builtin_new -RuleHash::AppendRuleToTable(nsHashtable &, nsIAtom *, nsICSSStyleRule *, int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -RuleHash::AppendRuleToTable(nsHashtable &, int, nsICSSStyleRule *) - - -__builtin_new -AtomKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -RuleHash::AppendRuleToTable(nsHashtable &, nsIAtom *, nsICSSStyleRule *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -RuleHash::RuleHash(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -RuleHash::AppendRuleToTable(nsHashtable &, nsIAtom *, nsICSSStyleRule *) - - -__builtin_new -__builtin_vec_new -RuleHash::EnumerateAllRules(nsIAtom *, nsIAtom *, nsVoidArray const &, void (*)(nsICSSStyleRule *, void *), void *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -RuleHash::AppendRuleToTable(nsHashtable &, nsIAtom *, nsICSSStyleRule *, int) - -# ---------------------------------------------------------------------- -# -# nsCSSSelector -# - - -__builtin_new -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - - -__builtin_new -nsAtomList::nsAtomList(nsAtomList const &) -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - - -__builtin_new -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - - -__builtin_new -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsAttrSelector::nsAttrSelector(nsAttrSelector const &) -nsCSSSelector::nsCSSSelector(nsCSSSelector const &) - -# ---------------------------------------------------------------------- -# -# StyleSetImpl -# - - -__builtin_new -CSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor *&, nsIStyleRuleProcessor *) -StyleSetImpl::ClearOverrideRuleProcessors(void) - - -__builtin_new -CSSRuleProcessor::GetRuleCascade(nsIPresContext *, nsIAtom *) -CSSRuleProcessor::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIStyleContext *, nsIRuleWalker *) -StyleSetImpl::ReplaceBackstopStyleSheets(nsISupportsArray *) - - -__builtin_new -CSSRuleProcessor::GetRuleCascade(nsIPresContext *, nsIAtom *) -CSSRuleProcessor::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIAtom *, nsIStyleContext *, nsICSSPseudoComparator *, nsIRuleWalker *) -StyleSetImpl::ResolveStyleFor(nsIPresContext *, nsIContent *, nsIStyleContext *, int) - - -__builtin_new -nsSupportsArray::Create(nsISupports *, nsID const &, void **) -NS_NewISupportsArray(nsISupportsArray **) -StyleSetImpl::EnsureArray(nsISupportsArray **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsRuleNode::Transition(nsIStyleRule *, nsIRuleNode **) -nsRuleWalker::Forward(nsIStyleRule *) -StyleSetImpl::AddImportantRules(nsIRuleNode *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsRuleNode::Transition(nsIStyleRule *, nsIRuleNode **) -nsRuleWalker::Forward(nsIStyleRule *) -nsHTMLBodyElement::WalkInlineStyleRules(nsIRuleWalker *) -HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIStyleContext *, nsIRuleWalker *) -StyleSetImpl::ReplaceBackstopStyleSheets(nsISupportsArray *) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports *, void *) -nsSupportsArray::EnumerateBackwards(int (*)(nsISupports *, void *), void *) -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports *, void *) -CSSRuleProcessor::GetRuleCascade(nsIPresContext *, nsIAtom *) -CSSRuleProcessor::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIStyleContext *, nsIRuleWalker *) -StyleSetImpl::ReplaceBackstopStyleSheets(nsISupportsArray *) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -CSSRuleProcessor::AppendStyleSheet(nsICSSStyleSheet *) -CSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor *&, nsIStyleRuleProcessor *) -StyleSetImpl::ClearOverrideRuleProcessors(void) - -//---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsString::operator=(nsString const &) -StyleListImpl::ResetFrom(nsStyleList const *, nsIPresContext *) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports *, void *) -nsSupportsArray::EnumerateBackwards(int (*)(nsISupports *, void *), void *) -CSSRuleProcessor::CascadeSheetRulesInto(nsISupports *, void *) -CSSRuleProcessor::GetRuleCascade(nsIPresContext *, nsIAtom *) -CSSRuleProcessor::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIAtom *, nsIStyleContext *, nsICSSPseudoComparator *, nsIRuleWalker *) -StyleSetImpl::ResolveStyleFor(nsIPresContext *, nsIContent *, nsIStyleContext *, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -CSSRuleProcessor::ClearRuleCascades(void) -nsSupportsArray::EnumerateBackwards(int (*)(nsISupports *, void *), void *) -CSSRuleProcessor::GetRuleCascade(nsIPresContext *, nsIAtom *) -CSSRuleProcessor::RulesMatching(nsIPresContext *, nsIAtom *, nsIContent *, nsIAtom *, nsIStyleContext *, nsICSSPseudoComparator *, nsIRuleWalker *) -StyleSetImpl::ResolveStyleFor(nsIPresContext *, nsIContent *, nsIStyleContext *, int) - -# ---------------------------------------------------------------------- - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -StyleContextCache::VerifyList(unsigned int) - - -__builtin_new -StyleContextCache::AllocateList(void) - -# ---------------------------------------------------------------------- -# -# nsPersistentProperties -# - - -__builtin_new -nsPersistentProperties::Create(nsISupports *, nsID const &, void **) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -nsPersistentProperties::SetStringProperty(nsAString const &, nsAString &, nsAString &) -nsPersistentProperties::Load(nsIInputStream *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCppSharedAllocator::allocate(unsigned int, void const *) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsString::ToNewUnicode(void) const -nsPersistentProperties::SetStringProperty(nsString const &, nsString &, nsString &) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -nsPersistentProperties::SetStringProperty(nsString const &, nsString &, nsString &) - - -PR_Malloc -PL_ArenaFinish -PL_NewHashTable -nsPersistentProperties::nsPersistentProperties(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsPersistentProperties::SetStringProperty(nsAString const &, nsAString &, nsAString &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsPersistentProperties::SetStringProperty(nsAString const &, nsAString &, nsAString &) - -# ---------------------------------------------------------------------- -# -# nsCSSValue -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCppSharedAllocator::allocate(unsigned int, void const *) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsString::ToNewUnicode(void) const -nsCSSValue::operator=(nsCSSValue const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsCSSValue::SetStringValue(nsAString const &, nsCSSUnit) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsCSSValue::SetStringValue(nsAString const &, nsCSSUnit) - -# ---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStringKey::Clone(void) const - -#---------------------------------------------------------------------- -# -# nsTextFragment -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsTextFragment::SetTo(unsigned short const *, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsAString const &) -nsTextFragment::operator=(nsAString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -char * AllocateStringCopy(basic_nsAReadableString const &, char *) -ToNewCString(basic_nsAReadableString const &) -nsTextFragment::operator=(basic_nsAReadableString const &) - -#---------------------------------------------------------------------- -# -# nsTextBoxFrame -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsTextBoxFrame::UpdateAttributes(nsIPresContext *, nsIAtom *, int &, int &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsTextBoxFrame::CalculateTitleForWidth(nsIPresContext *, nsRenderingContext &, int) - -# ---------------------------------------------------------------------- -# -# nsPopupSetFrame -# - - -__builtin_new -nsPopupSetFrame::AddPopupFrame(nsIFrame *) - -#---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsACString const &) -nsStdURL::GetSpec(char **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsString::ToNewCString(void) const -nsSimpleURI::SetSpec(char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsAString const &) -nsSimpleURI::SetSpec(char const *) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -PL_HashTableAdd -nsNodeInfoManager::GetNodeInfo(nsIAtom *, nsIAtom *, int, nsINodeInfo *&) - - -PR_Malloc -PL_ArenaFinish -PL_NewHashTable -nsNodeInfoManager::nsNodeInfoManager(void) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawRemove -PL_HashTableRemove -nsNodeInfoManager::RemoveNodeInfo(nsNodeInfo *) - - -XPT_ArenaMalloc -xptiInterfaceInfo::CopyName(char const *, xptiWorkingSet *) - - -__builtin_new -xptiInterfaceInfo::PartiallyResolveLocked(XPTInterfaceDescriptor *, xptiWorkingSet *) - - -XPT_ArenaMalloc - - -siglongjmp -pthread_create - - -XkbAllocClientMap - - -_XiCheckExtInit - - -_XAllocScratch - - -XUnlockDisplay - - -_XlcCreateLC - - -XkbUseExtension - - -_XimServerDestroy - - -_XlcAddCharSet - - -XInitExtension - - -_XlcGenericLoader - - -_XwcDefaultDrawImageString - - -_XlcAddCT - - -XShmCreateImage - - -_XFreeAtomTable - - -XCreateRegion - - -XIntersectRegion - - -_XlcCreateLocaleDataBase - - -_XUpdateAtomCache - - -XrmMergeDatabases - - -XrmParseCommand - - -XOpenDisplay - - -XCreateGC - - -_XlcResetConverter - - -_XEnq - - -_XimLcctstowcs - - -XtMalloc - - -XtCalloc - - -Xpermalloc - - -_XlcCreateDefaultCharSet - - -_XimLocalSetICValues - - -_XimLocalCreateIC - - -_XlcSetConverter - - -_XkbGetCharset - - -g_malloc - - -g_realloc - - -g_malloc0 - - -_XimLcctstoutf8 - - -loader_png -gdk_imlib_load_image - - -loader_png -gdk_imlib_save_image - - -_dl_lookup_versioned_symbol_skip - - -_dl_dst_substitute - - -_dl_map_object_deps - - -_dl_map_object - - -_dl_debug_message - - -PR_Malloc -bufio_SetBufferSize -nsXPTCStubBase::Sentinel9(void) -NR_RegSetBufferSize -nsRegistry::SetBufferSize(int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsXBLService::nsXBLService(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsXBLService::nsXBLService(void) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -InMemoryAssertionEnumeratorImpl::operator new(unsigned int, nsFixedSizeAllocator &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsGenericModule::nsGenericModule(char const *, unsigned int, nsModuleComponentInfo *, unsigned int (*)(nsIModule *), void (*)(nsIModule *)) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsGenericModule::GetClassObject(nsIComponentManager *, nsID const &, nsID const &, void **) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsGenericModule::GetClassObject(nsIComponentManager *, nsID const &, nsID const &, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsGenericModule::nsGenericModule(char const *, unsigned int, nsModuleComponentInfo *, void (*)(nsIModule *)) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::nsHashtable(unsigned int, int) -nsGenericModule::nsGenericModule(char const *, unsigned int, nsModuleComponentInfo *, unsigned int (*)(nsIModule *), void (*)(nsIModule *)) - - -gettext -gettext -setlocale -setlocale -nsUNIXCharset::nsUNIXCharset(void) - -# ---------------------------------------------------------------------- -# -# nsLocaleService -# - - -textdomain -textdomain -setlocale -setlocale -nsLocaleService::nsLocaleService(void) - - -setlocale -setlocale -setlocale -nsLocaleService::nsLocaleService(void) - - -PR_Malloc -PL_ArenaFinish -PL_NewHashTable -nsLocale::nsLocale(void) - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -PL_HashTableAdd -nsLocale::AddCategory(unsigned short const *, unsigned short const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::do_AssignFromElementPtr(unsigned short const *) -nsString::nsString(unsigned short const *) -nsLocale::AddCategory(unsigned short const *, unsigned short const *) - -# ---------------------------------------------------------------------- -# -# nsServiceManagerImpl (obsolete?) -# - - -__builtin_new -nsServiceManagerImpl::nsServiceManagerImpl(void) -NS_NewServiceManager(nsIServiceManager **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsServiceManagerImpl::nsServiceManagerImpl(void) - - -__builtin_new -nsHashtable::Put(nsHashKey *, void *) -nsServiceManagerImpl::GetService(nsID const &, nsID const &, nsISupports **, nsIShutdownListener *) - - -__builtin_new -nsServiceManagerImpl::nsServiceManagerImpl(void) -NS_NewServiceManager(nsIServiceManager **) - - -__builtin_new -nsServiceManagerImpl::GetService(nsID const &, nsID const &, nsISupports **, nsIShutdownListener *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsServiceManagerImpl::GetService(nsID const &, nsID const &, nsISupports **, nsIShutdownListener *) - -#---------------------------------------------------------------------- -# -# nsXMLElement -# - - -__builtin_new -nsGenericContainerElement::SetAttribute(nsINodeInfo *, basic_nsAReadableString const &, int) -nsGenericXMLElement::SetAttribute(nsINodeInfo *, basic_nsAReadableString const &, int) - - -__builtin_new -nsGenericContainerElement::SetAttribute(nsINodeInfo *, basic_nsAReadableString const &, int) -nsXMLElement::SetAttribute(nsINodeInfo *, basic_nsAReadableString const &, int) - - -__builtin_new -nsGenericContainerElement::SetAttr(nsINodeInfo *, nsAString const &, int) -nsXMLElement::SetAttr(nsINodeInfo *, nsAString const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsString::nsString(nsAString const &) -nsGenericContainerElement::SetAttr(nsINodeInfo *, nsAString const &, int) -nsXMLElement::SetAttr(nsINodeInfo *, nsAString const &, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsCheapVoidArray::AppendElement(void *) -nsGenericContainerElement::AppendChildTo(nsIContent *, int, int) -nsXMLContentSink::AddContentAsLeaf(nsIContent *) - -#---------------------------------------------------------------------- -# -# nsXMLDocument -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsDocument::nsDocument(void) -nsMarkupDocument::nsMarkupDocument(void) -nsXMLDocument::nsXMLDocument(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsString::AppendWithConversion(char const *, int) -nsString::AssignWithConversion(char const *) -nsDocument::StartDocumentLoad(char const *, nsIChannel *, nsILoadGroup *, nsISupports *, nsIStreamListener **, int) -nsXMLDocument::StartDocumentLoad(char const *, nsIChannel *, nsILoadGroup *, nsISupports *, nsIStreamListener **, int) - -#---------------------------------------------------------------------- - - -__builtin_new -nsGCCache::nsGCCache(void) - -#---------------------------------------------------------------------- -# -# prefs -# - - -_init -PL_HashTableRawAdd -PL_HashTableAdd -pref_HashPref - - -_init -PL_NewHashTable -PREF_Init - - -pref_HashPref - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsPref::nsPref(void) - - -PREF_RegisterCallback - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsCString::nsCString(nsCString const &) -nsTArray::InsertElementAt(int, nsCString const &) -nsPrefBranch::AddObserver(char const *, nsIObserver *) - -#---------------------------------------------------------------------- - - -PR_Calloc -PR_SetThreadPrivate -nsThread::RegisterThreadSelf(void) - - -XFreeFont - - -__builtin_new -nsFontGTK::operator new(unsigned int) - - -__builtin_new -nsCheapVoidArray::SwitchToVector(void) -nsCheapVoidArray::AppendElement(void *) -nsGenericContainerElement::AppendChildTo(nsIContent *, int) - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsCheapVoidArray::AppendElement(void *) -nsGenericContainerElement::AppendChildTo(nsIContent *, int, int) - -#---------------------------------------------------------------------- -# -# nsObserverService -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsObserverService::GetObserverList(unsigned short const *, nsIObserverList **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsObserverService::GetObserverList(unsigned short const *, nsIObserverList **) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsObserverService::GetObserverList(nsString const &, nsIObserverList **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsObserverService::GetObserverList(nsString const &, nsIObserverList **) - - -__builtin_new -NS_NewObserverList(nsIObserverList **) -nsObserverService::GetObserverList(nsString const &, nsIObserverList **) - - -__builtin_new -nsObserverService::GetObserverList(nsString const &, nsIObserverList **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsObserverService::GetObserverList(nsString const &, nsIObserverList **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsObserverService::GetObserverList(char const *, nsObserverList **) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsObserverList::AddObserver(nsIObserver *, int) - -#---------------------------------------------------------------------- - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsViewManager::nsViewManager(void) - - -__builtin_new -nsViewManager2::AddToDisplayList(int *, nsView *, nsRect &, nsRect &, unsigned int, int, int) - -# ---------------------------------------------------------------------- -# -# nsBindingManager -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsBindingManager::SetContentListFor(nsIContent *, nsISupportsArray *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsBindingManager::SetInsertionParent(nsIContent *, nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsBindingManager::SetAnonymousNodesFor(nsIContent *, nsISupportsArray *) - - -__builtin_new -nsISupportsKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsBindingManager::SetBinding(nsIContent *, nsIXBLBinding *) - - -__builtin_new -nsBindingManager::SetBinding(nsIContent *, nsIXBLBinding *) - - -__builtin_new -nsBindingManager::SetInsertionParent(nsIContent *, nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsBindingManager::SetBinding(nsIContent *, nsIXBLBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsBindingManager::SetBinding(nsIContent *, nsIXBLBinding *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsBindingManager::SetInsertionParent(nsIContent *, nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsBindingManager::SetInsertionParent(nsIContent *, nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsBindingManager::SetWrappedJS(nsIContent *, nsIXPConnectWrappedJS *) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsBindingManager::AddToAttachedQueue(nsIXBLBinding *) - -# ---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsString::nsString(nsAString const &) -NameSpaceManagerImpl::RegisterNameSpace(nsAString const &, int &) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsLayoutUtils::GetDynamicScriptContext(JSContext *, nsIScriptContext **) -NameSpaceManagerImpl::NameSpaceManagerImpl(void) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -NameSpaceManagerImpl::RegisterNameSpace(basic_nsAReadableString const &, int &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsStr::StrAppend(nsStr &, nsStr const &, unsigned int, int) -nsStr::StrAssign(nsStr &, nsStr const &, unsigned int, int) -nsString::nsString(nsString const &) -nsLayoutUtils::CopyNewlineNormalizedUnicodeTo(nsReadingIterator &, nsReadingIterator const &, basic_nsAWritableString &) -NameSpaceManagerImpl::NameSpaceManagerImpl(void) - - -__builtin_new -nsErrorService::Create(nsISupports *, nsID const &, void **) - - -__builtin_new -nsVoidKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsInt2StrHashtable::Put(unsigned int, char const *) -nsErrorService::RegisterErrorStringBundleKey(unsigned int, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsInt2StrHashtable::Put(unsigned int, char const *) -nsErrorService::RegisterErrorStringBundleKey(unsigned int, char const *) - - -__builtin_new -ArenaImpl::Create(nsISupports *, nsID const &, void **) -NS_NewHeapArena(nsIArena **, unsigned int) -nsDocument::Init(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsDocument::nsDocument(void) - - -__builtin_new -nsDocument::SetHeaderData(nsIAtom *, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsDocument::AddReference(void *, nsISupports *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(basic_nsAReadableString const &) -nsDocHeaderData::nsDocHeaderData(nsIAtom *, basic_nsAReadableString const &) - - -__builtin_new -XPCContext::newXPCContext(XPCJSRuntime *, JSContext *) - - -__builtin_new -nsEventQueueServiceImpl::Create(nsISupports *, nsID const &, void **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsEventQueueServiceImpl::nsEventQueueServiceImpl(void) - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, EventArrayType, int, nsHashKey *, int) - - -PR_Malloc -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, EventArrayType, int, nsHashKey *, int) -nsEventListenerManager::SetJSEventListener(nsIScriptContext *, nsISupports *, nsIAtom *, int) -nsEventListenerManager::AddScriptEventListener(nsIScriptContext *, nsISupports *, nsIAtom *, nsAString const &, int) - - -PR_Malloc -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, EventArrayType, int, nsHashKey *, int) -nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *, nsAString const &, int) - - -PR_Malloc -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, EventArrayType, int, nsHashKey *, int) -nsEventListenerManager::AddEventListenerByIID(nsIDOMEventListener *, nsID const &, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::ReplaceElementAt(void *, int) -nsEventListenerManager::GetListenersByType(EventArrayType, nsHashKey *, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::ReplaceElementAt(void *, int) -nsEventListenerManager::GetListenersByType(EventArrayType, nsHashKey *, int) - - -__builtin_new -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, nsID const &, int, int) - - -PR_Malloc -nsEventListenerManager::AddEventListener(nsIDOMEventListener *, nsID const &, int, int) - - -__builtin_new -nsCParserNode::AddAttribute(CToken *) - - -__builtin_new -__builtin_vec_new -nsDeque::GrowCapacity(void) -nsDeque::Push(void *) -nsCParserNode::AddAttribute(CToken *) - - -PR_Malloc -nsSocketTransportService::Init(void) - - -PR_Malloc -nsSocketTransport::AsyncWrite(nsIInputStream *, nsIStreamObserver *, nsISupports *) - - -PR_Malloc -_PR_Getfd -PR_GetConnectStatus -PR_Socket -PR_OpenTCPSocket -nsSocketTransport::doConnection(short) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -CompositeDataSourceImpl::CompositeDataSourceImpl(void) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -CompositeDataSourceImpl::GetTargets(nsIRDFResource *, nsIRDFResource *, int, nsISimpleEnumerator **) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode *, nsISimpleEnumerator **) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource *, nsISimpleEnumerator **) - -# ---------------------------------------------------------------------- -# -# nsHTMLValue -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(basic_nsAReadableString const &, unsigned short *) -ToNewUnicode(basic_nsAReadableString const &) -nsHTMLValue::nsHTMLValue(basic_nsAReadableString const &, nsHTMLUnit) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsHTMLValue::SetStringValue(nsAString const &, nsHTMLUnit) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsHTMLValue::nsHTMLValue(nsAString const &, nsHTMLUnit) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsHTMLValue::SetStringValue(nsAString const &, nsHTMLUnit) - -# ---------------------------------------------------------------------- - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsMemCache::GetCachedNetData(char const *, unsigned int, nsINetDataCacheRecord **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsMemCache::Init(void) - - -__builtin_new -nsOpaqueKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsMemCache::GetCachedNetData(char const *, unsigned int, nsINetDataCacheRecord **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsOpaqueKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsMemCache::GetCachedNetData(char const *, unsigned int, nsINetDataCacheRecord **) - - -__builtin_new -nsOpaqueKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsMemCache::GetCachedNetData(char const *, unsigned int, nsINetDataCacheRecord **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsOpaqueKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsMemCache::GetCachedNetData(char const *, unsigned int, nsINetDataCacheRecord **) - - -__builtin_new -__builtin_vec_new -nsMemCacheRecord::SetMetaData(unsigned int, char const *) - - -__builtin_new -__builtin_vec_new -nsMemCacheRecord::Init(char const *, unsigned int, unsigned int, nsMemCache *) - - -PR_Realloc -nsXPIDLString type_info function -nsXPIDLString type_info function -nsTextFormatter::vsmprintf(unsigned short const *, void *) -nsTextFormatter::smprintf(unsigned short const *,...) - - -PR_Malloc -nsXPIDLString type_info function -nsXPIDLString type_info function -nsTextFormatter::vsmprintf(unsigned short const *, void *) - - -PR_Realloc -nsXPIDLString type_info function -nsXPIDLString type_info function -nsTextFormatter::vsmprintf(unsigned short const *, void *) - -#---------------------------------------------------------------------- -# -# nsPresContext -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsPresContext::nsPresContext(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresContext::LoadImage(nsString const &, nsIFrame *, imgIRequest **) - -#---------------------------------------------------------------------- -# -# nsPresState -# - - -__builtin_new -nsPresState::SetStateProperty(nsAString const &, nsAString const &) - - -__builtin_new -nsPresState::SetStatePropertyAsSupports(nsAString const &, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStatePropertyAsSupports(basic_nsAReadableString const &, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsPresState::SetStateProperty(basic_nsAReadableString const &, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsPresState::SetStatePropertyAsSupports(basic_nsAReadableString const &, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStateProperty(basic_nsAReadableString const &, basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsSupportsWStringImpl::SetDataWithLength(unsigned int, unsigned short const *) -nsSupportsWStringImpl::SetData(unsigned short const *) -nsPresState::SetStateProperty(basic_nsAReadableString const &, basic_nsAReadableString const &) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStatePropertyAsSupports(basic_nsAReadableString const &, nsISupports *) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStateProperty(basic_nsAReadableString const &, basic_nsAReadableString const &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsSupportsWStringImpl::SetDataWithLength(unsigned int, unsigned short const *) -nsSupportsWStringImpl::SetData(unsigned short const *) -nsPresState::SetStateProperty(basic_nsAReadableString const &, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsPresState::SetStateProperty(nsAString const &, nsAString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsPresState::SetStatePropertyAsSupports(nsAString const &, nsISupports *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStateProperty(nsAString const &, nsAString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsPresState::SetStatePropertyAsSupports(nsAString const &, nsISupports *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsSupportsStringImpl::SetDataWithLength(unsigned int, char const *) -nsSupportsStringImpl::SetData(char const *) -nsPresState::SetStateProperty(nsAString const &, nsAString const &) - -# ---------------------------------------------------------------------- -# -# Prefs stuff -# - - -PL_strdup -pref_HashPref - - -PL_strdup -PREF_LockPref - - -PL_strdup -PREF_RegisterCallback - -#---------------------------------------------------------------------- -# -# Imagelib Stuff -# - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -imgRequest::AddProxy(imgRequestProxy *) - - -__builtin_new -ImageRequestImpl::AddObserver(nsIImageRequestObserver *) - - -PR_Malloc -XP_AddObserver -ImageRequestImpl::Init(void *, char const *, nsIImageRequestObserver *, unsigned int const *, unsigned int, unsigned int, unsigned int, ilINetContext *) - - -__builtin_new -ImageNetContextImpl::GetURL(ilIURL *, ImgCachePolicy, ilINetReader *, int) - -# il_group_notify() is really a call to a static rounting il_init_scaling() - -PR_Malloc -il_group_notify(_IL_GroupContext *, long) -il_size(il_container_struct *) -ImgDCallbk::ImgDCBImageSize(void) - - -PR_Calloc -il_gif_write(il_container_struct *, unsigned char const *, int) - - -PR_Malloc -il_gif_write(il_container_struct *, unsigned char const *, int) - - -PR_Calloc -il_gif_init(il_container_struct *) - - -PR_Calloc -IL_GetImage - - -PR_Calloc -il_get_container(_IL_GroupContext *, ImgCachePolicy, char const *, _NI_IRGB *, IL_DitherMode, int, int, int) - - -PR_Calloc -IL_CreateTrueColorSpace - - -PR_Calloc -il_size(il_container_struct *) -ImgDCallbk::ImgDCBImageSize(void) - - -PR_Calloc -IL_CreateGreyScaleColorSpace - - -PR_Malloc -il_BACat(char **, unsigned int, char const *, unsigned int) - - -PR_Realloc -il_BACat(char **, unsigned int, char const *, unsigned int) - - -PR_Malloc -ImageConsumer::OnStartRequest(nsIChannel *, nsISupports *) - -# These are really called from `static' routines in ilclient.cpp, -# *not* ImgDCallbk::CreateInstance() - -PR_Calloc -ImgDCallbk::CreateInstance(nsID const &, il_container_struct *, nsID const &, void **) - -#---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -nsImageGTK::Init(int, int, int, nsMaskRequirements) - -#---------------------------------------------------------------------- -# -# nsLayoutHistoryState -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsLayoutHistoryState::nsLayoutHistoryState(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsLayoutHistoryState::nsLayoutHistoryState(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsLayoutHistoryState::AddState(unsigned int, nsIPresState *, nsIStatefulFrame::StateType) - - -__builtin_new -nsVoidKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsLayoutHistoryState::AddState(unsigned int, nsIPresState *, nsIStatefulFrame::StateType) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsLayoutHistoryState::AddState(nsCString const &, nsIPresState *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsLayoutHistoryState::AddState(nsCString const &, nsIPresState *) - -# ---------------------------------------------------------------------- -# -# nsCookieService -# - - -PR_Realloc -Local_SACat(char **, char const *) -COOKIE_GetCookie(char *) - - -PR_Malloc -cookie_IsFromHost(_cookie_CookieStruct *, char *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsAString const &) -COOKIE_Read(void) -nsCookieService::Init(void) - -# ---------------------------------------------------------------------- - - -PR_Realloc -nsMemoryImpl::Realloc(void *, unsigned int) -nsMemory::Realloc(void *, unsigned int) -nsReplacementPolicy::AssociateCacheEntryWithRecord(nsINetDataCacheRecord *, nsINetDataCache *, nsCachedNetData **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsReplacementPolicy::Init(unsigned int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AssignFromReadable(nsACString const &) -nsACString::do_AssignFromElementPtr(char const *) -nsHttpHeaderArray::SetHeader(nsHttpAtom, char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsHTTPHandler::SetServerCapabilities(char const *, int, unsigned int) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsHTTPHandler::nsHTTPHandler(void) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsHTTPHandler::SetServerCapabilities(char const *, int, unsigned int) - - -PR_Malloc -PL_ArenaAllocate -ArenaImpl::Alloc(unsigned int) -nsCachedNetData::operator new(unsigned int, nsIArena *) - - -PR_Malloc -ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo *, nsIInputStream *, unsigned int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsSegmentedBuffer::AppendNewSegment(void) - - -PL_strndup -ExtractString - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -__17nsObjectHashtablePFP9nsHashKeyPvPv_PvPvPFP9nsHashKeyPvPv_iT2Uii -nsJAR::nsJAR(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsJAR::nsJAR(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewCString(nsACString const &) -nsIOService::ResolveRelativePath(char const *, char const *, char **) -nsJARURI::SetSpec(char const *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsStreamConverterService::Init(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsLayoutUtils::GetDynamicScriptContext(JSContext *, nsIScriptContext **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsDNSService::GetLookupEntry(char const *, nsDNSLookup **) - - -PL_DHashAllocTable -PL_DHashTableInit -nsDNSService::Init(void) - - -__builtin_new -nsDNSService::GetLookupEntry(char const *, nsDNSLookup **) - - -__builtin_new -nsDNSService::Lookup(char const *, nsIDNSListener *, nsISupports *, nsIRequest **) - - -__builtin_new -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsDNSService::GetLookupEntry(char const *, nsDNSLookup **) - - -gethostbyname2 -PR_GetIPNodeByName -nsDNSLookup::InitiateLookup(void) - - -__builtin_new -nsSupportsArray::Create(nsISupports *, nsID const &, void **) -NS_NewISupportsArray(nsISupportsArray **) -nsDNSLookup::Init(char const *) - - -__builtin_new -nsDNSLookup::Create(char const *) - -# ---------------------------------------------------------------------- -# -# nsFormControlList -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsFormControlList::AddElementToTable(nsIFormControl *, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsFormControlList::nsFormControlList(nsIDOMHTMLFormElement *) - - -__builtin_new -nsFormControlList::AddElementToTable(nsIFormControl *, basic_nsAReadableString const &) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsFormControlList::AddElementToTable(nsIFormControl *, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsFormControlList::AddElementToTable(nsIFormControl *, basic_nsAReadableString const &) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsFormControlList::AddElementToTable(nsIFormControl *, nsAString const &) - -# ---------------------------------------------------------------------- -# -# nsControllerCommandManager -# - - -__builtin_new -__builtin_vec_new -NS_NewControllerCommandManager(nsIControllerCommandManager **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsControllerCommandManager::nsControllerCommandManager(void) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsControllerCommandManager::RegisterCommand(nsAString const &, nsIControllerCommand *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsControllerCommandManager::RegisterCommand(unsigned short const *, nsIControllerCommand *) - - -__builtin_new -nsStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsControllerCommandManager::RegisterCommand(unsigned short const *, nsIControllerCommand *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsSupportsHashtable::nsSupportsHashtable(unsigned int, int) -nsControllerCommandManager::nsControllerCommandManager(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsConsoleService::nsConsoleService(void) - - -__builtin_new -mozilla::dom::Element::GetDOMSlots(void) - - -__builtin_new -HTMLAttribute::CopyHTMLAttributes(HTMLAttribute *, HTMLAttribute **) - -# ---------------------------------------------------------------------- -# -# HTMLAttributesImpl -# - - -__builtin_new -HTMLAttributesImpl::SetAttributeFor(nsIAtom *, nsAString const &, int, nsIHTMLContent *, nsIHTMLStyleSheet *) - - -__builtin_new -HTMLAttributesImpl::SetAttributeFor(nsIAtom *, nsHTMLValue const &, int, nsIHTMLContent *, nsIHTMLStyleSheet *, int &) - - -__builtin_new -__builtin_vec_new -HTMLAttributesImpl::SetAttributeName(nsIAtom *, int &) - - -__builtin_new -nsHTMLMappedAttributes::SetAttribute(nsIAtom *, nsHTMLValue const &) -HTMLAttributesImpl::SetAttributeFor(nsIAtom *, nsHTMLValue const &, int, nsIHTMLContent *, nsIHTMLStyleSheet *, int &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsHTMLValue::nsHTMLValue(nsHTMLValue const &) -HTMLAttributesImpl::SetAttributeFor(nsIAtom *, nsHTMLValue const &, int, nsIHTMLContent *, nsIHTMLStyleSheet *, int &) - - -__builtin_new -nsHTMLMappedAttributes::nsHTMLMappedAttributes(nsHTMLMappedAttributes const &) -nsHTMLMappedAttributes::Clone(nsHTMLMappedAttributes **) const -HTMLAttributesImpl::EnsureSingleMappedFor(nsIHTMLContent *, nsIHTMLStyleSheet *, int) - -# ---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -nsEntityConverter::LoadVersionPropertyFile(void) - - -__builtin_new -__builtin_vec_new -nsTableFrame::nsTableFrame(void) - - -__builtin_new -__builtin_vec_new -nsTableFrame::BalanceColumnWidths(nsIPresContext *, nsHTMLReflowState const &, nsSize const &, nsSize *) - - -__builtin_new -nsTableFrame::Init(nsIPresContext *, nsIContent *, nsIFrame *, nsIStyleContext *, nsIFrame *) - - -__builtin_new -nsTableCellFrame::GetFrameName(nsString &) const - - -__builtin_new -nsCellMap::AppendCell(nsTableCellMap &, nsTableCellFrame &, int, int) - - -__builtin_new -nsCellMap::Grow(nsTableCellMap &, int, int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::nsVoidArray(int) -nsCellMap::Grow(nsTableCellMap &, int, int) - - -__builtin_new -nsTableCellMap::InsertGroupCellMap(nsTableRowGroupFrame &, nsTableRowGroupFrame *&) - - -__builtin_new -nsTableCellMap::AddColsAtEnd(unsigned int) - - -__builtin_new -__builtin_vec_new -nsEncoderSupport::nsEncoderSupport(void) - - -__builtin_new -Init__18nsFrameImageLoaderP14nsIPresContextP13nsIImageGroupRC8nsStringPCUiPC6nsSizeP8nsIFrame16nsImageAnimationPFP14nsIPresContextP19nsIFrameImageLoaderP8nsIFramePvUi_UiPvT9 - - -__builtin_new -AddFrame__18nsFrameImageLoaderP8nsIFramePFP14nsIPresContextP19nsIFrameImageLoaderP8nsIFramePvUi_UiPvT3 - - - -__builtin_new -nsFloaterCacheFreeList::Alloc(void) - - -__builtin_new -nsDocLoaderImpl::AddChannelInfo(nsIChannel *) - - -__builtin_new -nsDocLoaderImpl::AddRequestInfo(nsIRequest *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsTokenAllocator::nsTokenAllocator(void) - - -__builtin_new -__builtin_vec_new -SinkContext::AddText(basic_nsAReadableString const &) - - -__builtin_new -__builtin_vec_new -SinkContext::GrowStack(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsScanner::Append(char const *, unsigned int) - - -__builtin_new -nsParser::Parse(nsIURI *, nsIStreamObserver *, int, void *, nsDTDMode) - - -__builtin_new -nsParser::Parse(basic_nsAReadableString const &, void *, nsString const &, int, int, nsDTDMode) - - -__builtin_new -__builtin_vec_new -nsParser::OnDataAvailable(nsIChannel *, nsISupports *, nsIInputStream *, unsigned int, unsigned int) - - -__builtin_new -__builtin_vec_new -InitializeElementTable(void) - - -__builtin_new -nsStorageStream::Init(unsigned int, unsigned int, nsIMemory *) - - -__builtin_new -__builtin_vec_new -nsEntryStack::EnsureCapacityFor(int, int) - - -__builtin_new -nsCacheManager::Init(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(unsigned short const *) -nsScriptError::Init(unsigned short const *, unsigned short const *, unsigned short const *, unsigned int, unsigned int, unsigned int, char const *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -~.* -~.* -basic_nsAWritableString::Assign(char const *) -nsScriptError::Init(unsigned short const *, unsigned short const *, unsigned short const *, unsigned int, unsigned int, unsigned int, char const *) - - -PR_Malloc -bufio_SetBufferSize - - -PR_Malloc -nsMemoryImpl::Alloc -nsMemory::Alloc -ToNewUnicode - - -PR_Malloc -nsMemoryImpl::Alloc -nsMemory::Alloc -nsStr::Alloc - - -__builtin_new -nsDiskCacheDevice::Init(void) - - -__builtin_new -__builtin_vec_new -XULContentSinkImpl::AddAttributes(nsIParserNode const &, nsXULPrototypeElement *) - -# -# XPCNativeInterface::NewInstance allocates an array of XPCNativeMember -# objects, and it also allocates an array of bytes to use for -# XPCNativeInterface objects. Trace would be the same for each. -# - -__builtin_new -__builtin_vec_new -XPCNativeInterface::NewInstance(XPCCallContext &, nsIInterfaceInfo *) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCNativeInterface::GetNewOrUsed(XPCCallContext &, nsID const *) - - -__builtin_new -__builtin_vec_new -nsDiskCacheBlockFile::Open(nsILocalFile *, unsigned int) - -#---------------------------------------------------------------------- -# -# nsConflictSet -# - - -__builtin_new -__builtin_vec_new -nsConflictSet::AllocBindingTable(void *, unsigned int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsConflictSet::AllocBindingEntry(void *, void const *) - - -__builtin_new -__builtin_vec_new -nsConflictSet::AllocClusterTable(void *, unsigned int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsConflictSet::AllocClusterEntry(void *, void const *) - - -__builtin_new -__builtin_vec_new -nsConflictSet::AllocSupportTable(void *, unsigned int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsConflictSet::AllocSupportEntry(void *, void const *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsRDFConMemberTestNode::Element::Clone(void *) const - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsRDFConInstanceTestNode::Element::Clone(void *) const - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsRDFConInstanceTestNode::FilterInstantiations(InstantiationSet &, void *) const - - -__builtin_new -MemoryElementSet::Add(MemoryElement *) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsTemplateMatchRefSet::AddToTable(nsTemplateMatch *) -nsTemplateMatchRefSet::Add(nsTemplateMatch const *) -nsConflictSet::Add(nsTemplateMatch *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsConflictSet::Init(void) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsConflictSet::SupportEntry::Create(nsFixedSizeAllocator &) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsConflictSet::ClusterEntry::Create(nsFixedSizeAllocator &) - -#---------------------------------------------------------------------- - - -__builtin_new -nsAssignmentSet::Add(nsAssignment const &) - -#---------------------------------------------------------------------- -# -# nsXULTemplateBuilder -# - - -__builtin_new -nsXULTemplateBuilder::CompileSimpleRule(nsIContent *, int, InnerNode *) - - -PL_DHashAllocTable -PL_DHashTableInit -nsXULContentBuilder::nsXULContentBuilder(void) - - -PL_DHashAllocTable -PL_DHashTableInit -nsContentSupportMap::Init(void) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsXULContentBuilder::BuildContentFromTemplate(nsIContent *, nsIContent *, nsIContent *, int, nsIRDFResource *, int, nsTemplateMatch *, nsIContent **, int *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsXULTemplateBuilder::AddBindingsFor(nsXULTemplateBuilder *, nsAString const &, void *) - -#---------------------------------------------------------------------- -# -# nsRuleNetwork -# - - -PL_DHashAllocTable -PL_DHashTableInit -nsRuleNetwork::Init(void) - -#---------------------------------------------------------------------- -# -# nsTemplateRule -# - - -__builtin_new -nsTemplateRule::AddBinding(int, nsIRDFResource *, int) - -#---------------------------------------------------------------------- -# -# nsTemplateMatch -# - - -__builtin_new -nsAssignmentSet::Add(nsAssignment const &) -nsTemplateRule::ComputeAssignmentFor(nsConflictSet &, nsTemplateMatch *, int, Value *) const -nsTemplateMatch::GetAssignmentFor(nsConflictSet &, int, Value *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsInstantiationNode::Propagate(InstantiationSet const &, void *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsRDFConMemberTestNode::FilterInstantiations(InstantiationSet &, void *) const - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsTemplateMatch::Create(nsFixedSizeAllocator &, nsTemplateRule const *, Instantiation const &, nsAssignmentSet const &) - -#---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -ReteNodeSet::Add(ReteNode *) - -#---------------------------------------------------------------------- - - -__builtin_new -__builtin_vec_new -nsStaticComponentLoader::GetModuleInfo(void) - - -__builtin_new -__builtin_vec_new -RuleHash::EnumerateAllRules(int, nsIAtom *, nsIAtom *, nsVoidArray const &, void (*)(nsICSSStyleRule *, void *), void *) - - -__builtin_new -__builtin_vec_new -XPCNativeSet::NewInstance(XPCCallContext &, nsIInterfaceInfo *) - - -JS_DHashAllocTable -JS_DHashTableFinish -JS_DHashTableOperate -XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo *) - - -__builtin_new -__builtin_vec_new -XPCNativeSet::NewInstanceMutate(XPCNativeSet *, XPCNativeInterface *, unsigned short) - - -__builtin_new -__builtin_vec_new -nsResourceSet::Add(nsIRDFResource *) - - -__builtin_new -__builtin_vec_new -nsXPCWrappedJSClass::nsXPCWrappedJSClass(XPCCallContext &, nsID const &, nsIInterfaceInfo *) - - -__builtin_new -orkinHeap::Alloc(nsIMdbEnv *, unsigned int, void **) - - -__builtin_new -nsGenericContainerElement::SetAttribute(nsINodeInfo *, nsAString const &, int) - -# -# Space for LiteralImpl is allocated using global operator new so -# that extra space can be allocated for its string value. -# - -__builtin_new -LiteralImpl::Create - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -XULContentSinkImpl::FlushText(int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsString::ToNewUnicode(void) const -nsPersistentProperties::SetStringProperty(nsString const &, nsString &, nsString &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCRT::strndup(unsigned short const *, unsigned int) -nsCRT::strdup(unsigned short const *) -nsCSSValue::operator=(nsCSSValue const &) - -#---------------------------------------------------------------------- -# -# nsXULDocument -# - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsAutoVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsXULDocument::AddObserver(nsIDocumentObserver *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULDocument::SetBoxObjectFor(nsIDOMElement *, nsIBoxObject *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULDocument::SetTemplateBuilderFor(nsIContent *, nsIXULTemplateBuilder *) - -# ---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsElementMap::Add(nsAString const &, nsIContent *) -nsXULDocument::AddElementToMap(nsIContent *) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsElementMap::Add(nsAString const &, nsIContent *) -nsXULDocument::AddElementForID(nsAString const &, nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsXULTreeElement::SelectCallback(nsITimer *, void *) -PL_HashTableRawAdd -PL_HashTableAdd -nsElementMap::Add(nsAString const &, nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -NS_NewControllerCommandManager(nsIControllerCommandManager **) -PL_HashTableRawAdd -PL_HashTableAdd -nsElementMap::Add(nsAString const &, nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsElementMap::Add(nsAString const &, nsIContent *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::AddBucket(unsigned int) -nsFixedSizeAllocator::Init(char const *, unsigned int const *, int, int, int) -nsElementMap::nsElementMap(void) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -unsigned short * AllocateStringCopy(nsAString const &, unsigned short *) -ToNewUnicode(nsAString const &) -nsElementMap::Add(nsAString const &, nsIContent *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsXULDocument::AddReference(void *, nsISupports *) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsXULDocument::PrepareToWalk(void) - - -PL_DHashAllocTable -PL_DHashTableInit -PL_NewDHashTable -nsXULDocument::AddBroadcastListenerFor(nsIDOMElement *, nsIDOMElement *, nsAString const &) - -#---------------------------------------------------------------------- - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ToNewUnicode(nsAString const &) -nsHTMLValue::nsHTMLValue(nsAString const &, nsHTMLUnit) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ExtractURLScheme -nsStdURL::Resolve(char const *, char **) -CSSParserImpl::ParseURL(int &, nsCSSValue &) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -ExtractURLScheme -nsStdURL::Resolve(char const *, char **) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsRuleNode::Transition(nsIStyleRule *, nsIRuleNode **) -nsRuleWalker::Forward(nsIStyleRule *) - -# -# Doesn't inherit nsISupports -# - -__builtin_new -nsRuleNode::Transition(nsIStyleRule *, nsIRuleNode **) - -# -# No vtable. -# - -__builtin_new -nsClassList::ParseClasses(nsClassList **, nsAString const &) - -# -# Doesn't inherit nsISupports -# - -__builtin_new -nsCheapVoidArray::SwitchToVector(void) - - -__builtin_new -nsEventListenerManager::GetListenersByType(EventArrayType, nsHashKey *, int) - -#---------------------------------------------------------------------- - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableInit(PLHashTable *, unsigned int, unsigned int (*)(void const *), int (*)(void const *, void const *), int (*)(void const *, void const *), PLHashAllocOps const *, void *) -nsHashtable::nsHashtable(unsigned int, int) -nsObjectHashtable::nsObjectHashtable(void *(*)(nsHashKey *, void *, void *), void *, int (*)(nsHashKey *, void *, void *), void *, unsigned int, int) -nsServiceManagerImpl::nsServiceManagerImpl(void) - - -__builtin_new -nsXPIDLCString::PrepareForUseAsOutParam(void) - - -__builtin_new -nsXBLBinding::InitClass - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -InMemoryDataSource::LockedAssert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -nsXBLPrototypeBinding::ConstructAttributeTable(nsIContent *) - -#---------------------------------------------------------------------- -# -# nsRuleNode -# - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsSupportsHashtable::Put(nsHashKey *, nsISupports *, nsISupports **) -nsRuleNode::Transition(nsIStyleRule *, nsIRuleNode **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AppendFromReadable(nsAString const &) -nsAString::do_AppendFromElementPtr(unsigned short const *) -nsRuleNode::ComputeDisplayData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AppendFromReadable(nsAString const &) -nsAString::do_AppendFromElementPtr(unsigned short const *) -nsRuleNode::ComputeBackgroundData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AppendFromReadable(nsAString const &) -nsAString::do_AppendFromElementPtr(unsigned short const *) -nsRuleNode::ComputeListData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - -# ---------------------------------------------------------------------- - -# This stuff will only show off if you've turned off the FrameArena -# in nsPresShell.cpp - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeOutlineData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeContentData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeTableData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeUIResetData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeXULData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::SetDefaultOnRoot(nsStyleStructID, nsIStyleContext *) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeListData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeTextData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeTextResetData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputePaddingData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeFontData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeVisibilityData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeColorData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - -# ---------------------------------------------------------------------- -# -# nsBookmarksService -# - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -InMemoryDataSource::LockedAssert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) -InMemoryDataSource::Assert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) -BookmarkParser::updateAtom(nsIRDFDataSource *, nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int *) - - -PR_Malloc -PL_ArenaAllocate -nsFixedSizeAllocator::Alloc(unsigned int) -Assertion::Create(nsFixedSizeAllocator &, nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) -InMemoryDataSource::LockedAssert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) -InMemoryDataSource::Assert(nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int) -BookmarkParser::updateAtom(nsIRDFDataSource *, nsIRDFResource *, nsIRDFResource *, nsIRDFNode *, int *) - -# ---------------------------------------------------------------------- -# -# The following types will only be visible if nsPresShell.cpp is compiled -# with the DEBUG_TRACEMALLOC_FRAMEARENA defined. -# - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleContext::SetStyle(nsStyleStructID, nsStyleStruct const &) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleBorder::operator new(unsigned int, nsIPresContext *) - -# XXX This one is a bit sloppy, and may include some of the other -# style data structs. - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeDisplayData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleContext::SetStyle(nsStyleStructID, nsStyleStruct const &) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeBorderData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeUIData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputePositionData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStylePadding::operator new(unsigned int, nsIPresContext *) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleMargin::operator new(unsigned int, nsIPresContext *) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeBackgroundData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsStyleBackground::nsStyleBackground(nsStyleBackground const &) - -# XXX this'll may be subsumed as nsResetStyleData - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsRuleNode::ComputeDisplayData(nsStyleStruct *, nsCSSStruct const &, nsIStyleContext *, nsRuleNode *, nsRuleNode::RuleDetail const &, int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -nsStyleDisplay::nsStyleDisplay(nsStyleDisplay const &) - -# ---------------------------------------------------------------------- -# The following will only show up if you turn off the FrameArena -# in nsPresShell.cpp - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleContext::GetUniqueStyleData(nsIPresContext *, nsStyleStructID const &) - - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsPresContext::AllocateFromShell(unsigned int, void **) -nsStyleFont::operator new(unsigned int, nsIPresContext *) - -# ---------------------------------------------------------------------- -# -# Frames -# - - -__builtin_new -nsLineBox::SetCombinedArea(nsRect const &) - -# This will only appear when the FrameArena is off. - -PR_Malloc -FrameArena::AllocateFrame(unsigned int, void **) -PresShell::AllocateFrame(unsigned int, void **) -nsLineBox::operator new(unsigned int, nsIPresShell *) - -# ---------------------------------------------------------------------- -# -# nsCacheService -# - - -__builtin_new -nsCacheService::ActivateEntry(nsCacheRequest *, nsCacheEntry **) - - -__builtin_new -nsCacheEntry::CreateDescriptor(nsCacheRequest *, int, nsICacheEntryDescriptor **) -nsCacheService::ProcessRequest(nsCacheRequest *, int, nsICacheEntryDescriptor **) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsCString::SetCapacity(unsigned int) -nsCString::SetLength(unsigned int) -nsACString::do_AppendFromReadable(nsACString const &) -nsACString::do_AppendFromElementPtr(char const *) -nsCacheService::CreateRequest(nsCacheSession *, char const *, int, int, nsICacheListener *, nsCacheRequest **) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsCacheEntryHashTable::AddEntry(nsCacheEntry *) -nsCacheService::ActivateEntry(nsCacheRequest *, nsCacheEntry **) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsCacheEntryHashTable::RemoveEntry(nsCacheEntry *) - -# ---------------------------------------------------------------------- - - -PL_DHashAllocTable -PL_DHashTableInit -nsCacheMetaData::Init(void) - -# ---------------------------------------------------------------------- -# -# nsXMLMIMEDataSource -# - - -PR_Malloc -PL_ArenaFinish -PL_HashTableRawAdd -PL_HashTableAdd -nsXMLMIMEDataSource::InitFromFile(nsIFile *) - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsXMLMIMEDataSource::AddMapping(char const *, char const *, char const *, nsIURI *, unsigned int, unsigned int) - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -nsTArray::InsertElementAt(int, nsCString const &) -nsXMLMIMEDataSource::AddMapping(char const *, char const *, char const *, nsIURI *, unsigned int, unsigned int) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsXMLMIMEDataSource::AddMapping(char const *, char const *, char const *, nsIURI *, unsigned int, unsigned int) - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsCStringKey::Clone(void) const -nsHashtable::Put(nsHashKey *, void *) -nsXMLMIMEDataSource::AddMapping(char const *, char const *, char const *, nsIURI *, unsigned int, unsigned int) - -#---------------------------------------------------------------------- -# -# nsRegion -# - - -__builtin_new -__builtin_vec_new -RgnRectMemoryAllocator::RgnRectMemoryAllocator(unsigned int) -nsRegion::Offset(int, int) - - -__builtin_new -__builtin_vec_new -RgnRectMemoryAllocator::Alloc(void) -nsRegion::Or(nsRegion const &, nsRectFast const &) - - -__builtin_new -__builtin_vec_new -RgnRectMemoryAllocator::Alloc(void) -nsRegion::SetToElements(unsigned int) - -#---------------------------------------------------------------------- -# -# nsCharsetMenu -# - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsCharsetConverterManager::GetRegistryEnumeration2(char *, int, nsISupportsArray **) -nsCharsetConverterManager::GetEncoderList(nsISupportsArray **) -nsCharsetMenu::InitResources(void) - - -__builtin_new -nsCharsetMenu::AddCharsetToItemArray(nsVoidArray *, nsIAtom *, nsMenuEntry **, int) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsCharsetConverterManager::GetRegistryEnumeration2(char *, int, nsISupportsArray **) -nsCharsetConverterManager::GetDecoderList(nsISupportsArray **) -nsCharsetMenu::InitResources(void) - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -InMemoryDataSource::AddObserver(nsIRDFObserver *) -nsCharsetMenu::AddObserver(nsIRDFObserver *) - -#---------------------------------------------------------------------- -# -# nsLoadGroup -# - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsLoadGroup::AddRequest(nsIRequest *, nsISupports *) - -#---------------------------------------------------------------------- -# -# Wallet -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -Wallet_Decrypt2 - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::AssignFromReadable(nsAString const &) -Wallet_RandomName - - -PR_Malloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -Wallet_RandomName - - -__builtin_new -__builtin_vec_new -Wallet_Decrypt2 - - -__builtin_new -Wallet_RandomName - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -Wallet_Decrypt2 - - -PR_Realloc -nsVoidArray::SizeTo(int) -nsVoidArray::GrowArrayBy(int) -nsVoidArray::InsertElementAt(void *, int) -Wallet_RandomName - -#---------------------------------------------------------------------- -# -# nsMemoryCacheDevice -# - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsCacheEntryHashTable::RemoveEntry(nsCacheEntry *) -nsMemoryCacheDevice::EvictEntry(nsCacheEntry *) - -#---------------------------------------------------------------------- -# -# nsSHEntry -# - - -PR_Malloc -nsMemoryImpl::Alloc(unsigned int) -nsMemory::Alloc(unsigned int) -nsStr::Alloc(nsStr &, unsigned int) -nsStr::Realloc(nsStr &, unsigned int) -nsStr::EnsureCapacity(nsStr &, unsigned int) -nsStr::GrowCapacity(nsStr &, unsigned int) -nsString::SetCapacity(unsigned int) -nsString::SetLength(unsigned int) -nsAString::do_AssignFromReadable(nsAString const &) -nsAString::do_AssignFromElementPtr(unsigned short const *) -nsSHEntry::SetTitle(unsigned short const *) - -# ---------------------------------------------------------------------- - - -PR_Malloc -PL_HashTableFinalize(PLHashTable *) -PL_HashTableRawAdd -nsHashtable::Put(nsHashKey *, void *) -nsOutlinerStyleCache::GetStyleContext(nsICSSPseudoComparator *, nsIPresContext *, nsIContent *, nsIStyleContext *, nsIAtom *, nsISupportsArray *, nsIStyleContext **) - -# ---------------------------------------------------------------------- -# -# nsMsgDatabase -# - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsMsgDatabase::AddHdrToCache(nsIMsgDBHdr *, unsigned int) - - -PL_DHashAllocTable -PL_DHashTableFinish -PL_DHashTableOperate -nsMsgDatabase::AddHdrToUseCache(nsIMsgDBHdr *, unsigned int) - -# ---------------------------------------------------------------------- -# -# nsMsgFolderDataSource -# - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -nsMsgFolderDataSource::getFolderArcLabelsOut(nsISupportsArray **) - -# ---------------------------------------------------------------------- -# -# singsign -# - - -__builtin_new -SI_DeletePersistentUserData - -# ---------------------------------------------------------------------- -# -# LocalStoreImpl -# - - -__builtin_new -__builtin_vec_new -nsSupportsArray::GrowArrayBy(int) -nsSupportsArray::InsertElementAt(nsISupports *, unsigned int) -nsSupportsArray::AppendElement(nsISupports *) -LocalStoreImpl::AddObserver(nsIRDFObserver *) - -# ---------------------------------------------------------------------- -# -# NSS -# - - -PR_Malloc -PL_ArenaAllocate -PORT_ArenaAlloc - - -PR_Malloc -PL_ArenaAllocate -nss_ZAlloc diff --git a/tools/trace-malloc/uncategorized.pl b/tools/trace-malloc/uncategorized.pl deleted file mode 100755 index 0501bfc3fffc..000000000000 --- a/tools/trace-malloc/uncategorized.pl +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/perl -w -# -# 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/. - -# This tool is used to construct the ``type inference'' file. It -# prints the total number of bytes that are attributed to a type that -# cannot be inferred, grouped by stack trace; e.g., -# -# (100) PR_Malloc -# (50) foo -# (50) foo2::foo2 -# (25) bar -# (25) baz -# (50) __builtin_new -# (50) foo2::foo2 -# -# -# Which indicates that 100 bytes were allocated by uninferrable -# classes via PR_Malloc(). Of that 100 bytes, 50 were allocated from -# calls by foo(), 25 from calls by bar(), and 25 from calls by baz(). -# 50 bytes were allocated by __builtin_new from foo2's ctor. -# -# -# From this, we might be able to infer the type of the object that was -# created by examining the PR_Malloc() usage in foo() and the -# ::operator new() usage in foo2(), and could add new type inference -# rules; e.g., -# -# -# foo -# foo2 -# -# # Attribute ::operator new() usage in foo2's ctor to foo2 -# -# __builtin_new -# foo2::foo2 - -use 5.004; -use strict; -use Getopt::Long; - -# So we can find TraceMalloc.pm -use FindBin; -use lib "$FindBin::Bin"; - -use TraceMalloc; - -# Collect program options -$::opt_help = 0; -$::opt_depth = 10; -$::opt_types = "${FindBin::Bin}/types.dat"; -GetOptions("help", "depth=n", "types=s"); - -if ($::opt_help) { - die "usage: uncategorized.pl [options] - --help Display this message - --depth= Display at most stack frames - --types= Read type heuristics from "; -} - -# Initialize type inference juju from the type file specified by -# ``--types''. -TraceMalloc::init_type_inference($::opt_types); - -# Read the objects from the dump file. For each object, remember up to -# ``--depth'' stack frames (from the top). Thread together common -# stack prefixes, accumulating the number of bytes attributed to the -# prefix. - -# This'll hold the inverted stacks -$::Stacks = { '#bytes#' => 0 }; - -sub collect_stacks($) { - my ($object) = @_; - my $stack = $object->{'stack'}; - - return unless ($object->{'type'} eq 'void*') && (TraceMalloc::infer_type($stack) eq 'void*'); - - my $count = 0; - my $link = \%::Stacks; - FRAME: foreach my $frame (@$stack) { - last FRAME unless $count++ < $::opt_depth; - - $link->{'#bytes#'} += $object->{'size'}; - $link->{$frame} = { '#bytes#' => 0 } unless $link->{$frame}; - $link = $link->{$frame}; - } -} - -TraceMalloc::read(\&collect_stacks); - -# Do a depth-first walk of the inverted stack tree. - -sub walk($$) { - my ($links, $indent) = @_; - - my @keys; - KEY: foreach my $key (keys %$links) { - next KEY if $key eq '#bytes#'; - $keys[$#keys + 1] = $key; - } - - foreach my $key (sort { $links->{$b}->{'#bytes#'} <=> $links->{$a}->{'#bytes#'} } @keys) { - for (my $i = 0; $i < $indent; ++$i) { - print " "; - } - - print "($links->{$key}->{'#bytes#'}) $key\n"; - - walk($links->{$key}, $indent + 1); - } -} - -walk(\%::Stacks, 0); - diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp index a20c26c92a5e..44c53cc289f2 100644 --- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -32,10 +32,6 @@ #include #endif -#ifdef NS_TRACE_MALLOC -#include "nsTraceMalloc.h" -#endif - #include "mozilla/BlockingResourceBase.h" #include "mozilla/PoisonIOInterposer.h" @@ -1024,14 +1020,6 @@ NS_LogInit() nsTraceRefcnt::SetActivityIsLegal(true); } #endif - -#ifdef NS_TRACE_MALLOC - // XXX we don't have to worry about shutting down trace-malloc; it - // handles this itself, through an atexit() callback. - if (!NS_TraceMallocHasStarted()) { - NS_TraceMallocStartup(-1); // -1 == no logging - } -#endif } EXPORT_XPCOM_API(void) diff --git a/xpcom/base/nscore.h b/xpcom/base/nscore.h index 31badbcb9acf..1140392dc731 100644 --- a/xpcom/base/nscore.h +++ b/xpcom/base/nscore.h @@ -242,7 +242,7 @@ * sense to touch memory pages and free that memory at shutdown, * unless we are running leak stats. */ -#if defined(NS_TRACE_MALLOC) || defined(NS_BUILD_REFCNT_LOGGING) || defined(MOZ_VALGRIND) +#if defined(NS_BUILD_REFCNT_LOGGING) || defined(MOZ_VALGRIND) #define NS_FREE_PERMANENT_DATA #endif diff --git a/xpcom/glue/standalone/nsXPCOMGlue.cpp b/xpcom/glue/standalone/nsXPCOMGlue.cpp index f51606d96718..35b55528bc92 100644 --- a/xpcom/glue/standalone/nsXPCOMGlue.cpp +++ b/xpcom/glue/standalone/nsXPCOMGlue.cpp @@ -155,70 +155,6 @@ NS_HIDDEN __typeof(dlclose) __wrap_dlclose; #define dlclose __wrap_dlclose #endif -#ifdef NS_TRACE_MALLOC -extern "C" { -NS_EXPORT_(__ptr_t) __libc_malloc(size_t); -NS_EXPORT_(__ptr_t) __libc_calloc(size_t, size_t); -NS_EXPORT_(__ptr_t) __libc_realloc(__ptr_t, size_t); -NS_EXPORT_(void) __libc_free(__ptr_t); -NS_EXPORT_(__ptr_t) __libc_memalign(size_t, size_t); -NS_EXPORT_(__ptr_t) __libc_valloc(size_t); -} - -static __ptr_t (*_malloc)(size_t) = __libc_malloc; -static __ptr_t (*_calloc)(size_t, size_t) = __libc_calloc; -static __ptr_t (*_realloc)(__ptr_t, size_t) = __libc_realloc; -static void (*_free)(__ptr_t) = __libc_free; -static __ptr_t (*_memalign)(size_t, size_t) = __libc_memalign; -static __ptr_t (*_valloc)(size_t) = __libc_valloc; - -NS_EXPORT_(__ptr_t) malloc(size_t size) -{ - return _malloc(size); -} - -NS_EXPORT_(__ptr_t) calloc(size_t nmemb, size_t size) -{ - return _calloc(nmemb, size); -} - -NS_EXPORT_(__ptr_t) realloc(__ptr_t ptr, size_t size) -{ - return _realloc(ptr, size); -} - -NS_EXPORT_(void) free(__ptr_t ptr) -{ - _free(ptr); -} - -NS_EXPORT_(void) cfree(__ptr_t ptr) -{ - _free(ptr); -} - -NS_EXPORT_(__ptr_t) memalign(size_t boundary, size_t size) -{ - return _memalign(boundary, size); -} - -NS_EXPORT_(int) -posix_memalign(void** memptr, size_t alignment, size_t size) -{ - __ptr_t ptr = _memalign(alignment, size); - if (!ptr) { - return ENOMEM; - } - *memptr = ptr; - return 0; -} - -NS_EXPORT_(__ptr_t) valloc(size_t size) -{ - return _valloc(size); -} -#endif /* NS_TRACE_MALLOC */ - typedef void* LibHandleType; static LibHandleType @@ -322,17 +258,6 @@ typedef Scoped ScopedCloseFile; static void XPCOMGlueUnload() { -#if !defined(XP_WIN) && !defined(XP_MACOSX) && defined(NS_TRACE_MALLOC) - if (sTop) { - _malloc = __libc_malloc; - _calloc = __libc_calloc; - _realloc = __libc_realloc; - _free = __libc_free; - _memalign = __libc_memalign; - _valloc = __libc_valloc; - } -#endif - while (sTop) { CloseLibHandle(sTop->libHandle); @@ -468,15 +393,6 @@ XPCOMGlueLoad(const char* aXPCOMFile) return nullptr; } -#if !defined(XP_WIN) && !defined(XP_MACOSX) && defined(NS_TRACE_MALLOC) - _malloc = (__ptr_t(*)(size_t)) GetSymbol(sTop->libHandle, "malloc"); - _calloc = (__ptr_t(*)(size_t, size_t)) GetSymbol(sTop->libHandle, "calloc"); - _realloc = (__ptr_t(*)(__ptr_t, size_t)) GetSymbol(sTop->libHandle, "realloc"); - _free = (void(*)(__ptr_t)) GetSymbol(sTop->libHandle, "free"); - _memalign = (__ptr_t(*)(size_t, size_t)) GetSymbol(sTop->libHandle, "memalign"); - _valloc = (__ptr_t(*)(size_t)) GetSymbol(sTop->libHandle, "valloc"); -#endif - return sym; } From 3aabf959b674953af7583cae0d0fab238ca12a99 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 00:01:25 -0800 Subject: [PATCH 004/224] Bug 1116735 - Allocate frames in the decoder. r=tn --HG-- extra : rebase_source : df5c3cbe4e8a8ad40e4a7fa04a2c53e1c3bad559 --- image/decoders/nsBMPDecoder.cpp | 35 ++++--- image/decoders/nsBMPDecoder.h | 3 + image/src/Decoder.cpp | 163 +++++++++++++++++++++++++++++--- image/src/Decoder.h | 26 +++++ image/src/FrameAnimator.cpp | 6 -- image/src/FrameAnimator.h | 5 - image/src/ImageMetadata.h | 6 +- image/src/RasterImage.cpp | 135 +++----------------------- image/src/RasterImage.h | 39 +++----- 9 files changed, 229 insertions(+), 189 deletions(-) diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp index 0ec4d0f7620c..6b71478e1429 100644 --- a/image/decoders/nsBMPDecoder.cpp +++ b/image/decoders/nsBMPDecoder.cpp @@ -39,17 +39,22 @@ GetBMPLog() #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col) nsBMPDecoder::nsBMPDecoder(RasterImage& aImage) - : Decoder(aImage) -{ - mColors = nullptr; - mRow = nullptr; - mCurPos = mPos = mNumColors = mRowBytes = 0; - mOldLine = mCurLine = 1; // Otherwise decoder will never start - mState = eRLEStateInitial; - mStateData = 0; - mLOH = WIN_V3_HEADER_LENGTH; - mUseAlphaData = mHaveAlphaData = false; -} + : Decoder(aImage) + , mPos(0) + , mLOH(WIN_V3_HEADER_LENGTH) + , mNumColors(0) + , mColors(nullptr) + , mRow(nullptr) + , mRowBytes(0) + , mCurLine(1) // Otherwise decoder will never start. + , mOldLine(1) + , mCurPos(0) + , mState(eRLEStateInitial) + , mStateData(0) + , mProcessedHeader(false) + , mUseAlphaData(false) + , mHaveAlphaData(false) +{ } nsBMPDecoder::~nsBMPDecoder() { @@ -327,10 +332,12 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount, // data. In the latter case aCount should be 0. MOZ_ASSERT(mPos >= mLOH || aCount == 0); - // HasSize is called to ensure that if at this point mPos == mLOH but - // we have no data left to process, the next time WriteInternal is called + // mProcessedHeader is checked to ensure that if at this point mPos == mLOH + // but we have no data left to process, the next time WriteInternal is called // we won't enter this condition again. - if (mPos == mLOH && !HasSize()) { + if (mPos == mLOH && !mProcessedHeader) { + mProcessedHeader = true; + ProcessInfoHeader(); PR_LOG(GetBMPLog(), PR_LOG_DEBUG, ("BMP is %lix%lix%lu. compression=%lu\n", diff --git a/image/decoders/nsBMPDecoder.h b/image/decoders/nsBMPDecoder.h index 7749a903b0dd..4446b08afe5f 100644 --- a/image/decoders/nsBMPDecoder.h +++ b/image/decoders/nsBMPDecoder.h @@ -94,6 +94,9 @@ private: /// data to native data as necessary void ProcessInfoHeader(); + /// True if we've already processed the BMP header. + bool mProcessedHeader; + // Stores whether the image data may store alpha data, or if // the alpha data is unspecified and filled with a padding byte of 0. // When a 32BPP bitmap is stored in an ICO or CUR file, its 4th byte diff --git a/image/src/Decoder.cpp b/image/src/Decoder.cpp index af075a8f1e2b..74050072dfaf 100644 --- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -5,12 +5,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Decoder.h" + +#include "mozilla/gfx/2D.h" +#include "imgIContainer.h" #include "nsIConsoleService.h" #include "nsIScriptError.h" #include "GeckoProfiler.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" +using mozilla::gfx::IntSize; +using mozilla::gfx::SurfaceFormat; + namespace mozilla { namespace image { @@ -82,6 +88,7 @@ Decoder::InitSharedDecoder(uint8_t* aImageData, uint32_t aImageDataLength, // We have all the frame data, so we've started the frame. if (!IsSizeDecode()) { + mFrameCount++; PostFrameStart(); } @@ -232,19 +239,19 @@ Decoder::AllocateFrame() MOZ_ASSERT(mNeedsNewFrame); MOZ_ASSERT(NS_IsMainThread()); - mCurrentFrame = mImage.EnsureFrame(mNewFrameData.mFrameNum, - mNewFrameData.mFrameRect, - mDecodeFlags, - mNewFrameData.mFormat, - mNewFrameData.mPaletteDepth, - mCurrentFrame.get()); + mCurrentFrame = EnsureFrame(mNewFrameData.mFrameNum, + mNewFrameData.mFrameRect, + mDecodeFlags, + mNewFrameData.mFormat, + mNewFrameData.mPaletteDepth, + mCurrentFrame.get()); if (mCurrentFrame) { // Gather the raw pointers the decoders will use. mCurrentFrame->GetImageData(&mImageData, &mImageDataLength); mCurrentFrame->GetPaletteData(&mColormap, &mColormapSize); - if (mNewFrameData.mFrameNum == mFrameCount) { + if (mNewFrameData.mFrameNum + 1 == mFrameCount) { PostFrameStart(); } } else { @@ -264,6 +271,141 @@ Decoder::AllocateFrame() return mCurrentFrame ? NS_OK : NS_ERROR_FAILURE; } +RawAccessFrameRef +Decoder::EnsureFrame(uint32_t aFrameNum, + const nsIntRect& aFrameRect, + uint32_t aDecodeFlags, + SurfaceFormat aFormat, + uint8_t aPaletteDepth, + imgFrame* aPreviousFrame) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (mDataError || NS_FAILED(mFailCode)) { + return RawAccessFrameRef(); + } + + MOZ_ASSERT(aFrameNum <= mFrameCount, "Invalid frame index!"); + if (aFrameNum > mFrameCount) { + return RawAccessFrameRef(); + } + + // Adding a frame that doesn't already exist. This is the normal case. + if (aFrameNum == mFrameCount) { + return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat, + aPaletteDepth, aPreviousFrame); + } + + // We're replacing a frame. It must be the first frame; there's no reason to + // ever replace any other frame, since the first frame is the only one we + // speculatively allocate without knowing what the decoder really needs. + // XXX(seth): I'm not convinced there's any reason to support this at all. We + // should figure out how to avoid triggering this and rip it out. + MOZ_ASSERT(aFrameNum == 0, "Replacing a frame other than the first?"); + MOZ_ASSERT(mFrameCount == 1, "Should have only one frame"); + MOZ_ASSERT(aPreviousFrame, "Need the previous frame to replace"); + if (aFrameNum != 0 || !aPreviousFrame || mFrameCount != 1) { + return RawAccessFrameRef(); + } + + MOZ_ASSERT(!aPreviousFrame->GetRect().IsEqualEdges(aFrameRect) || + aPreviousFrame->GetFormat() != aFormat || + aPreviousFrame->GetPaletteDepth() != aPaletteDepth, + "Replacing first frame with the same kind of frame?"); + + // Remove the old frame from the SurfaceCache. + IntSize prevFrameSize = aPreviousFrame->GetImageSize(); + SurfaceCache::RemoveSurface(ImageKey(&mImage), + RasterSurfaceKey(prevFrameSize, aDecodeFlags, 0)); + mFrameCount = 0; + mInFrame = false; + + // Add the new frame as usual. + return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat, + aPaletteDepth, nullptr); +} + +RawAccessFrameRef +Decoder::InternalAddFrame(uint32_t aFrameNum, + const nsIntRect& aFrameRect, + uint32_t aDecodeFlags, + SurfaceFormat aFormat, + uint8_t aPaletteDepth, + imgFrame* aPreviousFrame) +{ + MOZ_ASSERT(aFrameNum <= mFrameCount, "Invalid frame index!"); + if (aFrameNum > mFrameCount) { + return RawAccessFrameRef(); + } + + MOZ_ASSERT(mImageMetadata.HasSize()); + nsIntSize imageSize(mImageMetadata.GetWidth(), mImageMetadata.GetHeight()); + if (imageSize.width <= 0 || imageSize.height <= 0 || + aFrameRect.width <= 0 || aFrameRect.height <= 0) { + NS_WARNING("Trying to add frame with zero or negative size"); + return RawAccessFrameRef(); + } + + if (!SurfaceCache::CanHold(imageSize.ToIntSize())) { + NS_WARNING("Trying to add frame that's too large for the SurfaceCache"); + return RawAccessFrameRef(); + } + + nsRefPtr frame = new imgFrame(); + if (NS_FAILED(frame->InitForDecoder(imageSize, aFrameRect, aFormat, + aPaletteDepth))) { + NS_WARNING("imgFrame::Init should succeed"); + return RawAccessFrameRef(); + } + frame->SetAsNonPremult(aDecodeFlags & + imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA); + + RawAccessFrameRef ref = frame->RawAccessRef(); + if (!ref) { + return RawAccessFrameRef(); + } + + bool succeeded = + SurfaceCache::Insert(frame, ImageKey(&mImage), + RasterSurfaceKey(imageSize.ToIntSize(), + aDecodeFlags, + aFrameNum), + Lifetime::Persistent); + if (!succeeded) { + return RawAccessFrameRef(); + } + + nsIntRect refreshArea; + + if (aFrameNum == 1) { + MOZ_ASSERT(aPreviousFrame, "Must provide a previous frame when animated"); + aPreviousFrame->SetRawAccessOnly(); + + // If we dispose of the first frame by clearing it, then the first frame's + // refresh area is all of itself. + // RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR). + DisposalMethod disposalMethod = aPreviousFrame->GetDisposalMethod(); + if (disposalMethod == DisposalMethod::CLEAR || + disposalMethod == DisposalMethod::CLEAR_ALL || + disposalMethod == DisposalMethod::RESTORE_PREVIOUS) { + refreshArea = aPreviousFrame->GetRect(); + } + } + + if (aFrameNum > 0) { + ref->SetRawAccessOnly(); + + // Some GIFs are huge but only have a small area that they animate. We only + // need to refresh that small area when frame 0 comes around again. + refreshArea.UnionRect(refreshArea, frame->GetRect()); + } + + mFrameCount++; + mImage.OnAddedFrame(mFrameCount, refreshArea); + + return ref; +} + void Decoder::SetSizeOnImage() { @@ -316,7 +458,6 @@ Decoder::PostFrameStart() NS_ABORT_IF_FALSE(!mInFrame, "Starting new frame but not done with old one!"); // Update our state to reflect the new frame - mFrameCount++; mInFrame = true; // If we just became animated, record that fact. @@ -324,12 +465,6 @@ Decoder::PostFrameStart() mIsAnimated = true; mProgress |= FLAG_IS_ANIMATED; } - - // Decoder implementations should only call this method if they successfully - // appended the frame to the image. So mFrameCount should always match that - // reported by the Image. - MOZ_ASSERT(mFrameCount == mImage.GetNumFrames(), - "Decoder frame count doesn't match image's!"); } void diff --git a/image/src/Decoder.h b/image/src/Decoder.h index 16d38780a310..bfb816bd21f0 100644 --- a/image/src/Decoder.h +++ b/image/src/Decoder.h @@ -159,6 +159,11 @@ public: bool HasSize() const { return mImageMetadata.HasSize(); } void SetSizeOnImage(); + void SetSize(const nsIntSize& aSize, const Orientation& aOrientation) + { + PostSize(aSize.width, aSize.height, aOrientation); + } + // Use HistogramCount as an invalid Histogram ID virtual Telemetry::ID SpeedHistogram() { return Telemetry::HistogramCount; } @@ -265,6 +270,27 @@ protected: void PostDataError(); void PostDecoderError(nsresult aFailCode); + /** + * Ensures that a given frame number exists with the given parameters, and + * returns a RawAccessFrameRef for that frame. + * It is not possible to create sparse frame arrays; you can only append + * frames to the current frame array, or if there is only one frame in the + * array, replace that frame. + * If a non-paletted frame is desired, pass 0 for aPaletteDepth. + */ + RawAccessFrameRef EnsureFrame(uint32_t aFrameNum, + const nsIntRect& aFrameRect, + uint32_t aDecodeFlags, + gfx::SurfaceFormat aFormat, + uint8_t aPaletteDepth, + imgFrame* aPreviousFrame); + + RawAccessFrameRef InternalAddFrame(uint32_t aFrameNum, + const nsIntRect& aFrameRect, + uint32_t aDecodeFlags, + gfx::SurfaceFormat aFormat, + uint8_t aPaletteDepth, + imgFrame* aPreviousFrame); /* * Member variables. * diff --git a/image/src/FrameAnimator.cpp b/image/src/FrameAnimator.cpp index 15fc9228de7a..f80a6e60f02f 100644 --- a/image/src/FrameAnimator.cpp +++ b/image/src/FrameAnimator.cpp @@ -246,12 +246,6 @@ FrameAnimator::SetAnimationFrameTime(const TimeStamp& aTime) mCurrentAnimationFrameTime = aTime; } -void -FrameAnimator::SetFirstFrameRefreshArea(const nsIntRect& aRect) -{ - mFirstFrameRefreshArea = aRect; -} - void FrameAnimator::UnionFirstFrameRefreshArea(const nsIntRect& aRect) { diff --git a/image/src/FrameAnimator.h b/image/src/FrameAnimator.h index bef92dc992d7..b918082f03d7 100644 --- a/image/src/FrameAnimator.h +++ b/image/src/FrameAnimator.h @@ -99,11 +99,6 @@ public: */ void SetAnimationMode(uint16_t aAnimationMode); - /** - * Set the area to refresh when we loop around to the first frame. - */ - void SetFirstFrameRefreshArea(const nsIntRect& aRect); - /** * Union the area to refresh when we loop around to the first frame with this * rect. diff --git a/image/src/ImageMetadata.h b/image/src/ImageMetadata.h index e05d9b3c0e65..d2546592c764 100644 --- a/image/src/ImageMetadata.h +++ b/image/src/ImageMetadata.h @@ -42,8 +42,10 @@ public: void SetSize(int32_t width, int32_t height, Orientation orientation) { - mSize.emplace(nsIntSize(width, height)); - mOrientation.emplace(orientation); + if (!HasSize()) { + mSize.emplace(nsIntSize(width, height)); + mOrientation.emplace(orientation); + } } bool HasSize() const { return mSize.isSome(); } diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index 6b43c7198c54..d828f6c176b9 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -930,58 +930,18 @@ RasterImage::SizeOfDecoded(gfxMemoryLocation aLocation, return n; } -RawAccessFrameRef -RasterImage::InternalAddFrame(uint32_t aFrameNum, - const nsIntRect& aFrameRect, - uint32_t aDecodeFlags, - SurfaceFormat aFormat, - uint8_t aPaletteDepth, - imgFrame* aPreviousFrame) +void +RasterImage::OnAddedFrame(uint32_t aNewFrameCount, + const nsIntRect& aNewRefreshArea) { - // We assume that we're in the middle of decoding because we unlock the - // previous frame when we create a new frame, and only when decoding do we - // lock frames. - MOZ_ASSERT(mDecoder, "Only decoders may add frames!"); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT((mFrameCount == 1 && aNewFrameCount == 1) || + mFrameCount < aNewFrameCount, + "Frame count running backwards"); - MOZ_ASSERT(aFrameNum <= GetNumFrames(), "Invalid frame index!"); - if (aFrameNum > GetNumFrames()) { - return RawAccessFrameRef(); - } + mFrameCount = aNewFrameCount; - if (mSize.width <= 0 || mSize.height <= 0) { - NS_WARNING("Trying to add frame with zero or negative size"); - return RawAccessFrameRef(); - } - - if (!SurfaceCache::CanHold(mSize.ToIntSize())) { - NS_WARNING("Trying to add frame that's too large for the SurfaceCache"); - return RawAccessFrameRef(); - } - - nsRefPtr frame = new imgFrame(); - if (NS_FAILED(frame->InitForDecoder(mSize, aFrameRect, aFormat, - aPaletteDepth))) { - NS_WARNING("imgFrame::Init should succeed"); - return RawAccessFrameRef(); - } - frame->SetAsNonPremult(aDecodeFlags & FLAG_DECODE_NO_PREMULTIPLY_ALPHA); - - RawAccessFrameRef ref = frame->RawAccessRef(); - if (!ref) { - return RawAccessFrameRef(); - } - - bool succeeded = - SurfaceCache::Insert(frame, ImageKey(this), - RasterSurfaceKey(mSize.ToIntSize(), - aDecodeFlags, - aFrameNum), - Lifetime::Persistent); - if (!succeeded) { - return RawAccessFrameRef(); - } - - if (aFrameNum == 1) { + if (aNewFrameCount == 2) { // We're becoming animated, so initialize animation stuff. MOZ_ASSERT(!mAnim, "Already have animation state?"); mAnim = MakeUnique(this, mSize.ToIntSize(), mAnimationMode); @@ -996,34 +956,14 @@ RasterImage::InternalAddFrame(uint32_t aFrameNum, // in the old world either, locking is acceptable for the moment. LockImage(); - MOZ_ASSERT(aPreviousFrame, "Must provide a previous frame when animated"); - aPreviousFrame->SetRawAccessOnly(); - - // If we dispose of the first frame by clearing it, then the first frame's - // refresh area is all of itself. - // RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR). - DisposalMethod disposalMethod = aPreviousFrame->GetDisposalMethod(); - if (disposalMethod == DisposalMethod::CLEAR || - disposalMethod == DisposalMethod::CLEAR_ALL || - disposalMethod == DisposalMethod::RESTORE_PREVIOUS) { - mAnim->SetFirstFrameRefreshArea(aPreviousFrame->GetRect()); - } - if (mPendingAnimation && ShouldAnimate()) { StartAnimation(); } } - if (aFrameNum > 0) { - ref->SetRawAccessOnly(); - - // Some GIFs are huge but only have a small area that they animate. We only - // need to refresh that small area when frame 0 comes around again. - mAnim->UnionFirstFrameRefreshArea(frame->GetRect()); + if (aNewFrameCount > 1) { + mAnim->UnionFirstFrameRefreshArea(aNewRefreshArea); } - - mFrameCount++; - return ref; } nsresult @@ -1064,58 +1004,6 @@ RasterImage::SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation) return NS_OK; } -RawAccessFrameRef -RasterImage::EnsureFrame(uint32_t aFrameNum, - const nsIntRect& aFrameRect, - uint32_t aDecodeFlags, - SurfaceFormat aFormat, - uint8_t aPaletteDepth, - imgFrame* aPreviousFrame) -{ - if (mError) { - return RawAccessFrameRef(); - } - - MOZ_ASSERT(aFrameNum <= GetNumFrames(), "Invalid frame index!"); - if (aFrameNum > GetNumFrames()) { - return RawAccessFrameRef(); - } - - // Adding a frame that doesn't already exist. This is the normal case. - if (aFrameNum == GetNumFrames()) { - return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat, - aPaletteDepth, aPreviousFrame); - } - - // We're replacing a frame. It must be the first frame; there's no reason to - // ever replace any other frame, since the first frame is the only one we - // speculatively allocate without knowing what the decoder really needs. - // XXX(seth): I'm not convinced there's any reason to support this at all. We - // should figure out how to avoid triggering this and rip it out. - MOZ_ASSERT(aFrameNum == 0, "Replacing a frame other than the first?"); - MOZ_ASSERT(GetNumFrames() == 1, "Should have only one frame"); - MOZ_ASSERT(aPreviousFrame, "Need the previous frame to replace"); - MOZ_ASSERT(!mAnim, "Shouldn't be animated"); - if (aFrameNum != 0 || !aPreviousFrame || GetNumFrames() != 1) { - return RawAccessFrameRef(); - } - - MOZ_ASSERT(!aPreviousFrame->GetRect().IsEqualEdges(aFrameRect) || - aPreviousFrame->GetFormat() != aFormat || - aPreviousFrame->GetPaletteDepth() != aPaletteDepth, - "Replacing first frame with the same kind of frame?"); - - // Remove the old frame from the SurfaceCache. - IntSize prevFrameSize = aPreviousFrame->GetImageSize(); - SurfaceCache::RemoveSurface(ImageKey(this), - RasterSurfaceKey(prevFrameSize, aDecodeFlags, 0)); - mFrameCount = 0; - - // Add the new frame as usual. - return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat, - aPaletteDepth, nullptr); -} - void RasterImage::DecodingComplete(imgFrame* aFinalFrame) { @@ -1631,6 +1519,7 @@ RasterImage::InitDecoder(bool aDoSizeDecode) // We already have the size; tell the decoder so it can preallocate a // frame. By default, we create an ARGB frame with no offset. If decoders // need a different type, they need to ask for it themselves. + mDecoder->SetSize(mSize, mOrientation); mDecoder->NeedNewFrame(0, 0, 0, mSize.width, mSize.height, SurfaceFormat::B8G8R8A8); mDecoder->AllocateFrame(); diff --git a/image/src/RasterImage.h b/image/src/RasterImage.h index 1ffd13865214..6ffebb282c78 100644 --- a/image/src/RasterImage.h +++ b/image/src/RasterImage.h @@ -177,7 +177,12 @@ public: /* Triggers discarding. */ void Discard(); - /* Callbacks for decoders */ + + ////////////////////////////////////////////////////////////////////////////// + // Decoder callbacks. + ////////////////////////////////////////////////////////////////////////////// + + void OnAddedFrame(uint32_t aNewFrameCount, const nsIntRect& aNewRefreshArea); /** Sets the size and inherent orientation of the container. This should only * be called by the decoder. This function may be called multiple times, but @@ -185,30 +190,20 @@ public: */ nsresult SetSize(int32_t aWidth, int32_t aHeight, Orientation aOrientation); - /** - * Ensures that a given frame number exists with the given parameters, and - * returns a RawAccessFrameRef for that frame. - * It is not possible to create sparse frame arrays; you can only append - * frames to the current frame array, or if there is only one frame in the - * array, replace that frame. - * If a non-paletted frame is desired, pass 0 for aPaletteDepth. - */ - RawAccessFrameRef EnsureFrame(uint32_t aFrameNum, - const nsIntRect& aFrameRect, - uint32_t aDecodeFlags, - gfx::SurfaceFormat aFormat, - uint8_t aPaletteDepth, - imgFrame* aPreviousFrame); - - /* notification that the entire image has been decoded */ - void DecodingComplete(imgFrame* aFinalFrame); - /** * Number of times to loop the image. * @note -1 means forever. */ void SetLoopCount(int32_t aLoopCount); + /* notification that the entire image has been decoded */ + void DecodingComplete(imgFrame* aFinalFrame); + + + ////////////////////////////////////////////////////////////////////////////// + // Network callbacks. + ////////////////////////////////////////////////////////////////////////////// + /* Add compressed source data to the imgContainer. * * The decoder will use this data, either immediately or at draw time, to @@ -309,12 +304,6 @@ private: size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const; - RawAccessFrameRef InternalAddFrame(uint32_t aFrameNum, - const nsIntRect& aFrameRect, - uint32_t aDecodeFlags, - gfx::SurfaceFormat aFormat, - uint8_t aPaletteDepth, - imgFrame* aPreviousFrame); nsresult DoImageDataComplete(); already_AddRefed GetCurrentImage(); From 2308938365924d1d04b58fa22915e16c00837629 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 00:04:31 -0800 Subject: [PATCH 005/224] Bug 1116733 (Part 1) - Allocate frames off-main-thread. r=tn --- image/decoders/nsGIFDecoder2.cpp | 14 +- image/decoders/nsPNGDecoder.cpp | 11 +- image/src/Decoder.cpp | 47 ++- image/src/FrameAnimator.cpp | 161 +++++----- image/src/RasterImage.cpp | 54 +++- image/src/SurfaceCache.cpp | 34 +- image/src/imgFrame.cpp | 290 +++++++++++++----- image/src/imgFrame.h | 213 +++++++++---- .../2d.drawImage.broken.html.ini | 5 - 9 files changed, 537 insertions(+), 292 deletions(-) delete mode 100644 testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.broken.html.ini diff --git a/image/decoders/nsGIFDecoder2.cpp b/image/decoders/nsGIFDecoder2.cpp index df87a13199e4..89a9d56da959 100644 --- a/image/decoders/nsGIFDecoder2.cpp +++ b/image/decoders/nsGIFDecoder2.cpp @@ -199,12 +199,6 @@ nsGIFDecoder2::BeginImageFrame(uint16_t aDepth) NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset, mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height, format); - } else { - // Our preallocated frame matches up, with the possible exception - // of alpha. - if (format == gfx::SurfaceFormat::B8G8R8X8) { - currentFrame->SetHasNoAlpha(); - } } } @@ -233,8 +227,12 @@ nsGIFDecoder2::EndImageFrame() mGIFStruct.screen_height - realFrameHeight); PostInvalidation(r); } - // This transparency check is only valid for first frame - if (mGIFStruct.is_transparent && !mSawTransparency) { + + // The first frame was preallocated with alpha; if it wasn't transparent, we + // should fix that. We can also mark it opaque unconditionally if we didn't + // actually see any transparent pixels - this test is only valid for the + // first frame. + if (!mGIFStruct.is_transparent || !mSawTransparency) { opacity = Opacity::OPAQUE; } } diff --git a/image/decoders/nsPNGDecoder.cpp b/image/decoders/nsPNGDecoder.cpp index af28b36c6ec0..bc3a4433f46f 100644 --- a/image/decoders/nsPNGDecoder.cpp +++ b/image/decoders/nsPNGDecoder.cpp @@ -165,11 +165,6 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, NeedNewFrame(mNumFrames, x_offset, y_offset, width, height, format); } else if (mNumFrames != 0) { NeedNewFrame(mNumFrames, x_offset, y_offset, width, height, format); - } else { - // Our preallocated frame matches up, with the possible exception of alpha. - if (format == gfx::SurfaceFormat::B8G8R8X8) { - currentFrame->SetHasNoAlpha(); - } } mFrameRect = neededRect; @@ -204,11 +199,9 @@ nsPNGDecoder::EndImageFrame() mNumFrames++; - Opacity opacity; - if (mFrameHasNoAlpha) { + Opacity opacity = Opacity::SOME_TRANSPARENCY; + if (format == gfx::SurfaceFormat::B8G8R8X8 || mFrameHasNoAlpha) { opacity = Opacity::OPAQUE; - } else { - opacity = Opacity::SOME_TRANSPARENCY; } #ifdef PNG_APNG_SUPPORTED diff --git a/image/src/Decoder.cpp b/image/src/Decoder.cpp index 74050072dfaf..bbbcd525aefb 100644 --- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -134,19 +134,18 @@ Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) // Pass the data along to the implementation WriteInternal(aBuffer, aCount, aStrategy); - // If we're a synchronous decoder and we need a new frame to proceed, let's - // create one and call it again. - if (aStrategy == DecodeStrategy::SYNC) { - while (NeedsNewFrame() && !HasDataError()) { - nsresult rv = AllocateFrame(); + // If we need a new frame to proceed, let's create one and call it again. + while (NeedsNewFrame() && !HasDataError()) { + MOZ_ASSERT(!IsSizeDecode(), "Shouldn't need new frame for size decode"); - if (NS_SUCCEEDED(rv)) { - // Use the data we saved when we asked for a new frame. - WriteInternal(nullptr, 0, aStrategy); - } + nsresult rv = AllocateFrame(); - mNeedsToFlushData = false; + if (NS_SUCCEEDED(rv)) { + // Use the data we saved when we asked for a new frame. + WriteInternal(nullptr, 0, aStrategy); } + + mNeedsToFlushData = false; } // Finish telemetry. @@ -237,7 +236,6 @@ nsresult Decoder::AllocateFrame() { MOZ_ASSERT(mNeedsNewFrame); - MOZ_ASSERT(NS_IsMainThread()); mCurrentFrame = EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mFrameRect, @@ -279,8 +277,6 @@ Decoder::EnsureFrame(uint32_t aFrameNum, uint8_t aPaletteDepth, imgFrame* aPreviousFrame) { - MOZ_ASSERT(NS_IsMainThread()); - if (mDataError || NS_FAILED(mFailCode)) { return RawAccessFrameRef(); } @@ -352,13 +348,13 @@ Decoder::InternalAddFrame(uint32_t aFrameNum, } nsRefPtr frame = new imgFrame(); + bool nonPremult = + aDecodeFlags & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA; if (NS_FAILED(frame->InitForDecoder(imageSize, aFrameRect, aFormat, - aPaletteDepth))) { + aPaletteDepth, nonPremult))) { NS_WARNING("imgFrame::Init should succeed"); return RawAccessFrameRef(); } - frame->SetAsNonPremult(aDecodeFlags & - imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA); RawAccessFrameRef ref = frame->RawAccessRef(); if (!ref) { @@ -384,11 +380,11 @@ Decoder::InternalAddFrame(uint32_t aFrameNum, // If we dispose of the first frame by clearing it, then the first frame's // refresh area is all of itself. // RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR). - DisposalMethod disposalMethod = aPreviousFrame->GetDisposalMethod(); - if (disposalMethod == DisposalMethod::CLEAR || - disposalMethod == DisposalMethod::CLEAR_ALL || - disposalMethod == DisposalMethod::RESTORE_PREVIOUS) { - refreshArea = aPreviousFrame->GetRect(); + AnimationData previousFrameData = aPreviousFrame->GetAnimationData(); + if (previousFrameData.mDisposalMethod == DisposalMethod::CLEAR || + previousFrameData.mDisposalMethod == DisposalMethod::CLEAR_ALL || + previousFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) { + refreshArea = previousFrameData.mRect; } } @@ -481,14 +477,7 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */, // Update our state mInFrame = false; - if (aFrameOpacity == Opacity::OPAQUE) { - mCurrentFrame->SetHasNoAlpha(); - } - - mCurrentFrame->SetDisposalMethod(aDisposalMethod); - mCurrentFrame->SetRawTimeout(aTimeout); - mCurrentFrame->SetBlendMethod(aBlendMethod); - mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect()); + mCurrentFrame->Finish(aFrameOpacity, aDisposalMethod, aTimeout, aBlendMethod); mProgress |= FLAG_FRAME_COMPLETE | FLAG_ONLOAD_UNBLOCKED; } diff --git a/image/src/FrameAnimator.cpp b/image/src/FrameAnimator.cpp index f80a6e60f02f..1819c60b0269 100644 --- a/image/src/FrameAnimator.cpp +++ b/image/src/FrameAnimator.cpp @@ -289,7 +289,7 @@ int32_t FrameAnimator::GetTimeoutForFrame(uint32_t aFrameNum) const { RawAccessFrameRef frame = GetRawFrame(aFrameNum); - const int32_t timeout = frame->GetRawTimeout(); + AnimationData data = frame->GetAnimationData(); // Ensure a minimal time between updates so we don't throttle the UI thread. // consider 0 == unspecified and make it fast but not too fast. Unless we @@ -304,11 +304,11 @@ FrameAnimator::GetTimeoutForFrame(uint32_t aFrameNum) const // It seems that there are broken tools out there that set a 0ms or 10ms // timeout when they really want a "default" one. So munge values in that // range. - if (timeout >= 0 && timeout <= 10 && mLoopCount != 0) { + if (data.mRawTimeout >= 0 && data.mRawTimeout <= 10 && mLoopCount != 0) { return 100; } - return timeout; + return data.mRawTimeout; } size_t @@ -352,34 +352,34 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, MOZ_ASSERT(prevFrame && nextFrame, "Should have frames here"); - DisposalMethod prevFrameDisposalMethod = prevFrame->GetDisposalMethod(); - if (prevFrameDisposalMethod == DisposalMethod::RESTORE_PREVIOUS && + AnimationData prevFrameData = prevFrame->GetAnimationData(); + if (prevFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS && !mCompositingPrevFrame) { - prevFrameDisposalMethod = DisposalMethod::CLEAR; + prevFrameData.mDisposalMethod = DisposalMethod::CLEAR; } - nsIntRect prevFrameRect = prevFrame->GetRect(); - bool isFullPrevFrame = (prevFrameRect.x == 0 && prevFrameRect.y == 0 && - prevFrameRect.width == mSize.width && - prevFrameRect.height == mSize.height); + bool isFullPrevFrame = prevFrameData.mRect.x == 0 && + prevFrameData.mRect.y == 0 && + prevFrameData.mRect.width == mSize.width && + prevFrameData.mRect.height == mSize.height; // Optimization: DisposeClearAll if the previous frame is the same size as // container and it's clearing itself if (isFullPrevFrame && - (prevFrameDisposalMethod == DisposalMethod::CLEAR)) { - prevFrameDisposalMethod = DisposalMethod::CLEAR_ALL; + (prevFrameData.mDisposalMethod == DisposalMethod::CLEAR)) { + prevFrameData.mDisposalMethod = DisposalMethod::CLEAR_ALL; } - DisposalMethod nextFrameDisposalMethod = nextFrame->GetDisposalMethod(); - nsIntRect nextFrameRect = nextFrame->GetRect(); - bool isFullNextFrame = (nextFrameRect.x == 0 && nextFrameRect.y == 0 && - nextFrameRect.width == mSize.width && - nextFrameRect.height == mSize.height); + AnimationData nextFrameData = nextFrame->GetAnimationData(); + bool isFullNextFrame = nextFrameData.mRect.x == 0 && + nextFrameData.mRect.y == 0 && + nextFrameData.mRect.width == mSize.width && + nextFrameData.mRect.height == mSize.height; if (!nextFrame->GetIsPaletted()) { // Optimization: Skip compositing if the previous frame wants to clear the // whole image - if (prevFrameDisposalMethod == DisposalMethod::CLEAR_ALL) { + if (prevFrameData.mDisposalMethod == DisposalMethod::CLEAR_ALL) { aDirtyRect->SetRect(0, 0, mSize.width, mSize.height); return true; } @@ -387,19 +387,19 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, // Optimization: Skip compositing if this frame is the same size as the // container and it's fully drawing over prev frame (no alpha) if (isFullNextFrame && - (nextFrameDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) && - !nextFrame->GetHasAlpha()) { + (nextFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) && + !nextFrameData.mHasAlpha) { aDirtyRect->SetRect(0, 0, mSize.width, mSize.height); return true; } } // Calculate area that needs updating - switch (prevFrameDisposalMethod) { + switch (prevFrameData.mDisposalMethod) { default: case DisposalMethod::NOT_SPECIFIED: case DisposalMethod::KEEP: - *aDirtyRect = nextFrameRect; + *aDirtyRect = nextFrameData.mRect; break; case DisposalMethod::CLEAR_ALL: @@ -415,7 +415,7 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, // way at the bottom, and both frames being small, we'd be // telling framechanged to refresh the whole image when only two // small areas are needed. - aDirtyRect->UnionRect(nextFrameRect, prevFrameRect); + aDirtyRect->UnionRect(nextFrameData.mRect, prevFrameData.mRect); break; case DisposalMethod::RESTORE_PREVIOUS: @@ -453,6 +453,8 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, needToBlankComposite = true; } + AnimationData compositingFrameData = mCompositingFrame->GetAnimationData(); + // More optimizations possible when next frame is not transparent // But if the next frame has DisposalMethod::RESTORE_PREVIOUS, // this "no disposal" optimization is not possible, @@ -460,8 +462,8 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, // needs to be stored in compositingFrame, so it can be // copied into compositingPrevFrame later. bool doDisposal = true; - if (!nextFrame->GetHasAlpha() && - nextFrameDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) { + if (!nextFrameData.mHasAlpha && + nextFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) { if (isFullNextFrame) { // Optimization: No need to dispose prev.frame when // next frame is full frame and not transparent. @@ -469,12 +471,12 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, // No need to blank the composite frame needToBlankComposite = false; } else { - if ((prevFrameRect.x >= nextFrameRect.x) && - (prevFrameRect.y >= nextFrameRect.y) && - (prevFrameRect.x + prevFrameRect.width <= - nextFrameRect.x + nextFrameRect.width) && - (prevFrameRect.y + prevFrameRect.height <= - nextFrameRect.y + nextFrameRect.height)) { + if ((prevFrameData.mRect.x >= nextFrameData.mRect.x) && + (prevFrameData.mRect.y >= nextFrameData.mRect.y) && + (prevFrameData.mRect.x + prevFrameData.mRect.width <= + nextFrameData.mRect.x + nextFrameData.mRect.width) && + (prevFrameData.mRect.y + prevFrameData.mRect.height <= + nextFrameData.mRect.y + nextFrameData.mRect.height)) { // Optimization: No need to dispose prev.frame when // next frame fully overlaps previous frame. doDisposal = false; @@ -484,43 +486,46 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, if (doDisposal) { // Dispose of previous: clear, restore, or keep (copy) - switch (prevFrameDisposalMethod) { + switch (prevFrameData.mDisposalMethod) { case DisposalMethod::CLEAR: if (needToBlankComposite) { // If we just created the composite, it could have anything in its // buffer. Clear whole frame - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect); } else { // Only blank out previous frame area (both color & Mask/Alpha) - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect(), - prevFrameRect); + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect, + prevFrameData.mRect); } break; case DisposalMethod::CLEAR_ALL: - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect); break; case DisposalMethod::RESTORE_PREVIOUS: // It would be better to copy only the area changed back to // compositingFrame. if (mCompositingPrevFrame) { - CopyFrameImage(mCompositingPrevFrame->GetRawData(), - mCompositingPrevFrame->GetRect(), - mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + AnimationData compositingPrevFrameData = + mCompositingPrevFrame->GetAnimationData(); + + CopyFrameImage(compositingPrevFrameData.mRawData, + compositingPrevFrameData.mRect, + compositingFrameData.mRawData, + compositingFrameData.mRect); // destroy only if we don't need it for this frame's disposal - if (nextFrameDisposalMethod != + if (nextFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS) { mCompositingPrevFrame.reset(); } } else { - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect); } break; @@ -535,39 +540,39 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, if (mLastCompositedFrameIndex != int32_t(aNextFrameIndex - 1)) { if (isFullPrevFrame && !prevFrame->GetIsPaletted()) { // Just copy the bits - CopyFrameImage(prevFrame->GetRawData(), - prevFrame->GetRect(), - mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + CopyFrameImage(prevFrameData.mRawData, + prevFrameData.mRect, + compositingFrameData.mRawData, + compositingFrameData.mRect); } else { if (needToBlankComposite) { // Only blank composite when prev is transparent or not full. - if (prevFrame->GetHasAlpha() || !isFullPrevFrame) { - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + if (prevFrameData.mHasAlpha || !isFullPrevFrame) { + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect); } } - DrawFrameTo(prevFrame->GetRawData(), prevFrameRect, - prevFrame->PaletteDataLength(), - prevFrame->GetHasAlpha(), - mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect(), - prevFrame->GetBlendMethod()); + DrawFrameTo(prevFrameData.mRawData, prevFrameData.mRect, + prevFrameData.mPaletteDataLength, + prevFrameData.mHasAlpha, + compositingFrameData.mRawData, + compositingFrameData.mRect, + prevFrameData.mBlendMethod); } } } } else if (needToBlankComposite) { // If we just created the composite, it could have anything in its // buffers. Clear them - ClearFrame(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect()); + ClearFrame(compositingFrameData.mRawData, + compositingFrameData.mRect); } // Check if the frame we are composing wants the previous image restored after // it is done. Don't store it (again) if last frame wanted its image restored // too - if ((nextFrameDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) && - (prevFrameDisposalMethod != DisposalMethod::RESTORE_PREVIOUS)) { + if ((nextFrameData.mDisposalMethod == DisposalMethod::RESTORE_PREVIOUS) && + (prevFrameData.mDisposalMethod != DisposalMethod::RESTORE_PREVIOUS)) { // We are storing the whole image. // It would be better if we just stored the area that nextFrame is going to // overwrite. @@ -583,28 +588,26 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect, mCompositingPrevFrame = newFrame->RawAccessRef(); } - CopyFrameImage(mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect(), - mCompositingPrevFrame->GetRawData(), - mCompositingPrevFrame->GetRect()); + AnimationData compositingPrevFrameData = + mCompositingPrevFrame->GetAnimationData(); + + CopyFrameImage(compositingFrameData.mRawData, + compositingFrameData.mRect, + compositingPrevFrameData.mRawData, + compositingPrevFrameData.mRect); } // blit next frame into it's correct spot - DrawFrameTo(nextFrame->GetRawData(), nextFrameRect, - nextFrame->PaletteDataLength(), - nextFrame->GetHasAlpha(), - mCompositingFrame->GetRawData(), - mCompositingFrame->GetRect(), - nextFrame->GetBlendMethod()); - - // Set timeout of CompositeFrame to timeout of frame we just composed - // Bug 177948 - int32_t timeout = nextFrame->GetRawTimeout(); - mCompositingFrame->SetRawTimeout(timeout); + DrawFrameTo(nextFrameData.mRawData, nextFrameData.mRect, + nextFrameData.mPaletteDataLength, + nextFrameData.mHasAlpha, + compositingFrameData.mRawData, + compositingFrameData.mRect, + nextFrameData.mBlendMethod); // Tell the image that it is fully 'downloaded'. nsresult rv = - mCompositingFrame->ImageUpdated(mCompositingFrame->GetRect()); + mCompositingFrame->ImageUpdated(compositingFrameData.mRect); if (NS_FAILED(rv)) { return false; } diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index d828f6c176b9..b4aac4673f3e 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -199,18 +199,14 @@ public: { if (mState == eReady) { // Collect information from the frames that we need to scale. - uint8_t* srcData = mSrcRef->GetImageData(); - IntSize srcSize = mSrcRef->GetSize(); - uint32_t srcStride = mSrcRef->GetImageBytesPerRow(); - uint8_t* dstData = mDstRef->GetImageData(); - uint32_t dstStride = mDstRef->GetImageBytesPerRow(); - SurfaceFormat srcFormat = mSrcRef->GetFormat(); + ScalingData srcData = mSrcRef->GetScalingData(); + ScalingData dstData = mDstRef->GetScalingData(); // Actually do the scaling. bool succeeded = - gfx::Scale(srcData, srcSize.width, srcSize.height, srcStride, - dstData, mDstSize.width, mDstSize.height, dstStride, - srcFormat); + gfx::Scale(srcData.mRawData, srcData.mSize.width, srcData.mSize.height, + srcData.mBytesPerRow, dstData.mRawData, mDstSize.width, + mDstSize.height, dstData.mBytesPerRow, srcData.mFormat); if (succeeded) { // Mark the frame as complete and discardable. @@ -657,6 +653,13 @@ RasterImage::IsOpaque() void RasterImage::OnSurfaceDiscarded() { + if (!NS_IsMainThread()) { + nsCOMPtr runnable = + NS_NewRunnableMethod(this, &RasterImage::OnSurfaceDiscarded); + NS_DispatchToMainThread(runnable); + return; + } + if (mProgressTracker) { mProgressTracker->OnDiscard(); } @@ -930,11 +933,42 @@ RasterImage::SizeOfDecoded(gfxMemoryLocation aLocation, return n; } +class OnAddedFrameRunnable : public nsRunnable +{ +public: + OnAddedFrameRunnable(RasterImage* aImage, + uint32_t aNewFrameCount, + const nsIntRect& aNewRefreshArea) + : mImage(aImage) + , mNewFrameCount(aNewFrameCount) + , mNewRefreshArea(aNewRefreshArea) + { + MOZ_ASSERT(aImage); + } + + NS_IMETHOD Run() + { + mImage->OnAddedFrame(mNewFrameCount, mNewRefreshArea); + return NS_OK; + } + +private: + nsRefPtr mImage; + uint32_t mNewFrameCount; + nsIntRect mNewRefreshArea; +}; + void RasterImage::OnAddedFrame(uint32_t aNewFrameCount, const nsIntRect& aNewRefreshArea) { - MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + nsCOMPtr runnable = + new OnAddedFrameRunnable(this, aNewFrameCount, aNewRefreshArea); + NS_DispatchToMainThread(runnable); + return; + } + MOZ_ASSERT((mFrameCount == 1 && aNewFrameCount == 1) || mFrameCount < aNewFrameCount, "Frame count running backwards"); diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index 6034d534b888..b3d99c3843aa 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -15,6 +15,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/Likely.h" #include "mozilla/Move.h" +#include "mozilla/Mutex.h" #include "mozilla/RefPtr.h" #include "mozilla/StaticPtr.h" #include "nsIMemoryReporter.h" @@ -119,7 +120,8 @@ class CachedSurface { ~CachedSurface() {} public: - NS_INLINE_DECL_REFCOUNTING(CachedSurface) + MOZ_DECLARE_REFCOUNTED_TYPENAME(CachedSurface) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CachedSurface) CachedSurface(imgFrame* aSurface, const Cost aCost, @@ -215,7 +217,8 @@ class ImageSurfaceCache public: ImageSurfaceCache() : mLocked(false) { } - NS_INLINE_DECL_REFCOUNTING(ImageSurfaceCache) + MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageSurfaceCache) typedef nsRefPtrHashtable, CachedSurface> SurfaceTable; @@ -277,6 +280,7 @@ public: : mExpirationTracker(MOZ_THIS_IN_INITIALIZER_LIST(), aSurfaceCacheExpirationTimeMS) , mMemoryPressureObserver(new MemoryPressureObserver) + , mMutex("SurfaceCache") , mDiscardFactor(aSurfaceCacheDiscardFactor) , mMaxCost(aSurfaceCacheSize) , mAvailableCost(aSurfaceCacheSize) @@ -298,9 +302,9 @@ private: } public: - void InitMemoryReporter() { - RegisterWeakMemoryReporter(this); - } + void InitMemoryReporter() { RegisterWeakMemoryReporter(this); } + + Mutex& GetMutex() { return mMutex; } bool Insert(imgFrame* aSurface, const Cost aCost, @@ -705,6 +709,7 @@ private: nsRefPtrHashtable, ImageSurfaceCache> mImageCaches; SurfaceTracker mExpirationTracker; nsRefPtr mMemoryPressureObserver; + Mutex mMutex; const uint32_t mDiscardFactor; const Cost mMaxCost; Cost mAvailableCost; @@ -722,6 +727,7 @@ NS_IMPL_ISUPPORTS(SurfaceCacheImpl::MemoryPressureObserver, nsIObserver) SurfaceCache::Initialize() { // Initialize preferences. + MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!sInstance, "Shouldn't initialize more than once"); // See gfxPrefs for the default values of these preferences. @@ -775,6 +781,7 @@ SurfaceCache::Initialize() /* static */ void SurfaceCache::Shutdown() { + MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(sInstance, "No singleton - was Shutdown() called twice?"); sInstance = nullptr; } @@ -783,11 +790,11 @@ SurfaceCache::Shutdown() SurfaceCache::Lookup(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey) { - MOZ_ASSERT(NS_IsMainThread()); if (!sInstance) { return DrawableFrameRef(); } + MutexAutoLock lock(sInstance->GetMutex()); return sInstance->Lookup(aImageKey, aSurfaceKey); } @@ -797,11 +804,11 @@ SurfaceCache::Insert(imgFrame* aSurface, const SurfaceKey& aSurfaceKey, Lifetime aLifetime) { - MOZ_ASSERT(NS_IsMainThread()); if (!sInstance) { return false; } + MutexAutoLock lock(sInstance->GetMutex()); Cost cost = ComputeCost(aSurfaceKey.Size()); return sInstance->Insert(aSurface, cost, aImageKey, aSurfaceKey, aLifetime); } @@ -809,7 +816,6 @@ SurfaceCache::Insert(imgFrame* aSurface, /* static */ bool SurfaceCache::CanHold(const IntSize& aSize) { - MOZ_ASSERT(NS_IsMainThread()); if (!sInstance) { return false; } @@ -821,8 +827,8 @@ SurfaceCache::CanHold(const IntSize& aSize) /* static */ void SurfaceCache::LockImage(Image* aImageKey) { - MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { + MutexAutoLock lock(sInstance->GetMutex()); return sInstance->LockImage(aImageKey); } } @@ -830,8 +836,8 @@ SurfaceCache::LockImage(Image* aImageKey) /* static */ void SurfaceCache::UnlockImage(Image* aImageKey) { - MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { + MutexAutoLock lock(sInstance->GetMutex()); return sInstance->UnlockImage(aImageKey); } } @@ -840,8 +846,8 @@ SurfaceCache::UnlockImage(Image* aImageKey) SurfaceCache::RemoveSurface(const ImageKey aImageKey, const SurfaceKey& aSurfaceKey) { - MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { + MutexAutoLock lock(sInstance->GetMutex()); sInstance->RemoveSurface(aImageKey, aSurfaceKey); } } @@ -849,8 +855,8 @@ SurfaceCache::RemoveSurface(const ImageKey aImageKey, /* static */ void SurfaceCache::RemoveImage(Image* aImageKey) { - MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { + MutexAutoLock lock(sInstance->GetMutex()); sInstance->RemoveImage(aImageKey); } } @@ -858,8 +864,8 @@ SurfaceCache::RemoveImage(Image* aImageKey) /* static */ void SurfaceCache::DiscardAll() { - MOZ_ASSERT(NS_IsMainThread()); if (sInstance) { + MutexAutoLock lock(sInstance->GetMutex()); sInstance->DiscardAll(); } } @@ -869,11 +875,11 @@ SurfaceCache::SizeOfSurfaces(const ImageKey aImageKey, gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) { - MOZ_ASSERT(NS_IsMainThread()); if (!sInstance) { return 0; } + MutexAutoLock lock(sInstance->GetMutex()); return sInstance->SizeOfSurfaces(aImageKey, aLocation, aMallocSizeOf); } diff --git a/image/src/imgFrame.cpp b/image/src/imgFrame.cpp index 7731a463921a..cf0910770411 100644 --- a/image/src/imgFrame.cpp +++ b/image/src/imgFrame.cpp @@ -22,6 +22,7 @@ static bool gDisableOptimize = false; #include "MainThreadUtils.h" #include "mozilla/MemoryReporting.h" #include "nsMargin.h" +#include "nsThreadUtils.h" #include "mozilla/CheckedInt.h" #include "mozilla/gfx/Tools.h" @@ -128,19 +129,20 @@ static bool AllowedImageAndFrameDimensions(const nsIntSize& aImageSize, } -imgFrame::imgFrame() : - mDecoded(0, 0, 0, 0), - mDecodedMutex("imgFrame::mDecoded"), - mPalettedImageData(nullptr), - mTimeout(100), - mLockCount(0), - mDisposalMethod(DisposalMethod::NOT_SPECIFIED), - mBlendMethod(BlendMethod::OVER), - mSinglePixel(false), - mCompositingFailed(false), - mHasNoAlpha(false), - mNonPremult(false), - mOptimizable(false) +imgFrame::imgFrame() + : mMutex("imgFrame") + , mDecoded(0, 0, 0, 0) + , mLockCount(0) + , mTimeout(100) + , mDisposalMethod(DisposalMethod::NOT_SPECIFIED) + , mBlendMethod(BlendMethod::OVER) + , mHasNoAlpha(false) + , mPalettedImageData(nullptr) + , mPaletteDepth(0) + , mNonPremult(false) + , mSinglePixel(false) + , mCompositingFailed(false) + , mOptimizable(false) { static bool hasCheckedOptimize = false; if (!hasCheckedOptimize) { @@ -161,7 +163,8 @@ nsresult imgFrame::InitForDecoder(const nsIntSize& aImageSize, const nsIntRect& aRect, SurfaceFormat aFormat, - uint8_t aPaletteDepth /* = 0 */) + uint8_t aPaletteDepth /* = 0 */, + bool aNonPremult /* = false */) { // Assert for properties that should be verified by decoders, // warn for properties related to bad content. @@ -176,6 +179,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, mFormat = aFormat; mPaletteDepth = aPaletteDepth; + mNonPremult = aNonPremult; if (aPaletteDepth != 0) { // We're creating for a paletted image. @@ -185,8 +189,11 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, return NS_ERROR_FAILURE; } - // Use the fallible allocator here - mPalettedImageData = (uint8_t*)moz_malloc(PaletteDataLength() + GetImageDataLength()); + // Use the fallible allocator here. Paletted images always use 1 byte per + // pixel, so calculating the amount of memory we need is straightforward. + mPalettedImageData = + static_cast(moz_malloc(PaletteDataLength() + + (mSize.width * mSize.height))); if (!mPalettedImageData) NS_WARNING("moz_malloc for paletted image data should succeed"); NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); @@ -300,6 +307,7 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable, nsresult imgFrame::Optimize() { MOZ_ASSERT(NS_IsMainThread()); + mMutex.AssertCurrentThreadOwns(); MOZ_ASSERT(mLockCount == 1, "Should only optimize when holding the lock exclusively"); @@ -359,7 +367,8 @@ nsresult imgFrame::Optimize() SurfaceFormat optFormat = gfxPlatform::GetPlatform()->Optimal2DFormatForContent(gfxContentType::COLOR); - if (!GetHasAlpha() && optFormat == SurfaceFormat::R5G6B5) { + if (mFormat != SurfaceFormat::B8G8R8A8 && + optFormat == SurfaceFormat::R5G6B5) { RefPtr buf = AllocateBufferForImage(mSize, optFormat); if (!buf) @@ -428,7 +437,8 @@ imgFrame::RawAccessRef() void imgFrame::SetRawAccessOnly() { - MOZ_ASSERT(mLockCount > 0, "Must hold a RawAccessFrameRef"); + AssertImageDataLocked(); + // Lock our data and throw away the key. LockImageData(); } @@ -444,6 +454,9 @@ imgFrame::SurfaceForDrawing(bool aDoPadding, ImageRegion& aRegion, SourceSurface* aSurface) { + MOZ_ASSERT(NS_IsMainThread()); + mMutex.AssertCurrentThreadOwns(); + IntSize size(int32_t(aImageRect.Width()), int32_t(aImageRect.Height())); if (!aDoPadding && !aDoPartialDecode) { NS_ASSERTION(!mSinglePixel, "This should already have been handled"); @@ -496,19 +509,22 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion, PROFILER_LABEL("imgFrame", "Draw", js::ProfileEntry::Category::GRAPHICS); + MOZ_ASSERT(NS_IsMainThread()); NS_ASSERTION(!aRegion.Rect().IsEmpty(), "Drawing empty region!"); NS_ASSERTION(!aRegion.IsRestricted() || !aRegion.Rect().Intersect(aRegion.Restriction()).IsEmpty(), "We must be allowed to sample *some* source pixels!"); NS_ASSERTION(!mPalettedImageData, "Directly drawing a paletted image!"); + MutexAutoLock lock(mMutex); + nsIntMargin padding(mOffset.y, mImageSize.width - (mOffset.x + mSize.width), mImageSize.height - (mOffset.y + mSize.height), mOffset.x); bool doPadding = padding != nsIntMargin(0,0,0,0); - bool doPartialDecode = !ImageComplete(); + bool doPartialDecode = !ImageCompleteInternal(); if (mSinglePixel && !doPadding && !doPartialDecode) { if (mSinglePixelColor.a == 0.0) { @@ -522,7 +538,7 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion, return true; } - RefPtr surf = GetSurface(); + RefPtr surf = GetSurfaceInternal(); if (!surf && !mSinglePixel) { return false; } @@ -550,10 +566,17 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion, return true; } -// This can be called from any thread, but not simultaneously. -nsresult imgFrame::ImageUpdated(const nsIntRect &aUpdateRect) +nsresult +imgFrame::ImageUpdated(const nsIntRect& aUpdateRect) { - MutexAutoLock lock(mDecodedMutex); + MutexAutoLock lock(mMutex); + return ImageUpdatedInternal(aUpdateRect); +} + +nsresult +imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) +{ + mMutex.AssertCurrentThreadOwns(); mDecoded.UnionRect(mDecoded, aUpdateRect); @@ -565,6 +588,23 @@ nsresult imgFrame::ImageUpdated(const nsIntRect &aUpdateRect) return NS_OK; } +void +imgFrame::Finish(Opacity aFrameOpacity, DisposalMethod aDisposalMethod, + int32_t aRawTimeout, BlendMethod aBlendMethod) +{ + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); + + if (aFrameOpacity == Opacity::OPAQUE) { + mHasNoAlpha = true; + } + + mDisposalMethod = aDisposalMethod; + mTimeout = aRawTimeout; + mBlendMethod = aBlendMethod; + ImageUpdatedInternal(GetRect()); +} + nsIntRect imgFrame::GetRect() const { return nsIntRect(mOffset, nsIntSize(mSize.width, mSize.height)); @@ -573,6 +613,8 @@ nsIntRect imgFrame::GetRect() const int32_t imgFrame::GetStride() const { + mMutex.AssertCurrentThreadOwns(); + if (mImageSurface) { return mImageSurface->Stride(); } @@ -582,11 +624,14 @@ imgFrame::GetStride() const SurfaceFormat imgFrame::GetFormat() const { + MutexAutoLock lock(mMutex); return mFormat; } uint32_t imgFrame::GetImageBytesPerRow() const { + mMutex.AssertCurrentThreadOwns(); + if (mVBuf) return mSize.width * BytesPerPixel(mFormat); @@ -601,18 +646,31 @@ uint32_t imgFrame::GetImageDataLength() const return GetImageBytesPerRow() * mSize.height; } -void imgFrame::GetImageData(uint8_t **aData, uint32_t *length) const +void +imgFrame::GetImageData(uint8_t** aData, uint32_t* aLength) const { - NS_ABORT_IF_FALSE(mLockCount != 0, "Can't GetImageData unless frame is locked"); + MutexAutoLock lock(mMutex); + GetImageDataInternal(aData, aLength); +} - if (mImageSurface) +void +imgFrame::GetImageDataInternal(uint8_t** aData, uint32_t* aLength) const +{ + mMutex.AssertCurrentThreadOwns(); + MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); + + if (mImageSurface) { *aData = mVBufPtr; - else if (mPalettedImageData) + MOZ_ASSERT(*aData, "mImageSurface is non-null, but mVBufPtr is null in GetImageData"); + } else if (mPalettedImageData) { *aData = mPalettedImageData + PaletteDataLength(); - else + MOZ_ASSERT(*aData, "mPalettedImageData is non-null, but result is null in GetImageData"); + } else { + MOZ_ASSERT(false, "Have neither mImageSurface nor mPalettedImageData in GetImageData"); *aData = nullptr; + } - *length = GetImageDataLength(); + *aLength = GetImageDataLength(); } uint8_t* imgFrame::GetImageData() const @@ -628,14 +686,9 @@ bool imgFrame::GetIsPaletted() const return mPalettedImageData != nullptr; } -bool imgFrame::GetHasAlpha() const -{ - return mFormat == SurfaceFormat::B8G8R8A8; -} - void imgFrame::GetPaletteData(uint32_t **aPalette, uint32_t *length) const { - NS_ABORT_IF_FALSE(mLockCount != 0, "Can't GetPaletteData unless frame is locked"); + AssertImageDataLocked(); if (!mPalettedImageData) { *aPalette = nullptr; @@ -654,21 +707,12 @@ uint32_t* imgFrame::GetPaletteData() const return data; } -uint8_t* -imgFrame::GetRawData() const +nsresult +imgFrame::LockImageData() { - MOZ_ASSERT(mLockCount, "Should be locked to call GetRawData()"); - if (mPalettedImageData) { - return mPalettedImageData; - } - return GetImageData(); -} + MutexAutoLock lock(mMutex); -nsresult imgFrame::LockImageData() -{ - MOZ_ASSERT(NS_IsMainThread()); - - NS_ABORT_IF_FALSE(mLockCount >= 0, "Unbalanced locks and unlocks"); + MOZ_ASSERT(mLockCount >= 0, "Unbalanced locks and unlocks"); if (mLockCount < 0) { return NS_ERROR_FAILURE; } @@ -680,9 +724,26 @@ nsresult imgFrame::LockImageData() return NS_OK; } - // Paletted images don't have surfaces, so there's nothing to do. - if (mPalettedImageData) + // If we're the first lock, but have an image surface, we're OK. + if (mImageSurface) { + mVBufPtr = mVBuf; return NS_OK; + } + + // Paletted images don't have surfaces, so there's nothing to do. + if (mPalettedImageData) { + return NS_OK; + } + + return Deoptimize(); +} + +nsresult +imgFrame::Deoptimize() +{ + MOZ_ASSERT(NS_IsMainThread()); + mMutex.AssertCurrentThreadOwns(); + MOZ_ASSERT(!mImageSurface); if (!mImageSurface) { if (mVBuf) { @@ -746,9 +807,34 @@ nsresult imgFrame::LockImageData() return NS_OK; } -nsresult imgFrame::UnlockImageData() +void +imgFrame::AssertImageDataLocked() const { - MOZ_ASSERT(NS_IsMainThread()); +#ifdef DEBUG + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); +#endif +} + +class UnlockImageDataRunnable : public nsRunnable +{ +public: + UnlockImageDataRunnable(imgFrame* aTarget) + : mTarget(aTarget) + { + MOZ_ASSERT(mTarget); + } + + NS_IMETHOD Run() { return mTarget->UnlockImageData(); } + +private: + nsRefPtr mTarget; +}; + +nsresult +imgFrame::UnlockImageData() +{ + MutexAutoLock lock(mMutex); MOZ_ASSERT(mLockCount > 0, "Unlocking an unlocked image!"); if (mLockCount <= 0) { @@ -759,6 +845,13 @@ nsresult imgFrame::UnlockImageData() // surface anymore. (But we don't need to do anything for paletted images, // which don't have surfaces.) if (mLockCount == 1 && !mPalettedImageData) { + // We can't safely optimize off-main-thread, so create a runnable to do it. + if (!NS_IsMainThread()) { + nsCOMPtr runnable = new UnlockImageDataRunnable(this); + NS_DispatchToMainThread(runnable); + return NS_OK; + } + // If we're using a surface format with alpha but the image has no alpha, // change the format. This doesn't change the underlying data at all, but // allows DrawTargets to avoid blending when drawing known opaque images. @@ -783,13 +876,37 @@ nsresult imgFrame::UnlockImageData() void imgFrame::SetOptimizable() { - MOZ_ASSERT(mLockCount, "Expected to be locked when SetOptimizable is called"); + MOZ_ASSERT(NS_IsMainThread()); + AssertImageDataLocked(); mOptimizable = true; } +Color +imgFrame::SinglePixelColor() const +{ + MOZ_ASSERT(NS_IsMainThread()); + return mSinglePixelColor; +} + +bool +imgFrame::IsSinglePixel() const +{ + MOZ_ASSERT(NS_IsMainThread()); + return mSinglePixel; +} + TemporaryRef imgFrame::GetSurface() { + MutexAutoLock lock(mMutex); + return GetSurfaceInternal(); +} + +TemporaryRef +imgFrame::GetSurfaceInternal() +{ + mMutex.AssertCurrentThreadOwns(); + if (mOptSurface) { if (mOptSurface->IsValid()) return mOptSurface; @@ -813,9 +930,11 @@ imgFrame::GetSurface() TemporaryRef imgFrame::GetDrawTarget() { - MOZ_ASSERT(mLockCount >= 1, "Should lock before requesting a DrawTarget"); + MutexAutoLock lock(mMutex); - uint8_t* data = GetImageData(); + uint8_t* data; + uint32_t length; + GetImageDataInternal(&data, &length); if (!data) { return nullptr; } @@ -825,45 +944,64 @@ imgFrame::GetDrawTarget() CreateDrawTargetForData(data, mSize, stride, mFormat); } -int32_t imgFrame::GetRawTimeout() const +AnimationData +imgFrame::GetAnimationData() const { - return mTimeout; + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); + + uint8_t* data; + if (mPalettedImageData) { + data = mPalettedImageData; + } else { + uint32_t length; + GetImageDataInternal(&data, &length); + } + + bool hasAlpha = mFormat == SurfaceFormat::B8G8R8A8; + + return AnimationData(data, PaletteDataLength(), mTimeout, GetRect(), + mBlendMethod, mDisposalMethod, hasAlpha); } -void imgFrame::SetRawTimeout(int32_t aTimeout) +ScalingData +imgFrame::GetScalingData() const { - mTimeout = aTimeout; + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); + MOZ_ASSERT(!GetIsPaletted(), "GetScalingData can't handle paletted images"); + + uint8_t* data; + uint32_t length; + GetImageDataInternal(&data, &length); + + return ScalingData(data, mSize, GetImageBytesPerRow(), mFormat); } -// This can be called from any thread. -bool imgFrame::ImageComplete() const +bool +imgFrame::ImageComplete() const { - MutexAutoLock lock(mDecodedMutex); + MutexAutoLock lock(mMutex); + return ImageCompleteInternal(); +} +bool +imgFrame::ImageCompleteInternal() const +{ + mMutex.AssertCurrentThreadOwns(); return mDecoded.IsEqualInterior(nsIntRect(mOffset.x, mOffset.y, mSize.width, mSize.height)); } -// A hint from the image decoders that this image has no alpha, even -// though we're decoding it as B8G8R8A8. -void imgFrame::SetHasNoAlpha() -{ - MOZ_ASSERT(mLockCount, "Expected to be locked when SetHasNoAlpha is called"); - mHasNoAlpha = true; -} - -void imgFrame::SetAsNonPremult(bool aIsNonPremult) -{ - mNonPremult = aIsNonPremult; -} - bool imgFrame::GetCompositingFailed() const { + MOZ_ASSERT(NS_IsMainThread()); return mCompositingFailed; } void imgFrame::SetCompositingFailed(bool val) { + MOZ_ASSERT(NS_IsMainThread()); mCompositingFailed = val; } @@ -871,6 +1009,8 @@ size_t imgFrame::SizeOfExcludingThis(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const { + MutexAutoLock lock(mMutex); + // aMallocSizeOf is only used if aLocation==gfxMemoryLocation::IN_PROCESS_HEAP. It // should be nullptr otherwise. NS_ABORT_IF_FALSE( diff --git a/image/src/imgFrame.h b/image/src/imgFrame.h index 0f22d761bfd2..f59b665a656b 100644 --- a/image/src/imgFrame.h +++ b/image/src/imgFrame.h @@ -14,6 +14,7 @@ #include "mozilla/VolatileBuffer.h" #include "gfxDrawable.h" #include "imgIContainer.h" +#include "MainThreadUtils.h" namespace mozilla { namespace image { @@ -45,6 +46,65 @@ MOZ_BEGIN_ENUM_CLASS(Opacity, uint8_t) SOME_TRANSPARENCY MOZ_END_ENUM_CLASS(Opacity) + +/** + * AnimationData contains all of the information necessary for using an imgFrame + * as part of an animation. + * + * It includes pointers to the raw image data of the underlying imgFrame, but + * does not own that data. A RawAccessFrameRef for the underlying imgFrame must + * outlive the AnimationData for it to remain valid. + */ +struct AnimationData +{ + AnimationData(uint8_t* aRawData, uint32_t aPaletteDataLength, + int32_t aRawTimeout, const nsIntRect& aRect, + BlendMethod aBlendMethod, DisposalMethod aDisposalMethod, + bool aHasAlpha) + : mRawData(aRawData) + , mPaletteDataLength(aPaletteDataLength) + , mRawTimeout(aRawTimeout) + , mRect(aRect) + , mBlendMethod(aBlendMethod) + , mDisposalMethod(aDisposalMethod) + , mHasAlpha(aHasAlpha) + { } + + uint8_t* mRawData; + uint32_t mPaletteDataLength; + int32_t mRawTimeout; + nsIntRect mRect; + BlendMethod mBlendMethod; + DisposalMethod mDisposalMethod; + bool mHasAlpha; +}; + +/** + * ScalingData contains all of the information necessary for performing + * high-quality (CPU-based) scaling an imgFrame. + * + * It includes pointers to the raw image data of the underlying imgFrame, but + * does not own that data. A RawAccessFrameRef for the underlying imgFrame must + * outlive the ScalingData for it to remain valid. + */ +struct ScalingData +{ + ScalingData(uint8_t* aRawData, + gfx::IntSize aSize, + uint32_t aBytesPerRow, + gfx::SurfaceFormat aFormat) + : mRawData(aRawData) + , mSize(aSize) + , mBytesPerRow(aBytesPerRow) + , mFormat(aFormat) + { } + + uint8_t* mRawData; + gfx::IntSize mSize; + uint32_t mBytesPerRow; + gfx::SurfaceFormat mFormat; +}; + class imgFrame { typedef gfx::Color Color; @@ -71,7 +131,8 @@ public: nsresult InitForDecoder(const nsIntSize& aImageSize, const nsIntRect& aRect, SurfaceFormat aFormat, - uint8_t aPaletteDepth = 0); + uint8_t aPaletteDepth = 0, + bool aNonPremult = false); nsresult InitForDecoder(const nsIntSize& aSize, SurfaceFormat aFormat, @@ -118,71 +179,61 @@ public: nsresult ImageUpdated(const nsIntRect &aUpdateRect); + /** + * Mark this imgFrame as completely decoded, and set final options. + * + * @param aFrameOpacity Whether this imgFrame is opaque. + * @param aDisposalMethod For animation frames, how this imgFrame is cleared + * from the compositing frame before the next frame is + * displayed. + * @param aRawTimeout For animation frames, the timeout in milliseconds + * before the next frame is displayed. This timeout is + * not necessarily the timeout that will actually be + * used; see FrameAnimator::GetTimeoutForFrame. + * @param aBlendMethod For animation frames, a blending method to be used + * when compositing this frame. + */ + void Finish(Opacity aFrameOpacity, DisposalMethod aDisposalMethod, + int32_t aRawTimeout, BlendMethod aBlendMethod); + IntSize GetImageSize() { return mImageSize; } nsIntRect GetRect() const; IntSize GetSize() const { return mSize; } bool NeedsPadding() const { return mOffset != nsIntPoint(0, 0); } - int32_t GetStride() const; - SurfaceFormat GetFormat() const; - uint32_t GetImageBytesPerRow() const; - uint32_t GetImageDataLength() const; - bool GetIsPaletted() const; - bool GetHasAlpha() const; void GetImageData(uint8_t **aData, uint32_t *length) const; uint8_t* GetImageData() const; + + bool GetIsPaletted() const; void GetPaletteData(uint32_t **aPalette, uint32_t *length) const; uint32_t* GetPaletteData() const; - uint8_t* GetRawData() const; + uint8_t GetPaletteDepth() const { return mPaletteDepth; } - int32_t GetRawTimeout() const; - void SetRawTimeout(int32_t aTimeout); + /** + * Get the SurfaceFormat for this imgFrame. + * + * This should only be used for assertions. + */ + SurfaceFormat GetFormat() const; - DisposalMethod GetDisposalMethod() const { return mDisposalMethod; } - void SetDisposalMethod(DisposalMethod aDisposalMethod) - { - mDisposalMethod = aDisposalMethod; - } - - BlendMethod GetBlendMethod() const { return mBlendMethod; } - void SetBlendMethod(BlendMethod aBlendMethod) { mBlendMethod = aBlendMethod; } + AnimationData GetAnimationData() const; + ScalingData GetScalingData() const; bool ImageComplete() const; - void SetHasNoAlpha(); - void SetAsNonPremult(bool aIsNonPremult); - bool GetCompositingFailed() const; void SetCompositingFailed(bool val); void SetOptimizable(); + Color SinglePixelColor() const; + bool IsSinglePixel() const; + TemporaryRef GetSurface(); TemporaryRef GetDrawTarget(); - Color - SinglePixelColor() - { - return mSinglePixelColor; - } - - bool IsSinglePixel() - { - return mSinglePixel; - } - - TemporaryRef CachedSurface(); - size_t SizeOfExcludingThis(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const; - uint8_t GetPaletteDepth() const { return mPaletteDepth; } - uint32_t PaletteDataLength() const { - if (!mPaletteDepth) - return 0; - - return ((1 << mPaletteDepth) * sizeof(uint32_t)); - } - private: // methods ~imgFrame(); @@ -190,6 +241,23 @@ private: // methods nsresult LockImageData(); nsresult UnlockImageData(); nsresult Optimize(); + nsresult Deoptimize(); + + void AssertImageDataLocked() const; + + bool ImageCompleteInternal() const; + nsresult ImageUpdatedInternal(const nsIntRect& aUpdateRect); + void GetImageDataInternal(uint8_t **aData, uint32_t *length) const; + uint32_t GetImageBytesPerRow() const; + uint32_t GetImageDataLength() const; + int32_t GetStride() const; + TemporaryRef GetSurfaceInternal(); + + uint32_t PaletteDataLength() const + { + return mPaletteDepth ? (1 << mPaletteDepth) * sizeof(uint32_t) + : 0; + } struct SurfaceWithFormat { nsRefPtr mDrawable; @@ -210,46 +278,65 @@ private: // methods SourceSurface* aSurface); private: // data + friend class DrawableFrameRef; + friend class RawAccessFrameRef; + friend class UnlockImageDataRunnable; + + ////////////////////////////////////////////////////////////////////////////// + // Thread-safe mutable data, protected by mMutex. + ////////////////////////////////////////////////////////////////////////////// + + mutable Mutex mMutex; + RefPtr mImageSurface; RefPtr mOptSurface; + RefPtr mVBuf; + VolatileBufferPtr mVBufPtr; + + nsIntRect mDecoded; + + //! Number of RawAccessFrameRefs currently alive for this imgFrame. + int32_t mLockCount; + + //! Raw timeout for this frame. (See FrameAnimator::GetTimeoutForFrame.) + int32_t mTimeout; // -1 means display forever. + + DisposalMethod mDisposalMethod; + BlendMethod mBlendMethod; + SurfaceFormat mFormat; + + bool mHasNoAlpha; + + + ////////////////////////////////////////////////////////////////////////////// + // Effectively const data, only mutated in the Init methods. + ////////////////////////////////////////////////////////////////////////////// + IntSize mImageSize; IntSize mSize; nsIntPoint mOffset; - nsIntRect mDecoded; - - mutable Mutex mDecodedMutex; - // The palette and image data for images that are paletted, since Cairo // doesn't support these images. // The paletted data comes first, then the image data itself. // Total length is PaletteDataLength() + GetImageDataLength(). uint8_t* mPalettedImageData; + uint8_t mPaletteDepth; + + bool mNonPremult; + + + ////////////////////////////////////////////////////////////////////////////// + // Main-thread-only mutable data. + ////////////////////////////////////////////////////////////////////////////// // Note that the data stored in gfx::Color is *non-alpha-premultiplied*. Color mSinglePixelColor; - int32_t mTimeout; // -1 means display forever - - /** Indicates how many readers currently have locked this frame */ - int32_t mLockCount; - - RefPtr mVBuf; - VolatileBufferPtr mVBufPtr; - - SurfaceFormat mFormat; - uint8_t mPaletteDepth; - DisposalMethod mDisposalMethod; - BlendMethod mBlendMethod; bool mSinglePixel; bool mCompositingFailed; - bool mHasNoAlpha; - bool mNonPremult; bool mOptimizable; - - friend class DrawableFrameRef; - friend class RawAccessFrameRef; }; /** diff --git a/testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.broken.html.ini b/testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.broken.html.ini deleted file mode 100644 index 7143009c0549..000000000000 --- a/testing/web-platform/meta/2dcontext/drawing-images-to-the-canvas/2d.drawImage.broken.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[2d.drawImage.broken.html] - type: testharness - [Canvas test: 2d.drawImage.broken] - expected: FAIL - From e723960bef20946d4c70074a45735905c76456ca Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 00:04:31 -0800 Subject: [PATCH 006/224] Bug 1116733 (Part 2) - Remove DecodeStrategy and frame allocation handling outside of Decoder. r=tn --- image/decoders/nsBMPDecoder.cpp | 3 +- image/decoders/nsBMPDecoder.h | 4 +- image/decoders/nsGIFDecoder2.cpp | 3 +- image/decoders/nsGIFDecoder2.h | 3 +- image/decoders/nsICODecoder.cpp | 21 ++-- image/decoders/nsICODecoder.h | 10 +- image/decoders/nsIconDecoder.cpp | 3 +- image/decoders/nsIconDecoder.h | 3 +- image/decoders/nsJPEGDecoder.cpp | 3 +- image/decoders/nsJPEGDecoder.h | 3 +- image/decoders/nsPNGDecoder.cpp | 3 +- image/decoders/nsPNGDecoder.h | 3 +- image/src/DecodePool.cpp | 162 +++++++------------------------ image/src/DecodePool.h | 19 +--- image/src/Decoder.cpp | 17 ++-- image/src/Decoder.h | 15 ++- image/src/RasterImage.cpp | 43 ++------ image/src/RasterImage.h | 4 +- 18 files changed, 88 insertions(+), 234 deletions(-) diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp index 6b71478e1429..57e4f01ad1ef 100644 --- a/image/decoders/nsBMPDecoder.cpp +++ b/image/decoders/nsBMPDecoder.cpp @@ -199,8 +199,7 @@ nsBMPDecoder::CalcBitShift() } void -nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy) +nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); diff --git a/image/decoders/nsBMPDecoder.h b/image/decoders/nsBMPDecoder.h index 4446b08afe5f..086eee4b5559 100644 --- a/image/decoders/nsBMPDecoder.h +++ b/image/decoders/nsBMPDecoder.h @@ -50,8 +50,8 @@ public: // for 32BPP bitmaps. Only use after the bitmap has been processed. bool HasAlphaData() const; - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, + uint32_t aCount) MOZ_OVERRIDE; virtual void FinishInternal() MOZ_OVERRIDE; private: diff --git a/image/decoders/nsGIFDecoder2.cpp b/image/decoders/nsGIFDecoder2.cpp index 89a9d56da959..aad439cc9fa5 100644 --- a/image/decoders/nsGIFDecoder2.cpp +++ b/image/decoders/nsGIFDecoder2.cpp @@ -567,8 +567,7 @@ ConvertColormap(uint32_t* aColormap, uint32_t aColors) } void -nsGIFDecoder2::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy) +nsGIFDecoder2::WriteInternal(const char* aBuffer, uint32_t aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); diff --git a/image/decoders/nsGIFDecoder2.h b/image/decoders/nsGIFDecoder2.h index fb07b41399f9..04ef594218eb 100644 --- a/image/decoders/nsGIFDecoder2.h +++ b/image/decoders/nsGIFDecoder2.h @@ -26,8 +26,7 @@ public: explicit nsGIFDecoder2(RasterImage& aImage); ~nsGIFDecoder2(); - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE; virtual void FinishInternal() MOZ_OVERRIDE; virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE; diff --git a/image/decoders/nsICODecoder.cpp b/image/decoders/nsICODecoder.cpp index 62075c79a1b7..80111327c3ae 100644 --- a/image/decoders/nsICODecoder.cpp +++ b/image/decoders/nsICODecoder.cpp @@ -214,14 +214,13 @@ nsICODecoder::SetHotSpotIfCursor() } void -nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) +nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); if (!aCount) { if (mContainedDecoder) { - WriteToContainedDecoder(aBuffer, aCount, aStrategy); + WriteToContainedDecoder(aBuffer, aCount); } return; } @@ -346,7 +345,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength, mColormap, mColormapSize, Move(mRefForContainedDecoder)); - if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE, aStrategy)) { + if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) { return; } } @@ -354,7 +353,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, // If we have a PNG, let the PNG decoder do all of the rest of the work if (mIsPNG && mContainedDecoder && mPos >= mImageOffset + PNGSIGNATURESIZE) { - if (!WriteToContainedDecoder(aBuffer, aCount, aStrategy)) { + if (!WriteToContainedDecoder(aBuffer, aCount)) { return; } @@ -433,8 +432,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, PostDataError(); return; } - if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer), - aStrategy)) { + if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer))) { return; } @@ -455,7 +453,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, } // Write out the BMP's bitmap info header - if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw), aStrategy)) { + if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw))) { return; } @@ -505,7 +503,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, toFeed = aCount; } - if (!WriteToContainedDecoder(aBuffer, toFeed, aStrategy)) { + if (!WriteToContainedDecoder(aBuffer, toFeed)) { return; } @@ -594,10 +592,9 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount, } bool -nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) +nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount) { - mContainedDecoder->Write(aBuffer, aCount, aStrategy); + mContainedDecoder->Write(aBuffer, aCount); mProgress |= mContainedDecoder->TakeProgress(); mInvalidRect.Union(mContainedDecoder->TakeInvalidRect()); if (mContainedDecoder->HasDataError()) { diff --git a/image/decoders/nsICODecoder.h b/image/decoders/nsICODecoder.h index 4c7b1066fd1a..e8dfece364d4 100644 --- a/image/decoders/nsICODecoder.h +++ b/image/decoders/nsICODecoder.h @@ -38,17 +38,17 @@ public: return mDirEntry.mHeight == 0 ? 256 : mDirEntry.mHeight; } - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE; virtual void FinishInternal() MOZ_OVERRIDE; - virtual bool NeedsNewFrame() const MOZ_OVERRIDE; virtual nsresult AllocateFrame() MOZ_OVERRIDE; +protected: + virtual bool NeedsNewFrame() const MOZ_OVERRIDE; + private: // Writes to the contained decoder and sets the appropriate errors // Returns true if there are no errors. - bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy); + bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount); // Processes a single dir entry of the icon resource void ProcessDirEntry(IconDirEntry& aTarget); diff --git a/image/decoders/nsIconDecoder.cpp b/image/decoders/nsIconDecoder.cpp index e7c32624ae18..a1658e536b40 100644 --- a/image/decoders/nsIconDecoder.cpp +++ b/image/decoders/nsIconDecoder.cpp @@ -29,8 +29,7 @@ nsIconDecoder::~nsIconDecoder() { } void -nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy) +nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); diff --git a/image/decoders/nsIconDecoder.h b/image/decoders/nsIconDecoder.h index e92feead7dc2..358423d29a62 100644 --- a/image/decoders/nsIconDecoder.h +++ b/image/decoders/nsIconDecoder.h @@ -41,8 +41,7 @@ public: explicit nsIconDecoder(RasterImage& aImage); virtual ~nsIconDecoder(); - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE; uint8_t mWidth; uint8_t mHeight; diff --git a/image/decoders/nsJPEGDecoder.cpp b/image/decoders/nsJPEGDecoder.cpp index 2c78d6cfddc3..c51c4c341fac 100644 --- a/image/decoders/nsJPEGDecoder.cpp +++ b/image/decoders/nsJPEGDecoder.cpp @@ -190,8 +190,7 @@ nsJPEGDecoder::FinishInternal() } void -nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy) +nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount) { mSegment = (const JOCTET*)aBuffer; mSegmentLen = aCount; diff --git a/image/decoders/nsJPEGDecoder.h b/image/decoders/nsJPEGDecoder.h index 77619c202dac..74c1a3d83164 100644 --- a/image/decoders/nsJPEGDecoder.h +++ b/image/decoders/nsJPEGDecoder.h @@ -56,8 +56,7 @@ public: virtual ~nsJPEGDecoder(); virtual void InitInternal() MOZ_OVERRIDE; - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE; virtual void FinishInternal() MOZ_OVERRIDE; virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE; diff --git a/image/decoders/nsPNGDecoder.cpp b/image/decoders/nsPNGDecoder.cpp index bc3a4433f46f..1cd00f87d7f6 100644 --- a/image/decoders/nsPNGDecoder.cpp +++ b/image/decoders/nsPNGDecoder.cpp @@ -313,8 +313,7 @@ nsPNGDecoder::InitInternal() } void -nsPNGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy) +nsPNGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount) { NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!"); diff --git a/image/decoders/nsPNGDecoder.h b/image/decoders/nsPNGDecoder.h index 6191e973a3b7..cae9584cbc80 100644 --- a/image/decoders/nsPNGDecoder.h +++ b/image/decoders/nsPNGDecoder.h @@ -28,8 +28,7 @@ public: virtual ~nsPNGDecoder(); virtual void InitInternal() MOZ_OVERRIDE; - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy) MOZ_OVERRIDE; + virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE; virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE; void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, diff --git a/image/src/DecodePool.cpp b/image/src/DecodePool.cpp index 730366e6dca8..6e3cdf0ab13e 100644 --- a/image/src/DecodePool.cpp +++ b/image/src/DecodePool.cpp @@ -66,49 +66,6 @@ private: nsRefPtr mImage; }; -class FrameNeededWorker : public nsRunnable -{ -public: - /** - * Called when an off-main-thread decoder needs a new frame to be allocated on - * the main thread. - * - * After allocating the new frame, the worker will call RequestDecode to - * continue decoding. - */ - static void Dispatch(RasterImage* aImage) - { - nsCOMPtr worker = new FrameNeededWorker(aImage); - NS_DispatchToMainThread(worker); - } - - NS_IMETHOD Run() MOZ_OVERRIDE - { - ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor); - nsresult rv = NS_OK; - - // If we got a synchronous decode in the mean time, we don't need to do - // anything. - if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) { - rv = mImage->mDecoder->AllocateFrame(); - } - - if (NS_SUCCEEDED(rv) && mImage->mDecoder) { - // By definition, we're not done decoding, so enqueue us for more decoding. - DecodePool::Singleton()->RequestDecode(mImage); - } - - return NS_OK; - } - -private: - explicit FrameNeededWorker(RasterImage* aImage) - : mImage(aImage) - { } - - nsRefPtr mImage; -}; - class DecodeWorker : public nsRunnable { public: @@ -132,13 +89,6 @@ public: return NS_OK; } - // If we're a decode job that's been enqueued since a previous decode that - // still needs a new frame, we can't do anything. Wait until the - // FrameNeededWorker enqueues another frame. - if (mImage->mDecoder->NeedsNewFrame()) { - return NS_OK; - } - mImage->mDecodeStatus = DecodeStatus::ACTIVE; size_t oldByteCount = mImage->mDecoder->BytesDecoded(); @@ -150,23 +100,18 @@ public: size_t maxBytes = mImage->mSourceData.Length() - mImage->mDecoder->BytesDecoded(); - DecodePool::Singleton()->DecodeSomeOfImage(mImage, DecodeStrategy::ASYNC, - type, maxBytes); + DecodePool::Singleton()->DecodeSomeOfImage(mImage, type, maxBytes); size_t bytesDecoded = mImage->mDecoder->BytesDecoded() - oldByteCount; mImage->mDecodeStatus = DecodeStatus::WORK_DONE; - if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) { - // The decoder needs a new frame. Enqueue an event to get it; that event - // will enqueue another decode request when it's done. - FrameNeededWorker::Dispatch(mImage); - } else if (mImage->mDecoder && - !mImage->mError && - !mImage->mPendingError && - !mImage->IsDecodeFinished() && - bytesDecoded < maxBytes && - bytesDecoded > 0) { + if (mImage->mDecoder && + !mImage->mError && + !mImage->mPendingError && + !mImage->IsDecodeFinished() && + bytesDecoded < maxBytes && + bytesDecoded > 0) { // We aren't finished decoding, and we have more data, so add this request // to the back of the list. DecodePool::Singleton()->RequestDecode(mImage); @@ -323,30 +268,26 @@ DecodePool::RequestDecode(RasterImage* aImage) MOZ_ASSERT(aImage->mDecoder); aImage->mDecodingMonitor.AssertCurrentThreadIn(); - // If we're currently waiting on a new frame for this image, we can't do any - // decoding. - if (!aImage->mDecoder->NeedsNewFrame()) { - if (aImage->mDecodeStatus == DecodeStatus::PENDING || - aImage->mDecodeStatus == DecodeStatus::ACTIVE) { - // The image is already in our list of images to decode, or currently being - // decoded, so we don't have to do anything else. - return; - } + if (aImage->mDecodeStatus == DecodeStatus::PENDING || + aImage->mDecodeStatus == DecodeStatus::ACTIVE) { + // The image is already in our list of images to decode, or currently being + // decoded, so we don't have to do anything else. + return; + } - aImage->mDecodeStatus = DecodeStatus::PENDING; - nsCOMPtr worker = new DecodeWorker(aImage); + aImage->mDecodeStatus = DecodeStatus::PENDING; + nsCOMPtr worker = new DecodeWorker(aImage); - MutexAutoLock threadPoolLock(mThreadPoolMutex); - if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) { - NS_DispatchToMainThread(worker); - } else { - mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL); - } + MutexAutoLock threadPoolLock(mThreadPoolMutex); + if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) { + NS_DispatchToMainThread(worker); + } else { + mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL); } } void -DecodePool::DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy) +DecodePool::DecodeABitOf(RasterImage* aImage) { MOZ_ASSERT(NS_IsMainThread()); aImage->mDecodingMonitor.AssertCurrentThreadIn(); @@ -356,23 +297,17 @@ DecodePool::DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy) aImage->FinishedSomeDecoding(); } - DecodeSomeOfImage(aImage, aStrategy); + DecodeSomeOfImage(aImage); aImage->FinishedSomeDecoding(); - // If the decoder needs a new frame, enqueue an event to get it; that event - // will enqueue another decode request when it's done. - if (aImage->mDecoder && aImage->mDecoder->NeedsNewFrame()) { - FrameNeededWorker::Dispatch(aImage); - } else { - // If we aren't yet finished decoding and we have more data in hand, add - // this request to the back of the priority list. - if (aImage->mDecoder && - !aImage->mError && - !aImage->IsDecodeFinished() && - aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded()) { - RequestDecode(aImage); - } + // If we aren't yet finished decoding and we have more data in hand, add + // this request to the back of the priority list. + if (aImage->mDecoder && + !aImage->mError && + !aImage->IsDecodeFinished() && + aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded()) { + RequestDecode(aImage); } } @@ -401,28 +336,16 @@ DecodePool::DecodeUntilSizeAvailable(RasterImage* aImage) } } - // We use DecodeStrategy::ASYNC here because we just want to get the size - // information here and defer the rest of the work. - nsresult rv = - DecodeSomeOfImage(aImage, DecodeStrategy::ASYNC, DecodeUntil::SIZE); + nsresult rv = DecodeSomeOfImage(aImage, DecodeUntil::SIZE); if (NS_FAILED(rv)) { return rv; } - // If the decoder needs a new frame, enqueue an event to get it; that event - // will enqueue another decode request when it's done. - if (aImage->mDecoder && aImage->mDecoder->NeedsNewFrame()) { - FrameNeededWorker::Dispatch(aImage); - } else { - rv = aImage->FinishedSomeDecoding(); - } - - return rv; + return aImage->FinishedSomeDecoding(); } nsresult DecodePool::DecodeSomeOfImage(RasterImage* aImage, - DecodeStrategy aStrategy, DecodeUntil aDecodeUntil /* = DecodeUntil::TIME */, uint32_t bytesToDecode /* = 0 */) { @@ -447,15 +370,6 @@ DecodePool::DecodeSomeOfImage(RasterImage* aImage, return NS_OK; } - if (aImage->mDecoder->NeedsNewFrame()) { - if (aStrategy == DecodeStrategy::SYNC) { - MOZ_ASSERT(NS_IsMainThread()); - aImage->mDecoder->AllocateFrame(); - } else { - return NS_OK; - } - } - nsRefPtr decoderKungFuDeathGrip = aImage->mDecoder; uint32_t maxBytes; @@ -482,16 +396,12 @@ DecodePool::DecodeSomeOfImage(RasterImage* aImage, // * the decode completes, // * we're an DecodeUntil::SIZE decode and we get the size, or // * we run out of time. - // We also try to decode at least one "chunk" if we've allocated a new frame, - // even if we have no more data to send to the decoder. - while ((aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded() && - bytesToDecode > 0 && - !aImage->IsDecodeFinished() && - !(aDecodeUntil == DecodeUntil::SIZE && aImage->mHasSize) && - !aImage->mDecoder->NeedsNewFrame()) || - aImage->mDecoder->NeedsToFlushData()) { + while (aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded() && + bytesToDecode > 0 && + !aImage->IsDecodeFinished() && + !(aDecodeUntil == DecodeUntil::SIZE && aImage->mHasSize)) { uint32_t chunkSize = min(bytesToDecode, maxBytes); - nsresult rv = aImage->DecodeSomeData(chunkSize, aStrategy); + nsresult rv = aImage->DecodeSomeData(chunkSize); if (NS_FAILED(rv)) { aImage->DoError(); return rv; diff --git a/image/src/DecodePool.h b/image/src/DecodePool.h index 504d658b153a..9b7c75930d7b 100644 --- a/image/src/DecodePool.h +++ b/image/src/DecodePool.h @@ -25,22 +25,6 @@ namespace image { class Decoder; class RasterImage; -MOZ_BEGIN_ENUM_CLASS(DecodeStrategy, uint8_t) - // DecodeStrategy::SYNC requests a synchronous decode, which will continue - // decoding frames as long as it has more source data. It returns to the - // caller only once decoding is complete (or until it needs more source data - // before continuing). Because DecodeStrategy::SYNC can involve allocating new - // imgFrames, it can only be run on the main thread. - SYNC, - - // DecodeStrategy::ASYNC requests an asynchronous decode, which will continue - // decoding until it either finishes a frame or runs out of source data. - // Because DecodeStrategy::ASYNC does not allocate new imgFrames, it can be - // safely run off the main thread. (And hence workers in the decode pool - // always use it.) - ASYNC -MOZ_END_ENUM_CLASS(DecodeStrategy) - MOZ_BEGIN_ENUM_CLASS(DecodeStatus, uint8_t) INACTIVE, PENDING, @@ -92,7 +76,7 @@ public: * Decode aImage for a short amount of time, and post the remainder to the * queue. */ - void DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy); + void DecodeABitOf(RasterImage* aImage); /** * Ask the DecodePool to stop decoding this image. Internally, we also @@ -128,7 +112,6 @@ public: * DONE_BYTES, decode until all bytesToDecode bytes are decoded. */ nsresult DecodeSomeOfImage(RasterImage* aImage, - DecodeStrategy aStrategy, DecodeUntil aDecodeUntil = DecodeUntil::TIME, uint32_t bytesToDecode = 0); diff --git a/image/src/Decoder.cpp b/image/src/Decoder.cpp index bbbcd525aefb..c33adc5128bb 100644 --- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -98,13 +98,11 @@ Decoder::InitSharedDecoder(uint8_t* aImageData, uint32_t aImageDataLength, } void -Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) +Decoder::Write(const char* aBuffer, uint32_t aCount) { PROFILER_LABEL("ImageDecoder", "Write", js::ProfileEntry::Category::GRAPHICS); - MOZ_ASSERT(NS_IsMainThread() || aStrategy == DecodeStrategy::ASYNC); - // We're strict about decoder errors MOZ_ASSERT(!HasDecoderError(), "Not allowed to make more decoder calls after error!"); @@ -131,8 +129,13 @@ Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) return; } - // Pass the data along to the implementation - WriteInternal(aBuffer, aCount, aStrategy); + MOZ_ASSERT(!NeedsNewFrame() || HasDataError(), + "Should not need a new frame before writing anything"); + MOZ_ASSERT(!NeedsToFlushData() || HasDataError(), + "Should not need to flush data before writing anything"); + + // Pass the data along to the implementation. + WriteInternal(aBuffer, aCount); // If we need a new frame to proceed, let's create one and call it again. while (NeedsNewFrame() && !HasDataError()) { @@ -142,7 +145,7 @@ Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) if (NS_SUCCEEDED(rv)) { // Use the data we saved when we asked for a new frame. - WriteInternal(nullptr, 0, aStrategy); + WriteInternal(nullptr, 0); } mNeedsToFlushData = false; @@ -418,7 +421,7 @@ Decoder::SetSizeOnImage() */ void Decoder::InitInternal() { } -void Decoder::WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) { } +void Decoder::WriteInternal(const char* aBuffer, uint32_t aCount) { } void Decoder::FinishInternal() { } /* diff --git a/image/src/Decoder.h b/image/src/Decoder.h index bfb816bd21f0..e4e74d78bdf8 100644 --- a/image/src/Decoder.h +++ b/image/src/Decoder.h @@ -56,7 +56,7 @@ public: * * Notifications Sent: TODO */ - void Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy); + void Write(const char* aBuffer, uint32_t aCount); /** * Informs the decoder that all the data has been written. @@ -180,13 +180,8 @@ public: uint32_t width, uint32_t height, gfx::SurfaceFormat format, uint8_t palette_depth = 0); - virtual bool NeedsNewFrame() const { return mNeedsNewFrame; } - // Returns true if we may have stored data that we need to flush now that we - // have a new frame to decode into. Callers can use Write() to actually - // flush the data; see the documentation for that method. - bool NeedsToFlushData() const { return mNeedsToFlushData; } // Try to allocate a frame as described in mNewFrameData and return the // status code from that attempt. Clears mNewFrameData. @@ -212,8 +207,7 @@ protected: * only these methods. */ virtual void InitInternal(); - virtual void WriteInternal(const char* aBuffer, uint32_t aCount, - DecodeStrategy aStrategy); + virtual void WriteInternal(const char* aBuffer, uint32_t aCount); virtual void FinishInternal(); /* @@ -270,6 +264,11 @@ protected: void PostDataError(); void PostDecoderError(nsresult aFailCode); + // Returns true if we may have stored data that we need to flush now that we + // have a new frame to decode into. Callers can use Write() to actually + // flush the data; see the documentation for that method. + bool NeedsToFlushData() const { return mNeedsToFlushData; } + /** * Ensures that a given frame number exists with the given parameters, and * returns a RawAccessFrameRef for that frame. diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index b4aac4673f3e..ea6186adf520 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -1230,7 +1230,7 @@ RasterImage::AddSourceData(const char *aBuffer, uint32_t aCount) // write the data directly to the decoder. (If we haven't gotten the size, // we'll queue up the data and write it out when we do.) if (!StoringSourceData() && mHasSize) { - rv = WriteToDecoder(aBuffer, aCount, DecodeStrategy::SYNC); + rv = WriteToDecoder(aBuffer, aCount); CONTAINER_ENSURE_SUCCESS(rv); rv = FinishedSomeDecoding(); @@ -1638,7 +1638,7 @@ RasterImage::ShutdownDecoder(ShutdownReason aReason) // Writes the data to the decoder, updating the total number of bytes written. nsresult -RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy aStrategy) +RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount) { mDecodingMonitor.AssertCurrentThreadIn(); @@ -1647,7 +1647,7 @@ RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy // Write nsRefPtr kungFuDeathGrip = mDecoder; - mDecoder->Write(aBuffer, aCount, aStrategy); + mDecoder->Write(aBuffer, aCount); CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError()); @@ -1717,11 +1717,6 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType) if (mDecoded) return NS_OK; - // If we're currently waiting for a new frame, we can't do anything until - // that frame is allocated. - if (mDecoder && mDecoder->NeedsNewFrame()) - return NS_OK; - // If we have a size decoder open, make sure we get the size if (mDecoder && mDecoder->IsSizeDecode()) { nsresult rv = DecodePool::Singleton()->DecodeUntilSizeAvailable(this); @@ -1821,7 +1816,7 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType) PROFILER_LABEL_PRINTF("RasterImage", "DecodeABitOf", js::ProfileEntry::Category::GRAPHICS, "%s", GetURIString().get()); - DecodePool::Singleton()->DecodeABitOf(this, DecodeStrategy::SYNC); + DecodePool::Singleton()->DecodeABitOf(this); return NS_OK; } @@ -1889,11 +1884,6 @@ RasterImage::SyncDecode() } } - // If we're currently waiting on a new frame for this image, create it now. - if (mDecoder && mDecoder->NeedsNewFrame()) { - mDecoder->AllocateFrame(); - } - // If we don't have a decoder, create one if (!mDecoder) { rv = InitDecoder(/* aDoSizeDecode = */ false); @@ -1903,8 +1893,7 @@ RasterImage::SyncDecode() MOZ_ASSERT(mDecoder); // Write everything we have - rv = DecodeSomeData(mSourceData.Length() - mDecoder->BytesDecoded(), - DecodeStrategy::SYNC); + rv = DecodeSomeData(mSourceData.Length() - mDecoder->BytesDecoded()); CONTAINER_ENSURE_SUCCESS(rv); rv = FinishedSomeDecoding(); @@ -2215,22 +2204,12 @@ RasterImage::RequestDiscard() // Flushes up to aMaxBytes to the decoder. nsresult -RasterImage::DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy) +RasterImage::DecodeSomeData(size_t aMaxBytes) { MOZ_ASSERT(mDecoder, "Should have a decoder"); mDecodingMonitor.AssertCurrentThreadIn(); - // First, if we've just been called because we allocated a frame on the main - // thread, let the decoder deal with the data it set aside at that time by - // passing it a null buffer. - if (mDecoder->NeedsToFlushData()) { - nsresult rv = WriteToDecoder(nullptr, 0, aStrategy); - if (NS_FAILED(rv) || mDecoder->NeedsNewFrame()) { - return rv; - } - } - // If we have nothing else to decode, return. if (mDecoder->BytesDecoded() == mSourceData.Length()) { return NS_OK; @@ -2242,8 +2221,7 @@ RasterImage::DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy) size_t bytesToDecode = min(aMaxBytes, mSourceData.Length() - mDecoder->BytesDecoded()); return WriteToDecoder(mSourceData.Elements() + mDecoder->BytesDecoded(), - bytesToDecode, - aStrategy); + bytesToDecode); } @@ -2267,13 +2245,6 @@ RasterImage::IsDecodeFinished() return true; } - // If the decoder returned because it needed a new frame and we haven't - // written to it since then, the decoder may be storing data that it hasn't - // decoded yet. - if (mDecoder->NeedsNewFrame() || mDecoder->NeedsToFlushData()) { - return false; - } - // Otherwise, if we have all the source data and wrote all the source data, // we're done. // diff --git a/image/src/RasterImage.h b/image/src/RasterImage.h index 6ffebb282c78..7ec0078bd411 100644 --- a/image/src/RasterImage.h +++ b/image/src/RasterImage.h @@ -426,8 +426,8 @@ private: // data nsresult WantDecodedFrames(uint32_t aFlags, bool aShouldSyncNotify); nsresult SyncDecode(); nsresult InitDecoder(bool aDoSizeDecode); - nsresult WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy aStrategy); - nsresult DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy); + nsresult WriteToDecoder(const char *aBuffer, uint32_t aCount); + nsresult DecodeSomeData(size_t aMaxBytes); bool IsDecodeFinished(); TimeStamp mDrawStartTime; From df59da86892c56108d6514055dc5b3934cf64f4b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 00:29:39 -0800 Subject: [PATCH 007/224] Bug 1116746 - Remove unused statistics code from RasterImage. r=tn --- image/src/RasterImage.cpp | 69 --------------------------------------- 1 file changed, 69 deletions(-) diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index ea6186adf520..377f74a64cde 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -129,13 +129,6 @@ static int32_t sMaxDecodeCount = 0; } \ PR_END_MACRO - - -static int num_containers; -static int num_discardable_containers; -static int64_t total_source_bytes; -static int64_t discardable_source_bytes; - class ScaleRunner : public nsRunnable { enum ScaleState @@ -309,30 +302,11 @@ RasterImage::RasterImage(ProgressTracker* aProgressTracker, mProgressTrackerInit = new ProgressTrackerInit(this, aProgressTracker); Telemetry::GetHistogramById(Telemetry::IMAGE_DECODE_COUNT)->Add(0); - - // Statistics - num_containers++; } //****************************************************************************** RasterImage::~RasterImage() { - // Discardable statistics - if (mDiscardable) { - num_discardable_containers--; - discardable_source_bytes -= mSourceData.Length(); - - PR_LOG (GetCompressedImageAccountingLog(), PR_LOG_DEBUG, - ("CompressedImageAccounting: destroying RasterImage %p. " - "Total Containers: %d, Discardable containers: %d, " - "Total source bytes: %lld, Source bytes for discardable containers %lld", - this, - num_containers, - num_discardable_containers, - total_source_bytes, - discardable_source_bytes)); - } - if (mDecoder) { // Kill off our decode request, if it's pending. (If not, this call is // harmless.) @@ -345,10 +319,6 @@ RasterImage::~RasterImage() SurfaceCache::RemoveImage(ImageKey(this)); mAnim = nullptr; - - // Total statistics - num_containers--; - total_source_bytes -= mSourceData.Length(); } /* static */ void @@ -386,12 +356,6 @@ RasterImage::Init(const char* aMimeType, mDecodeOnDraw = !!(aFlags & INIT_FLAG_DECODE_ON_DRAW); mTransient = !!(aFlags & INIT_FLAG_TRANSIENT); - // Statistics - if (mDiscardable) { - num_discardable_containers++; - discardable_source_bytes += mSourceData.Length(); - } - // Lock this image's surfaces in the SurfaceCache if we're not discardable. if (!mDiscardable) { SurfaceCache::LockImage(ImageKey(this)); @@ -1250,21 +1214,6 @@ RasterImage::AddSourceData(const char *aBuffer, uint32_t aCount) } } - // Statistics - total_source_bytes += aCount; - if (mDiscardable) - discardable_source_bytes += aCount; - PR_LOG (GetCompressedImageAccountingLog(), PR_LOG_DEBUG, - ("CompressedImageAccounting: Added compressed data to RasterImage %p (%s). " - "Total Containers: %d, Discardable containers: %d, " - "Total source bytes: %lld, Source bytes for discardable containers %lld", - this, - mSourceDataMimeType.get(), - num_containers, - num_discardable_containers, - total_source_bytes, - discardable_source_bytes)); - return NS_OK; } @@ -1450,9 +1399,6 @@ RasterImage::Discard() // timers are cancelled. NS_ABORT_IF_FALSE(!mAnim, "Asked to discard for animated image!"); - // For post-operation logging - int old_frame_count = GetNumFrames(); - // Delete all the decoded frames. SurfaceCache::RemoveImage(ImageKey(this)); @@ -1466,21 +1412,6 @@ RasterImage::Discard() } mDecodeStatus = DecodeStatus::INACTIVE; - - // Log - PR_LOG(GetCompressedImageAccountingLog(), PR_LOG_DEBUG, - ("CompressedImageAccounting: discarded uncompressed image " - "data from RasterImage %p (%s) - %d frames (cached count: %d); " - "Total Containers: %d, Discardable containers: %d, " - "Total source bytes: %lld, Source bytes for discardable containers %lld", - this, - mSourceDataMimeType.get(), - old_frame_count, - GetNumFrames(), - num_containers, - num_discardable_containers, - total_source_bytes, - discardable_source_bytes)); } bool From 8f47ed3254f12f6c44011e0585cef2e407026d22 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 00:29:41 -0800 Subject: [PATCH 008/224] Bug 1116747 - Always use multithreaded image decoding. r=tn --- gfx/thebes/gfxPrefs.h | 1 - image/src/DecodePool.cpp | 77 +++++++++++++++++-------------------- modules/libpref/init/all.js | 4 -- 3 files changed, 36 insertions(+), 46 deletions(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 626f6654d9b5..5de23578b662 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -245,7 +245,6 @@ private: DECL_GFX_PREF(Once, "image.mem.surfacecache.min_expiration_ms", ImageMemSurfaceCacheMinExpirationMS, uint32_t, 60*1000); DECL_GFX_PREF(Once, "image.mem.surfacecache.size_factor", ImageMemSurfaceCacheSizeFactor, uint32_t, 64); DECL_GFX_PREF(Live, "image.mozsamplesize.enabled", ImageMozSampleSizeEnabled, bool, false); - DECL_GFX_PREF(Live, "image.multithreaded_decoding.enabled", ImageMTDecodingEnabled, bool, true); DECL_GFX_PREF(Live, "image.multithreaded_decoding.limit", ImageMTDecodingLimit, int32_t, -1); DECL_GFX_PREF(Once, "layers.acceleration.disabled", LayersAccelerationDisabled, bool, false); diff --git a/image/src/DecodePool.cpp b/image/src/DecodePool.cpp index 6e3cdf0ab13e..027414a5ecf8 100644 --- a/image/src/DecodePool.cpp +++ b/image/src/DecodePool.cpp @@ -75,6 +75,8 @@ public: NS_IMETHOD Run() MOZ_OVERRIDE { + MOZ_ASSERT(!NS_IsMainThread()); + ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor); // If we were interrupted, we shouldn't do any work. @@ -93,14 +95,10 @@ public: size_t oldByteCount = mImage->mDecoder->BytesDecoded(); - // Multithreaded decoding can be disabled. If we've done so, we don't want - // to monopolize the main thread, and will allow a timeout. - DecodeUntil type = NS_IsMainThread() ? DecodeUntil::TIME - : DecodeUntil::DONE_BYTES; - size_t maxBytes = mImage->mSourceData.Length() - mImage->mDecoder->BytesDecoded(); - DecodePool::Singleton()->DecodeSomeOfImage(mImage, type, maxBytes); + DecodePool::Singleton()->DecodeSomeOfImage(mImage, DecodeUntil::DONE_BYTES, + maxBytes); size_t bytesDecoded = mImage->mDecoder->BytesDecoded() - oldByteCount; @@ -126,17 +124,15 @@ public: protected: virtual ~DecodeWorker() { - if (gfxPrefs::ImageMTDecodingEnabled()) { - // Dispatch mImage to main thread to prevent mImage from being destructed by decode thread. - nsCOMPtr mainThread = do_GetMainThread(); - NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!"); - if (mainThread) { - // Handle ambiguous nsISupports inheritance - RasterImage* rawImg = nullptr; - mImage.swap(rawImg); - DebugOnly rv = NS_ProxyRelease(mainThread, NS_ISUPPORTS_CAST(ImageResource*, rawImg)); - MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to proxy release to main thread"); - } + // Dispatch mImage to main thread to prevent mImage from being destructed by decode thread. + nsCOMPtr mainThread = do_GetMainThread(); + NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!"); + if (mainThread) { + // Handle ambiguous nsISupports inheritance + RasterImage* rawImg = nullptr; + mImage.swap(rawImg); + DebugOnly rv = NS_ProxyRelease(mainThread, NS_ISUPPORTS_CAST(ImageResource*, rawImg)); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to proxy release to main thread"); } } @@ -208,32 +204,31 @@ DecodePool::GetEventTarget() DecodePool::DecodePool() : mThreadPoolMutex("Thread Pool") { - if (gfxPrefs::ImageMTDecodingEnabled()) { - mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID); - if (mThreadPool) { - mThreadPool->SetName(NS_LITERAL_CSTRING("ImageDecoder")); - int32_t prefLimit = gfxPrefs::ImageMTDecodingLimit(); - uint32_t limit; - if (prefLimit <= 0) { - limit = max(PR_GetNumberOfProcessors(), 2) - 1; - } else { - limit = static_cast(prefLimit); - } + mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID); + MOZ_RELEASE_ASSERT(mThreadPool, + "Should succeed in creating image decoding thread pool"); - mThreadPool->SetThreadLimit(limit); - mThreadPool->SetIdleThreadLimit(limit); + mThreadPool->SetName(NS_LITERAL_CSTRING("ImageDecoder")); + int32_t prefLimit = gfxPrefs::ImageMTDecodingLimit(); + uint32_t limit; + if (prefLimit <= 0) { + limit = max(PR_GetNumberOfProcessors(), 2) - 1; + } else { + limit = static_cast(prefLimit); + } + + mThreadPool->SetThreadLimit(limit); + mThreadPool->SetIdleThreadLimit(limit); #ifdef MOZ_NUWA_PROCESS - if (IsNuwaProcess()) { - mThreadPool->SetListener(new RIDThreadPoolListener()); - } + if (IsNuwaProcess()) { + mThreadPool->SetListener(new RIDThreadPoolListener()); + } #endif - nsCOMPtr obsSvc = services::GetObserverService(); - if (obsSvc) { - obsSvc->AddObserver(this, "xpcom-shutdown-threads", false); - } - } + nsCOMPtr obsSvc = services::GetObserverService(); + if (obsSvc) { + obsSvc->AddObserver(this, "xpcom-shutdown-threads", false); } } @@ -278,10 +273,10 @@ DecodePool::RequestDecode(RasterImage* aImage) aImage->mDecodeStatus = DecodeStatus::PENDING; nsCOMPtr worker = new DecodeWorker(aImage); + // Dispatch to the thread pool if it exists. If it doesn't, we're currently + // shutting down, so it's OK to just drop the job on the floor. MutexAutoLock threadPoolLock(mThreadPoolMutex); - if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) { - NS_DispatchToMainThread(worker); - } else { + if (mThreadPool) { mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL); } } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index b3e1a710aeff..caa973c2dea1 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3799,10 +3799,6 @@ pref("image.mem.surfacecache.size_factor", 4); // and laptop systems, where we never discard visible images. pref("image.mem.surfacecache.discard_factor", 1); -// Whether we decode images on multiple background threads rather than the -// foreground thread. -pref("image.multithreaded_decoding.enabled", true); - // How many threads we'll use for multithreaded decoding. If < 0, will be // automatically determined based on the system's number of cores. pref("image.multithreaded_decoding.limit", -1); From d3da56cc5bd41af1cc957af338855c9680329bb6 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 8 Jan 2015 01:28:21 -0800 Subject: [PATCH 009/224] Bug 1116733 (Followup) - Mark constructor of UnlockImageDataRunnable explicit on a CLOSED TREE. r=me --HG-- extra : amend_source : 866c595f036229aa3047d725b6158430536a911f --- image/src/imgFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/src/imgFrame.cpp b/image/src/imgFrame.cpp index cf0910770411..4054f96357f0 100644 --- a/image/src/imgFrame.cpp +++ b/image/src/imgFrame.cpp @@ -819,7 +819,7 @@ imgFrame::AssertImageDataLocked() const class UnlockImageDataRunnable : public nsRunnable { public: - UnlockImageDataRunnable(imgFrame* aTarget) + explicit UnlockImageDataRunnable(imgFrame* aTarget) : mTarget(aTarget) { MOZ_ASSERT(mTarget); From 25234619947e98258f67bef52cf8d76e173a6f59 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 2 Jan 2015 17:19:43 +0000 Subject: [PATCH 010/224] Bug 1099152 - Call gcSlice() or gc() depending on whether we want a incemental GC or not r=terrence --- js/src/jsgc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index e67c502c0562..9153fb5329b0 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3324,7 +3324,7 @@ GCRuntime::maybePeriodicFullGC() */ #ifndef JS_MORE_DETERMINISTIC int64_t now = PRMJ_Now(); - if (nextFullGCTime && nextFullGCTime <= now) { + if (nextFullGCTime && nextFullGCTime <= now && !isIncrementalGCInProgress()) { if (chunkAllocationSinceLastGC || numArenasFreeCommitted > decommitThreshold) { @@ -6362,7 +6362,7 @@ GCRuntime::notifyDidPaint() if (zealMode == ZealFrameGCValue) { JS::PrepareForFullGC(rt); - gcSlice(GC_NORMAL, JS::gcreason::REFRESH_FRAME); + gc(GC_NORMAL, JS::gcreason::REFRESH_FRAME); return; } #endif From 2d26e13c1b357ba6b5c7fd099bc161b5adbe88f8 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 2 Jan 2015 17:19:43 +0000 Subject: [PATCH 011/224] Bug 1099152 - Separate out methods to start and continue incrmental GC r=terrence --- js/src/devtools/rootAnalysis/loadCallgraph.js | 2 +- js/src/gc/GCRuntime.h | 12 +-- js/src/jsfriendapi.cpp | 7 +- js/src/jsgc.cpp | 98 ++++++++++++------- 4 files changed, 72 insertions(+), 47 deletions(-) diff --git a/js/src/devtools/rootAnalysis/loadCallgraph.js b/js/src/devtools/rootAnalysis/loadCallgraph.js index 6a1a040740a1..022fcdeb8a84 100644 --- a/js/src/devtools/rootAnalysis/loadCallgraph.js +++ b/js/src/devtools/rootAnalysis/loadCallgraph.js @@ -160,7 +160,7 @@ function loadCallgraph(file) suppressedFunctions[name] = true; } - for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, js::SliceBudget*, uint32, uint32)', + for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, js::SliceBudget, uint32)', 'void js::gc::GCRuntime::minorGC(uint32)', 'void js::gc::GCRuntime::minorGC(uint32)' ]) { diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index f4e5ae43e324..6f4d439bacab 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -317,8 +317,9 @@ class GCRuntime } bool gcIfNeeded(JSContext *cx = nullptr); void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason); - void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0); - void gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason); + void startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0); + void gcSlice(JS::gcreason::Reason reason, int64_t millis = 0); + void finishGC(JS::gcreason::Reason reason); void gcDebugSlice(SliceBudget &budget); void runDebugGC(); @@ -557,10 +558,9 @@ class GCRuntime void startBackgroundAllocTaskIfIdle(); void requestMajorGC(JS::gcreason::Reason reason); - void collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind, - JS::gcreason::Reason reason); - bool gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind, - JS::gcreason::Reason reason); + SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis); + void collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason); + bool gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason); gcstats::ZoneGCStats scanZonesBeforeGC(); void budgetIncrementalGC(SliceBudget &budget); void resetIncrementalGC(const char *reason); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index c9645f7853a6..1182ac528eee 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -210,13 +210,16 @@ JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason) JS_FRIEND_API(void) JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) { - rt->gc.gcSlice(GC_NORMAL, reason, millis); + if (!rt->gc.isIncrementalGCInProgress()) + rt->gc.startGC(GC_NORMAL, reason, millis); + else + rt->gc.gcSlice(reason, millis); } JS_FRIEND_API(void) JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason) { - rt->gc.gcFinalSlice(GC_NORMAL, reason); + rt->gc.finishGC(reason); } JS_FRIEND_API(JSPrincipals *) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 9153fb5329b0..37016059bb82 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3303,7 +3303,7 @@ GCRuntime::maybeGC(Zone *zone) !isBackgroundSweeping()) { PrepareZoneForGC(zone); - gcSlice(GC_NORMAL, JS::gcreason::MAYBEGC); + startGC(GC_NORMAL, JS::gcreason::MAYBEGC); return true; } @@ -3329,7 +3329,7 @@ GCRuntime::maybePeriodicFullGC() numArenasFreeCommitted > decommitThreshold) { JS::PrepareForFullGC(rt); - gcSlice(GC_SHRINK, JS::gcreason::MAYBEGC); + startGC(GC_SHRINK, JS::gcreason::MAYBEGC); } else { nextFullGCTime = now + GC_IDLE_FULL_SPAN; } @@ -5752,9 +5752,16 @@ GCRuntime::resetIncrementalGC(const char *reason) /* Finish sweeping the current zone group, then abort. */ abortSweepAfterCurrentGroup = true; + + /* Don't perform any compaction after sweeping. */ + JSGCInvocationKind oldInvocationKind = invocationKind; + invocationKind = GC_NORMAL; + SliceBudget budget; incrementalCollectSlice(budget, JS::gcreason::RESET); + invocationKind = oldInvocationKind; + { gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD); rt->gc.waitBackgroundSweepOrAllocEnd(); @@ -6077,8 +6084,7 @@ class AutoDisableStoreBuffer * to run another cycle. */ MOZ_NEVER_INLINE bool -GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind, - JS::gcreason::Reason reason) +GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason) { evictNursery(reason); @@ -6141,10 +6147,6 @@ GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gck TraceMajorGCStart(); - /* Set the invocation kind in the first slice. */ - if (!isIncrementalGCInProgress()) - invocationKind = gckind; - incrementalCollectSlice(budget, reason); #ifndef JS_MORE_DETERMINISTIC @@ -6229,8 +6231,7 @@ GCRuntime::scanZonesBeforeGC() } void -GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind, - JS::gcreason::Reason reason) +GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason) { /* GC shouldn't be running in parallel execution mode */ MOZ_ALWAYS_TRUE(!InParallelSection()); @@ -6257,9 +6258,9 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck AutoStopVerifyingBarriers av(rt, reason == JS::gcreason::SHUTDOWN_CC || reason == JS::gcreason::DESTROY_RUNTIME); - gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), gckind, reason); + gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, reason); - cleanUpEverything = ShouldCleanUpEverything(reason, gckind); + cleanUpEverything = ShouldCleanUpEverything(reason, invocationKind); bool repeat = false; do { @@ -6274,7 +6275,7 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck } poked = false; - bool wasReset = gcCycle(incremental, budget, gckind, reason); + bool wasReset = gcCycle(incremental, budget, reason); if (!isIncrementalGCInProgress()) { gcstats::AutoPhase ap(stats, gcstats::PHASE_GC_END); @@ -6316,34 +6317,48 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck EnqueuePendingParseTasksAfterGC(rt); } +SliceBudget +GCRuntime::defaultBudget(JS::gcreason::Reason reason, int64_t millis) +{ + if (millis == 0) { + if (reason == JS::gcreason::ALLOC_TRIGGER) + millis = sliceBudget; + else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled()) + millis = sliceBudget * IGC_MARK_SLICE_MULTIPLIER; + else + millis = sliceBudget; + } + + return SliceBudget(TimeBudget(millis)); +} + void GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason) { - SliceBudget budget; - collect(false, budget, gckind, reason); + invocationKind = gckind; + collect(false, SliceBudget(), reason); } void -GCRuntime::gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis) +GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis) { - SliceBudget budget; - if (millis) - budget = SliceBudget(TimeBudget(millis)); - else if (reason == JS::gcreason::ALLOC_TRIGGER) - budget = SliceBudget(TimeBudget(sliceBudget)); - else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled()) - budget = SliceBudget(TimeBudget(sliceBudget * IGC_MARK_SLICE_MULTIPLIER)); - else - budget = SliceBudget(TimeBudget(sliceBudget)); - - collect(true, budget, gckind, reason); + MOZ_ASSERT(!isIncrementalGCInProgress()); + invocationKind = gckind; + collect(true, defaultBudget(reason, millis), reason); } void -GCRuntime::gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason) +GCRuntime::gcSlice(JS::gcreason::Reason reason, int64_t millis) { - SliceBudget budget; - collect(true, budget, gckind, reason); + MOZ_ASSERT(isIncrementalGCInProgress()); + collect(true, defaultBudget(reason, millis), reason); +} + +void +GCRuntime::finishGC(JS::gcreason::Reason reason) +{ + MOZ_ASSERT(isIncrementalGCInProgress()); + collect(true, SliceBudget(), reason); } void @@ -6367,9 +6382,9 @@ GCRuntime::notifyDidPaint() } #endif - if (JS::IsIncrementalGCInProgress(rt) && !interFrameGC) { + if (isIncrementalGCInProgress() && !interFrameGC) { JS::PrepareForIncrementalGC(rt); - gcSlice(GC_NORMAL, JS::gcreason::REFRESH_FRAME); + gcSlice(JS::gcreason::REFRESH_FRAME); } interFrameGC = false; @@ -6389,12 +6404,14 @@ void GCRuntime::gcDebugSlice(SliceBudget &budget) { if (!ZonesSelected(rt)) { - if (JS::IsIncrementalGCInProgress(rt)) + if (isIncrementalGCInProgress()) JS::PrepareForIncrementalGC(rt); else JS::PrepareForFullGC(rt); } - collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC); + if (!isIncrementalGCInProgress()) + invocationKind = GC_NORMAL; + collect(true, budget, JS::gcreason::DEBUG_GC); } /* Schedule a full GC unless a zone will already be collected. */ @@ -6513,7 +6530,10 @@ GCRuntime::gcIfNeeded(JSContext *cx /* = nullptr */) } if (majorGCRequested) { - gcSlice(GC_NORMAL, rt->gc.majorGCTriggerReason); + if (!isIncrementalGCInProgress()) + startGC(GC_NORMAL, majorGCTriggerReason); + else + gcSlice(majorGCTriggerReason); return true; } @@ -6678,7 +6698,9 @@ GCRuntime::runDebugGC() budget = SliceBudget(WorkBudget(1)); } - collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC); + if (!isIncrementalGCInProgress()) + invocationKind = GC_NORMAL; + collect(true, budget, JS::gcreason::DEBUG_GC); /* * For multi-slice zeal, reset the slice size when we get to the sweep @@ -6690,9 +6712,9 @@ GCRuntime::runDebugGC() incrementalLimit = zealFrequency / 2; } } else if (type == ZealCompactValue) { - collect(false, budget, GC_SHRINK, JS::gcreason::DEBUG_GC); + gc(GC_SHRINK, JS::gcreason::DEBUG_GC); } else { - collect(false, budget, GC_NORMAL, JS::gcreason::DEBUG_GC); + gc(GC_NORMAL, JS::gcreason::DEBUG_GC); } #endif From e004c7d3a29844cec12c4c705a16d11daf82158a Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 2 Jan 2015 17:19:43 +0000 Subject: [PATCH 012/224] Bug 1099152 - Separate out external APIs to start and continute an incremental GC r=terrence r=mccr8 --- dom/base/nsJSEnvironment.cpp | 4 ++-- js/public/GCAPI.h | 21 ++++++++++++++----- js/src/jsapi-tests/testGCFinalizeCallback.cpp | 6 +++--- js/src/jsfriendapi.cpp | 13 +++++++----- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index edf7a29ad16e..7d913fce8004 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1281,7 +1281,7 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, if (sCCLockedOut && aIncremental == IncrementalGC) { // We're in the middle of incremental GC. Do another slice. JS::PrepareForIncrementalGC(sRuntime); - JS::IncrementalGC(sRuntime, aReason, aSliceMillis); + JS::IncrementalGCSlice(sRuntime, aReason, aSliceMillis); return; } @@ -1294,7 +1294,7 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, if (aIncremental == IncrementalGC) { MOZ_ASSERT(aShrinking == NonShrinkingGC); - JS::IncrementalGC(sRuntime, aReason, aSliceMillis); + JS::StartIncrementalGC(sRuntime, aReason, aSliceMillis); } else if (aShrinking == ShrinkingGC) { JS::ShrinkingGC(sRuntime, aReason); } else { diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 67843d40fe3a..439fb5805163 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -207,16 +207,27 @@ ShrinkingGC(JSRuntime *rt, gcreason::Reason reason); */ /* - * Begin an incremental collection and perform one slice worth of work or - * perform a slice of an ongoing incremental collection. When this function - * returns, the collection is not complete. This function must be called - * repeatedly until !IsIncrementalGCInProgress(rt). + * Begin an incremental collection and perform one slice worth of work. When + * this function returns, the collection may not be complete. + * IncrementalGCSlice() must be called repeatedly until + * !IsIncrementalGCInProgress(rt). * * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or * shorter than the requested interval. */ extern JS_FRIEND_API(void) -IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); +StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); + +/* + * Perform a slice of an ongoing incremental collection. When this function + * returns, the collection may not be complete. It must be called repeatedly + * until !IsIncrementalGCInProgress(rt). + * + * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or + * shorter than the requested interval. + */ +extern JS_FRIEND_API(void) +IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); /* * If IsIncrementalGCInProgress(rt), this call finishes the ongoing collection diff --git a/js/src/jsapi-tests/testGCFinalizeCallback.cpp b/js/src/jsapi-tests/testGCFinalizeCallback.cpp index e526ce1c1173..99673d6dd1c7 100644 --- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp +++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp @@ -24,7 +24,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Full GC, incremental. */ FinalizeCalls = 0; JS::PrepareForFullGC(rt); - JS::IncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(rt->gc.isFullGc()); CHECK(checkMultipleGroups()); @@ -61,7 +61,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Compartment GC, incremental, single compartment. */ FinalizeCalls = 0; JS::PrepareZoneForGC(global1->zone()); - JS::IncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); @@ -73,7 +73,7 @@ BEGIN_TEST(testGCFinalizeCallback) JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global3->zone()); - JS::IncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkMultipleGroups()); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 1182ac528eee..41aca0d0ec4f 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -208,12 +208,15 @@ JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason) } JS_FRIEND_API(void) -JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) +JS::StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) { - if (!rt->gc.isIncrementalGCInProgress()) - rt->gc.startGC(GC_NORMAL, reason, millis); - else - rt->gc.gcSlice(reason, millis); + rt->gc.startGC(GC_NORMAL, reason, millis); +} + +JS_FRIEND_API(void) +JS::IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis) +{ + rt->gc.gcSlice(reason, millis); } JS_FRIEND_API(void) From 0b1dcc49a251c682a053ca76b37445c6316ba615 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 2 Jan 2015 17:19:43 +0000 Subject: [PATCH 013/224] Bug 1099152 - Make external GC APIs take invocation kind as a parameter r=terrence r=mccr8 --- dom/base/nsJSEnvironment.cpp | 7 ++-- dom/workers/WorkerPrivate.cpp | 4 +-- js/public/GCAPI.h | 34 ++++++++++++------- js/src/builtin/TestingFunctions.cpp | 6 ++-- js/src/jsapi-tests/testGCFinalizeCallback.cpp | 10 +++--- js/src/jsapi-tests/testPreserveJitCode.cpp | 4 +-- js/src/jsapi-tests/tests.h | 2 +- js/src/jsfriendapi.cpp | 16 ++++----- js/src/jsgc.h | 11 ------ js/xpconnect/src/XPCComponents.cpp | 10 +++--- xpcom/base/CycleCollectedJSRuntime.cpp | 2 +- 11 files changed, 47 insertions(+), 59 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 7d913fce8004..5f0c683aa581 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1294,11 +1294,10 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, if (aIncremental == IncrementalGC) { MOZ_ASSERT(aShrinking == NonShrinkingGC); - JS::StartIncrementalGC(sRuntime, aReason, aSliceMillis); - } else if (aShrinking == ShrinkingGC) { - JS::ShrinkingGC(sRuntime, aReason); + JS::StartIncrementalGC(sRuntime, GC_NORMAL, aReason, aSliceMillis); } else { - JS::GCForReason(sRuntime, aReason); + JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL; + JS::GCForReason(sRuntime, gckind, aReason); } } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 47cf553b4c7c..2da1743c253c 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -6020,14 +6020,14 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking, JS::PrepareForFullGC(rt); if (aShrinking) { - JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER); + JS::GCForReason(rt, GC_SHRINK, JS::gcreason::DOM_WORKER); if (!aCollectChildren) { LOG(("Worker %p collected idle garbage\n", this)); } } else { - JS::GCForReason(rt, JS::gcreason::DOM_WORKER); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::DOM_WORKER); LOG(("Worker %p collected garbage\n", this)); } } diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 439fb5805163..c2da39a2356e 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -31,6 +31,17 @@ typedef enum JSGCMode { JSGC_MODE_INCREMENTAL = 2 } JSGCMode; +/* + * Kinds of js_GC invocation. + */ +typedef enum JSGCInvocationKind { + /* Normal invocation. */ + GC_NORMAL = 0, + + /* Minimize GC triggers and release empty GC chunks right away. */ + GC_SHRINK = 1 +} JSGCInvocationKind; + namespace JS { #define GCREASONS(D) \ @@ -168,20 +179,16 @@ SkipZoneForGC(Zone *zone); */ /* - * Performs a non-incremental collection of all selected zones. Some objects - * that are unreachable from the program may still be alive afterwards because - * of internal references. + * Performs a non-incremental collection of all selected zones. + * + * If the gckind argument is GC_NORMAL, then some objects that are unreachable + * from the program may still be alive afterwards because of internal + * references; if GC_SHRINK is passed then caches and other temporary references + * to objects will be cleared and all unreferenced objects will be removed from + * the system. */ extern JS_FRIEND_API(void) -GCForReason(JSRuntime *rt, gcreason::Reason reason); - -/* - * Perform a non-incremental collection after clearing caches and other - * temporary references to objects. This will remove all unreferenced objects - * in the system. - */ -extern JS_FRIEND_API(void) -ShrinkingGC(JSRuntime *rt, gcreason::Reason reason); +GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason); /* * Incremental GC: @@ -216,7 +223,8 @@ ShrinkingGC(JSRuntime *rt, gcreason::Reason reason); * shorter than the requested interval. */ extern JS_FRIEND_API(void) -StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); +StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, + int64_t millis = 0); /* * Perform a slice of an ongoing incremental collection. When this function diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index faf5484aa35f..8718f4c8fe42 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -238,10 +238,8 @@ GC(JSContext *cx, unsigned argc, jsval *vp) else JS::PrepareForFullGC(cx->runtime()); - if (shrinking) - JS::ShrinkingGC(cx->runtime(), JS::gcreason::API); - else - JS::GCForReason(cx->runtime(), JS::gcreason::API); + JSGCInvocationKind gckind = shrinking ? GC_SHRINK : GC_NORMAL; + JS::GCForReason(cx->runtime(), gckind, JS::gcreason::API); char buf[256] = { '\0' }; #ifndef JS_MORE_DETERMINISTIC diff --git a/js/src/jsapi-tests/testGCFinalizeCallback.cpp b/js/src/jsapi-tests/testGCFinalizeCallback.cpp index 99673d6dd1c7..b7c681b9aabb 100644 --- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp +++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp @@ -24,7 +24,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Full GC, incremental. */ FinalizeCalls = 0; JS::PrepareForFullGC(rt); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(rt->gc.isFullGc()); CHECK(checkMultipleGroups()); @@ -41,7 +41,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Compartment GC, non-incremental, single compartment. */ FinalizeCalls = 0; JS::PrepareZoneForGC(global1->zone()); - JS::GCForReason(rt, JS::gcreason::API); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); CHECK(checkFinalizeStatus()); @@ -52,7 +52,7 @@ BEGIN_TEST(testGCFinalizeCallback) JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global3->zone()); - JS::GCForReason(rt, JS::gcreason::API); + JS::GCForReason(rt, GC_NORMAL, JS::gcreason::API); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); CHECK(checkFinalizeStatus()); @@ -61,7 +61,7 @@ BEGIN_TEST(testGCFinalizeCallback) /* Compartment GC, incremental, single compartment. */ FinalizeCalls = 0; JS::PrepareZoneForGC(global1->zone()); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkSingleGroup()); @@ -73,7 +73,7 @@ BEGIN_TEST(testGCFinalizeCallback) JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global3->zone()); - JS::StartIncrementalGC(rt, JS::gcreason::API, 1000000); + JS::StartIncrementalGC(rt, GC_NORMAL, JS::gcreason::API, 1000000); CHECK(!rt->gc.isIncrementalGCInProgress()); CHECK(!rt->gc.isFullGc()); CHECK(checkMultipleGroups()); diff --git a/js/src/jsapi-tests/testPreserveJitCode.cpp b/js/src/jsapi-tests/testPreserveJitCode.cpp index fd7d328a3e0c..40ee89a8d030 100644 --- a/js/src/jsapi-tests/testPreserveJitCode.cpp +++ b/js/src/jsapi-tests/testPreserveJitCode.cpp @@ -65,10 +65,10 @@ testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts) CHECK_EQUAL(value.toInt32(), 45); CHECK_EQUAL(countIonScripts(global), 1u); - GCForReason(rt, gcreason::API); + GCForReason(rt, GC_NORMAL, gcreason::API); CHECK_EQUAL(countIonScripts(global), remainingIonScripts); - ShrinkingGC(rt, gcreason::API); + GCForReason(rt, GC_SHRINK, gcreason::API); CHECK_EQUAL(countIonScripts(global), 0u); return true; diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index d01113d93802..20bd5ea2f798 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -428,7 +428,7 @@ class AutoLeaveZeal JS_GetGCZeal(cx_, &zeal_, &frequency_); JS_SetGCZeal(cx_, 0, 0); JS::PrepareForFullGC(JS_GetRuntime(cx_)); - JS::ShrinkingGC(JS_GetRuntime(cx_), JS::gcreason::DEBUG_GC); + JS::GCForReason(JS_GetRuntime(cx_), GC_SHRINK, JS::gcreason::DEBUG_GC); } ~AutoLeaveZeal() { JS_SetGCZeal(cx_, zeal_, frequency_); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 41aca0d0ec4f..5e88e90be572 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -196,21 +196,17 @@ JS::SkipZoneForGC(Zone *zone) } JS_FRIEND_API(void) -JS::GCForReason(JSRuntime *rt, gcreason::Reason reason) +JS::GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) { - rt->gc.gc(GC_NORMAL, reason); + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.gc(gckind, reason); } JS_FRIEND_API(void) -JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason) +JS::StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) { - rt->gc.gc(GC_SHRINK, reason); -} - -JS_FRIEND_API(void) -JS::StartIncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis) -{ - rt->gc.startGC(GC_NORMAL, reason, millis); + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.startGC(gckind, reason, millis); } JS_FRIEND_API(void) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index d37156aa400e..1d6002154c01 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -903,17 +903,6 @@ TraceRuntime(JSTracer *trc); extern void ReleaseAllJITCode(FreeOp *op); -/* - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* Minimize GC triggers and release empty GC chunks right away. */ - GC_SHRINK = 1 -} JSGCInvocationKind; - extern void PrepareForDebugGC(JSRuntime *rt); diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index e6aa4593281e..6af61cbdd8ed 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2750,7 +2750,7 @@ nsXPCComponents_Utils::ForceGC() { JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); PrepareForFullGC(rt); - GCForReason(rt, gcreason::COMPONENT_UTILS); + GCForReason(rt, GC_NORMAL, gcreason::COMPONENT_UTILS); return NS_OK; } @@ -2800,7 +2800,7 @@ nsXPCComponents_Utils::ForceShrinkingGC() { JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime(); PrepareForFullGC(rt); - ShrinkingGC(rt, gcreason::COMPONENT_UTILS); + GCForReason(rt, GC_SHRINK, gcreason::COMPONENT_UTILS); return NS_OK; } @@ -2823,10 +2823,8 @@ class PreciseGCRunnable : public nsRunnable } PrepareForFullGC(rt); - if (mShrinking) - ShrinkingGC(rt, gcreason::COMPONENT_UTILS); - else - GCForReason(rt, gcreason::COMPONENT_UTILS); + JSGCInvocationKind gckind = mShrinking ? GC_SHRINK : GC_NORMAL; + GCForReason(rt, gckind, gcreason::COMPONENT_UTILS); mCallback->Callback(); return NS_OK; diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index e4e6b5be3d4e..0e10a427c394 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -1025,7 +1025,7 @@ CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const JS::gcreason::Reason gcreason = static_cast(aReason); JS::PrepareForFullGC(mJSRuntime); - JS::GCForReason(mJSRuntime, gcreason); + JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason); } void From ea9c3246f6c6f16172b6a89df85d41dec3d875a7 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Mon, 5 Jan 2015 13:22:53 +0000 Subject: [PATCH 014/224] Bug 1117098 - Move definition of external GC API methods out of jsfriendapi.cpp r=terrence --- js/public/GCAPI.h | 52 +++++----- js/src/jsfriendapi.cpp | 222 ---------------------------------------- js/src/jsgc.cpp | 226 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 250 insertions(+), 250 deletions(-) diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index c2da39a2356e..dfbb84e8f6fa 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -141,13 +141,13 @@ enum Reason { /* * Schedule the given zone to be collected as part of the next GC. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) PrepareZoneForGC(Zone *zone); /* * Schedule all zones to be collected in the next GC. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) PrepareForFullGC(JSRuntime *rt); /* @@ -155,21 +155,21 @@ PrepareForFullGC(JSRuntime *rt); * previous incremental slice must be selected in subsequent slices as well. * This function selects those slices automatically. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) PrepareForIncrementalGC(JSRuntime *rt); /* * Returns true if any zone in the system has been scheduled for GC with one of * the functions above or by the JS engine. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsGCScheduled(JSRuntime *rt); /* * Undoes the effect of the Prepare methods above. The given zone will not be * collected in the next GC. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) SkipZoneForGC(Zone *zone); /* @@ -187,7 +187,7 @@ SkipZoneForGC(Zone *zone); * to objects will be cleared and all unreferenced objects will be removed from * the system. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason); /* @@ -222,7 +222,7 @@ GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason); * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or * shorter than the requested interval. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis = 0); @@ -234,7 +234,7 @@ StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason re * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or * shorter than the requested interval. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); /* @@ -243,7 +243,7 @@ IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0); * this is equivalent to GCForReason. When this function returns, * IsIncrementalGCInProgress(rt) will always be false. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason); enum GCProgress { @@ -263,7 +263,7 @@ enum GCProgress { GC_CYCLE_END }; -struct JS_FRIEND_API(GCDescription) { +struct JS_PUBLIC_API(GCDescription) { bool isCompartment_; explicit GCDescription(bool isCompartment) @@ -281,7 +281,7 @@ typedef void * callback may be used for GC notifications as well as to perform additional * marking. */ -extern JS_FRIEND_API(GCSliceCallback) +extern JS_PUBLIC_API(GCSliceCallback) SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback); /* @@ -290,7 +290,7 @@ SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback); * There is not currently a way to re-enable incremental GC once it has been * disabled on the runtime. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) DisableIncrementalGC(JSRuntime *rt); /* @@ -301,7 +301,7 @@ DisableIncrementalGC(JSRuntime *rt); * GCDescription returned by GCSliceCallback may help narrow down the cause if * collections are not happening incrementally when expected. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsIncrementalGCEnabled(JSRuntime *rt); /* @@ -310,20 +310,20 @@ IsIncrementalGCEnabled(JSRuntime *rt); * pointer callbacks. There is not currently a way to re-enable compacting GC * once it has been disabled on the runtime. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) DisableCompactingGC(JSRuntime *rt); /* * Returns true if compacting GC is enabled. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsCompactingGCEnabled(JSRuntime *rt); /* * Returns true while an incremental GC is ongoing, both when actively * collecting and between slices. */ -JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsIncrementalGCInProgress(JSRuntime *rt); /* @@ -331,29 +331,29 @@ IsIncrementalGCInProgress(JSRuntime *rt); * This is generally only true when running mutator code in-between GC slices. * At other times, the barrier may be elided for performance. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsIncrementalBarrierNeeded(JSRuntime *rt); -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsIncrementalBarrierNeeded(JSContext *cx); /* * Notify the GC that a reference to a GC thing is about to be overwritten. * These methods must be called if IsIncrementalBarrierNeeded. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) IncrementalReferenceBarrier(GCCellPtr thing); -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) IncrementalValueBarrier(const Value &v); -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) IncrementalObjectBarrier(JSObject *obj); /* * Returns true if the most recent GC ran incrementally. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) WasIncrementalGC(JSRuntime *rt); /* @@ -365,7 +365,7 @@ WasIncrementalGC(JSRuntime *rt); */ /* Ensure that generational GC is disabled within some scope. */ -class JS_FRIEND_API(AutoDisableGenerationalGC) +class JS_PUBLIC_API(AutoDisableGenerationalGC) { js::gc::GCRuntime *gc; #ifdef JS_GC_ZEAL @@ -381,7 +381,7 @@ class JS_FRIEND_API(AutoDisableGenerationalGC) * Returns true if generational allocation and collection is currently enabled * on the given runtime. */ -extern JS_FRIEND_API(bool) +extern JS_PUBLIC_API(bool) IsGenerationalGCEnabled(JSRuntime *rt); /* @@ -389,7 +389,7 @@ IsGenerationalGCEnabled(JSRuntime *rt); * of GCs that have been run, but is guaranteed to be monotonically increasing * with GC activity. */ -extern JS_FRIEND_API(size_t) +extern JS_PUBLIC_API(size_t) GetGCNumber(); /* @@ -397,7 +397,7 @@ GetGCNumber(); * back to the system incase it is needed soon afterwards. This call forces the * GC to return this memory immediately. */ -extern JS_FRIEND_API(void) +extern JS_PUBLIC_API(void) ShrinkGCBuffers(JSRuntime *rt); /* diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 5e88e90be572..7169c4527edf 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -153,74 +153,6 @@ JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, HandleObject pro return obj; } -JS_FRIEND_API(void) -JS::PrepareZoneForGC(Zone *zone) -{ - zone->scheduleGC(); -} - -JS_FRIEND_API(void) -JS::PrepareForFullGC(JSRuntime *rt) -{ - for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) - zone->scheduleGC(); -} - -JS_FRIEND_API(void) -JS::PrepareForIncrementalGC(JSRuntime *rt) -{ - if (!JS::IsIncrementalGCInProgress(rt)) - return; - - for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { - if (zone->wasGCStarted()) - PrepareZoneForGC(zone); - } -} - -JS_FRIEND_API(bool) -JS::IsGCScheduled(JSRuntime *rt) -{ - for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { - if (zone->isGCScheduled()) - return true; - } - - return false; -} - -JS_FRIEND_API(void) -JS::SkipZoneForGC(Zone *zone) -{ - zone->unscheduleGC(); -} - -JS_FRIEND_API(void) -JS::GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) -{ - MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); - rt->gc.gc(gckind, reason); -} - -JS_FRIEND_API(void) -JS::StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) -{ - MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); - rt->gc.startGC(gckind, reason, millis); -} - -JS_FRIEND_API(void) -JS::IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis) -{ - rt->gc.gcSlice(reason, millis); -} - -JS_FRIEND_API(void) -JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason) -{ - rt->gc.finishGC(reason); -} - JS_FRIEND_API(JSPrincipals *) JS_GetCompartmentPrincipals(JSCompartment *compartment) { @@ -1065,12 +997,6 @@ js::IsContextRunningJS(JSContext *cx) return cx->currentlyRunning(); } -JS_FRIEND_API(JS::GCSliceCallback) -JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) -{ - return rt->gc.setSliceCallback(callback); -} - JS_FRIEND_API(int64_t) GetMaxGCPauseSinceClear(JSRuntime *rt) { @@ -1083,160 +1009,12 @@ ClearMaxGCPauseAccumulator(JSRuntime *rt) return rt->gc.stats.clearMaxGCPauseAccumulator(); } -JS_FRIEND_API(bool) -JS::WasIncrementalGC(JSRuntime *rt) -{ - return rt->gc.isIncrementalGc(); -} - -char16_t * -JS::GCDescription::formatMessage(JSRuntime *rt) const -{ - return rt->gc.stats.formatMessage(); -} - -char16_t * -JS::GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const -{ - return rt->gc.stats.formatJSON(timestamp); -} - JS_FRIEND_API(void) JS::NotifyDidPaint(JSRuntime *rt) { rt->gc.notifyDidPaint(); } -JS_FRIEND_API(bool) -JS::IsIncrementalGCEnabled(JSRuntime *rt) -{ - return rt->gc.isIncrementalGCEnabled(); -} - -JS_FRIEND_API(bool) -JS::IsIncrementalGCInProgress(JSRuntime *rt) -{ - return rt->gc.isIncrementalGCInProgress() && !rt->gc.isVerifyPreBarriersEnabled(); -} - -JS_FRIEND_API(void) -JS::DisableIncrementalGC(JSRuntime *rt) -{ - rt->gc.disallowIncrementalGC(); -} - -JS_FRIEND_API(void) -JS::DisableCompactingGC(JSRuntime *rt) -{ -#ifdef JSGC_COMPACTING - rt->gc.disableCompactingGC(); -#endif -} - -JS_FRIEND_API(bool) -JS::IsCompactingGCEnabled(JSRuntime *rt) -{ -#ifdef JSGC_COMPACTING - return rt->gc.isCompactingGCEnabled(); -#else - return false; -#endif -} - -JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt) - : gc(&rt->gc) -#ifdef JS_GC_ZEAL - , restartVerifier(false) -#endif -{ -#ifdef JS_GC_ZEAL - restartVerifier = gc->endVerifyPostBarriers(); -#endif - gc->disableGenerationalGC(); -} - -JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC() -{ - gc->enableGenerationalGC(); -#ifdef JS_GC_ZEAL - if (restartVerifier) { - MOZ_ASSERT(gc->isGenerationalGCEnabled()); - gc->startVerifyPostBarriers(); - } -#endif -} - -extern JS_FRIEND_API(bool) -JS::IsGenerationalGCEnabled(JSRuntime *rt) -{ - return rt->gc.isGenerationalGCEnabled(); -} - -JS_FRIEND_API(bool) -JS::IsIncrementalBarrierNeeded(JSRuntime *rt) -{ - return rt->gc.state() == gc::MARK && !rt->isHeapBusy(); -} - -JS_FRIEND_API(bool) -JS::IsIncrementalBarrierNeeded(JSContext *cx) -{ - return IsIncrementalBarrierNeeded(cx->runtime()); -} - -JS_FRIEND_API(void) -JS::IncrementalObjectBarrier(JSObject *obj) -{ - if (!obj) - return; - - MOZ_ASSERT(!obj->zone()->runtimeFromMainThread()->isHeapMajorCollecting()); - - JSObject::writeBarrierPre(obj); -} - -JS_FRIEND_API(void) -JS::IncrementalReferenceBarrier(GCCellPtr thing) -{ - if (!thing) - return; - - if (thing.isString() && StringIsPermanentAtom(thing.toString())) - return; - -#ifdef DEBUG - Zone *zone = thing.isObject() - ? thing.toObject()->zone() - : thing.asCell()->asTenured().zone(); - MOZ_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting()); -#endif - - switch(thing.kind()) { - case JSTRACE_OBJECT: return JSObject::writeBarrierPre(thing.toObject()); - case JSTRACE_STRING: return JSString::writeBarrierPre(thing.toString()); - case JSTRACE_SCRIPT: return JSScript::writeBarrierPre(thing.toScript()); - case JSTRACE_SYMBOL: return JS::Symbol::writeBarrierPre(thing.toSymbol()); - case JSTRACE_LAZY_SCRIPT: - return LazyScript::writeBarrierPre(static_cast(thing.asCell())); - case JSTRACE_JITCODE: - return jit::JitCode::writeBarrierPre(static_cast(thing.asCell())); - case JSTRACE_SHAPE: - return Shape::writeBarrierPre(static_cast(thing.asCell())); - case JSTRACE_BASE_SHAPE: - return BaseShape::writeBarrierPre(static_cast(thing.asCell())); - case JSTRACE_TYPE_OBJECT: - return types::TypeObject::writeBarrierPre(static_cast(thing.asCell())); - default: - MOZ_CRASH("Invalid trace kind in IncrementalReferenceBarrier."); - } -} - -JS_FRIEND_API(void) -JS::IncrementalValueBarrier(const Value &v) -{ - js::HeapValue::writeBarrierPre(v); -} - JS_FRIEND_API(void) JS::PokeGC(JSRuntime *rt) { diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 37016059bb82..c599452eb021 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -6422,7 +6422,7 @@ js::PrepareForDebugGC(JSRuntime *rt) JS::PrepareForFullGC(rt); } -JS_FRIEND_API(void) +JS_PUBLIC_API(void) JS::ShrinkGCBuffers(JSRuntime *rt) { rt->gc.shrinkBuffers(); @@ -6940,7 +6940,7 @@ js::gc::AssertGCThingHasType(js::gc::Cell *cell, JSGCTraceKind kind) MOZ_ASSERT(MapAllocToTraceKind(cell->asTenured().getAllocKind()) == kind); } -JS_FRIEND_API(size_t) +JS_PUBLIC_API(size_t) JS::GetGCNumber() { JSRuntime *rt = js::TlsPerThreadData.get()->runtimeFromMainThread(); @@ -7078,3 +7078,225 @@ js::gc::CheckHashTablesAfterMovingGC(JSRuntime *rt) } } #endif + +JS_PUBLIC_API(void) +JS::PrepareZoneForGC(Zone *zone) +{ + zone->scheduleGC(); +} + +JS_PUBLIC_API(void) +JS::PrepareForFullGC(JSRuntime *rt) +{ + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) + zone->scheduleGC(); +} + +JS_PUBLIC_API(void) +JS::PrepareForIncrementalGC(JSRuntime *rt) +{ + if (!JS::IsIncrementalGCInProgress(rt)) + return; + + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { + if (zone->wasGCStarted()) + PrepareZoneForGC(zone); + } +} + +JS_PUBLIC_API(bool) +JS::IsGCScheduled(JSRuntime *rt) +{ + for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { + if (zone->isGCScheduled()) + return true; + } + + return false; +} + +JS_PUBLIC_API(void) +JS::SkipZoneForGC(Zone *zone) +{ + zone->unscheduleGC(); +} + +JS_PUBLIC_API(void) +JS::GCForReason(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason) +{ + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.gc(gckind, reason); +} + +JS_PUBLIC_API(void) +JS::StartIncrementalGC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason, int64_t millis) +{ + MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); + rt->gc.startGC(gckind, reason, millis); +} + +JS_PUBLIC_API(void) +JS::IncrementalGCSlice(JSRuntime *rt, gcreason::Reason reason, int64_t millis) +{ + rt->gc.gcSlice(reason, millis); +} + +JS_PUBLIC_API(void) +JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason) +{ + rt->gc.finishGC(reason); +} + +char16_t * +JS::GCDescription::formatMessage(JSRuntime *rt) const +{ + return rt->gc.stats.formatMessage(); +} + +char16_t * +JS::GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const +{ + return rt->gc.stats.formatJSON(timestamp); +} + +JS_PUBLIC_API(JS::GCSliceCallback) +JS::SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback) +{ + return rt->gc.setSliceCallback(callback); +} + +JS_PUBLIC_API(void) +JS::DisableIncrementalGC(JSRuntime *rt) +{ + rt->gc.disallowIncrementalGC(); +} + +JS_PUBLIC_API(bool) +JS::IsIncrementalGCEnabled(JSRuntime *rt) +{ + return rt->gc.isIncrementalGCEnabled(); +} + +JS_PUBLIC_API(void) +JS::DisableCompactingGC(JSRuntime *rt) +{ +#ifdef JSGC_COMPACTING + rt->gc.disableCompactingGC(); +#endif +} + +JS_PUBLIC_API(bool) +JS::IsCompactingGCEnabled(JSRuntime *rt) +{ +#ifdef JSGC_COMPACTING + return rt->gc.isCompactingGCEnabled(); +#else + return false; +#endif +} + +JS_PUBLIC_API(bool) +JS::IsIncrementalGCInProgress(JSRuntime *rt) +{ + return rt->gc.isIncrementalGCInProgress() && !rt->gc.isVerifyPreBarriersEnabled(); +} + +JS_PUBLIC_API(bool) +JS::IsIncrementalBarrierNeeded(JSRuntime *rt) +{ + return rt->gc.state() == gc::MARK && !rt->isHeapBusy(); +} + +JS_PUBLIC_API(bool) +JS::IsIncrementalBarrierNeeded(JSContext *cx) +{ + return IsIncrementalBarrierNeeded(cx->runtime()); +} + +JS_PUBLIC_API(void) +JS::IncrementalReferenceBarrier(GCCellPtr thing) +{ + if (!thing) + return; + + if (thing.isString() && StringIsPermanentAtom(thing.toString())) + return; + +#ifdef DEBUG + Zone *zone = thing.isObject() + ? thing.toObject()->zone() + : thing.asCell()->asTenured().zone(); + MOZ_ASSERT(!zone->runtimeFromMainThread()->isHeapMajorCollecting()); +#endif + + switch(thing.kind()) { + case JSTRACE_OBJECT: return JSObject::writeBarrierPre(thing.toObject()); + case JSTRACE_STRING: return JSString::writeBarrierPre(thing.toString()); + case JSTRACE_SCRIPT: return JSScript::writeBarrierPre(thing.toScript()); + case JSTRACE_SYMBOL: return JS::Symbol::writeBarrierPre(thing.toSymbol()); + case JSTRACE_LAZY_SCRIPT: + return LazyScript::writeBarrierPre(static_cast(thing.asCell())); + case JSTRACE_JITCODE: + return jit::JitCode::writeBarrierPre(static_cast(thing.asCell())); + case JSTRACE_SHAPE: + return Shape::writeBarrierPre(static_cast(thing.asCell())); + case JSTRACE_BASE_SHAPE: + return BaseShape::writeBarrierPre(static_cast(thing.asCell())); + case JSTRACE_TYPE_OBJECT: + return types::TypeObject::writeBarrierPre(static_cast(thing.asCell())); + default: + MOZ_CRASH("Invalid trace kind in IncrementalReferenceBarrier."); + } +} + +JS_PUBLIC_API(void) +JS::IncrementalValueBarrier(const Value &v) +{ + js::HeapValue::writeBarrierPre(v); +} + +JS_PUBLIC_API(void) +JS::IncrementalObjectBarrier(JSObject *obj) +{ + if (!obj) + return; + + MOZ_ASSERT(!obj->zone()->runtimeFromMainThread()->isHeapMajorCollecting()); + + JSObject::writeBarrierPre(obj); +} + +JS_PUBLIC_API(bool) +JS::WasIncrementalGC(JSRuntime *rt) +{ + return rt->gc.isIncrementalGc(); +} + +JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt) + : gc(&rt->gc) +#ifdef JS_GC_ZEAL + , restartVerifier(false) +#endif +{ +#ifdef JS_GC_ZEAL + restartVerifier = gc->endVerifyPostBarriers(); +#endif + gc->disableGenerationalGC(); +} + +JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC() +{ + gc->enableGenerationalGC(); +#ifdef JS_GC_ZEAL + if (restartVerifier) { + MOZ_ASSERT(gc->isGenerationalGCEnabled()); + gc->startVerifyPostBarriers(); + } +#endif +} + +JS_PUBLIC_API(bool) +JS::IsGenerationalGCEnabled(JSRuntime *rt) +{ + return rt->gc.isGenerationalGCEnabled(); +} From 32d27c84d2bb26a0863c203047052ba7a127b4fa Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Thu, 8 Jan 2015 02:10:24 -0800 Subject: [PATCH 015/224] Bug 1063471: finish off converting nsBlockReflowContext to logical coordinates (comment-only change), r=jfkthame --- layout/generic/nsBlockReflowContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index 79a735e63ee9..5d55bea53d74 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -354,7 +354,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState, aBEndMarginResult.Include(aReflowState.ComputedLogicalMargin(). ConvertTo(parentWM, wm).BEnd(parentWM)); } else { - // The used bottom-margin is set to zero above a break. + // The used block-end-margin is set to zero before a break. aBEndMarginResult.Zero(); } @@ -406,7 +406,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState, // See if the frame fit. If it's the first frame or empty then it // always fits. If the block-size is unconstrained then it always fits, // even if there's some sort of integer overflow that makes bCoord + - // mMetrics.BSize() appear to go beyond the available height. + // mMetrics.BSize() appear to go beyond the available block size. if (!empty && !aForceFit && mSpace.BSize(mWritingMode) != NS_UNCONSTRAINEDSIZE) { nscoord bEnd = mBCoord - From 9107bf11e5003d69a0f9a35ebf59d49d8ae0098b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 8 Jan 2015 11:31:13 +0000 Subject: [PATCH 016/224] Bug 1077354 - Allow CTypes to pass DataView argumets as pointers r=terrence --- js/src/ctypes/CTypes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 10e0b1670d82..12a3ccb6f92f 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -2464,7 +2464,7 @@ ImplicitConvert(JSContext* cx, } *static_cast(buffer) = ptr; break; - } if (val.isObject() && JS_IsTypedArrayObject(valObj)) { + } if (val.isObject() && JS_IsArrayBufferViewObject(valObj)) { // Same as ArrayBuffer, above, though note that this will take the offset // of the view into account. if(!CanConvertTypedArrayItemTo(baseType, valObj, cx)) { From 37e0662101522f3d3a6fc92c23f70430b7f74831 Mon Sep 17 00:00:00 2001 From: David Rajchenbach-Teller Date: Thu, 20 Nov 2014 12:40:08 +0100 Subject: [PATCH 017/224] Bug 1077354 - Extending PromiseWorker to simplify transfering values r=froydnj --- .../promiseworker/PromiseWorker.jsm | 39 ++++++++++++++++++- .../tests/xpcshell/test_Promise.js | 24 ++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/toolkit/components/promiseworker/PromiseWorker.jsm b/toolkit/components/promiseworker/PromiseWorker.jsm index efe8a908c8c9..a90b91477fc0 100644 --- a/toolkit/components/promiseworker/PromiseWorker.jsm +++ b/toolkit/components/promiseworker/PromiseWorker.jsm @@ -244,7 +244,10 @@ this.BasePromiseWorker.prototype = { * @param {string} fun The name of the function to call. * @param {Array} args The arguments to pass to `fun`. If any * of the arguments is a Promise, it is resolved before posting the - * message. By convention, the last argument may be an object `options` + * message. If any of the arguments needs to be transfered instead + * of copied, this may be specified by making the argument an instance + * of `BasePromiseWorker.Meta` or by using the `transfers` argument. + * By convention, the last argument may be an object `options` * with some of the following fields: * - {number|null} outExecutionDuration A parameter to be filled with the * duration of the off main thread execution for this call. @@ -264,6 +267,22 @@ this.BasePromiseWorker.prototype = { } if (transfers) { transfers = yield Promise.resolve(Promise.all(transfers)); + } else { + transfers = []; + } + + if (args) { + // Extract `Meta` data + args = args.map(arg => { + if (arg instanceof BasePromiseWorker.Meta) { + if (arg.meta && "transfers" in arg.meta) { + transfers.push(...arg.meta.transfers); + } + return arg.data; + } else { + return arg; + } + }); } let id = ++this._id; @@ -352,3 +371,21 @@ this.BasePromiseWorker.prototype = { function WorkerError(data) { this.data = data; }; + +/** + * A constructor used to send data to the worker thread while + * with special treatment (e.g. transmitting data instead of + * copying it). + * + * @param {object=} data The data to send to the caller thread. + * @param {object=} meta Additional instructions, as an object + * that may contain the following fields: + * - {Array} transfers An array of objects that should be transferred + * instead of being copied. + * + * @constructor + */ +this.BasePromiseWorker.Meta = function(data, meta) { + this.data = data; + this.meta = meta; +}; diff --git a/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js b/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js index e5d758fb54d1..de20837c3199 100644 --- a/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js +++ b/toolkit/components/promiseworker/tests/xpcshell/test_Promise.js @@ -60,6 +60,7 @@ add_task(function* test_rejected_promise_args() { } }); +// Test that we can transfer to the worker using argument `transfer` add_task(function* test_transfer_args() { let array = new Uint8Array(4); for (let i = 0; i < 4; ++i) { @@ -80,6 +81,29 @@ add_task(function* test_transfer_args() { } }); +// Test that we can transfer to the worker using an instance of `Meta` +add_task(function* test_transfer_with_meta() { + let array = new Uint8Array(4); + for (let i = 0; i < 4; ++i) { + array[i] = i; + } + Assert.equal(array.buffer.byteLength, 4, "The buffer is not neutered yet"); + + let message = new BasePromiseWorker.Meta(array, {transfers: [array.buffer]}); + let result = (yield worker.post("bounce", [message]))[0]; + + // Check that the buffer has been sent + Assert.equal(array.buffer.byteLength, 0, "The buffer has been neutered"); + + // Check that the result is correct + Assert.equal(result.toString(), "[object Uint8Array]", "The result appears to be a Typed Array"); + Assert.equal(result.byteLength, 4, "The result has the right size"); + + for (let i = 0; i < 4; ++i) { + Assert.equal(result[i], i); + } +}); + function run_test() { run_next_test(); } From 0e23adfc34d509afd0a6e508c8ac4bff9453798e Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 8 Jan 2015 11:31:21 +0000 Subject: [PATCH 018/224] Bug 1077354 - Transfer buffers to OS.File methods rather than passing a pointer r=froydnj --- .../osfile/modules/osfile_async_front.jsm | 8 - .../modules/osfile_shared_allthreads.jsm | 159 ++++++++---------- .../osfile/modules/osfile_shared_front.jsm | 36 ++-- .../osfile/modules/osfile_unix_front.jsm | 2 +- .../osfile/modules/osfile_win_front.jsm | 2 +- .../tests/mochi/worker_test_osfile_comms.js | 12 +- .../tests/mochi/worker_test_osfile_front.js | 53 ------ .../osfile/tests/xpcshell/test_compression.js | 8 +- .../osfile/tests/xpcshell/test_read_write.js | 15 +- toolkit/components/workerlz4/lz4.js | 20 +-- toolkit/modules/ZipUtils.jsm | 4 +- 11 files changed, 119 insertions(+), 200 deletions(-) diff --git a/toolkit/components/osfile/modules/osfile_async_front.jsm b/toolkit/components/osfile/modules/osfile_async_front.jsm index 0d810dc34f6e..e0ba3ab71c8e 100644 --- a/toolkit/components/osfile/modules/osfile_async_front.jsm +++ b/toolkit/components/osfile/modules/osfile_async_front.jsm @@ -647,10 +647,6 @@ File.prototype = { options = clone(options, ["outExecutionDuration"]); options.bytes = buffer.byteLength; } - // Note: Type.void_t.out_ptr.toMsg ensures that - // - the buffer is effectively shared (not neutered) between both - // threads; - // - we take care of any |byteOffset|. return Scheduler.post("File_prototype_write", [this._fdmsg, Type.void_t.in_ptr.toMsg(buffer), @@ -1162,10 +1158,6 @@ File.writeAtomic = function writeAtomic(path, buffer, options = {}) { if (isTypedArray(buffer) && (!("bytes" in options))) { options.bytes = buffer.byteLength; }; - // Note: Type.void_t.out_ptr.toMsg ensures that - // - the buffer is effectively shared (not neutered) between both - // threads; - // - we take care of any |byteOffset|. let refObj = {}; TelemetryStopwatch.start("OSFILE_WRITEATOMIC_JANK_MS", refObj); let promise = Scheduler.post("writeAtomic", diff --git a/toolkit/components/osfile/modules/osfile_shared_allthreads.jsm b/toolkit/components/osfile/modules/osfile_shared_allthreads.jsm index a6110bb5fd66..7e91686b7e44 100644 --- a/toolkit/components/osfile/modules/osfile_shared_allthreads.jsm +++ b/toolkit/components/osfile/modules/osfile_shared_allthreads.jsm @@ -25,6 +25,15 @@ const Cu = typeof Components != "undefined" ? Components.utils : undefined; const Ci = typeof Components != "undefined" ? Components.interfaces : undefined; const Cc = typeof Components != "undefined" ? Components.classes : undefined; + +/** + * A constructor for messages that require transfers instead of copies. + * + * See BasePromiseWorker.Meta. + * + * @constructor + */ +let Meta; if (typeof Components != "undefined") { // Global definition of |exports|, to keep everybody happy. // In non-main thread, |exports| is provided by the module @@ -32,6 +41,10 @@ if (typeof Components != "undefined") { this.exports = {}; Cu.import("resource://gre/modules/Services.jsm", this); + Meta = Cu.import("resource://gre/modules/PromiseWorker.jsm", {}).BasePromiseWorker.Meta; +} else { + importScripts("resource://gre/modules/workers/require.js"); + Meta = require("resource://gre/modules/workers/PromiseWorker.js").Meta; } let EXPORTED_SYMBOLS = [ @@ -46,11 +59,11 @@ let EXPORTED_SYMBOLS = [ "declareFFI", "declareLazy", "declareLazyFFI", - "normalizeToPointer", + "normalizeBufferArgs", "projectValue", + "isArrayBuffer", "isTypedArray", "defineLazyGetter", - "offsetBy", "OS" // Warning: this exported symbol will disappear ]; @@ -141,7 +154,15 @@ let stringifyArg = function stringifyArg(arg) { * compartment. */ if (argToString === "[object Object]") { - return JSON.stringify(arg); + return JSON.stringify(arg, function(key, value) { + if (isTypedArray(value)) { + return "["+ value.constructor.name + " " + value.byteOffset + " " + value.byteLength + "]"; + } + if (isArrayBuffer(arg)) { + return "[" + value.constructor.name + " " + value.byteLength + "]"; + } + return value; + }); } else { return argToString; } @@ -387,11 +408,20 @@ Type.prototype = { * Utility function used to determine whether an object is a typed array */ let isTypedArray = function isTypedArray(obj) { - return typeof obj == "object" + return obj != null && typeof obj == "object" && "byteOffset" in obj; }; exports.isTypedArray = isTypedArray; +/** + * Utility function used to determine whether an object is an ArrayBuffer. + */ +let isArrayBuffer = function(obj) { + return obj != null && typeof obj == "object" && + obj.constructor.name == "ArrayBuffer"; +}; +exports.isArrayBuffer = isArrayBuffer; + /** * A |Type| of pointers. * @@ -430,13 +460,16 @@ PtrType.prototype.toMsg = function ptr_toMsg(value) { if (typeof value == "string") { return { string: value }; } + if (isTypedArray(value)) { + // Automatically transfer typed arrays + return new Meta({data: value}, {transfers: [value.buffer]}); + } + if (isArrayBuffer(value)) { + // Automatically transfer array buffers + return new Meta({data: value}, {transfers: [value]}); + } let normalized; - if (isTypedArray(value)) { // Typed array - normalized = Type.uint8_t.in_ptr.implementation(value.buffer); - if (value.byteOffset != 0) { - normalized = offsetBy(normalized, value.byteOffset); - } - } else if ("addressOfElement" in value) { // C array + if ("addressOfElement" in value) { // C array normalized = value.addressOfElement(0); } else if ("isNull" in value) { // C pointer normalized = value; @@ -458,6 +491,9 @@ PtrType.prototype.fromMsg = function ptr_fromMsg(msg) { if ("string" in msg) { return msg.string; } + if ("data" in msg) { + return msg.data; + } if ("ptr" in msg) { let address = ctypes.uintptr_t(msg.ptr); return this.cast(address); @@ -1144,96 +1180,34 @@ function declareLazy(object, field, lib, ...declareArgs) { } exports.declareLazy = declareLazy; -// A bogus array type used to perform pointer arithmetics -let gOffsetByType; - /** - * Advance a pointer by a number of items. + * Utility function used to sanity check buffer and length arguments. The + * buffer must be a Typed Array. * - * This method implements adding an integer to a pointer in C. - * - * Example: - * // ptr is a uint16_t*, - * offsetBy(ptr, 3) - * // returns a uint16_t* with the address ptr + 3 * 2 bytes - * - * @param {C pointer} pointer The start pointer. - * @param {number} length The number of items to advance. Must not be - * negative. - * - * @return {C pointer} |pointer| advanced by |length| items - */ -let offsetBy = - function offsetBy(pointer, length) { - if (length === undefined || length < 0) { - throw new TypeError("offsetBy expects a positive number"); - } - if (!("isNull" in pointer)) { - throw new TypeError("offsetBy expects a pointer"); - } - if (length == 0) { - return pointer; - } - let type = pointer.constructor; - let size = type.targetType.size; - if (size == 0 || size == null) { - throw new TypeError("offsetBy cannot be applied to a pointer without size"); - } - let bytes = length * size; - if (!gOffsetByType || gOffsetByType.size <= bytes) { - gOffsetByType = ctypes.uint8_t.array(bytes * 2); - } - let addr = ctypes.cast(pointer, gOffsetByType.ptr). - contents.addressOfElement(bytes); - return ctypes.cast(addr, type); -}; -exports.offsetBy = offsetBy; - -/** - * Utility function used to normalize a Typed Array or C - * pointer into a uint8_t C pointer. - * - * Future versions might extend this to other data structures. - * - * @param {Typed array | C pointer} candidate The buffer. If - * a C pointer, it must be non-null. + * @param {Typed array} candidate The buffer. * @param {number} bytes The number of bytes that |candidate| should contain. - * Used for sanity checking if the size of |candidate| can be determined. * - * @return {ptr:{C pointer}, bytes:number} A C pointer of type uint8_t, - * corresponding to the start of |candidate|. + * @return number The bytes argument clamped to the length of the buffer. */ -function normalizeToPointer(candidate, bytes) { +function normalizeBufferArgs(candidate, bytes) { if (!candidate) { - throw new TypeError("Expecting a Typed Array or a C pointer"); + throw new TypeError("Expecting a Typed Array"); } - let ptr; - if ("isNull" in candidate) { - if (candidate.isNull()) { - throw new TypeError("Expecting a non-null pointer"); - } - ptr = Type.uint8_t.out_ptr.cast(candidate); - if (bytes == null) { - throw new TypeError("C pointer missing bytes indication."); - } - } else if (isTypedArray(candidate)) { - // Typed Array - ptr = Type.uint8_t.out_ptr.implementation(candidate.buffer); - if (bytes == null) { - bytes = candidate.byteLength; - } else if (candidate.byteLength < bytes) { - throw new TypeError("Buffer is too short. I need at least " + - bytes + - " bytes but I have only " + - candidate.byteLength + - "bytes"); - } - } else { - throw new TypeError("Expecting a Typed Array or a C pointer"); + if (!isTypedArray(candidate)) { + throw new TypeError("Expecting a Typed Array"); } - return {ptr: ptr, bytes: bytes}; + if (bytes == null) { + bytes = candidate.byteLength; + } else if (candidate.byteLength < bytes) { + throw new TypeError("Buffer is too short. I need at least " + + bytes + + " bytes but I have only " + + candidate.byteLength + + "bytes"); + } + return bytes; }; -exports.normalizeToPointer = normalizeToPointer; +exports.normalizeBufferArgs = normalizeBufferArgs; ///////////////////// OS interactions @@ -1274,8 +1248,7 @@ exports.OS = { declareFFI: declareFFI, projectValue: projectValue, isTypedArray: isTypedArray, - defineLazyGetter: defineLazyGetter, - offsetBy: offsetBy + defineLazyGetter: defineLazyGetter } }; diff --git a/toolkit/components/osfile/modules/osfile_shared_front.jsm b/toolkit/components/osfile/modules/osfile_shared_front.jsm index 17476400dc60..2df5bcc43243 100644 --- a/toolkit/components/osfile/modules/osfile_shared_front.jsm +++ b/toolkit/components/osfile/modules/osfile_shared_front.jsm @@ -62,23 +62,24 @@ AbstractFile.prototype = { options = clone(maybeBytes); maybeBytes = null; } else { - options = clone(options || {}); + options = options || {}; } - if(!("bytes" in options)) { - options.bytes = maybeBytes == null ? this.stat().size : maybeBytes; + let bytes = options.bytes || undefined; + if (bytes === undefined) { + bytes = maybeBytes == null ? this.stat().size : maybeBytes; } - let buffer = new Uint8Array(options.bytes); - let {ptr, bytes} = SharedAll.normalizeToPointer(buffer, options.bytes); + let buffer = new Uint8Array(bytes); let pos = 0; while (pos < bytes) { - let chunkSize = this._read(ptr, bytes - pos, options); + let length = bytes - pos; + let view = new DataView(buffer.buffer, pos, length); + let chunkSize = this._read(view, length, options); if (chunkSize == 0) { break; } pos += chunkSize; - ptr = SharedAll.offsetBy(ptr, chunkSize); } - if (pos == options.bytes) { + if (pos == bytes) { return buffer; } else { return buffer.subarray(0, pos); @@ -91,27 +92,24 @@ AbstractFile.prototype = { * Note that, by default, this function may perform several I/O * operations to ensure that the buffer is fully written. * - * @param {Typed array | C pointer} buffer The buffer in which the - * the bytes are stored. The buffer must be large enough to - * accomodate |bytes| bytes. + * @param {Typed array} buffer The buffer in which the the bytes are + * stored. The buffer must be large enough to accomodate |bytes| bytes. * @param {*=} options Optionally, an object that may contain the * following fields: * - {number} bytes The number of |bytes| to write from the buffer. If - * unspecified, this is |buffer.byteLength|. Note that |bytes| is required - * if |buffer| is a C pointer. + * unspecified, this is |buffer.byteLength|. * * @return {number} The number of bytes actually written. */ write: function write(buffer, options = {}) { - - let {ptr, bytes} = - SharedAll.normalizeToPointer(buffer, ("bytes" in options) ? options.bytes : undefined); - + let bytes = + SharedAll.normalizeBufferArgs(buffer, ("bytes" in options) ? options.bytes : undefined); let pos = 0; while (pos < bytes) { - let chunkSize = this._write(ptr, bytes - pos, options); + let length = bytes - pos; + let view = new DataView(buffer.buffer, buffer.byteOffset + pos, length); + let chunkSize = this._write(view, length, options); pos += chunkSize; - ptr = SharedAll.offsetBy(ptr, chunkSize); } return pos; } diff --git a/toolkit/components/osfile/modules/osfile_unix_front.jsm b/toolkit/components/osfile/modules/osfile_unix_front.jsm index 46cfd3ec9cb7..0c3620b325ed 100644 --- a/toolkit/components/osfile/modules/osfile_unix_front.jsm +++ b/toolkit/components/osfile/modules/osfile_unix_front.jsm @@ -112,7 +112,7 @@ /** * Write some bytes to a file. * - * @param {C pointer} buffer A buffer holding the data that must be + * @param {Typed array} buffer A buffer holding the data that must be * written. * @param {number} nbytes The number of bytes to write. It must not * exceed the size of |buffer| in bytes. diff --git a/toolkit/components/osfile/modules/osfile_win_front.jsm b/toolkit/components/osfile/modules/osfile_win_front.jsm index f66dd1ab14bd..5c36afb4b6f3 100644 --- a/toolkit/components/osfile/modules/osfile_win_front.jsm +++ b/toolkit/components/osfile/modules/osfile_win_front.jsm @@ -125,7 +125,7 @@ /** * Write some bytes to a file. * - * @param {C pointer} buffer A buffer holding the data that must be + * @param {Typed array} buffer A buffer holding the data that must be * written. * @param {number} nbytes The number of bytes to write. It must not * exceed the size of |buffer| in bytes. diff --git a/toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js b/toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js index e398b92d1dd4..fff2fb0d2e5e 100644 --- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js +++ b/toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js @@ -36,10 +36,8 @@ self.onmessage = function(msg) { })(), type: OS.Shared.Type.char.in_ptr, check: function check_ArrayBuffer(candidate, prefix) { - let cast = ctypes.cast(candidate, ctypes.uint8_t.ptr); for (let i = 0; i < 15; ++i) { - is(cast.contents, i % 256, prefix + "Checking that the contents of the ArrayBuffer were preserved"); - cast = cast.increment(); + is(candidate[i], i % 256, prefix + "Checking that the contents of the ArrayBuffer were preserved"); } }}, { typename: "OS.Shared.Type.char.in_ptr", @@ -106,6 +104,11 @@ self.onmessage = function(msg) { return; } + if ("data" in serialized) { + // Unwrap from `Meta` + serialized = serialized.data; + } + // 2. Test deserialization let deserialized; try { @@ -120,7 +123,8 @@ self.onmessage = function(msg) { } // 3. Local test deserialized value - info("Running test on deserialized value " + serialized); + info("Running test on deserialized value " + deserialized + + " aka " + JSON.stringify(deserialized)); check(deserialized, "Local test: "); // 4. Test sending serialized diff --git a/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js b/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js index 7807c152b5cf..02b2ced35d9e 100644 --- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js +++ b/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js @@ -22,7 +22,6 @@ self.onmessage = function onmessage_start(msg) { }; try { test_init(); - test_offsetby(); test_open_existing_file(); test_open_non_existing_file(); test_flush_open_file(); @@ -48,58 +47,6 @@ function test_init() { importScripts("resource://gre/modules/osfile.jsm"); } -function test_offsetby() { - info("Starting test_offsetby"); - - // Initialize one array - let LENGTH = 1024; - let buf = new ArrayBuffer(LENGTH); - let view = new Uint8Array(buf); - let i; - for (i = 0; i < LENGTH; ++i) { - view[i] = i; - } - - // Walk through the array with offsetBy by 8 bits - let uint8 = SharedAll.Type.uint8_t.in_ptr.implementation(buf); - for (i = 0; i < LENGTH; ++i) { - let value = SharedAll.offsetBy(uint8, i).contents; - if (value != i%256) { - is(value, i % 256, "test_offsetby: Walking through array with offsetBy (8 bits)"); - break; - } - } - - // Walk again by 16 bits - let uint16 = SharedAll.Type.uint16_t.in_ptr.implementation(buf); - let view2 = new Uint16Array(buf); - for (i = 0; i < LENGTH/2; ++i) { - let value = SharedAll.offsetBy(uint16, i).contents; - if (value != view2[i]) { - is(value, view2[i], "test_offsetby: Walking through array with offsetBy (16 bits)"); - break; - } - } - - // Ensure that offsetBy(..., 0) is idempotent - let startptr = SharedAll.offsetBy(uint8, 0); - let startptr2 = SharedAll.offsetBy(startptr, 0); - is(startptr.toString(), startptr2.toString(), "test_offsetby: offsetBy(..., 0) is idmpotent"); - - // Ensure that offsetBy(ptr, ...) does not work if ptr is a void* - let ptr = ctypes.voidptr_t(0); - let exn; - try { - SharedAll.offsetBy(ptr, 1); - } catch (x) { - exn = x; - } - ok(!!exn, "test_offsetby: rejected offsetBy with void*"); - - info("test_offsetby: complete"); -} - - /** * Test that we can open an existing file. */ diff --git a/toolkit/components/osfile/tests/xpcshell/test_compression.js b/toolkit/components/osfile/tests/xpcshell/test_compression.js index bc0167c52b71..2ea8d6260450 100644 --- a/toolkit/components/osfile/tests/xpcshell/test_compression.js +++ b/toolkit/components/osfile/tests/xpcshell/test_compression.js @@ -12,19 +12,21 @@ function run_test() { add_task(function test_compress_lz4() { let path = OS.Path.join(OS.Constants.Path.tmpDir, "compression.lz"); - let array = new Uint8Array(1024); + let length = 1024; + let array = new Uint8Array(length); for (let i = 0; i < array.byteLength; ++i) { array[i] = i; } + let arrayAsString = Array.prototype.join.call(array); do_print("Writing data with lz4 compression"); let bytes = yield OS.File.writeAtomic(path, array, { compression: "lz4" }); - do_print("Compressed " + array.byteLength + " bytes into " + bytes); + do_print("Compressed " + length + " bytes into " + bytes); do_print("Reading back with lz4 decompression"); let decompressed = yield OS.File.read(path, { compression: "lz4" }); do_print("Decompressed into " + decompressed.byteLength + " bytes"); - do_check_eq(Array.prototype.join.call(array), Array.prototype.join.call(decompressed)); + do_check_eq(arrayAsString, Array.prototype.join.call(decompressed)); }); add_task(function test_uncompressed() { diff --git a/toolkit/components/osfile/tests/xpcshell/test_read_write.js b/toolkit/components/osfile/tests/xpcshell/test_read_write.js index aa969d669be0..94856be83f42 100644 --- a/toolkit/components/osfile/tests/xpcshell/test_read_write.js +++ b/toolkit/components/osfile/tests/xpcshell/test_read_write.js @@ -41,9 +41,10 @@ add_test_pair(function* read_write_all() { let pathSource = OS.Path.join(currentDir, EXISTING_FILE); let contents = yield OS.File.read(pathSource); do_check_true(!!contents); // Content is not empty + let bytesRead = contents.byteLength; let bytesWritten = yield OS.File.writeAtomic(DEST_PATH, contents, options); - do_check_eq(contents.byteLength, bytesWritten); // Correct number of bytes written + do_check_eq(bytesRead, bytesWritten); // Correct number of bytes written // Check that options are not altered do_check_eq(JSON.stringify(options), JSON.stringify(optionsBackup)); @@ -54,6 +55,7 @@ add_test_pair(function* read_write_all() { // Check that writeAtomic fails if noOverwrite is true and the destination // file already exists! + contents = new Uint8Array(300); let view = new Uint8Array(contents.buffer, 10, 200); try { let opt = JSON.parse(JSON.stringify(options)); @@ -71,16 +73,17 @@ add_test_pair(function* read_write_all() { // Now write a subset let START = 10; let LENGTH = 100; + contents = new Uint8Array(300); + for (var i = 0; i < contents.byteLength; i++) + contents[i] = i % 256; view = new Uint8Array(contents.buffer, START, LENGTH); bytesWritten = yield OS.File.writeAtomic(DEST_PATH, view, options); do_check_eq(bytesWritten, LENGTH); let array2 = yield OS.File.read(DEST_PATH); - let view1 = new Uint8Array(contents.buffer, START, LENGTH); - do_check_eq(view1.length, array2.length); - let decoder = new TextDecoder(); - do_check_eq(decoder.decode(view1), decoder.decode(array2)); - + do_check_eq(LENGTH, array2.length); + for (var i = 0; i < LENGTH; i++) + do_check_eq(array2[i], (i + START) % 256); // Cleanup. yield OS.File.remove(DEST_PATH); diff --git a/toolkit/components/workerlz4/lz4.js b/toolkit/components/workerlz4/lz4.js index 909adc194cbc..a1b49f473c45 100644 --- a/toolkit/components/workerlz4/lz4.js +++ b/toolkit/components/workerlz4/lz4.js @@ -93,39 +93,39 @@ function compressFileContent(array, options = {}) { exports.compressFileContent = compressFileContent; function decompressFileContent(array, options = {}) { - let {ptr, bytes} = SharedAll.normalizeToPointer(array, options.bytes || null); + let bytes = SharedAll.normalizeBufferArgs(array, options.bytes || null); if (bytes < HEADER_SIZE) { throw new LZError("decompress", "becauseLZNoHeader", "Buffer is too short (no header)"); } // Read headers - let expectMagicNumber = ctypes.cast(ptr, EXPECTED_HEADER_TYPE.ptr).contents; + let expectMagicNumber = new DataView(array.buffer, 0, MAGIC_NUMBER.byteLength); for (let i = 0; i < MAGIC_NUMBER.byteLength; ++i) { - if (expectMagicNumber[i] != MAGIC_NUMBER[i]) { + if (expectMagicNumber.getUint8(i) != MAGIC_NUMBER[i]) { throw new LZError("decompress", "becauseLZWrongMagicNumber", "Invalid header (no magic number"); } } - let sizeBuf = - ctypes.cast( - SharedAll.offsetBy(ptr, MAGIC_NUMBER.byteLength), - EXPECTED_SIZE_BUFFER_TYPE.ptr).contents; + let sizeBuf = new DataView(array.buffer, MAGIC_NUMBER.byteLength, BYTES_IN_SIZE_HEADER); let expectDecompressedSize = - sizeBuf[0] + (sizeBuf[1] << 8) + (sizeBuf[2] << 16) + (sizeBuf[3] << 24); + sizeBuf.getUint8(0) + + (sizeBuf.getUint8(1) << 8) + + (sizeBuf.getUint8(2) << 16) + + (sizeBuf.getUint8(3) << 24); if (expectDecompressedSize == 0) { // The underlying algorithm cannot handle a size of 0 return new Uint8Array(0); } // Prepare the input buffer - let inputPtr = SharedAll.offsetBy(ptr, HEADER_SIZE); + let inputData = new DataView(array.buffer, HEADER_SIZE); // Prepare the output buffer let outputBuffer = new Uint8Array(expectDecompressedSize); let decompressedBytes = (new SharedAll.Type.size_t.implementation(0)); // Decompress - let success = Internals.decompress(inputPtr, bytes - HEADER_SIZE, + let success = Internals.decompress(inputData, bytes - HEADER_SIZE, outputBuffer, outputBuffer.byteLength, decompressedBytes.address()); if (!success) { diff --git a/toolkit/modules/ZipUtils.jsm b/toolkit/modules/ZipUtils.jsm index 7979443c5cdd..4f735f89ddba 100644 --- a/toolkit/modules/ZipUtils.jsm +++ b/toolkit/modules/ZipUtils.jsm @@ -52,7 +52,6 @@ function saveStreamAsync(aPath, aStream, aFile) { createInstance(Ci.nsIBinaryInputStream); source.setInputStream(input); - let data = new Uint8Array(EXTRACTION_BUFFER); function readFailed(error) { try { @@ -72,7 +71,8 @@ function saveStreamAsync(aPath, aStream, aFile) { function readData() { try { - let count = Math.min(source.available(), data.byteLength); + let count = Math.min(source.available(), EXTRACTION_BUFFER); + let data = new Uint8Array(count); source.readArrayBuffer(count, data.buffer); aFile.write(data, { bytes: count }).then(function() { From e3f325b307de0a62c47a535710059515181cf434 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 23:20:16 +1100 Subject: [PATCH 019/224] Bug 1055658 part 1 - Move code for applying relative position to an independent method. r=dbaron --HG-- extra : source : 30aa25e2233135e3c4792f406af6d2cdc055758c --- layout/generic/nsLineLayout.cpp | 30 ++++++++++++++++++++---------- layout/generic/nsLineLayout.h | 2 ++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 3e222ca16d5a..a6f8b3503a4c 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -3021,6 +3021,25 @@ nsLineLayout::RelativePositionFrames(nsOverflowAreas& aOverflowAreas) RelativePositionFrames(mRootSpan, aOverflowAreas); } +// This method applies any relative positioning to the given frame. +void +nsLineLayout::ApplyRelativePositioning(PerFrameData* aPFD) +{ + if (!aPFD->mRelativePos) { + return; + } + + nsIFrame* frame = aPFD->mFrame; + WritingMode frameWM = frame->GetWritingMode(); + LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth); + // right and bottom are handled by + // nsHTMLReflowState::ComputeRelativeOffsets + nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM, + aPFD->mOffsets, &origin, + mContainerWidth); + frame->SetPosition(frameWM, origin, mContainerWidth); +} + void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas) { @@ -3059,16 +3078,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo nsIFrame* frame = pfd->mFrame; // Adjust the origin of the frame - if (pfd->mRelativePos) { - WritingMode frameWM = frame->GetWritingMode(); - LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth); - // right and bottom are handled by - // nsHTMLReflowState::ComputeRelativeOffsets - nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM, - pfd->mOffsets, &origin, - mContainerWidth); - frame->SetPosition(frameWM, origin, mContainerWidth); - } + ApplyRelativePositioning(pfd); // We must position the view correctly before positioning its // descendants so that widgets are positioned properly (since only diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 5eb9fff79a60..32000148b55b 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -665,6 +665,8 @@ protected: nscoord aDistanceFromStart, nscoord aLineBSize); + void ApplyRelativePositioning(PerFrameData* aPFD); + void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); From d5ce9a9dff98f35193492876446d85a924d36d14 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 23:20:16 +1100 Subject: [PATCH 020/224] Bug 1055658 part 2 - Add relative positioning support for ruby annotations. r=dbaron --HG-- extra : source : 19d8bb736510b1f162aba3df5d2a6b851ea705de --- layout/generic/nsLineLayout.cpp | 41 +++++++++++++++++++++++++++++++++ layout/generic/nsLineLayout.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index a6f8b3503a4c..676f49eeff5f 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -253,6 +253,21 @@ nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord, pfd->mAscent = 0; pfd->mSpan = psd; psd->mFrame = pfd; + nsIFrame* frame = mBlockReflowState->frame; + if (frame->GetType() == nsGkAtoms::rubyTextContainerFrame) { + // Ruby text container won't be reflowed via ReflowFrame, hence the + // relative positioning information should be recorded here. + MOZ_ASSERT(mBaseLineLayout != this); + pfd->mRelativePos = + mBlockReflowState->mStyleDisplay->IsRelativelyPositionedStyle(); + if (pfd->mRelativePos) { + MOZ_ASSERT( + mBlockReflowState->GetWritingMode() == frame->GetWritingMode(), + "mBlockReflowState->frame == frame, " + "hence they should have identical writing mode"); + pfd->mOffsets = mBlockReflowState->ComputedLogicalOffsets(); + } + } } void @@ -675,6 +690,7 @@ nsLineLayout::NewPerFrameData(nsIFrame* aFrame) WritingMode frameWM = aFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; pfd->mBounds = LogicalRect(lineWM); + pfd->mOverflowAreas.Clear(); pfd->mMargin = LogicalMargin(lineWM); pfd->mBorderPadding = LogicalMargin(lineWM); pfd->mOffsets = LogicalMargin(frameWM); @@ -3040,6 +3056,26 @@ nsLineLayout::ApplyRelativePositioning(PerFrameData* aPFD) frame->SetPosition(frameWM, origin, mContainerWidth); } +// This method do relative positioning for ruby annotations. +void +nsLineLayout::RelativePositionAnnotations(PerSpanData* aRubyPSD, + nsOverflowAreas& aOverflowAreas) +{ + MOZ_ASSERT(aRubyPSD->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame); + for (PerFrameData* pfd = aRubyPSD->mFirstFrame; pfd; pfd = pfd->mNext) { + MOZ_ASSERT(pfd->mFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame); + for (PerFrameData* rtc = pfd->mNextAnnotation; + rtc; rtc = rtc->mNextAnnotation) { + nsIFrame* rtcFrame = rtc->mFrame; + MOZ_ASSERT(rtcFrame->GetType() == nsGkAtoms::rubyTextContainerFrame); + ApplyRelativePositioning(rtc); + nsOverflowAreas rtcOverflowAreas; + RelativePositionFrames(rtc->mSpan, rtcOverflowAreas); + aOverflowAreas.UnionWith(rtcOverflowAreas + rtcFrame->GetPosition()); + } + } +} + void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas) { @@ -3134,6 +3170,11 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo overflowAreas.UnionWith(r + frame->GetPosition()); } + // Also compute relative position in the annotations. + if (psd->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame) { + RelativePositionAnnotations(psd, overflowAreas); + } + // If we just computed a spans combined area, we need to update its // overflow rect... if (psd != mRootSpan) { diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 32000148b55b..44bf7286aa75 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -667,6 +667,9 @@ protected: void ApplyRelativePositioning(PerFrameData* aPFD); + void RelativePositionAnnotations(PerSpanData* aRubyPSD, + nsOverflowAreas& aOverflowAreas); + void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); From a36d3789952b524ba726817fad537523defffd3e Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 23:20:16 +1100 Subject: [PATCH 021/224] Bug 1055658 part 3 - Add reftests for ruby annotation relative positioning. r=dbaron --HG-- extra : source : c352bc5450a3a939dc79ff55bd94e2cc78614ea0 --- layout/reftests/css-ruby/reftest.list | 2 ++ .../css-ruby/relative-positioning-1-ref.html | 29 +++++++++++++++ .../css-ruby/relative-positioning-1.html | 24 +++++++++++++ .../css-ruby/relative-positioning-2-ref.html | 36 +++++++++++++++++++ .../css-ruby/relative-positioning-2.html | 30 ++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 layout/reftests/css-ruby/relative-positioning-1-ref.html create mode 100644 layout/reftests/css-ruby/relative-positioning-1.html create mode 100644 layout/reftests/css-ruby/relative-positioning-2-ref.html create mode 100644 layout/reftests/css-ruby/relative-positioning-2.html diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index c903e1df745e..87e2cd174267 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -28,6 +28,8 @@ fuzzy-if(winWidget,35,1) == dynamic-removal-3.html dynamic-removal-3-ref.html # == line-height-1.html line-height-1-ref.html == line-height-2.html line-height-2-ref.html == line-height-3.html line-height-3-ref.html +== relative-positioning-1.html relative-positioning-1-ref.html +== relative-positioning-2.html relative-positioning-2-ref.html == ruby-span-1.html ruby-span-1-ref.html == ruby-whitespace-1.html ruby-whitespace-1-ref.html == ruby-whitespace-2.html ruby-whitespace-2-ref.html diff --git a/layout/reftests/css-ruby/relative-positioning-1-ref.html b/layout/reftests/css-ruby/relative-positioning-1-ref.html new file mode 100644 index 000000000000..f8df05509207 --- /dev/null +++ b/layout/reftests/css-ruby/relative-positioning-1-ref.html @@ -0,0 +1,29 @@ + + + + + Bug 1055658 - Relative positioning for ruby + + + +
+
+
+
abc
+   +
+ base +
+
+ + diff --git a/layout/reftests/css-ruby/relative-positioning-1.html b/layout/reftests/css-ruby/relative-positioning-1.html new file mode 100644 index 000000000000..0616f2e0e40d --- /dev/null +++ b/layout/reftests/css-ruby/relative-positioning-1.html @@ -0,0 +1,24 @@ + + + + + Bug 1055658 - Relative positioning for ruby + + + + + + base + abc +
+
+ + diff --git a/layout/reftests/css-ruby/relative-positioning-2-ref.html b/layout/reftests/css-ruby/relative-positioning-2-ref.html new file mode 100644 index 000000000000..ac3568c9505e --- /dev/null +++ b/layout/reftests/css-ruby/relative-positioning-2-ref.html @@ -0,0 +1,36 @@ + + + + + Bug 1055658 - Relative positioning for ruby + + + +
+ before +
+
+
+ text1 + text2 + text3 +
+   +
+ base1 + base2 + base3 +
+ after +
+ + diff --git a/layout/reftests/css-ruby/relative-positioning-2.html b/layout/reftests/css-ruby/relative-positioning-2.html new file mode 100644 index 000000000000..34dcc69b731f --- /dev/null +++ b/layout/reftests/css-ruby/relative-positioning-2.html @@ -0,0 +1,30 @@ + + + + + Bug 1055658 - Relative positioning for ruby + + + + + before + + base1 + text1 + base2 + text2 + base3 + text3 + + after + + From cd8f0da1f4c470a9eda31c9a7cf8a5e5bb829065 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 23:20:16 +1100 Subject: [PATCH 022/224] Bug 1055658 part 4 - Revert RubyReflowState. r=dbaron --HG-- extra : source : 4ee892ec7dde8957aa733401bfd7746a97ebcf7e --- layout/generic/RubyReflowState.cpp | 24 -------- layout/generic/RubyReflowState.h | 68 --------------------- layout/generic/moz.build | 1 - layout/generic/nsHTMLReflowState.cpp | 2 - layout/generic/nsHTMLReflowState.h | 7 --- layout/generic/nsLineLayout.cpp | 5 -- layout/generic/nsLineLayout.h | 15 ----- layout/generic/nsRubyBaseContainerFrame.cpp | 3 +- layout/generic/nsRubyBaseContainerFrame.h | 3 +- layout/generic/nsRubyFrame.cpp | 6 -- layout/generic/nsRubyTextContainerFrame.cpp | 7 +-- layout/generic/nsRubyTextContainerFrame.h | 10 ++- 12 files changed, 12 insertions(+), 139 deletions(-) delete mode 100644 layout/generic/RubyReflowState.cpp delete mode 100644 layout/generic/RubyReflowState.h diff --git a/layout/generic/RubyReflowState.cpp b/layout/generic/RubyReflowState.cpp deleted file mode 100644 index 8cade0c415ee..000000000000 --- a/layout/generic/RubyReflowState.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* states and methods used while laying out a ruby segment */ - -#include "RubyReflowState.h" - -using namespace mozilla; - -RubyReflowState::RubyReflowState( - WritingMode aLineWM, - const nsTArray& aTextContainers) - : mCurrentContainerIndex(kBaseContainerIndex) -{ - uint32_t rtcCount = aTextContainers.Length(); - mTextContainers.SetCapacity(rtcCount); - for (uint32_t i = 0; i < rtcCount; i++) { - mTextContainers.AppendElement( - TextContainerInfo(aLineWM, aTextContainers[i])); - } -} diff --git a/layout/generic/RubyReflowState.h b/layout/generic/RubyReflowState.h deleted file mode 100644 index 212317b3f73e..000000000000 --- a/layout/generic/RubyReflowState.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* states and methods used while laying out a ruby segment */ - -#ifndef mozilla_RubyReflowState_h_ -#define mozilla_RubyReflowState_h_ - -#include "mozilla/Attributes.h" -#include "WritingModes.h" -#include "nsTArray.h" - -#define RTC_ARRAY_SIZE 1 - -class nsRubyTextContainerFrame; - -namespace mozilla { - -class MOZ_STACK_CLASS RubyReflowState MOZ_FINAL -{ -public: - explicit RubyReflowState( - WritingMode aLineWM, - const nsTArray& aTextContainers); - - struct TextContainerInfo - { - nsRubyTextContainerFrame* mFrame; - LogicalSize mLineSize; - - TextContainerInfo(WritingMode aLineWM, nsRubyTextContainerFrame* aFrame) - : mFrame(aFrame) - , mLineSize(aLineWM) { } - }; - - void AdvanceCurrentContainerIndex() { mCurrentContainerIndex++; } - - void SetTextContainerInfo(int32_t aIndex, - nsRubyTextContainerFrame* aContainer, - const LogicalSize& aLineSize) - { - MOZ_ASSERT(mTextContainers[aIndex].mFrame == aContainer); - mTextContainers[aIndex].mLineSize = aLineSize; - } - - const TextContainerInfo& - GetCurrentTextContainerInfo(nsRubyTextContainerFrame* aFrame) const - { - MOZ_ASSERT(mTextContainers[mCurrentContainerIndex].mFrame == aFrame); - return mTextContainers[mCurrentContainerIndex]; - } - -private: - static MOZ_CONSTEXPR_VAR int32_t kBaseContainerIndex = -1; - // The index of the current reflowing container. When it equals to - // kBaseContainerIndex, we are reflowing ruby base. Otherwise, it - // stands for the index of text containers in the ruby segment. - int32_t mCurrentContainerIndex; - - nsAutoTArray mTextContainers; -}; - -} - -#endif // mozilla_RubyReflowState_h_ diff --git a/layout/generic/moz.build b/layout/generic/moz.build index be752630b8a0..0d413496e088 100644 --- a/layout/generic/moz.build +++ b/layout/generic/moz.build @@ -95,7 +95,6 @@ UNIFIED_SOURCES += [ 'nsTextRunTransformations.cpp', 'nsVideoFrame.cpp', 'nsViewportFrame.cpp', - 'RubyReflowState.cpp', 'RubyUtils.cpp', 'ScrollbarActivity.cpp', 'StickyScrollContainer.cpp', diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 53a9e43c2caf..34446aea1660 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -72,7 +72,6 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext, AvailableBSize() = aAvailableSpace.BSize(mWritingMode); mFloatManager = nullptr; mLineLayout = nullptr; - mRubyReflowState = nullptr; memset(&mFlags, 0, sizeof(mFlags)); mDiscoveredClearance = nullptr; mPercentHeightObserver = nullptr; @@ -208,7 +207,6 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext, mLineLayout = aParentReflowState.mLineLayout; else mLineLayout = nullptr; - mRubyReflowState = nullptr; // Note: mFlags was initialized as a copy of aParentReflowState.mFlags up in // this constructor's init list, so the only flags that we need to explicitly diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 7c6751e632f6..da282f702bd6 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -21,10 +21,6 @@ class nsLineLayout; class nsIPercentHeightObserver; struct nsHypotheticalBox; -namespace mozilla { -class RubyReflowState; -} - /** * @return aValue clamped to [aMinValue, aMaxValue]. * @@ -262,9 +258,6 @@ struct nsHTMLReflowState : public nsCSSOffsetState { // LineLayout object (only for inline reflow; set to nullptr otherwise) nsLineLayout* mLineLayout; - // RubyReflowState object (only for ruby reflow; set to nullptr otherwise) - mozilla::RubyReflowState* mRubyReflowState; - // The appropriate reflow state for the containing block (for // percentage widths, etc.) of this reflow state's frame. const nsHTMLReflowState *mCBReflowState; diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 676f49eeff5f..3bb43cea7b56 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -67,7 +67,6 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, mForceBreakFrameOffset(-1), mMinLineBSize(0), mTextIndent(0), - mRubyReflowState(nullptr), mFirstLetterStyleOK(false), mIsTopOfPage(false), mImpactedByFloats(false), @@ -886,10 +885,6 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, aFrame, availSize); nsHTMLReflowState& reflowState = *reflowStateHolder; reflowState.mLineLayout = this; - if (mRubyReflowState) { - reflowState.mRubyReflowState = mRubyReflowState; - mRubyReflowState = nullptr; - } reflowState.mFlags.mIsTopOfPage = mIsTopOfPage; if (reflowState.ComputedISize() == NS_UNCONSTRAINEDSIZE) { reflowState.AvailableISize() = availableSpaceOnLine; diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 44bf7286aa75..64beb5fe7000 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -27,10 +27,6 @@ class nsFloatManager; struct nsStyleText; -namespace mozilla { -class RubyReflowState; -} - class nsLineLayout { public: /** @@ -102,13 +98,6 @@ public: bool IsZeroBSize(); - // The ruby layout will be passed to the next frame to be reflowed - // via the HTML reflow state. - void SetRubyReflowState(mozilla::RubyReflowState* aRubyReflowState) - { - mRubyReflowState = aRubyReflowState; - } - // Reflows the frame and returns the reflow status. aPushedFrame is true // if the frame is pushed to the next line because it doesn't fit. void ReflowFrame(nsIFrame* aFrame, @@ -565,10 +554,6 @@ protected: int32_t mLineNumber; mozilla::JustificationInfo mJustificationInfo; - // The ruby layout for the next frame to be reflowed. - // It is reset every time it is used. - mozilla::RubyReflowState* mRubyReflowState; - int32_t mTotalPlacedFrames; nscoord mBStartEdge; diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 0a613310b852..0a280ea3c720 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -341,7 +341,6 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, "No line layout provided to RubyBaseContainerFrame reflow method."); return; } - MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided"); AutoTextContainerArray textContainers; GetTextContainers(textContainers); @@ -494,7 +493,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, lineLayout->VerticalAlignLine(); LogicalSize lineSize(lineWM, rtcISize, lineLayout->GetFinalLineBSize()); - aReflowState.mRubyReflowState->SetTextContainerInfo(i, textContainer, lineSize); + textContainer->SetLineSize(lineSize); lineLayout->EndLineReflow(); } diff --git a/layout/generic/nsRubyBaseContainerFrame.h b/layout/generic/nsRubyBaseContainerFrame.h index 526a861d58be..530acc6c2a61 100644 --- a/layout/generic/nsRubyBaseContainerFrame.h +++ b/layout/generic/nsRubyBaseContainerFrame.h @@ -13,7 +13,8 @@ #include "nsRubyTextContainerFrame.h" #include "nsRubyBaseFrame.h" #include "nsRubyTextFrame.h" -#include "RubyReflowState.h" + +#define RTC_ARRAY_SIZE 1 /** * Factory function. diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index c9b059cf139d..68eabe110b53 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -11,7 +11,6 @@ #include "nsStyleContext.h" #include "WritingModes.h" #include "RubyUtils.h" -#include "RubyReflowState.h" #include "nsRubyBaseContainerFrame.h" #include "nsRubyTextContainerFrame.h" @@ -241,11 +240,9 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, textContainers.AppendElement(iter.GetTextContainer()); } const uint32_t rtcCount = textContainers.Length(); - RubyReflowState rubyReflowState(lineWM, textContainers); nsHTMLReflowMetrics baseMetrics(aReflowState); bool pushedFrame; - aReflowState.mLineLayout->SetRubyReflowState(&rubyReflowState); aReflowState.mLineLayout->ReflowFrame(aBaseContainer, aStatus, &baseMetrics, pushedFrame); @@ -330,13 +327,10 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, nsRect offsetRect = baseRect; for (uint32_t i = 0; i < rtcCount; i++) { nsRubyTextContainerFrame* textContainer = textContainers[i]; - rubyReflowState.AdvanceCurrentContainerIndex(); - nsReflowStatus textReflowStatus; nsHTMLReflowMetrics textMetrics(aReflowState); nsHTMLReflowState textReflowState(aPresContext, aReflowState, textContainer, availSize); - textReflowState.mRubyReflowState = &rubyReflowState; // FIXME We probably shouldn't be using the same nsLineLayout for // the text containers. But it should be fine now as we are // not actually using this line layout to reflow something, diff --git a/layout/generic/nsRubyTextContainerFrame.cpp b/layout/generic/nsRubyTextContainerFrame.cpp index 2c75e8a738ca..4721ba0813cc 100644 --- a/layout/generic/nsRubyTextContainerFrame.cpp +++ b/layout/generic/nsRubyTextContainerFrame.cpp @@ -10,7 +10,6 @@ #include "nsPresContext.h" #include "nsStyleContext.h" #include "WritingModes.h" -#include "RubyReflowState.h" #include "mozilla/UniquePtr.h" using namespace mozilla; @@ -125,8 +124,6 @@ nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext, DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); - MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided"); - // All rt children have already been reflowed. All we need to do is // to report complete and return the desired size provided by the // ruby base container. @@ -137,7 +134,5 @@ nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext, // will take care of our continuations. aStatus = NS_FRAME_COMPLETE; WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode(); - const RubyReflowState::TextContainerInfo& info = - aReflowState.mRubyReflowState->GetCurrentTextContainerInfo(this); - aDesiredSize.SetSize(lineWM, info.mLineSize); + aDesiredSize.SetSize(lineWM, mLineSize); } diff --git a/layout/generic/nsRubyTextContainerFrame.h b/layout/generic/nsRubyTextContainerFrame.h index b2588f5048a0..ce79f6242f4c 100644 --- a/layout/generic/nsRubyTextContainerFrame.h +++ b/layout/generic/nsRubyTextContainerFrame.h @@ -62,12 +62,18 @@ protected: NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); explicit nsRubyTextContainerFrame(nsStyleContext* aContext) - : nsRubyTextContainerFrameSuper(aContext) {} + : nsRubyTextContainerFrameSuper(aContext) + , mLineSize(mozilla::WritingMode(aContext)) {} void UpdateSpanFlag(); - // For MoveOverflowToChildList friend class nsRubyBaseContainerFrame; + void SetLineSize(const mozilla::LogicalSize& aSize) { mLineSize = aSize; } + + // The intended dimensions of the ruby text container. It is set by + // the corresponding ruby base container when the segment is reflowed, + // and used when the ruby text container is reflowed by its parent. + mozilla::LogicalSize mLineSize; }; #endif /* nsRubyTextContainerFrame_h___ */ From e056d920d02765ca9a631efe224e7ad9218e9730 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 8 Jan 2015 12:51:00 +0000 Subject: [PATCH 023/224] Bug 1062108 - Don't increase glyph advances when applying fake-bold to a fixed-pitch font. r=jdaggett --- gfx/thebes/gfxFT2Fonts.cpp | 3 ++- gfx/thebes/gfxFont.cpp | 16 +++++++++++----- gfx/thebes/gfxFont.h | 1 + gfx/thebes/gfxMacFont.cpp | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/gfx/thebes/gfxFT2Fonts.cpp b/gfx/thebes/gfxFT2Fonts.cpp index 45618655a1b3..26ae52e9efcb 100644 --- a/gfx/thebes/gfxFT2Fonts.cpp +++ b/gfx/thebes/gfxFT2Fonts.cpp @@ -55,7 +55,8 @@ gfxFT2Font::ShapeText(gfxContext *aContext, aVertical, aShapedText)) { // harfbuzz must have failed(?!), just render raw glyphs AddRange(aText, aOffset, aLength, aShapedText); - PostShapingFixup(aContext, aText, aOffset, aLength, aShapedText); + PostShapingFixup(aContext, aText, aOffset, aLength, aVertical, + aShapedText); } return true; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index c72dbb4c092b..ff246686d4f8 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -2490,7 +2490,8 @@ gfxFont::ShapeText(gfxContext *aContext, NS_WARN_IF_FALSE(ok, "shaper failed, expect scrambled or missing text"); - PostShapingFixup(aContext, aText, aOffset, aLength, aShapedText); + PostShapingFixup(aContext, aText, aOffset, aLength, aVertical, + aShapedText); return ok; } @@ -2500,13 +2501,18 @@ gfxFont::PostShapingFixup(gfxContext *aContext, const char16_t *aText, uint32_t aOffset, uint32_t aLength, + bool aVertical, gfxShapedText *aShapedText) { if (IsSyntheticBold()) { - float synBoldOffset = - GetSyntheticBoldOffset() * CalcXScale(aContext); - aShapedText->AdjustAdvancesForSyntheticBold(synBoldOffset, - aOffset, aLength); + const Metrics& metrics = + GetMetrics(aVertical ? eVertical : eHorizontal); + if (metrics.maxAdvance > metrics.aveCharWidth) { + float synBoldOffset = + GetSyntheticBoldOffset() * CalcXScale(aContext); + aShapedText->AdjustAdvancesForSyntheticBold(synBoldOffset, + aOffset, aLength); + } } } diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index aeeb2da229b4..f641d8fdf097 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1881,6 +1881,7 @@ protected: const char16_t *aText, uint32_t aOffset, // position within aShapedText uint32_t aLength, + bool aVertical, gfxShapedText *aShapedText); // Shape text directly into a range within a textrun, without using the diff --git a/gfx/thebes/gfxMacFont.cpp b/gfx/thebes/gfxMacFont.cpp index 2f36f4e7afc7..aa7e71fc668c 100644 --- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -143,7 +143,8 @@ gfxMacFont::ShapeText(gfxContext *aContext, } if (mCoreTextShaper->ShapeText(aContext, aText, aOffset, aLength, aScript, aVertical, aShapedText)) { - PostShapingFixup(aContext, aText, aOffset, aLength, aShapedText); + PostShapingFixup(aContext, aText, aOffset, aLength, aVertical, + aShapedText); return true; } } From f29017166bd7e4af7c8b09b46a517c184cd0caff Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 8 Jan 2015 12:52:03 +0000 Subject: [PATCH 024/224] Bug 1062108 - Test that and have the same width in bold monospace font. r=jdaggett --- layout/reftests/bugs/1062108-1-ref.html | 16 ++++++++++++++++ layout/reftests/bugs/1062108-1.html | 16 ++++++++++++++++ layout/reftests/bugs/reftest.list | 1 + 3 files changed, 33 insertions(+) create mode 100644 layout/reftests/bugs/1062108-1-ref.html create mode 100644 layout/reftests/bugs/1062108-1.html diff --git a/layout/reftests/bugs/1062108-1-ref.html b/layout/reftests/bugs/1062108-1-ref.html new file mode 100644 index 000000000000..8a45e122c5ff --- /dev/null +++ b/layout/reftests/bugs/1062108-1-ref.html @@ -0,0 +1,16 @@ + + + + +Bug 1062108 + + + +10 spaces: "xxxxxxxxxx" + + diff --git a/layout/reftests/bugs/1062108-1.html b/layout/reftests/bugs/1062108-1.html new file mode 100644 index 000000000000..1f6b8f99fa64 --- /dev/null +++ b/layout/reftests/bugs/1062108-1.html @@ -0,0 +1,16 @@ + + + + +Bug 1062108 + + + +10 spaces: "          " + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 8f232e0a4e8f..00137b2d4929 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1841,6 +1841,7 @@ test-pref(layout.css.grid.enabled,true) == 1053035-1-grid.html 1053035-1-ref.htm == 1059498-1.html 1059498-1-ref.html == 1059498-2.html 1059498-1-ref.html == 1059498-3.html 1059498-1-ref.html +== 1062108-1.html 1062108-1-ref.html fails-if(Android) == 1062792-1.html 1062792-1-ref.html == 1062963-floatmanager-reflow.html 1062963-floatmanager-reflow-ref.html test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html From 8da00ce66d978f9e503934d0ac69a3c1ca0f039f Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Thu, 8 Jan 2015 12:52:10 +0000 Subject: [PATCH 025/224] Bug 1062108 - Adjust existing tests that are affected by the fix to synthetic-bold glyph advance. r=jdaggett --- layout/reftests/bugs/reftest.list | 2 +- layout/reftests/text/synthetic-bold-metrics-01-notref.html | 6 +++--- layout/reftests/text/synthetic-bold-metrics-01.html | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 00137b2d4929..52c2e10f6bd5 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1194,7 +1194,7 @@ test-pref(dom.use_xbl_scopes_for_remote_xul,true) != 449149-1b.html about:blank == 455105-2.html 455105-ref.html == 455171-5.html 455171-5-ref.html == 455280-1.xhtml 455280-1-ref.xhtml -skip-if(B2G) fails-if(Android) == 455826-1.html 455826-1-ref.html +skip-if(B2G) == 455826-1.html 455826-1-ref.html skip-if(B2G) fails-if(cocoaWidget) fails-if(Android) == 456147.xul 456147-ref.html # bug 458047 fuzzy-if(Android,11,40) fuzzy-if(B2G,11,35) fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1a.html 456219-1-ref.html # bug 853273 fuzzy-if(Android,11,40) fuzzy-if(B2G,11,35) fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1b.html 456219-1-ref.html # bug 853273 diff --git a/layout/reftests/text/synthetic-bold-metrics-01-notref.html b/layout/reftests/text/synthetic-bold-metrics-01-notref.html index 6b239637084a..62eeebde6688 100644 --- a/layout/reftests/text/synthetic-bold-metrics-01-notref.html +++ b/layout/reftests/text/synthetic-bold-metrics-01-notref.html @@ -3,12 +3,12 @@ + 新幹線 diff --git a/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html b/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html index 23258d28a065..74b174bcfa67 100644 --- a/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html +++ b/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html @@ -6,15 +6,7 @@ - + diff --git a/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html b/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html index 88ebf819030d..d707237ca90b 100644 --- a/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html +++ b/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html @@ -6,14 +6,9 @@ + diff --git a/layout/reftests/css-ruby/ruby-whitespace-1-ref.html b/layout/reftests/css-ruby/ruby-whitespace-1-ref.html index 8a9c1c9d313d..18393f0d72d4 100644 --- a/layout/reftests/css-ruby/ruby-whitespace-1-ref.html +++ b/layout/reftests/css-ruby/ruby-whitespace-1-ref.html @@ -1,15 +1,9 @@ + @@ -25,7 +19,7 @@ ruby, rb, rt, rbc, rtc { unicode-bidi: isolate; }

Base one Base threeText one Text three + >

Text one Text three

diff --git a/layout/reftests/css-ruby/ruby-whitespace-1.html b/layout/reftests/css-ruby/ruby-whitespace-1.html index 3c8a10757e3c..ca09154cbfc3 100644 --- a/layout/reftests/css-ruby/ruby-whitespace-1.html +++ b/layout/reftests/css-ruby/ruby-whitespace-1.html @@ -1,15 +1,9 @@ + diff --git a/layout/reftests/css-ruby/ruby-whitespace-2-ref.html b/layout/reftests/css-ruby/ruby-whitespace-2-ref.html index 518f85d44988..dd8007af584a 100644 --- a/layout/reftests/css-ruby/ruby-whitespace-2-ref.html +++ b/layout/reftests/css-ruby/ruby-whitespace-2-ref.html @@ -2,25 +2,17 @@ - + -abcd BASETEXT +abcd BASETEXT -abcdBASETEXT +abcdBASETEXT -abcd BASETEXT +abcd BASETEXT diff --git a/layout/reftests/css-ruby/ruby-whitespace-2.html b/layout/reftests/css-ruby/ruby-whitespace-2.html index 71d5904c4505..92895975df3c 100644 --- a/layout/reftests/css-ruby/ruby-whitespace-2.html +++ b/layout/reftests/css-ruby/ruby-whitespace-2.html @@ -2,15 +2,7 @@ - + From bfb0d2cc6e8d3fb2fdd6c93dd1a61fdc9139a6de Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 16:02:41 +1100 Subject: [PATCH 119/224] Bug 1069519 part 2 - Make line height calculation be aware of ruby annotations. r=dholbert --HG-- extra : source : e8c8f94afde330276b5d907520d93da10e8f998c --- layout/generic/nsLineLayout.cpp | 24 +++++++++++++++++++ layout/generic/nsRubyFrame.cpp | 11 +++++++++ layout/generic/nsRubyFrame.h | 12 ++++++++++ .../css-ruby/justification-1-ref.html | 2 +- layout/reftests/css-ruby/justification-1.html | 4 ++-- .../css-ruby/ruby-reflow-1-noruby.html | 3 +++ .../css-ruby/ruby-reflow-1-opaqueruby.html | 3 +++ .../ruby-reflow-1-transparentruby.html | 1 + 8 files changed, 57 insertions(+), 3 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 7b5d1b9f072a..3e222ca16d5a 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -24,6 +24,7 @@ #include "nsTextFrame.h" #include "nsStyleStructInlines.h" #include "nsBidiPresUtils.h" +#include "nsRubyFrame.h" #include "RubyUtils.h" #include @@ -1826,6 +1827,29 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) psd->mBStartLeading = leading / 2; psd->mBEndLeading = leading - psd->mBStartLeading; psd->mLogicalBSize = logicalBSize; + if (spanFrame->GetType() == nsGkAtoms::rubyFrame) { + // We may need to extend leadings here for ruby annotations as + // required by section Line Spacing in the CSS Ruby spec. + // See http://dev.w3.org/csswg/css-ruby/#line-height + auto rubyFrame = static_cast(spanFrame); + nscoord startLeading, endLeading; + rubyFrame->GetBlockLeadings(startLeading, endLeading); + nscoord deltaLeading = startLeading + endLeading - leading; + if (deltaLeading > 0) { + // If the total leading is not wide enough for ruby annotations, + // extend the side which is not enough. If both sides are not + // wide enough, replace the leadings with the requested values. + if (startLeading < psd->mBStartLeading) { + psd->mBEndLeading += deltaLeading; + } else if (endLeading < psd->mBEndLeading) { + psd->mBStartLeading += deltaLeading; + } else { + psd->mBStartLeading = startLeading; + psd->mBEndLeading = endLeading; + } + psd->mLogicalBSize += deltaLeading; + } + } if (zeroEffectiveSpanBox) { // When the span-box is to be ignored, zero out the initial diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 8126ceb6154f..c9b059cf139d 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -167,6 +167,9 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, // Grab overflow frames from prev-in-flow and its own. MoveOverflowToChildList(); + // Clear leadings + mBStartLeading = mBEndLeading = 0; + // Begin the span for the ruby frame WritingMode frameWM = aReflowState.GetWritingMode(); WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode(); @@ -394,6 +397,14 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, RubyUtils::SetReservedISize(aBaseContainer, deltaISize); aReflowState.mLineLayout->AdvanceICoord(deltaISize); } + + // Set block leadings of the base container + LogicalMargin leadings(lineWM, offsetRect - baseRect); + NS_ASSERTION(leadings.BStart(lineWM) >= 0 && leadings.BEnd(lineWM) >= 0, + "Leadings should be non-negative (because adding " + "ruby annotation can only increase the size)"); + mBStartLeading = std::max(mBStartLeading, leadings.BStart(lineWM)); + mBEndLeading = std::max(mBEndLeading, leadings.BEnd(lineWM)); } nsRubyBaseContainerFrame* diff --git a/layout/generic/nsRubyFrame.h b/layout/generic/nsRubyFrame.h index cef1aad8c9a5..9beb4346b64e 100644 --- a/layout/generic/nsRubyFrame.h +++ b/layout/generic/nsRubyFrame.h @@ -56,6 +56,12 @@ public: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif + void GetBlockLeadings(nscoord& aStartLeading, nscoord& aEndLeading) + { + aStartLeading = mBStartLeading; + aEndLeading = mBEndLeading; + } + protected: friend nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); @@ -68,7 +74,13 @@ protected: nsRubyBaseContainerFrame* PullOneSegment(ContinuationTraversingState& aState); + // The three members below are not initialized until the first reflow. + nscoord mBaseline; + + // The leadings required to put the annotations. + nscoord mBStartLeading; + nscoord mBEndLeading; }; #endif /* nsRubyFrame_h___ */ diff --git a/layout/reftests/css-ruby/justification-1-ref.html b/layout/reftests/css-ruby/justification-1-ref.html index 0033e450e1d4..160376f02e05 100644 --- a/layout/reftests/css-ruby/justification-1-ref.html +++ b/layout/reftests/css-ruby/justification-1-ref.html @@ -5,7 +5,7 @@ Bug 1116631 - Justification with ruby span diff --git a/layout/reftests/css-ruby/justification-1.html b/layout/reftests/css-ruby/justification-1.html index d20ac0b43c42..52ed780763d1 100644 --- a/layout/reftests/css-ruby/justification-1.html +++ b/layout/reftests/css-ruby/justification-1.html @@ -5,13 +5,13 @@ Bug 1116631 - Justification with ruby span

ab -
+
diff --git a/layout/reftests/css-ruby/ruby-reflow-1-noruby.html b/layout/reftests/css-ruby/ruby-reflow-1-noruby.html index 11130b0f8b19..4119dc9bd3f8 100644 --- a/layout/reftests/css-ruby/ruby-reflow-1-noruby.html +++ b/layout/reftests/css-ruby/ruby-reflow-1-noruby.html @@ -7,6 +7,9 @@ + 新幹線 diff --git a/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html b/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html index 74b174bcfa67..245d7136d579 100644 --- a/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html +++ b/layout/reftests/css-ruby/ruby-reflow-1-opaqueruby.html @@ -7,6 +7,9 @@ + diff --git a/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html b/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html index d707237ca90b..0d2967a384c6 100644 --- a/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html +++ b/layout/reftests/css-ruby/ruby-reflow-1-transparentruby.html @@ -8,6 +8,7 @@ From 364fe61104b14afc5afc7edb97f4a7525cac1c0c Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 16:02:41 +1100 Subject: [PATCH 120/224] Bug 1069519 part 3 - Add reftests for ruby line height calculation. r=dholbert --HG-- extra : source : 728da9f1603aea283356de9f69f678667514cc70 --- .../reftests/css-ruby/line-height-1-ref.html | 17 +++++++++++++++++ layout/reftests/css-ruby/line-height-1.html | 14 ++++++++++++++ .../reftests/css-ruby/line-height-2-ref.html | 18 ++++++++++++++++++ layout/reftests/css-ruby/line-height-2.html | 15 +++++++++++++++ .../reftests/css-ruby/line-height-3-ref.html | 18 ++++++++++++++++++ layout/reftests/css-ruby/line-height-3.html | 16 ++++++++++++++++ layout/reftests/css-ruby/reftest.list | 3 +++ layout/reftests/css-ruby/utils.js | 5 +++++ 8 files changed, 106 insertions(+) create mode 100644 layout/reftests/css-ruby/line-height-1-ref.html create mode 100644 layout/reftests/css-ruby/line-height-1.html create mode 100644 layout/reftests/css-ruby/line-height-2-ref.html create mode 100644 layout/reftests/css-ruby/line-height-2.html create mode 100644 layout/reftests/css-ruby/line-height-3-ref.html create mode 100644 layout/reftests/css-ruby/line-height-3.html create mode 100644 layout/reftests/css-ruby/utils.js diff --git a/layout/reftests/css-ruby/line-height-1-ref.html b/layout/reftests/css-ruby/line-height-1-ref.html new file mode 100644 index 000000000000..f12eb3ea567c --- /dev/null +++ b/layout/reftests/css-ruby/line-height-1-ref.html @@ -0,0 +1,17 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + +
base
+ + + diff --git a/layout/reftests/css-ruby/line-height-1.html b/layout/reftests/css-ruby/line-height-1.html new file mode 100644 index 000000000000..fc7463e381e4 --- /dev/null +++ b/layout/reftests/css-ruby/line-height-1.html @@ -0,0 +1,14 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + + base + text + + + diff --git a/layout/reftests/css-ruby/line-height-2-ref.html b/layout/reftests/css-ruby/line-height-2-ref.html new file mode 100644 index 000000000000..9ed54600be19 --- /dev/null +++ b/layout/reftests/css-ruby/line-height-2-ref.html @@ -0,0 +1,18 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + +
base
+ next line + + + diff --git a/layout/reftests/css-ruby/line-height-2.html b/layout/reftests/css-ruby/line-height-2.html new file mode 100644 index 000000000000..bc401e329345 --- /dev/null +++ b/layout/reftests/css-ruby/line-height-2.html @@ -0,0 +1,15 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + + base + text +
+ next line + + diff --git a/layout/reftests/css-ruby/line-height-3-ref.html b/layout/reftests/css-ruby/line-height-3-ref.html new file mode 100644 index 000000000000..f919b1ace479 --- /dev/null +++ b/layout/reftests/css-ruby/line-height-3-ref.html @@ -0,0 +1,18 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + +
base
+ next line + + + diff --git a/layout/reftests/css-ruby/line-height-3.html b/layout/reftests/css-ruby/line-height-3.html new file mode 100644 index 000000000000..4aa331ed754d --- /dev/null +++ b/layout/reftests/css-ruby/line-height-3.html @@ -0,0 +1,16 @@ + + + + + Bug 1069519 - Ruby line height calculation + + + + + base + text + text +
+ next line + + diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index 6b43e2cc2c3d..dc4c405ae9ee 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -22,6 +22,9 @@ fuzzy-if(winWidget,35,1) == dynamic-removal-3.html dynamic-removal-3-ref.html # == inlinize-blocks-5.html inlinize-blocks-5-ref.html == justification-1.html justification-1-ref.html == justification-2.html justification-2-ref.html +== line-height-1.html line-height-1-ref.html +== line-height-2.html line-height-2-ref.html +== line-height-3.html line-height-3-ref.html == ruby-span-1.html ruby-span-1-ref.html == ruby-whitespace-1.html ruby-whitespace-1-ref.html == ruby-whitespace-2.html ruby-whitespace-2-ref.html diff --git a/layout/reftests/css-ruby/utils.js b/layout/reftests/css-ruby/utils.js new file mode 100644 index 000000000000..49a99d202a34 --- /dev/null +++ b/layout/reftests/css-ruby/utils.js @@ -0,0 +1,5 @@ +function makeHeightMatchInlineBox(block, inline) { + var height = inline.getBoundingClientRect().height + 'px'; + block.style.height = height; + block.style.lineHeight = height; +} From 05d08f5899840a0a08343fccff35a31c35bf3193 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Wed, 7 Jan 2015 15:51:20 -0800 Subject: [PATCH 121/224] Bug 1107638 - Add innerWindowID to LoadInfo (r=sicking,jduell) --- docshell/base/LoadInfo.cpp | 24 ++++++++++++++++++++ docshell/base/LoadInfo.h | 18 +++++++++++++++ docshell/base/nsILoadInfo.idl | 20 +++++++++++++++++ netwerk/ipc/NeckoChannelParams.ipdlh | 2 ++ netwerk/protocol/ftp/FTPChannelChild.cpp | 2 ++ netwerk/protocol/ftp/FTPChannelParent.cpp | 25 ++++++++++----------- netwerk/protocol/ftp/FTPChannelParent.h | 3 ++- netwerk/protocol/http/HttpChannelChild.cpp | 2 ++ netwerk/protocol/http/HttpChannelParent.cpp | 24 +++++++++----------- netwerk/protocol/http/HttpChannelParent.h | 3 ++- 10 files changed, 95 insertions(+), 28 deletions(-) diff --git a/docshell/base/LoadInfo.cpp b/docshell/base/LoadInfo.cpp index e2e8c2c4c637..2969ef7f2f22 100644 --- a/docshell/base/LoadInfo.cpp +++ b/docshell/base/LoadInfo.cpp @@ -28,6 +28,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mSecurityFlags(aSecurityFlags) , mContentPolicyType(aContentPolicyType) , mBaseURI(aBaseURI) + , mInnerWindowID(aLoadingContext ? + aLoadingContext->OwnerDoc()->InnerWindowID() : 0) { MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); @@ -43,6 +45,21 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, } } +LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsSecurityFlags aSecurityFlags, + nsContentPolicyType aContentPolicyType, + uint32_t aInnerWindowID) + : mLoadingPrincipal(aLoadingPrincipal) + , mTriggeringPrincipal(aTriggeringPrincipal) + , mSecurityFlags(aSecurityFlags) + , mContentPolicyType(aContentPolicyType) + , mInnerWindowID(aInnerWindowID) +{ + MOZ_ASSERT(mLoadingPrincipal); + MOZ_ASSERT(mTriggeringPrincipal); +} + LoadInfo::~LoadInfo() { } @@ -135,4 +152,11 @@ LoadInfo::BaseURI() return mBaseURI; } +NS_IMETHODIMP +LoadInfo::GetInnerWindowID(uint32_t* outInnerWindowID) +{ + *outInnerWindowID = mInnerWindowID; + return NS_OK; +} + } // namespace mozilla diff --git a/docshell/base/LoadInfo.h b/docshell/base/LoadInfo.h index 974cc1fd35de..d391505d0bff 100644 --- a/docshell/base/LoadInfo.h +++ b/docshell/base/LoadInfo.h @@ -17,6 +17,11 @@ class nsINode; namespace mozilla { +namespace net { +class HttpChannelParent; +class FTPChannelParent; +} + /** * Class that provides an nsILoadInfo implementation. */ @@ -35,6 +40,18 @@ public: nsIURI* aBaseURI = nullptr); private: + // private constructor that is only allowed to be called from within + // HttpChannelParent and FTPChannelParent declared as friends undeneath. + // In e10s we can not serialize nsINode, hence we store the innerWindowID. + LoadInfo(nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsSecurityFlags aSecurityFlags, + nsContentPolicyType aContentPolicyType, + uint32_t aInnerWindowID); + + friend class net::HttpChannelParent; + friend class net::FTPChannelParent; + ~LoadInfo(); nsCOMPtr mLoadingPrincipal; @@ -43,6 +60,7 @@ private: nsSecurityFlags mSecurityFlags; nsContentPolicyType mContentPolicyType; nsCOMPtr mBaseURI; + uint32_t mInnerWindowID; }; } // namespace mozilla diff --git a/docshell/base/nsILoadInfo.idl b/docshell/base/nsILoadInfo.idl index 2e516d821388..d68c29e40a29 100644 --- a/docshell/base/nsILoadInfo.idl +++ b/docshell/base/nsILoadInfo.idl @@ -180,4 +180,24 @@ interface nsILoadInfo : nsISupports */ [noscript, notxpcom, nostdcall, binaryname(BaseURI)] nsIURI binaryBaseURI(); + + /** + * The innerWindowId of the loadingDocument, used to identify + * the loadingDocument in e10s where the loadingDocument is + * not available. + * + * Warning: If the loadingDocument is null, then the + * innerWindowId is 0. + */ + readonly attribute unsigned long innerWindowID; + +%{ C++ + inline uint32_t GetInnerWindowID() + { + uint32_t result; + mozilla::DebugOnly rv = GetInnerWindowID(&result); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + return result; + } +%} }; diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 9a0783fc4eb1..fef864f52afe 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -57,6 +57,7 @@ struct HttpChannelOpenArgs PrincipalInfo triggeringPrincipalInfo; uint32_t securityFlags; uint32_t contentPolicyType; + uint32_t innerWindowID; }; struct HttpChannelConnectArgs @@ -84,6 +85,7 @@ struct FTPChannelOpenArgs PrincipalInfo triggeringPrincipalInfo; uint32_t securityFlags; uint32_t contentPolicyType; + uint32_t innerWindowID; }; struct FTPChannelConnectArgs diff --git a/netwerk/protocol/ftp/FTPChannelChild.cpp b/netwerk/protocol/ftp/FTPChannelChild.cpp index b4ef232f53f0..049526fea45d 100644 --- a/netwerk/protocol/ftp/FTPChannelChild.cpp +++ b/netwerk/protocol/ftp/FTPChannelChild.cpp @@ -163,6 +163,7 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo, openArgs.securityFlags() = aLoadInfo->GetSecurityFlags(); openArgs.contentPolicyType() = aLoadInfo->GetContentPolicyType(); + openArgs.innerWindowID() = aLoadInfo->GetInnerWindowID(); return; } @@ -173,6 +174,7 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo, openArgs.triggeringPrincipalInfo() = requestingPrincipalInfo; openArgs.securityFlags() = nsILoadInfo::SEC_NORMAL; openArgs.contentPolicyType() = nsIContentPolicy::TYPE_OTHER; + openArgs.innerWindowID() = 0; } NS_IMETHODIMP diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp index c367b56dd087..d7c4c00e4f43 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -19,6 +19,7 @@ #include "nsIContentPolicy.h" #include "mozilla/ipc/BackgroundUtils.h" #include "nsIOService.h" +#include "mozilla/LoadInfo.h" using namespace mozilla::ipc; @@ -88,7 +89,7 @@ FTPChannelParent::Init(const FTPChannelCreationArgs& aArgs) const FTPChannelOpenArgs& a = aArgs.get_FTPChannelOpenArgs(); return DoAsyncOpen(a.uri(), a.startPos(), a.entityID(), a.uploadStream(), a.requestingPrincipalInfo(), a.triggeringPrincipalInfo(), - a.securityFlags(), a.contentPolicyType()); + a.securityFlags(), a.contentPolicyType(), a.innerWindowID()); } case FTPChannelCreationArgs::TFTPChannelConnectArgs: { @@ -109,7 +110,8 @@ FTPChannelParent::DoAsyncOpen(const URIParams& aURI, const ipc::PrincipalInfo& aRequestingPrincipalInfo, const ipc::PrincipalInfo& aTriggeringPrincipalInfo, const uint32_t& aSecurityFlags, - const uint32_t& aContentPolicyType) + const uint32_t& aContentPolicyType, + const uint32_t& aInnerWindowID) { nsCOMPtr uri = DeserializeURI(aURI); if (!uri) @@ -148,19 +150,16 @@ FTPChannelParent::DoAsyncOpen(const URIParams& aURI, if (NS_FAILED(rv)) { return SendFailedAsyncOpen(rv); } - + + nsCOMPtr loadInfo = + new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, + aSecurityFlags, aContentPolicyType, + aInnerWindowID); nsCOMPtr chan; - rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(chan), - uri, - requestingPrincipal, - triggeringPrincipal, - aSecurityFlags, - aContentPolicyType, - nullptr, // aLoadGroup - nullptr, // aCallbacks - nsIRequest::LOAD_NORMAL, - ios); + rv = NS_NewChannelInternal(getter_AddRefs(chan), uri, loadInfo, + nullptr, nullptr, + nsIRequest::LOAD_NORMAL, ios); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); diff --git a/netwerk/protocol/ftp/FTPChannelParent.h b/netwerk/protocol/ftp/FTPChannelParent.h index 8101bf47734d..1254d7be6583 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.h +++ b/netwerk/protocol/ftp/FTPChannelParent.h @@ -68,7 +68,8 @@ protected: const ipc::PrincipalInfo& aRequestingPrincipalInfo, const ipc::PrincipalInfo& aTriggeringPrincipalInfo, const uint32_t& aSecurityFlags, - const uint32_t& aContentPolicyType); + const uint32_t& aContentPolicyType, + const uint32_t& aInnerWindowID); // used to connect redirected-to channel in parent with just created // ChildChannel. Used during HTTP->FTP redirects. diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index a1828b4f59db..70289006d8aa 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1275,6 +1275,7 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo, openArgs.securityFlags() = aLoadInfo->GetSecurityFlags(); openArgs.contentPolicyType() = aLoadInfo->GetContentPolicyType(); + openArgs.innerWindowID() = aLoadInfo->GetInnerWindowID(); return; } @@ -1285,6 +1286,7 @@ propagateLoadInfo(nsILoadInfo *aLoadInfo, openArgs.triggeringPrincipalInfo() = requestingPrincipalInfo; openArgs.securityFlags() = nsILoadInfo::SEC_NORMAL; openArgs.contentPolicyType() = nsIContentPolicy::TYPE_OTHER; + openArgs.innerWindowID() = 0; } NS_IMETHODIMP diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 352cec741f48..b5e4192f7ed1 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -31,7 +31,7 @@ #include "mozilla/ipc/BackgroundUtils.h" #include "nsIOService.h" #include "nsICachingChannel.h" - +#include "mozilla/LoadInfo.h" using namespace mozilla::dom; using namespace mozilla::ipc; @@ -106,7 +106,7 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs) a.entityID(), a.chooseApplicationCache(), a.appCacheClientID(), a.allowSpdy(), a.fds(), a.requestingPrincipalInfo(), a.triggeringPrincipalInfo(), - a.securityFlags(), a.contentPolicyType()); + a.securityFlags(), a.contentPolicyType(), a.innerWindowID()); } case HttpChannelCreationArgs::THttpChannelConnectArgs: { @@ -196,7 +196,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI, const ipc::PrincipalInfo& aRequestingPrincipalInfo, const ipc::PrincipalInfo& aTriggeringPrincipalInfo, const uint32_t& aSecurityFlags, - const uint32_t& aContentPolicyType) + const uint32_t& aContentPolicyType, + const uint32_t& aInnerWindowID) { nsCOMPtr uri = DeserializeURI(aURI); if (!uri) { @@ -246,17 +247,14 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI, loadFlags |= nsICachingChannel::LOAD_NO_NETWORK_IO; } + nsCOMPtr loadInfo = + new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, + aSecurityFlags, aContentPolicyType, + aInnerWindowID); + nsCOMPtr channel; - rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel), - uri, - requestingPrincipal, - triggeringPrincipal, - aSecurityFlags, - aContentPolicyType, - nullptr, // loadGroup - nullptr, // aCallbacks - loadFlags, - ios); + rv = NS_NewChannelInternal(getter_AddRefs(channel), uri, loadInfo, + nullptr, nullptr, loadFlags, ios); if (NS_FAILED(rv)) return SendFailedAsyncOpen(rv); diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 27e974a1849b..c3a446502f55 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -114,7 +114,8 @@ protected: const ipc::PrincipalInfo& aRequestingPrincipalInfo, const ipc::PrincipalInfo& aTriggeringPrincipalInfo, const uint32_t& aSecurityFlags, - const uint32_t& aContentPolicyType); + const uint32_t& aContentPolicyType, + const uint32_t& aInnerWindowID); virtual bool RecvSetPriority(const uint16_t& priority) MOZ_OVERRIDE; virtual bool RecvSetClassOfService(const uint32_t& cos) MOZ_OVERRIDE; From 9996110430903a49ffeafe0f11f9cce509a860dc Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 7 Jan 2015 01:18:42 -0800 Subject: [PATCH 122/224] Bug 1118038 - Remove JIT parts of PJS. (r=lth) --- js/src/asmjs/AsmJSValidate.cpp | 2 +- js/src/gc/Zone.cpp | 3 +- js/src/jit/BaselineIC.cpp | 35 +- js/src/jit/CodeGenerator.cpp | 803 +++------------ js/src/jit/CodeGenerator.h | 27 - js/src/jit/CompileInfo.h | 4 - js/src/jit/Ion.cpp | 319 +----- js/src/jit/Ion.h | 5 - js/src/jit/IonAnalysis.cpp | 1 - js/src/jit/IonBuilder.cpp | 71 +- js/src/jit/IonBuilder.h | 8 - js/src/jit/IonCaches.cpp | 448 +-------- js/src/jit/IonCaches.h | 287 +----- js/src/jit/IonCode.h | 16 +- js/src/jit/IonTypes.h | 5 +- js/src/jit/JitCompartment.h | 51 +- js/src/jit/JitFrames.cpp | 24 - js/src/jit/JitFrames.h | 1 - js/src/jit/LIR-Common.h | 350 +------ js/src/jit/LIR.h | 2 - js/src/jit/LOpcodes.h | 11 - js/src/jit/Lowering.cpp | 134 +-- js/src/jit/Lowering.h | 10 - js/src/jit/MCallOptimize.cpp | 134 --- js/src/jit/MIR.cpp | 11 - js/src/jit/MIR.h | 377 -------- js/src/jit/MIRGraph.cpp | 32 - js/src/jit/MIRGraph.h | 6 - js/src/jit/MOpcodes.h | 11 - js/src/jit/MacroAssembler.cpp | 260 +---- js/src/jit/MacroAssembler.h | 50 +- js/src/jit/ParallelFunctions.cpp | 620 ------------ js/src/jit/ParallelFunctions.h | 81 -- js/src/jit/ParallelSafetyAnalysis.cpp | 913 ------------------ js/src/jit/ParallelSafetyAnalysis.h | 51 - js/src/jit/VMFunctions.h | 4 - js/src/jit/arm/Bailouts-arm.cpp | 5 +- js/src/jit/arm/CodeGenerator-arm.cpp | 20 +- js/src/jit/arm/CodeGenerator-arm.h | 2 - js/src/jit/arm/Lowering-arm.cpp | 6 - js/src/jit/arm/Lowering-arm.h | 7 - js/src/jit/arm/Trampoline-arm.cpp | 55 +- js/src/jit/mips/Bailouts-mips.cpp | 5 +- js/src/jit/mips/CodeGenerator-mips.cpp | 14 +- js/src/jit/mips/CodeGenerator-mips.h | 2 - js/src/jit/mips/Lowering-mips.cpp | 6 - js/src/jit/mips/Lowering-mips.h | 7 - js/src/jit/mips/Trampoline-mips.cpp | 54 +- js/src/jit/none/Lowering-none.h | 2 - js/src/jit/none/Trampoline-none.cpp | 5 +- js/src/jit/shared/CodeGenerator-shared.cpp | 13 +- js/src/jit/shared/CodeGenerator-shared.h | 1 - .../jit/shared/CodeGenerator-x86-shared.cpp | 173 +--- js/src/jit/shared/CodeGenerator-x86-shared.h | 2 - js/src/jit/shared/Lowering-shared.h | 5 - js/src/jit/shared/Lowering-x86-shared.cpp | 13 - js/src/jit/shared/Lowering-x86-shared.h | 1 - js/src/jit/x64/Assembler-x64.h | 7 - js/src/jit/x64/Bailouts-x64.cpp | 6 +- js/src/jit/x64/Lowering-x64.h | 10 - js/src/jit/x64/Trampoline-x64.cpp | 51 +- js/src/jit/x86/Assembler-x86.h | 7 - js/src/jit/x86/Bailouts-x86.cpp | 5 +- js/src/jit/x86/CodeGenerator-x86.cpp | 47 - js/src/jit/x86/Lowering-x86.cpp | 23 - js/src/jit/x86/Lowering-x86.h | 5 - js/src/jit/x86/Trampoline-x86.cpp | 53 +- js/src/jsgc.cpp | 3 +- js/src/moz.build | 2 - js/src/vm/ForkJoin.cpp | 65 +- 70 files changed, 275 insertions(+), 5574 deletions(-) delete mode 100644 js/src/jit/ParallelFunctions.cpp delete mode 100644 js/src/jit/ParallelFunctions.h delete mode 100644 js/src/jit/ParallelSafetyAnalysis.cpp delete mode 100644 js/src/jit/ParallelSafetyAnalysis.h diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index 9219fd04c05d..832a35c930df 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -8492,7 +8492,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit // 2.4. Load callee executable entry point masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee); - masm.loadBaselineOrIonNoArgCheck(callee, callee, SequentialExecution, nullptr); + masm.loadBaselineOrIonNoArgCheck(callee, callee, nullptr); // 3. Argc unsigned argc = exit.sig().args().length(); diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 898cd63c6fd4..105ed4a59f2b 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -185,8 +185,7 @@ Zone::discardJitCode(FreeOp *fop) for (ZoneCellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); - jit::FinishInvalidation(fop, script); - jit::FinishInvalidation(fop, script); + jit::FinishInvalidation(fop, script); /* * Discard baseline script if it's not marked as active. Note that diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 9d8970462b32..8aa26837caf1 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4261,7 +4261,7 @@ ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg) Register code = regs.takeAnyExcluding(ArgumentsRectifierReg); masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code); - masm.loadBaselineOrIonRaw(code, code, SequentialExecution, nullptr); + masm.loadBaselineOrIonRaw(code, code, nullptr); Register scratch = regs.takeAny(); @@ -4274,7 +4274,7 @@ ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg) MOZ_ASSERT(ArgumentsRectifierReg != code); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), code); masm.loadPtr(Address(code, JitCode::offsetOfCode()), code); @@ -4494,8 +4494,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm) scratchReg); masm.branchIfFunctionHasNoScript(scratchReg, popR1 ? &failurePopR1 : &failure); masm.loadPtr(Address(scratchReg, JSFunction::offsetOfNativeOrScript()), scratchReg); - masm.loadBaselineOrIonRaw(scratchReg, scratchReg, SequentialExecution, - popR1 ? &failurePopR1 : &failure); + masm.loadBaselineOrIonRaw(scratchReg, scratchReg, popR1 ? &failurePopR1 : &failure); // At this point, we are guaranteed to successfully complete. if (popR1) @@ -7421,7 +7420,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) masm.loadPtr(Address(BaselineStubReg, ICGetProp_CallScripted::offsetOfGetter()), callee); masm.branchIfFunctionHasNoScript(callee, &failureLeaveStubFrame); masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code); - masm.loadBaselineOrIonRaw(code, code, SequentialExecution, &failureLeaveStubFrame); + masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame); // Getter is called with 0 arguments, just |obj| as thisv. // Note that we use Push, not push, so that callJit will align the stack @@ -7441,7 +7440,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != code); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), code); masm.loadPtr(Address(code, JitCode::offsetOfCode()), code); @@ -8793,7 +8792,7 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) masm.loadPtr(Address(BaselineStubReg, ICSetProp_CallScripted::offsetOfSetter()), callee); masm.branchIfFunctionHasNoScript(callee, &failureLeaveStubFrame); masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), code); - masm.loadBaselineOrIonRaw(code, code, SequentialExecution, &failureLeaveStubFrame); + masm.loadBaselineOrIonRaw(code, code, &failureLeaveStubFrame); // Setter is called with the new value as the only argument, and |obj| as thisv. // Note that we use Push, not push, so that callJit will align the stack @@ -8818,7 +8817,7 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != code); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), code); masm.loadPtr(Address(code, JitCode::offsetOfCode()), code); @@ -9760,7 +9759,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, masm.branchIfFunctionHasNoScript(target, failure); Register temp = regs.takeAny(); masm.loadPtr(Address(target, JSFunction::offsetOfNativeOrScript()), temp); - masm.loadBaselineOrIonRaw(temp, temp, SequentialExecution, failure); + masm.loadBaselineOrIonRaw(temp, temp, failure); regs.add(temp); } return target; @@ -9995,7 +9994,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) Register code; if (!isConstructing_) { code = regs.takeAny(); - masm.loadBaselineOrIonRaw(callee, code, SequentialExecution, &failure); + masm.loadBaselineOrIonRaw(callee, code, &failure); } else { Address scriptCode(callee, JSScript::offsetOfBaselineOrIonRaw()); masm.branchPtr(Assembler::Equal, scriptCode, ImmPtr(nullptr), &failure); @@ -10079,7 +10078,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee); code = regs.takeAny(); - masm.loadBaselineOrIonRaw(callee, code, SequentialExecution, &failureLeaveStubFrame); + masm.loadBaselineOrIonRaw(callee, code, &failureLeaveStubFrame); // Release callee register, but don't add ExtractTemp0 back into the pool // ExtractTemp0 is used later, and if it's allocated to some other register at that @@ -10123,7 +10122,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != argcReg); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), code); masm.loadPtr(Address(code, JitCode::offsetOfCode()), code); @@ -10600,7 +10599,7 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm) // Load nargs into scratch for underflow check, and then load jitcode pointer into target. masm.load16ZeroExtend(Address(target, JSFunction::offsetOfNargs()), scratch); masm.loadPtr(Address(target, JSFunction::offsetOfNativeOrScript()), target); - masm.loadBaselineOrIonRaw(target, target, SequentialExecution, nullptr); + masm.loadBaselineOrIonRaw(target, target, nullptr); // Handle arguments underflow. Label noUnderflow; @@ -10611,7 +10610,7 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != argcReg); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), target); masm.loadPtr(Address(target, JitCode::offsetOfCode()), target); @@ -10701,7 +10700,7 @@ ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm) // Load nargs into scratch for underflow check, and then load jitcode pointer into target. masm.load16ZeroExtend(Address(target, JSFunction::offsetOfNargs()), scratch); masm.loadPtr(Address(target, JSFunction::offsetOfNativeOrScript()), target); - masm.loadBaselineOrIonRaw(target, target, SequentialExecution, nullptr); + masm.loadBaselineOrIonRaw(target, target, nullptr); // Handle arguments underflow. Label noUnderflow; @@ -10712,7 +10711,7 @@ ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != argcReg); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), target); masm.loadPtr(Address(target, JitCode::offsetOfCode()), target); @@ -10781,7 +10780,7 @@ ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm) // Load the start of the target JitCode. Register code = regs.takeAny(); - masm.loadBaselineOrIonRaw(callee, code, SequentialExecution, &failure); + masm.loadBaselineOrIonRaw(callee, code, &failure); // We no longer need R1. regs.add(R1); @@ -10834,7 +10833,7 @@ ICCall_ScriptedFunCall::Compiler::generateStubCode(MacroAssembler &masm) MOZ_ASSERT(ArgumentsRectifierReg != argcReg); JitCode *argumentsRectifier = - cx->runtime()->jitRuntime()->getArgumentsRectifier(SequentialExecution); + cx->runtime()->jitRuntime()->getArgumentsRectifier(); masm.movePtr(ImmGCPtr(argumentsRectifier), code); masm.loadPtr(Address(code, JitCode::offsetOfCode()), code); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index da7248519557..2267250d169a 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -31,10 +31,7 @@ #include "jit/Lowering.h" #include "jit/MIRGenerator.h" #include "jit/MoveEmitter.h" -#include "jit/ParallelFunctions.h" -#include "jit/ParallelSafetyAnalysis.h" #include "jit/RangeAnalysis.h" -#include "vm/ForkJoin.h" #include "vm/MatchPairs.h" #include "vm/RegExpStatics.h" #include "vm/TraceLogging.h" @@ -167,10 +164,7 @@ CodeGenerator::~CodeGenerator() } typedef bool (*StringToNumberFn)(ThreadSafeContext *, JSString *, double *); -typedef bool (*StringToNumberParFn)(ForkJoinContext *, JSString *, double *); -static const VMFunctionsModal StringToNumberInfo = VMFunctionsModal( - FunctionInfo(StringToNumber), - FunctionInfo(StringToNumberPar)); +static const VMFunction StringToNumberInfo = FunctionInfo(StringToNumber); void CodeGenerator::visitValueToInt32(LValueToInt32 *lir) @@ -821,10 +815,7 @@ CodeGenerator::emitIntToString(Register input, Register output, Label *ool) } typedef JSFlatString *(*IntToStringFn)(ThreadSafeContext *, int); -typedef JSFlatString *(*IntToStringParFn)(ForkJoinContext *, int); -static const VMFunctionsModal IntToStringInfo = VMFunctionsModal( - FunctionInfo(Int32ToString), - FunctionInfo(IntToStringPar)); +static const VMFunction IntToStringInfo = FunctionInfo(Int32ToString); void CodeGenerator::visitIntToString(LIntToString *lir) @@ -841,10 +832,7 @@ CodeGenerator::visitIntToString(LIntToString *lir) } typedef JSString *(*DoubleToStringFn)(ThreadSafeContext *, double); -typedef JSString *(*DoubleToStringParFn)(ForkJoinContext *, double); -static const VMFunctionsModal DoubleToStringInfo = VMFunctionsModal( - FunctionInfo(NumberToString), - FunctionInfo(DoubleToStringPar)); +static const VMFunction DoubleToStringInfo = FunctionInfo(NumberToString); void CodeGenerator::visitDoubleToString(LDoubleToString *lir) @@ -864,10 +852,7 @@ CodeGenerator::visitDoubleToString(LDoubleToString *lir) } typedef JSString *(*PrimitiveToStringFn)(JSContext *, HandleValue); -typedef JSString *(*PrimitiveToStringParFn)(ForkJoinContext *, HandleValue); -static const VMFunctionsModal PrimitiveToStringInfo = VMFunctionsModal( - FunctionInfo(ToStringSlow), - FunctionInfo(PrimitiveToStringPar)); +static const VMFunction PrimitiveToStringInfo = FunctionInfo(ToStringSlow); void CodeGenerator::visitValueToString(LValueToString *lir) @@ -1765,22 +1750,6 @@ CodeGenerator::emitLambdaInit(Register output, Register scopeChain, masm.storePtr(ImmGCPtr(info.fun->displayAtom()), Address(output, JSFunction::offsetOfAtom())); } -void -CodeGenerator::visitLambdaPar(LLambdaPar *lir) -{ - Register resultReg = ToRegister(lir->output()); - Register cxReg = ToRegister(lir->forkJoinContext()); - Register scopeChainReg = ToRegister(lir->scopeChain()); - Register tempReg1 = ToRegister(lir->getTemp0()); - Register tempReg2 = ToRegister(lir->getTemp1()); - const LambdaFunctionInfo &info = lir->mir()->info(); - - MOZ_ASSERT(scopeChainReg != resultReg); - - emitAllocateGCThingPar(lir, resultReg, cxReg, tempReg1, tempReg2, info.fun); - emitLambdaInit(resultReg, scopeChainReg, info); -} - void CodeGenerator::visitLabel(LLabel *lir) { @@ -1853,10 +1822,7 @@ class OutOfLineInterruptCheckImplicit : public OutOfLineCodeBase }; typedef bool (*InterruptCheckFn)(JSContext *); -typedef bool (*InterruptCheckParFn)(ForkJoinContext *); -static const VMFunctionsModal InterruptCheckInfo = VMFunctionsModal( - FunctionInfo(InterruptCheck), - FunctionInfo(InterruptCheckPar)); +static const VMFunction InterruptCheckInfo = FunctionInfo(InterruptCheck); void CodeGenerator::visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit *ool) @@ -2021,10 +1987,8 @@ CodeGenerator::visitOsrEntry(LOsrEntry *lir) setOsrEntryOffset(masm.size()); #ifdef JS_TRACE_LOGGING - if (gen->info().executionMode() == SequentialExecution) { - emitTracelogStopEvent(TraceLogger_Baseline); - emitTracelogStartEvent(TraceLogger_IonMonkey); - } + emitTracelogStopEvent(TraceLogger_Baseline); + emitTracelogStartEvent(TraceLogger_IonMonkey); #endif // Allocate the full frame for this function @@ -2452,30 +2416,6 @@ CodeGenerator::visitFunctionEnvironment(LFunctionEnvironment *lir) masm.loadPtr(environment, ToRegister(lir->output())); } -void -CodeGenerator::visitForkJoinContext(LForkJoinContext *lir) -{ - const Register tempReg = ToRegister(lir->getTempReg()); - - masm.setupUnalignedABICall(0, tempReg); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ForkJoinContextPar)); - MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg); -} - -void -CodeGenerator::visitGuardThreadExclusive(LGuardThreadExclusive *lir) -{ - MOZ_ASSERT(gen->info().executionMode() == ParallelExecution); - - const Register tempReg = ToRegister(lir->getTempReg()); - masm.setupUnalignedABICall(2, tempReg); - masm.passABIArg(ToRegister(lir->forkJoinContext())); - masm.passABIArg(ToRegister(lir->object())); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ParallelWriteGuard)); - - bailoutIfFalseBool(ReturnReg, lir->snapshot()); -} - void CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity *guard) { @@ -2669,10 +2609,8 @@ CodeGenerator::visitCallNative(LCallNative *call) masm.checkStackAlignment(); - // Sequential native functions have the signature: + // Native functions have the signature: // bool (*)(JSContext *, unsigned, Value *vp) - // and parallel native functions have the signature: - // ParallelResult (*)(ForkJoinContext *, unsigned, Value *vp) // Where vp[0] is space for an outparam, vp[1] is |this|, and vp[2] onward // are the function arguments. @@ -2684,12 +2622,7 @@ CodeGenerator::visitCallNative(LCallNative *call) masm.Push(ObjectValue(*target)); // Preload arguments into registers. - // - // Note that for parallel execution, loadContext does an ABI call, so we - // need to do this before we load the other argument registers, otherwise - // we'll hose them. - ExecutionMode executionMode = gen->info().executionMode(); - masm.loadContext(argContextReg, tempReg, executionMode); + masm.loadJSContext(argContextReg); masm.move32(Imm32(call->numStackArgs()), argUintNReg); masm.movePtr(StackPointer, argVpReg); @@ -2698,8 +2631,7 @@ CodeGenerator::visitCallNative(LCallNative *call) // Construct native exit frame. uint32_t safepointOffset; masm.buildFakeExitFrame(tempReg, &safepointOffset); - masm.enterFakeExitFrame(argContextReg, tempReg, executionMode, - NativeExitFrameLayout::Token()); + masm.enterFakeExitFrame(NativeExitFrameLayout::Token()); markSafepointAt(safepointOffset, call); @@ -2708,22 +2640,10 @@ CodeGenerator::visitCallNative(LCallNative *call) masm.passABIArg(argContextReg); masm.passABIArg(argUintNReg); masm.passABIArg(argVpReg); - - switch (executionMode) { - case SequentialExecution: - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->native())); - break; - - case ParallelExecution: - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->parallelNative())); - break; - - default: - MOZ_CRASH("No such execution mode"); - } + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target->native())); // Test for failure. - masm.branchIfFalseBool(ReturnReg, masm.failureLabel(executionMode)); + masm.branchIfFalseBool(ReturnReg, masm.failureLabel()); // Load the outparam vp[0] into output register(s). masm.loadValue(Address(StackPointer, NativeExitFrameLayout::offsetOfResult()), JSReturnOperand); @@ -2908,14 +2828,13 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) Register objreg = ToRegister(call->getTempObject()); Register nargsreg = ToRegister(call->getNargsReg()); uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot()); - ExecutionMode executionMode = gen->info().executionMode(); Label invoke, thunk, makeCall, end; // Known-target case is handled by LCallKnown. MOZ_ASSERT(!call->hasSingleTarget()); // Generate an ArgumentsRectifier. - JitCode *argumentsRectifier = gen->jitRuntime()->getArgumentsRectifier(executionMode); + JitCode *argumentsRectifier = gen->jitRuntime()->getArgumentsRectifier(); masm.checkStackAlignment(); @@ -2934,7 +2853,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) masm.loadPtr(Address(calleereg, JSFunction::offsetOfNativeOrScript()), objreg); // Load script jitcode. - masm.loadBaselineOrIonRaw(objreg, objreg, executionMode, &invoke); + masm.loadBaselineOrIonRaw(objreg, objreg, &invoke); // Nestle the StackPointer up to the argument vector. masm.freeStack(unusedStack); @@ -2972,18 +2891,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) // Handle uncompiled or native functions. masm.bind(&invoke); - switch (executionMode) { - case SequentialExecution: - emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack); - break; - - case ParallelExecution: - emitCallToUncompiledScriptPar(call, calleereg); - break; - - default: - MOZ_CRASH("No such execution mode"); - } + emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack); masm.bind(&end); @@ -2999,20 +2907,6 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) dropArguments(call->numStackArgs() + 1); } -typedef bool (*CallToUncompiledScriptParFn)(ForkJoinContext *, JSObject *); -static const VMFunction CallToUncompiledScriptParInfo = - FunctionInfo(CallToUncompiledScriptPar); - -// Generates a call to CallToUncompiledScriptPar() and then bails out. -// |calleeReg| should contain the JSFunction*. -void -CodeGenerator::emitCallToUncompiledScriptPar(LInstruction *lir, Register calleeReg) -{ - pushArg(calleeReg); - callVM(CallToUncompiledScriptParInfo, lir); - masm.assumeUnreachable("CallToUncompiledScriptParInfo always returns false."); -} - void CodeGenerator::visitCallKnown(LCallKnown *call) { @@ -3020,7 +2914,6 @@ CodeGenerator::visitCallKnown(LCallKnown *call) Register objreg = ToRegister(call->getTempObject()); uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot()); DebugOnly target = call->getSingleTarget(); - ExecutionMode executionMode = gen->info().executionMode(); Label end, uncompiled; // Native single targets are handled by LCallNative. @@ -3041,9 +2934,9 @@ CodeGenerator::visitCallKnown(LCallKnown *call) // Load script jitcode. if (call->mir()->needsArgCheck()) - masm.loadBaselineOrIonRaw(objreg, objreg, executionMode, &uncompiled); + masm.loadBaselineOrIonRaw(objreg, objreg, &uncompiled); else - masm.loadBaselineOrIonNoArgCheck(objreg, objreg, executionMode, &uncompiled); + masm.loadBaselineOrIonNoArgCheck(objreg, objreg, &uncompiled); // Nestle the StackPointer up to the argument vector. masm.freeStack(unusedStack); @@ -3066,18 +2959,7 @@ CodeGenerator::visitCallKnown(LCallKnown *call) // Handle uncompiled functions. masm.bind(&uncompiled); - switch (executionMode) { - case SequentialExecution: - emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack); - break; - - case ParallelExecution: - emitCallToUncompiledScriptPar(call, calleereg); - break; - - default: - MOZ_CRASH("No such execution mode"); - } + emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack); masm.bind(&end); @@ -3200,7 +3082,6 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply) masm.checkStackAlignment(); // If the function is known to be uncompilable, only emit the call to InvokeFunction. - ExecutionMode executionMode = gen->info().executionMode(); if (apply->hasSingleTarget()) { JSFunction *target = apply->getSingleTarget(); if (target->isNative()) { @@ -3224,7 +3105,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply) masm.loadPtr(Address(calleereg, JSFunction::offsetOfNativeOrScript()), objreg); // Load script jitcode. - masm.loadBaselineOrIonRaw(objreg, objreg, executionMode, &invoke); + masm.loadBaselineOrIonRaw(objreg, objreg, &invoke); // Call with an Ion frame or a rectifier frame. { @@ -3257,7 +3138,7 @@ CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric *apply) masm.bind(&underflow); // Hardcode the address of the argumentsRectifier code. - JitCode *argumentsRectifier = gen->jitRuntime()->getArgumentsRectifier(executionMode); + JitCode *argumentsRectifier = gen->jitRuntime()->getArgumentsRectifier(); MOZ_ASSERT(ArgumentsRectifierReg != objreg); masm.movePtr(ImmGCPtr(argumentsRectifier), objreg); // Necessary for GC marking. @@ -3553,10 +3434,8 @@ CodeGenerator::visitDefFun(LDefFun *lir) } typedef bool (*CheckOverRecursedFn)(JSContext *); -typedef bool (*CheckOverRecursedParFn)(ForkJoinContext *); -static const VMFunctionsModal CheckOverRecursedInfo = VMFunctionsModal( - FunctionInfo(CheckOverRecursed), - FunctionInfo(CheckOverRecursedPar)); +static const VMFunction CheckOverRecursedInfo = + FunctionInfo(CheckOverRecursed); void CodeGenerator::visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool) @@ -3575,42 +3454,6 @@ CodeGenerator::visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool) masm.jump(ool->rejoin()); } -void -CodeGenerator::visitCheckOverRecursedPar(LCheckOverRecursedPar *lir) -{ - // See above: unlike visitCheckOverRecursed(), this code runs in - // parallel mode and hence uses the jitStackLimit from the current - // thread state. Also, we must check the interrupt flags because - // on interrupt or abort, only the stack limit for the main thread - // is reset, not the worker threads. See comment in vm/ForkJoin.h - // for more details. - - Register cxReg = ToRegister(lir->forkJoinContext()); - Register tempReg = ToRegister(lir->getTempReg()); - - masm.loadPtr(Address(cxReg, offsetof(ForkJoinContext, perThreadData)), tempReg); - masm.loadPtr(Address(tempReg, PerThreadData::offsetOfJitStackLimit()), tempReg); - - // Conditional forward (unlikely) branch to failure. - CheckOverRecursedFailure *ool = new(alloc()) CheckOverRecursedFailure(lir); - addOutOfLineCode(ool, lir->mir()); - - masm.branchPtr(Assembler::BelowOrEqual, StackPointer, tempReg, ool->entry()); - masm.checkInterruptFlagPar(tempReg, ool->entry()); - masm.bind(ool->rejoin()); -} - -void -CodeGenerator::visitInterruptCheckPar(LInterruptCheckPar *lir) -{ - // First check for cx->shared->interrupt_. - OutOfLineCode *ool = oolCallVM(InterruptCheckInfo, lir, (ArgList()), StoreNothing()); - - Register tempReg = ToRegister(lir->getTempReg()); - masm.checkInterruptFlagPar(tempReg, ool->entry()); - masm.bind(ool->rejoin()); -} - IonScriptCounts * CodeGenerator::maybeCreateScriptCounts() { @@ -3773,35 +3616,33 @@ CodeGenerator::emitObjectOrStringResultChecks(LInstruction *lir, MDefinition *mi } // Check that we have a valid GC pointer. - if (gen->info().executionMode() != ParallelExecution) { - saveVolatile(); - masm.setupUnalignedABICall(2, temp); - masm.loadJSContext(temp); - masm.passABIArg(temp); - masm.passABIArg(output); + saveVolatile(); + masm.setupUnalignedABICall(2, temp); + masm.loadJSContext(temp); + masm.passABIArg(temp); + masm.passABIArg(output); - void *callee; - switch (mir->type()) { - case MIRType_Object: - callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidObjectPtr); - break; - case MIRType_ObjectOrNull: - callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidObjectOrNullPtr); - break; - case MIRType_String: - callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidStringPtr); - break; - case MIRType_Symbol: - callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidSymbolPtr); - break; - default: - MOZ_CRASH(); - } - - masm.callWithABINoProfiling(callee); - restoreVolatile(); + void *callee; + switch (mir->type()) { + case MIRType_Object: + callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidObjectPtr); + break; + case MIRType_ObjectOrNull: + callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidObjectOrNullPtr); + break; + case MIRType_String: + callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidStringPtr); + break; + case MIRType_Symbol: + callee = JS_FUNC_TO_DATA_PTR(void *, AssertValidSymbolPtr); + break; + default: + MOZ_CRASH(); } + masm.callWithABINoProfiling(callee); + restoreVolatile(); + masm.bind(&done); masm.pop(temp); } @@ -3844,20 +3685,18 @@ CodeGenerator::emitValueResultChecks(LInstruction *lir, MDefinition *mir) } // Check that we have a valid GC pointer. - if (gen->info().executionMode() != ParallelExecution) { - saveVolatile(); + saveVolatile(); - masm.pushValue(output); - masm.movePtr(StackPointer, temp1); + masm.pushValue(output); + masm.movePtr(StackPointer, temp1); - masm.setupUnalignedABICall(2, temp2); - masm.loadJSContext(temp2); - masm.passABIArg(temp2); - masm.passABIArg(temp1); - masm.callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssertValidValue)); - masm.popValue(output); - restoreVolatile(); - } + masm.setupUnalignedABICall(2, temp2); + masm.loadJSContext(temp2); + masm.passABIArg(temp2); + masm.passABIArg(temp1); + masm.callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssertValidValue)); + masm.popValue(output); + restoreVolatile(); masm.bind(&done); masm.pop(temp2); @@ -4013,8 +3852,6 @@ static const VMFunction NewDenseArrayInfo = FunctionInfo(NewDen void CodeGenerator::visitNewArrayCallVM(LNewArray *lir) { - MOZ_ASSERT(gen->info().executionMode() == SequentialExecution); - Register objReg = ToRegister(lir->output()); MOZ_ASSERT(!lir->isCall()); @@ -4046,9 +3883,6 @@ static const VMFunction CreateDerivedTypedObjInfo = void CodeGenerator::visitNewDerivedTypedObject(LNewDerivedTypedObject *lir) { - // Not yet made safe for par exec: - MOZ_ASSERT(gen->info().executionMode() == SequentialExecution); - pushArg(ToRegister(lir->offset())); pushArg(ToRegister(lir->owner())); pushArg(ToRegister(lir->type())); @@ -4088,7 +3922,6 @@ CodeGenerator::visitHypot(LHypot *lir) void CodeGenerator::visitNewArray(LNewArray *lir) { - MOZ_ASSERT(gen->info().executionMode() == SequentialExecution); Register objReg = ToRegister(lir->output()); Register tempReg = ToRegister(lir->temp()); ArrayObject *templateObject = lir->mir()->templateObject(); @@ -4204,8 +4037,6 @@ static const VMFunction NewInitObjectWithClassPrototypeInfo = void CodeGenerator::visitNewObjectVMCall(LNewObject *lir) { - MOZ_ASSERT(gen->info().executionMode() == SequentialExecution); - Register objReg = ToRegister(lir->output()); MOZ_ASSERT(!lir->isCall()); @@ -4315,7 +4146,6 @@ ShouldInitFixedSlots(LInstruction *lir, NativeObject *templateObj) void CodeGenerator::visitNewObject(LNewObject *lir) { - MOZ_ASSERT(gen->info().executionMode() == SequentialExecution); Register objReg = ToRegister(lir->output()); Register tempReg = ToRegister(lir->temp()); PlainObject *templateObject = lir->mir()->templateObject(); @@ -4442,45 +4272,6 @@ CodeGenerator::visitNewSingletonCallObject(LNewSingletonCallObject *lir) masm.bind(ool->rejoin()); } -void -CodeGenerator::visitNewCallObjectPar(LNewCallObjectPar *lir) -{ - Register resultReg = ToRegister(lir->output()); - Register cxReg = ToRegister(lir->forkJoinContext()); - Register tempReg1 = ToRegister(lir->getTemp0()); - Register tempReg2 = ToRegister(lir->getTemp1()); - CallObject *templateObj = lir->mir()->templateObj(); - - emitAllocateGCThingPar(lir, resultReg, cxReg, tempReg1, tempReg2, templateObj); -} - -typedef ArrayObject *(*ExtendArrayParFn)(ForkJoinContext*, ArrayObject*, uint32_t); -static const VMFunction ExtendArrayParInfo = - FunctionInfo(ExtendArrayPar); - -void -CodeGenerator::visitNewDenseArrayPar(LNewDenseArrayPar *lir) -{ - Register cxReg = ToRegister(lir->forkJoinContext()); - Register lengthReg = ToRegister(lir->length()); - Register tempReg0 = ToRegister(lir->getTemp0()); - Register tempReg1 = ToRegister(lir->getTemp1()); - Register tempReg2 = ToRegister(lir->getTemp2()); - ArrayObject *templateObj = lir->mir()->templateObject(); - - emitAllocateGCThingPar(lir, tempReg2, cxReg, tempReg0, tempReg1, templateObj); - - // Invoke a C helper to allocate the elements. The helper returns - // nullptr on allocation error or the array object. - - saveLive(lir); - pushArg(lengthReg); - pushArg(tempReg2); - callVM(ExtendArrayParInfo, lir); - storeResultTo(ToRegister(lir->output())); - restoreLive(lir); -} - typedef JSObject *(*NewStringObjectFn)(JSContext *, HandleString); static const VMFunction NewStringObjectInfo = FunctionInfo(NewStringObject); @@ -4506,76 +4297,6 @@ CodeGenerator::visitNewStringObject(LNewStringObject *lir) masm.bind(ool->rejoin()); } -void -CodeGenerator::visitNewPar(LNewPar *lir) -{ - Register objReg = ToRegister(lir->output()); - Register cxReg = ToRegister(lir->forkJoinContext()); - Register tempReg1 = ToRegister(lir->getTemp0()); - Register tempReg2 = ToRegister(lir->getTemp1()); - NativeObject *templateObject = lir->mir()->templateObject(); - emitAllocateGCThingPar(lir, objReg, cxReg, tempReg1, tempReg2, templateObject); -} - -class OutOfLineNewGCThingPar : public OutOfLineCodeBase -{ -public: - LInstruction *lir; - gc::AllocKind allocKind; - Register objReg; - Register cxReg; - - OutOfLineNewGCThingPar(LInstruction *lir, gc::AllocKind allocKind, Register objReg, - Register cxReg) - : lir(lir), allocKind(allocKind), objReg(objReg), cxReg(cxReg) - {} - - void accept(CodeGenerator *codegen) { - codegen->visitOutOfLineNewGCThingPar(this); - } -}; - -typedef JSObject *(*NewGCThingParFn)(ForkJoinContext *, js::gc::AllocKind allocKind); -static const VMFunction NewGCThingParInfo = - FunctionInfo(NewGCThingPar); - -void -CodeGenerator::emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg, - Register tempReg1, Register tempReg2, NativeObject *templateObj) -{ - MOZ_ASSERT(lir->mirRaw()); - MOZ_ASSERT(lir->mirRaw()->isInstruction()); - - gc::AllocKind allocKind = templateObj->asTenured().getAllocKind(); - OutOfLineNewGCThingPar *ool = new(alloc()) OutOfLineNewGCThingPar(lir, allocKind, objReg, cxReg); - addOutOfLineCode(ool, lir->mirRaw()->toInstruction()); - - masm.newGCThingPar(objReg, cxReg, tempReg1, tempReg2, templateObj, ool->entry()); - masm.bind(ool->rejoin()); - masm.initGCThing(objReg, tempReg1, templateObj); -} - -void -CodeGenerator::visitOutOfLineNewGCThingPar(OutOfLineNewGCThingPar *ool) -{ - // As a fallback for allocation in par. exec. mode, we invoke the - // C helper NewGCThingPar(), which calls into the GC code. If it - // returns nullptr, we bail. If returns non-nullptr, we rejoin the - // original instruction. - Register out = ool->objReg; - - saveVolatile(out); - masm.setupUnalignedABICall(2, out); - masm.passABIArg(ool->cxReg); - masm.move32(Imm32(ool->allocKind), out); - masm.passABIArg(out); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NewGCThingPar)); - masm.storeCallResult(out); - restoreVolatile(out); - - bailoutTestPtr(Assembler::Zero, out, out, ool->lir->snapshot()); -} - typedef bool(*InitElemFn)(JSContext *cx, HandleObject obj, HandleValue id, HandleValue value); static const VMFunction InitElemInfo = @@ -5187,16 +4908,13 @@ CodeGenerator::visitModD(LModD *ins) } typedef bool (*BinaryFn)(JSContext *, MutableHandleValue, MutableHandleValue, MutableHandleValue); -typedef bool (*BinaryParFn)(ForkJoinContext *, HandleValue, HandleValue, MutableHandleValue); static const VMFunction AddInfo = FunctionInfo(js::AddValues); static const VMFunction SubInfo = FunctionInfo(js::SubValues); static const VMFunction MulInfo = FunctionInfo(js::MulValues); static const VMFunction DivInfo = FunctionInfo(js::DivValues); static const VMFunction ModInfo = FunctionInfo(js::ModValues); -static const VMFunctionsModal UrshInfo = VMFunctionsModal( - FunctionInfo(js::UrshValues), - FunctionInfo(UrshValuesPar)); +static const VMFunction UrshInfo = FunctionInfo(js::UrshValues); void CodeGenerator::visitBinaryV(LBinaryV *lir) @@ -5235,13 +4953,10 @@ CodeGenerator::visitBinaryV(LBinaryV *lir) } typedef bool (*StringCompareFn)(JSContext *, HandleString, HandleString, bool *); -typedef bool (*StringCompareParFn)(ForkJoinContext *, HandleString, HandleString, bool *); -static const VMFunctionsModal StringsEqualInfo = VMFunctionsModal( - FunctionInfo(jit::StringsEqual), - FunctionInfo(jit::StringsEqualPar)); -static const VMFunctionsModal StringsNotEqualInfo = VMFunctionsModal( - FunctionInfo(jit::StringsEqual), - FunctionInfo(jit::StringsUnequalPar)); +static const VMFunction StringsEqualInfo = + FunctionInfo(jit::StringsEqual); +static const VMFunction StringsNotEqualInfo = + FunctionInfo(jit::StringsEqual); void CodeGenerator::emitCompareS(LInstruction *lir, JSOp op, Register left, Register right, @@ -5299,31 +5014,14 @@ CodeGenerator::visitCompareS(LCompareS *lir) } typedef bool (*CompareFn)(JSContext *, MutableHandleValue, MutableHandleValue, bool *); -typedef bool (*CompareParFn)(ForkJoinContext *, MutableHandleValue, MutableHandleValue, bool *); -static const VMFunctionsModal EqInfo = VMFunctionsModal( - FunctionInfo(jit::LooselyEqual), - FunctionInfo(jit::LooselyEqualPar)); -static const VMFunctionsModal NeInfo = VMFunctionsModal( - FunctionInfo(jit::LooselyEqual), - FunctionInfo(jit::LooselyUnequalPar)); -static const VMFunctionsModal StrictEqInfo = VMFunctionsModal( - FunctionInfo(jit::StrictlyEqual), - FunctionInfo(jit::StrictlyEqualPar)); -static const VMFunctionsModal StrictNeInfo = VMFunctionsModal( - FunctionInfo(jit::StrictlyEqual), - FunctionInfo(jit::StrictlyUnequalPar)); -static const VMFunctionsModal LtInfo = VMFunctionsModal( - FunctionInfo(jit::LessThan), - FunctionInfo(jit::LessThanPar)); -static const VMFunctionsModal LeInfo = VMFunctionsModal( - FunctionInfo(jit::LessThanOrEqual), - FunctionInfo(jit::LessThanOrEqualPar)); -static const VMFunctionsModal GtInfo = VMFunctionsModal( - FunctionInfo(jit::GreaterThan), - FunctionInfo(jit::GreaterThanPar)); -static const VMFunctionsModal GeInfo = VMFunctionsModal( - FunctionInfo(jit::GreaterThanOrEqual), - FunctionInfo(jit::GreaterThanOrEqualPar)); +static const VMFunction EqInfo = FunctionInfo(jit::LooselyEqual); +static const VMFunction NeInfo = FunctionInfo(jit::LooselyEqual); +static const VMFunction StrictEqInfo = FunctionInfo(jit::StrictlyEqual); +static const VMFunction StrictNeInfo = FunctionInfo(jit::StrictlyEqual); +static const VMFunction LtInfo = FunctionInfo(jit::LessThan); +static const VMFunction LeInfo = FunctionInfo(jit::LessThanOrEqual); +static const VMFunction GtInfo = FunctionInfo(jit::GreaterThan); +static const VMFunction GeInfo = FunctionInfo(jit::GreaterThanOrEqual); void CodeGenerator::visitCompareVM(LCompareVM *lir) @@ -5584,10 +5282,7 @@ CodeGenerator::visitEmulatesUndefinedAndBranch(LEmulatesUndefinedAndBranch *lir) } typedef JSString *(*ConcatStringsFn)(ThreadSafeContext *, HandleString, HandleString); -typedef JSString *(*ConcatStringsParFn)(ForkJoinContext *, HandleString, HandleString); -static const VMFunctionsModal ConcatStringsInfo = VMFunctionsModal( - FunctionInfo(ConcatStrings), - FunctionInfo(ConcatStringsPar)); +static const VMFunction ConcatStringsInfo = FunctionInfo(ConcatStrings); void CodeGenerator::emitConcat(LInstruction *lir, Register lhs, Register rhs, Register output) @@ -5595,8 +5290,7 @@ CodeGenerator::emitConcat(LInstruction *lir, Register lhs, Register rhs, Registe OutOfLineCode *ool = oolCallVM(ConcatStringsInfo, lir, (ArgList(), lhs, rhs), StoreRegisterTo(output)); - ExecutionMode mode = gen->info().executionMode(); - JitCode *stringConcatStub = gen->compartment->jitCompartment()->stringConcatStubNoBarrier(mode); + JitCode *stringConcatStub = gen->compartment->jitCompartment()->stringConcatStubNoBarrier(); masm.call(stringConcatStub); masm.branchTestPtr(Assembler::Zero, output, output, ool->entry()); @@ -5623,26 +5317,6 @@ CodeGenerator::visitConcat(LConcat *lir) emitConcat(lir, lhs, rhs, output); } -void -CodeGenerator::visitConcatPar(LConcatPar *lir) -{ - DebugOnly cx = ToRegister(lir->forkJoinContext()); - Register lhs = ToRegister(lir->lhs()); - Register rhs = ToRegister(lir->rhs()); - Register output = ToRegister(lir->output()); - - MOZ_ASSERT(lhs == CallTempReg0); - MOZ_ASSERT(rhs == CallTempReg1); - MOZ_ASSERT((Register)cx == CallTempReg4); - MOZ_ASSERT(ToRegister(lir->temp1()) == CallTempReg0); - MOZ_ASSERT(ToRegister(lir->temp2()) == CallTempReg1); - MOZ_ASSERT(ToRegister(lir->temp3()) == CallTempReg2); - MOZ_ASSERT(ToRegister(lir->temp4()) == CallTempReg3); - MOZ_ASSERT(output == CallTempReg5); - - emitConcat(lir, lhs, rhs, output); -} - static void CopyStringChars(MacroAssembler &masm, Register to, Register from, Register len, Register byteOpScratch, size_t fromWidth, size_t toWidth) @@ -5703,8 +5377,8 @@ CopyStringCharsMaybeInflate(MacroAssembler &masm, Register input, Register destC static void ConcatFatInlineString(MacroAssembler &masm, Register lhs, Register rhs, Register output, - Register temp1, Register temp2, Register temp3, Register forkJoinContext, - ExecutionMode mode, Label *failure, Label *failurePopTemps, bool isTwoByte) + Register temp1, Register temp2, Register temp3, + Label *failure, Label *failurePopTemps, bool isTwoByte) { // State: result length in temp2. @@ -5713,20 +5387,7 @@ ConcatFatInlineString(MacroAssembler &masm, Register lhs, Register rhs, Register masm.branchIfRope(rhs, failure); // Allocate a JSFatInlineString. - switch (mode) { - case SequentialExecution: - masm.newGCFatInlineString(output, temp1, failure); - break; - case ParallelExecution: - masm.push(temp1); - masm.push(temp2); - masm.newGCFatInlineStringPar(output, forkJoinContext, temp1, temp2, failurePopTemps); - masm.pop(temp2); - masm.pop(temp1); - break; - default: - MOZ_CRASH("No such execution mode"); - } + masm.newGCFatInlineString(output, temp1, failure); // Store length and flags. uint32_t flags = JSString::INIT_FAT_INLINE_FLAGS; @@ -5739,12 +5400,6 @@ ConcatFatInlineString(MacroAssembler &masm, Register lhs, Register rhs, Register masm.computeEffectiveAddress(Address(output, JSInlineString::offsetOfInlineStorage()), temp2); { - // We use temp3 in this block, which in parallel execution also holds - // a live ForkJoinContext pointer. If we are compiling for parallel - // execution, be sure to save and restore the ForkJoinContext. - if (mode == ParallelExecution) - masm.push(temp3); - // Copy lhs chars. Note that this advances temp2 to point to the next // char. This also clobbers the lhs register. if (isTwoByte) { @@ -5769,9 +5424,6 @@ ConcatFatInlineString(MacroAssembler &masm, Register lhs, Register rhs, Register masm.store16(Imm32(0), Address(temp2, 0)); else masm.store8(Imm32(0), Address(temp2, 0)); - - if (mode == ParallelExecution) - masm.pop(temp3); } masm.ret(); @@ -5896,7 +5548,7 @@ CodeGenerator::visitSubstr(LSubstr *lir) } JitCode * -JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode) +JitCompartment::generateStringConcatStub(JSContext *cx) { MacroAssembler masm(cx); @@ -5907,11 +5559,6 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode) Register temp3 = CallTempReg4; Register output = CallTempReg5; - // In parallel execution, we pass in the ForkJoinContext in CallTempReg4, as - // by the time we need to use the temp3 we no longer have need of the - // cx. - Register forkJoinContext = CallTempReg4; - Label failure, failurePopTemps; #ifdef JS_USE_LINK_REGISTER masm.pushReturnAddress(); @@ -5954,20 +5601,7 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode) masm.branch32(Assembler::Above, temp2, Imm32(JSString::MAX_LENGTH), &failure); // Allocate a new rope. - switch (mode) { - case SequentialExecution: - masm.newGCString(output, temp3, &failure); - break; - case ParallelExecution: - masm.push(temp1); - masm.push(temp2); - masm.newGCStringPar(output, forkJoinContext, temp1, temp2, &failurePopTemps); - masm.pop(temp2); - masm.pop(temp1); - break; - default: - MOZ_CRASH("No such execution mode"); - } + masm.newGCString(output, temp3, &failure); // Store rope length and flags. temp1 still holds the result of AND'ing the // lhs and rhs flags, so we just have to clear the other flags to get our @@ -5991,12 +5625,12 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode) masm.ret(); masm.bind(&isFatInlineTwoByte); - ConcatFatInlineString(masm, lhs, rhs, output, temp1, temp2, temp3, forkJoinContext, - mode, &failure, &failurePopTemps, true); + ConcatFatInlineString(masm, lhs, rhs, output, temp1, temp2, temp3, + &failure, &failurePopTemps, true); masm.bind(&isFatInlineLatin1); - ConcatFatInlineString(masm, lhs, rhs, output, temp1, temp2, temp3, forkJoinContext, - mode, &failure, &failurePopTemps, false); + ConcatFatInlineString(masm, lhs, rhs, output, temp1, temp2, temp3, + &failure, &failurePopTemps, false); masm.bind(&failurePopTemps); masm.pop(temp2); @@ -6525,10 +6159,7 @@ CodeGenerator::visitStoreElementHoleV(LStoreElementHoleV *lir) typedef bool (*SetDenseElementFn)(JSContext *, HandleNativeObject, int32_t, HandleValue, bool strict); -typedef bool (*SetDenseElementParFn)(ForkJoinContext *, HandleObject, int32_t, HandleValue, bool); -static const VMFunctionsModal SetDenseElementInfo = VMFunctionsModal( - FunctionInfo(SetDenseElement), - FunctionInfo(SetDenseElementPar)); +static const VMFunction SetDenseElementInfo = FunctionInfo(SetDenseElement); void CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool) @@ -7156,11 +6787,8 @@ CodeGenerator::visitRunOncePrologue(LRunOncePrologue *lir) typedef JSObject *(*InitRestParameterFn)(JSContext *, uint32_t, Value *, HandleObject, HandleObject); -typedef JSObject *(*InitRestParameterParFn)(ForkJoinContext *, uint32_t, Value *, - HandleObject, HandleArrayObject); -static const VMFunctionsModal InitRestParameterInfo = VMFunctionsModal( - FunctionInfo(InitRestParameter), - FunctionInfo(InitRestParameterPar)); +static const VMFunction InitRestParameterInfo = + FunctionInfo(InitRestParameter); void CodeGenerator::emitRest(LInstruction *lir, Register array, Register numActuals, @@ -7222,24 +6850,6 @@ CodeGenerator::visitRest(LRest *lir) emitRest(lir, temp2, numActuals, temp0, temp1, numFormals, templateObject, false, ToRegister(lir->output())); } -// LRestPar cannot derive from LCallInstructionHelper because emitAllocateGCThingPar may -// itself contain a VM call. Thus there's some manual work here and in emitRest(). - -void -CodeGenerator::visitRestPar(LRestPar *lir) -{ - Register numActuals = ToRegister(lir->numActuals()); - Register cx = ToRegister(lir->forkJoinContext()); - Register temp0 = ToRegister(lir->getTemp(0)); - Register temp1 = ToRegister(lir->getTemp(1)); - Register temp2 = ToRegister(lir->getTemp(2)); - unsigned numFormals = lir->mir()->numFormals(); - ArrayObject *templateObject = lir->mir()->templateObject(); - - emitAllocateGCThingPar(lir, temp2, cx, temp0, temp1, templateObject); - emitRest(lir, temp2, numActuals, temp0, temp1, numFormals, templateObject, true, ToRegister(lir->output())); -} - bool CodeGenerator::generateAsmJS(AsmJSFunctionLabels *labels) { @@ -7339,7 +6949,7 @@ CodeGenerator::generate() masm.bind(&skipPrologue); #ifdef JS_TRACE_LOGGING - if (!gen->compilingAsmJS() && gen->info().executionMode() == SequentialExecution) { + if (!gen->compilingAsmJS()) { emitTracelogScriptStart(); emitTracelogStartEvent(TraceLogger_IonMonkey); } @@ -7423,19 +7033,14 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) ExecutionMode executionMode = gen->info().executionMode(); OptimizationLevel optimizationLevel = gen->optimizationInfo().level(); - MOZ_ASSERT_IF(HasIonScript(script, executionMode), executionMode == SequentialExecution); - // We finished the new IonScript. Invalidate the current active IonScript, // so we can replace it with this new (probably higher optimized) version. if (HasIonScript(script, executionMode)) { MOZ_ASSERT(GetIonScript(script, executionMode)->isRecompiling()); // Do a normal invalidate, except don't cancel offThread compilations, // since that will cancel this compilation too. - if (!Invalidate(cx, script, SequentialExecution, - /* resetUses */ false, /* cancelOffThread*/ false)) - { + if (!Invalidate(cx, script, /* resetUses */ false, /* cancelOffThread*/ false)) return false; - } } if (scriptCounts_ && !script->hasScriptCounts() && !script->initScriptCounts(cx)) @@ -7462,12 +7067,6 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) // We encode safepoints after the OSI-point offsets have been determined. encodeSafepoints(); - // List of possible scripts that this graph may call. Currently this is - // only tracked when compiling for parallel execution. - CallTargetVector callTargets(alloc()); - if (executionMode == ParallelExecution) - AddPossibleCallees(cx, graph.mir(), callTargets); - AutoDiscardIonCode discardIonCode(cx, &recompileInfo); IonScript *ionScript = @@ -7477,8 +7076,7 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) recovers_.size(), bailouts_.length(), graph.numConstants(), safepointIndices_.length(), osiIndices_.length(), cacheList_.length(), runtimeData_.length(), - safepoints_.size(), callTargets.length(), - patchableBackedges_.length(), optimizationLevel); + safepoints_.size(), patchableBackedges_.length(), optimizationLevel); if (!ionScript) return false; discardIonCode.ionScript = ionScript; @@ -7488,9 +7086,7 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) // read barriers which were skipped while compiling the script off thread. Linker linker(masm); AutoFlushICache afc("IonLink"); - JitCode *code = (executionMode == SequentialExecution) - ? linker.newCodeForIonScript(cx) - : linker.newCode(cx, ION_CODE); + JitCode *code = linker.newCodeForIonScript(cx); if (!code) return false; @@ -7550,12 +7146,6 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) SetIonScript(cx, script, executionMode, ionScript); - // In parallel execution mode, when we first compile a script, we - // don't know that its potential callees are compiled, so set a - // flag warning that the callees may not be fully compiled. - if (!callTargets.empty()) - ionScript->setHasUncompiledCallTarget(); - invalidateEpilogueData_.fixup(&masm); Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, invalidateEpilogueData_), ImmPtr(ionScript), @@ -7608,8 +7198,6 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) ionScript->copyRecovers(&recovers_); if (graph.numConstants()) ionScript->copyConstants(graph.constantPool()); - if (callTargets.length() > 0) - ionScript->copyCallTargetEntries(callTargets.begin()); if (patchableBackedges_.length() > 0) ionScript->copyPatchableBackedges(cx, code, patchableBackedges_.begin(), masm); @@ -7636,21 +7224,11 @@ CodeGenerator::link(JSContext *cx, types::CompilerConstraintList *constraints) } #endif - switch (executionMode) { - case SequentialExecution: - // The correct state for prebarriers is unknown until the end of compilation, - // since a GC can occur during code generation. All barriers are emitted - // off-by-default, and are toggled on here if necessary. - if (cx->zone()->needsIncrementalBarrier()) - ionScript->toggleBarriers(true); - break; - case ParallelExecution: - // We don't run incremental GC during parallel execution; no need to - // turn on barriers. - break; - default: - MOZ_CRASH("No such execution mode"); - } + // The correct state for prebarriers is unknown until the end of compilation, + // since a GC can occur during code generation. All barriers are emitted + // off-by-default, and are toggled on here if necessary. + if (cx->zone()->needsIncrementalBarrier()) + ionScript->toggleBarriers(true); // Attach any generated script counts to the script. if (IonScriptCounts *counts = extractScriptCounts()) @@ -7753,10 +7331,7 @@ CodeGenerator::visitCallGetElement(LCallGetElement *lir) typedef bool (*SetObjectElementFn)(JSContext *, HandleObject, HandleValue, HandleValue, bool strict); -typedef bool (*SetElementParFn)(ForkJoinContext *, HandleObject, HandleValue, HandleValue, bool); -static const VMFunctionsModal SetObjectElementInfo = VMFunctionsModal( - FunctionInfo(SetObjectElement), - FunctionInfo(SetElementPar)); +static const VMFunction SetObjectElementInfo = FunctionInfo(SetObjectElement); void CodeGenerator::visitCallSetElement(LCallSetElement *lir) @@ -7904,22 +7479,9 @@ CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi PropertyName *name, TypedOrValueRegister output, bool monitoredResult, jsbytecode *profilerLeavePc) { - switch (gen->info().executionMode()) { - case SequentialExecution: { - GetPropertyIC cache(liveRegs, objReg, name, output, monitoredResult); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - case ParallelExecution: { - GetPropertyParIC cache(objReg, name, output); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - default: - MOZ_CRASH("Bad execution mode"); - } + GetPropertyIC cache(liveRegs, objReg, name, output, monitoredResult); + cache.setProfilerLeavePC(profilerLeavePc); + addCache(ins, allocateCache(cache)); } void @@ -7927,22 +7489,9 @@ CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Regi PropertyName *name, ConstantOrRegister value, bool strict, bool needsTypeBarrier, jsbytecode *profilerLeavePc) { - switch (gen->info().executionMode()) { - case SequentialExecution: { - SetPropertyIC cache(liveRegs, objReg, name, value, strict, needsTypeBarrier); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - case ParallelExecution: { - SetPropertyParIC cache(objReg, name, value, strict, needsTypeBarrier); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - default: - MOZ_CRASH("Bad execution mode"); - } + SetPropertyIC cache(liveRegs, objReg, name, value, strict, needsTypeBarrier); + cache.setProfilerLeavePC(profilerLeavePc); + addCache(ins, allocateCache(cache)); } void @@ -7952,24 +7501,10 @@ CodeGenerator::addSetElementCache(LInstruction *ins, Register obj, Register unbo ConstantOrRegister value, bool strict, bool guardHoles, jsbytecode *profilerLeavePc) { - switch (gen->info().executionMode()) { - case SequentialExecution: { - SetElementIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict, - guardHoles); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - case ParallelExecution: { - SetElementParIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict, - guardHoles); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - default: - MOZ_CRASH("Bad execution mode"); - } + SetElementIC cache(obj, unboxIndex, temp, tempDouble, tempFloat32, index, value, strict, + guardHoles); + cache.setProfilerLeavePC(profilerLeavePc); + addCache(ins, allocateCache(cache)); } void @@ -8025,47 +7560,15 @@ CodeGenerator::visitGetPropertyIC(OutOfLineUpdateCache *ool, DataPtrrejoin()); } -typedef bool (*GetPropertyParICFn)(ForkJoinContext *, size_t, HandleObject, MutableHandleValue); -const VMFunction GetPropertyParIC::UpdateInfo = - FunctionInfo(GetPropertyParIC::update); - -void -CodeGenerator::visitGetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic) -{ - LInstruction *lir = ool->lir(); - saveLive(lir); - - pushArg(ic->object()); - pushArg(Imm32(ool->getCacheIndex())); - callVM(GetPropertyParIC::UpdateInfo, lir); - StoreValueTo(ic->output()).generate(this); - restoreLiveIgnore(lir, StoreValueTo(ic->output()).clobbered()); - - masm.jump(ool->rejoin()); -} - void CodeGenerator::addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index, TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult, jsbytecode *profilerLeavePc) { - switch (gen->info().executionMode()) { - case SequentialExecution: { - RegisterSet liveRegs = ins->safepoint()->liveRegs(); - GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - case ParallelExecution: { - GetElementParIC cache(obj, index, output, monitoredResult, allowDoubleResult); - cache.setProfilerLeavePC(profilerLeavePc); - addCache(ins, allocateCache(cache)); - break; - } - default: - MOZ_CRASH("No such execution mode"); - } + RegisterSet liveRegs = ins->safepoint()->liveRegs(); + GetElementIC cache(liveRegs, obj, index, output, monitoredResult, allowDoubleResult); + cache.setProfilerLeavePC(profilerLeavePc); + addCache(ins, allocateCache(cache)); } void @@ -8169,47 +7672,6 @@ CodeGenerator::visitSetElementIC(OutOfLineUpdateCache *ool, DataPtrrejoin()); } -typedef bool (*SetElementParICFn)(ForkJoinContext *, size_t, HandleObject, HandleValue, HandleValue); -const VMFunction SetElementParIC::UpdateInfo = - FunctionInfo(SetElementParIC::update); - -void -CodeGenerator::visitSetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic) -{ - LInstruction *lir = ool->lir(); - saveLive(lir); - - pushArg(ic->value()); - pushArg(ic->index()); - pushArg(ic->object()); - pushArg(Imm32(ool->getCacheIndex())); - callVM(SetElementParIC::UpdateInfo, lir); - restoreLive(lir); - - masm.jump(ool->rejoin()); -} - -typedef bool (*GetElementParICFn)(ForkJoinContext *, size_t, HandleObject, HandleValue, - MutableHandleValue); -const VMFunction GetElementParIC::UpdateInfo = - FunctionInfo(GetElementParIC::update); - -void -CodeGenerator::visitGetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic) -{ - LInstruction *lir = ool->lir(); - saveLive(lir); - - pushArg(ic->index()); - pushArg(ic->object()); - pushArg(Imm32(ool->getCacheIndex())); - callVM(GetElementParIC::UpdateInfo, lir); - StoreValueTo(ic->output()).generate(this); - restoreLiveIgnore(lir, StoreValueTo(ic->output()).clobbered()); - - masm.jump(ool->rejoin()); -} - void CodeGenerator::visitBindNameCache(LBindNameCache *ins) { @@ -8242,11 +7704,7 @@ CodeGenerator::visitBindNameIC(OutOfLineUpdateCache *ool, DataPtr &i typedef bool (*SetPropertyFn)(JSContext *, HandleObject, HandlePropertyName, const HandleValue, bool, jsbytecode *); -typedef bool (*SetPropertyParFn)(ForkJoinContext *, HandleObject, - HandlePropertyName, const HandleValue, bool, jsbytecode *); -static const VMFunctionsModal SetPropertyInfo = VMFunctionsModal( - FunctionInfo(SetProperty), - FunctionInfo(SetPropertyPar)); +static const VMFunction SetPropertyInfo = FunctionInfo(SetProperty); void CodeGenerator::visitCallSetProperty(LCallSetProperty *ins) @@ -8349,25 +7807,6 @@ CodeGenerator::visitSetPropertyIC(OutOfLineUpdateCache *ool, DataPtrrejoin()); } -typedef bool (*SetPropertyParICFn)(ForkJoinContext *, size_t, HandleObject, HandleValue); -const VMFunction SetPropertyParIC::UpdateInfo = - FunctionInfo(SetPropertyParIC::update); - -void -CodeGenerator::visitSetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic) -{ - LInstruction *lir = ool->lir(); - saveLive(lir); - - pushArg(ic->value()); - pushArg(ic->object()); - pushArg(Imm32(ool->getCacheIndex())); - callVM(SetPropertyParIC::UpdateInfo, lir); - restoreLive(lir); - - masm.jump(ool->rejoin()); -} - typedef bool (*ThrowFn)(JSContext *, HandleValue); static const VMFunction ThrowInfoCodeGen = FunctionInfo(js::Throw); @@ -8379,10 +7818,7 @@ CodeGenerator::visitThrow(LThrow *lir) } typedef bool (*BitNotFn)(JSContext *, HandleValue, int *p); -typedef bool (*BitNotParFn)(ForkJoinContext *, HandleValue, int32_t *); -static const VMFunctionsModal BitNotInfo = VMFunctionsModal( - FunctionInfo(BitNot), - FunctionInfo(BitNotPar)); +static const VMFunction BitNotInfo = FunctionInfo(BitNot); void CodeGenerator::visitBitNotV(LBitNotV *lir) @@ -8392,22 +7828,11 @@ CodeGenerator::visitBitNotV(LBitNotV *lir) } typedef bool (*BitopFn)(JSContext *, HandleValue, HandleValue, int *p); -typedef bool (*BitopParFn)(ForkJoinContext *, HandleValue, HandleValue, int32_t *); -static const VMFunctionsModal BitAndInfo = VMFunctionsModal( - FunctionInfo(BitAnd), - FunctionInfo(BitAndPar)); -static const VMFunctionsModal BitOrInfo = VMFunctionsModal( - FunctionInfo(BitOr), - FunctionInfo(BitOrPar)); -static const VMFunctionsModal BitXorInfo = VMFunctionsModal( - FunctionInfo(BitXor), - FunctionInfo(BitXorPar)); -static const VMFunctionsModal BitLhsInfo = VMFunctionsModal( - FunctionInfo(BitLsh), - FunctionInfo(BitLshPar)); -static const VMFunctionsModal BitRhsInfo = VMFunctionsModal( - FunctionInfo(BitRsh), - FunctionInfo(BitRshPar)); +static const VMFunction BitAndInfo = FunctionInfo(BitAnd); +static const VMFunction BitOrInfo = FunctionInfo(BitOr); +static const VMFunction BitXorInfo = FunctionInfo(BitXor); +static const VMFunction BitLhsInfo = FunctionInfo(BitLsh); +static const VMFunction BitRhsInfo = FunctionInfo(BitRsh); void CodeGenerator::visitBitOpV(LBitOpV *lir) diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index e1a5d5be0132..c86057f0186a 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -33,14 +33,11 @@ class OutOfLineTestObject; class OutOfLineNewArray; class OutOfLineNewObject; class CheckOverRecursedFailure; -class CheckOverRecursedFailurePar; -class OutOfLineInterruptCheckPar; class OutOfLineInterruptCheckImplicit; class OutOfLineUnboxFloatingPoint; class OutOfLineStoreElementHole; class OutOfLineTypeOfV; class OutOfLineLoadTypedArray; -class OutOfLineNewGCThingPar; class OutOfLineUpdateCache; class OutOfLineCallPostWriteBarrier; class OutOfLineIsCallable; @@ -113,7 +110,6 @@ class CodeGenerator : public CodeGeneratorSpecific void visitLambda(LLambda *lir); void visitLambdaArrow(LLambdaArrow *lir); void visitLambdaForSingleton(LLambdaForSingleton *lir); - void visitLambdaPar(LLambdaPar *lir); void visitPointer(LPointer *lir); void visitSlots(LSlots *lir); void visitLoadSlotT(LLoadSlotT *lir); @@ -162,10 +158,7 @@ class CodeGenerator : public CodeGeneratorSpecific void visitNewDeclEnvObject(LNewDeclEnvObject *lir); void visitNewCallObject(LNewCallObject *lir); void visitNewSingletonCallObject(LNewSingletonCallObject *lir); - void visitNewCallObjectPar(LNewCallObjectPar *lir); void visitNewStringObject(LNewStringObject *lir); - void visitNewPar(LNewPar *lir); - void visitNewDenseArrayPar(LNewDenseArrayPar *lir); void visitNewDerivedTypedObject(LNewDerivedTypedObject *lir); void visitInitElem(LInitElem *lir); void visitInitElemGetterSetter(LInitElemGetterSetter *lir); @@ -231,13 +224,10 @@ class CodeGenerator : public CodeGeneratorSpecific void visitEmulatesUndefinedAndBranch(LEmulatesUndefinedAndBranch *lir); void emitConcat(LInstruction *lir, Register lhs, Register rhs, Register output); void visitConcat(LConcat *lir); - void visitConcatPar(LConcatPar *lir); void visitCharCodeAt(LCharCodeAt *lir); void visitFromCharCode(LFromCharCode *lir); void visitStringSplit(LStringSplit *lir); void visitFunctionEnvironment(LFunctionEnvironment *lir); - void visitForkJoinContext(LForkJoinContext *lir); - void visitGuardThreadExclusive(LGuardThreadExclusive *lir); void visitCallGetProperty(LCallGetProperty *lir); void visitCallGetElement(LCallGetElement *lir); void visitCallSetElement(LCallSetElement *lir); @@ -291,7 +281,6 @@ class CodeGenerator : public CodeGeneratorSpecific Register temp0, Register temp1, unsigned numFormals, JSObject *templateObject, bool saveAndRestore, Register resultreg); void visitRest(LRest *lir); - void visitRestPar(LRestPar *lir); void visitCallSetProperty(LCallSetProperty *ins); void visitCallDeleteProperty(LCallDeleteProperty *lir); void visitCallDeleteElement(LCallDeleteElement *lir); @@ -325,11 +314,6 @@ class CodeGenerator : public CodeGeneratorSpecific void visitCheckOverRecursed(LCheckOverRecursed *lir); void visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool); - void visitCheckOverRecursedPar(LCheckOverRecursedPar *lir); - - void visitInterruptCheckPar(LInterruptCheckPar *lir); - void visitOutOfLineInterruptCheckPar(OutOfLineInterruptCheckPar *ool); - void visitInterruptCheckImplicit(LInterruptCheckImplicit *ins); void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit *ins); @@ -337,7 +321,6 @@ class CodeGenerator : public CodeGeneratorSpecific void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint *ool); void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole *ool); - void visitOutOfLineNewGCThingPar(OutOfLineNewGCThingPar *ool); void loadJSScriptForBlock(MBasicBlock *block, Register reg); void loadOutermostJSScript(Register reg); @@ -358,13 +341,9 @@ class CodeGenerator : public CodeGeneratorSpecific void visitCallsiteCloneCache(LCallsiteCloneCache *ins); void visitGetPropertyIC(OutOfLineUpdateCache *ool, DataPtr &ic); - void visitGetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitSetPropertyIC(OutOfLineUpdateCache *ool, DataPtr &ic); - void visitSetPropertyParIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitGetElementIC(OutOfLineUpdateCache *ool, DataPtr &ic); - void visitGetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitSetElementIC(OutOfLineUpdateCache *ool, DataPtr &ic); - void visitSetElementParIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitBindNameIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitNameIC(OutOfLineUpdateCache *ool, DataPtr &ic); void visitCallsiteCloneIC(OutOfLineUpdateCache *ool, DataPtr &ic); @@ -401,12 +380,6 @@ class CodeGenerator : public CodeGeneratorSpecific bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr); - void emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg, - Register tempReg1, Register tempReg2, - NativeObject *templateObj); - - void emitCallToUncompiledScriptPar(LInstruction *lir, Register calleeReg); - void emitLambdaInit(Register resultReg, Register scopeChainReg, const LambdaFunctionInfo &info); diff --git a/js/src/jit/CompileInfo.h b/js/src/jit/CompileInfo.h index 8e4ea6c05985..88871ee5485f 100644 --- a/js/src/jit/CompileInfo.h +++ b/js/src/jit/CompileInfo.h @@ -431,10 +431,6 @@ class CompileInfo return executionMode_ == DefinitePropertiesAnalysis || executionMode_ == ArgumentsUsageAnalysis; } - bool isParallelExecution() const { - return executionMode_ == ParallelExecution; - } - // Returns true if a slot can be observed out-side the current frame while // the frame is active on the stack. This implies that these definitions // would have to be executed and that they cannot be removed even if they diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index e10492b85007..02dc0e6d11c2 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -33,14 +33,12 @@ #include "jit/LIR.h" #include "jit/LoopUnroller.h" #include "jit/Lowering.h" -#include "jit/ParallelSafetyAnalysis.h" #include "jit/PerfSpewer.h" #include "jit/RangeAnalysis.h" #include "jit/ScalarReplacement.h" #include "jit/Sink.h" #include "jit/StupidAllocator.h" #include "jit/ValueNumbering.h" -#include "vm/ForkJoin.h" #include "vm/HelperThreads.h" #include "vm/TraceLogging.h" @@ -154,16 +152,13 @@ JitRuntime::JitRuntime() : execAlloc_(nullptr), ionAlloc_(nullptr), exceptionTail_(nullptr), - exceptionTailParallel_(nullptr), bailoutTail_(nullptr), enterJIT_(nullptr), bailoutHandler_(nullptr), argumentsRectifier_(nullptr), argumentsRectifierReturnAddr_(nullptr), - parallelArgumentsRectifier_(nullptr), invalidator_(nullptr), debugTrapHandler_(nullptr), - forkJoinGetSliceStub_(nullptr), baselineDebugModeOSRHandler_(nullptr), functionWrappers_(nullptr), osrTempData_(nullptr), @@ -210,16 +205,11 @@ JitRuntime::initialize(JSContext *cx) JitSpew(JitSpew_Codegen, "# Emitting exception tail stub"); void *handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleException); - void *handlerParallel = JS_FUNC_TO_DATA_PTR(void *, jit::HandleParallelFailure); exceptionTail_ = generateExceptionTailStub(cx, handler); if (!exceptionTail_) return false; - exceptionTailParallel_ = generateExceptionTailStub(cx, handlerParallel); - if (!exceptionTailParallel_) - return false; - JitSpew(JitSpew_Codegen, "# Emitting bailout tail stub"); bailoutTail_ = generateBailoutTailStub(cx); if (!bailoutTail_) @@ -243,15 +233,10 @@ JitRuntime::initialize(JSContext *cx) } JitSpew(JitSpew_Codegen, "# Emitting bailout handler"); - bailoutHandler_ = generateBailoutHandler(cx, SequentialExecution); + bailoutHandler_ = generateBailoutHandler(cx); if (!bailoutHandler_) return false; - JitSpew(JitSpew_Codegen, "# Emitting parallel bailout handler"); - parallelBailoutHandler_ = generateBailoutHandler(cx, ParallelExecution); - if (!parallelBailoutHandler_) - return false; - JitSpew(JitSpew_Codegen, "# Emitting invalidator"); invalidator_ = generateInvalidator(cx); if (!invalidator_) @@ -259,15 +244,10 @@ JitRuntime::initialize(JSContext *cx) } JitSpew(JitSpew_Codegen, "# Emitting sequential arguments rectifier"); - argumentsRectifier_ = generateArgumentsRectifier(cx, SequentialExecution, &argumentsRectifierReturnAddr_); + argumentsRectifier_ = generateArgumentsRectifier(cx, &argumentsRectifierReturnAddr_); if (!argumentsRectifier_) return false; - JitSpew(JitSpew_Codegen, "# Emitting parallel arguments rectifier"); - parallelArgumentsRectifier_ = generateArgumentsRectifier(cx, ParallelExecution, nullptr); - if (!parallelArgumentsRectifier_) - return false; - JitSpew(JitSpew_Codegen, "# Emitting EnterJIT sequence"); enterJIT_ = generateEnterJIT(cx, EnterJitOptimized); if (!enterJIT_) @@ -344,18 +324,6 @@ JitRuntime::debugTrapHandler(JSContext *cx) return debugTrapHandler_; } -bool -JitRuntime::ensureForkJoinGetSliceStubExists(JSContext *cx) -{ - if (!forkJoinGetSliceStub_) { - JitSpew(JitSpew_Codegen, "# Emitting ForkJoinGetSlice stub"); - AutoLockForExclusiveAccess lock(cx); - AutoCompartment ac(cx, cx->runtime()->atomsCompartment()); - forkJoinGetSliceStub_ = generateForkJoinGetSliceStub(cx); - } - return !!forkJoinGetSliceStub_; -} - uint8_t * JitRuntime::allocateOsrTempData(size_t size) { @@ -405,7 +373,6 @@ JitCompartment::JitCompartment() baselineGetPropReturnAddr_(nullptr), baselineSetPropReturnAddr_(nullptr), stringConcatStub_(nullptr), - parallelStringConcatStub_(nullptr), regExpExecStub_(nullptr), regExpTestStub_(nullptr), activeParallelEntryScripts_(nullptr) @@ -432,17 +399,11 @@ bool JitCompartment::ensureIonStubsExist(JSContext *cx) { if (!stringConcatStub_) { - stringConcatStub_ = generateStringConcatStub(cx, SequentialExecution); + stringConcatStub_ = generateStringConcatStub(cx); if (!stringConcatStub_) return false; } - if (!parallelStringConcatStub_) { - parallelStringConcatStub_ = generateStringConcatStub(cx, ParallelExecution); - if (!parallelStringConcatStub_) - return false; - } - return true; } @@ -490,7 +451,7 @@ jit::FinishOffThreadBuilder(JSContext *cx, IonBuilder *builder) // Clear the recompiling flag of the old ionScript, since we continue to // use the old ionScript if recompiling fails. - if (executionMode == SequentialExecution && builder->script()->hasIonScript()) + if (builder->script()->hasIonScript()) builder->script()->ionScript()->clearRecompiling(); // Clean up if compilation did not succeed. @@ -650,9 +611,6 @@ JitCompartment::sweep(FreeOp *fop, JSCompartment *compartment) if (stringConcatStub_ && !IsJitCodeMarked(&stringConcatStub_)) stringConcatStub_ = nullptr; - if (parallelStringConcatStub_ && !IsJitCodeMarked(¶llelStringConcatStub_)) - parallelStringConcatStub_ = nullptr; - if (regExpExecStub_ && !IsJitCodeMarked(®ExpExecStub_)) regExpExecStub_ = nullptr; @@ -845,8 +803,6 @@ IonScript::IonScript() snapshotsRVATableSize_(0), constantTable_(0), constantEntries_(0), - callTargetList_(0), - callTargetEntries_(0), backedgeList_(0), backedgeEntries_(0), invalidationCount_(0), @@ -865,8 +821,7 @@ IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo, size_t constants, size_t safepointIndices, size_t osiIndices, size_t cacheEntries, size_t runtimeSize, size_t safepointsSize, - size_t callTargetEntries, size_t backedgeEntries, - OptimizationLevel optimizationLevel) + size_t backedgeEntries, OptimizationLevel optimizationLevel) { static const int DataAlignment = sizeof(void *); @@ -889,7 +844,6 @@ IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo, size_t paddedCacheEntriesSize = AlignBytes(cacheEntries * sizeof(uint32_t), DataAlignment); size_t paddedRuntimeSize = AlignBytes(runtimeSize, DataAlignment); size_t paddedSafepointSize = AlignBytes(safepointsSize, DataAlignment); - size_t paddedCallTargetSize = AlignBytes(callTargetEntries * sizeof(JSScript *), DataAlignment); size_t paddedBackedgeSize = AlignBytes(backedgeEntries * sizeof(PatchableBackedge), DataAlignment); size_t bytes = paddedSnapshotsSize + paddedRecoversSize + @@ -900,7 +854,6 @@ IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo, paddedCacheEntriesSize + paddedRuntimeSize + paddedSafepointSize + - paddedCallTargetSize + paddedBackedgeSize; IonScript *script = cx->zone()->pod_malloc_with_extra(bytes); if (!script) @@ -946,10 +899,6 @@ IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo, script->constantEntries_ = constants; offsetCursor += paddedConstantsSize; - script->callTargetList_ = offsetCursor; - script->callTargetEntries_ = callTargetEntries; - offsetCursor += paddedCallTargetSize; - script->backedgeList_ = offsetCursor; script->backedgeEntries_ = backedgeEntries; offsetCursor += paddedBackedgeSize; @@ -974,11 +923,6 @@ IonScript::trace(JSTracer *trc) for (size_t i = 0; i < numConstants(); i++) gc::MarkValue(trc, &getConstant(i), "constant"); - - // No write barrier is needed for the call target list, as it's attached - // at compilation time and is read only. - for (size_t i = 0; i < callTargetEntries(); i++) - gc::MarkScriptUnbarriered(trc, &callTargetList()[i], "callTarget"); } /* static */ void @@ -1028,13 +972,6 @@ IonScript::copyConstants(const Value *vp) constants()[i].init(vp[i]); } -void -IonScript::copyCallTargetEntries(JSScript **callTargets) -{ - for (size_t i = 0; i < callTargetEntries_; i++) - callTargetList()[i] = callTargets[i]; -} - void IonScript::copyPatchableBackedges(JSContext *cx, JitCode *code, PatchableBackedgeInfo *backedges, @@ -1380,21 +1317,6 @@ OptimizeMIR(MIRGenerator *mir) return false; } - // Parallel Safety Analysis. Note that this may delete blocks containing - // instructions pointed to by the dependency() field of instructions which - // are not deleted, leaving them dangling. This is ok, since we'll rerun - // AliasAnalysis, which recomputes them, before they're needed. - if (graph.entryBlock()->info().executionMode() == ParallelExecution) { - AutoTraceLog log(logger, TraceLogger_ParallelSafetyAnalysis); - ParallelSafetyAnalysis analysis(mir, graph); - if (!analysis.analyze()) - return false; - IonSpewPass("Parallel Safety Analysis"); - AssertExtendedGraphCoherency(graph); - if (mir->shouldCancel("Parallel Safety Analysis")) - return false; - } - ValueNumberer gvn(mir, graph); if (!gvn.init()) return false; @@ -1767,9 +1689,7 @@ AttachFinishedCompilations(JSContext *cx) // Try to defer linking if the script is on the stack, to postpone // invalidating them. - if (builder->info().executionMode() == SequentialExecution && - builder->script()->hasIonScript()) - { + if (builder->script()->hasIonScript()) { bool onStack = false; for (JitActivationIterator iter(cx->runtime()); !iter.done(); ++iter) { for (JitFrameIterator it(iter); !it.done(); ++it) { @@ -1875,8 +1795,7 @@ TrackPropertiesForSingletonScopes(JSContext *cx, JSScript *script, BaselineFrame static AbortReason IonCompile(JSContext *cx, JSScript *script, BaselineFrame *baselineFrame, jsbytecode *osrPc, bool constructing, - ExecutionMode executionMode, bool recompile, - OptimizationLevel optimizationLevel) + bool recompile, OptimizationLevel optimizationLevel) { TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime()); TraceLoggerEvent event(logger, TraceLogger_AnnotateScripts, script); @@ -1911,13 +1830,6 @@ IonCompile(JSContext *cx, JSScript *script, if (!cx->compartment()->jitCompartment()->ensureIonStubsExist(cx)) return AbortReason_Alloc; - if (executionMode == ParallelExecution && - LIRGenerator::allowInlineForkJoinGetSlice() && - !cx->runtime()->jitRuntime()->ensureForkJoinGetSliceStubExists(cx)) - { - return AbortReason_Alloc; - } - MIRGraph *graph = alloc->new_(temp); if (!graph) return AbortReason_Alloc; @@ -1927,7 +1839,7 @@ IonCompile(JSContext *cx, JSScript *script, return AbortReason_Alloc; CompileInfo *info = alloc->new_(script, script->functionNonDelazifying(), osrPc, - constructing, executionMode, + constructing, SequentialExecution, script->needsArgsObj(), inlineScriptTree); if (!info) return AbortReason_Alloc; @@ -1958,15 +1870,13 @@ IonCompile(JSContext *cx, JSScript *script, if (!builder) return AbortReason_Alloc; - MOZ_ASSERT(recompile == HasIonScript(builder->script(), executionMode)); - MOZ_ASSERT(CanIonCompile(builder->script(), executionMode)); + MOZ_ASSERT(recompile == builder->script()->hasIonScript()); + MOZ_ASSERT(CanIonCompile(builder->script(), SequentialExecution)); RootedScript builderScript(cx, builder->script()); - if (recompile) { - MOZ_ASSERT(executionMode == SequentialExecution); + if (recompile) builderScript->ionScript()->setRecompiling(); - } #ifdef DEBUG IonSpewFunction ionSpewFunction(graph, builderScript); @@ -1993,7 +1903,7 @@ IonCompile(JSContext *cx, JSScript *script, // If possible, compile the script off thread. if (OffThreadCompilationAvailable(cx)) { if (!recompile) - SetIonScript(cx, builderScript, executionMode, ION_COMPILING_SCRIPT); + builderScript->setIonScript(cx, ION_COMPILING_SCRIPT); JitSpew(JitSpew_IonLogs, "Can't log script %s:%d. (Compiled on background thread.)", builderScript->filename(), builderScript->lineno()); @@ -2105,25 +2015,18 @@ CanIonCompileScript(JSContext *cx, JSScript *script, bool osr) } static OptimizationLevel -GetOptimizationLevel(HandleScript script, jsbytecode *pc, ExecutionMode executionMode) +GetOptimizationLevel(HandleScript script, jsbytecode *pc) { - if (executionMode == ParallelExecution) - return Optimization_Normal; - - MOZ_ASSERT(executionMode == SequentialExecution); - return js_IonOptimizations.levelForScript(script, pc); } static MethodStatus Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode *osrPc, - bool constructing, ExecutionMode executionMode, bool forceRecompile = false) + bool constructing, bool forceRecompile = false) { MOZ_ASSERT(jit::IsIonEnabled(cx)); MOZ_ASSERT(jit::IsBaselineEnabled(cx)); MOZ_ASSERT_IF(osrPc != nullptr, LoopEntryCanIonOsr(osrPc)); - MOZ_ASSERT_IF(executionMode == ParallelExecution, !osrFrame && !osrPc); - MOZ_ASSERT_IF(executionMode == ParallelExecution, !HasIonScript(script, executionMode)); if (!script->hasBaselineScript()) return Method_Skipped; @@ -2145,11 +2048,11 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode } bool recompile = false; - OptimizationLevel optimizationLevel = GetOptimizationLevel(script, osrPc, executionMode); + OptimizationLevel optimizationLevel = GetOptimizationLevel(script, osrPc); if (optimizationLevel == Optimization_DontCompile) return Method_Skipped; - IonScript *scriptIon = GetIonScript(script, executionMode); + IonScript *scriptIon = script->maybeIonScript(); if (scriptIon) { if (!scriptIon->method()) return Method_CantCompile; @@ -2169,7 +2072,7 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode recompile = true; } - AbortReason reason = IonCompile(cx, script, osrFrame, osrPc, constructing, executionMode, + AbortReason reason = IonCompile(cx, script, osrFrame, osrPc, constructing, recompile, optimizationLevel); if (reason == AbortReason_Error) return Method_Error; @@ -2183,7 +2086,7 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode } // Compilation succeeded or we invalidated right away or an inlining/alloc abort - if (HasIonScript(script, executionMode)) + if (script->hasIonScript()) return Method_Compiled; return Method_Skipped; } @@ -2239,7 +2142,7 @@ jit::CanEnterAtBranch(JSContext *cx, JSScript *script, BaselineFrame *osrFrame, // (This means a background thread compilation with that pc could have started or not.) RootedScript rscript(cx, script); MethodStatus status = Compile(cx, rscript, osrFrame, pc, osrFrame->isConstructing(), - SequentialExecution, force); + force); if (status != Method_Compiled) { if (status == Method_CantCompile) ForbidCompilation(cx, script); @@ -2309,8 +2212,7 @@ jit::CanEnter(JSContext *cx, RunState &state) // Attempt compilation. Returns Method_Compiled if already compiled. bool constructing = state.isInvoke() && state.asInvoke()->constructing(); - MethodStatus status = - Compile(cx, rscript, nullptr, nullptr, constructing, SequentialExecution); + MethodStatus status = Compile(cx, rscript, nullptr, nullptr, constructing); if (status != Method_Compiled) { if (status == Method_CantCompile) ForbidCompilation(cx, rscript); @@ -2336,8 +2238,7 @@ jit::CompileFunctionForBaseline(JSContext *cx, HandleScript script, BaselineFram } // Attempt compilation. Returns Method_Compiled if already compiled. - MethodStatus status = - Compile(cx, script, frame, nullptr, frame->isConstructing(), SequentialExecution); + MethodStatus status = Compile(cx, script, frame, nullptr, frame->isConstructing()); if (status != Method_Compiled) { if (status == Method_CantCompile) ForbidCompilation(cx, script); @@ -2355,8 +2256,7 @@ jit::Recompile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsby if (script->ionScript()->isRecompiling()) return Method_Compiled; - MethodStatus status = - Compile(cx, script, osrFrame, osrPc, constructing, SequentialExecution, force); + MethodStatus status = Compile(cx, script, osrFrame, osrPc, constructing, force); if (status != Method_Compiled) { if (status == Method_CantCompile) ForbidCompilation(cx, script); @@ -2366,49 +2266,6 @@ jit::Recompile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsby return Method_Compiled; } -MethodStatus -jit::CanEnterInParallel(JSContext *cx, HandleScript script) -{ - // Skip if the script has been disabled. - // - // Note: We return Method_Skipped in this case because the other - // CanEnter() methods do so. However, ForkJoin.cpp detects this - // condition differently treats it more like an error. - if (!script->canParallelIonCompile()) - return Method_Skipped; - - // Skip if the script is being compiled off thread. - if (script->isParallelIonCompilingOffThread()) - return Method_Skipped; - - MethodStatus status = Compile(cx, script, nullptr, nullptr, false, ParallelExecution); - if (status != Method_Compiled) { - if (status == Method_CantCompile) - ForbidCompilation(cx, script, ParallelExecution); - return status; - } - - // This can GC, so afterward, script->parallelIon is - // not guaranteed to be valid. - if (!cx->runtime()->jitRuntime()->enterIon()) - return Method_Error; - - // Subtle: it is possible for GC to occur during - // compilation of one of the invoked functions, which - // would cause the earlier functions (such as the - // kernel itself) to be collected. In this event, we - // give up and fallback to sequential for now. - if (!script->hasParallelIonScript()) { - parallel::Spew( - parallel::SpewCompile, - "Script %p:%s:%u was garbage-collected or invalidated", - script.get(), script->filename(), script->lineno()); - return Method_Skipped; - } - - return Method_Compiled; -} - MethodStatus jit::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs) { @@ -2805,17 +2662,9 @@ jit::Invalidate(types::TypeZone &types, FreeOp *fop, numInvalidations--; // Wait for the scripts to get warm again before doing another - // compile, unless either: - // (1) we are recompiling *because* a script got hot; - // (resetUses is false); or, - // (2) we are invalidating a parallel script. This is because - // the warmUpCounter only applies to sequential uses. Parallel - // execution *requires* ion, and so we don't limit it to - // methods with a high usage count (though we do check that - // the warmUpCount is at least 1 when compiling the transitive - // closure of potential callees, to avoid compiling things - // that are never run at all). - if (resetUses && executionMode != ParallelExecution) + // compile, unless we are recompiling *because* a script got hot + // (resetUses is false). + if (resetUses) script->resetWarmUpCounter(); } @@ -2844,8 +2693,7 @@ jit::IonScript::invalidate(JSContext *cx, bool resetUses, const char *reason) } bool -jit::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetUses, - bool cancelOffThread) +jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses, bool cancelOffThread) { MOZ_ASSERT(script->hasIonScript()); @@ -2871,32 +2719,14 @@ jit::Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetU } types::RecompileInfoVector scripts; - - switch (mode) { - case SequentialExecution: - MOZ_ASSERT(script->hasIonScript()); - if (!scripts.append(script->ionScript()->recompileInfo())) - return false; - break; - case ParallelExecution: - MOZ_ASSERT(script->hasParallelIonScript()); - if (!scripts.append(script->parallelIonScript()->recompileInfo())) - return false; - break; - default: - MOZ_CRASH("No such execution mode"); - } + MOZ_ASSERT(script->hasIonScript()); + if (!scripts.append(script->ionScript()->recompileInfo())) + return false; Invalidate(cx, scripts, resetUses, cancelOffThread); return true; } -bool -jit::Invalidate(JSContext *cx, JSScript *script, bool resetUses, bool cancelOffThread) -{ - return Invalidate(cx, script, SequentialExecution, resetUses, cancelOffThread); -} - static void FinishInvalidationOf(FreeOp *fop, JSScript *script, IonScript *ionScript) { @@ -2913,83 +2743,36 @@ FinishInvalidationOf(FreeOp *fop, JSScript *script, IonScript *ionScript) jit::IonScript::Destroy(fop, ionScript); } -template void jit::FinishInvalidation(FreeOp *fop, JSScript *script) { - // In all cases, nullptr out script->ion or script->parallelIon to avoid - // re-entry. - switch (mode) { - case SequentialExecution: - if (script->hasIonScript()) { - IonScript *ion = script->ionScript(); - script->setIonScript(nullptr, nullptr); - FinishInvalidationOf(fop, script, ion); - } - return; - - case ParallelExecution: - if (script->hasParallelIonScript()) { - IonScript *parallelIon = script->parallelIonScript(); - script->setParallelIonScript(nullptr); - FinishInvalidationOf(fop, script, parallelIon); - } - return; - - default: - MOZ_CRASH("bad execution mode"); + // In all cases, nullptr out script->ion to avoid re-entry. + if (script->hasIonScript()) { + IonScript *ion = script->ionScript(); + script->setIonScript(nullptr, nullptr); + FinishInvalidationOf(fop, script, ion); } } -template void -jit::FinishInvalidation(FreeOp *fop, JSScript *script); - -template void -jit::FinishInvalidation(FreeOp *fop, JSScript *script); - void jit::ForbidCompilation(JSContext *cx, JSScript *script) { - ForbidCompilation(cx, script, SequentialExecution); -} - -void -jit::ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode) -{ - JitSpew(JitSpew_IonAbort, "Disabling Ion mode %d compilation of script %s:%d", - mode, script->filename(), script->lineno()); + JitSpew(JitSpew_IonAbort, "Disabling Ion compilation of script %s:%d", + script->filename(), script->lineno()); CancelOffThreadIonCompile(cx->compartment(), script); - switch (mode) { - case SequentialExecution: - if (script->hasIonScript()) { - // It is only safe to modify script->ion if the script is not currently - // running, because JitFrameIterator needs to tell what ionScript to - // use (either the one on the JSScript, or the one hidden in the - // breadcrumbs Invalidation() leaves). Therefore, if invalidation - // fails, we cannot disable the script. - if (!Invalidate(cx, script, mode, false)) - return; - } - - script->setIonScript(cx, ION_DISABLED_SCRIPT); - return; - - case ParallelExecution: - if (script->hasParallelIonScript()) { - if (!Invalidate(cx, script, mode, false)) - return; - } - - script->setParallelIonScript(ION_DISABLED_SCRIPT); - return; - - default: - MOZ_CRASH("No such execution mode"); + if (script->hasIonScript()) { + // It is only safe to modify script->ion if the script is not currently + // running, because JitFrameIterator needs to tell what ionScript to + // use (either the one on the JSScript, or the one hidden in the + // breadcrumbs Invalidation() leaves). Therefore, if invalidation + // fails, we cannot disable the script. + if (!Invalidate(cx, script, false)) + return; } - MOZ_CRASH("No such execution mode"); + script->setIonScript(cx, ION_DISABLED_SCRIPT); } AutoFlushICache * @@ -3139,9 +2922,6 @@ jit::PurgeCaches(JSScript *script) { if (script->hasIonScript()) script->ionScript()->purgeCaches(); - - if (script->hasParallelIonScript()) - script->parallelIonScript()->purgeCaches(); } size_t @@ -3152,9 +2932,6 @@ jit::SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf) if (script->hasIonScript()) result += script->ionScript()->sizeOfIncludingThis(mallocSizeOf); - if (script->hasParallelIonScript()) - result += script->parallelIonScript()->sizeOfIncludingThis(mallocSizeOf); - return result; } @@ -3164,9 +2941,6 @@ jit::DestroyJitScripts(FreeOp *fop, JSScript *script) if (script->hasIonScript()) jit::IonScript::Destroy(fop, script->ionScript()); - if (script->hasParallelIonScript()) - jit::IonScript::Destroy(fop, script->parallelIonScript()); - if (script->hasBaselineScript()) jit::BaselineScript::Destroy(fop, script->baselineScript()); } @@ -3177,9 +2951,6 @@ jit::TraceJitScripts(JSTracer* trc, JSScript *script) if (script->hasIonScript()) jit::IonScript::Trace(trc, script->ionScript()); - if (script->hasParallelIonScript()) - jit::IonScript::Trace(trc, script->parallelIonScript()); - if (script->hasBaselineScript()) jit::BaselineScript::Trace(trc, script->baselineScript()); } diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index c2f077fe901a..70da5e65ffe8 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -88,8 +88,6 @@ MethodStatus CanEnter(JSContext *cx, RunState &state); MethodStatus CompileFunctionForBaseline(JSContext *cx, HandleScript script, BaselineFrame *frame); MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs); -MethodStatus CanEnterInParallel(JSContext *cx, HandleScript script); - MethodStatus Recompile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode *osrPc, bool constructing, bool force); @@ -129,8 +127,6 @@ void Invalidate(types::TypeZone &types, FreeOp *fop, bool cancelOffThread = true); void Invalidate(JSContext *cx, const types::RecompileInfoVector &invalid, bool resetUses = true, bool cancelOffThread = true); -bool Invalidate(JSContext *cx, JSScript *script, ExecutionMode mode, bool resetUses = true, - bool cancelOffThread = true); bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true, bool cancelOffThread = true); @@ -194,7 +190,6 @@ NumLocalsAndArgs(JSScript *script) } void ForbidCompilation(JSContext *cx, JSScript *script); -void ForbidCompilation(JSContext *cx, JSScript *script, ExecutionMode mode); void PurgeCaches(JSScript *script); size_t SizeOfIonData(JSScript *script, mozilla::MallocSizeOf mallocSizeOf); diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 5d2ac7142fd4..19ad88bf8a6e 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -2065,7 +2065,6 @@ IsResumableMIRType(MIRType type) case MIRType_Pointer: case MIRType_Shape: case MIRType_TypeObject: - case MIRType_ForkJoinContext: case MIRType_Float32x4: case MIRType_Int32x4: case MIRType_Doublex2: diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 1444f7b8f332..8b75049a0417 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6262,11 +6262,6 @@ IonBuilder::jsop_initprop(PropertyName *name) needsBarrier = false; } - // In parallel execution, we never require write barriers. See - // forkjoin.cpp for more information. - if (info().executionMode() == ParallelExecution) - needsBarrier = false; - if (templateObject->isFixedSlot(shape->slot())) { MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), obj, shape->slot(), value); if (needsBarrier) @@ -7148,7 +7143,7 @@ jit::NeedsPostBarrier(CompileInfo &info, MDefinition *value) { if (!GetJitContext()->runtime->gcNursery().exists()) return false; - return info.executionMode() != ParallelExecution && value->mightBeType(MIRType_Object); + return value->mightBeType(MIRType_Object); } bool @@ -7957,10 +7952,6 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index) if (index->mightBeType(MIRType_String) || index->mightBeType(MIRType_Symbol)) barrier = BarrierKind::TypeSet; - // See note about always needing a barrier in jsop_getprop. - if (needsToMonitorMissingProperties(types)) - barrier = BarrierKind::TypeSet; - MInstruction *ins = MGetElementCache::New(alloc(), obj, index, barrier == BarrierKind::TypeSet); current->add(ins); @@ -8030,14 +8021,8 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index) // If we can load the element as a definite double, make sure to check that // the array has been converted to homogenous doubles first. - // - // NB: We disable this optimization in parallel execution mode - // because it is inherently not threadsafe (how do you convert the - // array atomically when there might be concurrent readers)? types::TemporaryTypeSet *objTypes = obj->resultTypeSet(); - ExecutionMode executionMode = info().executionMode(); bool loadDouble = - executionMode == SequentialExecution && barrier == BarrierKind::NoBarrier && loopDepth_ && !readOutOfBounds && @@ -8072,37 +8057,6 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index) MOZ_ASSERT(knownType == MIRType_Value); } - // If the array is being converted to doubles, but we've observed - // just int, substitute a type set of int+double into the observed - // type set. The reason for this is that, in the - // interpreter+baseline, such arrays may consist of mixed - // ints/doubles, but when we enter ion code, we will be coercing - // all inputs to doubles. Therefore, the type barrier checking for - // just int is highly likely (*almost* guaranteed) to fail sooner - // or later. Essentially, by eagerly coercing to double, ion is - // making the observed types outdated. To compensate for this, we - // substitute a broader observed type set consisting of both ints - // and doubles. There is perhaps a tradeoff here, so we limit this - // optimization to parallel code, where it is needed to prevent - // perpetual bailouts in some extreme cases. (Bug 977853) - // - // NB: we have not added a MConvertElementsToDoubles MIR, so we - // cannot *assume* the result is a double. - if (executionMode == ParallelExecution && - barrier != BarrierKind::NoBarrier && - types->getKnownMIRType() == MIRType_Int32 && - objTypes && - objTypes->convertDoubleElements(constraints()) == types::TemporaryTypeSet::AlwaysConvertToDoubles) - { - // Note: double implies int32 as well for typesets - LifoAlloc *lifoAlloc = alloc().lifoAlloc(); - types = lifoAlloc->new_(lifoAlloc, types::Type::DoubleType()); - if (!types) - return false; - - barrier = BarrierKind::NoBarrier; // Don't need a barrier anymore - } - if (knownType != MIRType_Value) load->setResultType(knownType); @@ -10025,9 +9979,6 @@ IonBuilder::getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name, if (inspector->hasSeenAccessedGetter(pc)) barrier = BarrierKind::TypeSet; - if (needsToMonitorMissingProperties(types)) - barrier = BarrierKind::TypeSet; - // Caches can read values from prototypes, so update the barrier to // reflect such possible values. if (barrier != BarrierKind::TypeSet) { @@ -10043,14 +9994,7 @@ IonBuilder::getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name, barrier == BarrierKind::TypeSet); // Try to mark the cache as idempotent. - // - // In parallel execution, idempotency of caches is ignored, since we - // repeat the entire ForkJoin workload if we bail out. Note that it's - // overly restrictive to mark everything as idempotent, because we can - // treat non-idempotent caches in parallel as repeatable. - if (obj->type() == MIRType_Object && !invalidatedIdempotentCache() && - info().executionMode() != ParallelExecution) - { + if (obj->type() == MIRType_Object && !invalidatedIdempotentCache()) { if (PropertyReadIsIdempotent(constraints(), obj, name)) load->setIdempotent(); } @@ -10162,17 +10106,6 @@ IonBuilder::getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *na return true; } -bool -IonBuilder::needsToMonitorMissingProperties(types::TemporaryTypeSet *types) -{ - // GetPropertyParIC and GetElementParIC cannot safely call - // TypeScript::Monitor to ensure that the observed type set contains - // undefined. To account for possible missing properties, which property - // types do not track, we must always insert a type barrier. - return info().executionMode() == ParallelExecution && - !types->hasType(types::Type::UndefinedType()); -} - bool IonBuilder::jsop_setprop(PropertyName *name) { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 294a75d4163d..6bd40b77106d 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -439,7 +439,6 @@ class IonBuilder types::TemporaryTypeSet *types); bool getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name, BarrierKind barrier, types::TemporaryTypeSet *types); - bool needsToMonitorMissingProperties(types::TemporaryTypeSet *types); // jsop_setprop() helpers. bool setPropTryCommonSetter(bool *emitted, MDefinition *obj, @@ -770,18 +769,12 @@ class IonBuilder ScalarTypeDescr::Type arrayType); bool inlineUnsafeSetTypedObjectArrayElement(CallInfo &callInfo, uint32_t base, ScalarTypeDescr::Type arrayType); - InliningStatus inlineNewDenseArray(CallInfo &callInfo); - InliningStatus inlineNewDenseArrayForSequentialExecution(CallInfo &callInfo); - InliningStatus inlineNewDenseArrayForParallelExecution(CallInfo &callInfo); // Slot intrinsics. InliningStatus inlineUnsafeSetReservedSlot(CallInfo &callInfo); InliningStatus inlineUnsafeGetReservedSlot(CallInfo &callInfo, MIRType knownValueType); - // ForkJoin intrinsics - InliningStatus inlineForkJoinGetSlice(CallInfo &callInfo); - // TypedArray intrinsics. InliningStatus inlineIsTypedArray(CallInfo &callInfo); InliningStatus inlineTypedArrayLength(CallInfo &callInfo); @@ -808,7 +801,6 @@ class IonBuilder InliningStatus inlineSubstringKernel(CallInfo &callInfo); // Testing functions. - InliningStatus inlineForceSequentialOrInParallelSection(CallInfo &callInfo); InliningStatus inlineBailout(CallInfo &callInfo); InliningStatus inlineAssertFloat32(CallInfo &callInfo); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 8fc30b2a535f..8001c0c7ba5f 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -21,7 +21,6 @@ #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" #endif -#include "jit/ParallelFunctions.h" #include "jit/VMFunctions.h" #include "vm/Shape.h" @@ -396,9 +395,7 @@ IonCache::attachStub(MacroAssembler &masm, StubAttacher &attacher, Handlenew_(cx); - return stubbedShapes_ && stubbedShapes_->init(); - } - return true; -} - -bool -ParallelIonCache::hasOrAddStubbedShape(LockedJSContext &cx, Shape *shape, bool *alreadyStubbed) -{ - // Check if we have already stubbed the current object to avoid - // attaching a duplicate stub. - if (!initStubbedShapes(cx)) - return false; - ShapeSet::AddPtr p = stubbedShapes_->lookupForAdd(shape); - if ((*alreadyStubbed = !!p)) - return true; - return stubbedShapes_->add(p, shape); -} - -void -ParallelIonCache::reset() -{ - DispatchIonCache::reset(); - if (stubbedShapes_) - stubbedShapes_->clear(); -} - -void -ParallelIonCache::destroy() -{ - DispatchIonCache::destroy(); - js_delete(stubbedShapes_); -} - -void -GetPropertyParIC::reset() -{ - ParallelIonCache::reset(); - hasTypedArrayLengthStub_ = false; - hasSharedTypedArrayLengthStub_ = false; -} - -bool -GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, - HandleNativeObject holder, HandleShape shape) -{ - // Ready to generate the read slot stub. - DispatchStubPrepender attacher(*this); - MacroAssembler masm(cx, ion); - GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output()); - - return linkAndAttachStub(cx, masm, attacher, ion, "parallel reading"); -} - -bool -GetPropertyParIC::attachArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - if (!GenerateArrayLength(cx, masm, attacher, obj, object(), output())) - return false; - - return linkAndAttachStub(cx, masm, attacher, ion, "parallel array length"); -} - -bool -GetPropertyParIC::attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - GenerateTypedArrayLength(cx, masm, attacher, AnyTypedArrayLayout(obj), object(), output()); - - setHasTypedArrayLengthStub(obj); - return linkAndAttachStub(cx, masm, attacher, ion, "parallel typed array length"); -} - -bool -GetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, - HandleObject obj, MutableHandleValue vp) -{ - IonScript *ion = GetTopJitJSScript(cx)->parallelIonScript(); - GetPropertyParIC &cache = ion->getCache(cacheIndex).toGetPropertyPar(); - - // Grab the property early, as the pure path is fast anyways and doesn't - // need a lock. If we can't do it purely, bail out of parallel execution. - if (!GetPropertyPure(cx, obj, NameToId(cache.name()), vp.address())) - return false; - - // Avoid unnecessary locking if cannot attach stubs. - if (!cache.canAttachStub()) - return true; - - { - // Lock the context before mutating the cache. Ideally we'd like to do - // finer-grained locking, with one lock per cache. However, generating - // new jitcode uses a global ExecutableAllocator tied to the runtime. - LockedJSContext ncx(cx); - - if (cache.canAttachStub()) { - bool alreadyStubbed; - if (!cache.hasOrAddStubbedShape(ncx, obj->lastProperty(), &alreadyStubbed)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - if (alreadyStubbed) - return true; - - // See note about the stub limit in GetPropertyCache. - bool attachedStub = false; - - { - RootedShape shape(ncx); - RootedNativeObject holder(ncx); - RootedPropertyName name(ncx, cache.name()); - - GetPropertyIC::NativeGetPropCacheability canCache = - CanAttachNativeGetProp(ncx, cache, obj, name, &holder, &shape); - - if (canCache == GetPropertyIC::CanAttachReadSlot) { - if (!cache.attachReadSlot(ncx, ion, obj, holder, shape)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - - if (!attachedStub && canCache == GetPropertyIC::CanAttachArrayLength) { - if (!cache.attachArrayLength(ncx, ion, obj)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - } - - if (!attachedStub && !cache.hasAnyTypedArrayLengthStub(obj) && - IsAnyTypedArray(obj) && cx->names().length == cache.name() && - (cache.output().type() == MIRType_Value || cache.output().type() == MIRType_Int32)) - { - if (!cache.attachTypedArrayLength(ncx, ion, obj)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - } - } - - return true; -} - void IonCache::disable() { @@ -2909,112 +2758,6 @@ SetPropertyIC::reset() hasGenericProxyStub_ = false; } -bool -SetPropertyParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - HandleValue value) -{ - MOZ_ASSERT(cx->isThreadLocal(obj)); - - IonScript *ion = GetTopJitJSScript(cx)->parallelIonScript(); - SetPropertyParIC &cache = ion->getCache(cacheIndex).toSetPropertyPar(); - - RootedValue v(cx, value); - RootedId id(cx, AtomToId(cache.name())); - - if (!obj->isNative()) - return false; - RootedNativeObject nobj(cx, &obj->as()); - - // Avoid unnecessary locking if cannot attach stubs. - if (!cache.canAttachStub()) { - return baseops::SetPropertyHelper( - cx, nobj, nobj, id, baseops::Qualified, &v, cache.strict()); - } - - SetPropertyIC::NativeSetPropCacheability canCache = SetPropertyIC::CanAttachNone; - bool attachedStub = false; - - { - // See note about locking context in GetPropertyParIC::update. - LockedJSContext ncx(cx); - - if (cache.canAttachStub()) { - bool alreadyStubbed; - if (!cache.hasOrAddStubbedShape(ncx, nobj->lastProperty(), &alreadyStubbed)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - if (alreadyStubbed) { - return baseops::SetPropertyHelper( - cx, nobj, nobj, id, baseops::Qualified, &v, cache.strict()); - } - - // If the object has a lazy type, we need to de-lazify it, but - // this is not safe in parallel. - if (nobj->hasLazyType()) - return false; - - { - RootedShape shape(cx); - RootedNativeObject holder(cx); - bool checkTypeset; - canCache = CanAttachNativeSetProp(cx, nobj, id, cache.value(), cache.needsTypeBarrier(), - &holder, &shape, &checkTypeset); - - if (canCache == SetPropertyIC::CanAttachSetSlot) { - if (!cache.attachSetSlot(ncx, ion, nobj, shape, checkTypeset)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - } - } - } - - uint32_t oldSlots = nobj->numDynamicSlots(); - RootedShape oldShape(cx, nobj->lastProperty()); - RootedTypeObject oldType(cx, nobj->type()); - - if (!baseops::SetPropertyHelper(cx, nobj, nobj, id, baseops::Qualified, &v, - cache.strict())) - { - return false; - } - - bool checkTypeset; - if (!attachedStub && canCache == SetPropertyIC::MaybeCanAttachAddSlot && - IsPropertyAddInlineable(nobj, id, - cache.value(), oldSlots, oldShape, cache.needsTypeBarrier(), - &checkTypeset)) - { - LockedJSContext ncx(cx); - if (cache.canAttachStub() && !cache.attachAddSlot(ncx, ion, nobj, oldShape, oldType, checkTypeset)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - } - - return true; -} - -bool -SetPropertyParIC::attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj, - HandleShape shape, bool checkTypeset) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - GenerateSetSlot(cx, masm, attacher, obj, shape, object(), value(), needsTypeBarrier(), - checkTypeset); - return linkAndAttachStub(cx, masm, attacher, ion, "parallel setting"); -} - -bool -SetPropertyParIC::attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj, - HandleShape oldShape, HandleTypeObject oldType, bool checkTypeset) -{ - MOZ_ASSERT_IF(!needsTypeBarrier(), !checkTypeset); - - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - GenerateAddSlot(cx, masm, attacher, obj, oldShape, oldType, object(), value(), checkTypeset); - return linkAndAttachStub(cx, masm, attacher, ion, "parallel adding"); -} - const size_t GetElementIC::MAX_FAILED_UPDATES = 16; /* static */ bool @@ -3898,191 +3641,6 @@ SetElementIC::reset() hasDenseStub_ = false; } -bool -SetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj, - const Value &idval) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval, - guardHoles(), object(), index(), - value(), tempToUnboxIndex(), - temp())) - { - return false; - } - - const char *message = guardHoles() ? - "parallel dense array (holes)" : - "parallel dense array"; - - return linkAndAttachStub(cx, masm, attacher, ion, message); -} - -bool -SetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, - HandleObject tarr) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr, - object(), index(), value(), - tempToUnboxIndex(), temp(), tempDouble(), tempFloat32())) - { - return false; - } - - return linkAndAttachStub(cx, masm, attacher, ion, "parallel typed array"); -} - -bool -SetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - HandleValue idval, HandleValue value) -{ - IonScript *ion = GetTopJitJSScript(cx)->parallelIonScript(); - SetElementParIC &cache = ion->getCache(cacheIndex).toSetElementPar(); - - // Avoid unnecessary locking if cannot attach stubs. - if (!cache.canAttachStub()) - return SetElementPar(cx, obj, idval, value, cache.strict()); - - { - LockedJSContext ncx(cx); - - if (cache.canAttachStub()) { - bool alreadyStubbed; - if (!cache.hasOrAddStubbedShape(ncx, obj->lastProperty(), &alreadyStubbed)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - if (alreadyStubbed) - return SetElementPar(cx, obj, idval, value, cache.strict()); - - bool attachedStub = false; - if (IsDenseElementSetInlineable(obj, idval)) { - if (!cache.attachDenseElement(ncx, ion, obj, idval)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - if (!attachedStub && IsTypedArrayElementSetInlineable(obj, idval, value)) { - if (!cache.attachTypedArrayElement(ncx, ion, obj)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - } - } - } - - return SetElementPar(cx, obj, idval, value, cache.strict()); -} - -bool -GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, - const Value &idval, HandlePropertyName name, HandleNativeObject holder, - HandleShape shape) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - - // Guard on the index value. - Label failures; - ValueOperand val = index().reg().valueReg(); - masm.branchTestValue(Assembler::NotEqual, val, idval, &failures); - - GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(), - &failures); - - return linkAndAttachStub(cx, masm, attacher, ion, "parallel getelem reading"); -} - -bool -GetElementParIC::attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj, - const Value &idval) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - if (!GenerateDenseElement(cx, masm, attacher, obj, idval, object(), index(), output())) - return false; - - return linkAndAttachStub(cx, masm, attacher, ion, "parallel dense element"); -} - -bool -GetElementParIC::attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, - HandleObject tarr, const Value &idval) -{ - MacroAssembler masm(cx, ion); - DispatchStubPrepender attacher(*this); - GenerateGetTypedArrayElement(cx, masm, attacher, tarr, idval, object(), index(), output(), - allowDoubleResult()); - return linkAndAttachStub(cx, masm, attacher, ion, "parallel typed array"); -} - -bool -GetElementParIC::update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - HandleValue idval, MutableHandleValue vp) -{ - IonScript *ion = GetTopJitJSScript(cx)->parallelIonScript(); - GetElementParIC &cache = ion->getCache(cacheIndex).toGetElementPar(); - - // Try to get the element early, as the pure path doesn't need a lock. If - // we can't do it purely, bail out of parallel execution. - if (!GetObjectElementOperationPure(cx, obj, idval, vp.address())) - return false; - - // Avoid unnecessary locking if cannot attach stubs. - if (!cache.canAttachStub()) - return true; - - { - // See note about locking context in GetPropertyParIC::update. - LockedJSContext ncx(cx); - - if (cache.canAttachStub()) { - bool alreadyStubbed; - if (!cache.hasOrAddStubbedShape(ncx, obj->lastProperty(), &alreadyStubbed)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - if (alreadyStubbed) - return true; - - jsid id; - if (!ValueToIdPure(idval, &id)) - return false; - - bool attachedStub = false; - if (cache.monitoredResult() && - GetElementIC::canAttachGetProp(obj, idval, id)) - { - RootedShape shape(ncx); - RootedNativeObject holder(ncx); - RootedPropertyName name(ncx, JSID_TO_ATOM(id)->asPropertyName()); - - GetPropertyIC::NativeGetPropCacheability canCache = - CanAttachNativeGetProp(ncx, cache, obj, name, &holder, &shape); - - if (canCache == GetPropertyIC::CanAttachReadSlot) - { - if (!cache.attachReadSlot(ncx, ion, obj, idval, name, holder, shape)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - } - if (!attachedStub && - GetElementIC::canAttachDenseElement(obj, idval)) - { - if (!cache.attachDenseElement(ncx, ion, obj, idval)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - if (!attachedStub && - GetElementIC::canAttachTypedArrayElement(obj, idval, cache.output())) - { - if (!cache.attachTypedArrayElement(ncx, ion, obj, idval)) - return cx->setPendingAbortFatal(ParallelBailoutOutOfMemory); - attachedStub = true; - } - } - } - - return true; -} - bool BindNameIC::attachGlobal(JSContext *cx, HandleScript outerScript, IonScript *ion, HandleObject scopeChain) diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index ddca47b5084e..e3c8a77c833f 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -31,11 +31,7 @@ class LInstruction; _(SetElement) \ _(BindName) \ _(Name) \ - _(CallsiteClone) \ - _(GetPropertyPar) \ - _(GetElementPar) \ - _(SetPropertyPar) \ - _(SetElementPar) + _(CallsiteClone) // Forward declarations of Cache kinds. #define FORWARD_DECLARE(kind) class kind##IC; @@ -420,7 +416,8 @@ class RepatchIonCache : public IonCache // not have to worry about aligning the exit jumps to ensure atomic patching, // at the expense of an extra memory read to load the very first stub. // -// ICs that need to work in parallel execution need to be dispatch style. +// ICs that need to work in parallel execution need to be dispatch +// style. Since PJS's removal, nothing else yet uses this style of ICs. // // Control flow Pointers Memory load // =======# ----. .----> ****** @@ -1079,284 +1076,6 @@ class CallsiteCloneIC : public RepatchIonCache static JSObject *update(JSContext *cx, size_t cacheIndex, HandleObject callee); }; -class ParallelIonCache : public DispatchIonCache -{ - protected: - // A set of all objects that are stubbed. Used to detect duplicates in - // parallel execution. - ShapeSet *stubbedShapes_; - - ParallelIonCache() - : stubbedShapes_(nullptr) - { - } - - bool initStubbedShapes(JSContext *cx); - - public: - void reset(); - void destroy(); - - bool hasOrAddStubbedShape(LockedJSContext &cx, Shape *shape, bool *alreadyStubbed); -}; - -class GetPropertyParIC : public ParallelIonCache -{ - protected: - Register object_; - PropertyName *name_; - TypedOrValueRegister output_; - bool hasTypedArrayLengthStub_ : 1; - bool hasSharedTypedArrayLengthStub_ : 1; - - public: - GetPropertyParIC(Register object, PropertyName *name, TypedOrValueRegister output) - : object_(object), - name_(name), - output_(output), - hasTypedArrayLengthStub_(false), - hasSharedTypedArrayLengthStub_(false) - { - } - - CACHE_HEADER(GetPropertyPar) - -#ifdef JS_CODEGEN_X86 - // x86 lacks a general purpose scratch register for dispatch caches and - // must be given one manually. - void initializeAddCacheState(LInstruction *ins, AddCacheState *addState); -#endif - - void reset(); - - Register object() const { - return object_; - } - PropertyName *name() const { - return name_; - } - TypedOrValueRegister output() const { - return output_; - } - bool hasAnyTypedArrayLengthStub(HandleObject obj) const { - return obj->is() ? hasTypedArrayLengthStub_ : hasSharedTypedArrayLengthStub_; - } - - void setHasTypedArrayLengthStub(HandleObject obj) { - if (obj->is()) { - MOZ_ASSERT(!hasTypedArrayLengthStub_); - hasTypedArrayLengthStub_ = true; - } else { - MOZ_ASSERT(!hasSharedTypedArrayLengthStub_); - hasSharedTypedArrayLengthStub_ = true; - } - } - - // CanAttachNativeGetProp Helpers - typedef LockedJSContext & Context; - bool canMonitorSingletonUndefinedSlot(HandleObject, HandleShape) const { return true; } - bool allowGetters() const { return false; } - bool allowArrayLength(Context, HandleObject) const { return true; } - - bool attachReadSlot(LockedJSContext &cx, IonScript *ion, - HandleObject obj, HandleNativeObject holder, - HandleShape shape); - bool attachArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj); - bool attachTypedArrayLength(LockedJSContext &cx, IonScript *ion, HandleObject obj); - - static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - MutableHandleValue vp); -}; - -class GetElementParIC : public ParallelIonCache -{ - protected: - Register object_; - ConstantOrRegister index_; - TypedOrValueRegister output_; - - bool monitoredResult_ : 1; - bool allowDoubleResult_ : 1; - - public: - GetElementParIC(Register object, ConstantOrRegister index, - TypedOrValueRegister output, bool monitoredResult, bool allowDoubleResult) - : object_(object), - index_(index), - output_(output), - monitoredResult_(monitoredResult), - allowDoubleResult_(allowDoubleResult) - { - } - - CACHE_HEADER(GetElementPar) - -#ifdef JS_CODEGEN_X86 - // x86 lacks a general purpose scratch register for dispatch caches and - // must be given one manually. - void initializeAddCacheState(LInstruction *ins, AddCacheState *addState); -#endif - - Register object() const { - return object_; - } - ConstantOrRegister index() const { - return index_; - } - TypedOrValueRegister output() const { - return output_; - } - bool monitoredResult() const { - return monitoredResult_; - } - bool allowDoubleResult() const { - return allowDoubleResult_; - } - - // CanAttachNativeGetProp Helpers - typedef LockedJSContext & Context; - bool canMonitorSingletonUndefinedSlot(HandleObject, HandleShape) const { return true; } - bool allowGetters() const { return false; } - bool allowArrayLength(Context, HandleObject) const { return false; } - - bool attachReadSlot(LockedJSContext &cx, IonScript *ion, HandleObject obj, const Value &idval, - HandlePropertyName name, HandleNativeObject holder, HandleShape shape); - bool attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj, - const Value &idval); - bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, HandleObject tarr, - const Value &idval); - - static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, HandleValue idval, - MutableHandleValue vp); - -}; - -class SetPropertyParIC : public ParallelIonCache -{ - protected: - Register object_; - PropertyName *name_; - ConstantOrRegister value_; - bool strict_; - bool needsTypeBarrier_; - - public: - SetPropertyParIC(Register object, PropertyName *name, ConstantOrRegister value, - bool strict, bool needsTypeBarrier) - : object_(object), - name_(name), - value_(value), - strict_(strict), - needsTypeBarrier_(needsTypeBarrier) - { - } - - CACHE_HEADER(SetPropertyPar) - -#ifdef JS_CODEGEN_X86 - // x86 lacks a general purpose scratch register for dispatch caches and - // must be given one manually. - void initializeAddCacheState(LInstruction *ins, AddCacheState *addState); -#endif - - Register object() const { - return object_; - } - PropertyName *name() const { - return name_; - } - ConstantOrRegister value() const { - return value_; - } - bool strict() const { - return strict_; - } - bool needsTypeBarrier() const { - return needsTypeBarrier_; - } - - bool attachSetSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj, HandleShape shape, - bool checkTypeset); - bool attachAddSlot(LockedJSContext &cx, IonScript *ion, HandleNativeObject obj, - HandleShape oldShape, HandleTypeObject oldType, bool checkTypeset); - - static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - HandleValue value); -}; - -class SetElementParIC : public ParallelIonCache -{ - protected: - Register object_; - Register tempToUnboxIndex_; - Register temp_; - FloatRegister tempDouble_; - FloatRegister tempFloat32_; - ValueOperand index_; - ConstantOrRegister value_; - bool strict_; - bool guardHoles_; - - public: - SetElementParIC(Register object, Register tempToUnboxIndex, Register temp, - FloatRegister tempDouble, FloatRegister tempFloat32, ValueOperand index, ConstantOrRegister value, - bool strict, bool guardHoles) - : object_(object), - tempToUnboxIndex_(tempToUnboxIndex), - temp_(temp), - tempDouble_(tempDouble), - tempFloat32_(tempFloat32), - index_(index), - value_(value), - strict_(strict), - guardHoles_(guardHoles) - { - } - - CACHE_HEADER(SetElementPar) - -#ifdef JS_CODEGEN_X86 - // x86 lacks a general purpose scratch register for dispatch caches and - // must be given one manually. - void initializeAddCacheState(LInstruction *ins, AddCacheState *addState); -#endif - - Register object() const { - return object_; - } - Register tempToUnboxIndex() const { - return tempToUnboxIndex_; - } - Register temp() const { - return temp_; - } - FloatRegister tempDouble() const { - return tempDouble_; - } - FloatRegister tempFloat32() const { - return tempFloat32_; - } - ValueOperand index() const { - return index_; - } - ConstantOrRegister value() const { - return value_; - } - bool strict() const { - return strict_; - } - bool guardHoles() const { - return guardHoles_; - } - - bool attachDenseElement(LockedJSContext &cx, IonScript *ion, HandleObject obj, - const Value &idval); - bool attachTypedArrayElement(LockedJSContext &cx, IonScript *ion, HandleObject tarr); - - static bool update(ForkJoinContext *cx, size_t cacheIndex, HandleObject obj, - HandleValue idval, HandleValue value); -}; - #undef CACHE_HEADER // Implement cache casts now that the compiler can see the inheritance. diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index 5a71f9efcf91..d3865c1eccb2 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -256,12 +256,6 @@ struct IonScript uint32_t constantTable_; uint32_t constantEntries_; - // List of scripts that we call. - // - // Currently this is only non-nullptr for parallel IonScripts. - uint32_t callTargetList_; - uint32_t callTargetEntries_; - // List of patchable backedges which are threaded into the runtime's list. uint32_t backedgeList_; uint32_t backedgeEntries_; @@ -333,9 +327,6 @@ struct IonScript uint8_t *runtimeData() { return &bottomBuffer()[runtimeData_]; } - JSScript **callTargetList() { - return (JSScript **) &bottomBuffer()[callTargetList_]; - } PatchableBackedge *backedgeList() { return (PatchableBackedge *) &bottomBuffer()[backedgeList_]; } @@ -354,8 +345,7 @@ struct IonScript size_t constants, size_t safepointIndexEntries, size_t osiIndexEntries, size_t cacheEntries, size_t runtimeSize, size_t safepointsSize, - size_t callTargetEntries, size_t backedgeEntries, - OptimizationLevel optimizationLevel); + size_t backedgeEntries, OptimizationLevel optimizationLevel); static void Trace(JSTracer *trc, IonScript *script); static void Destroy(FreeOp *fop, IonScript *script); @@ -490,9 +480,6 @@ struct IonScript size_t safepointsSize() const { return safepointsSize_; } - size_t callTargetEntries() const { - return callTargetEntries_; - } size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this); } @@ -552,7 +539,6 @@ struct IonScript void copyRuntimeData(const uint8_t *data); void copyCacheEntries(const uint32_t *caches, MacroAssembler &masm); void copySafepoints(const SafepointWriter *writer); - void copyCallTargetEntries(JSScript **callTargets); void copyPatchableBackedges(JSContext *cx, JitCode *code, PatchableBackedgeInfo *backedges, MacroAssembler &masm); diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 11bca60301ca..da6b0debe95f 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -381,8 +381,7 @@ enum MIRType MIRType_Pointer, // An opaque pointer that receives no special treatment MIRType_Shape, // A Shape pointer. MIRType_TypeObject, // A TypeObject pointer. - MIRType_ForkJoinContext, // js::ForkJoinContext* - MIRType_Last = MIRType_ForkJoinContext, + MIRType_Last = MIRType_TypeObject, MIRType_Float32x4 = MIRType_Float32 | (2 << VECTOR_SCALE_SHIFT), MIRType_Int32x4 = MIRType_Int32 | (2 << VECTOR_SCALE_SHIFT), MIRType_Doublex2 = MIRType_Double | (1 << VECTOR_SCALE_SHIFT) @@ -496,8 +495,6 @@ StringFromMIRType(MIRType type) return "Elements"; case MIRType_Pointer: return "Pointer"; - case MIRType_ForkJoinContext: - return "ForkJoinContext"; case MIRType_Int32x4: return "Int32x4"; case MIRType_Float32x4: diff --git a/js/src/jit/JitCompartment.h b/js/src/jit/JitCompartment.h index 4b36a3d23602..e097e8537813 100644 --- a/js/src/jit/JitCompartment.h +++ b/js/src/jit/JitCompartment.h @@ -154,7 +154,6 @@ class JitRuntime // Shared exception-handler tail. JitCode *exceptionTail_; - JitCode *exceptionTailParallel_; // Shared post-bailout-handler tail. JitCode *bailoutTail_; @@ -171,17 +170,11 @@ class JitRuntime // Generic bailout table; used if the bailout table overflows. JitCode *bailoutHandler_; - // Bailout handler for parallel execution. - JitCode *parallelBailoutHandler_; - // Argument-rectifying thunk, in the case of insufficient arguments passed // to a function call site. JitCode *argumentsRectifier_; void *argumentsRectifierReturnAddr_; - // Arguments-rectifying thunk which loads |parallelIon| instead of |ion|. - JitCode *parallelArgumentsRectifier_; - // Thunk that invalides an (Ion compiled) caller on the Ion stack. JitCode *invalidator_; @@ -202,9 +195,6 @@ class JitRuntime // Thunk used by the debugger for breakpoint and step mode. JitCode *debugTrapHandler_; - // Stub used to inline the ForkJoinGetSlice intrinsic. - JitCode *forkJoinGetSliceStub_; - // Thunk used to fix up on-stack recompile of baseline scripts. JitCode *baselineDebugModeOSRHandler_; void *baselineDebugModeOSRHandlerNoFrameRegPopAddr_; @@ -247,15 +237,14 @@ class JitRuntime JitCode *generateExceptionTailStub(JSContext *cx, void *handler); JitCode *generateBailoutTailStub(JSContext *cx); JitCode *generateEnterJIT(JSContext *cx, EnterJitType type); - JitCode *generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut); + JitCode *generateArgumentsRectifier(JSContext *cx, void **returnAddrOut); JitCode *generateBailoutTable(JSContext *cx, uint32_t frameClass); - JitCode *generateBailoutHandler(JSContext *cx, ExecutionMode mode); + JitCode *generateBailoutHandler(JSContext *cx); JitCode *generateInvalidator(JSContext *cx); JitCode *generatePreBarrier(JSContext *cx, MIRType type); JitCode *generateMallocStub(JSContext *cx); JitCode *generateFreeStub(JSContext *cx); JitCode *generateDebugTrapHandler(JSContext *cx); - JitCode *generateForkJoinGetSliceStub(JSContext *cx); JitCode *generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrameRegPopOffsetOut); JitCode *generateVMWrapper(JSContext *cx, const VMFunction &f); @@ -322,20 +311,13 @@ class JitRuntime JitCode *getBaselineDebugModeOSRHandler(JSContext *cx); void *getBaselineDebugModeOSRHandlerAddress(JSContext *cx, bool popFrameReg); - JitCode *getGenericBailoutHandler(ExecutionMode mode) const { - switch (mode) { - case SequentialExecution: return bailoutHandler_; - case ParallelExecution: return parallelBailoutHandler_; - default: MOZ_CRASH("No such execution mode"); - } + JitCode *getGenericBailoutHandler() const { + return bailoutHandler_; } JitCode *getExceptionTail() const { return exceptionTail_; } - JitCode *getExceptionTailParallel() const { - return exceptionTailParallel_; - } JitCode *getBailoutTail() const { return bailoutTail_; @@ -343,12 +325,8 @@ class JitRuntime JitCode *getBailoutTable(const FrameSizeClass &frameClass) const; - JitCode *getArgumentsRectifier(ExecutionMode mode) const { - switch (mode) { - case SequentialExecution: return argumentsRectifier_; - case ParallelExecution: return parallelArgumentsRectifier_; - default: MOZ_CRASH("No such execution mode"); - } + JitCode *getArgumentsRectifier() const { + return argumentsRectifier_; } void *getArgumentsRectifierReturnAddr() const { @@ -390,11 +368,6 @@ class JitRuntime return lazyLinkStub_; } - bool ensureForkJoinGetSliceStubExists(JSContext *cx); - JitCode *forkJoinGetSliceStub() const { - return forkJoinGetSliceStub_; - } - bool hasIonReturnOverride() const { return !ionReturnOverride_.isMagic(JS_ARG_POISON); } @@ -459,7 +432,6 @@ class JitCompartment // which may occur off thread and whose barriers are captured during // CodeGenerator::link. JitCode *stringConcatStub_; - JitCode *parallelStringConcatStub_; JitCode *regExpExecStub_; JitCode *regExpTestStub_; @@ -470,7 +442,7 @@ class JitCompartment ScriptSet; ScriptSet *activeParallelEntryScripts_; - JitCode *generateStringConcatStub(JSContext *cx, ExecutionMode mode); + JitCode *generateStringConcatStub(JSContext *cx); JitCode *generateRegExpExecStub(JSContext *cx); JitCode *generateRegExpTestStub(JSContext *cx); @@ -533,12 +505,8 @@ class JitCompartment void mark(JSTracer *trc, JSCompartment *compartment); void sweep(FreeOp *fop, JSCompartment *compartment); - JitCode *stringConcatStubNoBarrier(ExecutionMode mode) const { - switch (mode) { - case SequentialExecution: return stringConcatStub_; - case ParallelExecution: return parallelStringConcatStub_; - default: MOZ_CRASH("No such execution mode"); - } + JitCode *stringConcatStubNoBarrier() const { + return stringConcatStub_; } JitCode *regExpExecStubNoBarrier() const { @@ -566,7 +534,6 @@ class JitCompartment // Called from JSCompartment::discardJitCode(). void InvalidateAll(FreeOp *fop, JS::Zone *zone); -template void FinishInvalidation(FreeOp *fop, JSScript *script); // On windows systems, really large frames need to be incrementally touched. diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 01bbf522fa0b..e40bfb5700e5 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -21,7 +21,6 @@ #include "jit/JitCompartment.h" #include "jit/JitSpewer.h" #include "jit/MacroAssembler.h" -#include "jit/ParallelFunctions.h" #include "jit/PcScriptCache.h" #include "jit/Recover.h" #include "jit/Safepoints.h" @@ -872,29 +871,6 @@ HandleException(ResumeFromException *rfe) rfe->stackPointer = iter.fp(); } -void -HandleParallelFailure(ResumeFromException *rfe) -{ - parallel::Spew(parallel::SpewBailouts, "Bailing from VM reentry"); - - ForkJoinContext *cx = ForkJoinContext::current(); - JitFrameIterator frameIter(cx); - - // Advance to the first Ion frame so we can pull out the BailoutKind. - while (!frameIter.isIonJS()) - ++frameIter; - SnapshotIterator snapIter(frameIter); - - cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind()); - while (!frameIter.done()) - ++frameIter; - - rfe->kind = ResumeFromException::RESUME_ENTRY_FRAME; - - MOZ_ASSERT(frameIter.done()); - rfe->stackPointer = frameIter.fp(); -} - void EnsureExitFrame(CommonFrameLayout *frame) { diff --git a/js/src/jit/JitFrames.h b/js/src/jit/JitFrames.h index 687c22dfa392..80df81715063 100644 --- a/js/src/jit/JitFrames.h +++ b/js/src/jit/JitFrames.h @@ -269,7 +269,6 @@ struct ResumeFromException }; void HandleException(ResumeFromException *rfe); -void HandleParallelFailure(ResumeFromException *rfe); void EnsureExitFrame(CommonFrameLayout *frame); diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 3420a8763296..2d95cc213ff4 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -801,74 +801,6 @@ class LNewTypedObject : public LInstructionHelper<1, 0, 1> } }; -class LNewPar : public LInstructionHelper<1, 1, 2> -{ - public: - LIR_HEADER(NewPar); - - LNewPar(const LAllocation &cx, const LDefinition &temp1, const LDefinition &temp2) { - setOperand(0, cx); - setTemp(0, temp1); - setTemp(1, temp2); - } - - MNewPar *mir() const { - return mir_->toNewPar(); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const LDefinition *getTemp0() { - return getTemp(0); - } - - const LDefinition *getTemp1() { - return getTemp(1); - } -}; - -class LNewDenseArrayPar : public LInstructionHelper<1, 2, 3> -{ - public: - LIR_HEADER(NewDenseArrayPar); - - LNewDenseArrayPar(const LAllocation &cx, const LAllocation &length, - const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) - { - setOperand(0, cx); - setOperand(1, length); - setTemp(0, temp1); - setTemp(1, temp2); - setTemp(2, temp3); - } - - MNewDenseArrayPar *mir() const { - return mir_->toNewDenseArrayPar(); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const LAllocation *length() { - return getOperand(1); - } - - const LDefinition *getTemp0() { - return getTemp(0); - } - - const LDefinition *getTemp1() { - return getTemp(1); - } - - const LDefinition *getTemp2() { - return getTemp(2); - } -}; - // Allocates a new DeclEnvObject. // // This instruction generates two possible instruction sets: @@ -945,40 +877,6 @@ class LNewSingletonCallObject : public LInstructionHelper<1, 0, 1> } }; -class LNewCallObjectPar : public LInstructionHelper<1, 1, 2> -{ - LNewCallObjectPar(const LAllocation &cx, const LDefinition &temp1, const LDefinition &temp2) { - setOperand(0, cx); - setTemp(0, temp1); - setTemp(1, temp2); - } - -public: - LIR_HEADER(NewCallObjectPar); - - static LNewCallObjectPar *New(TempAllocator &alloc, const LAllocation &cx, - const LDefinition &temp1, const LDefinition &temp2) - { - return new(alloc) LNewCallObjectPar(cx, temp1, temp2); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const MNewCallObjectPar *mir() const { - return mir_->toNewCallObjectPar(); - } - - const LDefinition *getTemp0() { - return getTemp(0); - } - - const LDefinition *getTemp1() { - return getTemp(1); - } -}; - class LNewDerivedTypedObject : public LCallInstructionHelper<1, 3, 0> { public: @@ -1148,29 +1046,6 @@ class LCheckOverRecursed : public LInstructionHelper<0, 0, 0> } }; -class LCheckOverRecursedPar : public LInstructionHelper<0, 1, 1> -{ - public: - LIR_HEADER(CheckOverRecursedPar); - - LCheckOverRecursedPar(const LAllocation &cx, const LDefinition &tempReg) { - setOperand(0, cx); - setTemp(0, tempReg); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const LDefinition *getTempReg() { - return getTemp(0); - } - - MCheckOverRecursedPar *mir() const { - return mir_->toCheckOverRecursedPar(); - } -}; - class LAsmJSInterruptCheck : public LInstructionHelper<0, 0, 0> { Label *interruptExit_; @@ -1228,28 +1103,6 @@ class LInterruptCheckImplicit : public LInstructionHelper<0, 0, 0> } }; -class LInterruptCheckPar : public LInstructionHelper<0, 1, 1> -{ - public: - LIR_HEADER(InterruptCheckPar); - - LInterruptCheckPar(const LAllocation &cx, const LDefinition &tempReg) { - setOperand(0, cx); - setTemp(0, tempReg); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const LDefinition *getTempReg() { - return getTemp(0); - } - MInterruptCheckPar *mir() const { - return mir_->toInterruptCheckPar(); - } -}; - class LDefVar : public LCallInstructionHelper<0, 1, 0> { public: @@ -3379,47 +3232,6 @@ class LConcat : public LInstructionHelper<1, 2, 5> } }; -class LConcatPar : public LInstructionHelper<1, 3, 4> -{ - public: - LIR_HEADER(ConcatPar) - - LConcatPar(const LAllocation &cx, const LAllocation &lhs, const LAllocation &rhs, - const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3, - const LDefinition &temp4) - { - setOperand(0, cx); - setOperand(1, lhs); - setOperand(2, rhs); - setTemp(0, temp1); - setTemp(1, temp2); - setTemp(2, temp3); - setTemp(3, temp4); - } - - const LAllocation *forkJoinContext() { - return this->getOperand(0); - } - const LAllocation *lhs() { - return this->getOperand(1); - } - const LAllocation *rhs() { - return this->getOperand(2); - } - const LDefinition *temp1() { - return this->getTemp(0); - } - const LDefinition *temp2() { - return this->getTemp(1); - } - const LDefinition *temp3() { - return this->getTemp(2); - } - const LDefinition *temp4() { - return this->getTemp(3); - } -}; - // Get uint16 character code from a string. class LCharCodeAt : public LInstructionHelper<1, 2, 0> { @@ -4091,36 +3903,6 @@ class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1> } }; -class LLambdaPar : public LInstructionHelper<1, 2, 2> -{ - public: - LIR_HEADER(LambdaPar); - - LLambdaPar(const LAllocation &cx, const LAllocation &scopeChain, - const LDefinition &temp1, const LDefinition &temp2) - { - setOperand(0, cx); - setOperand(1, scopeChain); - setTemp(0, temp1); - setTemp(1, temp2); - } - const LAllocation *forkJoinContext() { - return getOperand(0); - } - const LAllocation *scopeChain() { - return getOperand(1); - } - const MLambdaPar *mir() const { - return mir_->toLambdaPar(); - } - const LDefinition *getTemp0() { - return getTemp(0); - } - const LDefinition *getTemp1() { - return getTemp(1); - } -}; - // Load the "slots" member out of a JSObject. // Input: JSObject pointer // Output: slots pointer @@ -5303,17 +5085,13 @@ class LGetPropertyCacheV : public LInstructionHelper // Patchable jump to stubs generated for a GetProperty cache, which loads a // value of a known type, possibly into an FP register. -class LGetPropertyCacheT : public LInstructionHelper<1, 1, 1> +class LGetPropertyCacheT : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(GetPropertyCacheT) - LGetPropertyCacheT(const LAllocation &object, const LDefinition &temp) { + explicit LGetPropertyCacheT(const LAllocation &object) { setOperand(0, object); - setTemp(0, temp); - } - const LDefinition *temp() { - return getTemp(0); } const MGetPropertyCache *mir() const { return mir_->toGetPropertyCache(); @@ -5441,16 +5219,14 @@ class LGetElementCacheV : public LInstructionHelper +class LGetElementCacheT : public LInstructionHelper<1, 2, 0> { public: LIR_HEADER(GetElementCacheT) - LGetElementCacheT(const LAllocation &object, const LAllocation &index, - const LDefinition &temp) { + LGetElementCacheT(const LAllocation &object, const LAllocation &index) { setOperand(0, object); setOperand(1, index); - setTemp(0, temp); } const LAllocation *object() { return getOperand(0); @@ -5461,9 +5237,6 @@ class LGetElementCacheT : public LInstructionHelper<1, 2, 1> const LDefinition *output() { return getDef(0); } - const LDefinition *temp() { - return getTemp(0); - } const MGetElementCache *mir() const { return mir_->toGetElementCache(); } @@ -5678,52 +5451,6 @@ class LFunctionEnvironment : public LInstructionHelper<1, 1, 0> } }; -class LForkJoinContext : public LCallInstructionHelper<1, 0, 1> -{ - public: - LIR_HEADER(ForkJoinContext); - - explicit LForkJoinContext(const LDefinition &temp1) { - setTemp(0, temp1); - } - - const LDefinition *getTempReg() { - return getTemp(0); - } -}; - -class LForkJoinGetSlice : public LInstructionHelper<1, 1, 4> -{ - public: - LIR_HEADER(ForkJoinGetSlice); - - LForkJoinGetSlice(const LAllocation &cx, - const LDefinition &temp1, const LDefinition &temp2, - const LDefinition &temp3, const LDefinition &temp4) { - setOperand(0, cx); - setTemp(0, temp1); - setTemp(1, temp2); - setTemp(2, temp3); - setTemp(3, temp4); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - const LDefinition *temp1() { - return getTemp(0); - } - const LDefinition *temp2() { - return getTemp(1); - } - const LDefinition *temp3() { - return getTemp(2); - } - const LDefinition *temp4() { - return getTemp(3); - } -}; - class LCallGetProperty : public LCallInstructionHelper { public: @@ -5821,16 +5548,14 @@ class LCallDeleteElement : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> // Patchable jump to stubs generated for a SetProperty cache, which stores a // boxed value. -class LSetPropertyCacheV : public LInstructionHelper<0, 1 + BOX_PIECES, 2> +class LSetPropertyCacheV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> { public: LIR_HEADER(SetPropertyCacheV) - LSetPropertyCacheV(const LAllocation &object, const LDefinition &slots, - const LDefinition &temp) { + LSetPropertyCacheV(const LAllocation &object, const LDefinition &slots) { setOperand(0, object); setTemp(0, slots); - setTemp(1, temp); } static const size_t Value = 1; @@ -5838,15 +5563,11 @@ class LSetPropertyCacheV : public LInstructionHelper<0, 1 + BOX_PIECES, 2> const MSetPropertyCache *mir() const { return mir_->toSetPropertyCache(); } - - const LDefinition *tempForDispatchCache() { - return getTemp(1); - } }; // Patchable jump to stubs generated for a SetProperty cache, which stores a // value of a known type. -class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2> +class LSetPropertyCacheT : public LInstructionHelper<0, 2, 1> { MIRType valueType_; @@ -5854,14 +5575,12 @@ class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2> LIR_HEADER(SetPropertyCacheT) LSetPropertyCacheT(const LAllocation &object, const LDefinition &slots, - const LAllocation &value, const LDefinition &temp, - MIRType valueType) + const LAllocation &value, MIRType valueType) : valueType_(valueType) { setOperand(0, object); setOperand(1, value); setTemp(0, slots); - setTemp(1, temp); } const MSetPropertyCache *mir() const { @@ -5873,10 +5592,6 @@ class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2> const char *extraName() const { return StringFromMIRType(valueType_); } - - const LDefinition *tempForDispatchCache() { - return getTemp(1); - } }; class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 4> @@ -6184,55 +5899,6 @@ class LRest : public LCallInstructionHelper<1, 1, 3> } }; -class LRestPar : public LInstructionHelper<1, 2, 3> -{ - public: - LIR_HEADER(RestPar); - - LRestPar(const LAllocation &cx, const LAllocation &numActuals, - const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) - { - setOperand(0, cx); - setOperand(1, numActuals); - setTemp(0, temp1); - setTemp(1, temp2); - setTemp(2, temp3); - } - const LAllocation *forkJoinContext() { - return getOperand(0); - } - const LAllocation *numActuals() { - return getOperand(1); - } - MRestPar *mir() const { - return mir_->toRestPar(); - } -}; - -class LGuardThreadExclusive : public LCallInstructionHelper<0, 2, 1> -{ - public: - LIR_HEADER(GuardThreadExclusive); - - LGuardThreadExclusive(const LAllocation &cx, const LAllocation &object, const LDefinition &temp1) { - setOperand(0, cx); - setOperand(1, object); - setTemp(0, temp1); - } - - const LAllocation *forkJoinContext() { - return getOperand(0); - } - - const LAllocation *object() { - return getOperand(1); - } - - const LDefinition *getTempReg() { - return getTemp(0); - } -}; - class LGuardShapePolymorphic : public LInstructionHelper<0, 1, 1> { public: diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 52dee477d12e..5551d767f6d3 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -569,8 +569,6 @@ class LDefinition return LDefinition::SLOTS; case MIRType_Pointer: return LDefinition::GENERAL; - case MIRType_ForkJoinContext: - return LDefinition::GENERAL; case MIRType_Int32x4: return LDefinition::INT32X4; case MIRType_Float32x4: diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 9b09b530db57..277bd758b4ea 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -55,9 +55,6 @@ _(NewCallObject) \ _(NewSingletonCallObject) \ _(NewStringObject) \ - _(NewPar) \ - _(NewDenseArrayPar) \ - _(NewCallObjectPar) \ _(NewDerivedTypedObject) \ _(InitElem) \ _(InitElemGetterSetter) \ @@ -65,7 +62,6 @@ _(InitProp) \ _(InitPropGetterSetter) \ _(CheckOverRecursed) \ - _(CheckOverRecursedPar) \ _(DefVar) \ _(DefFun) \ _(CallKnown) \ @@ -156,7 +152,6 @@ _(ModD) \ _(BinaryV) \ _(Concat) \ - _(ConcatPar) \ _(CharCodeAt) \ _(FromCharCode) \ _(StringSplit) \ @@ -193,7 +188,6 @@ _(Lambda) \ _(LambdaArrow) \ _(LambdaForSingleton) \ - _(LambdaPar) \ _(Slots) \ _(Elements) \ _(ConvertElementsToDoubles) \ @@ -208,7 +202,6 @@ _(GuardObjectType) \ _(GuardObjectIdentity) \ _(GuardClass) \ - _(GuardThreadExclusive) \ _(TypeBarrierV) \ _(TypeBarrierO) \ _(MonitorTypes) \ @@ -252,8 +245,6 @@ _(StoreFixedSlotV) \ _(StoreFixedSlotT) \ _(FunctionEnvironment) \ - _(ForkJoinContext) \ - _(ForkJoinGetSlice) \ _(GetPropertyCacheV) \ _(GetPropertyCacheT) \ _(GetPropertyPolymorphicV) \ @@ -297,7 +288,6 @@ _(SetFrameArgumentV) \ _(RunOncePrologue) \ _(Rest) \ - _(RestPar) \ _(TypeOfV) \ _(ToIdV) \ _(Floor) \ @@ -336,7 +326,6 @@ _(AsmJSCall) \ _(AsmJSCompareExchangeHeap) \ _(AsmJSAtomicBinopHeap) \ - _(InterruptCheckPar) \ _(RecompileCheck) \ _(MemoryBarrier) \ _(AssertRangeI) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index f8bce867b79c..de71f32fc165 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -130,15 +130,6 @@ LIRGenerator::visitCheckOverRecursed(MCheckOverRecursed *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitCheckOverRecursedPar(MCheckOverRecursedPar *ins) -{ - LCheckOverRecursedPar *lir = - new(alloc()) LCheckOverRecursedPar(useRegister(ins->forkJoinContext()), temp()); - add(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitDefVar(MDefVar *ins) { @@ -242,15 +233,6 @@ LIRGenerator::visitNewDerivedTypedObject(MNewDerivedTypedObject *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitNewCallObjectPar(MNewCallObjectPar *ins) -{ - const LAllocation &parThreadContext = useRegister(ins->forkJoinContext()); - LNewCallObjectPar *lir = LNewCallObjectPar::New(alloc(), parThreadContext, temp(), temp()); - define(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitNewStringObject(MNewStringObject *ins) { @@ -1599,28 +1581,6 @@ LIRGenerator::visitConcat(MConcat *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitConcatPar(MConcatPar *ins) -{ - MDefinition *cx = ins->forkJoinContext(); - MDefinition *lhs = ins->lhs(); - MDefinition *rhs = ins->rhs(); - - MOZ_ASSERT(lhs->type() == MIRType_String); - MOZ_ASSERT(rhs->type() == MIRType_String); - MOZ_ASSERT(ins->type() == MIRType_String); - - LConcatPar *lir = new(alloc()) LConcatPar(useFixed(cx, CallTempReg4), - useFixedAtStart(lhs, CallTempReg0), - useFixedAtStart(rhs, CallTempReg1), - tempFixed(CallTempReg0), - tempFixed(CallTempReg1), - tempFixed(CallTempReg2), - tempFixed(CallTempReg3)); - defineFixed(lir, ins, LAllocation(AnyRegister(CallTempReg5))); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitCharCodeAt(MCharCodeAt *ins) { @@ -2171,18 +2131,6 @@ LIRGenerator::visitLambdaArrow(MLambdaArrow *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitLambdaPar(MLambdaPar *ins) -{ - MOZ_ASSERT(!ins->info().singletonType); - MOZ_ASSERT(!ins->info().useNewTypeForClone); - LLambdaPar *lir = new(alloc()) LLambdaPar(useRegister(ins->forkJoinContext()), - useRegister(ins->scopeChain()), - temp(), temp()); - define(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitSlots(MSlots *ins) { @@ -2253,29 +2201,6 @@ LIRGenerator::visitFunctionEnvironment(MFunctionEnvironment *ins) define(new(alloc()) LFunctionEnvironment(useRegisterAtStart(ins->function())), ins); } -void -LIRGenerator::visitForkJoinContext(MForkJoinContext *ins) -{ - LForkJoinContext *lir = new(alloc()) LForkJoinContext(tempFixed(CallTempReg0)); - defineReturn(lir, ins); -} - -void -LIRGenerator::visitGuardThreadExclusive(MGuardThreadExclusive *ins) -{ - // FIXME (Bug 956281) -- For now, we always generate the most - // general form of write guard check. we could employ TI feedback - // to optimize this if we know that the object being tested is a - // typed object or know that it is definitely NOT a typed object. - LGuardThreadExclusive *lir = - new(alloc()) LGuardThreadExclusive(useFixed(ins->forkJoinContext(), CallTempReg0), - useFixed(ins->object(), CallTempReg1), - tempFixed(CallTempReg2)); - lir->setMir(ins); - assignSnapshot(lir, Bailout_GuardThreadExclusive); - add(lir, ins); -} - void LIRGenerator::visitInterruptCheck(MInterruptCheck *ins) { @@ -2299,40 +2224,6 @@ LIRGenerator::visitAsmJSInterruptCheck(MAsmJSInterruptCheck *ins) add(lir, ins); } -void -LIRGenerator::visitInterruptCheckPar(MInterruptCheckPar *ins) -{ - LInterruptCheckPar *lir = - new(alloc()) LInterruptCheckPar(useRegister(ins->forkJoinContext()), temp()); - add(lir, ins); - assignSafepoint(lir, ins); -} - -void -LIRGenerator::visitNewPar(MNewPar *ins) -{ - LNewPar *lir = new(alloc()) LNewPar(useRegister(ins->forkJoinContext()), temp(), temp()); - define(lir, ins); - assignSafepoint(lir, ins); -} - -void -LIRGenerator::visitNewDenseArrayPar(MNewDenseArrayPar *ins) -{ - MOZ_ASSERT(ins->forkJoinContext()->type() == MIRType_ForkJoinContext); - MOZ_ASSERT(ins->length()->type() == MIRType_Int32); - MOZ_ASSERT(ins->type() == MIRType_Object); - - LNewDenseArrayPar *lir = - new(alloc()) LNewDenseArrayPar(useRegister(ins->forkJoinContext()), - useRegister(ins->length()), - temp(), - temp(), - temp()); - define(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitStoreSlot(MStoreSlot *ins) { @@ -3155,8 +3046,7 @@ LIRGenerator::visitGetPropertyCache(MGetPropertyCache *ins) defineBox(lir, ins); assignSafepoint(lir, ins); } else { - LGetPropertyCacheT *lir = new(alloc()) LGetPropertyCacheT(useRegister(ins->object()), - tempForDispatchCache(ins->type())); + LGetPropertyCacheT *lir = new(alloc()) LGetPropertyCacheT(useRegister(ins->object())); define(lir, ins); assignSafepoint(lir, ins); } @@ -3216,8 +3106,7 @@ LIRGenerator::visitGetElementCache(MGetElementCache *ins) } else { MOZ_ASSERT(ins->index()->type() == MIRType_Int32); LGetElementCacheT *lir = new(alloc()) LGetElementCacheT(useRegister(ins->object()), - useRegister(ins->index()), - tempForDispatchCache(ins->type())); + useRegister(ins->index())); define(lir, ins); assignSafepoint(lir, ins); } @@ -3373,15 +3262,14 @@ LIRGenerator::visitSetPropertyCache(MSetPropertyCache *ins) { LUse obj = useRegisterAtStart(ins->object()); LDefinition slots = tempCopy(ins->object(), 0); - LDefinition dispatchTemp = tempForDispatchCache(); LInstruction *lir; if (ins->value()->type() == MIRType_Value) { - lir = new(alloc()) LSetPropertyCacheV(obj, slots, dispatchTemp); + lir = new(alloc()) LSetPropertyCacheV(obj, slots); useBox(lir, LSetPropertyCacheV::Value, ins->value()); } else { LAllocation value = useRegisterOrConstant(ins->value()); - lir = new(alloc()) LSetPropertyCacheT(obj, slots, value, dispatchTemp, ins->value()->type()); + lir = new(alloc()) LSetPropertyCacheT(obj, slots, value, ins->value()->type()); } add(lir, ins); @@ -3543,20 +3431,6 @@ LIRGenerator::visitRest(MRest *ins) assignSafepoint(lir, ins); } -void -LIRGenerator::visitRestPar(MRestPar *ins) -{ - MOZ_ASSERT(ins->numActuals()->type() == MIRType_Int32); - - LRestPar *lir = new(alloc()) LRestPar(useRegister(ins->forkJoinContext()), - useRegister(ins->numActuals()), - temp(), - temp(), - temp()); - define(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitThrow(MThrow *ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index b8432ffcb374..a829f0826a8a 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -80,16 +80,12 @@ class LIRGenerator : public LIRGeneratorSpecific void visitNewRunOnceCallObject(MNewRunOnceCallObject *ins); void visitNewStringObject(MNewStringObject *ins); void visitNewDerivedTypedObject(MNewDerivedTypedObject *ins); - void visitNewPar(MNewPar *ins); - void visitNewCallObjectPar(MNewCallObjectPar *ins); - void visitNewDenseArrayPar(MNewDenseArrayPar *ins); void visitInitElem(MInitElem *ins); void visitInitElemGetterSetter(MInitElemGetterSetter *ins); void visitMutateProto(MMutateProto *ins); void visitInitProp(MInitProp *ins); void visitInitPropGetterSetter(MInitPropGetterSetter *ins); void visitCheckOverRecursed(MCheckOverRecursed *ins); - void visitCheckOverRecursedPar(MCheckOverRecursedPar *ins); void visitDefVar(MDefVar *ins); void visitDefFun(MDefFun *ins); void visitCreateThisWithTemplate(MCreateThisWithTemplate *ins); @@ -142,7 +138,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitDiv(MDiv *ins); void visitMod(MMod *ins); void visitConcat(MConcat *ins); - void visitConcatPar(MConcatPar *ins); void visitCharCodeAt(MCharCodeAt *ins); void visitFromCharCode(MFromCharCode *ins); void visitStringSplit(MStringSplit *ins); @@ -167,7 +162,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitStringReplace(MStringReplace *ins); void visitLambda(MLambda *ins); void visitLambdaArrow(MLambdaArrow *ins); - void visitLambdaPar(MLambdaPar *ins); void visitSlots(MSlots *ins); void visitElements(MElements *ins); void visitConstantElements(MConstantElements *ins); @@ -176,11 +170,8 @@ class LIRGenerator : public LIRGeneratorSpecific void visitMaybeCopyElementsForWrite(MMaybeCopyElementsForWrite *ins); void visitLoadSlot(MLoadSlot *ins); void visitFunctionEnvironment(MFunctionEnvironment *ins); - void visitForkJoinContext(MForkJoinContext *ins); - void visitGuardThreadExclusive(MGuardThreadExclusive *ins); void visitInterruptCheck(MInterruptCheck *ins); void visitAsmJSInterruptCheck(MAsmJSInterruptCheck *ins); - void visitInterruptCheckPar(MInterruptCheckPar *ins); void visitStoreSlot(MStoreSlot *ins); void visitFilterTypeSet(MFilterTypeSet *ins); void visitTypeBarrier(MTypeBarrier *ins); @@ -252,7 +243,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitSetFrameArgument(MSetFrameArgument *ins); void visitRunOncePrologue(MRunOncePrologue *ins); void visitRest(MRest *ins); - void visitRestPar(MRestPar *ins); void visitThrow(MThrow *ins); void visitIn(MIn *ins); void visitInArray(MInArray *ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 08b0184596ba..d9571c996253 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -166,8 +166,6 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) // Array intrinsics. if (native == intrinsic_UnsafePutElements) return inlineUnsafePutElements(callInfo); - if (native == intrinsic_NewDenseArray) - return inlineNewDenseArray(callInfo); // Slot intrinsics. if (native == intrinsic_UnsafeSetReservedSlot) @@ -183,13 +181,6 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) if (native == intrinsic_UnsafeGetBooleanFromReservedSlot) return inlineUnsafeGetReservedSlot(callInfo, MIRType_Boolean); - // Parallel intrinsics. - if (native == intrinsic_ShouldForceSequential || - native == intrinsic_InParallelSection) - return inlineForceSequentialOrInParallelSection(callInfo); - if (native == intrinsic_ForkJoinGetSlice) - return inlineForkJoinGetSlice(callInfo); - // Utility intrinsics. if (native == intrinsic_IsCallable) return inlineIsCallable(callInfo); @@ -242,8 +233,6 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) return inlineSetTypedObjectOffset(callInfo); // Testing Functions - if (native == testingFunc_inParallelSection) - return inlineForceSequentialOrInParallelSection(callInfo); if (native == testingFunc_bailout) return inlineBailout(callInfo); if (native == testingFunc_assertFloat32) @@ -1776,129 +1765,6 @@ IonBuilder::inlineUnsafeSetTypedObjectArrayElement(CallInfo &callInfo, return true; } -IonBuilder::InliningStatus -IonBuilder::inlineForceSequentialOrInParallelSection(CallInfo &callInfo) -{ - if (callInfo.constructing()) - return InliningStatus_NotInlined; - - ExecutionMode executionMode = info().executionMode(); - switch (executionMode) { - case ParallelExecution: { - // During Parallel Exec, we always force sequential, so - // replace with true. This permits UCE to eliminate the - // entire path as dead, which is important. - callInfo.setImplicitlyUsedUnchecked(); - MConstant *ins = MConstant::New(alloc(), BooleanValue(true)); - current->add(ins); - current->push(ins); - return InliningStatus_Inlined; - } - - default: - // In sequential mode, leave as is, because we'd have to - // access the "in warmup" flag of the runtime. - return InliningStatus_NotInlined; - } - - MOZ_CRASH("Invalid execution mode"); -} - -IonBuilder::InliningStatus -IonBuilder::inlineForkJoinGetSlice(CallInfo &callInfo) -{ - if (info().executionMode() != ParallelExecution) - return InliningStatus_NotInlined; - - // Assert the way the function is used instead of testing, as it is a - // self-hosted function which must be used in a particular fashion. - MOZ_ASSERT(callInfo.argc() == 1 && !callInfo.constructing()); - MOZ_ASSERT(callInfo.getArg(0)->type() == MIRType_Int32); - - // Test this, as we might have not executed the native despite knowing the - // target here. - if (getInlineReturnType() != MIRType_Int32) - return InliningStatus_NotInlined; - - callInfo.setImplicitlyUsedUnchecked(); - - switch (info().executionMode()) { - case ParallelExecution: - if (LIRGenerator::allowInlineForkJoinGetSlice()) { - MForkJoinGetSlice *getSlice = MForkJoinGetSlice::New(alloc(), - graph().forkJoinContext()); - current->add(getSlice); - current->push(getSlice); - return InliningStatus_Inlined; - } - return InliningStatus_NotInlined; - - default: - // ForkJoinGetSlice acts as identity for sequential execution. - current->push(callInfo.getArg(0)); - return InliningStatus_Inlined; - } - - MOZ_CRASH("Invalid execution mode"); -} - -IonBuilder::InliningStatus -IonBuilder::inlineNewDenseArray(CallInfo &callInfo) -{ - if (callInfo.constructing() || callInfo.argc() != 1) - return InliningStatus_NotInlined; - - // For now, in seq. mode we just call the C function. In - // par. mode we use inlined MIR. - ExecutionMode executionMode = info().executionMode(); - switch (executionMode) { - case ParallelExecution: - return inlineNewDenseArrayForParallelExecution(callInfo); - default: - return inlineNewDenseArrayForSequentialExecution(callInfo); - } - - MOZ_CRASH("unknown ExecutionMode"); -} - -IonBuilder::InliningStatus -IonBuilder::inlineNewDenseArrayForSequentialExecution(CallInfo &callInfo) -{ - // not yet implemented; in seq. mode the C function is not so bad - return InliningStatus_NotInlined; -} - -IonBuilder::InliningStatus -IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo) -{ - // Create the new parallel array object. Parallel arrays have specially - // constructed type objects, so we can only perform the inlining if we - // already have one of these type objects. - types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet(); - if (returnTypes->getKnownMIRType() != MIRType_Object) - return InliningStatus_NotInlined; - if (returnTypes->unknownObject() || returnTypes->getObjectCount() != 1) - return InliningStatus_NotInlined; - if (callInfo.getArg(0)->type() != MIRType_Int32) - return InliningStatus_NotInlined; - types::TypeObject *typeObject = returnTypes->getTypeObject(0); - - NativeObject *templateObject = inspector->getTemplateObjectForNative(pc, intrinsic_NewDenseArray); - if (!templateObject || templateObject->type() != typeObject) - return InliningStatus_NotInlined; - - callInfo.setImplicitlyUsedUnchecked(); - - MNewDenseArrayPar *newObject = MNewDenseArrayPar::New(alloc(), - graph().forkJoinContext(), - callInfo.getArg(0), - &templateObject->as()); - current->add(newObject); - current->push(newObject); - - return InliningStatus_Inlined; -} - IonBuilder::InliningStatus IonBuilder::inlineHasClass(CallInfo &callInfo, const Class *clasp1, const Class *clasp2, diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index c95713e6d8dd..177505d73371 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2271,17 +2271,6 @@ MBinaryArithInstruction::inferFallback(BaselineInspector *inspector, return; } - // In parallel execution, for now anyhow, we *only* support adding - // and manipulating numbers (not strings or objects). So no - // matter what we can specialize to double...if the result ought - // to have been something else, we'll fail in the various type - // guards that get inserted later. - if (block()->info().executionMode() == ParallelExecution) { - specialization_ = MIRType_Double; - setResultType(MIRType_Double); - return; - } - // If we can't specialize because we have no type information at all for // the lhs or rhs, mark the binary instruction as having no possible types // either to avoid degrading subsequent analysis. diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index c54355046b75..bc9173304572 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -2836,40 +2836,6 @@ class MNewObject } }; -// Could be allocating either a new array or a new object. -class MNewPar - : public MUnaryInstruction, - public NoTypePolicy::Data -{ - AlwaysTenuredNativeObject templateObject_; - - MNewPar(MDefinition *cx, NativeObject *templateObject) - : MUnaryInstruction(cx), - templateObject_(templateObject) - { - setResultType(MIRType_Object); - } - - public: - INSTRUCTION_HEADER(NewPar); - - static MNewPar *New(TempAllocator &alloc, MDefinition *cx, NativeObject *templateObject) { - return new(alloc) MNewPar(cx, templateObject); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - - NativeObject *templateObject() const { - return templateObject_; - } - - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - class MNewTypedObject : public MNullaryInstruction { AlwaysTenured templateObject_; @@ -6075,46 +6041,6 @@ class MConcat ALLOW_CLONE(MConcat) }; -class MConcatPar - : public MTernaryInstruction, - public NoTypePolicy::Data -{ - MConcatPar(MDefinition *cx, MDefinition *left, MDefinition *right) - : MTernaryInstruction(cx, left, right) - { - // Type analysis has already run, before replacing with the parallel - // variant. - MOZ_ASSERT(left->type() == MIRType_String && right->type() == MIRType_String); - - setMovable(); - setResultType(MIRType_String); - } - - public: - INSTRUCTION_HEADER(ConcatPar) - - static MConcatPar *New(TempAllocator &alloc, MDefinition *cx, MConcat *concat) { - return new(alloc) MConcatPar(cx, concat->lhs(), concat->rhs()); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - MDefinition *lhs() const { - return getOperand(1); - } - MDefinition *rhs() const { - return getOperand(2); - } - - bool congruentTo(const MDefinition *ins) const { - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - class MCharCodeAt : public MBinaryInstruction, public MixPolicy, IntPolicy<1> >::Data @@ -6628,59 +6554,6 @@ class MCheckOverRecursed } }; -// Check the current frame for over-recursion past the global stack limit. -// Uses the per-thread recursion limit. -class MCheckOverRecursedPar - : public MUnaryInstruction, - public NoTypePolicy::Data -{ - explicit MCheckOverRecursedPar(MDefinition *cx) - : MUnaryInstruction(cx) - { - setResultType(MIRType_None); - setGuard(); - setMovable(); - } - - public: - INSTRUCTION_HEADER(CheckOverRecursedPar); - - static MCheckOverRecursedPar *New(TempAllocator &alloc, MDefinition *cx) { - return new(alloc) MCheckOverRecursedPar(cx); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } -}; - -// Check for an interrupt (or rendezvous) in parallel mode. -class MInterruptCheckPar - : public MUnaryInstruction, - public NoTypePolicy::Data -{ - explicit MInterruptCheckPar(MDefinition *cx) - : MUnaryInstruction(cx) - { - setResultType(MIRType_None); - setGuard(); - } - - public: - INSTRUCTION_HEADER(InterruptCheckPar); - - static MInterruptCheckPar *New(TempAllocator &alloc, MDefinition *cx) { - return new(alloc) MInterruptCheckPar(cx); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - // Check whether we need to fire the interrupt handler. class MInterruptCheck : public MNullaryInstruction { @@ -7196,43 +7069,6 @@ class MLambdaArrow } }; -class MLambdaPar - : public MBinaryInstruction, - public SingleObjectPolicy::Data -{ - LambdaFunctionInfo info_; - - MLambdaPar(MDefinition *cx, MDefinition *scopeChain, JSFunction *fun, - types::TemporaryTypeSet *resultTypes, const LambdaFunctionInfo &info) - : MBinaryInstruction(cx, scopeChain), info_(info) - { - MOZ_ASSERT(!info_.singletonType); - MOZ_ASSERT(!info_.useNewTypeForClone); - setResultType(MIRType_Object); - setResultTypeSet(resultTypes); - } - - public: - INSTRUCTION_HEADER(LambdaPar); - - static MLambdaPar *New(TempAllocator &alloc, MDefinition *cx, MLambda *lambda) { - return new(alloc) MLambdaPar(cx, lambda->scopeChain(), lambda->info().fun, - lambda->resultTypeSet(), lambda->info()); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - - MDefinition *scopeChain() const { - return getOperand(1); - } - - const LambdaFunctionInfo &info() const { - return info_; - } -}; - // Returns obj->slots. class MSlots : public MUnaryInstruction, @@ -10002,63 +9838,6 @@ class MFunctionEnvironment } }; -// Loads the current js::ForkJoinContext*. -// Only applicable in ParallelExecution. -class MForkJoinContext - : public MNullaryInstruction -{ - MForkJoinContext() - : MNullaryInstruction() - { - setResultType(MIRType_ForkJoinContext); - } - - public: - INSTRUCTION_HEADER(ForkJoinContext); - - static MForkJoinContext *New(TempAllocator &alloc) { - return new(alloc) MForkJoinContext(); - } - - AliasSet getAliasSet() const { - // Indicate that this instruction reads nothing, stores nothing. - // (For all intents and purposes) - return AliasSet::None(); - } - - bool possiblyCalls() const { - return true; - } -}; - -// Calls the ForkJoinGetSlice stub, used for inlining the eponymous intrinsic. -// Only applicable in ParallelExecution. -class MForkJoinGetSlice - : public MUnaryInstruction, - public NoTypePolicy::Data -{ - explicit MForkJoinGetSlice(MDefinition *cx) - : MUnaryInstruction(cx) - { - setResultType(MIRType_Int32); - } - - public: - INSTRUCTION_HEADER(ForkJoinGetSlice); - - static MForkJoinGetSlice *New(TempAllocator &alloc, MDefinition *cx) { - return new(alloc) MForkJoinGetSlice(cx); - } - - MDefinition *forkJoinContext() { - return getOperand(0); - } - - bool possiblyCalls() const { - return true; - } -}; - // Store to vp[slot] (slots that are not inline in an object). class MStoreSlot : public MBinaryInstruction, @@ -11323,82 +11102,6 @@ class MRest } }; -class MRestPar - : public MBinaryInstruction, - public MRestCommon, - public IntPolicy<1>::Data -{ - MRestPar(MDefinition *cx, MDefinition *numActuals, unsigned numFormals, - ArrayObject *templateObject, types::TemporaryTypeSet *resultTypes) - : MBinaryInstruction(cx, numActuals), - MRestCommon(numFormals, templateObject) - { - setResultType(MIRType_Object); - setResultTypeSet(resultTypes); - } - - public: - INSTRUCTION_HEADER(RestPar); - - static MRestPar *New(TempAllocator &alloc, MDefinition *cx, MRest *rest) { - return new(alloc) MRestPar(cx, rest->numActuals(), rest->numFormals(), - rest->templateObject(), rest->resultTypeSet()); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - MDefinition *numActuals() const { - return getOperand(1); - } - - AliasSet getAliasSet() const { - return AliasSet::None(); - } - bool possiblyCalls() const { - return true; - } -}; - -// Guard on an object being safe for writes by current parallel cx. -// Must be either thread-local or else a handle into the destination array. -class MGuardThreadExclusive - : public MBinaryInstruction, - public ObjectPolicy<1>::Data -{ - MGuardThreadExclusive(MDefinition *cx, MDefinition *obj) - : MBinaryInstruction(cx, obj) - { - setResultType(MIRType_None); - setGuard(); - } - - public: - INSTRUCTION_HEADER(GuardThreadExclusive); - - static MGuardThreadExclusive *New(TempAllocator &alloc, MDefinition *cx, MDefinition *obj) { - return new(alloc) MGuardThreadExclusive(cx, obj); - } - MDefinition *forkJoinContext() const { - return getOperand(0); - } - MDefinition *object() const { - return getOperand(1); - } - BailoutKind bailoutKind() const { - return Bailout_GuardThreadExclusive; - } - bool congruentTo(const MDefinition *ins) const { - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const { - return AliasSet::None(); - } - bool possiblyCalls() const { - return true; - } -}; - class MFilterTypeSet : public MUnaryInstruction, public FilterTypeSetPolicy::Data @@ -11646,39 +11349,6 @@ class MNewRunOnceCallObject : public MNewCallObjectBase } }; -class MNewCallObjectPar - : public MUnaryInstruction, - public NoTypePolicy::Data -{ - AlwaysTenured templateObj_; - - MNewCallObjectPar(MDefinition *cx, CallObject *templateObj) - : MUnaryInstruction(cx), - templateObj_(templateObj) - { - setResultType(MIRType_Object); - } - - public: - INSTRUCTION_HEADER(NewCallObjectPar); - - static MNewCallObjectPar *New(TempAllocator &alloc, MDefinition *cx, MNewCallObjectBase *callObj) { - return new(alloc) MNewCallObjectPar(cx, callObj->templateObject()); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - - CallObject *templateObj() const { - return templateObj_; - } - - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - class MNewStringObject : public MUnaryInstruction, public ConvertToStringPolicy<0>::Data @@ -11764,53 +11434,6 @@ class MEnclosingScope : public MLoadFixedSlot } }; -// Creates a dense array of the given length. -// -// Note: the template object should be an *empty* dense array! -class MNewDenseArrayPar - : public MBinaryInstruction, - public NoTypePolicy::Data -{ - AlwaysTenured templateObject_; - - MNewDenseArrayPar(MDefinition *cx, MDefinition *length, ArrayObject *templateObject) - : MBinaryInstruction(cx, length), - templateObject_(templateObject) - { - MOZ_ASSERT(length->type() == MIRType_Int32); - setResultType(MIRType_Object); - } - - public: - INSTRUCTION_HEADER(NewDenseArrayPar); - - static MNewDenseArrayPar *New(TempAllocator &alloc, MDefinition *cx, MDefinition *length, - ArrayObject *templateObject) - { - return new(alloc) MNewDenseArrayPar(cx, length, templateObject); - } - - MDefinition *forkJoinContext() const { - return getOperand(0); - } - - MDefinition *length() const { - return getOperand(1); - } - - ArrayObject *templateObject() const { - return templateObject_; - } - - bool possiblyCalls() const { - return true; - } - - AliasSet getAliasSet() const { - return AliasSet::None(); - } -}; - // This is an element of a spaghetti stack which is used to represent the memory // context which has to be restored in case of a bailout. struct MStoreToRecover : public TempObject, public InlineSpaghettiStackNode diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index b78f8125dc8e..fa76ff987a25 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -202,37 +202,6 @@ MIRGraph::unmarkBlocks() i->unmark(); } -MDefinition * -MIRGraph::forkJoinContext() -{ - // Search the entry block to find a ForkJoinContext instruction. If we do - // not find one, add one after the Start instruction. - // - // Note: the original design used a field in MIRGraph to cache the - // forkJoinContext rather than searching for it again. However, this - // could become out of date due to DCE. Given that we do not generally - // have to search very far to find the ForkJoinContext instruction if it - // exists, and that we don't look for it that often, I opted to simply - // eliminate the cache and search anew each time, so that it is that much - // easier to keep the IR coherent. - nmatsakis - - MBasicBlock *entry = entryBlock(); - MOZ_ASSERT(entry->info().executionMode() == ParallelExecution); - - MInstruction *start = nullptr; - for (MInstructionIterator ins(entry->begin()); ins != entry->end(); ins++) { - if (ins->isForkJoinContext()) - return *ins; - else if (ins->isStart()) - start = *ins; - } - MOZ_ASSERT(start); - - MForkJoinContext *cx = MForkJoinContext::New(alloc()); - entry->insertAfter(start, cx); - return cx; -} - MBasicBlock * MBasicBlock::New(MIRGraph &graph, BytecodeAnalysis *analysis, CompileInfo &info, MBasicBlock *pred, const BytecodeSite *site, Kind kind) @@ -807,7 +776,6 @@ MBasicBlock::safeInsertTop(MDefinition *ins, IgnoreTop ignore) : begin(ins->toInstruction()); while (insertIter->isBeta() || insertIter->isInterruptCheck() || - insertIter->isInterruptCheckPar() || insertIter->isConstant() || (!(ignore & IgnoreRecover) && insertIter->isRecoveredOnBailout())) { diff --git a/js/src/jit/MIRGraph.h b/js/src/jit/MIRGraph.h index 57f2c0a10eb3..1a1dcbb4cbf9 100644 --- a/js/src/jit/MIRGraph.h +++ b/js/src/jit/MIRGraph.h @@ -807,12 +807,6 @@ class MIRGraph hasTryBlock_ = true; } - // The per-thread context. So as not to modify the calling convention for - // parallel code, we obtain the current ForkJoinContext from thread-local - // storage. This helper method will lazilly insert an MForkJoinContext - // instruction in the entry block and return the definition. - MDefinition *forkJoinContext(); - void dump(FILE *fp); void dump(); }; diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 9f5aac8a55a9..6d2a19fd289b 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -91,7 +91,6 @@ namespace jit { _(Div) \ _(Mod) \ _(Concat) \ - _(ConcatPar) \ _(CharCodeAt) \ _(FromCharCode) \ _(StringSplit) \ @@ -247,17 +246,7 @@ namespace jit { _(AsmJSVoidReturn) \ _(AsmJSPassStackArg) \ _(AsmJSCall) \ - _(CheckOverRecursedPar) \ - _(NewCallObjectPar) \ - _(NewPar) \ - _(NewDenseArrayPar) \ _(NewDerivedTypedObject) \ - _(LambdaPar) \ - _(RestPar) \ - _(ForkJoinContext) \ - _(ForkJoinGetSlice) \ - _(GuardThreadExclusive) \ - _(InterruptCheckPar) \ _(RecompileCheck) \ _(MemoryBarrier) \ _(AsmJSCompareExchangeHeap) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index a02db61be18e..f17a5259e969 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -18,9 +18,7 @@ #include "jit/BaselineJIT.h" #include "jit/Lowering.h" #include "jit/MIR.h" -#include "jit/ParallelFunctions.h" #include "js/Conversions.h" -#include "vm/ForkJoin.h" #include "vm/TraceLogging.h" #include "jsgcinlines.h" @@ -835,86 +833,6 @@ MacroAssembler::newGCFatInlineString(Register result, Register temp, Label *fail allocateNonObject(result, temp, js::gc::FINALIZE_FAT_INLINE_STRING, fail); } -void -MacroAssembler::newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2, - gc::AllocKind allocKind, Label *fail) -{ - return newGCTenuredThingPar(result, cx, tempReg1, tempReg2, allocKind, fail); -} - -void -MacroAssembler::newGCTenuredThingPar(Register result, Register cx, - Register tempReg1, Register tempReg2, - gc::AllocKind allocKind, Label *fail) -{ - // Similar to ::newGCThing(), except that it allocates from a custom - // Allocator in the ForkJoinContext*, rather than being hardcoded to the - // compartment allocator. This requires two temporary registers. - // - // Subtle: I wanted to reuse `result` for one of the temporaries, but the - // register allocator was assigning it to the same register as `cx`. - // Then we overwrite that register which messed up the OOL code. - - uint32_t thingSize = (uint32_t)gc::Arena::thingSize(allocKind); - - // Load the allocator: - // tempReg1 = (Allocator*) forkJoinCx->allocator() - loadPtr(Address(cx, ThreadSafeContext::offsetOfAllocator()), - tempReg1); - - // Get a pointer to the relevant free list: - // tempReg1 = (FreeList*) &tempReg1->arenas.freeLists[(allocKind)] - uint32_t offset = (offsetof(Allocator, arenas) + - js::gc::ArenaLists::getFreeListOffset(allocKind)); - addPtr(Imm32(offset), tempReg1); - - // Load first item on the list - // tempReg2 = tempReg1->head.first - loadPtr(Address(tempReg1, gc::FreeList::offsetOfFirst()), tempReg2); - - // Check whether bump-allocation is possible. - // if tempReg1->head.last <= tempReg2, fail - branchPtr(Assembler::BelowOrEqual, - Address(tempReg1, gc::FreeList::offsetOfLast()), - tempReg2, - fail); - - // If so, take |first| and advance pointer by thingSize bytes. - // result = tempReg2; - // tempReg2 += thingSize; - movePtr(tempReg2, result); - addPtr(Imm32(thingSize), tempReg2); - - // Update |first|. - // tempReg1->head.first = tempReg2; - storePtr(tempReg2, Address(tempReg1, gc::FreeList::offsetOfFirst())); -} - -void -MacroAssembler::newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2, - NativeObject *templateObject, Label *fail) -{ - gc::AllocKind allocKind = templateObject->asTenured().getAllocKind(); - MOZ_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST); - MOZ_ASSERT(!templateObject->numDynamicSlots()); - - newGCThingPar(result, cx, tempReg1, tempReg2, allocKind, fail); -} - -void -MacroAssembler::newGCStringPar(Register result, Register cx, Register tempReg1, Register tempReg2, - Label *fail) -{ - newGCTenuredThingPar(result, cx, tempReg1, tempReg2, js::gc::FINALIZE_STRING, fail); -} - -void -MacroAssembler::newGCFatInlineStringPar(Register result, Register cx, Register tempReg1, - Register tempReg2, Label *fail) -{ - newGCTenuredThingPar(result, cx, tempReg1, tempReg2, js::gc::FINALIZE_FAT_INLINE_STRING, fail); -} - void MacroAssembler::copySlotsFromTemplate(Register obj, const NativeObject *templateObj, uint32_t start, uint32_t end) @@ -1203,13 +1121,6 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output) bind(&done); } -void -MacroAssembler::checkInterruptFlagPar(Register tempReg, Label *fail) -{ - movePtr(ImmPtr(GetJitContext()->runtime->addressOfInterruptParUint32()), tempReg); - branch32(Assembler::NonZero, Address(tempReg, 0), Imm32(0), fail); -} - // Save an exit frame (which must be aligned to the stack pointer) to // PerThreadData::jitTop of the main thread. void @@ -1219,15 +1130,6 @@ MacroAssembler::linkExitFrame() storePtr(StackPointer, jitTop); } -// Save an exit frame to the thread data of the current thread, given a -// register that holds a PerThreadData *. -void -MacroAssembler::linkParallelExitFrame(Register pt) -{ - Address jitTop(pt, offsetof(PerThreadData, jitTop)); - storePtr(StackPointer, jitTop); -} - static void ReportOverRecursed(JSContext *cx) { @@ -1384,52 +1286,19 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo) } void -MacroAssembler::loadBaselineOrIonRaw(Register script, Register dest, ExecutionMode mode, - Label *failure) +MacroAssembler::loadBaselineOrIonRaw(Register script, Register dest, Label *failure) { - if (mode == SequentialExecution) { - loadPtr(Address(script, JSScript::offsetOfBaselineOrIonRaw()), dest); - if (failure) - branchTestPtr(Assembler::Zero, dest, dest, failure); - } else { - loadPtr(Address(script, JSScript::offsetOfParallelIonScript()), dest); - if (failure) - branchPtr(Assembler::BelowOrEqual, dest, ImmPtr(ION_COMPILING_SCRIPT), failure); - loadPtr(Address(dest, IonScript::offsetOfMethod()), dest); - loadPtr(Address(dest, JitCode::offsetOfCode()), dest); - } + loadPtr(Address(script, JSScript::offsetOfBaselineOrIonRaw()), dest); + if (failure) + branchTestPtr(Assembler::Zero, dest, dest, failure); } void -MacroAssembler::loadBaselineOrIonNoArgCheck(Register script, Register dest, ExecutionMode mode, - Label *failure) +MacroAssembler::loadBaselineOrIonNoArgCheck(Register script, Register dest, Label *failure) { - if (mode == SequentialExecution) { - loadPtr(Address(script, JSScript::offsetOfBaselineOrIonSkipArgCheck()), dest); - if (failure) - branchTestPtr(Assembler::Zero, dest, dest, failure); - } else { - // Find second register to get the offset to skip argument check - Register offset = script; - if (script == dest) { - GeneralRegisterSet regs(GeneralRegisterSet::All()); - regs.take(dest); - offset = regs.takeAny(); - } - - loadPtr(Address(script, JSScript::offsetOfParallelIonScript()), dest); - if (failure) - branchPtr(Assembler::BelowOrEqual, dest, ImmPtr(ION_COMPILING_SCRIPT), failure); - - Push(offset); - load32(Address(script, IonScript::offsetOfSkipArgCheckEntryOffset()), offset); - - loadPtr(Address(dest, IonScript::offsetOfMethod()), dest); - loadPtr(Address(dest, JitCode::offsetOfCode()), dest); - addPtr(offset, dest); - - Pop(offset); - } + loadPtr(Address(script, JSScript::offsetOfBaselineOrIonSkipArgCheck()), dest); + if (failure) + branchTestPtr(Assembler::Zero, dest, dest, failure); } void @@ -1441,96 +1310,7 @@ MacroAssembler::loadBaselineFramePtr(Register framePtr, Register dest) } void -MacroAssembler::loadForkJoinContext(Register cx, Register scratch) -{ - // Load the current ForkJoinContext *. If we need a parallel exit frame, - // chances are we are about to do something very slow anyways, so just - // call ForkJoinContextPar again instead of using the cached version. - setupUnalignedABICall(0, scratch); - callWithABI(JS_FUNC_TO_DATA_PTR(void *, ForkJoinContextPar)); - if (ReturnReg != cx) - movePtr(ReturnReg, cx); -} - -void -MacroAssembler::loadContext(Register cxReg, Register scratch, ExecutionMode executionMode) -{ - switch (executionMode) { - case SequentialExecution: - // The scratch register is not used for sequential execution. - loadJSContext(cxReg); - break; - case ParallelExecution: - loadForkJoinContext(cxReg, scratch); - break; - default: - MOZ_CRASH("No such execution mode"); - } -} - -void -MacroAssembler::enterParallelExitFrameAndLoadContext(const VMFunction *f, Register cx, - Register scratch) -{ - loadForkJoinContext(cx, scratch); - // Load the PerThreadData from from the cx. - loadPtr(Address(cx, offsetof(ForkJoinContext, perThreadData)), scratch); - linkParallelExitFrame(scratch); - // Push the ioncode. - exitCodePatch_ = PushWithPatch(ImmWord(-1)); - // Push the VMFunction pointer, to mark arguments. - Push(ImmPtr(f)); -} - -void -MacroAssembler::enterFakeParallelExitFrame(Register cx, Register scratch, - JitCode *codeVal) -{ - // Load the PerThreadData from from the cx. - loadPtr(Address(cx, offsetof(ForkJoinContext, perThreadData)), scratch); - linkParallelExitFrame(scratch); - Push(ImmPtr(codeVal)); - Push(ImmPtr(nullptr)); -} - -void -MacroAssembler::enterExitFrameAndLoadContext(const VMFunction *f, Register cxReg, Register scratch, - ExecutionMode executionMode) -{ - switch (executionMode) { - case SequentialExecution: - // The scratch register is not used for sequential execution. - enterExitFrame(f); - loadJSContext(cxReg); - break; - case ParallelExecution: - enterParallelExitFrameAndLoadContext(f, cxReg, scratch); - break; - default: - MOZ_CRASH("No such execution mode"); - } -} - -void -MacroAssembler::enterFakeExitFrame(Register cxReg, Register scratch, - ExecutionMode executionMode, - JitCode *codeVal) -{ - switch (executionMode) { - case SequentialExecution: - // The cx and scratch registers are not used for sequential execution. - enterFakeExitFrame(codeVal); - break; - case ParallelExecution: - enterFakeParallelExitFrame(cxReg, scratch, codeVal); - break; - default: - MOZ_CRASH("No such execution mode"); - } -} - -void -MacroAssembler::handleFailure(ExecutionMode executionMode) +MacroAssembler::handleFailure() { // Re-entry code is irrelevant because the exception will leave the // running function and never come back @@ -1538,17 +1318,7 @@ MacroAssembler::handleFailure(ExecutionMode executionMode) sps_->skipNextReenter(); leaveSPSFrame(); - JitCode *excTail; - switch (executionMode) { - case SequentialExecution: - excTail = GetJitContext()->runtime->jitRuntime()->getExceptionTail(); - break; - case ParallelExecution: - excTail = GetJitContext()->runtime->jitRuntime()->getExceptionTailParallel(); - break; - default: - MOZ_CRASH("No such execution mode"); - } + JitCode *excTail = GetJitContext()->runtime->jitRuntime()->getExceptionTail(); jump(excTail); // Doesn't actually emit code, but balances the leave() @@ -2147,13 +1917,9 @@ MacroAssembler::convertTypedOrValueToInt(TypedOrValueRegister src, FloatRegister void MacroAssembler::finish() { - if (sequentialFailureLabel_.used()) { - bind(&sequentialFailureLabel_); - handleFailure(SequentialExecution); - } - if (parallelFailureLabel_.used()) { - bind(¶llelFailureLabel_); - handleFailure(ParallelExecution); + if (failureLabel_.used()) { + bind(&failureLabel_); + handleFailure(); } MacroAssemblerSpecific::finish(); diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index f12c6d4129b6..cd489daddc74 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -198,8 +198,7 @@ class MacroAssembler : public MacroAssemblerSpecific IonInstrumentation *sps_; // Labels for handling exceptions and failures. - NonAssertingLabel sequentialFailureLabel_; - NonAssertingLabel parallelFailureLabel_; + NonAssertingLabel failureLabel_; public: // If instrumentation should be emitted, then the sps parameter should be @@ -830,27 +829,11 @@ class MacroAssembler : public MacroAssemblerSpecific void newGCString(Register result, Register temp, Label *fail); void newGCFatInlineString(Register result, Register temp, Label *fail); - void newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2, - gc::AllocKind allocKind, Label *fail); - void newGCTenuredThingPar(Register result, Register cx, Register tempReg1, Register tempReg2, - gc::AllocKind allocKind, Label *fail); - void newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2, - NativeObject *templateObject, Label *fail); - void newGCStringPar(Register result, Register cx, Register tempReg1, Register tempReg2, - Label *fail); - void newGCFatInlineStringPar(Register result, Register cx, Register tempReg1, Register tempReg2, - Label *fail); - - // Compares two strings for equality based on the JSOP. // This checks for identical pointers, atoms and length and fails for everything else. void compareStrings(JSOp op, Register left, Register right, Register result, Label *fail); - // Checks the flags that signal that parallel code may need to interrupt or - // abort. Branches to fail in that case. - void checkInterruptFlagPar(Register tempReg, Label *fail); - // If the JitCode that created this assembler needs to transition into the VM, // we want to store the JitCode on the stack in order to mark it during a GC. // This is a reference to a patch location where the JitCode* will be written. @@ -859,7 +842,6 @@ class MacroAssembler : public MacroAssemblerSpecific private: void linkExitFrame(); - void linkParallelExitFrame(Register pt); public: void enterExitFrame(const VMFunction *f = nullptr) { @@ -884,20 +866,6 @@ class MacroAssembler : public MacroAssemblerSpecific movePtr(ImmPtr(GetJitContext()->runtime->addressOfThreadPool()), pool); } - void loadForkJoinContext(Register cx, Register scratch); - void loadContext(Register cxReg, Register scratch, ExecutionMode executionMode); - - void enterParallelExitFrameAndLoadContext(const VMFunction *f, Register cx, - Register scratch); - - void enterExitFrameAndLoadContext(const VMFunction *f, Register cxReg, Register scratch, - ExecutionMode executionMode); - - void enterFakeParallelExitFrame(Register cx, Register scratch, JitCode *codeVal); - - void enterFakeExitFrame(Register cxReg, Register scratch, ExecutionMode executionMode, - JitCode *codeVal); - void leaveExitFrame() { freeStack(ExitFooterFrame::Size()); } @@ -1169,8 +1137,8 @@ class MacroAssembler : public MacroAssemblerSpecific void spsMarkJit(SPSProfiler *p, Register framePtr, Register temp); void spsUnmarkJit(SPSProfiler *p, Register temp); - void loadBaselineOrIonRaw(Register script, Register dest, ExecutionMode mode, Label *failure); - void loadBaselineOrIonNoArgCheck(Register callee, Register dest, ExecutionMode mode, Label *failure); + void loadBaselineOrIonRaw(Register script, Register dest, Label *failure); + void loadBaselineOrIonNoArgCheck(Register callee, Register dest, Label *failure); void loadBaselineFramePtr(Register framePtr, Register dest); @@ -1180,20 +1148,16 @@ class MacroAssembler : public MacroAssemblerSpecific } private: - void handleFailure(ExecutionMode executionMode); + void handleFailure(); public: Label *exceptionLabel() { // Exceptions are currently handled the same way as sequential failures. - return &sequentialFailureLabel_; + return &failureLabel_; } - Label *failureLabel(ExecutionMode executionMode) { - switch (executionMode) { - case SequentialExecution: return &sequentialFailureLabel_; - case ParallelExecution: return ¶llelFailureLabel_; - default: MOZ_CRASH("Unexpected execution mode"); - } + Label *failureLabel() { + return &failureLabel_; } void finish(); diff --git a/js/src/jit/ParallelFunctions.cpp b/js/src/jit/ParallelFunctions.cpp deleted file mode 100644 index 22659c93acf8..000000000000 --- a/js/src/jit/ParallelFunctions.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 "jit/ParallelFunctions.h" - -#include "builtin/TypedObject.h" -#include "jit/arm/Simulator-arm.h" -#include "jit/mips/Simulator-mips.h" -#include "jit/RematerializedFrame.h" -#include "vm/ArrayObject.h" - -#include "jsgcinlines.h" -#include "jsobjinlines.h" - -#include "vm/NativeObject-inl.h" - -using namespace js; -using namespace jit; - -using mozilla::IsInRange; - -using JS::AutoCheckCannotGC; - -using parallel::Spew; -using parallel::SpewOps; -using parallel::SpewBailouts; - -// Load the current thread context. -ForkJoinContext * -jit::ForkJoinContextPar() -{ - return ForkJoinContext::current(); -} - -// NewGCThingPar() is called in place of NewGCThing() when executing -// parallel code. It uses the ArenaLists for the current thread and -// allocates from there. -JSObject * -jit::NewGCThingPar(ForkJoinContext *cx, gc::AllocKind allocKind) -{ - MOZ_ASSERT(ForkJoinContext::current() == cx); - return js::NewGCObject(cx, allocKind, 0, gc::TenuredHeap); -} - -bool -jit::ParallelWriteGuard(ForkJoinContext *cx, JSObject *object) -{ - // Implements the most general form of the write guard, which is - // suitable for writes to any object O. There are two cases to - // consider and test for: - // - // 1. Writes to thread-local memory are safe. Thread-local memory - // is defined as memory allocated by the current thread. - // The definition of the PJS API guarantees that such memory - // cannot have escaped to other parallel threads. - // - // 2. Writes into the output buffer are safe. Some PJS operations - // supply an out pointer into the final target buffer. The design - // of the API ensures that this out pointer is always pointing - // at a fresh region of the buffer that is not accessible to - // other threads. Thus, even though this output buffer has not - // been created by the current thread, it is writable. - // - // There are some subtleties to consider: - // - // A. Typed objects and typed arrays are just views onto a base buffer. - // For the purposes of guarding parallel writes, it is not important - // whether the *view* is thread-local -- what matters is whether - // the *underlying buffer* is thread-local. - // - // B. With regard to the output buffer, we have to be careful - // because of the potential for sequential iterations to be - // intermingled with parallel ones. During a sequential - // iteration, the out pointer could escape into global - // variables and so forth, and thus be used during later - // parallel operations. However, those out pointers must be - // pointing to distinct regions of the final output buffer than - // the ones that are currently being written, so there is no - // harm done in letting them be read (but not written). - // - // In order to be able to distinguish escaped out pointers from - // prior iterations and the proper out pointers from the - // current iteration, we always track a *target memory region* - // (which is a span of bytes within the output buffer) and not - // just the output buffer itself. - - MOZ_ASSERT(ForkJoinContext::current() == cx); - - if (object->is()) { - TypedObject &typedObj = object->as(); - - // Note: check target region based on `typedObj`, not the owner. - // This is because `typedObj` may point to some subregion of the - // owner and we only care if that *subregion* is within the - // target region, not the entire owner. - if (IsInTargetRegion(cx, &typedObj)) - return true; - - // Check whether the object which owns the memory is thread-local. - if (typedObj.is()) - return cx->isThreadLocal(&typedObj.as().owner()); - return cx->isThreadLocal(&typedObj); - } - - // For other kinds of writable objects, must be thread-local. - return cx->isThreadLocal(object); -} - -// Check that |object| (which must be a typed typedObj) maps -// to memory in the target region. -// -// For efficiency, we assume that all handles which the user has -// access to are either entirely within the target region or entirely -// without, but not straddling the target region nor encompassing -// it. This invariant is maintained by the PJS APIs, where the target -// region and handles are always elements of the same output array. -bool -jit::IsInTargetRegion(ForkJoinContext *cx, TypedObject *typedObj) -{ - MOZ_ASSERT(typedObj->is()); // in case JIT supplies something bogus - uint8_t *typedMem = typedObj->typedMem(); - return typedMem >= cx->targetRegionStart && - typedMem < cx->targetRegionEnd; -} - -bool -jit::CheckOverRecursedPar(ForkJoinContext *cx) -{ - MOZ_ASSERT(ForkJoinContext::current() == cx); - int stackDummy_; - - // In PJS, unlike sequential execution, we don't overwrite the stack limit - // on interrupt, but we do still call into this routine if the interrupt - // flag is set, so we still need to double check. - -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) - if (Simulator::Current()->overRecursed()) { - cx->bailoutRecord->joinCause(ParallelBailoutOverRecursed); - return false; - } -#endif - - if (!JS_CHECK_STACK_SIZE(cx->perThreadData->jitStackLimit(), &stackDummy_)) { - cx->bailoutRecord->joinCause(ParallelBailoutOverRecursed); - return false; - } - - return InterruptCheckPar(cx); -} - -bool -jit::InterruptCheckPar(ForkJoinContext *cx) -{ - MOZ_ASSERT(ForkJoinContext::current() == cx); - bool result = cx->check(); - if (!result) { - cx->bailoutRecord->joinCause(ParallelBailoutInterrupt); - return false; - } - return true; -} - -ArrayObject * -jit::ExtendArrayPar(ForkJoinContext *cx, ArrayObject *array, uint32_t length) -{ - NativeObject::EnsureDenseResult res = - array->ensureDenseElementsPreservePackedFlag(cx, 0, length); - if (res != NativeObject::ED_OK) - return nullptr; - return array; -} - -bool -jit::SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName name, - HandleValue value, bool strict, jsbytecode *pc) -{ - MOZ_ASSERT(cx->isThreadLocal(obj)); - - if (*pc == JSOP_SETALIASEDVAR) { - // See comment in jit::SetProperty. - Shape *shape = obj->as().lookupPure(name); - MOZ_ASSERT(shape && shape->hasSlot()); - return obj->as().setSlotIfHasType(shape, value); - } - - // Fail early on hooks. - if (obj->getOps()->setProperty) - return TP_RETRY_SEQUENTIALLY; - - RootedValue v(cx, value); - RootedId id(cx, NameToId(name)); - return baseops::SetPropertyHelper(cx, - obj.as(), - obj.as(), - id, baseops::Qualified, &v, - strict); -} - -bool -jit::SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index, HandleValue value, - bool strict) -{ - RootedId id(cx); - if (!ValueToIdPure(index, id.address())) - return false; - - if (!obj->isNative()) - return false; - - // SetObjectElementOperation, the sequential version, has several checks - // for certain deoptimizing behaviors, such as marking having written to - // holes and non-indexed element accesses. We don't do that here, as we - // can't modify any TI state anyways. If we need to add a new type, we - // would bail out. - RootedValue v(cx, value); - return baseops::SetPropertyHelper(cx, - obj.as(), - obj.as(), - id, baseops::Qualified, &v, - strict); -} - -bool -jit::SetDenseElementPar(ForkJoinContext *cx, HandleObject obj, int32_t index, HandleValue value, - bool strict) -{ - RootedValue indexVal(cx, Int32Value(index)); - return SetElementPar(cx, obj, indexVal, value, strict); -} - -JSString * -jit::ConcatStringsPar(ForkJoinContext *cx, HandleString left, HandleString right) -{ - return ConcatStrings(cx, left, right); -} - -JSFlatString * -jit::IntToStringPar(ForkJoinContext *cx, int i) -{ - return Int32ToString(cx, i); -} - -JSString * -jit::DoubleToStringPar(ForkJoinContext *cx, double d) -{ - return NumberToString(cx, d); -} - -JSString * -jit::PrimitiveToStringPar(ForkJoinContext *cx, HandleValue input) -{ - // All other cases are handled in assembly. - MOZ_ASSERT(input.isDouble() || input.isInt32()); - - if (input.isInt32()) - return Int32ToString(cx, input.toInt32()); - - return NumberToString(cx, input.toDouble()); -} - -bool -jit::StringToNumberPar(ForkJoinContext *cx, JSString *str, double *out) -{ - return StringToNumber(cx, str, out); -} - -#define PAR_RELATIONAL_OP(OP, EXPECTED) \ -do { \ - /* Optimize for two int-tagged operands (typical loop control). */ \ - if (lhs.isInt32() && rhs.isInt32()) { \ - *res = (lhs.toInt32() OP rhs.toInt32()) == EXPECTED; \ - } else if (lhs.isNumber() && rhs.isNumber()) { \ - double l = lhs.toNumber(), r = rhs.toNumber(); \ - *res = (l OP r) == EXPECTED; \ - } else if (lhs.isBoolean() && rhs.isBoolean()) { \ - int l = lhs.toBoolean() ? 1 : 0; \ - int r = rhs.toBoolean() ? 1 : 0; \ - *res = (l OP r) == EXPECTED; \ - } else if (lhs.isBoolean() && rhs.isNumber()) { \ - double l = lhs.toBoolean() ? 1.0 : 0.0; \ - double r = rhs.toNumber(); \ - *res = (l OP r) == EXPECTED; \ - } else if (lhs.isNumber() && rhs.isBoolean()) { \ - double l = lhs.toNumber(); \ - double r = rhs.toBoolean() ? 1.0 : 0.0; \ - *res = (l OP r) == EXPECTED; \ - } else { \ - int32_t vsZero; \ - if (!CompareMaybeStringsPar(cx, lhs, rhs, &vsZero)) \ - return false; \ - *res = (vsZero OP 0) == EXPECTED; \ - } \ - return true; \ -} while(0) - -static bool -CompareStringsPar(ForkJoinContext *cx, JSString *left, JSString *right, int32_t *res) -{ - ScopedThreadSafeStringInspector leftInspector(left); - ScopedThreadSafeStringInspector rightInspector(right); - AutoCheckCannotGC nogc; - if (!leftInspector.ensureChars(cx, nogc) || !rightInspector.ensureChars(cx, nogc)) - return false; - - if (leftInspector.hasLatin1Chars()) { - if (rightInspector.hasLatin1Chars()) { - *res = CompareChars(leftInspector.latin1Chars(), left->length(), - rightInspector.latin1Chars(), right->length()); - } else { - *res = CompareChars(leftInspector.latin1Chars(), left->length(), - rightInspector.twoByteChars(), right->length()); - } - } else { - if (rightInspector.hasLatin1Chars()) { - *res = CompareChars(leftInspector.twoByteChars(), left->length(), - rightInspector.latin1Chars(), right->length()); - } else { - *res = CompareChars(leftInspector.twoByteChars(), left->length(), - rightInspector.twoByteChars(), right->length()); - } - } - - return true; -} - -static bool -CompareMaybeStringsPar(ForkJoinContext *cx, HandleValue v1, HandleValue v2, int32_t *res) -{ - if (!v1.isString()) - return false; - if (!v2.isString()) - return false; - return CompareStringsPar(cx, v1.toString(), v2.toString(), res); -} - -template -bool -LooselyEqualImplPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - PAR_RELATIONAL_OP(==, Equal); -} - -bool -js::jit::LooselyEqualPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - return LooselyEqualImplPar(cx, lhs, rhs, res); -} - -bool -js::jit::LooselyUnequalPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - return LooselyEqualImplPar(cx, lhs, rhs, res); -} - -template -bool -StrictlyEqualImplPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - if (lhs.isNumber()) { - if (rhs.isNumber()) { - *res = (lhs.toNumber() == rhs.toNumber()) == Equal; - return true; - } - } else if (lhs.isBoolean()) { - if (rhs.isBoolean()) { - *res = (lhs.toBoolean() == rhs.toBoolean()) == Equal; - return true; - } - } else if (lhs.isNull()) { - if (rhs.isNull()) { - *res = Equal; - return true; - } - } else if (lhs.isUndefined()) { - if (rhs.isUndefined()) { - *res = Equal; - return true; - } - } else if (lhs.isObject()) { - if (rhs.isObject()) { - *res = (lhs.toObjectOrNull() == rhs.toObjectOrNull()) == Equal; - return true; - } - } else if (lhs.isString()) { - if (rhs.isString()) - return LooselyEqualImplPar(cx, lhs, rhs, res); - } - - *res = !Equal; - return true; -} - -bool -js::jit::StrictlyEqualPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - return StrictlyEqualImplPar(cx, lhs, rhs, res); -} - -bool -js::jit::StrictlyUnequalPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - return StrictlyEqualImplPar(cx, lhs, rhs, res); -} - -bool -js::jit::LessThanPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - PAR_RELATIONAL_OP(<, true); -} - -bool -js::jit::LessThanOrEqualPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - PAR_RELATIONAL_OP(<=, true); -} - -bool -js::jit::GreaterThanPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - PAR_RELATIONAL_OP(>, true); -} - -bool -js::jit::GreaterThanOrEqualPar(ForkJoinContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, bool *res) -{ - PAR_RELATIONAL_OP(>=, true); -} - -template -bool -StringsEqualImplPar(ForkJoinContext *cx, HandleString lhs, HandleString rhs, bool *res) -{ - int32_t vsZero; - bool ret = CompareStringsPar(cx, lhs, rhs, &vsZero); - if (ret != true) - return ret; - *res = (vsZero == 0) == Equal; - return true; -} - -bool -js::jit::StringsEqualPar(ForkJoinContext *cx, HandleString v1, HandleString v2, bool *res) -{ - return StringsEqualImplPar(cx, v1, v2, res); -} - -bool -js::jit::StringsUnequalPar(ForkJoinContext *cx, HandleString v1, HandleString v2, bool *res) -{ - return StringsEqualImplPar(cx, v1, v2, res); -} - -bool -jit::BitNotPar(ForkJoinContext *cx, HandleValue in, int32_t *out) -{ - if (in.isObject()) - return false; - int i; - if (!NonObjectToInt32(cx, in, &i)) - return false; - *out = ~i; - return true; -} - -#define BIT_OP(OP) \ - JS_BEGIN_MACRO \ - int32_t left, right; \ - if (lhs.isObject() || rhs.isObject()) \ - return false; \ - if (!NonObjectToInt32(cx, lhs, &left) || \ - !NonObjectToInt32(cx, rhs, &right)) \ - { \ - return false; \ - } \ - *out = (OP); \ - return true; \ - JS_END_MACRO - -bool -jit::BitXorPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out) -{ - BIT_OP(left ^ right); -} - -bool -jit::BitOrPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out) -{ - BIT_OP(left | right); -} - -bool -jit::BitAndPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out) -{ - BIT_OP(left & right); -} - -bool -jit::BitLshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out) -{ - BIT_OP(uint32_t(left) << (right & 31)); -} - -bool -jit::BitRshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out) -{ - BIT_OP(left >> (right & 31)); -} - -#undef BIT_OP - -bool -jit::UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, - MutableHandleValue out) -{ - uint32_t left; - int32_t right; - if (lhs.isObject() || rhs.isObject()) - return false; - if (!NonObjectToUint32(cx, lhs, &left) || !NonObjectToInt32(cx, rhs, &right)) - return false; - left >>= right & 31; - out.setNumber(uint32_t(left)); - return true; -} - -void -jit::BailoutPar(BailoutStack *sp, uint8_t **entryFramePointer) -{ - parallel::Spew(parallel::SpewBailouts, "Bailing"); - - ForkJoinContext *cx = ForkJoinContext::current(); - - // We don't have an exit frame. - MOZ_ASSERT(IsInRange(FAKE_JIT_TOP_FOR_BAILOUT, 0, 0x1000) && - IsInRange(FAKE_JIT_TOP_FOR_BAILOUT + sizeof(CommonFrameLayout), 0, 0x1000), - "Fake jitTop pointer should be within the first page."); - cx->perThreadData->jitTop = FAKE_JIT_TOP_FOR_BAILOUT; - - JitActivationIterator jitActivations(cx->perThreadData); - BailoutFrameInfo bailoutData(jitActivations, sp); - JitFrameIterator frameIter(jitActivations); - SnapshotIterator snapIter(frameIter); - - cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind()); - while (!frameIter.done()) - ++frameIter; - - MOZ_ASSERT(frameIter.done()); - *entryFramePointer = frameIter.fp(); -} - -bool -jit::CallToUncompiledScriptPar(ForkJoinContext *cx, JSObject *obj) -{ -#ifdef DEBUG - static const int max_bound_function_unrolling = 5; - - if (!obj->is()) { - Spew(SpewBailouts, "Call to non-function"); - return false; - } - - JSFunction *func = &obj->as(); - if (func->hasScript()) { - JSScript *script = func->nonLazyScript(); - Spew(SpewBailouts, "Call to uncompiled script: %p:%s:%d", - script, script->filename(), script->lineno()); - } else if (func->isInterpretedLazy()) { - Spew(SpewBailouts, "Call to uncompiled lazy script"); - } else if (func->isBoundFunction()) { - int depth = 0; - JSFunction *target = &func->getBoundFunctionTarget()->as(); - while (depth < max_bound_function_unrolling) { - if (target->hasScript()) - break; - if (target->isBoundFunction()) - target = &target->getBoundFunctionTarget()->as(); - depth--; - } - if (target->hasScript()) { - JSScript *script = target->nonLazyScript(); - Spew(SpewBailouts, "Call to bound function leading (depth: %d) to script: %p:%s:%d", - depth, script, script->filename(), script->lineno()); - } else { - Spew(SpewBailouts, "Call to bound function (excessive depth: %d)", depth); - } - } else { - MOZ_ASSERT(func->isNative()); - Spew(SpewBailouts, "Call to native function"); - } -#endif - - return false; -} - -JSObject * -jit::InitRestParameterPar(ForkJoinContext *cx, uint32_t length, Value *rest, - HandleObject templateObj, HandleArrayObject res) -{ - // In parallel execution, we should always have succeeded in allocation - // before this point. We can do the allocation here like in the sequential - // path, but duplicating the initGCThing logic is too tedious. - MOZ_ASSERT(res); - MOZ_ASSERT(!res->getDenseInitializedLength()); - MOZ_ASSERT(res->type() == templateObj->type()); - - if (length > 0) { - NativeObject::EnsureDenseResult edr = - res->ensureDenseElementsPreservePackedFlag(cx, 0, length); - if (edr != NativeObject::ED_OK) - return nullptr; - res->initDenseElementsUnbarriered(0, rest, length); - res->setLengthInt32(length); - } - - return res; -} diff --git a/js/src/jit/ParallelFunctions.h b/js/src/jit/ParallelFunctions.h deleted file mode 100644 index a4010c690eea..000000000000 --- a/js/src/jit/ParallelFunctions.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jit_ParallelFunctions_h -#define jit_ParallelFunctions_h - -#include "gc/Heap.h" -#include "vm/ForkJoin.h" - -namespace js { - -class TypedObject; // subclass of JSObject* defined in builtin/TypedObject.h - -namespace jit { - -ForkJoinContext *ForkJoinContextPar(); -JSObject *NewGCThingPar(ForkJoinContext *cx, gc::AllocKind allocKind); -bool ParallelWriteGuard(ForkJoinContext *cx, JSObject *object); -bool IsInTargetRegion(ForkJoinContext *cx, TypedObject *object); -bool CheckOverRecursedPar(ForkJoinContext *cx); -bool InterruptCheckPar(ForkJoinContext *cx); - -// Extends the given array with `length` new holes. Returns nullptr on -// failure or else `array`, which is convenient during code -// generation. -ArrayObject *ExtendArrayPar(ForkJoinContext *cx, ArrayObject *array, uint32_t length); - -// Set properties and elements on thread local objects. -bool SetPropertyPar(ForkJoinContext *cx, HandleObject obj, HandlePropertyName name, - HandleValue value, bool strict, jsbytecode *pc); -bool SetElementPar(ForkJoinContext *cx, HandleObject obj, HandleValue index, - HandleValue value, bool strict); -bool SetDenseElementPar(ForkJoinContext *cx, HandleObject obj, int32_t index, - HandleValue value, bool strict); - -// String related parallel functions. These tend to call existing VM functions -// that take a ThreadSafeContext. -JSString *ConcatStringsPar(ForkJoinContext *cx, HandleString left, HandleString right); -JSFlatString *IntToStringPar(ForkJoinContext *cx, int i); -JSString *DoubleToStringPar(ForkJoinContext *cx, double d); -JSString *PrimitiveToStringPar(ForkJoinContext *cx, HandleValue input); -bool StringToNumberPar(ForkJoinContext *cx, JSString *str, double *out); - -// Binary and unary operator functions on values. These tend to return -// RETRY_SEQUENTIALLY if the values are objects. -bool StrictlyEqualPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool StrictlyUnequalPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool LooselyEqualPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool LooselyUnequalPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool LessThanPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool LessThanOrEqualPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool GreaterThanPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); -bool GreaterThanOrEqualPar(ForkJoinContext *cx, MutableHandleValue v1, MutableHandleValue v2, bool *); - -bool StringsEqualPar(ForkJoinContext *cx, HandleString v1, HandleString v2, bool *); -bool StringsUnequalPar(ForkJoinContext *cx, HandleString v1, HandleString v2, bool *); - -bool BitNotPar(ForkJoinContext *cx, HandleValue in, int32_t *out); -bool BitXorPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out); -bool BitOrPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out); -bool BitAndPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out); -bool BitLshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out); -bool BitRshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out); - -bool UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue out); - -// Make a new rest parameter in parallel. -JSObject *InitRestParameterPar(ForkJoinContext *cx, uint32_t length, Value *rest, - HandleObject templateObj, HandleArrayObject res); - -// Abort and debug tracing functions. -void BailoutPar(BailoutStack *sp, uint8_t **entryFramePointer); -bool CallToUncompiledScriptPar(ForkJoinContext *cx, JSObject *obj); - -} // namespace jit -} // namespace js - -#endif /* jit_ParallelFunctions_h */ diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp deleted file mode 100644 index 835c223244bf..000000000000 --- a/js/src/jit/ParallelSafetyAnalysis.cpp +++ /dev/null @@ -1,913 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 "jit/ParallelSafetyAnalysis.h" - -#include "jit/Ion.h" -#include "jit/IonAnalysis.h" -#include "jit/JitSpewer.h" -#include "jit/MIR.h" -#include "jit/MIRGenerator.h" -#include "jit/MIRGraph.h" - -#include "jsinferinlines.h" -#include "jsobjinlines.h" - -using namespace js; -using namespace jit; - -using parallel::Spew; -using parallel::SpewMIR; -using parallel::SpewCompile; - -#define SAFE_OP(op) \ - virtual void visit##op(M##op *prop) { } - -#define CUSTOM_OP(op) \ - virtual void visit##op(M##op *prop); - -#define DROP_OP(op) \ - virtual void visit##op(M##op *ins) { \ - MBasicBlock *block = ins->block(); \ - block->discard(ins); \ - } - -#define PERMIT(T) (1 << T) - -#define PERMIT_INT32 (PERMIT(MIRType_Int32)) -#define PERMIT_NUMERIC (PERMIT(MIRType_Int32) | PERMIT(MIRType_Double)) - -#define SPECIALIZED_OP(op, flags) \ - virtual void visit##op(M##op *ins) { \ - visitSpecializedInstruction(ins, ins->specialization(), flags); \ - } - -#define UNSAFE_OP(op) \ - virtual void visit##op(M##op *ins) { \ - SpewMIR(ins, "Unsafe"); \ - markUnsafe(); \ - } - -#define WRITE_GUARDED_OP(op, obj) \ - virtual void visit##op(M##op *prop) { \ - insertWriteGuard(prop, prop->obj()); \ - } - -#define MAYBE_WRITE_GUARDED_OP(op, obj) \ - virtual void visit##op(M##op *prop) { \ - if (!prop->racy()) \ - insertWriteGuard(prop, prop->obj()); \ - } - -class ParallelSafetyVisitor : public MDefinitionVisitor -{ - MIRGraph &graph_; - bool unsafe_; - MDefinition *cx_; - - void insertWriteGuard(MInstruction *writeInstruction, MDefinition *valueBeingWritten); - - void replaceWithNewPar(MInstruction *newInstruction, NativeObject *templateObject); - void replace(MInstruction *oldInstruction, MInstruction *replacementInstruction); - - void visitSpecializedInstruction(MInstruction *ins, MIRType spec, uint32_t flags); - - // Intended for use in a visitXyz() instruction. - void markUnsafe() { - MOZ_ASSERT(!unsafe_); - unsafe_ = true; - } - - TempAllocator &alloc() const { - return graph_.alloc(); - } - - public: - explicit ParallelSafetyVisitor(MIRGraph &graph) - : graph_(graph), - unsafe_(false), - cx_(nullptr) - { } - - void clearUnsafe() { unsafe_ = false; } - bool unsafe() { return unsafe_; } - MDefinition *ForkJoinContext() { - if (!cx_) - cx_ = graph_.forkJoinContext(); - return cx_; - } - - bool convertToBailout(MInstructionIterator &iter); - - // I am taking the policy of blacklisting everything that's not - // obviously safe for now. We can loosen as we need. - - SAFE_OP(Constant) - SAFE_OP(SimdValueX4) - SAFE_OP(SimdSplatX4) - SAFE_OP(SimdConstant) - SAFE_OP(SimdConvert) - SAFE_OP(SimdReinterpretCast) - SAFE_OP(SimdExtractElement) - SAFE_OP(SimdInsertElement) - SAFE_OP(SimdSignMask) - SAFE_OP(SimdSwizzle) - SAFE_OP(SimdShuffle) - SAFE_OP(SimdUnaryArith) - SAFE_OP(SimdBinaryComp) - SAFE_OP(SimdBinaryArith) - SAFE_OP(SimdBinaryBitwise) - SAFE_OP(SimdShift) - SAFE_OP(SimdSelect) - UNSAFE_OP(CloneLiteral) - SAFE_OP(Parameter) - SAFE_OP(Callee) - SAFE_OP(IsConstructing) - SAFE_OP(TableSwitch) - SAFE_OP(Goto) - SAFE_OP(Test) - SAFE_OP(GotoWithFake) - SAFE_OP(Compare) - SAFE_OP(Phi) - SAFE_OP(Beta) - UNSAFE_OP(OsrValue) - UNSAFE_OP(OsrScopeChain) - UNSAFE_OP(OsrReturnValue) - UNSAFE_OP(OsrArgumentsObject) - UNSAFE_OP(ReturnFromCtor) - CUSTOM_OP(CheckOverRecursed) - UNSAFE_OP(DefVar) - UNSAFE_OP(DefFun) - UNSAFE_OP(CreateThis) - CUSTOM_OP(CreateThisWithTemplate) - UNSAFE_OP(CreateThisWithProto) - UNSAFE_OP(CreateArgumentsObject) - UNSAFE_OP(GetArgumentsObjectArg) - UNSAFE_OP(SetArgumentsObjectArg) - UNSAFE_OP(ComputeThis) - UNSAFE_OP(LoadArrowThis) - CUSTOM_OP(Call) - UNSAFE_OP(ApplyArgs) - UNSAFE_OP(ArraySplice) - SAFE_OP(Bail) - SAFE_OP(Unreachable) - UNSAFE_OP(AssertFloat32) - UNSAFE_OP(GetDynamicName) - UNSAFE_OP(FilterArgumentsOrEval) - UNSAFE_OP(CallDirectEval) - SAFE_OP(BitNot) - SAFE_OP(TypeOf) - UNSAFE_OP(ToId) - SAFE_OP(BitAnd) - SAFE_OP(BitOr) - SAFE_OP(BitXor) - SAFE_OP(Lsh) - SAFE_OP(Rsh) - SAFE_OP(Ursh) - SPECIALIZED_OP(MinMax, PERMIT_NUMERIC) - SAFE_OP(Abs) - SAFE_OP(Clz) - SAFE_OP(Sqrt) - UNSAFE_OP(Atan2) - UNSAFE_OP(Hypot) - CUSTOM_OP(MathFunction) - SPECIALIZED_OP(Add, PERMIT_NUMERIC) - SPECIALIZED_OP(Sub, PERMIT_NUMERIC) - SPECIALIZED_OP(Mul, PERMIT_NUMERIC) - SPECIALIZED_OP(Div, PERMIT_NUMERIC) - SPECIALIZED_OP(Mod, PERMIT_NUMERIC) - CUSTOM_OP(Concat) - SAFE_OP(ConcatPar) - UNSAFE_OP(CharCodeAt) - UNSAFE_OP(FromCharCode) - UNSAFE_OP(StringSplit) - SAFE_OP(Return) - CUSTOM_OP(Throw) - SAFE_OP(Box) // Boxing just creates a JSVal, doesn't alloc. - SAFE_OP(Unbox) - SAFE_OP(GuardObject) - SAFE_OP(ToDouble) - SAFE_OP(ToFloat32) - SAFE_OP(ToInt32) - SAFE_OP(TruncateToInt32) - SAFE_OP(MaybeToDoubleElement) - CUSTOM_OP(ToString) - UNSAFE_OP(ToObjectOrNull) - CUSTOM_OP(NewArray) - UNSAFE_OP(NewArrayCopyOnWrite) - UNSAFE_OP(NewArrayDynamicLength) - UNSAFE_OP(NewTypedObject) - CUSTOM_OP(NewObject) - CUSTOM_OP(NewCallObject) - CUSTOM_OP(NewRunOnceCallObject) - CUSTOM_OP(NewDerivedTypedObject) - SAFE_OP(ObjectState) - SAFE_OP(ArrayState) - UNSAFE_OP(InitElem) - UNSAFE_OP(InitElemGetterSetter) - UNSAFE_OP(MutateProto) - UNSAFE_OP(InitProp) - UNSAFE_OP(InitPropGetterSetter) - SAFE_OP(Start) - UNSAFE_OP(OsrEntry) - SAFE_OP(Nop) - SAFE_OP(LimitedTruncate) - UNSAFE_OP(RegExp) - CUSTOM_OP(Lambda) - UNSAFE_OP(LambdaArrow) - SAFE_OP(Slots) - SAFE_OP(Elements) - SAFE_OP(ConstantElements) - SAFE_OP(LoadSlot) - WRITE_GUARDED_OP(StoreSlot, slots) - SAFE_OP(FunctionEnvironment) // just a load of func env ptr - SAFE_OP(FilterTypeSet) - SAFE_OP(TypeBarrier) // causes a bailout if the type is not found: a-ok with us - SAFE_OP(MonitorTypes) // causes a bailout if the type is not found: a-ok with us - UNSAFE_OP(PostWriteBarrier) - SAFE_OP(GetPropertyCache) - SAFE_OP(GetPropertyPolymorphic) - UNSAFE_OP(SetPropertyPolymorphic) - SAFE_OP(GetElementCache) - WRITE_GUARDED_OP(SetElementCache, object) - UNSAFE_OP(BindNameCache) - SAFE_OP(GuardShape) - SAFE_OP(GuardShapePolymorphic) - SAFE_OP(GuardObjectType) - SAFE_OP(GuardObjectIdentity) - SAFE_OP(GuardClass) - SAFE_OP(AssertRange) - SAFE_OP(ArrayLength) - WRITE_GUARDED_OP(SetArrayLength, elements) - SAFE_OP(TypedArrayLength) - SAFE_OP(TypedArrayElements) - SAFE_OP(TypedObjectDescr) - SAFE_OP(TypedObjectElements) - SAFE_OP(SetTypedObjectOffset) - SAFE_OP(InitializedLength) - WRITE_GUARDED_OP(SetInitializedLength, elements) - SAFE_OP(Not) - SAFE_OP(BoundsCheck) - SAFE_OP(BoundsCheckLower) - SAFE_OP(LoadElement) - SAFE_OP(LoadElementHole) - SAFE_OP(LoadUnboxedObjectOrNull) - SAFE_OP(LoadUnboxedString) - MAYBE_WRITE_GUARDED_OP(StoreElement, elements) - WRITE_GUARDED_OP(StoreElementHole, elements) - UNSAFE_OP(StoreUnboxedObjectOrNull) - UNSAFE_OP(StoreUnboxedString) - UNSAFE_OP(ArrayPopShift) - UNSAFE_OP(ArrayPush) - SAFE_OP(LoadTypedArrayElement) - SAFE_OP(LoadTypedArrayElementHole) - SAFE_OP(LoadTypedArrayElementStatic) - MAYBE_WRITE_GUARDED_OP(StoreTypedArrayElement, elements) - WRITE_GUARDED_OP(StoreTypedArrayElementHole, elements) - UNSAFE_OP(StoreTypedArrayElementStatic) - UNSAFE_OP(ClampToUint8) - SAFE_OP(LoadFixedSlot) - WRITE_GUARDED_OP(StoreFixedSlot, object) - UNSAFE_OP(CallGetProperty) - UNSAFE_OP(GetNameCache) - UNSAFE_OP(CallGetIntrinsicValue) - UNSAFE_OP(CallsiteCloneCache) - UNSAFE_OP(CallGetElement) - WRITE_GUARDED_OP(CallSetElement, object) - UNSAFE_OP(CallInitElementArray) - WRITE_GUARDED_OP(CallSetProperty, object) - UNSAFE_OP(DeleteProperty) - UNSAFE_OP(DeleteElement) - WRITE_GUARDED_OP(SetPropertyCache, object) - UNSAFE_OP(IteratorStart) - UNSAFE_OP(IteratorMore) - UNSAFE_OP(IsNoIter) - UNSAFE_OP(IteratorEnd) - SAFE_OP(StringLength) - SAFE_OP(ArgumentsLength) - SAFE_OP(GetFrameArgument) - UNSAFE_OP(SetFrameArgument) - UNSAFE_OP(RunOncePrologue) - CUSTOM_OP(Rest) - SAFE_OP(RestPar) - SAFE_OP(Floor) - SAFE_OP(Ceil) - SAFE_OP(Round) - UNSAFE_OP(InstanceOf) - CUSTOM_OP(InterruptCheck) - UNSAFE_OP(AsmJSInterruptCheck) - SAFE_OP(ForkJoinContext) - SAFE_OP(ForkJoinGetSlice) - SAFE_OP(NewPar) - SAFE_OP(NewDenseArrayPar) - SAFE_OP(NewCallObjectPar) - SAFE_OP(LambdaPar) - UNSAFE_OP(ArrayConcat) - UNSAFE_OP(ArrayJoin) - UNSAFE_OP(GetDOMProperty) - UNSAFE_OP(GetDOMMember) - UNSAFE_OP(SetDOMProperty) - UNSAFE_OP(NewStringObject) - UNSAFE_OP(Random) - SAFE_OP(Pow) - SAFE_OP(PowHalf) - UNSAFE_OP(RegExpTest) - UNSAFE_OP(RegExpExec) - UNSAFE_OP(RegExpReplace) - UNSAFE_OP(StringReplace) - UNSAFE_OP(CallInstanceOf) - UNSAFE_OP(ProfilerStackOp) - UNSAFE_OP(GuardString) - UNSAFE_OP(Substr) - UNSAFE_OP(NewDeclEnvObject) - UNSAFE_OP(In) - UNSAFE_OP(InArray) - SAFE_OP(GuardThreadExclusive) - SAFE_OP(InterruptCheckPar) - SAFE_OP(CheckOverRecursedPar) - SAFE_OP(FunctionDispatch) - SAFE_OP(TypeObjectDispatch) - SAFE_OP(IsCallable) - SAFE_OP(IsObject) - SAFE_OP(HasClass) - UNSAFE_OP(EffectiveAddress) - UNSAFE_OP(AsmJSUnsignedToDouble) - UNSAFE_OP(AsmJSUnsignedToFloat32) - UNSAFE_OP(AsmJSNeg) - UNSAFE_OP(AsmJSLoadHeap) - UNSAFE_OP(AsmJSStoreHeap) - UNSAFE_OP(AsmJSLoadGlobalVar) - UNSAFE_OP(AsmJSStoreGlobalVar) - UNSAFE_OP(AsmJSLoadFuncPtr) - UNSAFE_OP(AsmJSLoadFFIFunc) - UNSAFE_OP(AsmJSReturn) - UNSAFE_OP(AsmJSVoidReturn) - UNSAFE_OP(AsmJSPassStackArg) - UNSAFE_OP(AsmJSParameter) - UNSAFE_OP(AsmJSCall) - DROP_OP(RecompileCheck) - UNSAFE_OP(CompareExchangeTypedArrayElement) - UNSAFE_OP(AtomicTypedArrayElementBinop) - UNSAFE_OP(MemoryBarrier) - UNSAFE_OP(AsmJSCompareExchangeHeap) - UNSAFE_OP(AsmJSAtomicBinopHeap) - UNSAFE_OP(UnknownValue) - UNSAFE_OP(LexicalCheck) - UNSAFE_OP(ThrowUninitializedLexical) - UNSAFE_OP(Debugger) - - // It looks like these could easily be made safe: - UNSAFE_OP(ConvertElementsToDoubles) - UNSAFE_OP(MaybeCopyElementsForWrite) -}; - -static void -TransplantResumePoint(MInstruction *oldInstruction, MInstruction *replacementInstruction) -{ - MOZ_ASSERT(!oldInstruction->isDiscarded()); - if (oldInstruction->resumePoint()) - replacementInstruction->stealResumePoint(oldInstruction); -} - -bool -ParallelSafetyAnalysis::analyze() -{ - // Walk the basic blocks in a DFS. When we encounter a block with an - // unsafe instruction, then we know that this block will bailout when - // executed. Therefore, we replace the block. - // - // We don't need a worklist, though, because the graph is sorted - // in RPO. Therefore, we just use the marked flags to tell us - // when we visited some predecessor of the current block. - ParallelSafetyVisitor visitor(graph_); - graph_.entryBlock()->mark(); // Note: in par. exec., we never enter from OSR. - uint32_t marked = 0; - for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) { - if (mir_->shouldCancel("ParallelSafetyAnalysis")) - return false; - - if (block->isMarked()) { - // Count the number of reachable blocks. - marked++; - - // Iterate through and transform the instructions. Stop - // if we encounter an inherently unsafe operation, in - // which case we will transform this block into a bailout - // block. - MInstruction *ins = nullptr; - MInstructionIterator iter(block->begin()); - while (iter != block->end() && !visitor.unsafe()) { - if (mir_->shouldCancel("ParallelSafetyAnalysis")) - return false; - - // We may be removing or replacing the current - // instruction, so advance `iter` now. Remember the - // last instr. we looked at for use later if it should - // prove unsafe. - ins = *iter++; - - ins->accept(&visitor); - } - - if (!visitor.unsafe()) { - // Block consists of only safe instructions. Visit its successors. - for (uint32_t i = 0; i < block->numSuccessors(); i++) - block->getSuccessor(i)->markUnchecked(); - } else { - // Block contains an unsafe instruction. That means that once - // we enter this block, we are guaranteed to bailout. - - // If this is the entry block, then there is no point - // in even trying to execute this function as it will - // always bailout. - if (*block == graph_.entryBlock()) { - Spew(SpewCompile, "Entry block contains unsafe MIR"); - mir_->disable(); - return false; - } - - // Otherwise, create a replacement that will. We seek back one - // position on the instruction iterator, as we will be - // discarding all instructions starting at the unsafe - // instruction. - if (!visitor.convertToBailout(--iter)) - return false; - } - } - } - - Spew(SpewCompile, "Safe"); - IonSpewPass("ParallelSafetyAnalysis"); - - // Sweep away any unmarked blocks. Note that this doesn't preserve - // AliasAnalysis dependencies, but we're not expected to at this point. - if (!RemoveUnmarkedBlocks(mir_, graph_, marked)) - return false; - IonSpewPass("UCEAfterParallelSafetyAnalysis"); - AssertExtendedGraphCoherency(graph_); - - return true; -} - -bool -ParallelSafetyVisitor::convertToBailout(MInstructionIterator &iter) -{ - // We expect iter to be settled on the unsafe instruction. - MInstruction *ins = *iter; - MBasicBlock *block = ins->block(); - MOZ_ASSERT(unsafe()); // `block` must have contained unsafe items - MOZ_ASSERT(block->isMarked()); // `block` must have been reachable to get here - - clearUnsafe(); - - // Allocate a new bailout instruction. - MBail *bail = MBail::New(graph_.alloc(), Bailout_ParallelUnsafe); - - // Discard the rest of the block and sever its link to its successors in - // the CFG. - for (size_t i = 0; i < block->numSuccessors(); i++) - block->getSuccessor(i)->removePredecessor(block); - block->discardAllInstructionsStartingAt(iter); - - // No more successors are reachable, so the current block can no longer be - // the parent of an inlined function. - if (block->outerResumePoint()) - block->clearOuterResumePoint(); - - // End the block in a bail. - block->add(bail); - block->end(MUnreachable::New(alloc())); - return true; -} - -///////////////////////////////////////////////////////////////////////////// -// Memory allocation -// -// Simple memory allocation opcodes---those which ultimately compile -// down to a (possibly inlined) invocation of NewGCThing()---are -// replaced with MNewPar, which is supplied with the thread context. -// These allocations will take place using per-helper-thread arenas. - -void -ParallelSafetyVisitor::visitCreateThisWithTemplate(MCreateThisWithTemplate *ins) -{ - replaceWithNewPar(ins, ins->templateObject()); -} - -void -ParallelSafetyVisitor::visitNewCallObject(MNewCallObject *ins) -{ - if (ins->templateObject()->hasDynamicSlots()) { - SpewMIR(ins, "call with dynamic slots"); - markUnsafe(); - } else { - replace(ins, MNewCallObjectPar::New(alloc(), ForkJoinContext(), ins)); - } -} - -void -ParallelSafetyVisitor::visitNewRunOnceCallObject(MNewRunOnceCallObject *ins) -{ - if (ins->templateObject()->hasDynamicSlots()) { - SpewMIR(ins, "call with dynamic slots"); - markUnsafe(); - } else { - replace(ins, MNewCallObjectPar::New(alloc(), ForkJoinContext(), ins)); - } -} - -void -ParallelSafetyVisitor::visitLambda(MLambda *ins) -{ - if (ins->info().singletonType || ins->info().useNewTypeForClone) { - // slow path: bail on parallel execution. - markUnsafe(); - } else { - // fast path: replace with LambdaPar op - replace(ins, MLambdaPar::New(alloc(), ForkJoinContext(), ins)); - } -} - -void -ParallelSafetyVisitor::visitNewObject(MNewObject *newInstruction) -{ - if (newInstruction->shouldUseVM()) { - SpewMIR(newInstruction, "should use VM"); - markUnsafe(); - } else { - replaceWithNewPar(newInstruction, newInstruction->templateObject()); - } -} - -void -ParallelSafetyVisitor::visitNewArray(MNewArray *newInstruction) -{ - if (newInstruction->shouldUseVM()) { - SpewMIR(newInstruction, "should use VM"); - markUnsafe(); - } else { - replaceWithNewPar(newInstruction, newInstruction->templateObject()); - } -} - -void -ParallelSafetyVisitor::visitNewDerivedTypedObject(MNewDerivedTypedObject *ins) -{ - // FIXME(Bug 984090) -- There should really be a parallel-safe - // version of NewDerivedTypedObject. However, until that is - // implemented, let's just ignore those with 0 uses, since they - // will be stripped out by DCE later. - if (!ins->hasUses()) - return; - - SpewMIR(ins, "visitNewDerivedTypedObject"); - markUnsafe(); -} - -void -ParallelSafetyVisitor::visitRest(MRest *ins) -{ - replace(ins, MRestPar::New(alloc(), ForkJoinContext(), ins)); -} - -void -ParallelSafetyVisitor::visitMathFunction(MMathFunction *ins) -{ - replace(ins, MMathFunction::New(alloc(), ins->input(), ins->function(), nullptr)); -} - -void -ParallelSafetyVisitor::visitConcat(MConcat *ins) -{ - replace(ins, MConcatPar::New(alloc(), ForkJoinContext(), ins)); -} - -void -ParallelSafetyVisitor::visitToString(MToString *ins) -{ - MIRType inputType = ins->input()->type(); - if (inputType != MIRType_Int32 && inputType != MIRType_Double) - markUnsafe(); -} - -void -ParallelSafetyVisitor::replaceWithNewPar(MInstruction *newInstruction, - NativeObject *templateObject) -{ - replace(newInstruction, MNewPar::New(alloc(), ForkJoinContext(), templateObject)); -} - -void -ParallelSafetyVisitor::replace(MInstruction *oldInstruction, - MInstruction *replacementInstruction) -{ - TransplantResumePoint(oldInstruction, replacementInstruction); - - MBasicBlock *block = oldInstruction->block(); - block->insertBefore(oldInstruction, replacementInstruction); - oldInstruction->replaceAllUsesWith(replacementInstruction); - block->discard(oldInstruction); - - // We may have replaced a specialized Float32 instruction by its - // non-specialized version, so just retry to specialize it. This relies on - // the fact that Phis' types don't change during the ParallelSafetyAnalysis; - // otherwise we'd have to run the entire TypeAnalyzer Float32 analysis once - // instructions have been replaced. - if (replacementInstruction->isFloat32Commutative() && - replacementInstruction->type() != MIRType_Float32) - { - replacementInstruction->trySpecializeFloat32(alloc()); - } - MOZ_ASSERT(oldInstruction->type() == replacementInstruction->type()); -} - -///////////////////////////////////////////////////////////////////////////// -// Write Guards -// -// We only want to permit writes to locally guarded objects. -// Furthermore, we want to avoid PICs and other non-thread-safe things -// (though perhaps we should support PICs at some point). If we -// cannot determine the origin of an object, we can insert a write -// guard which will check whether the object was allocated from the -// per-thread-arena or not. - -void -ParallelSafetyVisitor::insertWriteGuard(MInstruction *writeInstruction, - MDefinition *valueBeingWritten) -{ - // Many of the write operations do not take the JS object - // but rather something derived from it, such as the elements. - // So we need to identify the JS object: - MDefinition *object; - switch (valueBeingWritten->type()) { - case MIRType_Object: - object = valueBeingWritten; - break; - - case MIRType_Slots: - switch (valueBeingWritten->op()) { - case MDefinition::Op_Slots: - object = valueBeingWritten->toSlots()->object(); - break; - - default: - SpewMIR(writeInstruction, "cannot insert write guard for %s", - valueBeingWritten->opName()); - markUnsafe(); - return; - } - break; - - case MIRType_Elements: - switch (valueBeingWritten->op()) { - case MDefinition::Op_Elements: - object = valueBeingWritten->toElements()->object(); - break; - - case MDefinition::Op_TypedArrayElements: - object = valueBeingWritten->toTypedArrayElements()->object(); - break; - - case MDefinition::Op_TypedObjectElements: - object = valueBeingWritten->toTypedObjectElements()->object(); - break; - - default: - SpewMIR(writeInstruction, "cannot insert write guard for %s", - valueBeingWritten->opName()); - markUnsafe(); - return; - } - break; - - default: - SpewMIR(writeInstruction, "cannot insert write guard for MIR Type %d", - valueBeingWritten->type()); - markUnsafe(); - return; - } - - if (object->isUnbox()) - object = object->toUnbox()->input(); - - switch (object->op()) { - case MDefinition::Op_NewPar: - // MNewPar will always be creating something thread-local, omit the guard - SpewMIR(writeInstruction, "write to NewPar prop does not require guard"); - return; - default: - break; - } - - MBasicBlock *block = writeInstruction->block(); - MGuardThreadExclusive *writeGuard = - MGuardThreadExclusive::New(alloc(), ForkJoinContext(), object); - block->insertBefore(writeInstruction, writeGuard); - writeGuard->typePolicy()->adjustInputs(alloc(), writeGuard); -} - -///////////////////////////////////////////////////////////////////////////// -// Calls -// -// We only support calls to interpreted functions that that have already been -// Ion compiled. If a function has no IonScript, we bail out. - -void -ParallelSafetyVisitor::visitCall(MCall *ins) -{ - // DOM? Scary. - if (ins->isCallDOMNative()) { - SpewMIR(ins, "call to dom function"); - markUnsafe(); - return; - } - - JSFunction *target = ins->getSingleTarget(); - if (target) { - // Non-parallel native? Scary - if (target->isNative() && !target->hasParallelNative()) { - SpewMIR(ins, "call to non-parallel native function"); - markUnsafe(); - } - return; - } - - if (ins->isConstructing()) { - SpewMIR(ins, "call to unknown constructor"); - markUnsafe(); - } -} - -///////////////////////////////////////////////////////////////////////////// -// Stack limit, interrupts -// -// In sequential Ion code, the stack limit is stored in the JSRuntime. -// We store it in the thread context. We therefore need a separate -// instruction to access it, one parameterized by the thread context. -// Similar considerations apply to checking for interrupts. - -void -ParallelSafetyVisitor::visitCheckOverRecursed(MCheckOverRecursed *ins) -{ - replace(ins, MCheckOverRecursedPar::New(alloc(), ForkJoinContext())); -} - -void -ParallelSafetyVisitor::visitInterruptCheck(MInterruptCheck *ins) -{ - replace(ins, MInterruptCheckPar::New(alloc(), ForkJoinContext())); -} - -///////////////////////////////////////////////////////////////////////////// -// Specialized ops -// -// Some ops, like +, can be specialized to ints/doubles. Anything -// else is terrifying. -// -// TODO---Eventually, we should probably permit arbitrary + but bail -// if the operands are not both integers/floats. - -void -ParallelSafetyVisitor::visitSpecializedInstruction(MInstruction *ins, MIRType spec, - uint32_t flags) -{ - uint32_t flag = 1 << spec; - if (flags & flag) - return; - - SpewMIR(ins, "specialized to unacceptable type %d", spec); - markUnsafe(); -} - -///////////////////////////////////////////////////////////////////////////// -// Throw - -void -ParallelSafetyVisitor::visitThrow(MThrow *thr) -{ - MBasicBlock *block = thr->block(); - MOZ_ASSERT(block->lastIns() == thr); - MBail *bail = MBail::New(alloc(), Bailout_ParallelUnsafe); - block->discardLastIns(); - block->add(bail); - block->end(MUnreachable::New(alloc())); -} - -/////////////////////////////////////////////////////////////////////////// -// Callee extraction -// -// See comments in header file. - -static bool -GetPossibleCallees(JSContext *cx, HandleScript script, jsbytecode *pc, - types::TemporaryTypeSet *calleeTypes, CallTargetVector &targets); - -static bool -AddCallTarget(HandleScript script, CallTargetVector &targets); - -bool -jit::AddPossibleCallees(JSContext *cx, MIRGraph &graph, CallTargetVector &targets) -{ - for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) { - for (MInstructionIterator ins(block->begin()); ins != block->end(); ins++) - { - if (!ins->isCall()) - continue; - - MCall *callIns = ins->toCall(); - - RootedFunction target(cx, callIns->getSingleTarget()); - if (target) { - MOZ_ASSERT_IF(!target->isInterpreted(), target->hasParallelNative()); - - if (target->isInterpreted()) { - RootedScript script(cx, target->getOrCreateScript(cx)); - if (!script || !AddCallTarget(script, targets)) - return false; - } - - continue; - } - - types::TemporaryTypeSet *calleeTypes = callIns->getFunction()->resultTypeSet(); - RootedScript script(cx, callIns->block()->info().script()); - if (!GetPossibleCallees(cx, - script, - callIns->resumePoint()->pc(), - calleeTypes, - targets)) - return false; - } - } - - return true; -} - -static bool -GetPossibleCallees(JSContext *cx, - HandleScript script, - jsbytecode *pc, - types::TemporaryTypeSet *calleeTypes, - CallTargetVector &targets) -{ - if (!calleeTypes || calleeTypes->baseFlags() != 0) - return true; - - unsigned objCount = calleeTypes->getObjectCount(); - - if (objCount == 0) - return true; - - RootedFunction rootedFun(cx); - RootedScript rootedScript(cx); - for (unsigned i = 0; i < objCount; i++) { - JSObject *obj = calleeTypes->getSingleObject(i); - if (obj && obj->is()) { - rootedFun = &obj->as(); - } else { - types::TypeObject *typeObj = calleeTypes->getTypeObject(i); - if (!typeObj) - continue; - rootedFun = typeObj->interpretedFunction; - if (!rootedFun) - continue; - } - - if (!rootedFun->isInterpreted()) - continue; - - rootedScript = rootedFun->getOrCreateScript(cx); - if (!rootedScript) - return false; - - if (rootedScript->shouldCloneAtCallsite()) { - rootedFun = CloneFunctionAtCallsite(cx, rootedFun, script, pc); - if (!rootedFun) - return false; - rootedScript = rootedFun->nonLazyScript(); - } - - // check if this call target is already known - if (!AddCallTarget(rootedScript, targets)) - return false; - } - - return true; -} - -static bool -AddCallTarget(HandleScript script, CallTargetVector &targets) -{ - for (size_t i = 0; i < targets.length(); i++) { - if (targets[i] == script) - return true; - } - - if (!targets.append(script)) - return false; - - return true; -} diff --git a/js/src/jit/ParallelSafetyAnalysis.h b/js/src/jit/ParallelSafetyAnalysis.h deleted file mode 100644 index 4689282ecfd7..000000000000 --- a/js/src/jit/ParallelSafetyAnalysis.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 jit_ParallelSafetyAnalysis_h -#define jit_ParallelSafetyAnalysis_h - -#include "jit/MIR.h" - -namespace js { - -class InterpreterFrame; - -namespace jit { - -class MIRGraph; -class AutoDestroyAllocator; - -// Determines whether a function is compatible for parallel execution. -// Removes basic blocks containing unsafe MIR operations from the -// graph and replaces them with MBail blocks. -class ParallelSafetyAnalysis -{ - MIRGenerator *mir_; - MIRGraph &graph_; - - public: - ParallelSafetyAnalysis(MIRGenerator *mir, - MIRGraph &graph) - : mir_(mir), - graph_(graph) - {} - - bool analyze(); -}; - -// Code to collect list of possible call targets by scraping through -// TI and baseline data. Used to permit speculative transitive -// compilation in vm/ForkJoin. -// -// This code may clone scripts and thus may invoke the GC. Hence only -// run from the link phase, which executes on the main thread. -typedef Vector CallTargetVector; -bool AddPossibleCallees(JSContext *cx, MIRGraph &graph, CallTargetVector &targets); - -} // namespace jit -} // namespace js - -#endif /* jit_ParallelSafetyAnalysis_h */ diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 50c08ddd0701..da3c0077d121 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -15,7 +15,6 @@ namespace js { class DeclEnvObject; -class ForkJoinContext; class StaticWithObject; class InlineTypedObject; @@ -468,9 +467,6 @@ template <> struct MatchContext { template <> struct MatchContext { static const ExecutionMode execMode = SequentialExecution; }; -template <> struct MatchContext { - static const ExecutionMode execMode = ParallelExecution; -}; template <> struct MatchContext { // ThreadSafeContext functions can be called from either mode, but for // calling from parallel they should be wrapped first, so we default to diff --git a/js/src/jit/arm/Bailouts-arm.cpp b/js/src/jit/arm/Bailouts-arm.cpp index 0883accaa913..a99ed441ff74 100644 --- a/js/src/jit/arm/Bailouts-arm.cpp +++ b/js/src/jit/arm/Bailouts-arm.cpp @@ -79,10 +79,7 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations, JSScript *script = ScriptFromCalleeToken(((JitFrameLayout *) framePointer_)->calleeToken()); JitActivation *activation = activations.activation()->asJit(); - if (activation->cx()->isForkJoinContext()) - topIonScript_ = script->parallelIonScript(); - else - topIonScript_ = script->ionScript(); + topIonScript_ = script->ionScript(); attachOnJitActivation(activations); diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 42e1969b80f5..ec5462e11f90 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -60,10 +60,8 @@ CodeGeneratorARM::generateEpilogue() masm.bind(&returnLabel_); #ifdef JS_TRACE_LOGGING - if (gen->info().executionMode() == SequentialExecution) { - emitTracelogStopEvent(TraceLogger_IonMonkey); - emitTracelogScriptStop(); - } + emitTracelogStopEvent(TraceLogger_IonMonkey); + emitTracelogScriptStop(); #endif masm.freeStack(frameSize()); @@ -150,7 +148,7 @@ CodeGeneratorARM::generateOutOfLineCode() // Push the frame size, so the handler can recover the IonScript. masm.ma_mov(Imm32(frameSize()), lr); - JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(gen->info().executionMode()); + JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(); masm.branch(handler); } @@ -2185,18 +2183,6 @@ CodeGeneratorARM::visitNegF(LNegF *ins) masm.ma_vneg_f32(input, ToFloatRegister(ins->output())); } -void -CodeGeneratorARM::visitForkJoinGetSlice(LForkJoinGetSlice *ins) -{ - MOZ_CRASH("NYI"); -} - -JitCode * -JitRuntime::generateForkJoinGetSliceStub(JSContext *cx) -{ - MOZ_CRASH("NYI"); -} - void CodeGeneratorARM::memoryBarrier(MemoryBarrierBits barrier) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 2946340e99f3..b27e87e66b25 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -214,8 +214,6 @@ class CodeGeneratorARM : public CodeGeneratorShared void visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins); void visitAsmJSPassStackArg(LAsmJSPassStackArg *ins); - void visitForkJoinGetSlice(LForkJoinGetSlice *ins); - void visitMemoryBarrier(LMemoryBarrier *ins); void generateInvalidateEpilogue(); diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index 8c547f6b915a..5b756d95ddaa 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -550,12 +550,6 @@ LIRGeneratorARM::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic MOZ_CRASH("NYI"); } -void -LIRGeneratorARM::visitForkJoinGetSlice(MForkJoinGetSlice *ins) -{ - MOZ_CRASH("NYI"); -} - void LIRGeneratorARM::visitSimdBinaryArith(MSimdBinaryArith *ins) { diff --git a/js/src/jit/arm/Lowering-arm.h b/js/src/jit/arm/Lowering-arm.h index 18e6a21dfd07..c9160473c5fd 100644 --- a/js/src/jit/arm/Lowering-arm.h +++ b/js/src/jit/arm/Lowering-arm.h @@ -38,12 +38,6 @@ class LIRGeneratorARM : public LIRGeneratorShared bool needTempForPostBarrier() { return false; } - // x64 has a scratch register, so no need for another temp for dispatch - // ICs. - LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) { - return LDefinition::BogusTemp(); - } - void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); void defineUntypedPhi(MPhi *phi, size_t lirIndex); void lowerForShift(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir, MDefinition *lhs, @@ -106,7 +100,6 @@ class LIRGeneratorARM : public LIRGeneratorShared void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins); void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins); void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins); - void visitForkJoinGetSlice(MForkJoinGetSlice *ins); void visitSimdBinaryArith(MSimdBinaryArith *ins); void visitSimdSelect(MSimdSelect *ins); void visitSimdSplatX4(MSimdSplatX4 *ins); diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index 8fb1b6102ee0..4ecf5b8137e6 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -15,11 +15,8 @@ #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" #endif -#include "jit/ParallelFunctions.h" #include "jit/VMFunctions.h" -#include "jit/ExecutionMode-inl.h" - using namespace js; using namespace js::jit; @@ -416,7 +413,7 @@ JitRuntime::generateInvalidator(JSContext *cx) } JitCode * -JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut) +JitRuntime::generateArgumentsRectifier(JSContext *cx, void **returnAddrOut) { MacroAssembler masm(cx); masm.pushReturnAddress(); @@ -482,7 +479,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Note that this code assumes the function is JITted. masm.andPtr(Imm32(CalleeTokenMask), r1); masm.ma_ldr(DTRAddr(r1, DtrOffImm(JSFunction::offsetOfNativeOrScript())), r3); - masm.loadBaselineOrIonRaw(r3, r3, mode, nullptr); + masm.loadBaselineOrIonRaw(r3, r3, nullptr); masm.ma_callJitHalfPush(r3); uint32_t returnOffset = masm.currentOffset(); @@ -642,33 +639,6 @@ GenerateBailoutThunk(JSContext *cx, MacroAssembler &masm, uint32_t frameClass) masm.branch(bailoutTail); } -static void -GenerateParallelBailoutThunk(MacroAssembler &masm, uint32_t frameClass) -{ - // As GenerateBailoutThunk, except we return an error immediately. We do the - // bailout dance so that we can walk the stack and have accurate reporting - // of frame information. - - PushBailoutFrame(masm, frameClass, r0); - - // Parallel bailout is like parallel failure in that we unwind all the way - // to the entry frame. Reserve space for the frame pointer of the entry - // frame. - const int sizeOfEntryFramePointer = sizeof(uint8_t *) * 2; - masm.reserveStack(sizeOfEntryFramePointer); - masm.mov(sp, r1); - - masm.setupAlignedABICall(2); - masm.passABIArg(r0); - masm.passABIArg(r1); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, BailoutPar)); - - // Get the frame pointer of the entry frame and return. - masm.moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - masm.ma_ldr(Address(sp, 0), sp); - masm.as_dtr(IsLoad, 32, PostIndex, pc, DTRAddr(sp, DtrOffImm(4))); -} - JitCode * JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) { @@ -697,20 +667,10 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) } JitCode * -JitRuntime::generateBailoutHandler(JSContext *cx, ExecutionMode mode) +JitRuntime::generateBailoutHandler(JSContext *cx) { MacroAssembler masm(cx); - - switch (mode) { - case SequentialExecution: - GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); - break; - case ParallelExecution: - GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID); - break; - default: - MOZ_CRASH("No such execution mode"); - } + GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); AutoFlushICache afc("BailoutHandler"); @@ -753,7 +713,8 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) if (f.expectTailCall == NonTailCall) masm.pushReturnAddress(); - masm.enterExitFrameAndLoadContext(&f, cxreg, regs.getAny(), f.executionMode); + masm.enterExitFrame(&f); + masm.loadJSContext(cxreg); // Save the base of the argument set stored on the stack. Register argsBase = InvalidReg; @@ -841,10 +802,10 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // Test for failure. switch (f.failType()) { case Type_Object: - masm.branchTestPtr(Assembler::Zero, r0, r0, masm.failureLabel(f.executionMode)); + masm.branchTestPtr(Assembler::Zero, r0, r0, masm.failureLabel()); break; case Type_Bool: - masm.branchIfFalseBool(r0, masm.failureLabel(f.executionMode)); + masm.branchIfFalseBool(r0, masm.failureLabel()); break; default: MOZ_CRASH("unknown failure kind"); diff --git a/js/src/jit/mips/Bailouts-mips.cpp b/js/src/jit/mips/Bailouts-mips.cpp index 30f6b71a0deb..a492ea617285 100644 --- a/js/src/jit/mips/Bailouts-mips.cpp +++ b/js/src/jit/mips/Bailouts-mips.cpp @@ -22,10 +22,7 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations, JSScript *script = ScriptFromCalleeToken(((JitFrameLayout *) framePointer_)->calleeToken()); JitActivation *activation = activations.activation()->asJit(); - if (activation->cx()->isForkJoinContext()) - topIonScript_ = script->parallelIonScript(); - else - topIonScript_ = script->ionScript(); + topIonScript_ = script->ionScript(); attachOnJitActivation(activations); diff --git a/js/src/jit/mips/CodeGenerator-mips.cpp b/js/src/jit/mips/CodeGenerator-mips.cpp index 7f1db3b42b80..b8ef7f19c07a 100644 --- a/js/src/jit/mips/CodeGenerator-mips.cpp +++ b/js/src/jit/mips/CodeGenerator-mips.cpp @@ -168,7 +168,7 @@ CodeGeneratorMIPS::generateOutOfLineCode() // the same. masm.move32(Imm32(frameSize()), ra); - JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(gen->info().executionMode()); + JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(); masm.branch(handler); } @@ -2151,15 +2151,3 @@ CodeGeneratorMIPS::visitNegF(LNegF *ins) masm.as_negs(output, input); } - -void -CodeGeneratorMIPS::visitForkJoinGetSlice(LForkJoinGetSlice *ins) -{ - MOZ_CRASH("NYI"); -} - -JitCode * -JitRuntime::generateForkJoinGetSliceStub(JSContext *cx) -{ - MOZ_CRASH("NYI"); -} diff --git a/js/src/jit/mips/CodeGenerator-mips.h b/js/src/jit/mips/CodeGenerator-mips.h index bd6427a4f339..b5f1317d32de 100644 --- a/js/src/jit/mips/CodeGenerator-mips.h +++ b/js/src/jit/mips/CodeGenerator-mips.h @@ -264,8 +264,6 @@ class CodeGeneratorMIPS : public CodeGeneratorShared void visitAsmJSPassStackArg(LAsmJSPassStackArg *ins); - void visitForkJoinGetSlice(LForkJoinGetSlice *ins); - void generateInvalidateEpilogue(); protected: diff --git a/js/src/jit/mips/Lowering-mips.cpp b/js/src/jit/mips/Lowering-mips.cpp index 69927b39263c..45513b6e244d 100644 --- a/js/src/jit/mips/Lowering-mips.cpp +++ b/js/src/jit/mips/Lowering-mips.cpp @@ -540,12 +540,6 @@ LIRGeneratorMIPS::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStati MOZ_CRASH("NYI"); } -void -LIRGeneratorMIPS::visitForkJoinGetSlice(MForkJoinGetSlice *ins) -{ - MOZ_CRASH("NYI"); -} - void LIRGeneratorMIPS::visitSimdBinaryArith(MSimdBinaryArith *ins) { diff --git a/js/src/jit/mips/Lowering-mips.h b/js/src/jit/mips/Lowering-mips.h index a2277d87af76..32a4296f96bb 100644 --- a/js/src/jit/mips/Lowering-mips.h +++ b/js/src/jit/mips/Lowering-mips.h @@ -38,12 +38,6 @@ class LIRGeneratorMIPS : public LIRGeneratorShared bool needTempForPostBarrier() { return false; } - // MIPS has a scratch register, so no need for another temp for dispatch - // ICs. - LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) { - return LDefinition::BogusTemp(); - } - void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); void defineUntypedPhi(MPhi *phi, size_t lirIndex); void lowerForShift(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir, MDefinition *lhs, @@ -106,7 +100,6 @@ class LIRGeneratorMIPS : public LIRGeneratorShared void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins); void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins); void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins); - void visitForkJoinGetSlice(MForkJoinGetSlice *ins); void visitSimdBinaryArith(MSimdBinaryArith *ins); void visitSimdSelect(MSimdSelect *ins); void visitSimdSplatX4(MSimdSplatX4 *ins); diff --git a/js/src/jit/mips/Trampoline-mips.cpp b/js/src/jit/mips/Trampoline-mips.cpp index 328de42e7323..d83bfb7ebd1d 100644 --- a/js/src/jit/mips/Trampoline-mips.cpp +++ b/js/src/jit/mips/Trampoline-mips.cpp @@ -16,11 +16,8 @@ #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" #endif -#include "jit/ParallelFunctions.h" #include "jit/VMFunctions.h" -#include "jit/ExecutionMode-inl.h" - using namespace js; using namespace js::jit; @@ -386,7 +383,7 @@ JitRuntime::generateInvalidator(JSContext *cx) } JitCode * -JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut) +JitRuntime::generateArgumentsRectifier(JSContext *cx, void **returnAddrOut) { MacroAssembler masm(cx); @@ -475,7 +472,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Note that this code assumes the function is JITted. masm.andPtr(Imm32(CalleeTokenMask), calleeTokenReg); masm.loadPtr(Address(calleeTokenReg, JSFunction::offsetOfNativeOrScript()), t1); - masm.loadBaselineOrIonRaw(t1, t1, mode, nullptr); + masm.loadBaselineOrIonRaw(t1, t1, nullptr); masm.ma_callJitHalfPush(t1); uint32_t returnOffset = masm.currentOffset(); @@ -618,32 +615,6 @@ GenerateBailoutThunk(JSContext *cx, MacroAssembler &masm, uint32_t frameClass) masm.branch(bailoutTail); } -static void -GenerateParallelBailoutThunk(MacroAssembler &masm, uint32_t frameClass) -{ - // As GenerateBailoutThunk, except we return an error immediately. We do - // the bailout dance so that we can walk the stack and have accurate - // reporting of frame information. - - PushBailoutFrame(masm, frameClass, a0); - - // Parallel bailout is like parallel failure in that we unwind all the way - // to the entry frame. Reserve space for the frame pointer of the entry frame. - const int sizeOfEntryFramePointer = sizeof(uint8_t *) * 2; - masm.reserveStack(sizeOfEntryFramePointer); - masm.movePtr(sp, a1); - - masm.setupAlignedABICall(2); - masm.passABIArg(a0); - masm.passABIArg(a1); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, BailoutPar)); - - // Get the frame pointer of the entry frame and return. - masm.moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - masm.loadPtr(Address(sp, 0), sp); - masm.ret(); -} - JitCode * JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) { @@ -674,20 +645,10 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) } JitCode * -JitRuntime::generateBailoutHandler(JSContext *cx, ExecutionMode mode) +JitRuntime::generateBailoutHandler(JSContext *cx) { MacroAssembler masm(cx); - - switch (mode) { - case SequentialExecution: - GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); - break; - case ParallelExecution: - GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID); - break; - default: - MOZ_CRASH("No such execution mode"); - } + GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); AutoFlushICache afc("BailoutHandler"); @@ -721,7 +682,8 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) regs.take(cxreg); // We're aligned to an exit frame, so link it up. - masm.enterExitFrameAndLoadContext(&f, cxreg, regs.getAny(), f.executionMode); + masm.enterExitFrame(&f); + masm.loadJSContext(cxreg); // Save the base of the argument set stored on the stack. Register argsBase = InvalidReg; @@ -832,11 +794,11 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // Test for failure. switch (f.failType()) { case Type_Object: - masm.branchTestPtr(Assembler::Zero, v0, v0, masm.failureLabel(f.executionMode)); + masm.branchTestPtr(Assembler::Zero, v0, v0, masm.failureLabel()); break; case Type_Bool: // Called functions return bools, which are 0/false and non-zero/true - masm.branchIfFalseBool(v0, masm.failureLabel(f.executionMode)); + masm.branchIfFalseBool(v0, masm.failureLabel()); break; default: MOZ_CRASH("unknown failure kind"); diff --git a/js/src/jit/none/Lowering-none.h b/js/src/jit/none/Lowering-none.h index 09f6924b1bcd..a3726ec0221f 100644 --- a/js/src/jit/none/Lowering-none.h +++ b/js/src/jit/none/Lowering-none.h @@ -32,7 +32,6 @@ class LIRGeneratorNone : public LIRGeneratorShared LDefinition tempByteOpRegister() { MOZ_CRASH(); } LDefinition tempToUnbox() { MOZ_CRASH(); } bool needTempForPostBarrier() { MOZ_CRASH(); } - LDefinition tempForDispatchCache(MIRType v = MIRType_None) { MOZ_CRASH(); } void lowerUntypedPhiInput(MPhi *, uint32_t, LBlock *, size_t) { MOZ_CRASH(); } void defineUntypedPhi(MPhi *, size_t) { MOZ_CRASH(); } void lowerForShift(LInstructionHelper<1, 2, 0> *, MDefinition *, MDefinition *, MDefinition *) { @@ -78,7 +77,6 @@ class LIRGeneratorNone : public LIRGeneratorShared void visitAsmJSStoreHeap(MAsmJSStoreHeap *ins) { MOZ_CRASH(); } void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins) { MOZ_CRASH(); } void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins) { MOZ_CRASH(); } - void visitForkJoinGetSlice(MForkJoinGetSlice *ins) { MOZ_CRASH(); } void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop *ins) { MOZ_CRASH(); } void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins) { MOZ_CRASH(); } void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) { MOZ_CRASH(); } diff --git a/js/src/jit/none/Trampoline-none.cpp b/js/src/jit/none/Trampoline-none.cpp index 3e8d65b088f7..fd1fbbfcdb0f 100644 --- a/js/src/jit/none/Trampoline-none.cpp +++ b/js/src/jit/none/Trampoline-none.cpp @@ -19,15 +19,14 @@ using namespace js::jit; JitCode *JitRuntime::generateEnterJIT(JSContext *, EnterJitType) { MOZ_CRASH(); } JitCode *JitRuntime::generateInvalidator(JSContext *) { MOZ_CRASH(); } -JitCode *JitRuntime::generateArgumentsRectifier(JSContext *, ExecutionMode, void **) { MOZ_CRASH(); } +JitCode *JitRuntime::generateArgumentsRectifier(JSContext *, void **) { MOZ_CRASH(); } JitCode *JitRuntime::generateBailoutTable(JSContext *, uint32_t) { MOZ_CRASH(); } -JitCode *JitRuntime::generateBailoutHandler(JSContext *, ExecutionMode) { MOZ_CRASH(); } +JitCode *JitRuntime::generateBailoutHandler(JSContext *) { MOZ_CRASH(); } JitCode *JitRuntime::generateVMWrapper(JSContext *, const VMFunction &) { MOZ_CRASH(); } JitCode *JitRuntime::generatePreBarrier(JSContext *, MIRType) { MOZ_CRASH(); } JitCode *JitRuntime::generateDebugTrapHandler(JSContext *) { MOZ_CRASH(); } JitCode *JitRuntime::generateExceptionTailStub(JSContext *, void *) { MOZ_CRASH(); } JitCode *JitRuntime::generateBailoutTailStub(JSContext *) { MOZ_CRASH(); } -JitCode *JitRuntime::generateForkJoinGetSliceStub(JSContext *) { MOZ_CRASH(); } FrameSizeClass FrameSizeClass::FromDepth(uint32_t) { MOZ_CRASH(); } FrameSizeClass FrameSizeClass::ClassLimit() { MOZ_CRASH(); } diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index fb6689174ad9..d3fe18eab897 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -15,7 +15,6 @@ #include "jit/MacroAssembler.h" #include "jit/MIR.h" #include "jit/MIRGenerator.h" -#include "jit/ParallelFunctions.h" #include "js/Conversions.h" #include "vm/TraceLogging.h" @@ -494,13 +493,6 @@ CodeGeneratorShared::assignBailoutId(LSnapshot *snapshot) if (!deoptTable_) return false; - // We do not generate a bailout table for parallel code. - switch (gen->info().executionMode()) { - case SequentialExecution: break; - case ParallelExecution: return false; - default: MOZ_CRASH("No such execution mode"); - } - MOZ_ASSERT(frameClass_ != FrameSizeClass::None()); if (snapshot->bailoutId() != INVALID_BAILOUT_ID) @@ -974,9 +966,6 @@ CodeGeneratorShared::shouldVerifyOsiPointRegs(LSafepoint *safepoint) if (!checkOsiPointRegisters) return false; - if (gen->info().executionMode() != SequentialExecution) - return false; - if (safepoint->liveRegs().empty(true) && safepoint->liveRegs().empty(false)) return false; // No registers to check. @@ -1259,7 +1248,7 @@ CodeGeneratorShared::labelForBackedgeWithImplicitCheck(MBasicBlock *mir) } else { // The interrupt check should be the first instruction in the // loop header other than the initial label and move groups. - MOZ_ASSERT(iter->isInterruptCheck() || iter->isInterruptCheckPar()); + MOZ_ASSERT(iter->isInterruptCheck()); return nullptr; } } diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 3c70af1b7d9e..7a3729680274 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -17,7 +17,6 @@ #include "jit/Safepoints.h" #include "jit/Snapshots.h" #include "jit/VMFunctions.h" -#include "vm/ForkJoin.h" namespace js { namespace jit { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 859284281b23..dba0e2bcbe59 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -370,7 +370,7 @@ CodeGeneratorX86Shared::generateOutOfLineCode() // Push the frame size, so the handler can recover the IonScript. masm.push(Imm32(frameSize())); - JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(gen->info().executionMode()); + JitCode *handler = gen->jitRuntime()->getGenericBailoutHandler(); masm.jmp(ImmPtr(handler->raw()), Relocation::JITCODE); } @@ -3001,177 +3001,6 @@ CodeGeneratorX86Shared::visitSimdSelect(LSimdSelect *ins) masm.bitwiseOrX4(Operand(temp), output); } -void -CodeGeneratorX86Shared::visitForkJoinGetSlice(LForkJoinGetSlice *ins) -{ - MOZ_ASSERT(gen->info().executionMode() == ParallelExecution); - MOZ_ASSERT(ToRegister(ins->forkJoinContext()) == ForkJoinGetSliceReg_cx); - MOZ_ASSERT(ToRegister(ins->temp1()) == eax); - MOZ_ASSERT(ToRegister(ins->temp2()) == edx); - MOZ_ASSERT(ToRegister(ins->temp3()) == ForkJoinGetSliceReg_temp0); - MOZ_ASSERT(ToRegister(ins->temp4()) == ForkJoinGetSliceReg_temp1); - MOZ_ASSERT(ToRegister(ins->output()) == ForkJoinGetSliceReg_output); - - masm.call(gen->jitRuntime()->forkJoinGetSliceStub()); -} - -JitCode * -JitRuntime::generateForkJoinGetSliceStub(JSContext *cx) -{ - MacroAssembler masm(cx); - - // We need two fixed temps. We need to fix eax for cmpxchg, and edx for - // div. - Register cxReg = ForkJoinGetSliceReg_cx, worker = cxReg; - Register pool = ForkJoinGetSliceReg_temp0; - Register bounds = ForkJoinGetSliceReg_temp1; - Register output = ForkJoinGetSliceReg_output; - - MOZ_ASSERT(worker != eax && worker != edx); - MOZ_ASSERT(pool != eax && pool != edx); - MOZ_ASSERT(bounds != eax && bounds != edx); - MOZ_ASSERT(output != eax && output != edx); - - Label stealWork, noMoreWork, gotSlice; - Operand workerSliceBounds(Address(worker, ThreadPoolWorker::offsetOfSliceBounds())); - - // Clobber cx to load the worker. - masm.push(cxReg); - masm.loadPtr(Address(cxReg, ForkJoinContext::offsetOfWorker()), worker); - - // Load the thread pool, which is used in all cases below. - masm.loadThreadPool(pool); - - { - // Try to get a slice from the current thread. - Label getOwnSliceLoopHead; - masm.bind(&getOwnSliceLoopHead); - - // Load the slice bounds for the current thread. - masm.loadSliceBounds(worker, bounds); - - // The slice bounds is a uint32 composed from two uint16s: - // [ from , to ] - // ^~~~ ^~ - // upper 16 bits | lower 16 bits - masm.move32(bounds, output); - masm.shrl(Imm32(16), output); - - // If we don't have any slices left ourselves, move on to stealing. - masm.branch16(Assembler::Equal, output, bounds, &stealWork); - - // If we still have work, try to CAS [ from+1, to ]. - masm.move32(bounds, edx); - masm.add32(Imm32(0x10000), edx); - masm.move32(bounds, eax); - masm.atomic_cmpxchg32(edx, workerSliceBounds, eax); - masm.j(Assembler::NonZero, &getOwnSliceLoopHead); - - // If the CAS succeeded, return |from| in output. - masm.jump(&gotSlice); - } - - // Try to steal work. - masm.bind(&stealWork); - - // It's not technically correct to test whether work-stealing is turned on - // only during stub-generation time, but it's a DEBUG only thing. - // - // If stealing is off, stealWork falls through to noMoreWork. - if (cx->runtime()->threadPool.workStealing()) { - Label stealWorkLoopHead; - masm.bind(&stealWorkLoopHead); - - // Check if we have work. - masm.branch32(Assembler::Equal, - Address(pool, ThreadPool::offsetOfPendingSlices()), - Imm32(0), &noMoreWork); - - // Get an id at random. The following is an inline of - // the 32-bit xorshift in ThreadPoolWorker::randomWorker(). - { - // Reload the current worker. - masm.loadPtr(Address(StackPointer, 0), cxReg); - masm.loadPtr(Address(cxReg, ForkJoinContext::offsetOfWorker()), worker); - - // Perform the xorshift to get a random number in eax, using edx - // as a temp. - Address rngState(worker, ThreadPoolWorker::offsetOfSchedulerRNGState()); - masm.load32(rngState, eax); - masm.move32(eax, edx); - masm.shll(Imm32(ThreadPoolWorker::XORSHIFT_A), eax); - masm.xor32(edx, eax); - masm.move32(eax, edx); - masm.shrl(Imm32(ThreadPoolWorker::XORSHIFT_B), eax); - masm.xor32(edx, eax); - masm.move32(eax, edx); - masm.shll(Imm32(ThreadPoolWorker::XORSHIFT_C), eax); - masm.xor32(edx, eax); - masm.store32(eax, rngState); - - // Compute the random worker id by computing % numWorkers. Reuse - // output as a temp. - masm.move32(Imm32(0), edx); - masm.move32(Imm32(cx->runtime()->threadPool.numWorkers()), output); - masm.udiv(output); - } - - // Load the worker from the workers array. - masm.loadPtr(Address(pool, ThreadPool::offsetOfWorkers()), worker); - masm.loadPtr(BaseIndex(worker, edx, ScalePointer), worker); - - // Try to get a slice from the designated victim worker. - Label stealSliceFromWorkerLoopHead; - masm.bind(&stealSliceFromWorkerLoopHead); - - // Load the slice bounds and decompose for the victim worker. - masm.loadSliceBounds(worker, bounds); - masm.move32(bounds, eax); - masm.shrl(Imm32(16), eax); - - // If the victim worker has no more slices left, find another worker. - masm.branch16(Assembler::Equal, eax, bounds, &stealWorkLoopHead); - - // If the victim worker still has work, try to CAS [ from, to-1 ]. - masm.move32(bounds, output); - masm.sub32(Imm32(1), output); - masm.move32(bounds, eax); - masm.atomic_cmpxchg32(output, workerSliceBounds, eax); - masm.j(Assembler::NonZero, &stealSliceFromWorkerLoopHead); - - // If the CAS succeeded, return |to-1| in output. -#ifdef DEBUG - masm.atomic_inc32(Operand(Address(pool, ThreadPool::offsetOfStolenSlices()))); -#endif - // Copies lower 16 bits only. - masm.movzwl(output, output); - } else { - masm.jump(&noMoreWork); - } - - // If we successfully got a slice, decrement pool->pendingSlices_ and - // return the slice. - masm.bind(&gotSlice); - masm.atomic_dec32(Operand(Address(pool, ThreadPool::offsetOfPendingSlices()))); - masm.pop(cxReg); - masm.ret(); - - // There's no more slices to give out, return a sentinel value. - masm.bind(&noMoreWork); - masm.move32(Imm32(ThreadPool::MAX_SLICE_ID), output); - masm.pop(cxReg); - masm.ret(); - - Linker linker(masm); - JitCode *code = linker.newCode(cx, OTHER_CODE); - -#ifdef JS_ION_PERF - writePerfSpewerJitCodeProfile(code, "ForkJoinGetSliceStub"); -#endif - - return code; -} - void CodeGeneratorX86Shared::visitMemoryBarrier(LMemoryBarrier *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index 8e7a57666d0d..86df43cb8483 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -207,8 +207,6 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared void visitOutOfLineLoadTypedArrayOutOfBounds(OutOfLineLoadTypedArrayOutOfBounds *ool); - void visitForkJoinGetSlice(LForkJoinGetSlice *ins); - void visitNegI(LNegI *lir); void visitNegD(LNegD *lir); void visitNegF(LNegF *lir); diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h index 245ffba3935e..e2907131e3fe 100644 --- a/js/src/jit/shared/Lowering-shared.h +++ b/js/src/jit/shared/Lowering-shared.h @@ -218,11 +218,6 @@ class LIRGeneratorShared : public MDefinitionVisitor return false; } - // Whether we can inline ForkJoinGetSlice. - static bool allowInlineForkJoinGetSlice() { - return false; - } - }; } // namespace jit diff --git a/js/src/jit/shared/Lowering-x86-shared.cpp b/js/src/jit/shared/Lowering-x86-shared.cpp index 1f5759350c66..0e1178443f11 100644 --- a/js/src/jit/shared/Lowering-x86-shared.cpp +++ b/js/src/jit/shared/Lowering-x86-shared.cpp @@ -358,19 +358,6 @@ LIRGeneratorX86Shared::lowerTruncateFToInt32(MTruncateToInt32 *ins) define(new(alloc()) LTruncateFToInt32(useRegister(opd), maybeTemp), ins); } -void -LIRGeneratorX86Shared::visitForkJoinGetSlice(MForkJoinGetSlice *ins) -{ - // We fix eax and edx for cmpxchg and div. - LForkJoinGetSlice *lir = new(alloc()) - LForkJoinGetSlice(useFixed(ins->forkJoinContext(), ForkJoinGetSliceReg_cx), - tempFixed(eax), - tempFixed(edx), - tempFixed(ForkJoinGetSliceReg_temp0), - tempFixed(ForkJoinGetSliceReg_temp1)); - defineFixed(lir, ins, LAllocation(AnyRegister(ForkJoinGetSliceReg_output))); -} - void LIRGeneratorX86Shared::visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins) { diff --git a/js/src/jit/shared/Lowering-x86-shared.h b/js/src/jit/shared/Lowering-x86-shared.h index 8c03f9a29e15..5b52c3053bd4 100644 --- a/js/src/jit/shared/Lowering-x86-shared.h +++ b/js/src/jit/shared/Lowering-x86-shared.h @@ -52,7 +52,6 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared void lowerConstantFloat32(float d, MInstruction *ins); void lowerTruncateDToInt32(MTruncateToInt32 *ins); void lowerTruncateFToInt32(MTruncateToInt32 *ins); - void visitForkJoinGetSlice(MForkJoinGetSlice *ins); void visitSimdBinaryArith(MSimdBinaryArith *ins); void visitSimdSelect(MSimdSelect *ins); void visitSimdSplatX4(MSimdSplatX4 *ins); diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index 1419c0d976cf..1b9619912c12 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -134,13 +134,6 @@ static MOZ_CONSTEXPR_VAR uint32_t NumFloatArgRegs = 8; static MOZ_CONSTEXPR_VAR FloatRegister FloatArgRegs[NumFloatArgRegs] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 }; #endif -// The convention used by the ForkJoinGetSlice stub. None of these can be rax -// or rdx, which the stub also needs for cmpxchg and div, respectively. -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_cx = rdi; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_temp0 = rbx; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_temp1 = rcx; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_output = rsi; - // Registers used in the GenerateFFIIonExit Enable Activation block. static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = r10; static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = rax; diff --git a/js/src/jit/x64/Bailouts-x64.cpp b/js/src/jit/x64/Bailouts-x64.cpp index 74bdd79b2864..6e4b61a0d8f8 100644 --- a/js/src/jit/x64/Bailouts-x64.cpp +++ b/js/src/jit/x64/Bailouts-x64.cpp @@ -54,11 +54,7 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations, topFrameSize_ = framePointer_ - sp; JSScript *script = ScriptFromCalleeToken(((JitFrameLayout *) framePointer_)->calleeToken()); - JitActivation *activation = activations.activation()->asJit(); - if (activation->cx()->isForkJoinContext()) - topIonScript_ = script->parallelIonScript(); - else - topIonScript_ = script->ionScript(); + topIonScript_ = script->ionScript(); attachOnJitActivation(activations); snapshotOffset_ = bailout->snapshotOffset(); diff --git a/js/src/jit/x64/Lowering-x64.h b/js/src/jit/x64/Lowering-x64.h index 842e3d35a5e2..cfbaaa741857 100644 --- a/js/src/jit/x64/Lowering-x64.h +++ b/js/src/jit/x64/Lowering-x64.h @@ -38,12 +38,6 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared bool needTempForPostBarrier() { return false; } - // x64 has a scratch register, so no need for another temp for dispatch - // ICs. - LDefinition tempForDispatchCache(MIRType outputType = MIRType_None) { - return LDefinition::BogusTemp(); - } - public: void visitBox(MBox *box); void visitUnbox(MUnbox *unbox); @@ -55,10 +49,6 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins); void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins); void visitSubstr(MSubstr *ins); - - static bool allowInlineForkJoinGetSlice() { - return true; - } }; typedef LIRGeneratorX64 LIRGeneratorSpecific; diff --git a/js/src/jit/x64/Trampoline-x64.cpp b/js/src/jit/x64/Trampoline-x64.cpp index 86038c1692c7..d2a506c5461e 100644 --- a/js/src/jit/x64/Trampoline-x64.cpp +++ b/js/src/jit/x64/Trampoline-x64.cpp @@ -11,7 +11,6 @@ #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" #endif -#include "jit/ParallelFunctions.h" #include "jit/VMFunctions.h" #include "jit/x64/BaselineHelpers-x64.h" @@ -358,7 +357,7 @@ JitRuntime::generateInvalidator(JSContext *cx) } JitCode * -JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut) +JitRuntime::generateArgumentsRectifier(JSContext *cx, void **returnAddrOut) { // Do not erase the frame pointer in this function. @@ -421,7 +420,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Note that this code assumes the function is JITted. masm.andq(Imm32(uint32_t(CalleeTokenMask)), rax); masm.loadPtr(Address(rax, JSFunction::offsetOfNativeOrScript()), rax); - masm.loadBaselineOrIonRaw(rax, rax, mode, nullptr); + masm.loadBaselineOrIonRaw(rax, rax, nullptr); masm.call(rax); uint32_t returnOffset = masm.currentOffset(); @@ -493,31 +492,6 @@ GenerateBailoutThunk(JSContext *cx, MacroAssembler &masm, uint32_t frameClass) masm.jmp(bailoutTail); } -static void -GenerateParallelBailoutThunk(MacroAssembler &masm) -{ - // As GenerateBailoutThunk, except we return an error immediately. We do - // the bailout dance so that we can walk the stack and have accurate - // reporting of frame information. - - PushBailoutFrame(masm, r8); - - // Parallel bailout is like parallel failure in that we unwind all the way - // to the entry frame. Reserve space for the frame pointer of the entry frame. - masm.reserveStack(sizeof(uint8_t *)); - masm.movePtr(rsp, r9); - - masm.setupUnalignedABICall(2, rax); - masm.passABIArg(r8); - masm.passABIArg(r9); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, BailoutPar)); - - // Get the frame pointer of the entry frame and return. - masm.moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - masm.loadPtr(Address(rsp, 0), rsp); - masm.ret(); -} - JitCode * JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) { @@ -525,20 +499,10 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) } JitCode * -JitRuntime::generateBailoutHandler(JSContext *cx, ExecutionMode mode) +JitRuntime::generateBailoutHandler(JSContext *cx) { MacroAssembler masm; - - switch (mode) { - case SequentialExecution: - GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); - break; - case ParallelExecution: - GenerateParallelBailoutThunk(masm); - break; - default: - MOZ_CRASH("No such execution mode"); - } + GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); JitCode *code = linker.newCode(cx, OTHER_CODE); @@ -580,7 +544,8 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // +0 returnAddress // // We're aligned to an exit frame, so link it up. - masm.enterExitFrameAndLoadContext(&f, cxreg, regs.getAny(), f.executionMode); + masm.enterExitFrame(&f); + masm.loadJSContext(cxreg); // Save the current stack pointer as the base for copying arguments. Register argsBase = InvalidReg; @@ -665,11 +630,11 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // Test for failure. switch (f.failType()) { case Type_Object: - masm.branchTestPtr(Assembler::Zero, rax, rax, masm.failureLabel(f.executionMode)); + masm.branchTestPtr(Assembler::Zero, rax, rax, masm.failureLabel()); break; case Type_Bool: masm.testb(rax, rax); - masm.j(Assembler::Zero, masm.failureLabel(f.executionMode)); + masm.j(Assembler::Zero, masm.failureLabel()); break; default: MOZ_CRASH("unknown failure kind"); diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index b723cf0ccb47..58254e74b3b6 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -60,13 +60,6 @@ static MOZ_CONSTEXPR_VAR Register CallTempReg3 = ecx; static MOZ_CONSTEXPR_VAR Register CallTempReg4 = esi; static MOZ_CONSTEXPR_VAR Register CallTempReg5 = edx; -// The convention used by the ForkJoinGetSlice stub. None of these can be eax -// or edx, which the stub also needs for cmpxchg and div, respectively. -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_cx = edi; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_temp0 = ebx; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_temp1 = ecx; -static MOZ_CONSTEXPR_VAR Register ForkJoinGetSliceReg_output = esi; - // We have no arg regs, so our NonArgRegs are just our CallTempReg* static MOZ_CONSTEXPR_VAR Register CallTempNonArgRegs[] = { edi, eax, ebx, ecx, esi, edx }; static const uint32_t NumCallTempNonArgRegs = diff --git a/js/src/jit/x86/Bailouts-x86.cpp b/js/src/jit/x86/Bailouts-x86.cpp index ef8577de3389..f0425b85f8ae 100644 --- a/js/src/jit/x86/Bailouts-x86.cpp +++ b/js/src/jit/x86/Bailouts-x86.cpp @@ -75,10 +75,7 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator &activations, JSScript *script = ScriptFromCalleeToken(((JitFrameLayout *) framePointer_)->calleeToken()); JitActivation *activation = activations.activation()->asJit(); - if (activation->cx()->isForkJoinContext()) - topIonScript_ = script->parallelIonScript(); - else - topIonScript_ = script->ionScript(); + topIonScript_ = script->ionScript(); attachOnJitActivation(activations); diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index 78a3dfce9528..030baecd9036 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -691,53 +691,6 @@ DispatchIonCache::initializeAddCacheState(LInstruction *ins, AddCacheState *addS MOZ_CRASH("x86 needs manual assignment of dispatchScratch"); } -void -GetPropertyParIC::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) -{ - // We don't have a scratch register, but only use the temp if we needed - // one, it's BogusTemp otherwise. - MOZ_ASSERT(ins->isGetPropertyCacheV() || ins->isGetPropertyCacheT()); - if (ins->isGetPropertyCacheV() || ins->toGetPropertyCacheT()->temp()->isBogusTemp()) - addState->dispatchScratch = output_.scratchReg().gpr(); - else - addState->dispatchScratch = ToRegister(ins->toGetPropertyCacheT()->temp()); -} - -void -GetElementParIC::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) -{ - // We don't have a scratch register, but only use the temp if we needed - // one, it's BogusTemp otherwise. - MOZ_ASSERT(ins->isGetElementCacheV() || ins->isGetElementCacheT()); - if (ins->isGetElementCacheV() || ins->toGetElementCacheT()->temp()->isBogusTemp()) - addState->dispatchScratch = output_.scratchReg().gpr(); - else - addState->dispatchScratch = ToRegister(ins->toGetElementCacheT()->temp()); -} - -void -SetPropertyParIC::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) -{ - // We don't have an output register to reuse, so we always need a temp. - MOZ_ASSERT(ins->isSetPropertyCacheV() || ins->isSetPropertyCacheT()); - if (ins->isSetPropertyCacheV()) - addState->dispatchScratch = ToRegister(ins->toSetPropertyCacheV()->tempForDispatchCache()); - else - addState->dispatchScratch = ToRegister(ins->toSetPropertyCacheT()->tempForDispatchCache()); -} - -void -SetElementParIC::initializeAddCacheState(LInstruction *ins, AddCacheState *addState) -{ - // We don't have an output register to reuse, but luckily SetElementCache - // already needs a temp. - MOZ_ASSERT(ins->isSetElementCacheV() || ins->isSetElementCacheT()); - if (ins->isSetElementCacheV()) - addState->dispatchScratch = ToRegister(ins->toSetElementCacheV()->temp()); - else - addState->dispatchScratch = ToRegister(ins->toSetElementCacheT()->temp()); -} - namespace js { namespace jit { diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp index 20da6ed49050..a304dae81435 100644 --- a/js/src/jit/x86/Lowering-x86.cpp +++ b/js/src/jit/x86/Lowering-x86.cpp @@ -14,29 +14,6 @@ using namespace js; using namespace js::jit; -LDefinition -LIRGeneratorX86::tempForDispatchCache(MIRType outputType) -{ - // x86 doesn't have a scratch register and we need one for the - // indirect jump for dispatch-style ICs. - // - // Note that currently we only install dispatch-style ICs for parallel - // execution. If this assumption changes, please change it here. - if (gen->info().executionMode() != ParallelExecution) - return LDefinition::BogusTemp(); - - // If we don't have an output register, we need a temp. - if (outputType == MIRType_None) - return temp(); - - // If we have a double output register, we need a temp. - if (outputType == MIRType_Double) - return temp(); - - // Otherwise we have a non-double output register and we can reuse it. - return LDefinition::BogusTemp(); -} - void LIRGeneratorX86::useBox(LInstruction *lir, size_t n, MDefinition *mir, LUse::Policy policy, bool useAtStart) diff --git a/js/src/jit/x86/Lowering-x86.h b/js/src/jit/x86/Lowering-x86.h index 947fcf5010c2..b4581d77cda6 100644 --- a/js/src/jit/x86/Lowering-x86.h +++ b/js/src/jit/x86/Lowering-x86.h @@ -41,8 +41,6 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared bool needTempForPostBarrier() { return true; } - LDefinition tempForDispatchCache(MIRType outputType = MIRType_None); - void lowerUntypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex); void defineUntypedPhi(MPhi *phi, size_t lirIndex); @@ -66,9 +64,6 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared static bool allowStaticTypedArrayAccesses() { return true; } - static bool allowInlineForkJoinGetSlice() { - return true; - } }; typedef LIRGeneratorX86 LIRGeneratorSpecific; diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp index 7837b7254fb8..7f6902822558 100644 --- a/js/src/jit/x86/Trampoline-x86.cpp +++ b/js/src/jit/x86/Trampoline-x86.cpp @@ -15,14 +15,11 @@ #ifdef JS_ION_PERF # include "jit/PerfSpewer.h" #endif -#include "jit/ParallelFunctions.h" #include "jit/VMFunctions.h" #include "jit/x86/BaselineHelpers-x86.h" #include "jsscriptinlines.h" -#include "jit/ExecutionMode-inl.h" - using namespace js; using namespace js::jit; @@ -354,7 +351,7 @@ JitRuntime::generateInvalidator(JSContext *cx) } JitCode * -JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut) +JitRuntime::generateArgumentsRectifier(JSContext *cx, void **returnAddrOut) { MacroAssembler masm(cx); @@ -425,7 +422,7 @@ JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Note that this assumes the function is JITted. masm.andl(Imm32(CalleeTokenMask), eax); masm.loadPtr(Address(eax, JSFunction::offsetOfNativeOrScript()), eax); - masm.loadBaselineOrIonRaw(eax, eax, mode, nullptr); + masm.loadBaselineOrIonRaw(eax, eax, nullptr); masm.call(eax); uint32_t returnOffset = masm.currentOffset(); @@ -516,31 +513,6 @@ GenerateBailoutThunk(JSContext *cx, MacroAssembler &masm, uint32_t frameClass) masm.jmp(bailoutTail); } -static void -GenerateParallelBailoutThunk(MacroAssembler &masm, uint32_t frameClass) -{ - // As GenerateBailoutThunk, except we return an error immediately. We do - // the bailout dance so that we can walk the stack and have accurate - // reporting of frame information. - - PushBailoutFrame(masm, frameClass, eax); - - // Parallel bailout is like parallel failure in that we unwind all the way - // to the entry frame. Reserve space for the frame pointer of the entry frame. - masm.reserveStack(sizeof(uint8_t *)); - masm.movePtr(esp, ebx); - - masm.setupUnalignedABICall(2, ecx); - masm.passABIArg(eax); - masm.passABIArg(ebx); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, BailoutPar)); - - // Get the frame pointer of the entry frame and return. - masm.moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - masm.loadPtr(Address(esp, 0), esp); - masm.ret(); -} - JitCode * JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) { @@ -564,20 +536,10 @@ JitRuntime::generateBailoutTable(JSContext *cx, uint32_t frameClass) } JitCode * -JitRuntime::generateBailoutHandler(JSContext *cx, ExecutionMode mode) +JitRuntime::generateBailoutHandler(JSContext *cx) { MacroAssembler masm; - - switch (mode) { - case SequentialExecution: - GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); - break; - case ParallelExecution: - GenerateParallelBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID); - break; - default: - MOZ_CRASH("No such execution mode"); - } + GenerateBailoutThunk(cx, masm, NO_FRAME_SIZE_CLASS_ID); Linker linker(masm); JitCode *code = linker.newCode(cx, OTHER_CODE); @@ -618,7 +580,8 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // +0 returnAddress // // We're aligned to an exit frame, so link it up. - masm.enterExitFrameAndLoadContext(&f, cxreg, regs.getAny(), f.executionMode); + masm.enterExitFrame(&f); + masm.loadJSContext(cxreg); // Save the current stack pointer as the base for copying arguments. Register argsBase = InvalidReg; @@ -704,11 +667,11 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f) // Test for failure. switch (f.failType()) { case Type_Object: - masm.branchTestPtr(Assembler::Zero, eax, eax, masm.failureLabel(f.executionMode)); + masm.branchTestPtr(Assembler::Zero, eax, eax, masm.failureLabel()); break; case Type_Bool: masm.testb(eax, eax); - masm.j(Assembler::Zero, masm.failureLabel(f.executionMode)); + masm.j(Assembler::Zero, masm.failureLabel()); break; default: MOZ_CRASH("unknown failure kind"); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index ad5c6ab79a2c..e67c502c0562 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -6772,8 +6772,7 @@ js::ReleaseAllJITCode(FreeOp *fop) for (ZoneCellIter i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); - jit::FinishInvalidation(fop, script); - jit::FinishInvalidation(fop, script); + jit::FinishInvalidation(fop, script); /* * Discard baseline script if it's not marked as active. Note that diff --git a/js/src/moz.build b/js/src/moz.build index 4df5248615e7..b608013226a4 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -178,8 +178,6 @@ UNIFIED_SOURCES += [ 'jit/MIR.cpp', 'jit/MIRGraph.cpp', 'jit/MoveResolver.cpp', - 'jit/ParallelFunctions.cpp', - 'jit/ParallelSafetyAnalysis.cpp', 'jit/PerfSpewer.cpp', 'jit/RangeAnalysis.cpp', 'jit/Recover.cpp', diff --git a/js/src/vm/ForkJoin.cpp b/js/src/vm/ForkJoin.cpp index ff80ab33773e..2bdc6353f2ac 100644 --- a/js/src/vm/ForkJoin.cpp +++ b/js/src/vm/ForkJoin.cpp @@ -206,8 +206,6 @@ class ForkJoinOperation bool invalidateBailedOutScripts(); ExecutionStatus sequentialExecution(bool disqualified); - TrafficLight appendCallTargetsToWorklist(uint32_t index, ExecutionStatus *status); - TrafficLight appendCallTargetToWorklist(HandleScript script, ExecutionStatus *status); bool addToWorklist(HandleScript script); inline bool hasScript(const types::RecompileInfoVector &scripts, JSScript *script); }; // class ForkJoinOperation @@ -677,7 +675,7 @@ ForkJoinOperation::compileForParallelExecution(ExecutionStatus *status) if (!script->hasParallelIonScript()) { // Script has not yet been compiled. Attempt to compile it. SpewBeginCompile(script); - MethodStatus mstatus = CanEnterInParallel(cx_, script); + MethodStatus mstatus = Method_Error; SpewEndCompile(mstatus); switch (mstatus) { @@ -727,8 +725,6 @@ ForkJoinOperation::compileForParallelExecution(ExecutionStatus *status) // worklist if so. Clear the flag after that, since we // will be compiling the call targets. MOZ_ASSERT(script->hasParallelIonScript()); - if (appendCallTargetsToWorklist(i, status) == RedLight) - return RedLight; } // If there is compilation occurring in a helper thread, then @@ -794,65 +790,6 @@ ForkJoinOperation::compileForParallelExecution(ExecutionStatus *status) return GreenLight; } -ForkJoinOperation::TrafficLight -ForkJoinOperation::appendCallTargetsToWorklist(uint32_t index, ExecutionStatus *status) -{ - // GreenLight: call targets appended - // RedLight: fatal error or completed work via warmups or fallback - - MOZ_ASSERT(worklist_[index]->hasParallelIonScript()); - - // Check whether we have already enqueued the targets for - // this entry and avoid doing it again if so. - if (worklistData_[index].calleesEnqueued) - return GreenLight; - worklistData_[index].calleesEnqueued = true; - - // Iterate through the callees and enqueue them. - RootedScript target(cx_); - IonScript *ion = worklist_[index]->parallelIonScript(); - for (uint32_t i = 0; i < ion->callTargetEntries(); i++) { - target = ion->callTargetList()[i]; - parallel::Spew(parallel::SpewCompile, - "Adding call target %s:%u", - target->filename(), target->lineno()); - if (appendCallTargetToWorklist(target, status) == RedLight) - return RedLight; - } - - return GreenLight; -} - -ForkJoinOperation::TrafficLight -ForkJoinOperation::appendCallTargetToWorklist(HandleScript script, ExecutionStatus *status) -{ - // GreenLight: call target appended if necessary - // RedLight: fatal error or completed work via warmups or fallback - - MOZ_ASSERT(script); - - // Fallback to sequential if disabled. - if (!script->canParallelIonCompile()) { - Spew(SpewCompile, "Skipping %p:%s:%u, canParallelIonCompile() is false", - script.get(), script->filename(), script->lineno()); - return sequentialExecution(true, status); - } - - if (script->hasParallelIonScript()) { - // Skip if the code is expected to result in a bailout. - if (script->parallelIonScript()->bailoutExpected()) { - Spew(SpewCompile, "Skipping %p:%s:%u, bailout expected", - script.get(), script->filename(), script->lineno()); - return sequentialExecution(false, status); - } - } - - if (!addToWorklist(script)) - return fatalError(status); - - return GreenLight; -} - bool ForkJoinOperation::addToWorklist(HandleScript script) { From 15a1da71fdc0a36c25b774c1aa00c56f0501de66 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Wed, 7 Jan 2015 22:02:35 -0800 Subject: [PATCH 123/224] Bug 1116143 - Patch bare callVMs correctly in debug mode OSR. (r=jandem) --- .../tests/debug/execution-observability-03.js | 17 ++ js/src/jit/BaselineCompiler.cpp | 6 +- js/src/jit/BaselineDebugModeOSR.cpp | 152 +++++++++++------- js/src/jit/BaselineIC.h | 10 +- js/src/jit/BaselineJIT.cpp | 37 ++++- js/src/jit/BaselineJIT.h | 1 + js/src/jit/shared/BaselineCompiler-shared.h | 7 + 7 files changed, 165 insertions(+), 65 deletions(-) create mode 100644 js/src/jit-test/tests/debug/execution-observability-03.js diff --git a/js/src/jit-test/tests/debug/execution-observability-03.js b/js/src/jit-test/tests/debug/execution-observability-03.js new file mode 100644 index 000000000000..bc46d46d4c88 --- /dev/null +++ b/js/src/jit-test/tests/debug/execution-observability-03.js @@ -0,0 +1,17 @@ +// Tests that bare callVMs (in the delprop below) are patched correctly. + +var o = {}; +var global = this; +var p = new Proxy(o, { + "deleteProperty": function (target, key) { + var g = newGlobal(); + g.parent = global; + g.eval("var dbg = new Debugger(parent); dbg.onEnterFrame = function(frame) {};"); + return true; + } +}); +function test() { + for (var i=0; i<100; i++) {} + assertEq(delete p.foo, true); +} +test(); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index ef0dafd0aa85..0dae386b55a7 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -551,7 +551,7 @@ BaselineCompiler::emitStackCheck(bool earlyCheck) else if (needsEarlyStackCheck()) phase = CHECK_OVER_RECURSED; - if (!callVM(CheckOverRecursedWithExtraInfo, phase)) + if (!callVMNonOp(CheckOverRecursedWithExtraInfo, phase)) return false; masm.bind(&skipCall); @@ -626,7 +626,7 @@ BaselineCompiler::initScopeChain() masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); pushArg(R0.scratchReg()); - if (!callVM(HeavyweightFunPrologueInfo, phase)) + if (!callVMNonOp(HeavyweightFunPrologueInfo, phase)) return false; } } else { @@ -640,7 +640,7 @@ BaselineCompiler::initScopeChain() masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); pushArg(R0.scratchReg()); - if (!callVM(StrictEvalPrologueInfo, phase)) + if (!callVMNonOp(StrictEvalPrologueInfo, phase)) return false; } } diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 225f13328d4a..da8d6fb40a20 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -350,8 +350,7 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab // // Off to On: // A. From a "can call" stub. - // B. From a VM call (interrupt handler, debugger statement handler, - // throw). + // B. From a VM call. // H. From inside HandleExceptionBaseline. // // On to Off: @@ -473,25 +472,27 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab bool popFrameReg; switch (kind) { - case ICEntry::Kind_CallVM: + case ICEntry::Kind_CallVM: { // Case B above. // - // Patching returns from an interrupt handler or the debugger - // statement handler is similar in that we can resume at the - // next op. + // Patching returns from a VM call. After fixing up the the + // continuation for unsynced values (the frame register is + // popped by the callVM trampoline), we resume at the + // return-from-callVM address. The assumption here is that all + // callVMs which can trigger debug mode OSR are the *only* + // callVMs generated for their respective pc locations in the + // baseline JIT code. // - // Throws are treated differently, as patching a throw means - // we are recompiling on-stack scripts from inside an - // onExceptionUnwind invocation. The resume address must be - // settled on the throwing pc and not its successor, so that - // Debugger.Frame may report the correct offset. Note we never - // actually resume execution there, and it is set for the sake - // of frame iterators. - if (!iter.baselineFrame()->isDebuggerHandlingException()) - pc += GetBytecodeLength(pc); - recompInfo->resumeAddr = bl->nativeCodeForPC(script, pc, &recompInfo->slotInfo); - popFrameReg = true; + // Get the slot info for the next pc, but ignore the code + // address. We get the code address from the + // return-from-callVM entry instead. + (void) bl->maybeNativeCodeForPC(script, pc + GetBytecodeLength(pc), + &recompInfo->slotInfo); + ICEntry &callVMEntry = bl->callVMEntryFromPCOffset(pcOffset); + recompInfo->resumeAddr = bl->returnAddressForIC(callVMEntry); + popFrameReg = false; break; + } case ICEntry::Kind_DebugTrap: // Case C above. @@ -906,12 +907,9 @@ HasForcedReturn(BaselineDebugModeOSRInfo *info, bool rv) return true; // |rv| is the value in ReturnReg. If true, in the case of the prologue, - // debug trap, and debugger statement handler, it means a forced return. - if (kind == ICEntry::Kind_DebugPrologue || - (kind == ICEntry::Kind_CallVM && JSOp(*info->pc) == JSOP_DEBUGGER)) - { + // it means a forced return. + if (kind == ICEntry::Kind_DebugPrologue) return rv; - } // N.B. The debug trap handler handles its own forced return, so no // need to deal with it here. @@ -934,13 +932,19 @@ SyncBaselineDebugModeOSRInfo(BaselineFrame *frame, Value *vp, bool rv) return; } - // Read stack values and make sure R0 and R1 have the right values. - unsigned numUnsynced = info->slotInfo.numUnsynced(); - MOZ_ASSERT(numUnsynced <= 2); - if (numUnsynced > 0) - info->popValueInto(info->slotInfo.topSlotLocation(), vp); - if (numUnsynced > 1) - info->popValueInto(info->slotInfo.nextSlotLocation(), vp); + // Read stack values and make sure R0 and R1 have the right values if we + // aren't returning from a callVM. + // + // In the case of returning from a callVM, we don't need to restore R0 and + // R1 ourself since we'll return into code that does it if needed. + if (info->frameKind != ICEntry::Kind_CallVM) { + unsigned numUnsynced = info->slotInfo.numUnsynced(); + MOZ_ASSERT(numUnsynced <= 2); + if (numUnsynced > 0) + info->popValueInto(info->slotInfo.topSlotLocation(), vp); + if (numUnsynced > 1) + info->popValueInto(info->slotInfo.nextSlotLocation(), vp); + } // Scale stackAdjust. info->stackAdjust *= sizeof(Value); @@ -985,6 +989,53 @@ JitRuntime::getBaselineDebugModeOSRHandlerAddress(JSContext *cx, bool popFrameRe : baselineDebugModeOSRHandlerNoFrameRegPopAddr_; } +static void +EmitBaselineDebugModeOSRHandlerTail(MacroAssembler &masm, Register temp, bool returnFromCallVM) +{ + // Save real return address on the stack temporarily. + // + // If we're returning from a callVM, we don't need to worry about R0 and + // R1 but do need to propagate the original ReturnReg value. Otherwise we + // need to worry about R0 and R1 but can clobber ReturnReg. Indeed, on + // x86, R1 contains ReturnReg. + if (returnFromCallVM) { + masm.push(ReturnReg); + } else { + masm.pushValue(Address(temp, offsetof(BaselineDebugModeOSRInfo, valueR0))); + masm.pushValue(Address(temp, offsetof(BaselineDebugModeOSRInfo, valueR1))); + } + masm.push(BaselineFrameReg); + masm.push(Address(temp, offsetof(BaselineDebugModeOSRInfo, resumeAddr))); + + // Call a stub to free the allocated info. + masm.setupUnalignedABICall(1, temp); + masm.loadBaselineFramePtr(BaselineFrameReg, temp); + masm.passABIArg(temp); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, FinishBaselineDebugModeOSR)); + + // Restore saved values. + GeneralRegisterSet jumpRegs(GeneralRegisterSet::All()); + if (returnFromCallVM) { + jumpRegs.take(ReturnReg); + } else { + jumpRegs.take(R0); + jumpRegs.take(R1); + } + jumpRegs.take(BaselineFrameReg); + Register target = jumpRegs.takeAny(); + + masm.pop(target); + masm.pop(BaselineFrameReg); + if (returnFromCallVM) { + masm.pop(ReturnReg); + } else { + masm.popValue(R1); + masm.popValue(R0); + } + + masm.jump(target); +} + JitCode * JitRuntime::generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrameRegPopOffsetOut) { @@ -1005,6 +1056,7 @@ JitRuntime::generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrame // Record the stack pointer for syncing. masm.movePtr(StackPointer, syncedStackStart); + masm.push(ReturnReg); masm.push(BaselineFrameReg); // Call a stub to fully initialize the info. @@ -1016,37 +1068,27 @@ JitRuntime::generateBaselineDebugModeOSRHandler(JSContext *cx, uint32_t *noFrame masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, SyncBaselineDebugModeOSRInfo)); // Discard stack values depending on how many were unsynced, as we always - // have a fully synced stack in the recompile handler. See assert in - // DebugModeOSREntry constructor. + // have a fully synced stack in the recompile handler. We arrive here via + // a callVM, and prepareCallVM in BaselineCompiler always fully syncs the + // stack. masm.pop(BaselineFrameReg); + masm.pop(ReturnReg); masm.loadPtr(Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfScratchValue()), temp); masm.addPtr(Address(temp, offsetof(BaselineDebugModeOSRInfo, stackAdjust)), StackPointer); - // Save real return address on the stack temporarily. - masm.pushValue(Address(temp, offsetof(BaselineDebugModeOSRInfo, valueR0))); - masm.pushValue(Address(temp, offsetof(BaselineDebugModeOSRInfo, valueR1))); - masm.push(BaselineFrameReg); - masm.push(Address(temp, offsetof(BaselineDebugModeOSRInfo, resumeAddr))); + // Emit two tails for the case of returning from a callVM and all other + // cases, as the state we need to restore differs depending on the case. + Label returnFromCallVM, end; + masm.branch32(MacroAssembler::Equal, + Address(temp, offsetof(BaselineDebugModeOSRInfo, frameKind)), + Imm32(ICEntry::Kind_CallVM), + &returnFromCallVM); - // Call a stub to free the allocated info. - masm.setupUnalignedABICall(1, temp); - masm.loadBaselineFramePtr(BaselineFrameReg, temp); - masm.passABIArg(temp); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, FinishBaselineDebugModeOSR)); - - // Restore saved values. - GeneralRegisterSet jumpRegs(GeneralRegisterSet::All()); - jumpRegs.take(R0); - jumpRegs.take(R1); - jumpRegs.take(BaselineFrameReg); - Register target = jumpRegs.takeAny(); - - masm.pop(target); - masm.pop(BaselineFrameReg); - masm.popValue(R1); - masm.popValue(R0); - - masm.jump(target); + EmitBaselineDebugModeOSRHandlerTail(masm, temp, /* returnFromCallVM = */ false); + masm.jump(&end); + masm.bind(&returnFromCallVM); + EmitBaselineDebugModeOSRHandlerTail(masm, temp, /* returnFromCallVM = */ true); + masm.bind(&end); Linker linker(masm); AutoFlushICache afc("BaselineDebugModeOSRHandler"); diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 4a8a2c94b44a..60de69df253d 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -222,9 +222,13 @@ class ICEntry // A non-op IC entry. Kind_NonOp, - // A fake IC entry for returning from a callVM. + // A fake IC entry for returning from a callVM for an op. Kind_CallVM, + // A fake IC entry for returning from a callVM not for an op (e.g., in + // the prologue). + Kind_NonOpCallVM, + // A fake IC entry for returning from DebugTrapHandler. Kind_DebugTrap, @@ -299,6 +303,10 @@ class ICEntry MOZ_ASSERT(kind() == Kind_CallVM); setKind(Kind_DebugEpilogue); } + void setForNonOpCallVM() { + MOZ_ASSERT(kind() == Kind_CallVM); + setKind(Kind_NonOpCallVM); + } bool hasStub() const { return firstStub_ != nullptr; diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 9383079d707d..584fed0c69ac 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -563,16 +563,14 @@ BaselineScript::returnAddressForIC(const ICEntry &ent) return method()->raw() + ent.returnOffset().offset(); } -ICEntry & -BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) +static inline size_t +ComputeBinarySearchMid(BaselineScript *baseline, uint32_t pcOffset) { - // Multiple IC entries can have the same PC offset, but this method only looks for - // those which have isForOp() set. size_t bottom = 0; - size_t top = numICEntries(); + size_t top = baseline->numICEntries(); size_t mid = bottom + (top - bottom) / 2; while (mid < top) { - ICEntry &midEntry = icEntry(mid); + ICEntry &midEntry = baseline->icEntry(mid); if (midEntry.pcOffset() < pcOffset) bottom = mid + 1; else if (midEntry.pcOffset() > pcOffset) @@ -581,6 +579,15 @@ BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) break; mid = bottom + (top - bottom) / 2; } + return mid; +} + +ICEntry & +BaselineScript::icEntryFromPCOffset(uint32_t pcOffset) +{ + // Multiple IC entries can have the same PC offset, but this method only looks for + // those which have isForOp() set. + size_t mid = ComputeBinarySearchMid(this, pcOffset); // Found an IC entry with a matching PC offset. Search backward, and then // forward from this IC entry, looking for one with the same PC offset which @@ -619,6 +626,24 @@ BaselineScript::icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntr return icEntryFromPCOffset(pcOffset); } +ICEntry & +BaselineScript::callVMEntryFromPCOffset(uint32_t pcOffset) +{ + // Like icEntryFromPCOffset, but only looks for the fake ICEntries + // inserted by VM calls. + size_t mid = ComputeBinarySearchMid(this, pcOffset); + + for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--) { + if (icEntry(i).kind() == ICEntry::Kind_CallVM) + return icEntry(i); + } + for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++) { + if (icEntry(i).kind() == ICEntry::Kind_CallVM) + return icEntry(i); + } + MOZ_CRASH("Invalid PC offset for callVM entry."); +} + ICEntry * BaselineScript::maybeICEntryFromReturnAddress(uint8_t *returnAddr) { diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 3f6fbeb83ded..c87be741045c 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -346,6 +346,7 @@ struct BaselineScript ICEntry &icEntryFromReturnOffset(CodeOffsetLabel returnOffset); ICEntry &icEntryFromPCOffset(uint32_t pcOffset); ICEntry &icEntryFromPCOffset(uint32_t pcOffset, ICEntry *prevLookedUpEntry); + ICEntry &callVMEntryFromPCOffset(uint32_t pcOffset); ICEntry *maybeICEntryFromReturnAddress(uint8_t *returnAddr); ICEntry &icEntryFromReturnAddress(uint8_t *returnAddr); uint8_t *returnAddressForIC(const ICEntry &ent); diff --git a/js/src/jit/shared/BaselineCompiler-shared.h b/js/src/jit/shared/BaselineCompiler-shared.h index e77715a691fb..fa7740bc2245 100644 --- a/js/src/jit/shared/BaselineCompiler-shared.h +++ b/js/src/jit/shared/BaselineCompiler-shared.h @@ -140,6 +140,13 @@ class BaselineCompilerShared }; bool callVM(const VMFunction &fun, CallVMPhase phase=POST_INITIALIZE); + bool callVMNonOp(const VMFunction &fun, CallVMPhase phase=POST_INITIALIZE) { + if (!callVM(fun, phase)) + return false; + icEntries_.back().setForNonOpCallVM(); + return true; + } + public: BytecodeAnalysis &analysis() { return analysis_; From 2c2568cc6ca6e3af9b145adba7695bdc31cc4c5c Mon Sep 17 00:00:00 2001 From: David Major Date: Thu, 8 Jan 2015 19:13:04 +1300 Subject: [PATCH 124/224] Bug 1119030: Make MOZ_CRASHes unique to prevent compiler folding. r=Waldo --HG-- extra : rebase_source : f8401e3eee6c62545553452e355c8213480a869d --- mfbt/Assertions.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mfbt/Assertions.h b/mfbt/Assertions.h index 771f254e6ede..50fee3036154 100644 --- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -198,7 +198,7 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {} # define MOZ_REALLY_CRASH() \ do { \ ::__debugbreak(); \ - *((volatile int*) NULL) = 123; \ + *((volatile int*) NULL) = __LINE__; \ ::TerminateProcess(::GetCurrentProcess(), 3); \ ::MOZ_NoReturn(); \ } while (0) @@ -206,7 +206,7 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {} # define MOZ_REALLY_CRASH() \ do { \ __debugbreak(); \ - *((volatile int*) NULL) = 123; \ + *((volatile int*) NULL) = __LINE__; \ TerminateProcess(GetCurrentProcess(), 3); \ MOZ_NoReturn(); \ } while (0) @@ -215,13 +215,13 @@ __declspec(noreturn) __inline void MOZ_NoReturn() {} # ifdef __cplusplus # define MOZ_REALLY_CRASH() \ do { \ - *((volatile int*) NULL) = 123; \ + *((volatile int*) NULL) = __LINE__; \ ::abort(); \ } while (0) # else # define MOZ_REALLY_CRASH() \ do { \ - *((volatile int*) NULL) = 123; \ + *((volatile int*) NULL) = __LINE__; \ abort(); \ } while (0) # endif From e20ab8cabfd6f9a22b5533096b03be215675cae2 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 18:28:09 +1100 Subject: [PATCH 125/224] Bug 1099807 part 1 - Add common superclass for ruby base and ruby text. r=dholbert --HG-- extra : source : 9dd5b0a847a1d698589c14e9dde5ced195eed646 --- layout/generic/moz.build | 1 + layout/generic/nsFrameIdList.h | 1 + layout/generic/nsRubyBaseFrame.cpp | 11 +-------- layout/generic/nsRubyBaseFrame.h | 5 ++-- layout/generic/nsRubyContentFrame.cpp | 34 +++++++++++++++++++++++++++ layout/generic/nsRubyContentFrame.h | 29 +++++++++++++++++++++++ layout/generic/nsRubyTextFrame.cpp | 10 +------- layout/generic/nsRubyTextFrame.h | 5 ++-- layout/generic/nsTextFrame.h | 5 ++++ 9 files changed, 76 insertions(+), 25 deletions(-) create mode 100644 layout/generic/nsRubyContentFrame.cpp create mode 100644 layout/generic/nsRubyContentFrame.h diff --git a/layout/generic/moz.build b/layout/generic/moz.build index a6d54eeaee42..be752630b8a0 100644 --- a/layout/generic/moz.build +++ b/layout/generic/moz.build @@ -82,6 +82,7 @@ UNIFIED_SOURCES += [ 'nsPlaceholderFrame.cpp', 'nsRubyBaseContainerFrame.cpp', 'nsRubyBaseFrame.cpp', + 'nsRubyContentFrame.cpp', 'nsRubyFrame.cpp', 'nsRubyTextContainerFrame.cpp', 'nsRubyTextFrame.cpp', diff --git a/layout/generic/nsFrameIdList.h b/layout/generic/nsFrameIdList.h index 56acdf6d70e8..aa04fc3f7c1c 100644 --- a/layout/generic/nsFrameIdList.h +++ b/layout/generic/nsFrameIdList.h @@ -116,6 +116,7 @@ FRAME_ID(nsResizerFrame) FRAME_ID(nsRootBoxFrame) FRAME_ID(nsRubyBaseContainerFrame) FRAME_ID(nsRubyBaseFrame) +FRAME_ID(nsRubyContentFrame) FRAME_ID(nsRubyFrame) FRAME_ID(nsRubyTextContainerFrame) FRAME_ID(nsRubyTextFrame) diff --git a/layout/generic/nsRubyBaseFrame.cpp b/layout/generic/nsRubyBaseFrame.cpp index 2257d2293f41..a3e0bf4a8f5b 100644 --- a/layout/generic/nsRubyBaseFrame.cpp +++ b/layout/generic/nsRubyBaseFrame.cpp @@ -21,7 +21,7 @@ using namespace mozilla; NS_QUERYFRAME_HEAD(nsRubyBaseFrame) NS_QUERYFRAME_ENTRY(nsRubyBaseFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsInlineFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsRubyBaseFrameSuper) NS_IMPL_FRAMEARENA_HELPERS(nsRubyBaseFrame) @@ -51,12 +51,3 @@ nsRubyBaseFrame::GetFrameName(nsAString& aResult) const return MakeFrameName(NS_LITERAL_STRING("RubyBase"), aResult); } #endif - -/* virtual */ bool -nsRubyBaseFrame::IsFrameOfType(uint32_t aFlags) const -{ - if (aFlags & eBidiInlineContainer) { - return false; - } - return nsRubyBaseFrameSuper::IsFrameOfType(aFlags); -} diff --git a/layout/generic/nsRubyBaseFrame.h b/layout/generic/nsRubyBaseFrame.h index a44c83c899cd..1841e0dcbbf7 100644 --- a/layout/generic/nsRubyBaseFrame.h +++ b/layout/generic/nsRubyBaseFrame.h @@ -9,9 +9,9 @@ #ifndef nsRubyBaseFrame_h___ #define nsRubyBaseFrame_h___ -#include "nsInlineFrame.h" +#include "nsRubyContentFrame.h" -typedef nsInlineFrame nsRubyBaseFrameSuper; +typedef nsRubyContentFrame nsRubyBaseFrameSuper; /** * Factory function. @@ -29,7 +29,6 @@ public: // nsIFrame overrides virtual nsIAtom* GetType() const MOZ_OVERRIDE; - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE; #ifdef DEBUG_FRAME_DUMP virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; diff --git a/layout/generic/nsRubyContentFrame.cpp b/layout/generic/nsRubyContentFrame.cpp new file mode 100644 index 000000000000..4ee855ab4e2e --- /dev/null +++ b/layout/generic/nsRubyContentFrame.cpp @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code is subject to the terms of the Mozilla Public License + * version 2.0 (the "License"). You can obtain a copy of the License at + * http://mozilla.org/MPL/2.0/. */ + +/* base class for ruby rendering objects that directly contain content */ + +#include "nsRubyContentFrame.h" +#include "nsPresContext.h" +#include "nsStyleContext.h" + +using namespace mozilla; + +//---------------------------------------------------------------------- + +// Frame class boilerplate +// ======================= + +NS_IMPL_FRAMEARENA_HELPERS(nsRubyContentFrame) + +//---------------------------------------------------------------------- + +// nsRubyContentFrame Method Implementations +// ====================================== + +/* virtual */ bool +nsRubyContentFrame::IsFrameOfType(uint32_t aFlags) const +{ + if (aFlags & eBidiInlineContainer) { + return false; + } + return nsRubyContentFrameSuper::IsFrameOfType(aFlags); +} diff --git a/layout/generic/nsRubyContentFrame.h b/layout/generic/nsRubyContentFrame.h new file mode 100644 index 000000000000..4422323c7a3a --- /dev/null +++ b/layout/generic/nsRubyContentFrame.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code is subject to the terms of the Mozilla Public License + * version 2.0 (the "License"). You can obtain a copy of the License at + * http://mozilla.org/MPL/2.0/. */ + +/* base class for ruby rendering objects that directly contain content */ + +#ifndef nsRubyContentFrame_h___ +#define nsRubyContentFrame_h___ + +#include "nsInlineFrame.h" + +typedef nsInlineFrame nsRubyContentFrameSuper; + +class nsRubyContentFrame : public nsRubyContentFrameSuper +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + // nsIFrame overrides + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE; + +protected: + explicit nsRubyContentFrame(nsStyleContext* aContext) + : nsRubyContentFrameSuper(aContext) {} +}; + +#endif /* nsRubyContentFrame_h___ */ diff --git a/layout/generic/nsRubyTextFrame.cpp b/layout/generic/nsRubyTextFrame.cpp index ed0f8c2112f5..04655e08d654 100644 --- a/layout/generic/nsRubyTextFrame.cpp +++ b/layout/generic/nsRubyTextFrame.cpp @@ -21,7 +21,7 @@ using namespace mozilla; NS_QUERYFRAME_HEAD(nsRubyTextFrame) NS_QUERYFRAME_ENTRY(nsRubyTextFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsInlineFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsRubyTextFrameSuper) NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextFrame) @@ -52,14 +52,6 @@ nsRubyTextFrame::GetFrameName(nsAString& aResult) const } #endif -/* virtual */ bool -nsRubyTextFrame::IsFrameOfType(uint32_t aFlags) const -{ - if (aFlags & eBidiInlineContainer) { - return false; - } - return nsRubyTextFrameSuper::IsFrameOfType(aFlags); -} /* virtual */ void diff --git a/layout/generic/nsRubyTextFrame.h b/layout/generic/nsRubyTextFrame.h index 287f970b6b65..582f0d44b341 100644 --- a/layout/generic/nsRubyTextFrame.h +++ b/layout/generic/nsRubyTextFrame.h @@ -9,9 +9,9 @@ #ifndef nsRubyTextFrame_h___ #define nsRubyTextFrame_h___ -#include "nsInlineFrame.h" +#include "nsRubyContentFrame.h" -typedef nsInlineFrame nsRubyTextFrameSuper; +typedef nsRubyContentFrame nsRubyTextFrameSuper; /** * Factory function. @@ -29,7 +29,6 @@ public: // nsIFrame overrides virtual nsIAtom* GetType() const MOZ_OVERRIDE; - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE; #ifdef DEBUG_FRAME_DUMP virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 16c0560dbc9b..15f70fb215f6 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -15,6 +15,11 @@ #include "nsDisplayList.h" #include "JustificationUtils.h" +// Undo the windows.h damage +#if defined(XP_WIN) && defined(DrawText) +#undef DrawText +#endif + class nsTextPaintStyle; class PropertyProvider; struct SelectionDetails; From 5f3951012f45eae888d6ac6effafb9b28f98c4c1 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 18:28:09 +1100 Subject: [PATCH 126/224] Bug 1099807 part 2 - Implement intra-level whitespace pairing. r=dholbert Line breaking is not handled properly in this patch. It would be fixed in the part 4. --HG-- extra : source : 49c457bbcd3a55f7ee65b007d50dd2884c7158af --- layout/generic/nsRubyBaseContainerFrame.cpp | 81 ++++++++++++++++--- layout/generic/nsRubyContentFrame.cpp | 14 ++++ layout/generic/nsRubyContentFrame.h | 7 ++ .../css-ruby/ruby-whitespace-1-ref.html | 2 +- 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 7deb0d7e88f0..e2ea4442ca1e 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -77,40 +77,83 @@ public: bool AtEnd() const; uint32_t GetLevelCount() const { return mFrames.Length(); } - nsIFrame* GetFrame(uint32_t aIndex) const { return mFrames[aIndex]; } - nsIFrame* GetBaseFrame() const { return GetFrame(0); } - nsIFrame* GetTextFrame(uint32_t aIndex) const { return GetFrame(aIndex + 1); } + nsRubyContentFrame* GetFrameAtLevel(uint32_t aIndex) const; void GetColumn(RubyColumn& aColumn) const; private: - nsAutoTArray mFrames; + // Frames in this array are NOT necessary part of the current column. + // When in doubt, use GetFrameAtLevel to access it. + // See GetFrameAtLevel() and Next() for more info. + nsAutoTArray mFrames; + // Whether we are on a column for intra-level whitespaces + bool mAtIntraLevelWhitespace; }; RubyColumnEnumerator::RubyColumnEnumerator( nsRubyBaseContainerFrame* aBaseContainer, const nsTArray& aTextContainers) + : mAtIntraLevelWhitespace(false) { const uint32_t rtcCount = aTextContainers.Length(); mFrames.SetCapacity(rtcCount + 1); - mFrames.AppendElement(aBaseContainer->GetFirstPrincipalChild()); + + nsIFrame* rbFrame = aBaseContainer->GetFirstPrincipalChild(); + MOZ_ASSERT(!rbFrame || rbFrame->GetType() == nsGkAtoms::rubyBaseFrame); + mFrames.AppendElement(static_cast(rbFrame)); for (uint32_t i = 0; i < rtcCount; i++) { nsRubyTextContainerFrame* container = aTextContainers[i]; // If the container is for span, leave a nullptr here. // Spans do not take part in pairing. nsIFrame* rtFrame = !container->IsSpanContainer() ? - aTextContainers[i]->GetFirstPrincipalChild() : nullptr; - mFrames.AppendElement(rtFrame); + container->GetFirstPrincipalChild() : nullptr; + MOZ_ASSERT(!rtFrame || rtFrame->GetType() == nsGkAtoms::rubyTextFrame); + mFrames.AppendElement(static_cast(rtFrame)); + } + + // We have to init mAtIntraLevelWhitespace to be correct for the + // first column. There are two ways we could end up with intra-level + // whitespace in our first colum: + // 1. The current segment itself is an inter-segment whitespace; + // 2. If our ruby segment is split across multiple lines, and some + // intra-level whitespace happens to fall right after a line-break. + // Each line will get its own nsRubyBaseContainerFrame, and the + // container right after the line-break will end up with its first + // column containing that intra-level whitespace. + for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) { + nsRubyContentFrame* frame = mFrames[i]; + if (frame && frame->IsIntraLevelWhitespace()) { + mAtIntraLevelWhitespace = true; + break; + } } } void RubyColumnEnumerator::Next() { + bool advancingToIntraLevelWhitespace = false; for (uint32_t i = 0, iend = mFrames.Length(); i < iend; i++) { - if (mFrames[i]) { - mFrames[i] = mFrames[i]->GetNextSibling(); + nsRubyContentFrame* frame = mFrames[i]; + // If we've got intra-level whitespace frames at some levels in the + // current ruby column, we "faked" an anonymous box for all other + // levels for this column. So when we advance off this column, we + // don't advance any of the frames in those levels, because we're + // just advancing across the "fake" frames. + if (frame && (!mAtIntraLevelWhitespace || + frame->IsIntraLevelWhitespace())) { + nsIFrame* nextSibling = frame->GetNextSibling(); + MOZ_ASSERT(!nextSibling || nextSibling->GetType() == frame->GetType(), + "Frame type should be identical among a level"); + mFrames[i] = frame = static_cast(nextSibling); + if (!advancingToIntraLevelWhitespace && + frame && frame->IsIntraLevelWhitespace()) { + advancingToIntraLevelWhitespace = true; + } } } + MOZ_ASSERT(!advancingToIntraLevelWhitespace || !mAtIntraLevelWhitespace, + "Should never have adjacent intra-level whitespace columns"); + mAtIntraLevelWhitespace = advancingToIntraLevelWhitespace; } bool @@ -124,13 +167,27 @@ RubyColumnEnumerator::AtEnd() const return true; } +nsRubyContentFrame* +RubyColumnEnumerator::GetFrameAtLevel(uint32_t aIndex) const +{ + // If the current ruby column is for intra-level whitespaces, we + // return nullptr for any levels that do not have an actual intra- + // level whitespace frame in this column. This nullptr represents + // an anonymous empty intra-level whitespace box. (In this case, + // it's important that we NOT return mFrames[aIndex], because it's + // really part of the next column, not the current one.) + nsRubyContentFrame* frame = mFrames[aIndex]; + return !mAtIntraLevelWhitespace || + (frame && frame->IsIntraLevelWhitespace()) ? frame : nullptr; +} + void RubyColumnEnumerator::GetColumn(RubyColumn& aColumn) const { - aColumn.mBaseFrame = mFrames[0]; + aColumn.mBaseFrame = GetFrameAtLevel(0); aColumn.mTextFrames.ClearAndRetainStorage(); for (uint32_t i = 1, iend = mFrames.Length(); i < iend; i++) { - aColumn.mTextFrames.AppendElement(mFrames[i]); + aColumn.mTextFrames.AppendElement(GetFrameAtLevel(i)); } } @@ -141,7 +198,7 @@ CalculateColumnPrefISize(nsRenderingContext* aRenderingContext, nscoord max = 0; uint32_t levelCount = aEnumerator.GetLevelCount(); for (uint32_t i = 0; i < levelCount; i++) { - nsIFrame* frame = aEnumerator.GetFrame(i); + nsIFrame* frame = aEnumerator.GetFrameAtLevel(i); if (frame) { max = std::max(max, frame->GetPrefISize(aRenderingContext)); } diff --git a/layout/generic/nsRubyContentFrame.cpp b/layout/generic/nsRubyContentFrame.cpp index 4ee855ab4e2e..12f9bc9c7777 100644 --- a/layout/generic/nsRubyContentFrame.cpp +++ b/layout/generic/nsRubyContentFrame.cpp @@ -9,6 +9,7 @@ #include "nsRubyContentFrame.h" #include "nsPresContext.h" #include "nsStyleContext.h" +#include "nsCSSAnonBoxes.h" using namespace mozilla; @@ -32,3 +33,16 @@ nsRubyContentFrame::IsFrameOfType(uint32_t aFlags) const } return nsRubyContentFrameSuper::IsFrameOfType(aFlags); } + +bool +nsRubyContentFrame::IsIntraLevelWhitespace() const +{ + nsIAtom* pseudoType = StyleContext()->GetPseudo(); + if (pseudoType != nsCSSAnonBoxes::rubyBase && + pseudoType != nsCSSAnonBoxes::rubyText) { + return false; + } + + nsIFrame* child = mFrames.OnlyChild(); + return child && child->GetContent()->TextIsOnlyWhitespace(); +} diff --git a/layout/generic/nsRubyContentFrame.h b/layout/generic/nsRubyContentFrame.h index 4422323c7a3a..6adb71474770 100644 --- a/layout/generic/nsRubyContentFrame.h +++ b/layout/generic/nsRubyContentFrame.h @@ -21,6 +21,13 @@ public: // nsIFrame overrides virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE; + // Indicates whether this is an "intra-level whitespace" frame, i.e. + // an anonymous frame that was created to contain non-droppable + // whitespaces directly inside a ruby level container. This impacts + // ruby pairing behavior. + // See http://dev.w3.org/csswg/css-ruby/#anon-gen-interpret-space + bool IsIntraLevelWhitespace() const; + protected: explicit nsRubyContentFrame(nsStyleContext* aContext) : nsRubyContentFrameSuper(aContext) {} diff --git a/layout/reftests/css-ruby/ruby-whitespace-1-ref.html b/layout/reftests/css-ruby/ruby-whitespace-1-ref.html index 18393f0d72d4..f932a5d2986f 100644 --- a/layout/reftests/css-ruby/ruby-whitespace-1-ref.html +++ b/layout/reftests/css-ruby/ruby-whitespace-1-ref.html @@ -29,7 +29,7 @@ body { line-height: 5em; } > Text three Base one Base threeText oneText two/three
+ >Text oneText two/three

From a7ba233d21423a539923d28f7b5f7fa926c97c37 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 18:28:09 +1100 Subject: [PATCH 127/224] Bug 1099807 part 3 - Use specific frame type in RubyColumn. r=dholbert --HG-- extra : source : 0d78d1c0d10d9b5e32c0843a258d29e12f1369c4 --- layout/generic/nsRubyBaseContainerFrame.cpp | 27 ++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index e2ea4442ca1e..ffc2e2cddc71 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -62,8 +62,8 @@ nsRubyBaseContainerFrame::GetFrameName(nsAString& aResult) const */ struct MOZ_STACK_CLASS mozilla::RubyColumn { - nsIFrame* mBaseFrame; - nsAutoTArray mTextFrames; + nsRubyBaseFrame* mBaseFrame; + nsAutoTArray mTextFrames; RubyColumn() : mBaseFrame(nullptr) { } }; @@ -184,10 +184,14 @@ RubyColumnEnumerator::GetFrameAtLevel(uint32_t aIndex) const void RubyColumnEnumerator::GetColumn(RubyColumn& aColumn) const { - aColumn.mBaseFrame = GetFrameAtLevel(0); + nsRubyContentFrame* rbFrame = GetFrameAtLevel(0); + MOZ_ASSERT(!rbFrame || rbFrame->GetType() == nsGkAtoms::rubyBaseFrame); + aColumn.mBaseFrame = static_cast(rbFrame); aColumn.mTextFrames.ClearAndRetainStorage(); for (uint32_t i = 1, iend = mFrames.Length(); i < iend; i++) { - aColumn.mTextFrames.AppendElement(GetFrameAtLevel(i)); + nsRubyContentFrame* rtFrame = GetFrameAtLevel(i); + MOZ_ASSERT(!rtFrame || rtFrame->GetType() == nsGkAtoms::rubyTextFrame); + aColumn.mTextFrames.AppendElement(static_cast(rtFrame)); } } @@ -581,7 +585,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const ReflowState& aReflowState, PushChildren(column.mBaseFrame, column.mBaseFrame->GetPrevSibling()); } for (uint32_t i = 0; i < rtcCount; i++) { - nsIFrame* textFrame = column.mTextFrames[i]; + nsRubyTextFrame* textFrame = column.mTextFrames[i]; if (textFrame) { aReflowState.mTextContainers[i]->PushChildren( textFrame, textFrame->GetPrevSibling()); @@ -625,9 +629,8 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const ReflowState& aReflowState, // Reflow text frames for (uint32_t i = 0; i < rtcCount; i++) { - nsIFrame* textFrame = aColumn.mTextFrames[i]; + nsRubyTextFrame* textFrame = aColumn.mTextFrames[i]; if (textFrame) { - MOZ_ASSERT(textFrame->GetType() == nsGkAtoms::rubyTextFrame); nsAutoString annotationText; if (!nsContentUtils::GetNodeTextContent(textFrame->GetContent(), true, annotationText)) { @@ -667,7 +670,6 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const ReflowState& aReflowState, // Reflow the base frame if (aColumn.mBaseFrame) { - MOZ_ASSERT(aColumn.mBaseFrame->GetType() == nsGkAtoms::rubyBaseFrame); nsReflowStatus reflowStatus; nsHTMLReflowMetrics metrics(baseReflowState); RubyUtils::ClearReservedISize(aColumn.mBaseFrame); @@ -694,7 +696,7 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const ReflowState& aReflowState, continue; } nsLineLayout* lineLayout = textReflowStates[i]->mLineLayout; - nsIFrame* textFrame = aColumn.mTextFrames[i]; + nsRubyTextFrame* textFrame = aColumn.mTextFrames[i]; nscoord deltaISize = icoord - lineLayout->GetCurrentICoord(); if (deltaISize > 0) { lineLayout->AdvanceICoord(deltaISize); @@ -738,14 +740,17 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout, const TextContainerArray& textContainers = aPullFrameState.mTextContainers; const uint32_t rtcCount = textContainers.Length(); - aColumn.mBaseFrame = PullNextInFlowChild(aPullFrameState.mBase); + nsIFrame* nextBase = PullNextInFlowChild(aPullFrameState.mBase); + MOZ_ASSERT(!nextBase || nextBase->GetType() == nsGkAtoms::rubyBaseFrame); + aColumn.mBaseFrame = static_cast(nextBase); aIsComplete = !aColumn.mBaseFrame; aColumn.mTextFrames.ClearAndRetainStorage(); for (uint32_t i = 0; i < rtcCount; i++) { nsIFrame* nextText = textContainers[i]->PullNextInFlowChild(aPullFrameState.mTexts[i]); - aColumn.mTextFrames.AppendElement(nextText); + MOZ_ASSERT(!nextText || nextText->GetType() == nsGkAtoms::rubyTextFrame); + aColumn.mTextFrames.AppendElement(static_cast(nextText)); // If there exists any frame in continations, we haven't // completed the reflow process. aIsComplete = aIsComplete && !nextText; From 8beb2f48211b5271f6203b61d6f9728be17e07e6 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 18:28:09 +1100 Subject: [PATCH 128/224] Bug 1099807 part 4 - Fix line breaking around ruby intra-level whitespaces. r=dholbert --HG-- extra : source : f6ebe9d9c7c863b18497e3c326f4486c5837a163 --- layout/generic/nsRubyBaseContainerFrame.cpp | 70 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index ffc2e2cddc71..0a613310b852 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -14,6 +14,8 @@ #include "nsStyleStructInlines.h" #include "WritingModes.h" #include "RubyUtils.h" +#include "mozilla/Maybe.h" +#include "mozilla/DebugOnly.h" using namespace mozilla; @@ -64,7 +66,8 @@ struct MOZ_STACK_CLASS mozilla::RubyColumn { nsRubyBaseFrame* mBaseFrame; nsAutoTArray mTextFrames; - RubyColumn() : mBaseFrame(nullptr) { } + bool mIsIntraLevelWhitespace; + RubyColumn() : mBaseFrame(nullptr), mIsIntraLevelWhitespace(false) { } }; class MOZ_STACK_CLASS RubyColumnEnumerator @@ -193,6 +196,7 @@ RubyColumnEnumerator::GetColumn(RubyColumn& aColumn) const MOZ_ASSERT(!rtFrame || rtFrame->GetType() == nsGkAtoms::rubyTextFrame); aColumn.mTextFrames.AppendElement(static_cast(rtFrame)); } + aColumn.mIsIntraLevelWhitespace = mAtIntraLevelWhitespace; } static nscoord @@ -581,11 +585,30 @@ nsRubyBaseContainerFrame::ReflowColumns(const ReflowState& aReflowState, aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); MOZ_ASSERT(NS_FRAME_IS_COMPLETE(aStatus) || aReflowState.mAllowLineBreak); - if (column.mBaseFrame) { - PushChildren(column.mBaseFrame, column.mBaseFrame->GetPrevSibling()); + // If we are on an intra-level whitespace column, null values in + // column.mBaseFrame and column.mTextFrames don't represent the + // end of the frame-sibling-chain at that level -- instead, they + // represent an anonymous empty intra-level whitespace box. It is + // likely that there are frames in the next column (which can't be + // intra-level whitespace). Those frames should be pushed as well. + Maybe nextColumn; + if (column.mIsIntraLevelWhitespace && !e.AtEnd()) { + e.Next(); + nextColumn.emplace(); + e.GetColumn(nextColumn.ref()); + } + nsIFrame* baseFrame = column.mBaseFrame; + if (!baseFrame & nextColumn.isSome()) { + baseFrame = nextColumn->mBaseFrame; + } + if (baseFrame) { + PushChildren(baseFrame, baseFrame->GetPrevSibling()); } for (uint32_t i = 0; i < rtcCount; i++) { nsRubyTextFrame* textFrame = column.mTextFrames[i]; + if (!textFrame && nextColumn.isSome()) { + textFrame = nextColumn->mTextFrames[i]; + } if (textFrame) { aReflowState.mTextContainers[i]->PushChildren( textFrame, textFrame->GetPrevSibling()); @@ -740,20 +763,55 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout, const TextContainerArray& textContainers = aPullFrameState.mTextContainers; const uint32_t rtcCount = textContainers.Length(); - nsIFrame* nextBase = PullNextInFlowChild(aPullFrameState.mBase); + nsIFrame* nextBase = GetNextInFlowChild(aPullFrameState.mBase); MOZ_ASSERT(!nextBase || nextBase->GetType() == nsGkAtoms::rubyBaseFrame); aColumn.mBaseFrame = static_cast(nextBase); aIsComplete = !aColumn.mBaseFrame; + bool pullingIntraLevelWhitespace = + aColumn.mBaseFrame && aColumn.mBaseFrame->IsIntraLevelWhitespace(); aColumn.mTextFrames.ClearAndRetainStorage(); for (uint32_t i = 0; i < rtcCount; i++) { nsIFrame* nextText = - textContainers[i]->PullNextInFlowChild(aPullFrameState.mTexts[i]); + textContainers[i]->GetNextInFlowChild(aPullFrameState.mTexts[i]); MOZ_ASSERT(!nextText || nextText->GetType() == nsGkAtoms::rubyTextFrame); - aColumn.mTextFrames.AppendElement(static_cast(nextText)); + nsRubyTextFrame* textFrame = static_cast(nextText); + aColumn.mTextFrames.AppendElement(textFrame); // If there exists any frame in continations, we haven't // completed the reflow process. aIsComplete = aIsComplete && !nextText; + if (nextText && !pullingIntraLevelWhitespace) { + pullingIntraLevelWhitespace = textFrame->IsIntraLevelWhitespace(); + } + } + + aColumn.mIsIntraLevelWhitespace = pullingIntraLevelWhitespace; + if (pullingIntraLevelWhitespace) { + // We are pulling an intra-level whitespace. Drop all frames which + // are not part of this intra-level whitespace column. (Those frames + // are really part of the *next* column, after the pulled one.) + if (aColumn.mBaseFrame && !aColumn.mBaseFrame->IsIntraLevelWhitespace()) { + aColumn.mBaseFrame = nullptr; + } + for (uint32_t i = 0; i < rtcCount; i++) { + nsRubyTextFrame*& textFrame = aColumn.mTextFrames[i]; + if (textFrame && !textFrame->IsIntraLevelWhitespace()) { + textFrame = nullptr; + } + } + } + + // Pull the frames of this column. + if (aColumn.mBaseFrame) { + DebugOnly pulled = PullNextInFlowChild(aPullFrameState.mBase); + MOZ_ASSERT(pulled == aColumn.mBaseFrame, "pulled a wrong frame?"); + } + for (uint32_t i = 0; i < rtcCount; i++) { + if (aColumn.mTextFrames[i]) { + DebugOnly pulled = + textContainers[i]->PullNextInFlowChild(aPullFrameState.mTexts[i]); + MOZ_ASSERT(pulled == aColumn.mTextFrames[i], "pulled a wrong frame?"); + } } if (!aIsComplete) { From e3953dff5fc23f89c7619919d2c3c8f8a93d2621 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 8 Jan 2015 18:28:09 +1100 Subject: [PATCH 129/224] Bug 1099807 part 5 - Reftests for ruby intra-level whitespaces. r=dholbert --HG-- extra : source : 0bbef725cf7f1abee96b98c7fe507f35115ecea9 --- .../intra-level-whitespace-1-ref.html | 22 ++++++++++++ .../css-ruby/intra-level-whitespace-1.html | 22 ++++++++++++ .../intra-level-whitespace-2-ref.html | 28 +++++++++++++++ .../css-ruby/intra-level-whitespace-2.html | 33 ++++++++++++++++++ .../intra-level-whitespace-3-ref.html | 14 ++++++++ .../css-ruby/intra-level-whitespace-3.html | 34 +++++++++++++++++++ layout/reftests/css-ruby/reftest.list | 3 ++ 7 files changed, 156 insertions(+) create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-1-ref.html create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-1.html create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-2-ref.html create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-2.html create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-3-ref.html create mode 100644 layout/reftests/css-ruby/intra-level-whitespace-3.html diff --git a/layout/reftests/css-ruby/intra-level-whitespace-1-ref.html b/layout/reftests/css-ruby/intra-level-whitespace-1-ref.html new file mode 100644 index 000000000000..502452166fbc --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-1-ref.html @@ -0,0 +1,22 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + +

+ a b + x y +

+

+ a b + xy +

+

+ ab + x y +

+ + diff --git a/layout/reftests/css-ruby/intra-level-whitespace-1.html b/layout/reftests/css-ruby/intra-level-whitespace-1.html new file mode 100644 index 000000000000..d1f23cbdb403 --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-1.html @@ -0,0 +1,22 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + +

+ a b + x y +

+

+ a b + xy +

+

+ ab + x y +

+ + diff --git a/layout/reftests/css-ruby/intra-level-whitespace-2-ref.html b/layout/reftests/css-ruby/intra-level-whitespace-2-ref.html new file mode 100644 index 000000000000..fe580bb4400c --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-2-ref.html @@ -0,0 +1,28 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + + + + 12345 12345 67890 +
12345 678900987654321
+
123456789009876 54321
+
12345 6789009876 54321
+ + + diff --git a/layout/reftests/css-ruby/intra-level-whitespace-2.html b/layout/reftests/css-ruby/intra-level-whitespace-2.html new file mode 100644 index 000000000000..f2eddba6cefe --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-2.html @@ -0,0 +1,33 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + + + + 12345 12345 67890 +
12345 678900987654321
+
123456789009876 54321
+
12345 6789009876 54321
+ + + diff --git a/layout/reftests/css-ruby/intra-level-whitespace-3-ref.html b/layout/reftests/css-ruby/intra-level-whitespace-3-ref.html new file mode 100644 index 000000000000..1e43d0eac99d --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-3-ref.html @@ -0,0 +1,14 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + + | + beforebase + textafter + | + + diff --git a/layout/reftests/css-ruby/intra-level-whitespace-3.html b/layout/reftests/css-ruby/intra-level-whitespace-3.html new file mode 100644 index 000000000000..a3a9b6313dce --- /dev/null +++ b/layout/reftests/css-ruby/intra-level-whitespace-3.html @@ -0,0 +1,34 @@ + + + + + Bug 1099807 - Intra-level whitespace pairing + + + + + + | + base + text + | + + diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index dc4c405ae9ee..c903e1df745e 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -20,6 +20,9 @@ fuzzy-if(winWidget,35,1) == dynamic-removal-3.html dynamic-removal-3-ref.html # == inlinize-blocks-3.html inlinize-blocks-3-ref.html == inlinize-blocks-4.html inlinize-blocks-4-ref.html == inlinize-blocks-5.html inlinize-blocks-5-ref.html +== intra-level-whitespace-1.html intra-level-whitespace-1-ref.html +== intra-level-whitespace-2.html intra-level-whitespace-2-ref.html +== intra-level-whitespace-3.html intra-level-whitespace-3-ref.html == justification-1.html justification-1-ref.html == justification-2.html justification-2-ref.html == line-height-1.html line-height-1-ref.html From 62960a5119bd60d31d8ad2fe9c902b065c89d778 Mon Sep 17 00:00:00 2001 From: Michael Pruett Date: Mon, 5 Jan 2015 20:26:50 -0600 Subject: [PATCH 130/224] Bug 1118024 - Add explicit PL_DHashTable{Add,Lookup,Remove} functions. r=nfroyd --- xpcom/base/nsCycleCollector.cpp | 8 +++----- xpcom/ds/nsAtomTable.cpp | 6 +++--- xpcom/ds/nsPersistentProperties.cpp | 6 +++--- xpcom/ds/nsStaticNameTable.cpp | 9 +++------ xpcom/glue/nsTHashtable.h | 13 ++++++------- xpcom/glue/pldhash.cpp | 18 ++++++++++++++++++ xpcom/glue/pldhash.h | 12 ++++++++++++ xpcom/tests/TestPLDHash.cpp | 2 +- 8 files changed, 49 insertions(+), 25 deletions(-) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 111a6767e6b3..7256689f0563 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -898,8 +898,7 @@ PtrInfo* CCGraph::FindNode(void* aPtr) { PtrToNodeEntry* e = - static_cast(PL_DHashTableOperate(&mPtrToNodeMap, aPtr, - PL_DHASH_LOOKUP)); + static_cast(PL_DHashTableLookup(&mPtrToNodeMap, aPtr)); if (!PL_DHASH_ENTRY_IS_BUSY(e)) { return nullptr; } @@ -911,8 +910,7 @@ CCGraph::AddNodeToMap(void* aPtr) { JS::AutoSuppressGCAnalysis suppress; PtrToNodeEntry* e = - static_cast(PL_DHashTableOperate(&mPtrToNodeMap, aPtr, - PL_DHASH_ADD)); + static_cast(PL_DHashTableAdd(&mPtrToNodeMap, aPtr)); if (!e) { // Caller should track OOMs return nullptr; @@ -923,7 +921,7 @@ CCGraph::AddNodeToMap(void* aPtr) void CCGraph::RemoveNodeFromMap(void* aPtr) { - PL_DHashTableOperate(&mPtrToNodeMap, aPtr, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mPtrToNodeMap, aPtr); } diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 1de2ec1c6f2b..5810324b6abd 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -404,7 +404,7 @@ AtomImpl::~AtomImpl() // |AtomTableClearEntry|. if (!IsPermanentInDestructor()) { AtomTableKey key(mString, mLength, mHash); - PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_REMOVE); + PL_DHashTableRemove(&gAtomTable, &key); if (gAtomTable.ops && gAtomTable.EntryCount() == 0) { PL_DHashTableFinish(&gAtomTable); NS_ASSERTION(gAtomTable.EntryCount() == 0, @@ -555,7 +555,7 @@ GetAtomHashEntry(const char* aString, uint32_t aLength, uint32_t* aHashOut) EnsureTableExists(); AtomTableKey key(aString, aLength, aHashOut); AtomTableEntry* e = static_cast( - PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD)); + PL_DHashTableAdd(&gAtomTable, &key)); if (!e) { NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize()); } @@ -569,7 +569,7 @@ GetAtomHashEntry(const char16_t* aString, uint32_t aLength, uint32_t* aHashOut) EnsureTableExists(); AtomTableKey key(aString, aLength, aHashOut); AtomTableEntry* e = static_cast( - PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD)); + PL_DHashTableAdd(&gAtomTable, &key)); if (!e) { NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize()); } diff --git a/xpcom/ds/nsPersistentProperties.cpp b/xpcom/ds/nsPersistentProperties.cpp index c5ab53ce6ec7..e9e0239417d7 100644 --- a/xpcom/ds/nsPersistentProperties.cpp +++ b/xpcom/ds/nsPersistentProperties.cpp @@ -533,7 +533,7 @@ nsPersistentProperties::SetStringProperty(const nsACString& aKey, { const nsAFlatCString& flatKey = PromiseFlatCString(aKey); PropertyTableEntry* entry = static_cast( - PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_ADD)); + PL_DHashTableAdd(&mTable, flatKey.get())); if (entry->mKey) { aOldValue = entry->mValue; @@ -572,7 +572,7 @@ nsPersistentProperties::GetStringProperty(const nsACString& aKey, const nsAFlatCString& flatKey = PromiseFlatCString(aKey); PropertyTableEntry* entry = static_cast( - PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_LOOKUP)); + PL_DHashTableLookup(&mTable, flatKey.get())); if (PL_DHASH_ENTRY_IS_FREE(entry)) { return NS_ERROR_FAILURE; @@ -644,7 +644,7 @@ NS_IMETHODIMP nsPersistentProperties::Has(const char* aProp, bool* aResult) { PropertyTableEntry* entry = static_cast( - PL_DHashTableOperate(&mTable, aProp, PL_DHASH_LOOKUP)); + PL_DHashTableLookup(&mTable, aProp)); *aResult = (entry && PL_DHASH_ENTRY_IS_BUSY(entry)); return NS_OK; } diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index 6f2507ff8a6f..77bff1ee6f14 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -170,8 +170,7 @@ nsStaticCaseInsensitiveNameTable::Init(const char* const aNames[], NameTableKey key(strPtr); NameTableEntry* entry = - static_cast(PL_DHashTableOperate(&mNameTable, &key, - PL_DHASH_ADD)); + static_cast(PL_DHashTableAdd(&mNameTable, &key)); if (!entry) { continue; } @@ -197,8 +196,7 @@ nsStaticCaseInsensitiveNameTable::Lookup(const nsACString& aName) NameTableKey key(&str); NameTableEntry* entry = - static_cast(PL_DHashTableOperate(&mNameTable, &key, - PL_DHASH_LOOKUP)); + static_cast(PL_DHashTableLookup(&mNameTable, &key)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { return nsStaticCaseInsensitiveNameTable::NOT_FOUND; } @@ -216,8 +214,7 @@ nsStaticCaseInsensitiveNameTable::Lookup(const nsAString& aName) NameTableKey key(&str); NameTableEntry* entry = - static_cast(PL_DHashTableOperate(&mNameTable, &key, - PL_DHASH_LOOKUP)); + static_cast(PL_DHashTableLookup(&mNameTable, &key)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { return nsStaticCaseInsensitiveNameTable::NOT_FOUND; } diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index ab9cc1b7a90d..d17d449a8072 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -128,8 +128,8 @@ public: NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly."); EntryType* entry = reinterpret_cast( - PL_DHashTableOperate(const_cast(&mTable), - EntryType::KeyToPointer(aKey), PL_DHASH_LOOKUP)); + PL_DHashTableLookup(const_cast(&mTable), + EntryType::KeyToPointer(aKey))); return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nullptr; } @@ -158,8 +158,8 @@ public: EntryType* PutEntry(KeyType aKey, const fallible_t&) NS_WARN_UNUSED_RESULT { NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly."); - return static_cast(PL_DHashTableOperate( - &mTable, EntryType::KeyToPointer(aKey), PL_DHASH_ADD)); + return static_cast(PL_DHashTableAdd( + &mTable, EntryType::KeyToPointer(aKey))); } /** @@ -170,9 +170,8 @@ public: { NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly."); - PL_DHashTableOperate(&mTable, - EntryType::KeyToPointer(aKey), - PL_DHASH_REMOVE); + PL_DHashTableRemove(&mTable, + EntryType::KeyToPointer(aKey)); } /** diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 042f21022658..dd72f5426b49 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -667,6 +667,24 @@ PL_DHashTableOperate(PLDHashTable* aTable, const void* aKey, PLDHashOperator aOp return aTable->Operate(aKey, aOp); } +PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableLookup(PLDHashTable* aTable, const void* aKey) +{ + return aTable->Operate(aKey, PL_DHASH_LOOKUP); +} + +PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey) +{ + return aTable->Operate(aKey, PL_DHASH_ADD); +} + +void PL_DHASH_FASTCALL +PL_DHashTableRemove(PLDHashTable* aTable, const void* aKey) +{ + aTable->Operate(aKey, PL_DHASH_REMOVE); +} + MOZ_ALWAYS_INLINE void PLDHashTable::RawRemove(PLDHashEntryHdr* aEntry) { diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index c37aa30ad8eb..7e54ca08e227 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -527,6 +527,18 @@ PLDHashEntryHdr* PL_DHASH_FASTCALL PL_DHashTableOperate(PLDHashTable* aTable, const void* aKey, PLDHashOperator aOp); +/* Look up a key in table. */ +PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableLookup(PLDHashTable* aTable, const void* aKey); + +/* Add an entry identified by key to table. */ +PLDHashEntryHdr* PL_DHASH_FASTCALL +PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey); + +/* Remove an entry identified by key from table. */ +void PL_DHASH_FASTCALL +PL_DHashTableRemove(PLDHashTable* aTable, const void* aKey); + /* * Remove an entry already accessed via LOOKUP or ADD. * diff --git a/xpcom/tests/TestPLDHash.cpp b/xpcom/tests/TestPLDHash.cpp index f116e92e992c..34fe77368453 100644 --- a/xpcom/tests/TestPLDHash.cpp +++ b/xpcom/tests/TestPLDHash.cpp @@ -99,7 +99,7 @@ static bool test_pldhash_grow_to_max_capacity() // Keep inserting elements until failure occurs because the table is full. size_t numInserted = 0; while (true) { - if (!PL_DHashTableOperate(&t, (const void*)numInserted, PL_DHASH_ADD)) { + if (!PL_DHashTableAdd(&t, (const void*)numInserted)) { break; } numInserted++; From 411a94b05a39c63951e1767b3f0c369692e2cfb9 Mon Sep 17 00:00:00 2001 From: Michael Pruett Date: Mon, 5 Jan 2015 20:27:28 -0600 Subject: [PATCH 131/224] Bug 1118024 - Use new PL_DHashTable{Add,Lookup,Remove} functions. r=nfroyd --- dom/base/nsContentList.cpp | 17 ++--- dom/base/nsContentUtils.cpp | 12 +-- dom/base/nsDocument.cpp | 9 +-- dom/base/nsPropertyTable.cpp | 12 ++- dom/base/nsScriptNameSpaceManager.cpp | 15 ++-- dom/plugins/base/nsJSNPRuntime.cpp | 12 +-- dom/xul/XULDocument.cpp | 17 ++--- dom/xul/templates/nsContentSupportMap.cpp | 2 +- dom/xul/templates/nsContentSupportMap.h | 4 +- dom/xul/templates/nsTemplateMap.h | 8 +- .../commandhandler/nsCommandParams.cpp | 11 +-- gfx/thebes/gfxFT2FontList.cpp | 6 +- js/xpconnect/src/XPCMaps.cpp | 3 +- js/xpconnect/src/XPCMaps.h | 60 ++++++--------- layout/base/nsFrameManager.cpp | 14 ++-- layout/style/nsCSSRuleProcessor.cpp | 47 +++++------- layout/style/nsHTMLStyleSheet.cpp | 6 +- layout/style/nsRuleNode.cpp | 4 +- layout/tables/SpanningCellSorter.cpp | 3 +- modules/libpref/prefapi.cpp | 6 +- netwerk/base/src/nsLoadGroup.cpp | 14 ++-- netwerk/cache/nsCacheEntry.cpp | 6 +- netwerk/cache/nsDiskCacheBinding.cpp | 20 ++--- netwerk/dns/nsHostResolver.cpp | 14 ++-- netwerk/protocol/http/nsHttp.cpp | 4 +- parser/htmlparser/nsHTMLEntities.cpp | 13 ++-- rdf/base/nsInMemoryDataSource.cpp | 46 ++++++------ rdf/base/nsRDFService.cpp | 74 +++++++++---------- .../boot/src/nsSecureBrowserUIImpl.cpp | 6 +- security/manager/ssl/src/nsCertTree.cpp | 4 +- security/manager/ssl/src/nsNSSShutDown.cpp | 8 +- uriloader/base/nsDocLoader.cpp | 7 +- 32 files changed, 204 insertions(+), 280 deletions(-) diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 0c459d142d8c..6b6fb585ff36 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -230,9 +230,7 @@ NS_GetContentList(nsINode* aRootNode, // A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases // when the entry is already in the hashtable. entry = static_cast - (PL_DHashTableOperate(&gContentListHashTable, - &hashKey, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&gContentListHashTable, &hashKey)); if (entry) list = entry->mContentList; } @@ -346,9 +344,8 @@ GetFuncStringContentList(nsINode* aRootNode, // A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases // when the entry is already in the hashtable. entry = static_cast - (PL_DHashTableOperate(&gFuncStringContentListHashTable, - &hashKey, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&gFuncStringContentListHashTable, + &hashKey)); if (entry) { list = entry->mContentList; #ifdef DEBUG @@ -989,9 +986,7 @@ nsContentList::RemoveFromHashtable() if (!gContentListHashTable.ops) return; - PL_DHashTableOperate(&gContentListHashTable, - &key, - PL_DHASH_REMOVE); + PL_DHashTableRemove(&gContentListHashTable, &key); if (gContentListHashTable.EntryCount() == 0) { PL_DHashTableFinish(&gContentListHashTable); @@ -1032,9 +1027,7 @@ nsCacheableFuncStringContentList::RemoveFromFuncStringHashtable() } nsFuncStringCacheKey key(mRootNode, mFunc, mString); - PL_DHashTableOperate(&gFuncStringContentListHashTable, - &key, - PL_DHASH_REMOVE); + PL_DHashTableRemove(&gFuncStringContentListHashTable, &key); if (gFuncStringContentListHashTable.EntryCount() == 0) { PL_DHashTableFinish(&gFuncStringContentListHashTable); diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index f2cb337bff8a..a08ab399df8e 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3954,8 +3954,7 @@ nsContentUtils::TraverseListenerManager(nsINode *aNode, EventListenerManagerMapEntry *entry = static_cast - (PL_DHashTableOperate(&sEventListenerManagersHash, aNode, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sEventListenerManagersHash, aNode)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { CycleCollectionNoteChild(cb, entry->mListenerManager.get(), "[via hash] mListenerManager"); @@ -3974,8 +3973,7 @@ nsContentUtils::GetListenerManagerForNode(nsINode *aNode) EventListenerManagerMapEntry *entry = static_cast - (PL_DHashTableOperate(&sEventListenerManagersHash, aNode, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&sEventListenerManagersHash, aNode)); if (!entry) { return nullptr; @@ -4006,8 +4004,7 @@ nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode) EventListenerManagerMapEntry *entry = static_cast - (PL_DHashTableOperate(&sEventListenerManagersHash, aNode, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sEventListenerManagersHash, aNode)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { return entry->mListenerManager; } @@ -4022,8 +4019,7 @@ nsContentUtils::RemoveListenerManager(nsINode *aNode) if (sEventListenerManagersHash.ops) { EventListenerManagerMapEntry *entry = static_cast - (PL_DHashTableOperate(&sEventListenerManagersHash, aNode, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sEventListenerManagersHash, aNode)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { nsRefPtr listenerManager; listenerManager.swap(entry->mListenerManager); diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 00b5ecd6f5cc..f686591d4d37 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3960,8 +3960,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) if (mSubDocuments) { SubDocMapEntry *entry = static_cast - (PL_DHashTableOperate(mSubDocuments, aElement, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mSubDocuments, aElement)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { PL_DHashTableRawRemove(mSubDocuments, entry); @@ -3993,8 +3992,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) // Add a mapping to the hash table SubDocMapEntry *entry = static_cast - (PL_DHashTableOperate(mSubDocuments, aElement, - PL_DHASH_ADD)); + (PL_DHashTableAdd(mSubDocuments, aElement)); if (!entry) { return NS_ERROR_OUT_OF_MEMORY; @@ -4022,8 +4020,7 @@ nsDocument::GetSubDocumentFor(nsIContent *aContent) const if (mSubDocuments && aContent->IsElement()) { SubDocMapEntry *entry = static_cast - (PL_DHashTableOperate(mSubDocuments, aContent->AsElement(), - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mSubDocuments, aContent->AsElement())); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { return entry->mSubDocument; diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index cfd4e83a44b6..e49549b80559 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -95,8 +95,7 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { if (prop->mTransfer) { PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&prop->mObjectValueMap, aObject)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { rv = aOtherTable->SetProperty(aObject, prop->mName, entry->value, prop->mDtorFunc, @@ -126,7 +125,7 @@ nsPropertyTable::Enumerate(nsPropertyOwner aObject, PropertyList* prop; for (prop = mPropertyList; prop; prop = prop->mNext) { PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&prop->mObjectValueMap, aObject, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&prop->mObjectValueMap, aObject)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { aCallback(const_cast(aObject.get()), prop->mName, entry->value, aData); @@ -174,8 +173,7 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&propertyList->mObjectValueMap, aObject)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { propValue = entry->value; if (aRemove) { @@ -230,7 +228,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, // value is destroyed nsresult result = NS_OK; PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject, PL_DHASH_ADD)); + (PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; // A nullptr entry->key is the sign that the entry has just been allocated @@ -329,7 +327,7 @@ bool nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject) { PropertyListMapEntry *entry = static_cast - (PL_DHashTableOperate(&mObjectValueMap, aObject, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mObjectValueMap, aObject)); if (!PL_DHASH_ENTRY_IS_BUSY(entry)) return false; diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index 1b6e962cac7f..7a51ffa00dbd 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -144,7 +144,7 @@ nsScriptNameSpaceManager::AddToHash(PLDHashTable *aTable, const nsAString *aKey, { GlobalNameMapEntry *entry = static_cast - (PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD)); + (PL_DHashTableAdd(aTable, aKey)); if (!entry) { return nullptr; @@ -161,7 +161,7 @@ void nsScriptNameSpaceManager::RemoveFromHash(PLDHashTable *aTable, const nsAString *aKey) { - PL_DHashTableOperate(aTable, aKey, PL_DHASH_REMOVE); + PL_DHashTableRemove(aTable, aKey); } nsGlobalNameStruct* @@ -172,9 +172,8 @@ nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct* aStruct) if (!aStruct->mAlias->mProto) { GlobalNameMapEntry *proto = static_cast - (PL_DHashTableOperate(&mGlobalNames, - &aStruct->mAlias->mProtoName, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mGlobalNames, + &aStruct->mAlias->mProtoName)); if (PL_DHASH_ENTRY_IS_BUSY(proto)) { aStruct->mAlias->mProto = &proto->mGlobalName; @@ -389,8 +388,7 @@ nsScriptNameSpaceManager::LookupNameInternal(const nsAString& aName, { GlobalNameMapEntry *entry = static_cast - (PL_DHashTableOperate(&mGlobalNames, &aName, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mGlobalNames, &aName)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { if (aClassName) { @@ -410,8 +408,7 @@ nsScriptNameSpaceManager::LookupNavigatorName(const nsAString& aName) { GlobalNameMapEntry *entry = static_cast - (PL_DHashTableOperate(&mNavigatorNames, &aName, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mNavigatorNames, &aName)); if (!PL_DHASH_ENTRY_IS_BUSY(entry)) { return nullptr; diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index a50f21bd578f..a6bf01988f01 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1750,7 +1750,7 @@ NPObjWrapper_Finalize(js::FreeOp *fop, JSObject *obj) NPObject *npobj = (NPObject *)::JS_GetPrivate(obj); if (npobj) { if (sNPObjWrappers.ops) { - PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_REMOVE); + PL_DHashTableRemove(&sNPObjWrappers, npobj); } } @@ -1779,7 +1779,7 @@ NPObjWrapper_ObjectMoved(JSObject *obj, const JSObject *old) JS::AutoSuppressGCAnalysis nogc; NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sNPObjWrappers, npobj)); MOZ_ASSERT(PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObj); MOZ_ASSERT(entry->mJSObj == old); entry->mJSObj = obj; @@ -1832,7 +1832,7 @@ nsNPObjWrapper::OnDestroy(NPObject *npobj) } NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sNPObjWrappers, npobj)); if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObj) { // Found a live NPObject wrapper, null out its JSObjects' private @@ -1883,7 +1883,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj) } NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_ADD)); + (PL_DHashTableAdd(&sNPObjWrappers, npobj)); if (!entry) { // Out of memory @@ -1917,7 +1917,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj) // the table (see bug 445229). This is guaranteed to succeed. entry = static_cast - (PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&sNPObjWrappers, npobj)); NS_ASSERTION(entry && PL_DHASH_ENTRY_IS_BUSY(entry), "Hashtable didn't find what we just added?"); } @@ -2049,7 +2049,7 @@ LookupNPP(NPObject *npobj) } NPObjWrapperHashEntry *entry = static_cast - (PL_DHashTableOperate(&sNPObjWrappers, npobj, PL_DHASH_ADD)); + (PL_DHashTableAdd(&sNPObjWrappers, npobj)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { return nullptr; diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 815cd34ce4b2..bf6d0283acca 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -782,14 +782,12 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, BroadcasterMapEntry* entry = static_cast - (PL_DHashTableOperate(mBroadcasterMap, &aBroadcaster, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mBroadcasterMap, &aBroadcaster)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { entry = static_cast - (PL_DHashTableOperate(mBroadcasterMap, &aBroadcaster, - PL_DHASH_ADD)); + (PL_DHashTableAdd(mBroadcasterMap, &aBroadcaster)); if (! entry) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); @@ -850,8 +848,7 @@ XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster, BroadcasterMapEntry* entry = static_cast - (PL_DHashTableOperate(mBroadcasterMap, &aBroadcaster, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mBroadcasterMap, &aBroadcaster)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { nsCOMPtr attr = do_GetAtom(aAttr); @@ -866,8 +863,7 @@ XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster, delete bl; if (entry->mListeners.Count() == 0) - PL_DHashTableOperate(mBroadcasterMap, &aBroadcaster, - PL_DHASH_REMOVE); + PL_DHashTableRemove(mBroadcasterMap, &aBroadcaster); break; } @@ -974,8 +970,7 @@ XULDocument::AttributeChanged(nsIDocument* aDocument, CanBroadcast(aNameSpaceID, aAttribute)) { BroadcasterMapEntry* entry = static_cast - (PL_DHashTableOperate(mBroadcasterMap, aElement, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mBroadcasterMap, aElement)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { // We've got listeners: push the value. @@ -4171,7 +4166,7 @@ XULDocument::BroadcastAttributeChangeFromOverlay(nsIContent* aNode, return rv; BroadcasterMapEntry* entry = static_cast - (PL_DHashTableOperate(mBroadcasterMap, aNode->AsElement(), PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(mBroadcasterMap, aNode->AsElement())); if (!PL_DHASH_ENTRY_IS_BUSY(entry)) return rv; diff --git a/dom/xul/templates/nsContentSupportMap.cpp b/dom/xul/templates/nsContentSupportMap.cpp index 224dce752c02..9399c40a3b83 100644 --- a/dom/xul/templates/nsContentSupportMap.cpp +++ b/dom/xul/templates/nsContentSupportMap.cpp @@ -27,7 +27,7 @@ nsContentSupportMap::Remove(nsIContent* aElement) nsIContent* child = aElement; do { - PL_DHashTableOperate(&mMap, child, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mMap, child); child = child->GetNextNode(aElement); } while(child); diff --git a/dom/xul/templates/nsContentSupportMap.h b/dom/xul/templates/nsContentSupportMap.h index 6b0dc7c0e2ea..c64c1a6190dd 100644 --- a/dom/xul/templates/nsContentSupportMap.h +++ b/dom/xul/templates/nsContentSupportMap.h @@ -28,7 +28,7 @@ public: if (!mMap.ops) return NS_ERROR_NOT_INITIALIZED; - PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_ADD); + PLDHashEntryHdr* hdr = PL_DHashTableAdd(&mMap, aElement); if (!hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -42,7 +42,7 @@ public: if (!mMap.ops) return false; - PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mMap, aElement, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(&mMap, aElement); if (PL_DHASH_ENTRY_IS_FREE(hdr)) return false; diff --git a/dom/xul/templates/nsTemplateMap.h b/dom/xul/templates/nsTemplateMap.h index fae6f188b154..faf5bbc5483e 100644 --- a/dom/xul/templates/nsTemplateMap.h +++ b/dom/xul/templates/nsTemplateMap.h @@ -36,11 +36,11 @@ public: void Put(nsIContent* aContent, nsIContent* aTemplate) { - NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mTable, aContent, PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mTable, aContent)), "aContent already in map"); Entry* entry = - reinterpret_cast(PL_DHashTableOperate(&mTable, aContent, PL_DHASH_ADD)); + reinterpret_cast(PL_DHashTableAdd(&mTable, aContent)); if (entry) { entry->mContent = aContent; @@ -50,7 +50,7 @@ public: void Remove(nsIContent* aContent) { - PL_DHashTableOperate(&mTable, aContent, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mTable, aContent); for (nsIContent* child = aContent->GetFirstChild(); child; @@ -63,7 +63,7 @@ public: void GetTemplateFor(nsIContent* aContent, nsIContent** aResult) { Entry* entry = - reinterpret_cast(PL_DHashTableOperate(&mTable, aContent, PL_DHASH_LOOKUP)); + reinterpret_cast(PL_DHashTableLookup(&mTable, aContent)); if (PL_DHASH_ENTRY_IS_BUSY(&entry->mHdr)) NS_IF_ADDREF(*aResult = entry->mTemplate); diff --git a/embedding/components/commandhandler/nsCommandParams.cpp b/embedding/components/commandhandler/nsCommandParams.cpp index 7848ba5393a9..5695b4eb26d8 100644 --- a/embedding/components/commandhandler/nsCommandParams.cpp +++ b/embedding/components/commandhandler/nsCommandParams.cpp @@ -214,7 +214,7 @@ nsCommandParams::RemoveValue(const char* aName) { // PL_DHASH_REMOVE doesn't tell us if the entry was really removed, so we // return NS_OK unconditionally. - (void)PL_DHashTableOperate(&mValuesHash, (void *)aName, PL_DHASH_REMOVE); + (void)PL_DHashTableRemove(&mValuesHash, (void *)aName); return NS_OK; } @@ -222,8 +222,7 @@ nsCommandParams::HashEntry* nsCommandParams::GetNamedEntry(const char* aName) { HashEntry *foundEntry = - (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)aName, - PL_DHASH_LOOKUP); + (HashEntry *)PL_DHashTableLookup(&mValuesHash, (void *)aName); if (PL_DHASH_ENTRY_IS_BUSY(foundEntry)) { return foundEntry; } @@ -234,15 +233,13 @@ nsCommandParams::HashEntry* nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t entryType) { HashEntry *foundEntry = - (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)aName, - PL_DHASH_LOOKUP); + (HashEntry *)PL_DHashTableLookup(&mValuesHash, (void *)aName); if (PL_DHASH_ENTRY_IS_BUSY(foundEntry)) { // reuse existing entry foundEntry->Reset(entryType); return foundEntry; } - foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)aName, - PL_DHASH_ADD); + foundEntry = (HashEntry *)PL_DHashTableAdd(&mValuesHash, (void *)aName); if (!foundEntry) { return nullptr; } diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index a686b9e8cbf6..8838a96ec442 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -692,7 +692,7 @@ public: FNCMapEntry* mapEntry = static_cast - (PL_DHashTableOperate(&mMap, filename.get(), PL_DHASH_ADD)); + (PL_DHashTableAdd(&mMap, filename.get())); if (mapEntry) { mapEntry->mFilename.Assign(filename); mapEntry->mTimestamp = timestamp; @@ -719,7 +719,7 @@ public: return; } PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mMap, aFileName.get()); if (!hdr) { return; } @@ -744,7 +744,7 @@ public: } FNCMapEntry* entry = static_cast - (PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_ADD)); + (PL_DHashTableAdd(&mMap, aFileName.get())); if (entry) { entry->mFilename.Assign(aFileName); entry->mTimestamp = aTimestamp; diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index 10837f4d8312..f1d64a1f7b20 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -644,8 +644,7 @@ XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags, NS_PRECONDITION(si,"bad param"); XPCNativeScriptableShared key(flags, name); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, &key, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, &key); if (!entry) return false; diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 12c003a25822..9b55af70105b 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -111,8 +111,7 @@ public: inline XPCWrappedNative* Find(nsISupports* Obj) { NS_PRECONDITION(Obj,"bad param"); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, Obj, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, Obj); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -123,8 +122,7 @@ public: NS_PRECONDITION(wrapper,"bad param"); nsISupports* obj = wrapper->GetIdentityObject(); MOZ_ASSERT(!Find(obj), "wrapper already in new scope!"); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, obj, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, obj); if (!entry) return nullptr; if (entry->key) @@ -144,7 +142,7 @@ public: "nsISupports identity! This will most likely cause serious " "problems!"); #endif - PL_DHashTableOperate(mTable, wrapper->GetIdentityObject(), PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, wrapper->GetIdentityObject()); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -181,8 +179,7 @@ public: inline nsXPCWrappedJSClass* Find(REFNSIID iid) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, &iid, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, &iid); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -192,8 +189,7 @@ public: { NS_PRECONDITION(clazz,"bad param"); const nsIID* iid = &clazz->GetIID(); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, iid, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, iid); if (!entry) return nullptr; if (entry->key) @@ -206,7 +202,7 @@ public: inline void Remove(nsXPCWrappedJSClass* clazz) { NS_PRECONDITION(clazz,"bad param"); - PL_DHashTableOperate(mTable, &clazz->GetIID(), PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, &clazz->GetIID()); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -238,8 +234,7 @@ public: inline XPCNativeInterface* Find(REFNSIID iid) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, &iid, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, &iid); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -249,8 +244,7 @@ public: { NS_PRECONDITION(iface,"bad param"); const nsIID* iid = iface->GetIID(); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, iid, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, iid); if (!entry) return nullptr; if (entry->key) @@ -263,7 +257,7 @@ public: inline void Remove(XPCNativeInterface* iface) { NS_PRECONDITION(iface,"bad param"); - PL_DHashTableOperate(mTable, iface->GetIID(), PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, iface->GetIID()); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -298,8 +292,7 @@ public: inline XPCNativeSet* Find(nsIClassInfo* info) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, info, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, info); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -308,8 +301,7 @@ public: inline XPCNativeSet* Add(nsIClassInfo* info, XPCNativeSet* set) { NS_PRECONDITION(info,"bad param"); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, info, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, info); if (!entry) return nullptr; if (entry->key) @@ -322,7 +314,7 @@ public: inline void Remove(nsIClassInfo* info) { NS_PRECONDITION(info,"bad param"); - PL_DHashTableOperate(mTable, info, PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, info); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -358,8 +350,7 @@ public: inline XPCWrappedNativeProto* Find(nsIClassInfo* info) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, info, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, info); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -368,8 +359,7 @@ public: inline XPCWrappedNativeProto* Add(nsIClassInfo* info, XPCWrappedNativeProto* proto) { NS_PRECONDITION(info,"bad param"); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, info, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, info); if (!entry) return nullptr; if (entry->key) @@ -382,7 +372,7 @@ public: inline void Remove(nsIClassInfo* info) { NS_PRECONDITION(info,"bad param"); - PL_DHashTableOperate(mTable, info, PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, info); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -423,8 +413,7 @@ public: inline XPCNativeSet* Find(XPCNativeSetKey* key) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, key, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, key); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->key_value; @@ -434,8 +423,7 @@ public: { NS_PRECONDITION(key,"bad param"); NS_PRECONDITION(set,"bad param"); - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, key, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, key); if (!entry) return nullptr; if (entry->key_value) @@ -455,7 +443,7 @@ public: NS_PRECONDITION(set,"bad param"); XPCNativeSetKey key(set, nullptr, 0); - PL_DHashTableOperate(mTable, &key, PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, &key); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -500,8 +488,7 @@ public: inline nsIXPCFunctionThisTranslator* Find(REFNSIID iid) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, &iid, PL_DHASH_LOOKUP); + Entry* entry = (Entry*) PL_DHashTableLookup(mTable, &iid); if (PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; return entry->value; @@ -511,8 +498,7 @@ public: nsIXPCFunctionThisTranslator* obj) { - Entry* entry = (Entry*) - PL_DHashTableOperate(mTable, &iid, PL_DHASH_ADD); + Entry* entry = (Entry*) PL_DHashTableAdd(mTable, &iid); if (!entry) return nullptr; entry->value = obj; @@ -522,7 +508,7 @@ public: inline void Remove(REFNSIID iid) { - PL_DHashTableOperate(mTable, &iid, PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, &iid); } inline uint32_t Count() { return mTable->EntryCount(); } @@ -584,7 +570,7 @@ public: { NS_PRECONDITION(proto,"bad param"); PLDHashEntryStub* entry = (PLDHashEntryStub*) - PL_DHashTableOperate(mTable, proto, PL_DHASH_ADD); + PL_DHashTableAdd(mTable, proto); if (!entry) return nullptr; if (entry->key) @@ -596,7 +582,7 @@ public: inline void Remove(XPCWrappedNativeProto* proto) { NS_PRECONDITION(proto,"bad param"); - PL_DHashTableOperate(mTable, proto, PL_DHASH_REMOVE); + PL_DHashTableRemove(mTable, proto); } inline uint32_t Count() { return mTable->EntryCount(); } diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index f20cc3f313fa..674f7102b591 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -158,8 +158,8 @@ nsFrameManager::GetPlaceholderFrameFor(const nsIFrame* aFrame) if (mPlaceholderMap.ops) { PlaceholderMapEntry *entry = static_cast - (PL_DHashTableOperate(const_cast(&mPlaceholderMap), - aFrame, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(const_cast(&mPlaceholderMap), + aFrame)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { return entry->placeholderFrame; } @@ -178,9 +178,8 @@ nsFrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame) PL_DHashTableInit(&mPlaceholderMap, &PlaceholderMapOps, nullptr, sizeof(PlaceholderMapEntry)); } - PlaceholderMapEntry *entry = static_cast(PL_DHashTableOperate(&mPlaceholderMap, - aPlaceholderFrame->GetOutOfFlowFrame(), - PL_DHASH_ADD)); + PlaceholderMapEntry *entry = static_cast(PL_DHashTableAdd(&mPlaceholderMap, + aPlaceholderFrame->GetOutOfFlowFrame())); if (!entry) return NS_ERROR_OUT_OF_MEMORY; @@ -198,9 +197,8 @@ nsFrameManager::UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame "unexpected frame type"); if (mPlaceholderMap.ops) { - PL_DHashTableOperate(&mPlaceholderMap, - aPlaceholderFrame->GetOutOfFlowFrame(), - PL_DHASH_REMOVE); + PL_DHashTableRemove(&mPlaceholderMap, + aPlaceholderFrame->GetOutOfFlowFrame()); } } diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 473cbbde95d4..6e1aadccf5c6 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -598,7 +598,7 @@ void RuleHash::AppendRuleToTable(PLDHashTable* aTable, const void* aKey, { // Get a new or existing entry. RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD)); + (PL_DHashTableAdd(aTable, aKey)); if (!entry) return; entry->mRules.AppendElement(RuleValue(aRuleInfo, mRuleCount++, mQuirksMode)); @@ -610,7 +610,7 @@ AppendRuleToTagTable(PLDHashTable* aTable, nsIAtom* aKey, { // Get a new or exisiting entry RuleHashTagTableEntry *entry = static_cast - (PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD)); + (PL_DHashTableAdd(aTable, aKey)); if (!entry) return; @@ -725,8 +725,7 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso // universal rules within the namespace if (kNameSpaceID_Unknown != nameSpace && mNameSpaceTable.ops) { RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mNameSpaceTable, NS_INT32_TO_PTR(nameSpace), - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mNameSpaceTable, NS_INT32_TO_PTR(nameSpace))); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementNameSpaceCalls); @@ -734,7 +733,7 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso } if (mTagTable.ops) { RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mTagTable, tag, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mTagTable, tag)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementTagCalls); @@ -742,7 +741,7 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso } if (id && mIdTable.ops) { RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mIdTable, id, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mIdTable, id)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementIdCalls); @@ -751,8 +750,7 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso if (mClassTable.ops) { for (int32_t index = 0; index < classCount; ++index) { RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mClassTable, classList->AtomAt(index), - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mClassTable, classList->AtomAt(index))); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementClassCalls); @@ -1074,8 +1072,7 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) { AtomSelectorEntry *entry = static_cast - (PL_DHashTableOperate(&mAttributeSelectors, aAttribute, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&mAttributeSelectors, aAttribute)); if (!entry) return nullptr; return &entry->mSelectors; @@ -2616,8 +2613,7 @@ nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData) if (cascade && cascade->mAnonBoxRules.EntryCount()) { RuleHashTagTableEntry* entry = static_cast - (PL_DHashTableOperate(&cascade->mAnonBoxRules, aData->mPseudoTag, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&cascade->mAnonBoxRules, aData->mPseudoTag)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { nsTArray& rules = entry->mRules; for (RuleValue *value = rules.Elements(), *end = value + rules.Length(); @@ -2637,8 +2633,7 @@ nsCSSRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData) if (cascade && cascade->mXULTreeRules.EntryCount()) { RuleHashTagTableEntry* entry = static_cast - (PL_DHashTableOperate(&cascade->mXULTreeRules, aData->mPseudoTag, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&cascade->mXULTreeRules, aData->mPseudoTag)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { NodeMatchContext nodeContext(EventStates(), nsCSSRuleProcessor::IsLink(aData->mElement)); @@ -2873,8 +2868,7 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData if (id) { AtomSelectorEntry *entry = static_cast - (PL_DHashTableOperate(&cascade->mIdSelectors, - id, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&cascade->mIdSelectors, id)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { EnumerateSelectors(entry->mSelectors, &data); } @@ -2891,8 +2885,8 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData nsIAtom* curClass = elementClasses->AtomAt(i); AtomSelectorEntry *entry = static_cast - (PL_DHashTableOperate(&cascade->mClassSelectors, - curClass, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&cascade->mClassSelectors, + curClass)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { EnumerateSelectors(entry->mSelectors, &data); } @@ -2904,8 +2898,8 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData AtomSelectorEntry *entry = static_cast - (PL_DHashTableOperate(&cascade->mAttributeSelectors, - aData->mAttribute, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&cascade->mAttributeSelectors, + aData->mAttribute)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { EnumerateSelectors(entry->mSelectors, &data); } @@ -3156,9 +3150,8 @@ AddSelector(RuleCascadeData* aCascade, for (nsAtomList* curID = negation->mIDList; curID; curID = curID->mNext) { AtomSelectorEntry *entry = - static_cast(PL_DHashTableOperate(&aCascade->mIdSelectors, - curID->mAtom, - PL_DHASH_ADD)); + static_cast(PL_DHashTableAdd(&aCascade->mIdSelectors, + curID->mAtom)); if (entry) { entry->mSelectors.AppendElement(aSelectorInTopLevel); } @@ -3172,9 +3165,8 @@ AddSelector(RuleCascadeData* aCascade, for (nsAtomList* curClass = negation->mClassList; curClass; curClass = curClass->mNext) { AtomSelectorEntry *entry = - static_cast(PL_DHashTableOperate(&aCascade->mClassSelectors, - curClass->mAtom, - PL_DHASH_ADD)); + static_cast(PL_DHashTableAdd(&aCascade->mClassSelectors, + curClass->mAtom)); if (entry) { entry->mSelectors.AppendElement(aSelectorInTopLevel); } @@ -3437,8 +3429,7 @@ CascadeRuleEnumFunc(css::Rule* aRule, void* aData) sel; sel = sel->mNext) { int32_t weight = sel->mWeight; RuleByWeightEntry *entry = static_cast( - PL_DHashTableOperate(&data->mRulesByWeight, NS_INT32_TO_PTR(weight), - PL_DHASH_ADD)); + PL_DHashTableAdd(&data->mRulesByWeight, NS_INT32_TO_PTR(weight))); if (!entry) return false; entry->data.mWeight = weight; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index e923eae3da5b..b11a201bd30a 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -492,7 +492,7 @@ nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped) nullptr, sizeof(MappedAttrTableEntry)); } MappedAttrTableEntry *entry = static_cast - (PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_ADD)); + (PL_DHashTableAdd(&mMappedAttrTable, aMapped)); if (!entry) return nullptr; if (!entry->mAttributes) { @@ -513,7 +513,7 @@ nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped) uint32_t entryCount = mMappedAttrTable.EntryCount() - 1; #endif - PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mMappedAttrTable, aMapped); NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed"); } @@ -526,7 +526,7 @@ nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage) nullptr, sizeof(LangRuleTableEntry)); } LangRuleTableEntry *entry = static_cast - (PL_DHashTableOperate(&mLangRuleTable, &aLanguage, PL_DHASH_ADD)); + (PL_DHashTableAdd(&mLangRuleTable, &aLanguage)); if (!entry) { NS_ASSERTION(false, "out of memory"); return nullptr; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 29c3d7de9945..520d2da90037 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1537,7 +1537,7 @@ nsRuleNode::Transition(nsIStyleRule* aRule, uint8_t aLevel, if (ChildrenAreHashed()) { ChildrenHashEntry *entry = static_cast - (PL_DHashTableOperate(ChildrenHash(), &key, PL_DHASH_ADD)); + (PL_DHashTableAdd(ChildrenHash(), &key)); if (!entry) { NS_WARNING("out of memory"); return this; @@ -1615,7 +1615,7 @@ nsRuleNode::ConvertChildrenToHash(int32_t aNumKids) for (nsRuleNode* curr = ChildrenList(); curr; curr = curr->mNextSibling) { // This will never fail because of the initial size we gave the table. ChildrenHashEntry *entry = static_cast( - PL_DHashTableOperate(hash, curr->mRule, PL_DHASH_ADD)); + PL_DHashTableAdd(hash, curr->mRule)); NS_ASSERTION(!entry->mRuleNode, "duplicate entries in list"); entry->mRuleNode = curr; } diff --git a/layout/tables/SpanningCellSorter.cpp b/layout/tables/SpanningCellSorter.cpp index 8047312bcf05..ba01ae8fc5fd 100644 --- a/layout/tables/SpanningCellSorter.cpp +++ b/layout/tables/SpanningCellSorter.cpp @@ -80,8 +80,7 @@ SpanningCellSorter::AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol) sizeof(HashTableEntry)); } HashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mHashTable, NS_INT32_TO_PTR(aColSpan), - PL_DHASH_ADD)); + (PL_DHashTableAdd(&mHashTable, NS_INT32_TO_PTR(aColSpan))); NS_ENSURE_TRUE(entry, false); NS_ASSERTION(entry->mColSpan == 0 || entry->mColSpan == aColSpan, diff --git a/modules/libpref/prefapi.cpp b/modules/libpref/prefapi.cpp index 2be3ae9f375e..4804e58ce3a2 100644 --- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -614,7 +614,7 @@ PREF_ClearUserPref(const char *pref_name) pref->flags &= ~PREF_USERSET; if (!(pref->flags & PREF_HAS_DEFAULT)) { - PL_DHashTableOperate(&gHashTable, pref_name, PL_DHASH_REMOVE); + PL_DHashTableRemove(&gHashTable, pref_name); } pref_DoCallback(pref_name); @@ -734,7 +734,7 @@ PrefHashEntry* pref_HashTableLookup(const void *key) #endif PrefHashEntry* result = - static_cast(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_LOOKUP)); + static_cast(PL_DHashTableLookup(&gHashTable, key)); if (PL_DHASH_ENTRY_IS_FREE(result)) return nullptr; @@ -751,7 +751,7 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t if (!gHashTable.ops) return NS_ERROR_OUT_OF_MEMORY; - PrefHashEntry* pref = static_cast(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD)); + PrefHashEntry* pref = static_cast(PL_DHashTableAdd(&gHashTable, key)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; diff --git a/netwerk/base/src/nsLoadGroup.cpp b/netwerk/base/src/nsLoadGroup.cpp index 0ae05ddf9427..17511a3827a6 100644 --- a/netwerk/base/src/nsLoadGroup.cpp +++ b/netwerk/base/src/nsLoadGroup.cpp @@ -264,8 +264,7 @@ nsLoadGroup::Cancel(nsresult status) RequestMapEntry *entry = static_cast - (PL_DHashTableOperate(&mRequests, request, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mRequests, request)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { // |request| was removed already @@ -497,8 +496,7 @@ nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt) { RequestMapEntry *entry = static_cast - (PL_DHashTableOperate(&mRequests, request, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mRequests, request)); NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(entry), "Entry added to loadgroup twice, don't do that"); @@ -534,8 +532,7 @@ nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt) RequestMapEntry *entry = static_cast - (PL_DHashTableOperate(&mRequests, request, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&mRequests, request)); if (!entry) { return NS_ERROR_OUT_OF_MEMORY; @@ -572,7 +569,7 @@ nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt) // the damage... // - PL_DHashTableOperate(&mRequests, request, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mRequests, request); rv = NS_OK; @@ -618,8 +615,7 @@ nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt, // RequestMapEntry *entry = static_cast - (PL_DHashTableOperate(&mRequests, request, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mRequests, request)); if (PL_DHASH_ENTRY_IS_FREE(entry)) { LOG(("LOADGROUP [%x]: Unable to remove request %x. Not in group!\n", diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index 030b4fe42d89..1f9a68523a83 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -434,7 +434,7 @@ nsCacheEntryHashTable::GetEntry( const nsCString * key) NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); if (!initialized) return nullptr; - hashEntry = PL_DHashTableOperate(&table, key, PL_DHASH_LOOKUP); + hashEntry = PL_DHashTableLookup(&table, key); if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) { result = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry; } @@ -451,7 +451,7 @@ nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry) if (!initialized) return NS_ERROR_NOT_INITIALIZED; if (!cacheEntry) return NS_ERROR_NULL_POINTER; - hashEntry = PL_DHashTableOperate(&table, &(cacheEntry->mKey), PL_DHASH_ADD); + hashEntry = PL_DHashTableAdd(&table, &(cacheEntry->mKey)); #ifndef DEBUG_dougt NS_ASSERTION(((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry == 0, "### nsCacheEntryHashTable::AddEntry - entry already used"); @@ -475,7 +475,7 @@ nsCacheEntryHashTable::RemoveEntry( nsCacheEntry *cacheEntry) nsCacheEntry *check = GetEntry(&(cacheEntry->mKey)); NS_ASSERTION(check == cacheEntry, "### Attempting to remove unknown cache entry!!!"); #endif - (void) PL_DHashTableOperate(&table, &(cacheEntry->mKey), PL_DHASH_REMOVE); + PL_DHashTableRemove(&table, &(cacheEntry->mKey)); } diff --git a/netwerk/cache/nsDiskCacheBinding.cpp b/netwerk/cache/nsDiskCacheBinding.cpp index 470464bca60c..593f544199aa 100644 --- a/netwerk/cache/nsDiskCacheBinding.cpp +++ b/netwerk/cache/nsDiskCacheBinding.cpp @@ -204,9 +204,8 @@ nsDiskCacheBindery::FindActiveBinding(uint32_t hashNumber) // find hash entry for key HashTableEntry * hashEntry; hashEntry = - (HashTableEntry *) PL_DHashTableOperate(&table, - (void*)(uintptr_t) hashNumber, - PL_DHASH_LOOKUP); + (HashTableEntry *) PL_DHashTableLookup(&table, + (void*)(uintptr_t) hashNumber); if (PL_DHASH_ENTRY_IS_FREE(hashEntry)) return nullptr; // walk list looking for active entry @@ -239,9 +238,8 @@ nsDiskCacheBindery::AddBinding(nsDiskCacheBinding * binding) // find hash entry for key HashTableEntry * hashEntry; hashEntry = (HashTableEntry *) - PL_DHashTableOperate(&table, - (void *)(uintptr_t) binding->mRecord.HashNumber(), - PL_DHASH_ADD); + PL_DHashTableAdd(&table, + (void *)(uintptr_t) binding->mRecord.HashNumber()); if (!hashEntry) return NS_ERROR_OUT_OF_MEMORY; if (hashEntry->mBinding == nullptr) { @@ -303,9 +301,8 @@ nsDiskCacheBindery::RemoveBinding(nsDiskCacheBinding * binding) HashTableEntry * hashEntry; void * key = (void *)(uintptr_t)binding->mRecord.HashNumber(); - hashEntry = (HashTableEntry*) PL_DHashTableOperate(&table, - (void*)(uintptr_t) key, - PL_DHASH_LOOKUP); + hashEntry = (HashTableEntry*) PL_DHashTableLookup(&table, + (void*)(uintptr_t) key); if (!PL_DHASH_ENTRY_IS_BUSY(hashEntry)) { NS_WARNING("### disk cache: binding not in hashtable!"); return; @@ -314,9 +311,8 @@ nsDiskCacheBindery::RemoveBinding(nsDiskCacheBinding * binding) if (binding == hashEntry->mBinding) { if (PR_CLIST_IS_EMPTY(binding)) { // remove this hash entry - PL_DHashTableOperate(&table, - (void*)(uintptr_t) binding->mRecord.HashNumber(), - PL_DHASH_REMOVE); + PL_DHashTableRemove(&table, + (void*)(uintptr_t) binding->mRecord.HashNumber()); return; } else { diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index 532251bc0051..52bc1562f198 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -627,7 +627,7 @@ nsHostResolver::FlushCache() nsHostRecord *rec = static_cast(node); node = node->next; PR_REMOVE_AND_INIT_LINK(rec); - PL_DHashTableOperate(&mDB, (nsHostKey *) rec, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mDB, (nsHostKey *) rec); NS_RELEASE(rec); } } @@ -759,7 +759,7 @@ nsHostResolver::ResolveHost(const char *host, nsHostKey key = { host, flags, af }; nsHostDBEnt *he = static_cast - (PL_DHashTableOperate(&mDB, &key, PL_DHASH_ADD)); + (PL_DHashTableAdd(&mDB, &key)); // if the record is null, then HostDB_InitEntry failed. if (!he || !he->rec) { @@ -832,7 +832,7 @@ nsHostResolver::ResolveHost(const char *host, // First, search for an entry with AF_UNSPEC const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC }; nsHostDBEnt *unspecHe = static_cast - (PL_DHashTableOperate(&mDB, &unspecKey, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mDB, &unspecKey)); NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(unspecHe) || (PL_DHASH_ENTRY_IS_BUSY(unspecHe) && unspecHe->rec), @@ -960,7 +960,7 @@ nsHostResolver::DetachCallback(const char *host, nsHostKey key = { host, flags, af }; nsHostDBEnt *he = static_cast - (PL_DHashTableOperate(&mDB, &key, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mDB, &key)); if (he && he->rec) { // walk list looking for |callback|... we cannot assume // that it will be there! @@ -1252,7 +1252,7 @@ nsHostResolver::OnLookupComplete(nsHostRecord* rec, nsresult status, AddrInfo* r nsHostRecord *head = static_cast(PR_LIST_HEAD(&mEvictionQ)); PR_REMOVE_AND_INIT_LINK(head); - PL_DHashTableOperate(&mDB, (nsHostKey *) head, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mDB, (nsHostKey *) head); if (!head->negative) { // record the age of the entry upon eviction. @@ -1308,7 +1308,7 @@ nsHostResolver::CancelAsyncRequest(const char *host, // Lookup the host record associated with host, flags & address family nsHostKey key = { host, flags, af }; nsHostDBEnt *he = static_cast - (PL_DHashTableOperate(&mDB, &key, PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mDB, &key)); if (he && he->rec) { nsHostRecord* recPtr = nullptr; PRCList *node = he->rec->callbacks.next; @@ -1329,7 +1329,7 @@ nsHostResolver::CancelAsyncRequest(const char *host, // If there are no more callbacks, remove the hash table entry if (recPtr && PR_CLIST_IS_EMPTY(&recPtr->callbacks)) { - PL_DHashTableOperate(&mDB, (nsHostKey *)recPtr, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mDB, (nsHostKey *)recPtr); // If record is on a Queue, remove it and then deref it if (recPtr->next != recPtr) { PR_REMOVE_LINK(recPtr); diff --git a/netwerk/protocol/http/nsHttp.cpp b/netwerk/protocol/http/nsHttp.cpp index cae91990d526..177cc0948d69 100644 --- a/netwerk/protocol/http/nsHttp.cpp +++ b/netwerk/protocol/http/nsHttp.cpp @@ -125,7 +125,7 @@ nsHttp::CreateAtomTable() for (int i = 0; atoms[i]; ++i) { PLDHashEntryStub *stub = reinterpret_cast - (PL_DHashTableOperate(&sAtomTable, atoms[i], PL_DHASH_ADD)); + (PL_DHashTableAdd(&sAtomTable, atoms[i])); if (!stub) return NS_ERROR_OUT_OF_MEMORY; @@ -174,7 +174,7 @@ nsHttp::ResolveAtom(const char *str) MutexAutoLock lock(*sLock); PLDHashEntryStub *stub = reinterpret_cast - (PL_DHashTableOperate(&sAtomTable, str, PL_DHASH_ADD)); + (PL_DHashTableAdd(&sAtomTable, str)); if (!stub) return atom; // out of memory diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp index b03802e3e4cd..c385b6a7899f 100644 --- a/parser/htmlparser/nsHTMLEntities.cpp +++ b/parser/htmlparser/nsHTMLEntities.cpp @@ -109,9 +109,7 @@ nsHTMLEntities::AddRefTable(void) // add to Entity->Unicode table EntityNodeEntry* entry = static_cast - (PL_DHashTableOperate(&gEntityToUnicode, - node->mStr, - PL_DHASH_ADD)); + (PL_DHashTableAdd(&gEntityToUnicode, node->mStr)); NS_ASSERTION(entry, "Error adding an entry"); // Prefer earlier entries when we have duplication. if (!entry->node) @@ -119,9 +117,8 @@ nsHTMLEntities::AddRefTable(void) // add to Unicode->Entity table entry = static_cast - (PL_DHashTableOperate(&gUnicodeToEntity, - NS_INT32_TO_PTR(node->mUnicode), - PL_DHASH_ADD)); + (PL_DHashTableAdd(&gUnicodeToEntity, + NS_INT32_TO_PTR(node->mUnicode))); NS_ASSERTION(entry, "Error adding an entry"); // Prefer earlier entries when we have duplication. if (!entry->node) @@ -171,7 +168,7 @@ nsHTMLEntities::EntityToUnicode(const nsCString& aEntity) EntityNodeEntry* entry = static_cast - (PL_DHashTableOperate(&gEntityToUnicode, aEntity.get(), PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&gEntityToUnicode, aEntity.get())); if (!entry || PL_DHASH_ENTRY_IS_FREE(entry)) return -1; @@ -197,7 +194,7 @@ nsHTMLEntities::UnicodeToEntity(int32_t aUnicode) NS_ASSERTION(gUnicodeToEntity.ops, "no lookup table, needs addref"); EntityNodeEntry* entry = static_cast - (PL_DHashTableOperate(&gUnicodeToEntity, NS_INT32_TO_PTR(aUnicode), PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&gUnicodeToEntity, NS_INT32_TO_PTR(aUnicode))); if (!entry || PL_DHASH_ENTRY_IS_FREE(entry)) return nullptr; diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp index db49e30ecace..7b319bad1ed5 100644 --- a/rdf/base/nsInMemoryDataSource.cpp +++ b/rdf/base/nsInMemoryDataSource.cpp @@ -320,14 +320,14 @@ public: // Implementation methods Assertion* GetForwardArcs(nsIRDFResource* u) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mForwardArcs, u, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(&mForwardArcs, u); return PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; } Assertion* GetReverseArcs(nsIRDFNode* v) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(&mReverseArcs, v, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(&mReverseArcs, v); return PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; } @@ -436,8 +436,8 @@ InMemoryAssertionEnumeratorImpl::InMemoryAssertionEnumeratorImpl( if (mNextAssertion && mNextAssertion->mHashEntry) { // its our magical HASH_ENTRY forward hash for assertions - PLDHashEntryHdr* hdr = PL_DHashTableOperate(mNextAssertion->u.hash.mPropertyHash, - aProperty, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(mNextAssertion->u.hash.mPropertyHash, + aProperty); mNextAssertion = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -980,7 +980,7 @@ InMemoryDataSource::GetTarget(nsIRDFResource* source, Assertion *as = GetForwardArcs(source); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(as->u.hash.mPropertyHash, property, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(as->u.hash.mPropertyHash, property); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1026,7 +1026,7 @@ InMemoryDataSource::HasAssertion(nsIRDFResource* source, Assertion *as = GetForwardArcs(source); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(as->u.hash.mPropertyHash, property, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(as->u.hash.mPropertyHash, property); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1139,7 +1139,7 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, bool haveHash = (next) ? next->mHashEntry : false; if (haveHash) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(next->u.hash.mPropertyHash, aProperty, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(next->u.hash.mPropertyHash, aProperty); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1180,8 +1180,8 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, if (haveHash) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(next->u.hash.mPropertyHash, - aProperty, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(next->u.hash.mPropertyHash, + aProperty); Assertion *asRef = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1192,8 +1192,7 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, } else { - hdr = PL_DHashTableOperate(next->u.hash.mPropertyHash, - aProperty, PL_DHASH_ADD); + hdr = PL_DHashTableAdd(next->u.hash.mPropertyHash, aProperty); if (hdr) { Entry* entry = reinterpret_cast(hdr); @@ -1282,8 +1281,8 @@ InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, bool haveHash = (next) ? next->mHashEntry : false; if (haveHash) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(next->u.hash.mPropertyHash, - aProperty, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(next->u.hash.mPropertyHash, + aProperty); prev = next = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1306,8 +1305,8 @@ InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, PL_DHashTableRawRemove(root->u.hash.mPropertyHash, hdr); if (next && next->mNext) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(root->u.hash.mPropertyHash, - aProperty, PL_DHASH_ADD); + PLDHashEntryHdr* hdr = PL_DHashTableAdd(root->u.hash.mPropertyHash, + aProperty); if (hdr) { Entry* entry = reinterpret_cast(hdr); entry->mNode = aProperty; @@ -1585,8 +1584,8 @@ InMemoryDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, boo { Assertion* ass = GetForwardArcs(aSource); if (ass && ass->mHashEntry) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(ass->u.hash.mPropertyHash, - aArc, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(ass->u.hash.mPropertyHash, + aArc); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1746,8 +1745,8 @@ InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) nextRef = first->mNext; nsIRDFResource *prop = first->u.as.mProperty; - PLDHashEntryHdr* hdr = PL_DHashTableOperate(table, - prop, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(table, + prop); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1756,8 +1755,7 @@ InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) val->mNext = first; } else { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(table, - prop, PL_DHASH_ADD); + PLDHashEntryHdr* hdr = PL_DHashTableAdd(table, prop); if (hdr) { Entry* entry = reinterpret_cast(hdr); entry->mNode = prop; @@ -1812,8 +1810,8 @@ InMemoryDataSource::Mark(nsIRDFResource* aSource, Assertion *as = GetForwardArcs(aSource); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = PL_DHashTableOperate(as->u.hash.mPropertyHash, - aProperty, PL_DHASH_LOOKUP); + PLDHashEntryHdr* hdr = PL_DHashTableLookup(as->u.hash.mPropertyHash, + aProperty); Assertion* val = PL_DHASH_ENTRY_IS_BUSY(hdr) ? reinterpret_cast(hdr)->mAssertions : nullptr; @@ -1948,7 +1946,7 @@ InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable, // remove from the reverse arcs PLDHashEntryHdr* hdr = - PL_DHashTableOperate(info->mReverseArcs, as->u.as.mTarget, PL_DHASH_LOOKUP); + PL_DHashTableLookup(info->mReverseArcs, as->u.as.mTarget); NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(hdr), "no assertion in reverse arcs"); Entry* rentry = reinterpret_cast(hdr); diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp index d4bc2c15153b..8e6d133d2409 100644 --- a/rdf/base/nsRDFService.cpp +++ b/rdf/base/nsRDFService.cpp @@ -886,7 +886,7 @@ RDFServiceImpl::GetResource(const nsACString& aURI, nsIRDFResource** aResource) // First, check the cache to see if we've already created and // registered this thing. PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mResources, flatURI.get(), PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mResources, flatURI.get()); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { ResourceHashEntry *entry = static_cast(hdr); @@ -1056,7 +1056,7 @@ RDFServiceImpl::GetLiteral(const char16_t* aValue, nsIRDFLiteral** aLiteral) // See if we have one already cached PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mLiterals, aValue, PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mLiterals, aValue); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { LiteralHashEntry *entry = static_cast(hdr); @@ -1073,7 +1073,7 @@ RDFServiceImpl::GetDateLiteral(PRTime aTime, nsIRDFDate** aResult) { // See if we have one already cached PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mDates, &aTime, PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mDates, &aTime); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { DateHashEntry *entry = static_cast(hdr); @@ -1094,7 +1094,7 @@ RDFServiceImpl::GetIntLiteral(int32_t aInt, nsIRDFInt** aResult) { // See if we have one already cached PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mInts, &aInt, PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mInts, &aInt); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { IntHashEntry *entry = static_cast(hdr); @@ -1117,7 +1117,7 @@ RDFServiceImpl::GetBlobLiteral(const uint8_t *aBytes, int32_t aLength, BlobImpl::Data key = { aLength, const_cast(aBytes) }; PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mBlobs, &key, PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mBlobs, &key); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { BlobHashEntry *entry = static_cast(hdr); @@ -1180,7 +1180,7 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, bool aReplace) return NS_ERROR_NULL_POINTER; PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mResources, uri, PL_DHASH_LOOKUP); + PL_DHashTableLookup(&mResources, uri); if (PL_DHASH_ENTRY_IS_BUSY(hdr)) { if (!aReplace) { @@ -1198,7 +1198,7 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, bool aReplace) aResource, (const char*) uri)); } else { - hdr = PL_DHashTableOperate(&mResources, uri, PL_DHASH_ADD); + hdr = PL_DHashTableAdd(&mResources, uri); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1240,11 +1240,11 @@ RDFServiceImpl::UnregisterResource(nsIRDFResource* aResource) aResource, (const char*) uri)); #ifdef DEBUG - if (PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mResources, uri, PL_DHASH_LOOKUP))) + if (PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mResources, uri))) NS_WARNING("resource was never registered"); #endif - PL_DHashTableOperate(&mResources, uri, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mResources, uri); return NS_OK; } @@ -1432,13 +1432,12 @@ RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral) const char16_t* value; aLiteral->GetValueConst(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mLiterals, - value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mLiterals, + value)), "literal already registered"); PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mLiterals, value, PL_DHASH_ADD); + PL_DHashTableAdd(&mLiterals, value); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1466,12 +1465,11 @@ RDFServiceImpl::UnregisterLiteral(nsIRDFLiteral* aLiteral) const char16_t* value; aLiteral->GetValueConst(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mLiterals, - value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableLookup(&mLiterals, + value)), "literal was never registered"); - PL_DHashTableOperate(&mLiterals, value, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mLiterals, value); // N.B. that we _don't_ release the literal: we only held a weak // reference to it in the hashtable. @@ -1490,13 +1488,12 @@ RDFServiceImpl::RegisterInt(nsIRDFInt* aInt) int32_t value; aInt->GetValue(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mInts, - &value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mInts, + &value)), "int already registered"); PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mInts, &value, PL_DHASH_ADD); + PL_DHashTableAdd(&mInts, &value); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1524,12 +1521,11 @@ RDFServiceImpl::UnregisterInt(nsIRDFInt* aInt) int32_t value; aInt->GetValue(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mInts, - &value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableLookup(&mInts, + &value)), "int was never registered"); - PL_DHashTableOperate(&mInts, &value, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mInts, &value); // N.B. that we _don't_ release the literal: we only held a weak // reference to it in the hashtable. @@ -1548,13 +1544,12 @@ RDFServiceImpl::RegisterDate(nsIRDFDate* aDate) PRTime value; aDate->GetValue(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mDates, - &value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mDates, + &value)), "date already registered"); PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mDates, &value, PL_DHASH_ADD); + PL_DHashTableAdd(&mDates, &value); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1582,12 +1577,11 @@ RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate) PRTime value; aDate->GetValue(&value); - NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mDates, - &value, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableLookup(&mDates, + &value)), "date was never registered"); - PL_DHashTableOperate(&mDates, &value, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mDates, &value); // N.B. that we _don't_ release the literal: we only held a weak // reference to it in the hashtable. @@ -1601,13 +1595,12 @@ RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate) nsresult RDFServiceImpl::RegisterBlob(BlobImpl *aBlob) { - NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mBlobs, - &aBlob->mData, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableLookup(&mBlobs, + &aBlob->mData)), "blob already registered"); PLDHashEntryHdr *hdr = - PL_DHashTableOperate(&mBlobs, &aBlob->mData, PL_DHASH_ADD); + PL_DHashTableAdd(&mBlobs, &aBlob->mData); if (! hdr) return NS_ERROR_OUT_OF_MEMORY; @@ -1630,12 +1623,11 @@ RDFServiceImpl::RegisterBlob(BlobImpl *aBlob) nsresult RDFServiceImpl::UnregisterBlob(BlobImpl *aBlob) { - NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mBlobs, - &aBlob->mData, - PL_DHASH_LOOKUP)), + NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableLookup(&mBlobs, + &aBlob->mData)), "blob was never registered"); - PL_DHashTableOperate(&mBlobs, &aBlob->mData, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mBlobs, &aBlob->mData); // N.B. that we _don't_ release the literal: we only held a weak // reference to it in the hashtable. diff --git a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp index 7fad12d02eed..610774df836e 100644 --- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp +++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp @@ -962,7 +962,7 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress, // means, there has already been data transfered. ReentrantMonitorAutoEnter lock(mReentrantMonitor); - PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_ADD); + PL_DHashTableAdd(&mTransferringRequests, aRequest); return NS_OK; } @@ -975,10 +975,10 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress, { { /* scope for the ReentrantMonitorAutoEnter */ ReentrantMonitorAutoEnter lock(mReentrantMonitor); - PLDHashEntryHdr *entry = PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_LOOKUP); + PLDHashEntryHdr *entry = PL_DHashTableLookup(&mTransferringRequests, aRequest); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mTransferringRequests, aRequest); requestHasTransferedData = true; } diff --git a/security/manager/ssl/src/nsCertTree.cpp b/security/manager/ssl/src/nsCertTree.cpp index 0af9102625bd..3fbd53a12aae 100644 --- a/security/manager/ssl/src/nsCertTree.cpp +++ b/security/manager/ssl/src/nsCertTree.cpp @@ -212,13 +212,13 @@ nsCertTree::getCacheEntry(void *cache, void *aCert) PLDHashTable &aCompareCache = *reinterpret_cast(cache); CompareCacheHashEntryPtr *entryPtr = static_cast - (PL_DHashTableOperate(&aCompareCache, aCert, PL_DHASH_ADD)); + (PL_DHashTableAdd(&aCompareCache, aCert)); return entryPtr ? entryPtr->entry : nullptr; } void nsCertTree::RemoveCacheEntry(void *key) { - PL_DHashTableOperate(&mCompareCache, key, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mCompareCache, key); } // CountOrganizations diff --git a/security/manager/ssl/src/nsNSSShutDown.cpp b/security/manager/ssl/src/nsNSSShutDown.cpp index 2cf7418ae588..e2d2bee3725d 100644 --- a/security/manager/ssl/src/nsNSSShutDown.cpp +++ b/security/manager/ssl/src/nsNSSShutDown.cpp @@ -78,7 +78,7 @@ void nsNSSShutDownList::remember(nsNSSShutDownObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableOperate(&singleton->mObjects, o, PL_DHASH_ADD); + PL_DHashTableAdd(&singleton->mObjects, o); } void nsNSSShutDownList::forget(nsNSSShutDownObject *o) @@ -88,7 +88,7 @@ void nsNSSShutDownList::forget(nsNSSShutDownObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableOperate(&singleton->mObjects, o, PL_DHASH_REMOVE); + PL_DHashTableRemove(&singleton->mObjects, o); } void nsNSSShutDownList::remember(nsOnPK11LogoutCancelObject *o) @@ -98,7 +98,7 @@ void nsNSSShutDownList::remember(nsOnPK11LogoutCancelObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableOperate(&singleton->mPK11LogoutCancelObjects, o, PL_DHASH_ADD); + PL_DHashTableAdd(&singleton->mPK11LogoutCancelObjects, o); } void nsNSSShutDownList::forget(nsOnPK11LogoutCancelObject *o) @@ -108,7 +108,7 @@ void nsNSSShutDownList::forget(nsOnPK11LogoutCancelObject *o) PR_ASSERT(o); MutexAutoLock lock(singleton->mListLock); - PL_DHashTableOperate(&singleton->mPK11LogoutCancelObjects, o, PL_DHASH_REMOVE); + PL_DHashTableRemove(&singleton->mPK11LogoutCancelObjects, o); } void nsNSSShutDownList::trackSSLSocketCreate() diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index f7ce1262468c..f086b5499414 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -1344,7 +1344,7 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress, nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest) { - if (!PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_ADD)) { + if (!PL_DHashTableAdd(&mRequestInfoHash, aRequest)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1353,15 +1353,14 @@ nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest) void nsDocLoader::RemoveRequestInfo(nsIRequest *aRequest) { - PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_REMOVE); + PL_DHashTableRemove(&mRequestInfoHash, aRequest); } nsDocLoader::nsRequestInfo* nsDocLoader::GetRequestInfo(nsIRequest* aRequest) { nsRequestInfo* info = static_cast - (PL_DHashTableOperate(&mRequestInfoHash, aRequest, - PL_DHASH_LOOKUP)); + (PL_DHashTableLookup(&mRequestInfoHash, aRequest)); if (PL_DHASH_ENTRY_IS_FREE(info)) { // Nothing found in the hash, return null. From 46028c56ae1345994c132ac6d6b7c8be1be202e8 Mon Sep 17 00:00:00 2001 From: Shawn Ku Date: Wed, 7 Jan 2015 00:27:09 +0800 Subject: [PATCH 132/224] Bug 1113476: WebIDL patch - B2G RIL: support nsck/pck for SIM Lock types. r=edgar,hsinyi. --- dom/webidl/MozIcc.webidl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dom/webidl/MozIcc.webidl b/dom/webidl/MozIcc.webidl index eb664d660d49..09c71b84c897 100644 --- a/dom/webidl/MozIcc.webidl +++ b/dom/webidl/MozIcc.webidl @@ -57,19 +57,23 @@ enum IccLockType "puk", "puk2", "nck", // Network depersonalization -- network control key (NCK). + "nsck", // Network subset depersonalization -- network subset control key (NSCK). "nck1", // Network type 1 depersonalization -- network type 1 control key (NCK1). "nck2", // Network type 2 depersonalization -- network type 2 control key (NCK2). "hnck", // HRPD network depersonalization -- HRPD network control key (HNCK). "cck", // Corporate depersonalization -- corporate control key (CCK). "spck", // Service provider depersonalization -- service provider control key (SPCK). + "pck", // SIM depersonalization -- personalization control key (PCK). "rcck", // RUIM corporate depersonalization -- RUIM corporate control key (RCCK). "rspck", // RUIM service provider depersonalization -- RUIM service provider control key (RSPCK). "nckPuk", // Network PUK depersonalization -- network control key (NCK). + "nsckPuk", // Network subset PUK depersonalization -- network subset control key (NSCK). "nck1Puk", // Network type 1 PUK depersonalization -- network type 1 control key (NCK1). "nck2Puk", // Network type 2 PUK depersonalization -- Network type 2 control key (NCK2). "hnckPuk", // HRPD network PUK depersonalization -- HRPD network control key (HNCK). "cckPuk", // Corporate PUK depersonalization -- corporate control key (CCK). "spckPuk", // Service provider PUK depersonalization -- service provider control key (SPCK). + "pckPuk", // SIM PUK depersonalization -- personalization control key (PCK). "rcckPuk", // RUIM corporate PUK depersonalization -- RUIM corporate control key (RCCK). "rspckPuk", // RUIM service provider PUK depersonalization -- service provider control key (SPCK). "fdn" @@ -99,12 +103,12 @@ dictionary IccUnlockCardLockOptions required IccLockType lockType; DOMString? pin = null; // Necessary for lock types: "pin", "pin2", "nck", - // "nck1", "nck2", "hnck", "cck", "spck", "rcck", - // "rspck". + // "nsck", "nck1", "nck2", "hnck", "cck", "spck", + // "pck", "rcck", "rspck". DOMString? puk = null; // Necessary for lock types: "puk", "puk2", "nckPuk", - // "nck1Puk", "nck2Puk", "hnckPuk", "cckPuk", - // "spckPuk", "rcckPuk", "rspckPuk". + // "nsckPuk", "nck1Puk", "nck2Puk", "hnckPuk", "cckPuk", + // "spckPuk", "pckPuk", "rcckPuk", "rspckPuk". DOMString? newPin = null; // Necessary for lock types: "puk", "puk2". }; From 9b09e9d3fb3c21a81ee85519a65202362f0b9e17 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 8 Jan 2015 16:08:33 +0100 Subject: [PATCH 133/224] Backed out changeset 2ee5068037f2 (bug 1055658) --- layout/generic/RubyReflowState.cpp | 24 ++++++++ layout/generic/RubyReflowState.h | 68 +++++++++++++++++++++ layout/generic/moz.build | 1 + layout/generic/nsHTMLReflowState.cpp | 2 + layout/generic/nsHTMLReflowState.h | 7 +++ layout/generic/nsLineLayout.cpp | 5 ++ layout/generic/nsLineLayout.h | 15 +++++ layout/generic/nsRubyBaseContainerFrame.cpp | 3 +- layout/generic/nsRubyBaseContainerFrame.h | 3 +- layout/generic/nsRubyFrame.cpp | 6 ++ layout/generic/nsRubyTextContainerFrame.cpp | 7 ++- layout/generic/nsRubyTextContainerFrame.h | 10 +-- 12 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 layout/generic/RubyReflowState.cpp create mode 100644 layout/generic/RubyReflowState.h diff --git a/layout/generic/RubyReflowState.cpp b/layout/generic/RubyReflowState.cpp new file mode 100644 index 000000000000..8cade0c415ee --- /dev/null +++ b/layout/generic/RubyReflowState.cpp @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* states and methods used while laying out a ruby segment */ + +#include "RubyReflowState.h" + +using namespace mozilla; + +RubyReflowState::RubyReflowState( + WritingMode aLineWM, + const nsTArray& aTextContainers) + : mCurrentContainerIndex(kBaseContainerIndex) +{ + uint32_t rtcCount = aTextContainers.Length(); + mTextContainers.SetCapacity(rtcCount); + for (uint32_t i = 0; i < rtcCount; i++) { + mTextContainers.AppendElement( + TextContainerInfo(aLineWM, aTextContainers[i])); + } +} diff --git a/layout/generic/RubyReflowState.h b/layout/generic/RubyReflowState.h new file mode 100644 index 000000000000..212317b3f73e --- /dev/null +++ b/layout/generic/RubyReflowState.h @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* states and methods used while laying out a ruby segment */ + +#ifndef mozilla_RubyReflowState_h_ +#define mozilla_RubyReflowState_h_ + +#include "mozilla/Attributes.h" +#include "WritingModes.h" +#include "nsTArray.h" + +#define RTC_ARRAY_SIZE 1 + +class nsRubyTextContainerFrame; + +namespace mozilla { + +class MOZ_STACK_CLASS RubyReflowState MOZ_FINAL +{ +public: + explicit RubyReflowState( + WritingMode aLineWM, + const nsTArray& aTextContainers); + + struct TextContainerInfo + { + nsRubyTextContainerFrame* mFrame; + LogicalSize mLineSize; + + TextContainerInfo(WritingMode aLineWM, nsRubyTextContainerFrame* aFrame) + : mFrame(aFrame) + , mLineSize(aLineWM) { } + }; + + void AdvanceCurrentContainerIndex() { mCurrentContainerIndex++; } + + void SetTextContainerInfo(int32_t aIndex, + nsRubyTextContainerFrame* aContainer, + const LogicalSize& aLineSize) + { + MOZ_ASSERT(mTextContainers[aIndex].mFrame == aContainer); + mTextContainers[aIndex].mLineSize = aLineSize; + } + + const TextContainerInfo& + GetCurrentTextContainerInfo(nsRubyTextContainerFrame* aFrame) const + { + MOZ_ASSERT(mTextContainers[mCurrentContainerIndex].mFrame == aFrame); + return mTextContainers[mCurrentContainerIndex]; + } + +private: + static MOZ_CONSTEXPR_VAR int32_t kBaseContainerIndex = -1; + // The index of the current reflowing container. When it equals to + // kBaseContainerIndex, we are reflowing ruby base. Otherwise, it + // stands for the index of text containers in the ruby segment. + int32_t mCurrentContainerIndex; + + nsAutoTArray mTextContainers; +}; + +} + +#endif // mozilla_RubyReflowState_h_ diff --git a/layout/generic/moz.build b/layout/generic/moz.build index 0d413496e088..be752630b8a0 100644 --- a/layout/generic/moz.build +++ b/layout/generic/moz.build @@ -95,6 +95,7 @@ UNIFIED_SOURCES += [ 'nsTextRunTransformations.cpp', 'nsVideoFrame.cpp', 'nsViewportFrame.cpp', + 'RubyReflowState.cpp', 'RubyUtils.cpp', 'ScrollbarActivity.cpp', 'StickyScrollContainer.cpp', diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 34446aea1660..53a9e43c2caf 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -72,6 +72,7 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext, AvailableBSize() = aAvailableSpace.BSize(mWritingMode); mFloatManager = nullptr; mLineLayout = nullptr; + mRubyReflowState = nullptr; memset(&mFlags, 0, sizeof(mFlags)); mDiscoveredClearance = nullptr; mPercentHeightObserver = nullptr; @@ -207,6 +208,7 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext, mLineLayout = aParentReflowState.mLineLayout; else mLineLayout = nullptr; + mRubyReflowState = nullptr; // Note: mFlags was initialized as a copy of aParentReflowState.mFlags up in // this constructor's init list, so the only flags that we need to explicitly diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index da282f702bd6..7c6751e632f6 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -21,6 +21,10 @@ class nsLineLayout; class nsIPercentHeightObserver; struct nsHypotheticalBox; +namespace mozilla { +class RubyReflowState; +} + /** * @return aValue clamped to [aMinValue, aMaxValue]. * @@ -258,6 +262,9 @@ struct nsHTMLReflowState : public nsCSSOffsetState { // LineLayout object (only for inline reflow; set to nullptr otherwise) nsLineLayout* mLineLayout; + // RubyReflowState object (only for ruby reflow; set to nullptr otherwise) + mozilla::RubyReflowState* mRubyReflowState; + // The appropriate reflow state for the containing block (for // percentage widths, etc.) of this reflow state's frame. const nsHTMLReflowState *mCBReflowState; diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 3bb43cea7b56..676f49eeff5f 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -67,6 +67,7 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, mForceBreakFrameOffset(-1), mMinLineBSize(0), mTextIndent(0), + mRubyReflowState(nullptr), mFirstLetterStyleOK(false), mIsTopOfPage(false), mImpactedByFloats(false), @@ -885,6 +886,10 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, aFrame, availSize); nsHTMLReflowState& reflowState = *reflowStateHolder; reflowState.mLineLayout = this; + if (mRubyReflowState) { + reflowState.mRubyReflowState = mRubyReflowState; + mRubyReflowState = nullptr; + } reflowState.mFlags.mIsTopOfPage = mIsTopOfPage; if (reflowState.ComputedISize() == NS_UNCONSTRAINEDSIZE) { reflowState.AvailableISize() = availableSpaceOnLine; diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 64beb5fe7000..44bf7286aa75 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -27,6 +27,10 @@ class nsFloatManager; struct nsStyleText; +namespace mozilla { +class RubyReflowState; +} + class nsLineLayout { public: /** @@ -98,6 +102,13 @@ public: bool IsZeroBSize(); + // The ruby layout will be passed to the next frame to be reflowed + // via the HTML reflow state. + void SetRubyReflowState(mozilla::RubyReflowState* aRubyReflowState) + { + mRubyReflowState = aRubyReflowState; + } + // Reflows the frame and returns the reflow status. aPushedFrame is true // if the frame is pushed to the next line because it doesn't fit. void ReflowFrame(nsIFrame* aFrame, @@ -554,6 +565,10 @@ protected: int32_t mLineNumber; mozilla::JustificationInfo mJustificationInfo; + // The ruby layout for the next frame to be reflowed. + // It is reset every time it is used. + mozilla::RubyReflowState* mRubyReflowState; + int32_t mTotalPlacedFrames; nscoord mBStartEdge; diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 0a280ea3c720..0a613310b852 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -341,6 +341,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, "No line layout provided to RubyBaseContainerFrame reflow method."); return; } + MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided"); AutoTextContainerArray textContainers; GetTextContainers(textContainers); @@ -493,7 +494,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, lineLayout->VerticalAlignLine(); LogicalSize lineSize(lineWM, rtcISize, lineLayout->GetFinalLineBSize()); - textContainer->SetLineSize(lineSize); + aReflowState.mRubyReflowState->SetTextContainerInfo(i, textContainer, lineSize); lineLayout->EndLineReflow(); } diff --git a/layout/generic/nsRubyBaseContainerFrame.h b/layout/generic/nsRubyBaseContainerFrame.h index 530acc6c2a61..526a861d58be 100644 --- a/layout/generic/nsRubyBaseContainerFrame.h +++ b/layout/generic/nsRubyBaseContainerFrame.h @@ -13,8 +13,7 @@ #include "nsRubyTextContainerFrame.h" #include "nsRubyBaseFrame.h" #include "nsRubyTextFrame.h" - -#define RTC_ARRAY_SIZE 1 +#include "RubyReflowState.h" /** * Factory function. diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 68eabe110b53..c9b059cf139d 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -11,6 +11,7 @@ #include "nsStyleContext.h" #include "WritingModes.h" #include "RubyUtils.h" +#include "RubyReflowState.h" #include "nsRubyBaseContainerFrame.h" #include "nsRubyTextContainerFrame.h" @@ -240,9 +241,11 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, textContainers.AppendElement(iter.GetTextContainer()); } const uint32_t rtcCount = textContainers.Length(); + RubyReflowState rubyReflowState(lineWM, textContainers); nsHTMLReflowMetrics baseMetrics(aReflowState); bool pushedFrame; + aReflowState.mLineLayout->SetRubyReflowState(&rubyReflowState); aReflowState.mLineLayout->ReflowFrame(aBaseContainer, aStatus, &baseMetrics, pushedFrame); @@ -327,10 +330,13 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, nsRect offsetRect = baseRect; for (uint32_t i = 0; i < rtcCount; i++) { nsRubyTextContainerFrame* textContainer = textContainers[i]; + rubyReflowState.AdvanceCurrentContainerIndex(); + nsReflowStatus textReflowStatus; nsHTMLReflowMetrics textMetrics(aReflowState); nsHTMLReflowState textReflowState(aPresContext, aReflowState, textContainer, availSize); + textReflowState.mRubyReflowState = &rubyReflowState; // FIXME We probably shouldn't be using the same nsLineLayout for // the text containers. But it should be fine now as we are // not actually using this line layout to reflow something, diff --git a/layout/generic/nsRubyTextContainerFrame.cpp b/layout/generic/nsRubyTextContainerFrame.cpp index 4721ba0813cc..2c75e8a738ca 100644 --- a/layout/generic/nsRubyTextContainerFrame.cpp +++ b/layout/generic/nsRubyTextContainerFrame.cpp @@ -10,6 +10,7 @@ #include "nsPresContext.h" #include "nsStyleContext.h" #include "WritingModes.h" +#include "RubyReflowState.h" #include "mozilla/UniquePtr.h" using namespace mozilla; @@ -124,6 +125,8 @@ nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext, DO_GLOBAL_REFLOW_COUNT("nsRubyTextContainerFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); + MOZ_ASSERT(aReflowState.mRubyReflowState, "No ruby reflow state provided"); + // All rt children have already been reflowed. All we need to do is // to report complete and return the desired size provided by the // ruby base container. @@ -134,5 +137,7 @@ nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext, // will take care of our continuations. aStatus = NS_FRAME_COMPLETE; WritingMode lineWM = aReflowState.mLineLayout->GetWritingMode(); - aDesiredSize.SetSize(lineWM, mLineSize); + const RubyReflowState::TextContainerInfo& info = + aReflowState.mRubyReflowState->GetCurrentTextContainerInfo(this); + aDesiredSize.SetSize(lineWM, info.mLineSize); } diff --git a/layout/generic/nsRubyTextContainerFrame.h b/layout/generic/nsRubyTextContainerFrame.h index ce79f6242f4c..b2588f5048a0 100644 --- a/layout/generic/nsRubyTextContainerFrame.h +++ b/layout/generic/nsRubyTextContainerFrame.h @@ -62,18 +62,12 @@ protected: NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); explicit nsRubyTextContainerFrame(nsStyleContext* aContext) - : nsRubyTextContainerFrameSuper(aContext) - , mLineSize(mozilla::WritingMode(aContext)) {} + : nsRubyTextContainerFrameSuper(aContext) {} void UpdateSpanFlag(); + // For MoveOverflowToChildList friend class nsRubyBaseContainerFrame; - void SetLineSize(const mozilla::LogicalSize& aSize) { mLineSize = aSize; } - - // The intended dimensions of the ruby text container. It is set by - // the corresponding ruby base container when the segment is reflowed, - // and used when the ruby text container is reflowed by its parent. - mozilla::LogicalSize mLineSize; }; #endif /* nsRubyTextContainerFrame_h___ */ From e541bdd18608277481ee731293e88d3ceb525878 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 8 Jan 2015 16:08:35 +0100 Subject: [PATCH 134/224] Backed out changeset 9371c6f11873 (bug 1055658) --- layout/reftests/css-ruby/reftest.list | 2 -- .../css-ruby/relative-positioning-1-ref.html | 29 --------------- .../css-ruby/relative-positioning-1.html | 24 ------------- .../css-ruby/relative-positioning-2-ref.html | 36 ------------------- .../css-ruby/relative-positioning-2.html | 30 ---------------- 5 files changed, 121 deletions(-) delete mode 100644 layout/reftests/css-ruby/relative-positioning-1-ref.html delete mode 100644 layout/reftests/css-ruby/relative-positioning-1.html delete mode 100644 layout/reftests/css-ruby/relative-positioning-2-ref.html delete mode 100644 layout/reftests/css-ruby/relative-positioning-2.html diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index 87e2cd174267..c903e1df745e 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -28,8 +28,6 @@ fuzzy-if(winWidget,35,1) == dynamic-removal-3.html dynamic-removal-3-ref.html # == line-height-1.html line-height-1-ref.html == line-height-2.html line-height-2-ref.html == line-height-3.html line-height-3-ref.html -== relative-positioning-1.html relative-positioning-1-ref.html -== relative-positioning-2.html relative-positioning-2-ref.html == ruby-span-1.html ruby-span-1-ref.html == ruby-whitespace-1.html ruby-whitespace-1-ref.html == ruby-whitespace-2.html ruby-whitespace-2-ref.html diff --git a/layout/reftests/css-ruby/relative-positioning-1-ref.html b/layout/reftests/css-ruby/relative-positioning-1-ref.html deleted file mode 100644 index f8df05509207..000000000000 --- a/layout/reftests/css-ruby/relative-positioning-1-ref.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Bug 1055658 - Relative positioning for ruby - - - -
-
-
-
abc
-   -
- base -
-
- - diff --git a/layout/reftests/css-ruby/relative-positioning-1.html b/layout/reftests/css-ruby/relative-positioning-1.html deleted file mode 100644 index 0616f2e0e40d..000000000000 --- a/layout/reftests/css-ruby/relative-positioning-1.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Bug 1055658 - Relative positioning for ruby - - - - - - base - abc -
-
- - diff --git a/layout/reftests/css-ruby/relative-positioning-2-ref.html b/layout/reftests/css-ruby/relative-positioning-2-ref.html deleted file mode 100644 index ac3568c9505e..000000000000 --- a/layout/reftests/css-ruby/relative-positioning-2-ref.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Bug 1055658 - Relative positioning for ruby - - - -
- before -
-
-
- text1 - text2 - text3 -
-   -
- base1 - base2 - base3 -
- after -
- - diff --git a/layout/reftests/css-ruby/relative-positioning-2.html b/layout/reftests/css-ruby/relative-positioning-2.html deleted file mode 100644 index 34dcc69b731f..000000000000 --- a/layout/reftests/css-ruby/relative-positioning-2.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Bug 1055658 - Relative positioning for ruby - - - - - before - - base1 - text1 - base2 - text2 - base3 - text3 - - after - - From a2b93bb8fad8710b986c5da6c1444c876debd5ba Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 8 Jan 2015 16:08:37 +0100 Subject: [PATCH 135/224] Backed out changeset f4e02295ff1f (bug 1055658) --- layout/generic/nsLineLayout.cpp | 41 --------------------------------- layout/generic/nsLineLayout.h | 3 --- 2 files changed, 44 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 676f49eeff5f..a6f8b3503a4c 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -253,21 +253,6 @@ nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord, pfd->mAscent = 0; pfd->mSpan = psd; psd->mFrame = pfd; - nsIFrame* frame = mBlockReflowState->frame; - if (frame->GetType() == nsGkAtoms::rubyTextContainerFrame) { - // Ruby text container won't be reflowed via ReflowFrame, hence the - // relative positioning information should be recorded here. - MOZ_ASSERT(mBaseLineLayout != this); - pfd->mRelativePos = - mBlockReflowState->mStyleDisplay->IsRelativelyPositionedStyle(); - if (pfd->mRelativePos) { - MOZ_ASSERT( - mBlockReflowState->GetWritingMode() == frame->GetWritingMode(), - "mBlockReflowState->frame == frame, " - "hence they should have identical writing mode"); - pfd->mOffsets = mBlockReflowState->ComputedLogicalOffsets(); - } - } } void @@ -690,7 +675,6 @@ nsLineLayout::NewPerFrameData(nsIFrame* aFrame) WritingMode frameWM = aFrame->GetWritingMode(); WritingMode lineWM = mRootSpan->mWritingMode; pfd->mBounds = LogicalRect(lineWM); - pfd->mOverflowAreas.Clear(); pfd->mMargin = LogicalMargin(lineWM); pfd->mBorderPadding = LogicalMargin(lineWM); pfd->mOffsets = LogicalMargin(frameWM); @@ -3056,26 +3040,6 @@ nsLineLayout::ApplyRelativePositioning(PerFrameData* aPFD) frame->SetPosition(frameWM, origin, mContainerWidth); } -// This method do relative positioning for ruby annotations. -void -nsLineLayout::RelativePositionAnnotations(PerSpanData* aRubyPSD, - nsOverflowAreas& aOverflowAreas) -{ - MOZ_ASSERT(aRubyPSD->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame); - for (PerFrameData* pfd = aRubyPSD->mFirstFrame; pfd; pfd = pfd->mNext) { - MOZ_ASSERT(pfd->mFrame->GetType() == nsGkAtoms::rubyBaseContainerFrame); - for (PerFrameData* rtc = pfd->mNextAnnotation; - rtc; rtc = rtc->mNextAnnotation) { - nsIFrame* rtcFrame = rtc->mFrame; - MOZ_ASSERT(rtcFrame->GetType() == nsGkAtoms::rubyTextContainerFrame); - ApplyRelativePositioning(rtc); - nsOverflowAreas rtcOverflowAreas; - RelativePositionFrames(rtc->mSpan, rtcOverflowAreas); - aOverflowAreas.UnionWith(rtcOverflowAreas + rtcFrame->GetPosition()); - } - } -} - void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas) { @@ -3170,11 +3134,6 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo overflowAreas.UnionWith(r + frame->GetPosition()); } - // Also compute relative position in the annotations. - if (psd->mFrame->mFrame->GetType() == nsGkAtoms::rubyFrame) { - RelativePositionAnnotations(psd, overflowAreas); - } - // If we just computed a spans combined area, we need to update its // overflow rect... if (psd != mRootSpan) { diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 44bf7286aa75..32000148b55b 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -667,9 +667,6 @@ protected: void ApplyRelativePositioning(PerFrameData* aPFD); - void RelativePositionAnnotations(PerSpanData* aRubyPSD, - nsOverflowAreas& aOverflowAreas); - void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); From 4b471b29533de1a52ddf52272de7f08c54543030 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 8 Jan 2015 16:08:58 +0100 Subject: [PATCH 136/224] Backed out changeset 68d2b24c9351 (bug 1055658) for Reftest Failures --- layout/generic/nsLineLayout.cpp | 30 ++++++++++-------------------- layout/generic/nsLineLayout.h | 2 -- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index a6f8b3503a4c..3e222ca16d5a 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -3021,25 +3021,6 @@ nsLineLayout::RelativePositionFrames(nsOverflowAreas& aOverflowAreas) RelativePositionFrames(mRootSpan, aOverflowAreas); } -// This method applies any relative positioning to the given frame. -void -nsLineLayout::ApplyRelativePositioning(PerFrameData* aPFD) -{ - if (!aPFD->mRelativePos) { - return; - } - - nsIFrame* frame = aPFD->mFrame; - WritingMode frameWM = frame->GetWritingMode(); - LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth); - // right and bottom are handled by - // nsHTMLReflowState::ComputeRelativeOffsets - nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM, - aPFD->mOffsets, &origin, - mContainerWidth); - frame->SetPosition(frameWM, origin, mContainerWidth); -} - void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas) { @@ -3078,7 +3059,16 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo nsIFrame* frame = pfd->mFrame; // Adjust the origin of the frame - ApplyRelativePositioning(pfd); + if (pfd->mRelativePos) { + WritingMode frameWM = frame->GetWritingMode(); + LogicalPoint origin = frame->GetLogicalPosition(mContainerWidth); + // right and bottom are handled by + // nsHTMLReflowState::ComputeRelativeOffsets + nsHTMLReflowState::ApplyRelativePositioning(frame, frameWM, + pfd->mOffsets, &origin, + mContainerWidth); + frame->SetPosition(frameWM, origin, mContainerWidth); + } // We must position the view correctly before positioning its // descendants so that widgets are positioned properly (since only diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 32000148b55b..5eb9fff79a60 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -665,8 +665,6 @@ protected: nscoord aDistanceFromStart, nscoord aLineBSize); - void ApplyRelativePositioning(PerFrameData* aPFD); - void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas); bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize); From f04a74700aa8a1d703f5771a8e41af2023d65e17 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Thu, 8 Jan 2015 10:13:05 -0500 Subject: [PATCH 137/224] Bug 1118329 - reduce osx 10.6 talos jobs via talos.json. r=armenzg --- .../mochitest/tests/SimpleTest/SimpleTest.js | 4 +-- testing/talos/talos.json | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/testing/mochitest/tests/SimpleTest/SimpleTest.js b/testing/mochitest/tests/SimpleTest/SimpleTest.js index 8361fc655bbe..5ed67f6fd30e 100644 --- a/testing/mochitest/tests/SimpleTest/SimpleTest.js +++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js @@ -259,8 +259,8 @@ SimpleTest.ok = function (condition, name, diag) { SimpleTest.num_failed++; test.result = !test.result; } - var successInfo = {status:"PASS", expected:"PASS", message:"TEST-PASS"}; - var failureInfo = {status:"FAIL", expected:"FAIL", message:"TEST-KNOWN-FAIL"}; + var successInfo = {status:"FAIL", expected:"FAIL", message:"TEST-KNOWN-FAIL"}; + var failureInfo = {status:"PASS", expected:"FAIL", message:"TEST-UNEXPECTED-PASS"}; } else { var successInfo = {status:"PASS", expected:"PASS", message:"TEST-PASS"}; var failureInfo = {status:"FAIL", expected:"PASS", message:"TEST-UNEXPECTED-FAIL"}; diff --git a/testing/talos/talos.json b/testing/talos/talos.json index bf19b406e119..a75772999df9 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -14,10 +14,17 @@ "chromez": { "tests": ["tresize", "tcanvasmark"] }, + "chromez-snow": { + "tests": ["tresize", "tcanvasmark"] + }, "chromez-e10s": { "tests": ["tresize", "tcanvasmark"], "talos_options": ["--e10s"] }, + "chromez-snow-e10s": { + "tests": ["tresize", "tcanvasmark"], + "talos_options": ["--e10s"] + }, "dromaeojs": { "tests": ["dromaeo_css", "dromaeo_dom", "kraken", "v8_7"] }, @@ -28,6 +35,12 @@ "other": { "tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"] }, + "other-snow": { + "tests": ["tpaint"] + }, + "other-snow-e10s": { + "tests": ["tpaint"] + }, "other_nol64": { "tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"] }, @@ -63,6 +76,12 @@ "64": "http://talos-bundles.pvt.build.mozilla.org/zips/flash64_11_0_d1_98.zip" } }, + "g1-snow": { + "tests": ["glterrain"] + }, + "g1-snow-e10s": { + "tests": ["glterrain"] + }, "svgr": { "tests": ["tsvgx", "tsvgr_opacity", "tart", "tscrollx", "cart"] }, @@ -70,6 +89,12 @@ "tests": ["tsvgx", "tsvgr_opacity", "tart", "tscrollx", "cart"], "talos_options": ["--e10s"] }, + "svgr-snow": { + "tests": ["tsvgx", "tscrollx"] + }, + "svgr-snow-e10s": { + "tests": ["tsvgx", "tscrollx"] + }, "tp5o": { "tests": ["tp5o"], "pagesets_url": "http://talos-bundles.pvt.build.mozilla.org/zips/tp5n.zip", From 84a2b0acc4412cc22682e0ae2f375c8471d615f6 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Thu, 8 Jan 2015 16:28:08 +0100 Subject: [PATCH 138/224] Bug 1119266 - Disable test_oscillatorNodeNegativeFrequency.html for failures on Android, on a CLOSED TREE. --- dom/media/webaudio/test/mochitest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/dom/media/webaudio/test/mochitest.ini b/dom/media/webaudio/test/mochitest.ini index abe4b7fca50b..36cd3186dc3a 100644 --- a/dom/media/webaudio/test/mochitest.ini +++ b/dom/media/webaudio/test/mochitest.ini @@ -127,6 +127,7 @@ skip-if = (toolkit == 'gonk' && !debug) [test_oscillatorNode.html] [test_oscillatorNode2.html] [test_oscillatorNodeNegativeFrequency.html] +skip-if = (toolkit == 'gonk') || (toolkit == 'android') [test_oscillatorNodePassThrough.html] [test_oscillatorNodeStart.html] [test_oscillatorTypeChange.html] From 42db4dcf46280737a002c0f3429d8431aadac49f Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 08:42:42 -0500 Subject: [PATCH 139/224] Bug 1119225 - Emulate Visual C++ 2013 Update 3 when using clang-cl; r=ted --- build/autoconf/toolchain.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/autoconf/toolchain.m4 b/build/autoconf/toolchain.m4 index 08b7f5d7046c..c211b886ed7f 100644 --- a/build/autoconf/toolchain.m4 +++ b/build/autoconf/toolchain.m4 @@ -86,9 +86,9 @@ if test "$compiler" = "clang-cl"; then CC_VERSION=1800 CXX_VERSION=1800 MSVC_VERSION_FULL=180030723 - # Build on clang-cl with MSVC 2013 with fallback emulation. - CFLAGS="$CFLAGS -fmsc-version=1800 -fallback" - CXXFLAGS="$CXXFLAGS -fmsc-version=1800 -fallback" + # Build on clang-cl with MSVC 2013 Update 3 with fallback emulation. + CFLAGS="$CFLAGS -fms-compatibility-version=18.00.30723 -fallback" + CXXFLAGS="$CXXFLAGS -fms-compatibility-version=18.00.30723 -fallback" fi if test "$GNU_CC"; then From 895b53981b09b52edfe3e275080cef3f1562d51e Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 09:25:18 -0500 Subject: [PATCH 140/224] Bug 1119228 - Fix a fatal warning in PossiblyFail; r=jandem Recent clang emits the following warning (which is treated as an error) on this code: error: implicit conversion of nullptr constant to 'bool' [-Werror,-Wnull-conversion] --- js/public/Utility.h | 9 +++++++++ js/src/jsgcinlines.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/js/public/Utility.h b/js/public/Utility.h index 3c4c4e4935e1..e9ae6d72a0c4 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -88,9 +88,18 @@ static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() { asm(""); } return nullptr; \ } \ } while (0) +# define JS_OOM_POSSIBLY_FAIL_BOOL() \ + do \ + { \ + if (++OOM_counter > OOM_maxAllocations) { \ + JS_OOM_CALL_BP_FUNC();\ + return false; \ + } \ + } while (0) # else # define JS_OOM_POSSIBLY_FAIL() do {} while(0) +# define JS_OOM_POSSIBLY_FAIL_BOOL() do {} while(0) # endif /* DEBUG || JS_OOM_BREAKPOINT */ static inline void* js_malloc(size_t bytes) diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index f8a93b79ce6b..2ac758e5403d 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -444,7 +444,7 @@ TryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicSlots) static inline bool PossiblyFail() { - JS_OOM_POSSIBLY_FAIL(); + JS_OOM_POSSIBLY_FAIL_BOOL(); return true; } From 6c043d2ab76c7063623945de8f70d365f3e3cb10 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 09:36:31 -0500 Subject: [PATCH 141/224] Bug 1119232 - Fix a warning for the usage of the uninitialized gc member in JSRuntime's constructor; r=jandem clang emits the following warning on this code: warning: field 'gc' is uninitialized when used here [-Wuninitialized] The warning is not an indication of a real bug since we're just taking the store buffer's address, but we may as well silence it. --- js/src/jspubtd.h | 9 +++++++-- js/src/vm/Runtime.cpp | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index c4fd75c923e8..8581c5d33a3c 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -146,9 +146,9 @@ struct Runtime js::gc::StoreBuffer *gcStoreBufferPtr_; public: - explicit Runtime(js::gc::StoreBuffer *storeBuffer) + Runtime() : needsIncrementalBarrier_(false) - , gcStoreBufferPtr_(storeBuffer) + , gcStoreBufferPtr_(nullptr) {} bool needsIncrementalBarrier() const { @@ -161,6 +161,11 @@ struct Runtime return reinterpret_cast(rt); } + protected: + void setGCStoreBufferPtr(js::gc::StoreBuffer *storeBuffer) { + gcStoreBufferPtr_ = storeBuffer; + } + /* Allow inlining of PersistentRooted constructors and destructors. */ private: template friend class JS::PersistentRooted; diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 588b74054df4..a2a2c4067798 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -130,8 +130,7 @@ ReturnZeroSize(const void *p) } JSRuntime::JSRuntime(JSRuntime *parentRuntime) - : JS::shadow::Runtime(&gc.storeBuffer), - mainThread(this), + : mainThread(this), parentRuntime(parentRuntime), interrupt_(false), interruptPar_(false), @@ -230,6 +229,8 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime) oomCallback(nullptr), debuggerMallocSizeOf(ReturnZeroSize) { + setGCStoreBufferPtr(&gc.storeBuffer); + liveRuntimesCount++; /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ From 039292de5de816443353242cf68d1c6c82bb3b58 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 10:38:48 -0500 Subject: [PATCH 142/224] Bug 1119071 - Clean up some code used for older unsupported MSVC versions in MFBT; r=froydnj --- mfbt/Atomics.h | 9 +-------- mfbt/Attributes.h | 14 ++------------ mfbt/Compiler.h | 13 ------------- mfbt/NullPtr.h | 2 +- mfbt/TypedEnumInternal.h | 4 +--- mfbt/tests/TestMaybe.cpp | 15 +++++---------- mfbt/tests/TestTypedEnum.cpp | 4 +--- mfbt/tests/TestUniquePtr.cpp | 22 ---------------------- 8 files changed, 11 insertions(+), 72 deletions(-) diff --git a/mfbt/Atomics.h b/mfbt/Atomics.h index c7f76014276f..bf93f44f3bbd 100644 --- a/mfbt/Atomics.h +++ b/mfbt/Atomics.h @@ -42,14 +42,7 @@ # elif MOZ_USING_LIBCXX && defined(__clang__) # define MOZ_HAVE_CXX11_ATOMICS # endif -/* - * Although Visual Studio 2012's CRT supports , its atomic load - * implementation unnecessarily uses an atomic intrinsic for the less - * restrictive memory orderings, which can be prohibitively expensive. - * Therefore, we require at least Visual Studio 2013 for using the CRT - * (bug 1061764). - */ -#elif defined(_MSC_VER) && _MSC_VER >= 1800 +#elif defined(_MSC_VER) # if defined(DEBUG) /* * Provide our own failure code since we're having trouble linking to diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index 8b08d6078f15..d916d6a81ccf 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -50,18 +50,8 @@ * don't indicate support for them here, due to * http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug */ -# if _MSC_VER >= 1800 -# define MOZ_HAVE_CXX11_DELETE -# endif -# if _MSC_VER >= 1700 -# define MOZ_HAVE_CXX11_FINAL final -# else -# if defined(__clang__) -# error Please do not try to use clang-cl with MSVC10 or below emulation! -# endif - /* MSVC <= 10 used to spell "final" as "sealed". */ -# define MOZ_HAVE_CXX11_FINAL sealed -# endif +# define MOZ_HAVE_CXX11_DELETE +# define MOZ_HAVE_CXX11_FINAL final # define MOZ_HAVE_CXX11_OVERRIDE # define MOZ_HAVE_NEVER_INLINE __declspec(noinline) # define MOZ_HAVE_NORETURN __declspec(noreturn) diff --git a/mfbt/Compiler.h b/mfbt/Compiler.h index 50f127da8623..290fe51a358b 100644 --- a/mfbt/Compiler.h +++ b/mfbt/Compiler.h @@ -31,19 +31,6 @@ # undef MOZ_IS_MSVC # define MOZ_IS_MSVC 1 - /* - * This macro should simplify MSVC version checking. For example, to check - * for VC10 or later, check `#ifdef MOZ_MSVC_VERSION_AT_LEAST(10)`. - */ -# define MOZ_MSVC_VERSION_AT_LEAST(version) \ - (version == 10 ? _MSC_VER >= 1600 : \ - (version == 11 ? _MSC_VER >= 1700 : \ - (version == 12 ? _MSC_VER >= 1800 : \ - (version == 13 ? _MSC_VER >= 1900 : \ - 0)))) -# if !MOZ_MSVC_VERSION_AT_LEAST(10) -# error "mfbt (and Gecko) require at least MSVC 2010 RTM to build." -# endif #endif diff --git a/mfbt/NullPtr.h b/mfbt/NullPtr.h index 5963613c4b3f..1d1355e13e33 100644 --- a/mfbt/NullPtr.h +++ b/mfbt/NullPtr.h @@ -25,7 +25,7 @@ # endif # endif #elif defined(_MSC_VER) - // The minimum supported MSVC (10, _MSC_VER 1600) supports nullptr. + // The minimum supported MSVC (12, _MSC_VER 1800) supports nullptr. # define MOZ_HAVE_CXX11_NULLPTR #endif diff --git a/mfbt/TypedEnumInternal.h b/mfbt/TypedEnumInternal.h index db7c1feabf3a..5af19e20202e 100644 --- a/mfbt/TypedEnumInternal.h +++ b/mfbt/TypedEnumInternal.h @@ -38,9 +38,7 @@ # endif #elif defined(_MSC_VER) # define MOZ_HAVE_CXX11_ENUM_TYPE -# if _MSC_VER >= 1700 -# define MOZ_HAVE_CXX11_STRONG_ENUMS -# endif +# define MOZ_HAVE_CXX11_STRONG_ENUMS #endif namespace mozilla { diff --git a/mfbt/tests/TestMaybe.cpp b/mfbt/tests/TestMaybe.cpp index 9e4fcb8e7003..0ee02734eca2 100644 --- a/mfbt/tests/TestMaybe.cpp +++ b/mfbt/tests/TestMaybe.cpp @@ -23,18 +23,13 @@ using mozilla::Swap; using mozilla::ToMaybe; using mozilla::UniquePtr; -// Work around a bug in Visual Studio 2010 and 2012 that prevents expressions of +#if MOZ_IS_MSVC + template struct Identity { typedef T type; }; +# define DECLTYPE(EXPR) Identity::type +#elif MOZ_IS_GCC +// Work around a bug in GCC < 4.7 that prevents expressions of // the form |decltype(foo)::type| from working. See here: // http://stackoverflow.com/questions/14330768/c11-compiler-error-when-using-decltypevar-followed-by-internal-type-of-var -// GCC < 4.7 also has a similar bug. -#if MOZ_IS_MSVC -# if MOZ_MSVC_VERSION_AT_LEAST(12) -# define DECLTYPE(EXPR) decltype(EXPR) -# else - template struct Identity { typedef T type; }; -# define DECLTYPE(EXPR) Identity::type -# endif -#elif MOZ_IS_GCC # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) # define DECLTYPE(EXPR) decltype(EXPR) # else diff --git a/mfbt/tests/TestTypedEnum.cpp b/mfbt/tests/TestTypedEnum.cpp index 68813348f1ea..f08024325aeb 100644 --- a/mfbt/tests/TestTypedEnum.cpp +++ b/mfbt/tests/TestTypedEnum.cpp @@ -34,9 +34,7 @@ # endif # endif # elif defined(_MSC_VER) -# if _MSC_VER >= 1700 -# define MOZ_HAVE_IS_LITERAL -# endif +# define MOZ_HAVE_IS_LITERAL # endif #endif diff --git a/mfbt/tests/TestUniquePtr.cpp b/mfbt/tests/TestUniquePtr.cpp index d94de4fb369a..04f5c02dcbb5 100644 --- a/mfbt/tests/TestUniquePtr.cpp +++ b/mfbt/tests/TestUniquePtr.cpp @@ -330,24 +330,6 @@ TestReferenceDeleter() return true; } -// MSVC10 miscompiles mozilla::RemoveReference, claiming -// that the partial specializations RemoveReference and RemoveReference -// both match RemoveReference below. Thus in Mozilla code using -// UniquePtr with a function reference deleter is forbidden. But it doesn't -// hurt to run these tests when the compiler doesn't have problems with this, so -// do so for anything non-MSVC. -#if MOZ_IS_MSVC - // Technically this could be MOZ_MSVC_VERSION_AT_LEAST(11), but we're not - // going to support function deleters as long as we support MSVC10, so it - // hardly matters. In the meantime it's not worth the potential trouble (and - // potential for bustage) to run these tests on MSVC>=11. -# define SHOULD_TEST_FUNCTION_REFERENCE_DELETER 0 -#else -# define SHOULD_TEST_FUNCTION_REFERENCE_DELETER 1 -#endif - -#if SHOULD_TEST_FUNCTION_REFERENCE_DELETER - typedef void (&FreeSignature)(void*); static size_t DeleteIntFunctionCallCount = 0; @@ -400,8 +382,6 @@ TestFunctionReferenceDeleter() return true; } -#endif // SHOULD_TEST_FUNCTION_REFERENCE_DELETER - template::value> struct AppendNullptrTwice; @@ -597,11 +577,9 @@ main() if (!TestReferenceDeleter()) { return 1; } -#if SHOULD_TEST_FUNCTION_REFERENCE_DELETER if (!TestFunctionReferenceDeleter()) { return 1; } -#endif if (!TestVector()) { return 1; } From cb71061e0435a940e52896b5fe8d1fd461ee2072 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 10:12:45 -0500 Subject: [PATCH 143/224] Bug 1119254 - Mark virtual overridden functions as MOZ_OVERRIDE in xpcom; r=froydnj --- xpcom/tests/TestCOMArray.cpp | 4 ++-- xpcom/tests/TestRacingServiceManager.cpp | 4 ++-- xpcom/tests/TestTimers.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/xpcom/tests/TestCOMArray.cpp b/xpcom/tests/TestCOMArray.cpp index c3be1f63f4e1..6470080e3dc5 100644 --- a/xpcom/tests/TestCOMArray.cpp +++ b/xpcom/tests/TestCOMArray.cpp @@ -35,8 +35,8 @@ public: NS_DECL_ISUPPORTS // IFoo implementation - NS_IMETHOD_(MozExternalRefCountType) RefCnt() { return mRefCnt; } - NS_IMETHOD_(int32_t) ID() { return mID; } + NS_IMETHOD_(MozExternalRefCountType) RefCnt() MOZ_OVERRIDE { return mRefCnt; } + NS_IMETHOD_(int32_t) ID() MOZ_OVERRIDE { return mID; } static int32_t gCount; diff --git a/xpcom/tests/TestRacingServiceManager.cpp b/xpcom/tests/TestRacingServiceManager.cpp index 23ba19981fbc..1307970abbee 100644 --- a/xpcom/tests/TestRacingServiceManager.cpp +++ b/xpcom/tests/TestRacingServiceManager.cpp @@ -96,9 +96,9 @@ public: NS_IMETHOD CreateInstance(nsISupports* aDelegate, const nsIID& aIID, - void** aResult); + void** aResult) MOZ_OVERRIDE; - NS_IMETHOD LockFactory(bool aLock) { + NS_IMETHOD LockFactory(bool aLock) MOZ_OVERRIDE { return NS_OK; } diff --git a/xpcom/tests/TestTimers.cpp b/xpcom/tests/TestTimers.cpp index 421c5f4b889b..e2c33e55d7da 100644 --- a/xpcom/tests/TestTimers.cpp +++ b/xpcom/tests/TestTimers.cpp @@ -78,7 +78,7 @@ public: TimerCallback(nsIThread** aThreadPtr, ReentrantMonitor* aReentrantMonitor) : mThreadPtr(aThreadPtr), mReentrantMonitor(aReentrantMonitor) { } - NS_IMETHOD Notify(nsITimer* aTimer) { + NS_IMETHOD Notify(nsITimer* aTimer) MOZ_OVERRIDE { NS_ASSERTION(mThreadPtr, "Callback was not supposed to be called!"); nsCOMPtr current(do_GetCurrentThread()); From 86bcdd02b3915917129d8db812cbe0adcf38c9c9 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 8 Jan 2015 10:15:45 -0500 Subject: [PATCH 144/224] Bug 1119263 - Mark virtual overridden functions as MOZ_OVERRIDE in spellchecker; r=smaug --- .../spellcheck/hunspell/src/mozHunspell.h | 2 +- .../spellcheck/src/mozInlineSpellChecker.cpp | 4 ++-- extensions/spellcheck/src/mozSpellChecker.h | 24 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.h b/extensions/spellcheck/hunspell/src/mozHunspell.h index 845537a0c931..c39a6404aa2d 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.h +++ b/extensions/spellcheck/hunspell/src/mozHunspell.h @@ -102,7 +102,7 @@ public: nsresult ConvertCharset(const char16_t* aStr, char ** aDst); NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, - nsISupports* aData, bool aAnonymize) + nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE { return MOZ_COLLECT_REPORT( "explicit/spell-check", KIND_HEAP, UNITS_BYTES, HunspellAllocator::MemoryAllocated(), diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 6cb9af6c368d..99f6a317de3f 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -500,7 +500,7 @@ public: explicit InitEditorSpellCheckCallback(mozInlineSpellChecker* aSpellChecker) : mSpellChecker(aSpellChecker) {} - NS_IMETHOD EditorSpellCheckDone() + NS_IMETHOD EditorSpellCheckDone() MOZ_OVERRIDE { return mSpellChecker ? mSpellChecker->EditorSpellCheckInited() : NS_OK; } @@ -1950,7 +1950,7 @@ public: uint32_t aDisabledAsyncToken) : mSpellChecker(aSpellChecker), mDisabledAsyncToken(aDisabledAsyncToken) {} - NS_IMETHOD EditorSpellCheckDone() + NS_IMETHOD EditorSpellCheckDone() MOZ_OVERRIDE { // Ignore this callback if SetEnableRealTimeSpell(false) was called after // the UpdateCurrentDictionary call that triggered it. diff --git a/extensions/spellcheck/src/mozSpellChecker.h b/extensions/spellcheck/src/mozSpellChecker.h index 94db59899333..cc4e35de1bd4 100644 --- a/extensions/spellcheck/src/mozSpellChecker.h +++ b/extensions/spellcheck/src/mozSpellChecker.h @@ -35,20 +35,20 @@ public: nsresult Init(); // nsISpellChecker - NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, bool aFromStartofDoc); - NS_IMETHOD NextMisspelledWord(nsAString &aWord, nsTArray *aSuggestions); - NS_IMETHOD CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray *aSuggestions); - NS_IMETHOD Replace(const nsAString &aOldWord, const nsAString &aNewWord, bool aAllOccurrences); - NS_IMETHOD IgnoreAll(const nsAString &aWord); + NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, bool aFromStartofDoc) MOZ_OVERRIDE; + NS_IMETHOD NextMisspelledWord(nsAString &aWord, nsTArray *aSuggestions) MOZ_OVERRIDE; + NS_IMETHOD CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray *aSuggestions) MOZ_OVERRIDE; + NS_IMETHOD Replace(const nsAString &aOldWord, const nsAString &aNewWord, bool aAllOccurrences) MOZ_OVERRIDE; + NS_IMETHOD IgnoreAll(const nsAString &aWord) MOZ_OVERRIDE; - NS_IMETHOD AddWordToPersonalDictionary(const nsAString &aWord); - NS_IMETHOD RemoveWordFromPersonalDictionary(const nsAString &aWord); - NS_IMETHOD GetPersonalDictionary(nsTArray *aWordList); + NS_IMETHOD AddWordToPersonalDictionary(const nsAString &aWord) MOZ_OVERRIDE; + NS_IMETHOD RemoveWordFromPersonalDictionary(const nsAString &aWord) MOZ_OVERRIDE; + NS_IMETHOD GetPersonalDictionary(nsTArray *aWordList) MOZ_OVERRIDE; - NS_IMETHOD GetDictionaryList(nsTArray *aDictionaryList); - NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary); - NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary); - NS_IMETHOD CheckCurrentDictionary(); + NS_IMETHOD GetDictionaryList(nsTArray *aDictionaryList) MOZ_OVERRIDE; + NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary) MOZ_OVERRIDE; + NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) MOZ_OVERRIDE; + NS_IMETHOD CheckCurrentDictionary() MOZ_OVERRIDE; void DeleteRemoteEngine() { mEngine = nullptr; From 2f999e45d9504524b42d7b99ceef17b676f3f19d Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 8 Jan 2015 11:21:52 -0500 Subject: [PATCH 145/224] Bug 1118443 Make workers specify the XHR load group to use during the request. r=sicking --- dom/base/nsIXMLHttpRequest.idl | 9 +++++++-- dom/base/nsXMLHttpRequest.cpp | 12 +++++++++--- dom/base/nsXMLHttpRequest.h | 5 ++++- dom/base/test/TestGetURL.cpp | 2 +- dom/base/test/TestNativeXMLHttpRequest.cpp | 2 +- dom/workers/XMLHttpRequest.cpp | 3 ++- dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp | 2 +- js/xpconnect/src/Sandbox.cpp | 2 +- 8 files changed, 26 insertions(+), 11 deletions(-) diff --git a/dom/base/nsIXMLHttpRequest.idl b/dom/base/nsIXMLHttpRequest.idl index 59ec41d11f2b..ba2a8c406f33 100644 --- a/dom/base/nsIXMLHttpRequest.idl +++ b/dom/base/nsIXMLHttpRequest.idl @@ -8,6 +8,7 @@ interface nsIChannel; interface nsIDOMDocument; interface nsIDOMEventListener; +interface nsILoadGroup; interface nsIPrincipal; interface nsIScriptContext; interface nsIURI; @@ -67,7 +68,7 @@ interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget { * you're aware of all the security implications. And then think twice about * it. */ -[scriptable, uuid(2e91e088-e9fa-4ba4-9887-2a0b7cf27a3e)] +[scriptable, uuid(704e91dc-a3f6-4e4d-9f5f-4bb85159aeb7)] interface nsIXMLHttpRequest : nsISupports { /** @@ -295,11 +296,15 @@ interface nsIXMLHttpRequest : nsISupports * document. * @param baseURI The base URI to use when resolving relative URIs. May be * null. + * @param loadGroup An optional load group to use when performing the request. + * This will be used even if the global has a window with a + * load group. */ [noscript] void init(in nsIPrincipal principal, in nsIScriptContext scriptContext, in nsIGlobalObject globalObject, - in nsIURI baseURI); + in nsIURI baseURI, + [optional] in nsILoadGroup loadGroup); /** * Upload process can be tracked by adding event listener to |upload|. diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index 82c688864f35..766ff232bd6f 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -361,10 +361,11 @@ NS_IMETHODIMP nsXMLHttpRequest::Init(nsIPrincipal* aPrincipal, nsIScriptContext* aScriptContext, nsIGlobalObject* aGlobalObject, - nsIURI* aBaseURI) + nsIURI* aBaseURI, + nsILoadGroup* aLoadGroup) { NS_ENSURE_ARG_POINTER(aPrincipal); - + if (nsCOMPtr win = do_QueryInterface(aGlobalObject)) { if (win->IsOuterWindow()) { // Must be bound to inner window, innerize if necessary. @@ -374,7 +375,7 @@ nsXMLHttpRequest::Init(nsIPrincipal* aPrincipal, } } - Construct(aPrincipal, aGlobalObject, aBaseURI); + Construct(aPrincipal, aGlobalObject, aBaseURI, aLoadGroup); return NS_OK; } @@ -1436,6 +1437,11 @@ nsXMLHttpRequest::GetLoadGroup() const return nullptr; } + if (mLoadGroup) { + nsCOMPtr ref = mLoadGroup; + return ref.forget(); + } + nsresult rv = NS_ERROR_FAILURE; nsIScriptContext* sc = const_cast(this)->GetContextForEventHandlers(&rv); diff --git a/dom/base/nsXMLHttpRequest.h b/dom/base/nsXMLHttpRequest.h index 37edb86365aa..756faf948929 100644 --- a/dom/base/nsXMLHttpRequest.h +++ b/dom/base/nsXMLHttpRequest.h @@ -244,7 +244,8 @@ public: void Construct(nsIPrincipal* aPrincipal, nsIGlobalObject* aGlobalObject, - nsIURI* aBaseURI = nullptr) + nsIURI* aBaseURI = nullptr, + nsILoadGroup* aLoadGroup = nullptr) { MOZ_ASSERT(aPrincipal); MOZ_ASSERT_IF(nsCOMPtr win = do_QueryInterface( @@ -252,6 +253,7 @@ public: mPrincipal = aPrincipal; BindToOwner(aGlobalObject); mBaseURI = aBaseURI; + mLoadGroup = aLoadGroup; } void InitParameters(bool aAnon, bool aSystem); @@ -717,6 +719,7 @@ protected: nsIRequestObserver* mRequestObserver; nsCOMPtr mBaseURI; + nsCOMPtr mLoadGroup; uint32_t mState; diff --git a/dom/base/test/TestGetURL.cpp b/dom/base/test/TestGetURL.cpp index db48266113ac..a8222bc49aba 100644 --- a/dom/base/test/TestGetURL.cpp +++ b/dom/base/test/TestGetURL.cpp @@ -42,7 +42,7 @@ nsresult TestGetURL(const nsCString& aURL) rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); TEST_ENSURE_SUCCESS(rv, "Couldn't get system principal!"); - rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr); + rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr, nullptr); TEST_ENSURE_SUCCESS(rv, "Couldn't initialize the XHR!"); rv = xhr->Open(getString, aURL, false, empty, empty); diff --git a/dom/base/test/TestNativeXMLHttpRequest.cpp b/dom/base/test/TestNativeXMLHttpRequest.cpp index afa176d977ca..ef7f197db545 100644 --- a/dom/base/test/TestNativeXMLHttpRequest.cpp +++ b/dom/base/test/TestNativeXMLHttpRequest.cpp @@ -52,7 +52,7 @@ nsresult TestNativeXMLHttpRequest() rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); TEST_ENSURE_SUCCESS(rv, "Couldn't get system principal!"); - rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr); + rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr, nullptr); TEST_ENSURE_SUCCESS(rv, "Couldn't initialize the XHR!"); rv = xhr->Open(getString, testURL, false, empty, empty); diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index e213aa3425a1..dab622a8abef 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -919,7 +919,8 @@ Proxy::Init() nsCOMPtr global = do_QueryInterface(ownerWindow); if (NS_FAILED(mXHR->Init(mWorkerPrivate->GetPrincipal(), mWorkerPrivate->GetScriptContext(), - global, mWorkerPrivate->GetBaseURI()))) { + global, mWorkerPrivate->GetBaseURI(), + mWorkerPrivate->GetLoadGroup()))) { mXHR = nullptr; return false; } diff --git a/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp b/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp index ef5c2d4c9f89..041e05537075 100644 --- a/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp +++ b/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp @@ -173,7 +173,7 @@ nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources, rv = req->Init(docPrincipal, context, scriptObject ? scriptObject : doc->GetScopeObject(), - nullptr); + nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); rv = req->Open(NS_LITERAL_CSTRING("GET"), uriStr, true, diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 793377416cb5..963f84f19654 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -206,7 +206,7 @@ SandboxCreateXMLHttpRequest(JSContext *cx, unsigned argc, jsval *vp) nsCOMPtr xhr = new nsXMLHttpRequest(); nsresult rv = xhr->Init(nsContentUtils::SubjectPrincipal(), nullptr, - iglobal, nullptr); + iglobal, nullptr, nullptr); if (NS_FAILED(rv)) return false; From ed5fb37df8ccbe6b3a1758531d7f84e0c497c69c Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 8 Jan 2015 11:24:15 -0500 Subject: [PATCH 146/224] Bug 1110229 - Always paint the full low-res tile for performance and correctness. r=nical --- gfx/layers/client/TiledContentClient.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index f10ff377a66f..3966ec0039ca 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1489,6 +1489,11 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval while (true) { aRegionToPaint.And(aInvalidRegion, tileBounds); if (!aRegionToPaint.IsEmpty()) { + if (mResolution != CSSToParentLayerScale(1)) { + // Paint the entire tile for low-res. This is aimed to fixing low-res resampling + // and to avoid doing costly region accurate painting for a small area. + aRegionToPaint = tileBounds; + } break; } if (Abs(scrollDiffY) >= Abs(scrollDiffX)) { From 266f840884d698e78e9496ebddd070ba4d223c8e Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 8 Jan 2015 11:29:20 -0500 Subject: [PATCH 147/224] Bug 1109873 - Follow-up to fix debug logging bustage. r=me and DONTBUILD --- gfx/layers/apz/src/APZCTreeManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 23824e5000ab..392d8e75f4d9 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1374,9 +1374,9 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode, // If we didn't match anything in the subtree, check |node|. if (!result) { - APZCTM_LOG("Testing ParentLayer point %f %f (Layer %f %f) against node %p\n", - aHitTestPoint.x, aHitTestPoint.y, - hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, + APZCTM_LOG("Testing ParentLayer point %s (Layer %s) against node %p\n", + Stringify(aHitTestPoint).c_str(), + hitTestPointForChildLayers ? Stringify(hitTestPointForChildLayers.ref()).c_str() : "nil", node); HitTestResult hitResult = node->HitTest(aHitTestPoint); if (hitResult != HitTestResult::NoApzcHit) { From c8aa1b5d139eed1d2c78092911ad1816f7b10eda Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 8 Jan 2015 11:53:03 -0500 Subject: [PATCH 148/224] Bug 1110229 - bustage fix on a CLOSED TREE --- gfx/layers/client/TiledContentClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 3966ec0039ca..e16c06ecd19d 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1489,7 +1489,7 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval while (true) { aRegionToPaint.And(aInvalidRegion, tileBounds); if (!aRegionToPaint.IsEmpty()) { - if (mResolution != CSSToParentLayerScale(1)) { + if (mResolution != 1) { // Paint the entire tile for low-res. This is aimed to fixing low-res resampling // and to avoid doing costly region accurate painting for a small area. aRegionToPaint = tileBounds; From ae8c53e49b8fbe913651ab463093848666782ac1 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Jan 2015 11:57:09 -0500 Subject: [PATCH 149/224] Bug 1103000. Update the unitless length quick whitelist to match spec changes. r=dbaron --- layout/style/nsCSSPropList.h | 8 +++++++ layout/style/test/property_database.js | 32 +++++++++++++++++++------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index ac0915d7bf7e..0ebda8d5e57b 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -567,6 +567,7 @@ CSS_PROP_BACKGROUND( CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | CSS_PROPERTY_VALUE_LIST_USES_COMMAS | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_STORES_CALC, "", 0, @@ -1135,6 +1136,7 @@ CSS_PROP_TABLEBORDER( border_spacing, BorderSpacing, CSS_PROPERTY_PARSE_FUNCTION | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_VALUE_NONNEGATIVE, "", 0, @@ -2465,6 +2467,7 @@ CSS_PROP_POSITION( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_HLPO | VARIANT_CALC, @@ -2478,6 +2481,7 @@ CSS_PROP_POSITION( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_HKLPO | VARIANT_CALC, @@ -2491,6 +2495,7 @@ CSS_PROP_POSITION( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_AHLP | VARIANT_CALC, @@ -2504,6 +2509,7 @@ CSS_PROP_POSITION( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_AHKLP | VARIANT_CALC, @@ -3099,6 +3105,7 @@ CSS_PROP_TEXT( TextIndent, CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_HLP | VARIANT_CALC, @@ -3369,6 +3376,7 @@ CSS_PROP_TEXTRESET( CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE | CSS_PROPERTY_APPLIES_TO_PLACEHOLDER | CSS_PROPERTY_STORES_CALC | + CSS_PROPERTY_UNITLESS_LENGTH_QUIRK | CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, "", VARIANT_HKLP | VARIANT_CALC, diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 1f2d0102180b..ee957dd5fac5 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -2004,7 +2004,12 @@ var gCSSProperties = { "top 20%", "bottom 20%", "50% left", "top 50%", "50% bottom 10%", "right 10% 50%", "left right", "top bottom", "left 10% right", - "top 20px bottom 20px", "left left", "20 20" ] + "top 20px bottom 20px", "left left" ], + quirks_values: { + "20 20": "20px 20px", + "10 5px": "10px 5px", + "7px 2": "7px 2px", + }, }, "background-repeat": { domProp: "backgroundRepeat", @@ -2221,7 +2226,12 @@ var gCSSProperties = { type: CSS_TYPE_LONGHAND, initial_values: [ "0", "0 0", "0px", "0 0px", "calc(0px)", "calc(0px) calc(0em)", "calc(2em - 2em) calc(3px + 7px - 10px)", "calc(-5px)", "calc(-5px) calc(-5px)" ], other_values: [ "3px", "4em 2px", "4em 0", "0px 2px", "calc(7px)", "0 calc(7px)", "calc(7px) 0", "calc(0px) calc(7px)", "calc(7px) calc(0px)", "7px calc(0px)", "calc(0px) 7px", "7px calc(0px)", "3px calc(2em)" ], - invalid_values: [ "0%", "0 0%", "-5px", "-5px -5px", "0 -5px", "-5px 0" ] + invalid_values: [ "0%", "0 0%", "-5px", "-5px -5px", "0 -5px", "-5px 0" ], + quirks_values: { + "2px 5": "2px 5px", + "7": "7px", + "3 4px": "3px 4px", + }, }, "border-style": { domProp: "borderStyle", @@ -2930,7 +2940,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: [ "auto", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available", "5" ] + invalid_values: [ "auto", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ], + quirks_values: { "5": "5px" }, }, "max-width": { domProp: "maxWidth", @@ -2947,7 +2958,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: [ "auto", "5" ] + invalid_values: [ "auto" ], + quirks_values: { "5": "5px" }, }, "min-height": { domProp: "minHeight", @@ -2962,7 +2974,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: ["none", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available", "5" ] + invalid_values: ["none", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available" ], + quirks_values: { "5": "5px" }, }, "min-width": { domProp: "minWidth", @@ -2977,7 +2990,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: [ "none", "5" ] + invalid_values: [ "none" ], + quirks_values: { "5": "5px" }, }, "opacity": { @@ -3356,7 +3370,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: [ "5" ] + invalid_values: [ ], + quirks_values: { "5": "5px" }, }, "text-overflow": { domProp: "textOverflow", @@ -3478,7 +3493,8 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 50%)", ], - invalid_values: [ "5" ] + invalid_values: [ ], + quirks_values: { "5": "5px" }, }, "visibility": { domProp: "visibility", From a4c77d8da7bc474046d5ac7da7f3559cf6d45345 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Jan 2015 11:57:10 -0500 Subject: [PATCH 150/224] Bug 1112761 part 1. Replace Pref="media.mediasource.enabled" annotations in IDL with calls to a function which will end up doing something a bit more interesting. r=kinetik --- dom/media/mediasource/MediaSource.cpp | 6 ++++++ dom/media/mediasource/MediaSource.h | 2 ++ dom/webidl/HTMLVideoElement.webidl | 2 +- dom/webidl/MediaSource.webidl | 2 +- dom/webidl/SourceBuffer.webidl | 2 +- dom/webidl/SourceBufferList.webidl | 2 +- dom/webidl/VideoPlaybackQuality.webidl | 2 +- 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp index 5e6c08d37ed8..7fcf6523e2b4 100644 --- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -306,6 +306,12 @@ MediaSource::IsTypeSupported(const GlobalObject&, const nsAString& aType) return NS_SUCCEEDED(rv); } +/* static */ bool +MediaSource::Enabled(JSContext* cx, JSObject* aGlobal) +{ + return Preferences::GetBool("media.mediasource.enabled"); +} + bool MediaSource::Attach(MediaSourceDecoder* aDecoder) { diff --git a/dom/media/mediasource/MediaSource.h b/dom/media/mediasource/MediaSource.h index f2f1d6d70c4b..d30672b0bddf 100644 --- a/dom/media/mediasource/MediaSource.h +++ b/dom/media/mediasource/MediaSource.h @@ -60,6 +60,8 @@ public: void EndOfStream(const Optional& aError, ErrorResult& aRv); static bool IsTypeSupported(const GlobalObject&, const nsAString& aType); + + static bool Enabled(JSContext* cx, JSObject* aGlobal); /** End WebIDL Methods. */ NS_DECL_ISUPPORTS_INHERITED diff --git a/dom/webidl/HTMLVideoElement.webidl b/dom/webidl/HTMLVideoElement.webidl index 95a1f1885a8a..cfa2c783f6a4 100644 --- a/dom/webidl/HTMLVideoElement.webidl +++ b/dom/webidl/HTMLVideoElement.webidl @@ -48,6 +48,6 @@ partial interface HTMLVideoElement { // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#idl-def-HTMLVideoElement partial interface HTMLVideoElement { - [Pref="media.mediasource.enabled", NewObject] + [Func="mozilla::dom::MediaSource::Enabled", NewObject] VideoPlaybackQuality getVideoPlaybackQuality(); }; diff --git a/dom/webidl/MediaSource.webidl b/dom/webidl/MediaSource.webidl index 3714c80bbfa7..ca822f7886ce 100644 --- a/dom/webidl/MediaSource.webidl +++ b/dom/webidl/MediaSource.webidl @@ -21,7 +21,7 @@ enum MediaSourceEndOfStreamError { "decode" }; -[Constructor, Pref="media.mediasource.enabled"] +[Constructor, Func="mozilla::dom::MediaSource::Enabled"] interface MediaSource : EventTarget { readonly attribute SourceBufferList sourceBuffers; readonly attribute SourceBufferList activeSourceBuffers; diff --git a/dom/webidl/SourceBuffer.webidl b/dom/webidl/SourceBuffer.webidl index fbe0c9e6248c..3e3e6602c5d2 100644 --- a/dom/webidl/SourceBuffer.webidl +++ b/dom/webidl/SourceBuffer.webidl @@ -15,7 +15,7 @@ enum SourceBufferAppendMode { "sequence" }; -[Pref="media.mediasource.enabled"] +[Func="mozilla::dom::MediaSource::Enabled"] interface SourceBuffer : EventTarget { [SetterThrows] attribute SourceBufferAppendMode mode; diff --git a/dom/webidl/SourceBufferList.webidl b/dom/webidl/SourceBufferList.webidl index 98558a5011ed..badbfd8252be 100644 --- a/dom/webidl/SourceBufferList.webidl +++ b/dom/webidl/SourceBufferList.webidl @@ -10,7 +10,7 @@ * liability, trademark and document use rules apply. */ -[Pref="media.mediasource.enabled"] +[Func="mozilla::dom::MediaSource::Enabled"] interface SourceBufferList : EventTarget { readonly attribute unsigned long length; getter SourceBuffer (unsigned long index); diff --git a/dom/webidl/VideoPlaybackQuality.webidl b/dom/webidl/VideoPlaybackQuality.webidl index a65024ae38ed..abbe8d19a680 100644 --- a/dom/webidl/VideoPlaybackQuality.webidl +++ b/dom/webidl/VideoPlaybackQuality.webidl @@ -10,7 +10,7 @@ * liability, trademark and document use rules apply. */ -[Pref="media.mediasource.enabled"] +[Func="mozilla::dom::MediaSource::Enabled"] interface VideoPlaybackQuality { readonly attribute DOMHighResTimeStamp creationTime; readonly attribute unsigned long totalVideoFrames; From ef4aa6e1808b68f0867bd3ed9615328b3086822f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Jan 2015 11:57:11 -0500 Subject: [PATCH 151/224] Bug 1112761 part 2. Enable MediaSource based on a whitelist, not in general. r=kinetik --- dom/media/mediasource/MediaSource.cpp | 43 ++++++++++++++++++- .../mediasource/test/crashtests/1005366.html | 1 + .../mediasource/test/crashtests/1059035.html | 1 + .../test/crashtests/crashtests.list | 8 ++-- dom/media/mediasource/test/mediasource.js | 5 ++- .../test/test_MediaSource_disabled.html | 7 ++- dom/media/test/test_VideoPlaybackQuality.html | 7 ++- .../test_VideoPlaybackQuality_disabled.html | 7 ++- dom/media/test/test_eme_canvas_blocked.html | 1 + dom/media/test/test_eme_playback.html | 1 + .../test/test_eme_requestKeySystemAccess.html | 1 + .../test/test_eme_stream_capture_blocked.html | 1 + modules/libpref/init/all.js | 17 ++++++-- testing/profiles/prefs_general.js | 1 + 14 files changed, 88 insertions(+), 13 deletions(-) diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp index 7fcf6523e2b4..3edf4a77cfa4 100644 --- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -19,10 +19,14 @@ #include "mozilla/dom/TimeRanges.h" #include "mozilla/mozalloc.h" #include "nsContentTypeParser.h" +#include "nsContentUtils.h" #include "nsDebug.h" #include "nsError.h" +#include "nsIEffectiveTLDService.h" #include "nsIRunnable.h" #include "nsIScriptObjectPrincipal.h" +#include "nsIURI.h" +#include "nsNetCID.h" #include "nsPIDOMWindow.h" #include "nsString.h" #include "nsThreadUtils.h" @@ -309,7 +313,44 @@ MediaSource::IsTypeSupported(const GlobalObject&, const nsAString& aType) /* static */ bool MediaSource::Enabled(JSContext* cx, JSObject* aGlobal) { - return Preferences::GetBool("media.mediasource.enabled"); + MOZ_ASSERT(NS_IsMainThread()); + + // Don't use aGlobal across Preferences stuff, which the static + // analysis thinks can GC. + JS::Rooted global(cx, aGlobal); + + bool enabled = Preferences::GetBool("media.mediasource.enabled"); + if (!enabled) { + return false; + } + + // Check whether it's enabled everywhere or just YouTube. + bool restrict = Preferences::GetBool("media.mediasource.youtubeonly", false); + if (!restrict) { + return true; + } + + // We want to restrict to YouTube only. We define that as the + // origin being https://*.youtube.com. + nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(global); + nsCOMPtr uri; + if (NS_FAILED(principal->GetURI(getter_AddRefs(uri))) || !uri) { + return false; + } + + bool isHttps = false; + if (NS_FAILED(uri->SchemeIs("https", &isHttps)) || !isHttps) { + return false; + } + + nsCOMPtr tldServ = + do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); + NS_ENSURE_TRUE(tldServ, false); + + nsAutoCString eTLDplusOne; + return + NS_SUCCEEDED(tldServ->GetBaseDomain(uri, 0, eTLDplusOne)) && + eTLDplusOne.EqualsLiteral("youtube.com"); } bool diff --git a/dom/media/mediasource/test/crashtests/1005366.html b/dom/media/mediasource/test/crashtests/1005366.html index aa8b7f652e0a..a148ee4c2b13 100644 --- a/dom/media/mediasource/test/crashtests/1005366.html +++ b/dom/media/mediasource/test/crashtests/1005366.html @@ -6,6 +6,7 @@ /* user_pref("media.mediasource.enabled", true); +user_pref("media.mediasource.youtubeonly", false); */ function boom() diff --git a/dom/media/mediasource/test/crashtests/1059035.html b/dom/media/mediasource/test/crashtests/1059035.html index 9dfda34b8225..2b28e624271f 100644 --- a/dom/media/mediasource/test/crashtests/1059035.html +++ b/dom/media/mediasource/test/crashtests/1059035.html @@ -5,6 +5,7 @@ /* user_pref("media.mediasource.enabled", true); +user_pref("media.mediasource.youtubeonly", false); */ function boom() diff --git a/dom/media/mediasource/test/crashtests/crashtests.list b/dom/media/mediasource/test/crashtests/crashtests.list index e16ec261d25d..6509e3d66ec1 100644 --- a/dom/media/mediasource/test/crashtests/crashtests.list +++ b/dom/media/mediasource/test/crashtests/crashtests.list @@ -1,4 +1,4 @@ -test-pref(media.mediasource.enabled,true) load 926665.html -test-pref(media.mediasource.enabled,true) load 931388.html -test-pref(media.mediasource.enabled,true) load 1005366.html -test-pref(media.mediasource.enabled,true) load 1059035.html +test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 926665.html +test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 931388.html +test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1005366.html +test-pref(media.mediasource.enabled,true) test-pref(media.mediasource.youtubeonly,false) load 1059035.html diff --git a/dom/media/mediasource/test/mediasource.js b/dom/media/mediasource/test/mediasource.js index 921adbef9d0a..0efb3000e056 100644 --- a/dom/media/mediasource/test/mediasource.js +++ b/dom/media/mediasource/test/mediasource.js @@ -17,7 +17,10 @@ function runWithMSE(testFunction) { } addLoadEvent(function () { - SpecialPowers.pushPrefEnv({"set": [[ "media.mediasource.enabled", true ]]}, + SpecialPowers.pushPrefEnv({"set": [ + [ "media.mediasource.enabled", true ], + [ "media.mediasource.youtubeonly", false ], + ]}, bootstrapTest); }); } diff --git a/dom/media/mediasource/test/test_MediaSource_disabled.html b/dom/media/mediasource/test/test_MediaSource_disabled.html index e4d8d40a3f7d..49c79a24904b 100644 --- a/dom/media/mediasource/test/test_MediaSource_disabled.html +++ b/dom/media/mediasource/test/test_MediaSource_disabled.html @@ -19,7 +19,12 @@ function test() { SimpleTest.finish(); } -SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", false]]}, +SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", false], + ["media.mediasource.youtubeonly", false], + ] + }, test); diff --git a/dom/media/test/test_VideoPlaybackQuality.html b/dom/media/test/test_VideoPlaybackQuality.html index ce08f144afa5..23c395fb88a9 100644 --- a/dom/media/test/test_VideoPlaybackQuality.html +++ b/dom/media/test/test_VideoPlaybackQuality.html @@ -51,7 +51,12 @@ function test() { } addLoadEvent(function() { - SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", true]]}, test); + SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", true], + ["media.mediasource.youtubeonly", false], + ] + }, test); }); diff --git a/dom/media/test/test_VideoPlaybackQuality_disabled.html b/dom/media/test/test_VideoPlaybackQuality_disabled.html index 36f8a5c6e5de..9f2e5e5d4357 100644 --- a/dom/media/test/test_VideoPlaybackQuality_disabled.html +++ b/dom/media/test/test_VideoPlaybackQuality_disabled.html @@ -25,7 +25,12 @@ function test() { } addLoadEvent(function() { - SpecialPowers.pushPrefEnv({"set": [["media.mediasource.enabled", false]]}, test); + SpecialPowers.pushPrefEnv({"set": + [ + ["media.mediasource.enabled", false], + ["media.mediasource.youtubeonly", false], + ] + }, test); }); diff --git a/dom/media/test/test_eme_canvas_blocked.html b/dom/media/test/test_eme_canvas_blocked.html index 66e9a9e53f9d..5f868fd6b6de 100644 --- a/dom/media/test/test_eme_canvas_blocked.html +++ b/dom/media/test/test_eme_canvas_blocked.html @@ -49,6 +49,7 @@ function beginTest() { var prefs = [ [ "media.mediasource.enabled", true ], + [ "media.mediasource.youtubeonly", false ], [ "media.mediasource.mp4.enabled", true ], ]; diff --git a/dom/media/test/test_eme_playback.html b/dom/media/test/test_eme_playback.html index 39ae811131b6..3fc17d4143c4 100644 --- a/dom/media/test/test_eme_playback.html +++ b/dom/media/test/test_eme_playback.html @@ -92,6 +92,7 @@ function beginTest() { var prefs = [ [ "media.mediasource.enabled", true ], + [ "media.mediasource.youtubeonly", false ], [ "media.mediasource.mp4.enabled", true ], ]; diff --git a/dom/media/test/test_eme_requestKeySystemAccess.html b/dom/media/test/test_eme_requestKeySystemAccess.html index 48b3fabd7db8..d91aa2033cfb 100644 --- a/dom/media/test/test_eme_requestKeySystemAccess.html +++ b/dom/media/test/test_eme_requestKeySystemAccess.html @@ -274,6 +274,7 @@ function beginTest() { var prefs = [ [ "media.mediasource.enabled", true ], + [ "media.mediasource.youtubeonly", false ], [ "media.mediasource.mp4.enabled", true ], ]; diff --git a/dom/media/test/test_eme_stream_capture_blocked.html b/dom/media/test/test_eme_stream_capture_blocked.html index 58682343ce44..40b2a4d8be24 100644 --- a/dom/media/test/test_eme_stream_capture_blocked.html +++ b/dom/media/test/test_eme_stream_capture_blocked.html @@ -81,6 +81,7 @@ function beginTest() { var prefs = [ [ "media.mediasource.enabled", true ], + [ "media.mediasource.youtubeonly", false ], [ "media.mediasource.mp4.enabled", true ], ]; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index caa973c2dea1..a12ae6c99046 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -428,13 +428,22 @@ pref("media.webvtt.regions.enabled", false); // AudioTrack and VideoTrack support pref("media.track.enabled", false); -// Whether to enable MediaSource support -#ifdef RELEASE_BUILD -pref("media.mediasource.enabled", false); -#else +// Whether to enable MediaSource support. We want to enable on non-release +// builds and on release windows, but on release builds restrict to YouTube. We +// don't enable for YouTube on non-Windows for now because the MP4 code for +// those platforms isn't ready yet. +#if defined(XP_WIN) || !defined(RELEASE_BUILD) pref("media.mediasource.enabled", true); +#else +pref("media.mediasource.enabled", false); #endif +#ifdef RELEASE_BUILD +pref("media.mediasource.youtubeonly", true); +#else +pref("media.mediasource.youtubeonly", false); +#endif // RELEASE_BUILD + #ifdef MOZ_WIDGET_GONK pref("media.mediasource.mp4.enabled", false); pref("media.mediasource.webm.enabled", false); diff --git a/testing/profiles/prefs_general.js b/testing/profiles/prefs_general.js index e693103a4b92..e18fe96c053d 100644 --- a/testing/profiles/prefs_general.js +++ b/testing/profiles/prefs_general.js @@ -157,6 +157,7 @@ user_pref("layout.spammy_warnings.enabled", false); // Enable Media Source Extensions for testing user_pref("media.mediasource.enabled", true); +user_pref("media.mediasource.youtubeonly", false); user_pref("media.mediasource.mp4.enabled", true); user_pref("media.mediasource.webm.enabled", true); From bad2ee9b82c4eed0c9e17387c2544b143c9ea7fd Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Jan 2015 11:57:19 -0500 Subject: [PATCH 152/224] Bug 1117167. Make the generated implementation classes for JS-implemented bindings store an nsIGlobalObject, not an nsPIDOMWindow, so we can use them in sandboxes. r=peterv --- dom/bindings/BindingUtils.cpp | 31 ++++++++++--------- dom/bindings/BindingUtils.h | 10 +++--- dom/bindings/Codegen.py | 23 ++++++-------- dom/bindings/test/TestCImplementedInterface.h | 4 +-- dom/datastore/DataStoreService.cpp | 5 ++- 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 69b0e6686b4f..74bd8ee68917 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -2068,8 +2068,8 @@ ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj) } bool -GetWindowForJSImplementedObject(JSContext* cx, JS::Handle obj, - nsPIDOMWindow** window) +GetContentGlobalForJSImplementedObject(JSContext* cx, JS::Handle obj, + nsIGlobalObject** globalObj) { // Be very careful to not get tricked here. MOZ_ASSERT(NS_IsMainThread()); @@ -2095,37 +2095,36 @@ GetWindowForJSImplementedObject(JSContext* cx, JS::Handle obj, return false; } - // It's OK if we have null here: that just means the content-side - // object really wasn't associated with any window. - nsCOMPtr win(do_QueryInterface(global.GetAsSupports())); - win.forget(window); + DebugOnly rv = CallQueryInterface(global.GetAsSupports(), globalObj); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + MOZ_ASSERT(*globalObj); return true; } -already_AddRefed +already_AddRefed ConstructJSImplementation(JSContext* aCx, const char* aContractId, const GlobalObject& aGlobal, JS::MutableHandle aObject, ErrorResult& aRv) { - // Get the window to use as a parent and for initialization. - nsCOMPtr window = do_QueryInterface(aGlobal.GetAsSupports()); - if (!window) { + // Get the global object to use as a parent and for initialization. + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + if (!global) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } - ConstructJSImplementation(aCx, aContractId, window, aObject, aRv); + ConstructJSImplementation(aCx, aContractId, global, aObject, aRv); if (aRv.Failed()) { return nullptr; } - return window.forget(); + return global.forget(); } void ConstructJSImplementation(JSContext* aCx, const char* aContractId, - nsPIDOMWindow* aWindow, + nsIGlobalObject* aGlobal, JS::MutableHandle aObject, ErrorResult& aRv) { @@ -2145,12 +2144,14 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId, aRv.Throw(rv); return; } - // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer. + // Initialize the object, if it implements nsIDOMGlobalPropertyInitializer + // and our global is a window. nsCOMPtr gpi = do_QueryInterface(implISupports); + nsCOMPtr window = do_QueryInterface(aGlobal); if (gpi) { JS::Rooted initReturn(aCx); - rv = gpi->Init(aWindow, &initReturn); + rv = gpi->Init(window, &initReturn); if (NS_FAILED(rv)) { aRv.Throw(rv); return; diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index f886b76eaf5d..1f359a20ffa7 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -2651,19 +2651,19 @@ GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId) } // Given a JSObject* that represents the chrome side of a JS-implemented WebIDL -// interface, get the nsPIDOMWindow corresponding to the content side, if any. +// interface, get the nsIGlobalObject corresponding to the content side, if any. // A false return means an exception was thrown. bool -GetWindowForJSImplementedObject(JSContext* cx, JS::Handle obj, - nsPIDOMWindow** window); +GetContentGlobalForJSImplementedObject(JSContext* cx, JS::Handle obj, + nsIGlobalObject** global); void ConstructJSImplementation(JSContext* aCx, const char* aContractId, - nsPIDOMWindow* aWindow, + nsIGlobalObject* aGlobal, JS::MutableHandle aObject, ErrorResult& aRv); -already_AddRefed +already_AddRefed ConstructJSImplementation(JSContext* aCx, const char* aContractId, const GlobalObject& aGlobal, JS::MutableHandle aObject, diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index d5d677f52a15..066ad0b2002b 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3710,12 +3710,12 @@ class CastableObjectUnwrapper(): // XXXbz Wish we could check for a JS-implemented object // that already has a content reflection... if (!IsDOMObject(js::UncheckedUnwrap(${source}))) { - nsCOMPtr ourWindow; - if (!GetWindowForJSImplementedObject(cx, Callback(), getter_AddRefs(ourWindow))) { + nsCOMPtr contentGlobal; + if (!GetContentGlobalForJSImplementedObject(cx, Callback(), getter_AddRefs(contentGlobal))) { $*{exceptionCode} } JS::Rooted jsImplSourceObj(cx, ${source}); - ${target} = new ${type}(jsImplSourceObj, ourWindow); + ${target} = new ${type}(jsImplSourceObj, contentGlobal); } else { $*{codeOnFailure} } @@ -12291,7 +12291,7 @@ class CGBindingRoot(CGThing): jsImplemented = config.getDescriptors(webIDLFile=webIDLFile, isJSImplemented=True) bindingDeclareHeaders["nsWeakReference.h"] = jsImplemented - bindingHeaders["nsPIDOMWindow.h"] = jsImplemented + bindingHeaders["nsIGlobalObject.h"] = jsImplemented bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors def addHeaderBasedOnTypes(header, typeChecker): @@ -13300,7 +13300,6 @@ class CGJSImplMethod(CGJSImplMember): initCall = fill( """ // Wrap the object before calling __Init so that __DOM_IMPL__ is available. - nsCOMPtr globalHolder = do_QueryInterface(window); JS::Rooted scopeObj(cx, globalHolder->GetGlobalJSObject()); MOZ_ASSERT(js::IsObjectInContextCompartment(scopeObj, cx)); JS::Rooted wrappedVal(cx); @@ -13326,13 +13325,13 @@ def genConstructorBody(descriptor, initCall=""): return fill( """ JS::Rooted jsImplObj(cx); - nsCOMPtr window = + nsCOMPtr globalHolder = ConstructJSImplementation(cx, "${contractId}", global, &jsImplObj, aRv); if (aRv.Failed()) { return nullptr; } // Build the C++ implementation. - nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, window); + nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, globalHolder); $*{initCall} return impl.forget(); """, @@ -13516,7 +13515,7 @@ class CGJSImplClass(CGBindingImplClass): constructor = ClassConstructor( [Argument("JS::Handle", "aJSImplObject"), - Argument("nsPIDOMWindow*", "aParent")], + Argument("nsIGlobalObject*", "aParent")], visibility="public", baseConstructors=baseConstructors) @@ -13587,12 +13586,10 @@ class CGJSImplClass(CGBindingImplClass): if (global.Failed()) { return false; } - nsCOMPtr window = do_QueryInterface(global.GetAsSupports()); - if (!window) { - return ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of ${ifaceName}._create", "Window"); - } + nsCOMPtr globalHolder = do_QueryInterface(global.GetAsSupports()); + MOZ_ASSERT(globalHolder); JS::Rooted arg(cx, &args[1].toObject()); - nsRefPtr<${implName}> impl = new ${implName}(arg, window); + nsRefPtr<${implName}> impl = new ${implName}(arg, globalHolder); MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx)); return GetOrCreateDOMReflector(cx, impl, args.rval()); """, diff --git a/dom/bindings/test/TestCImplementedInterface.h b/dom/bindings/test/TestCImplementedInterface.h index c5462b714881..feb3b4e0e52d 100644 --- a/dom/bindings/test/TestCImplementedInterface.h +++ b/dom/bindings/test/TestCImplementedInterface.h @@ -18,7 +18,7 @@ class TestCImplementedInterface : public TestJSImplInterface { public: TestCImplementedInterface(JS::Handle aJSImpl, - nsPIDOMWindow* aParent) + nsIGlobalObject* aParent) : TestJSImplInterface(aJSImpl, aParent) {} }; @@ -27,7 +27,7 @@ class TestCImplementedInterface2 : public nsISupports, public nsWrapperCache { public: - explicit TestCImplementedInterface2(nsPIDOMWindow* aParent) + explicit TestCImplementedInterface2(nsIGlobalObject* aParent) {} NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TestCImplementedInterface2) diff --git a/dom/datastore/DataStoreService.cpp b/dom/datastore/DataStoreService.cpp index eef48ade2935..d8972c24ac3c 100644 --- a/dom/datastore/DataStoreService.cpp +++ b/dom/datastore/DataStoreService.cpp @@ -1005,9 +1005,12 @@ DataStoreService::GetDataStoresResolve(nsPIDOMWindow* aWindow, return; } + nsCOMPtr global = do_QueryInterface(aWindow); + MOZ_ASSERT(global); + JSAutoCompartment ac(cx, dataStoreJS); nsRefPtr dataStoreObj = new DataStoreImpl(dataStoreJS, - aWindow); + global); nsRefPtr exposedStore = new DataStore(aWindow); From b27a30a8fee0187296eb668346cbccc8a1054ebd Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 8 Jan 2015 12:32:12 -0500 Subject: [PATCH 153/224] Bug 987616 - Disable browser_image.js on debug builds due to frequent failures. --- image/test/browser/browser.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/test/browser/browser.ini b/image/test/browser/browser.ini index 46f56acdb242..9cea73060d82 100644 --- a/image/test/browser/browser.ini +++ b/image/test/browser/browser.ini @@ -10,4 +10,4 @@ support-files = [browser_bug666317.js] skip-if = e10s # Bug 948194 - Decoded Images seem to not be discarded on memory-pressure notification with e10s enabled [browser_image.js] -skip-if = e10s || !debug # Test is only to run on debug builds +skip-if = true # Bug 987616 From baaf4bfeb4fef2b6dcf2923176b1d0333764cb6a Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Tue, 6 Jan 2015 12:40:15 -0500 Subject: [PATCH 154/224] Bug 869208 - Increase the buffer size we're using to deliver network streams to OOPP plugins, r=aklotz --HG-- extra : rebase_source : 5be95b5e0d48b6429f5cd868432b2633a83d9800 --- dom/plugins/ipc/BrowserStreamParent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/plugins/ipc/BrowserStreamParent.cpp b/dom/plugins/ipc/BrowserStreamParent.cpp index 508833d88d3d..e4956f06f695 100644 --- a/dom/plugins/ipc/BrowserStreamParent.cpp +++ b/dom/plugins/ipc/BrowserStreamParent.cpp @@ -13,7 +13,7 @@ // How much data are we willing to send across the wire // in one chunk? -static const int32_t kSendDataChunk = 0x4000; +static const int32_t kSendDataChunk = 0xffff; namespace mozilla { namespace plugins { From ff2c0dc262117cf7bc2433fba120614bfe89b82b Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Tue, 6 Jan 2015 22:23:00 +0100 Subject: [PATCH 155/224] Bug 1118136 - Check if targets match before forcing dispatch selection state changed event. r=roc --- .../BrowserElementChildPreload.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index 94f1a91776e8..8ae8073ff8bc 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -94,7 +94,7 @@ function BrowserElementChild() { this._isContentWindowCreated = false; this._pendingSetInputMethodActive = []; - this._forceDispatchSelectionStateChanged = false; + this._selectionStateChangedTarget = null; this._init(); }; @@ -600,7 +600,7 @@ BrowserElementChild.prototype = { let isMouseUp = (e.states.indexOf('mouseup') == 0); let canPaste = this._isCommandEnabled("paste"); - if (!this._forceDispatchSelectionStateChanged) { + if (this._selectionStateChangedTarget != e.target) { // SelectionStateChanged events with the following states are not // necessary to trigger the text dialog, bypass these events // by default. @@ -624,14 +624,15 @@ BrowserElementChild.prototype = { } } - // If we select something and selection range is visible, we set the - // forceDispatchSelectionStateChanged flag as true to dispatch the - // next SelectionStateChange event so that the parent side can - // hide the text dialog. + // If we select something and selection range is visible, we cache current + // event's target to selectionStateChangedTarget. + // And dispatch the next SelectionStateChagne event if target is matched, so + // that the parent side can hide the text dialog. + // We clear selectionStateChangedTarget if selection carets are invisible. if (e.visible && !isCollapsed) { - this._forceDispatchSelectionStateChanged = true; + this._selectionStateChangedTarget = e.target; } else { - this._forceDispatchSelectionStateChanged = false; + this._selectionStateChangedTarget = null; } let zoomFactor = content.screen.width / content.innerWidth; From d11cf2ca74d93ee63ffde05c914dd9d7d1b2c110 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Wed, 7 Jan 2015 13:23:07 -0800 Subject: [PATCH 156/224] bug 1101194 - add telemetry for DataStorage table size r=mgoodwin --- security/manager/boot/src/DataStorage.cpp | 7 +++++++ toolkit/components/telemetry/Histograms.json | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/security/manager/boot/src/DataStorage.cpp b/security/manager/boot/src/DataStorage.cpp index f4d07f9b4621..b0da36fcbbfb 100644 --- a/security/manager/boot/src/DataStorage.cpp +++ b/security/manager/boot/src/DataStorage.cpp @@ -8,6 +8,7 @@ #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/Telemetry.h" #include "mozilla/unused.h" #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" @@ -110,6 +111,12 @@ private: DataStorage::Reader::~Reader() { + { + MutexAutoLock lock(mDataStorage->mMutex); + Telemetry::Accumulate(Telemetry::DATA_STORAGE_ENTRIES, + mDataStorage->mPersistentDataTable.Count()); + } + // Notify that calls to Get can proceed. { MonitorAutoLock readyLock(mDataStorage->mReadyMonitor); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 3fbb1c4f7e7d..18bb499b1529 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -7069,5 +7069,12 @@ "kind": "count", "keyed": true, "description": "Counts of plugin and content process crashes which are reported with a crash dump." + }, + "DATA_STORAGE_ENTRIES": { + "expires_in_version": "default", + "kind": "linear", + "high": "1024", + "n_buckets": 16, + "description": "The number of entries in persistent DataStorage (HSTS and HPKP data, basically)" } } From c9b9054838dfacc5048cae5f75951f5b417eb6cd Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Thu, 8 Jan 2015 09:54:13 -0800 Subject: [PATCH 157/224] Backout bug 1052793 for exposing bad decommitting behavior for compartmental GCs. --- dom/base/nsJSEnvironment.cpp | 12 +----------- xpcom/base/CycleCollectedJSRuntime.cpp | 19 ------------------- xpcom/base/CycleCollectedJSRuntime.h | 15 --------------- xpcom/base/nsCycleCollector.cpp | 5 ----- 4 files changed, 1 insertion(+), 50 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 5f0c683aa581..7c1ca0c7dd56 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -185,7 +185,6 @@ static uint32_t sForgetSkippableBeforeCC = 0; static uint32_t sPreviousSuspectedCount = 0; static uint32_t sCleanupsSinceLastGC = UINT32_MAX; static bool sNeedsFullCC = false; -static bool sNeedsFullGC = false; static bool sNeedsGCAfterCC = false; static bool sIncrementalCC = false; static bool sDidPaintAfterPreviousICCSlice = false; @@ -1285,13 +1284,7 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, return; } - if (sNeedsFullGC || aReason != JS::gcreason::CC_WAITING) { - sNeedsFullGC = false; - JS::PrepareForFullGC(sRuntime); - } else { - CycleCollectedJSRuntime::Get()->PrepareWaitingZonesForGC(); - } - + JS::PrepareForFullGC(sRuntime); if (aIncremental == IncrementalGC) { MOZ_ASSERT(aShrinking == NonShrinkingGC); JS::StartIncrementalGC(sRuntime, GC_NORMAL, aReason, aSliceMillis); @@ -1977,8 +1970,6 @@ nsJSContext::RunNextCollectorTimer() void nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay) { - sNeedsFullGC = sNeedsFullGC || aReason != JS::gcreason::CC_WAITING; - if (sGCTimer || sInterSliceGCTimer || sShuttingDown) { // There's already a timer for GC'ing, just return return; @@ -2300,7 +2291,6 @@ mozilla::dom::StartupJSEnvironment() sLikelyShortLivingObjectsNeedingGC = 0; sPostGCEventsToConsole = false; sNeedsFullCC = false; - sNeedsFullGC = false; sNeedsGCAfterCC = false; gNameSpaceManager = nullptr; sRuntimeService = nullptr; diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 0e10a427c394..e8049d77cf70 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -1265,7 +1265,6 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus) switch (aStatus) { case JSGC_BEGIN: nsCycleCollector_prepareForGarbageCollection(); - mZonesWaitingForGC.Clear(); break; case JSGC_END: { #ifdef MOZ_CRASHREPORTER @@ -1304,21 +1303,3 @@ CycleCollectedJSRuntime::OnLargeAllocationFailure() CustomLargeAllocationFailureCallback(); AnnotateAndSetOutOfMemory(&mLargeAllocationFailureState, OOMState::Reported); } - -static PLDHashOperator -PrepareWaitingZoneForGC(nsPtrHashKey* aZoneEntry, void*) -{ - JS::PrepareZoneForGC(aZoneEntry->GetKey()); - return PL_DHASH_NEXT; -} - -void -CycleCollectedJSRuntime::PrepareWaitingZonesForGC() -{ - if (mZonesWaitingForGC.Count() == 0) { - JS::PrepareForFullGC(Runtime()); - } else { - mZonesWaitingForGC.EnumerateEntries(PrepareWaitingZoneForGC, nullptr); - mZonesWaitingForGC.Clear(); - } -} diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 68a764d9671e..2305a8493d2a 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -15,7 +15,6 @@ #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" -#include "nsTHashtable.h" class nsCycleCollectionNoteRootCallback; class nsIException; @@ -292,18 +291,6 @@ public: // isn't one. static CycleCollectedJSRuntime* Get(); - // Add aZone to the set of zones waiting for a GC. - void AddZoneWaitingForGC(JS::Zone* aZone) - { - mZonesWaitingForGC.PutEntry(aZone); - } - - // Prepare any zones for GC that have been passed to AddZoneWaitingForGC() - // since the last GC or since the last call to PrepareWaitingZonesForGC(), - // whichever was most recent. If there were no such zones, prepare for a - // full GC. - void PrepareWaitingZonesForGC(); - private: JSGCThingParticipant mGCThingCycleCollectorGlobal; @@ -326,8 +313,6 @@ private: OOMState mOutOfMemoryState; OOMState mLargeAllocationFailureState; - - nsTHashtable> mZonesWaitingForGC; }; MOZ_FINISH_NESTED_ENUM_CLASS(CycleCollectedJSRuntime::OOMState) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 7256689f0563..d212d814bc72 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -3275,14 +3275,9 @@ nsCycleCollector::CollectWhite() if (pinfo->mColor == white && pinfo->mParticipant) { if (pinfo->IsGrayJS()) { ++numWhiteGCed; - JS::Zone* zone; if (MOZ_UNLIKELY(pinfo->mParticipant == zoneParticipant)) { ++numWhiteJSZones; - zone = static_cast(pinfo->mPointer); - } else { - zone = JS::GetTenuredGCThingZone(pinfo->mPointer); } - mJSRuntime->AddZoneWaitingForGC(zone); } else { whiteNodes.InfallibleAppend(pinfo); pinfo->mParticipant->Root(pinfo->mPointer); From f9d3f8f0017a4461cc914dcd3e675ed2bb78127e Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 8 Jan 2015 18:58:22 +0100 Subject: [PATCH 158/224] Bug 1114948 - Use NS_lroundf instead of NS_roundf in tioling code to avoid inconsistent behavior around zero. r=jrmuizel --- gfx/layers/client/TiledContentClient.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index e16c06ecd19d..f3ec10ea6365 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -27,7 +27,7 @@ #include "nsSize.h" // for nsIntSize #include "gfxReusableSharedImageSurfaceWrapper.h" #include "nsExpirationTracker.h" // for nsExpirationTracker -#include "nsMathUtils.h" // for NS_roundf +#include "nsMathUtils.h" // for NS_lroundf #include "gfx2DGlue.h" #include "LayersLogging.h" #include "UnitTransforms.h" // for TransformTo @@ -1189,7 +1189,7 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile, // Mark the newly updated area as invalid in the front buffer aTile.mInvalidFront.Or(aTile.mInvalidFront, - nsIntRect(NS_roundf(drawRect.x), NS_roundf(drawRect.y), + nsIntRect(NS_lroundf(drawRect.x), NS_lroundf(drawRect.y), drawRect.width, drawRect.height)); if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { @@ -1235,11 +1235,11 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile, dirtyRect->height); drawRect.Scale(mResolution); - gfx::IntRect copyRect(NS_roundf((dirtyRect->x - mSinglePaintBufferOffset.x) * mResolution), - NS_roundf((dirtyRect->y - mSinglePaintBufferOffset.y) * mResolution), + gfx::IntRect copyRect(NS_lroundf((dirtyRect->x - mSinglePaintBufferOffset.x) * mResolution), + NS_lroundf((dirtyRect->y - mSinglePaintBufferOffset.y) * mResolution), drawRect.width, drawRect.height); - gfx::IntPoint copyTarget(NS_roundf(drawRect.x), NS_roundf(drawRect.y)); + gfx::IntPoint copyTarget(NS_lroundf(drawRect.x), NS_lroundf(drawRect.y)); drawTarget->CopySurface(source, copyRect, copyTarget); // Mark the newly updated area as invalid in the front buffer From 95f81fbb0e55323f1929dbaf371120d46ecf8430 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Jan 2015 13:19:54 -0500 Subject: [PATCH 159/224] Bug 1103000 followup: remove failure annotations from the corresponding web platform test so we can reopen the CLOSED TREE. --- .../meta/quirks-mode/unitless-length.html.ini | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/testing/web-platform/meta/quirks-mode/unitless-length.html.ini b/testing/web-platform/meta/quirks-mode/unitless-length.html.ini index 964497642a1c..f9f2ae933231 100644 --- a/testing/web-platform/meta/quirks-mode/unitless-length.html.ini +++ b/testing/web-platform/meta/quirks-mode/unitless-length.html.ini @@ -20,34 +20,3 @@ [Excluded property bottom:1] expected: FAIL - - [1 (quirks)] - expected: FAIL - - [+1 (quirks)] - expected: FAIL - - [-1 (quirks)] - expected: FAIL - - [1.5 (quirks)] - expected: FAIL - - [+1.5 (quirks)] - expected: FAIL - - [-1.5 (quirks)] - expected: FAIL - - [1px 2 (quirks)] - expected: FAIL - - [1 2px (quirks)] - expected: FAIL - - [1 +2 (quirks)] - expected: FAIL - - [1 -2 (quirks)] - expected: FAIL - From 1bf832faa99462deaaadc57dded24ee54eb79509 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Tue, 6 Jan 2015 17:01:07 -0800 Subject: [PATCH 160/224] Bug 1118534 - Comment updates in nsIContentPolicy, nsIOService.idl, nsNetutil.h, NetUtil.jsm (r=sicking) --- dom/base/nsIContentPolicy.idl | 8 +++++++- netwerk/base/public/nsIIOService.idl | 3 +++ netwerk/base/public/nsNetUtil.h | 3 +++ netwerk/base/src/NetUtil.jsm | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dom/base/nsIContentPolicy.idl b/dom/base/nsIContentPolicy.idl index d25e621c9a44..646745ab0ac9 100644 --- a/dom/base/nsIContentPolicy.idl +++ b/dom/base/nsIContentPolicy.idl @@ -33,7 +33,13 @@ interface nsIContentPolicy : nsISupports const nsContentPolicyType TYPE_INVALID = 0; /** - * Gecko/Firefox developers: Do not use TYPE_OTHER under any circumstances. + * Gecko/Firefox developers: Avoid using TYPE_OTHER. Especially for + * requests that are coming from webpages. Or requests in general which + * you expect that security checks will be done on. + * Always use a more specific type if one is available. And do not hesitate + * to add more types as appropriate. + * But if you are fairly sure that no one would care about your more specific + * type, then it's ok to use TYPE_OTHER. * * Extension developers: Whenever it is reasonable, use one of the existing * content types. If none of the existing content types are right for diff --git a/netwerk/base/public/nsIIOService.idl b/netwerk/base/public/nsIIOService.idl index 884151592b58..67edbea1e36c 100644 --- a/netwerk/base/public/nsIIOService.idl +++ b/netwerk/base/public/nsIIOService.idl @@ -122,6 +122,9 @@ interface nsIIOService : nsISupports * Please note, if you provide both a loadingNode and a loadingPrincipal, * then loadingPrincipal must be equal to loadingNode->NodePrincipal(). * But less error prone is to just supply a loadingNode. + * + * Keep in mind that URIs coming from a webpage should *never* use the + * systemPrincipal as the loadingPrincipal. */ nsIChannel newChannelFromURI2(in nsIURI aURI, in nsIDOMNode aLoadingNode, diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 456222ab839d..eeb6b0bd4a14 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -257,6 +257,9 @@ NS_NewFileURI(nsIURI* *result, * Please note, if you provide both a loadingNode and a loadingPrincipal, * then loadingPrincipal must be equal to loadingNode->NodePrincipal(). * But less error prone is to just supply a loadingNode. +* +* Keep in mind that URIs coming from a webpage should *never* use the +* systemPrincipal as the loadingPrincipal. */ inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, diff --git a/netwerk/base/src/NetUtil.jsm b/netwerk/base/src/NetUtil.jsm index c33d85bda9d1..8cebc55d0004 100644 --- a/netwerk/base/src/NetUtil.jsm +++ b/netwerk/base/src/NetUtil.jsm @@ -397,6 +397,9 @@ this.NetUtil = { * Any of the content types defined in nsIContentPolicy.idl * @return an nsIChannel object. * + * Keep in mind that URIs coming from a webpage should *never* use the + * systemPrincipal as the loadingPrincipal. + * * Note: As an interim we have newChannel as well as newChannel2. * Once Bug 1087720 (which converts all js callers to use * newChannel2) lands, we can remove newChannel completely. From c1795f4024be6e19015c7918494105bb28d6ef29 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 6 Jan 2015 18:28:09 -0800 Subject: [PATCH 161/224] Bug 1118599 - Remove now-unneeded MOZILLA_PKIX_ENUM_CLASS workaround for GCC enum class bugs. r=mmc --- security/pkix/include/pkix/Result.h | 10 +-- security/pkix/include/pkix/enumclass.h | 38 ---------- security/pkix/include/pkix/pkixtypes.h | 12 +-- security/pkix/lib/pkixder.h | 4 +- security/pkix/lib/pkixnames.cpp | 75 ++++++++----------- security/pkix/lib/pkixocsp.cpp | 4 +- security/pkix/test/gtest/pkixbuild_tests.cpp | 3 +- .../pkixcert_signature_algorithm_tests.cpp | 3 +- .../pkixocsp_VerifyEncodedOCSPResponse.cpp | 22 ++---- security/pkix/test/lib/pkixtestutil.cpp | 32 ++++---- security/pkix/test/lib/pkixtestutil.h | 8 +- 11 files changed, 68 insertions(+), 143 deletions(-) delete mode 100644 security/pkix/include/pkix/enumclass.h diff --git a/security/pkix/include/pkix/Result.h b/security/pkix/include/pkix/Result.h index ebea29026a28..59015bc153f0 100644 --- a/security/pkix/include/pkix/Result.h +++ b/security/pkix/include/pkix/Result.h @@ -27,8 +27,6 @@ #include -#include "pkix/enumclass.h" - namespace mozilla { namespace pkix { static const unsigned int FATAL_ERROR_FLAG = 0x800; @@ -183,7 +181,7 @@ static const unsigned int FATAL_ERROR_FLAG = 0x800; SEC_ERROR_NO_MEMORY) \ /* nothing here */ -MOZILLA_PKIX_ENUM_CLASS Result +enum class Result { #define MOZILLA_PKIX_MAP(name, value, nss_name) name = value, MOZILLA_PKIX_MAP_LIST @@ -197,13 +195,7 @@ const char* MapResultToName(Result result); // We write many comparisons as (x != Success), and this shortened name makes // those comparisons clearer, especially because the shortened name often // results in less line wrapping. -// -// If MOZILLA_PKIX_ENUM_CLASS doesn't expand to "enum class" then -// Result::Success will already be in scope, and compilation would fail if we -// were to try to define a variable named "Success" here. -#ifdef MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS static const Result Success = Result::Success; -#endif inline bool IsFatalError(Result rv) diff --git a/security/pkix/include/pkix/enumclass.h b/security/pkix/include/pkix/enumclass.h deleted file mode 100644 index d48488d5cf69..000000000000 --- a/security/pkix/include/pkix/enumclass.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This code is made available to you under your choice of the following sets - * of licensing terms: - */ -/* 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/. - */ -/* Copyright 2013 Mozilla Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef mozilla_pkix__enumclass_h -#define mozilla_pkix__enumclass_h - -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) -// GCC before version 4.7 may crash when compiling code that static_casts a -// value of scoped typed enum type. See -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48106. -#define MOZILLA_PKIX_ENUM_CLASS enum -#else -#define MOZILLA_PKIX_ENUM_CLASS enum class -#define MOZILLA_PKIX_ENUM_CLASS_REALLY_IS_ENUM_CLASS -#endif - -#endif // mozilla_pkix__enumclass_h diff --git a/security/pkix/include/pkix/pkixtypes.h b/security/pkix/include/pkix/pkixtypes.h index d417f4089936..98fe338f92df 100644 --- a/security/pkix/include/pkix/pkixtypes.h +++ b/security/pkix/include/pkix/pkixtypes.h @@ -31,7 +31,7 @@ namespace mozilla { namespace pkix { -MOZILLA_PKIX_ENUM_CLASS DigestAlgorithm +enum class DigestAlgorithm { sha512 = 1, sha384 = 2, @@ -43,7 +43,7 @@ MOZILLA_PKIX_ENUM_CLASS DigestAlgorithm // * secp521r1 (OID 1.3.132.0.35, RFC 5480) // * secp384r1 (OID 1.3.132.0.34, RFC 5480) // * secp256r1 (OID 1.2.840.10045.3.17, RFC 5480) -MOZILLA_PKIX_ENUM_CLASS SignatureAlgorithm +enum class SignatureAlgorithm { // ecdsa-with-SHA512 (OID 1.2.840.10045.4.3.4, RFC 5758 Section 3.2) ecdsa_with_sha512 = 1, @@ -84,9 +84,9 @@ private: void operator=(const SignedDataWithSignature&) /*= delete*/; }; -MOZILLA_PKIX_ENUM_CLASS EndEntityOrCA { MustBeEndEntity = 0, MustBeCA = 1 }; +enum class EndEntityOrCA { MustBeEndEntity = 0, MustBeCA = 1 }; -MOZILLA_PKIX_ENUM_CLASS KeyUsage : uint8_t { +enum class KeyUsage : uint8_t { digitalSignature = 0, nonRepudiation = 1, keyEncipherment = 2, @@ -99,7 +99,7 @@ MOZILLA_PKIX_ENUM_CLASS KeyUsage : uint8_t { noParticularKeyUsageRequired = 0xff, }; -MOZILLA_PKIX_ENUM_CLASS KeyPurposeId { +enum class KeyPurposeId { anyExtendedKeyUsage = 0, id_kp_serverAuth = 1, // id-kp-serverAuth id_kp_clientAuth = 2, // id-kp-clientAuth @@ -118,7 +118,7 @@ struct CertPolicyId { static const CertPolicyId anyPolicy; }; -MOZILLA_PKIX_ENUM_CLASS TrustLevel { +enum class TrustLevel { TrustAnchor = 1, // certificate is a trusted root CA certificate or // equivalent *for the given policy*. ActivelyDistrusted = 2, // certificate is known to be bad diff --git a/security/pkix/lib/pkixder.h b/security/pkix/lib/pkixder.h index 9f69d6c8cfae..30f7ab0dfabf 100644 --- a/security/pkix/lib/pkixder.h +++ b/security/pkix/lib/pkixder.h @@ -74,7 +74,7 @@ enum Tag GENERALIZED_TIME = UNIVERSAL | 0x18, }; -MOZILLA_PKIX_ENUM_CLASS EmptyAllowed { No = 0, Yes = 1 }; +enum class EmptyAllowed { No = 0, Yes = 1 }; Result ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag, /*out*/ Input& value); @@ -474,7 +474,7 @@ CertificateSerialNumber(Reader& input, /*out*/ Input& value) // x.509 and OCSP both use this same version numbering scheme, though OCSP // only supports v1. -MOZILLA_PKIX_ENUM_CLASS Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3 }; +enum class Version { v1 = 0, v2 = 1, v3 = 2, v4 = 3 }; // X.509 Certificate and OCSP ResponseData both use this // "[0] EXPLICIT Version DEFAULT " construct, but with diff --git a/security/pkix/lib/pkixnames.cpp b/security/pkix/lib/pkixnames.cpp index e3b7f47063d2..7a70d8fb5405 100644 --- a/security/pkix/lib/pkixnames.cpp +++ b/security/pkix/lib/pkixnames.cpp @@ -52,7 +52,7 @@ namespace { // uniformResourceIdentifier [6] IA5String, // iPAddress [7] OCTET STRING, // registeredID [8] OBJECT IDENTIFIER } -MOZILLA_PKIX_ENUM_CLASS GeneralNameType : uint8_t +enum class GeneralNameType : uint8_t { // Note that these values are NOT contiguous. Some values have the // der::CONSTRUCTED bit set while others do not. @@ -115,9 +115,9 @@ ReadGeneralName(Reader& reader, return Success; } -MOZILLA_PKIX_ENUM_CLASS FallBackToSearchWithinSubject { No = 0, Yes = 1 }; +enum class FallBackToSearchWithinSubject { No = 0, Yes = 1 }; -MOZILLA_PKIX_ENUM_CLASS MatchResult +enum class MatchResult { NoNamesOfGivenType = 0, Mismatch = 1, @@ -159,36 +159,29 @@ Result CheckPresentedIDConformsToConstraints(GeneralNameType referenceIDType, uint8_t LocaleInsensitveToLower(uint8_t a); bool StartsWithIDNALabel(Input id); -MOZILLA_PKIX_ENUM_CLASS IDRole +enum class IDRole { ReferenceID = 0, PresentedID = 1, NameConstraint = 2, }; -MOZILLA_PKIX_ENUM_CLASS Wildcards -{ - AllowWildcards = 0, - DisallowWildcards = 1 -}; +enum class AllowWildcards { No = 0, Yes = 1 }; // DNSName constraints implicitly allow subdomain matching when there is no // leading dot ("foo.example.com" matches a constraint of "example.com"), but // RFC822Name constraints only allow subdomain matching when there is a leading // dot ("foo.example.com" does not match "example.com" but does match // ".example.com"). -MOZILLA_PKIX_ENUM_CLASS DotlessSubdomainMatches -{ - DisallowDotlessSubdomainMatches = 0, - AllowDotlessSubdomainMatches = 1 -}; +enum class AllowDotlessSubdomainMatches { No = 0, Yes = 1 }; -bool IsValidDNSID(Input hostname, IDRole idRole, Wildcards allowWildcards); +bool IsValidDNSID(Input hostname, IDRole idRole, + AllowWildcards allowWildcards); Result MatchPresentedDNSIDWithReferenceDNSID( Input presentedDNSID, - Wildcards allowWildcards, - DotlessSubdomainMatches allowDotlessSubdomainMatches, + AllowWildcards allowWildcards, + AllowDotlessSubdomainMatches allowDotlessSubdomainMatches, IDRole referenceDNSIDRole, Input referenceDNSID, /*out*/ bool& matches); @@ -211,9 +204,8 @@ MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID, /*out*/ bool& matches) { return MatchPresentedDNSIDWithReferenceDNSID( - presentedDNSID, Wildcards::AllowWildcards, - DotlessSubdomainMatches::AllowDotlessSubdomainMatches, - IDRole::ReferenceID, + presentedDNSID, AllowWildcards::Yes, + AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID, referenceDNSID, matches); } @@ -701,9 +693,9 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType, switch (referenceIDType) { case GeneralNameType::dNSName: rv = MatchPresentedDNSIDWithReferenceDNSID( - presentedID, Wildcards::AllowWildcards, - DotlessSubdomainMatches::AllowDotlessSubdomainMatches, - IDRole::ReferenceID, referenceID, foundMatch); + presentedID, AllowWildcards::Yes, + AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID, + referenceID, foundMatch); break; case GeneralNameType::iPAddress: @@ -741,7 +733,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType, return Success; } -MOZILLA_PKIX_ENUM_CLASS NameConstraintsSubtrees : uint8_t +enum class NameConstraintsSubtrees : uint8_t { permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0, excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1 @@ -858,9 +850,9 @@ CheckPresentedIDConformsToNameConstraintsSubtrees( switch (presentedIDType) { case GeneralNameType::dNSName: rv = MatchPresentedDNSIDWithReferenceDNSID( - presentedID, Wildcards::AllowWildcards, - DotlessSubdomainMatches::AllowDotlessSubdomainMatches, - IDRole::NameConstraint, base, matches); + presentedID, AllowWildcards::Yes, + AllowDotlessSubdomainMatches::Yes, IDRole::NameConstraint, + base, matches); if (rv != Success) { return rv; } @@ -1067,8 +1059,8 @@ CheckPresentedIDConformsToNameConstraintsSubtrees( Result MatchPresentedDNSIDWithReferenceDNSID( Input presentedDNSID, - Wildcards allowWildcards, - DotlessSubdomainMatches allowDotlessSubdomainMatches, + AllowWildcards allowWildcards, + AllowDotlessSubdomainMatches allowDotlessSubdomainMatches, IDRole referenceDNSIDRole, Input referenceDNSID, /*out*/ bool& matches) @@ -1077,8 +1069,7 @@ MatchPresentedDNSIDWithReferenceDNSID( return Result::ERROR_BAD_DER; } - if (!IsValidDNSID(referenceDNSID, referenceDNSIDRole, - Wildcards::DisallowWildcards)) { + if (!IsValidDNSID(referenceDNSID, referenceDNSIDRole, AllowWildcards::No)) { return Result::ERROR_BAD_DER; } @@ -1129,7 +1120,7 @@ MatchPresentedDNSIDWithReferenceDNSID( Result::FATAL_ERROR_LIBRARY_FAILURE); } } else if (allowDotlessSubdomainMatches == - DotlessSubdomainMatches::AllowDotlessSubdomainMatches) { + AllowDotlessSubdomainMatches::Yes) { if (presented.Skip(static_cast( presentedDNSID.GetLength() - referenceDNSID.GetLength() - 1)) != Success) { @@ -1453,8 +1444,7 @@ IsValidRFC822Name(Input input) } Input domain; reader.SkipToEnd(domain); - return IsValidDNSID(domain, IDRole::PresentedID, - Wildcards::DisallowWildcards); + return IsValidDNSID(domain, IDRole::PresentedID, AllowWildcards::No); } default: @@ -1506,9 +1496,9 @@ MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name, presented.SkipToEnd(presentedDNSID); return MatchPresentedDNSIDWithReferenceDNSID( - presentedDNSID, Wildcards::DisallowWildcards, - DotlessSubdomainMatches::DisallowDotlessSubdomainMatches, - IDRole::NameConstraint, referenceRFC822Name, matches); + presentedDNSID, AllowWildcards::No, + AllowDotlessSubdomainMatches::No, IDRole::NameConstraint, + referenceRFC822Name, matches); } default: @@ -1817,21 +1807,19 @@ ParseIPv6Address(Input hostname, /*out*/ uint8_t (&out)[16]) bool IsValidReferenceDNSID(Input hostname) { - return IsValidDNSID(hostname, IDRole::ReferenceID, - Wildcards::DisallowWildcards); + return IsValidDNSID(hostname, IDRole::ReferenceID, AllowWildcards::No); } bool IsValidPresentedDNSID(Input hostname) { - return IsValidDNSID(hostname, IDRole::PresentedID, - Wildcards::AllowWildcards); + return IsValidDNSID(hostname, IDRole::PresentedID, AllowWildcards::Yes); } namespace { bool -IsValidDNSID(Input hostname, IDRole idRole, Wildcards allowWildcards) +IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards) { if (hostname.GetLength() > 253) { return false; @@ -1851,8 +1839,7 @@ IsValidDNSID(Input hostname, IDRole idRole, Wildcards allowWildcards) // Only presented IDs are allowed to have wildcard labels. And, like // Chromium, be stricter than RFC 6125 requires by insisting that a // wildcard label consist only of '*'. - bool isWildcard = allowWildcards == Wildcards::AllowWildcards && - input.Peek('*'); + bool isWildcard = allowWildcards == AllowWildcards::Yes && input.Peek('*'); bool isFirstByte = !isWildcard; if (isWildcard) { Result rv = input.Skip(1); diff --git a/security/pkix/lib/pkixocsp.cpp b/security/pkix/lib/pkixocsp.cpp index 9f29f2eaadad..4732de155be1 100644 --- a/security/pkix/lib/pkixocsp.cpp +++ b/security/pkix/lib/pkixocsp.cpp @@ -33,7 +33,7 @@ namespace mozilla { namespace pkix { // These values correspond to the tag values in the ASN.1 CertStatus -MOZILLA_PKIX_ENUM_CLASS CertStatus : uint8_t { +enum class CertStatus : uint8_t { Good = der::CONTEXT_SPECIFIC | 0, Revoked = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, Unknown = der::CONTEXT_SPECIFIC | 2 @@ -140,7 +140,7 @@ CheckOCSPResponseSignerCert(TrustDomain& trustDomain, return rv; } -MOZILLA_PKIX_ENUM_CLASS ResponderIDType : uint8_t +enum class ResponderIDType : uint8_t { byName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, byKey = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 2 diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index a5f96b33daa0..6c584be221dc 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -49,8 +49,7 @@ CreateCert(const char* issuerCN, // null means "empty name" ByteString extensions[2]; if (endEntityOrCA == EndEntityOrCA::MustBeCA) { extensions[0] = - CreateEncodedBasicConstraints(true, nullptr, - ExtensionCriticality::Critical); + CreateEncodedBasicConstraints(true, nullptr, Critical::Yes); EXPECT_FALSE(ENCODING_FAILED(extensions[0])); } diff --git a/security/pkix/test/gtest/pkixcert_signature_algorithm_tests.cpp b/security/pkix/test/gtest/pkixcert_signature_algorithm_tests.cpp index 7365a77fb895..c13d1c7d7176 100644 --- a/security/pkix/test/gtest/pkixcert_signature_algorithm_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_signature_algorithm_tests.cpp @@ -30,8 +30,7 @@ CreateCert(const char* issuerCN, ByteString extensions[2]; if (endEntityOrCA == EndEntityOrCA::MustBeCA) { extensions[0] = - CreateEncodedBasicConstraints(true, nullptr, - ExtensionCriticality::Critical); + CreateEncodedBasicConstraints(true, nullptr, Critical::Yes); EXPECT_FALSE(ENCODING_FAILED(extensions[0])); } diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 6d2a2e66dbb7..d600b2b7cf94 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -477,8 +477,7 @@ protected: const ByteString extensions[] = { signerEKUDER - ? CreateEncodedEKUExtension(*signerEKUDER, - ExtensionCriticality::NotCritical) + ? CreateEncodedEKUExtension(*signerEKUDER, Critical::No) : ByteString(), ByteString() }; @@ -628,8 +627,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) static const char* signerName = "good_indirect_expired"; const ByteString extensions[] = { - CreateEncodedEKUExtension(OCSPSigningEKUDER, - ExtensionCriticality::NotCritical), + CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No), ByteString() }; @@ -664,8 +662,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) static const char* signerName = "good_indirect_future"; const ByteString extensions[] = { - CreateEncodedEKUExtension(OCSPSigningEKUDER, - ExtensionCriticality::NotCritical), + CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No), ByteString() }; @@ -772,8 +769,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) // Delegated responder cert signed by unknown issuer const ByteString extensions[] = { - CreateEncodedEKUExtension(OCSPSigningEKUDER, - ExtensionCriticality::NotCritical), + CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No), ByteString() }; ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); @@ -813,7 +809,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, // sub-CA of root (root is the direct issuer of endEntity) const ByteString subCAExtensions[] = { - CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), + CreateEncodedBasicConstraints(true, 0, Critical::No), ByteString() }; ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); @@ -825,8 +821,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { - CreateEncodedEKUExtension(OCSPSigningEKUDER, - ExtensionCriticality::NotCritical), + CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No), ByteString(), }; ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); @@ -867,7 +862,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, // sub-CA of root (root is the direct issuer of endEntity) const ByteString subCAExtensions[] = { - CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), + CreateEncodedBasicConstraints(true, 0, Critical::No), ByteString() }; ScopedTestKeyPair subCAKeyPair(GenerateKeyPair()); @@ -881,8 +876,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, // Delegated responder cert signed by that sub-CA const ByteString extensions[] = { - CreateEncodedEKUExtension(OCSPSigningEKUDER, - ExtensionCriticality::NotCritical), + CreateEncodedEKUExtension(OCSPSigningEKUDER, Critical::No), ByteString() }; ScopedTestKeyPair signerKeyPair(GenerateKeyPair()); diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index 0994ebfea6ed..08a2bb26ed8d 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -409,16 +409,14 @@ SignedData(const ByteString& tbsData, // -- by extnID // } static ByteString -Extension(Input extnID, ExtensionCriticality criticality, - const ByteString& extnValueBytes) +Extension(Input extnID, Critical critical, const ByteString& extnValueBytes) { ByteString encoded; encoded.append(ByteString(extnID.UnsafeGetData(), extnID.GetLength())); - if (criticality == ExtensionCriticality::Critical) { - ByteString critical(Boolean(true)); - encoded.append(critical); + if (critical == Critical::Yes) { + encoded.append(Boolean(true)); } ByteString extnValueSequence(TLV(der::SEQUENCE, extnValueBytes)); @@ -428,13 +426,12 @@ Extension(Input extnID, ExtensionCriticality criticality, } static ByteString -EmptyExtension(Input extnID, ExtensionCriticality criticality) +EmptyExtension(Input extnID, Critical critical) { ByteString encoded(extnID.UnsafeGetData(), extnID.GetLength()); - if (criticality == ExtensionCriticality::Critical) { - ByteString critical(Boolean(true)); - encoded.append(critical); + if (critical == Critical::Yes) { + encoded.append(Boolean(true)); } ByteString extnValue(TLV(der::OCTET_STRING, ByteString())); @@ -682,7 +679,7 @@ CreateEncodedSerialNumber(long serialNumberValue) ByteString CreateEncodedBasicConstraints(bool isCA, /*optional*/ long* pathLenConstraintValue, - ExtensionCriticality criticality) + Critical critical) { ByteString value; @@ -700,13 +697,13 @@ CreateEncodedBasicConstraints(bool isCA, static const uint8_t tlv_id_ce_basicConstraints[] = { 0x06, 0x03, 0x55, 0x1d, 0x13 }; - return Extension(Input(tlv_id_ce_basicConstraints), criticality, value); + return Extension(Input(tlv_id_ce_basicConstraints), critical, value); } // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId // KeyPurposeId ::= OBJECT IDENTIFIER ByteString -CreateEncodedEKUExtension(Input ekuOID, ExtensionCriticality criticality) +CreateEncodedEKUExtension(Input ekuOID, Critical critical) { ByteString value(ekuOID.UnsafeGetData(), ekuOID.GetLength()); @@ -715,7 +712,7 @@ CreateEncodedEKUExtension(Input ekuOID, ExtensionCriticality criticality) 0x06, 0x03, 0x55, 0x1d, 0x25 }; - return Extension(Input(tlv_id_ce_extKeyUsage), criticality, value); + return Extension(Input(tlv_id_ce_extKeyUsage), critical, value); } // python DottedOIDToCode.py --tlv id-ce-subjectAltName 2.5.29.17 @@ -726,15 +723,13 @@ static const uint8_t tlv_id_ce_subjectAltName[] = { ByteString CreateEncodedSubjectAltName(const ByteString& names) { - return Extension(Input(tlv_id_ce_subjectAltName), - ExtensionCriticality::NotCritical, names); + return Extension(Input(tlv_id_ce_subjectAltName), Critical::No, names); } ByteString CreateEncodedEmptySubjectAltName() { - return EmptyExtension(Input(tlv_id_ce_subjectAltName), - ExtensionCriticality::NotCritical); + return EmptyExtension(Input(tlv_id_ce_subjectAltName), Critical::No); } /////////////////////////////////////////////////////////////////////////////// @@ -839,8 +834,7 @@ OCSPExtension(OCSPResponseContext& context, OCSPResponseExtension& extension) ByteString encoded; encoded.append(extension.id); if (extension.critical) { - ByteString critical(Boolean(true)); - encoded.append(critical); + encoded.append(Boolean(true)); } ByteString value(TLV(der::OCTET_STRING, extension.value)); encoded.append(value); diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 21c1cf9a3757..5caad8bb289e 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -29,7 +29,6 @@ #include // Some Mozilla-supported compilers lack #include -#include "pkix/enumclass.h" #include "pkix/pkixtypes.h" #include "pkix/ScopedPtr.h" @@ -303,15 +302,14 @@ ByteString CreateEncodedCertificate(long version, const ByteString& signature, ByteString CreateEncodedSerialNumber(long value); -MOZILLA_PKIX_ENUM_CLASS ExtensionCriticality { NotCritical = 0, Critical = 1 }; +enum class Critical { No = 0, Yes = 1 }; ByteString CreateEncodedBasicConstraints(bool isCA, /*optional*/ long* pathLenConstraint, - ExtensionCriticality criticality); + Critical critical); // Creates a DER-encoded extKeyUsage extension with one EKU OID. -ByteString CreateEncodedEKUExtension(Input eku, - ExtensionCriticality criticality); +ByteString CreateEncodedEKUExtension(Input eku, Critical critical); /////////////////////////////////////////////////////////////////////////////// // Encode OCSP responses From 8362f5129c40d496f8d102d5c63bf50ec210fb58 Mon Sep 17 00:00:00 2001 From: Shawn Ku Date: Thu, 8 Jan 2015 11:23:09 +0800 Subject: [PATCH 162/224] Bug 1113476: IDL patch - B2G RIL: support nsck/pck for SIM Lock types. r=edgar. --- dom/icc/Assertions.cpp | 4 +++ dom/icc/interfaces/nsIIccProvider.idl | 38 +++++++++++++++------------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/dom/icc/Assertions.cpp b/dom/icc/Assertions.cpp index 6d74f0b926d1..0f9c7a07a33e 100644 --- a/dom/icc/Assertions.cpp +++ b/dom/icc/Assertions.cpp @@ -63,19 +63,23 @@ ASSERT_ICC_LOCK_TYPE_EQUALITY(Pin2, CARD_LOCK_TYPE_PIN2); ASSERT_ICC_LOCK_TYPE_EQUALITY(Puk, CARD_LOCK_TYPE_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Puk2, CARD_LOCK_TYPE_PUK2); ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck, CARD_LOCK_TYPE_NCK); +ASSERT_ICC_LOCK_TYPE_EQUALITY(Nsck, CARD_LOCK_TYPE_NSCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck1, CARD_LOCK_TYPE_NCK1); ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck2, CARD_LOCK_TYPE_NCK2); ASSERT_ICC_LOCK_TYPE_EQUALITY(Hnck, CARD_LOCK_TYPE_HNCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Cck, CARD_LOCK_TYPE_CCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Spck, CARD_LOCK_TYPE_SPCK); +ASSERT_ICC_LOCK_TYPE_EQUALITY(Pck, CARD_LOCK_TYPE_PCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Rcck, CARD_LOCK_TYPE_RCCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Rspck, CARD_LOCK_TYPE_RSPCK); ASSERT_ICC_LOCK_TYPE_EQUALITY(NckPuk, CARD_LOCK_TYPE_NCK_PUK); +ASSERT_ICC_LOCK_TYPE_EQUALITY(NsckPuk, CARD_LOCK_TYPE_NSCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck1Puk, CARD_LOCK_TYPE_NCK1_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck2Puk, CARD_LOCK_TYPE_NCK2_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(HnckPuk, CARD_LOCK_TYPE_HNCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(CckPuk, CARD_LOCK_TYPE_CCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(SpckPuk, CARD_LOCK_TYPE_SPCK_PUK); +ASSERT_ICC_LOCK_TYPE_EQUALITY(PckPuk, CARD_LOCK_TYPE_PCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(RcckPuk, CARD_LOCK_TYPE_RCCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(RspckPuk, CARD_LOCK_TYPE_RSPCK_PUK); ASSERT_ICC_LOCK_TYPE_EQUALITY(Fdn, CARD_LOCK_TYPE_FDN); diff --git a/dom/icc/interfaces/nsIIccProvider.idl b/dom/icc/interfaces/nsIIccProvider.idl index 3fe645f8ae6e..94f09d05d3b1 100644 --- a/dom/icc/interfaces/nsIIccProvider.idl +++ b/dom/icc/interfaces/nsIIccProvider.idl @@ -58,7 +58,7 @@ interface nsIIccChannelCallback : nsISupports /** * XPCOM component (in the content process) that provides the ICC information. */ -[scriptable, uuid(821bda2b-7abd-44c6-813e-d4bc68d73a0c)] +[scriptable, uuid(a203cd2e-2280-4d8e-a687-42b745d322c1)] interface nsIIccProvider : nsISupports { // MUST match enum IccCardState in MozIcc.webidl! @@ -101,22 +101,26 @@ interface nsIIccProvider : nsISupports const unsigned long CARD_LOCK_TYPE_PUK = 2; const unsigned long CARD_LOCK_TYPE_PUK2 = 3; const unsigned long CARD_LOCK_TYPE_NCK = 4; - const unsigned long CARD_LOCK_TYPE_NCK1 = 5; - const unsigned long CARD_LOCK_TYPE_NCK2 = 6; - const unsigned long CARD_LOCK_TYPE_HNCK = 7; - const unsigned long CARD_LOCK_TYPE_CCK = 8; - const unsigned long CARD_LOCK_TYPE_SPCK = 9; - const unsigned long CARD_LOCK_TYPE_RCCK = 10; - const unsigned long CARD_LOCK_TYPE_RSPCK = 11; - const unsigned long CARD_LOCK_TYPE_NCK_PUK = 12; - const unsigned long CARD_LOCK_TYPE_NCK1_PUK = 13; - const unsigned long CARD_LOCK_TYPE_NCK2_PUK = 14; - const unsigned long CARD_LOCK_TYPE_HNCK_PUK = 15; - const unsigned long CARD_LOCK_TYPE_CCK_PUK = 16; - const unsigned long CARD_LOCK_TYPE_SPCK_PUK = 17; - const unsigned long CARD_LOCK_TYPE_RCCK_PUK = 18; - const unsigned long CARD_LOCK_TYPE_RSPCK_PUK = 19; - const unsigned long CARD_LOCK_TYPE_FDN = 20; + const unsigned long CARD_LOCK_TYPE_NSCK = 5; + const unsigned long CARD_LOCK_TYPE_NCK1 = 6; + const unsigned long CARD_LOCK_TYPE_NCK2 = 7; + const unsigned long CARD_LOCK_TYPE_HNCK = 8; + const unsigned long CARD_LOCK_TYPE_CCK = 9; + const unsigned long CARD_LOCK_TYPE_SPCK = 10; + const unsigned long CARD_LOCK_TYPE_PCK = 11; + const unsigned long CARD_LOCK_TYPE_RCCK = 12; + const unsigned long CARD_LOCK_TYPE_RSPCK = 13; + const unsigned long CARD_LOCK_TYPE_NCK_PUK = 14; + const unsigned long CARD_LOCK_TYPE_NSCK_PUK = 15; + const unsigned long CARD_LOCK_TYPE_NCK1_PUK = 16; + const unsigned long CARD_LOCK_TYPE_NCK2_PUK = 17; + const unsigned long CARD_LOCK_TYPE_HNCK_PUK = 18; + const unsigned long CARD_LOCK_TYPE_CCK_PUK = 19; + const unsigned long CARD_LOCK_TYPE_SPCK_PUK = 20; + const unsigned long CARD_LOCK_TYPE_PCK_PUK = 21; + const unsigned long CARD_LOCK_TYPE_RCCK_PUK = 22; + const unsigned long CARD_LOCK_TYPE_RSPCK_PUK = 23; + const unsigned long CARD_LOCK_TYPE_FDN = 24; // MUST match with enum IccContactType in MozIcc.webidl const unsigned long CARD_CONTACT_TYPE_ADN = 0; From 1585dd96b65a4434dd71a3480126f866f6b73590 Mon Sep 17 00:00:00 2001 From: Shawn Ku Date: Thu, 8 Jan 2015 11:24:31 +0800 Subject: [PATCH 163/224] Bug 1113476: RIL patch - B2G RIL: support nsck/pck for SIM Lock types. r=edgar. --- dom/system/gonk/ril_consts.js | 59 ++++++++----------- dom/system/gonk/ril_worker.js | 11 +++- .../tests/test_ril_worker_icc_CardLock.js | 26 ++------ 3 files changed, 39 insertions(+), 57 deletions(-) diff --git a/dom/system/gonk/ril_consts.js b/dom/system/gonk/ril_consts.js index 4a8bce6aab35..91baa05735f7 100644 --- a/dom/system/gonk/ril_consts.js +++ b/dom/system/gonk/ril_consts.js @@ -668,6 +668,8 @@ this.ICC_SEL_CODE_PH_SP_PIN = "PH-SP PIN"; this.ICC_SEL_CODE_PH_SP_PUK = "PH-SP PUK"; this.ICC_SEL_CODE_PH_CORP_PIN = "PH-CORP PIN"; this.ICC_SEL_CODE_PH_CORP_PUK = "PH-CORP PUK"; +// TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM @ +// ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_PCK. this.ICC_USIM_TYPE1_TAG = 0xa8; this.ICC_USIM_TYPE2_TAG = 0xa9; @@ -2611,22 +2613,26 @@ this.GECKO_CARDLOCK_PIN2 = 1; this.GECKO_CARDLOCK_PUK = 2; this.GECKO_CARDLOCK_PUK2 = 3; this.GECKO_CARDLOCK_NCK = 4; -this.GECKO_CARDLOCK_NCK1 = 5; -this.GECKO_CARDLOCK_NCK2 = 6; -this.GECKO_CARDLOCK_HNCK = 7; -this.GECKO_CARDLOCK_CCK = 8; -this.GECKO_CARDLOCK_SPCK = 9; -this.GECKO_CARDLOCK_RCCK = 10; -this.GECKO_CARDLOCK_RSPCK = 11; -this.GECKO_CARDLOCK_NCK_PUK = 12; -this.GECKO_CARDLOCK_NCK1_PUK = 13; -this.GECKO_CARDLOCK_NCK2_PUK = 14; -this.GECKO_CARDLOCK_HNCK_PUK = 15; -this.GECKO_CARDLOCK_CCK_PUK = 16; -this.GECKO_CARDLOCK_SPCK_PUK = 17; -this.GECKO_CARDLOCK_RCCK_PUK = 18; -this.GECKO_CARDLOCK_RSPCK_PUK = 19; -this.GECKO_CARDLOCK_FDN = 20; +this.GECKO_CARDLOCK_NSCK = 5; +this.GECKO_CARDLOCK_NCK1 = 6; +this.GECKO_CARDLOCK_NCK2 = 7; +this.GECKO_CARDLOCK_HNCK = 8; +this.GECKO_CARDLOCK_CCK = 9; +this.GECKO_CARDLOCK_SPCK = 10; +this.GECKO_CARDLOCK_PCK = 11; +this.GECKO_CARDLOCK_RCCK = 12; +this.GECKO_CARDLOCK_RSPCK = 13; +this.GECKO_CARDLOCK_NCK_PUK = 14; +this.GECKO_CARDLOCK_NSCK_PUK = 15; +this.GECKO_CARDLOCK_NCK1_PUK = 16; +this.GECKO_CARDLOCK_NCK2_PUK = 17; +this.GECKO_CARDLOCK_HNCK_PUK = 18; +this.GECKO_CARDLOCK_CCK_PUK = 19; +this.GECKO_CARDLOCK_SPCK_PUK = 20; +this.GECKO_CARDLOCK_PCK_PUK = 21; +this.GECKO_CARDLOCK_RCCK_PUK = 22; +this.GECKO_CARDLOCK_RSPCK_PUK = 23; +this.GECKO_CARDLOCK_FDN = 24; this.GECKO_CARDLOCK_TO_FACILITY = {}; GECKO_CARDLOCK_TO_FACILITY[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM; @@ -2638,8 +2644,11 @@ GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PIN2] = ICC_SEL_CODE_SIM_PIN2; GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK] = ICC_SEL_CODE_SIM_PUK; GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK2] = ICC_SEL_CODE_SIM_PUK2; GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NCK] = ICC_SEL_CODE_PH_NET_PIN; +GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NSCK] = ICC_SEL_CODE_PH_NETSUB_PIN; GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_CCK] = ICC_SEL_CODE_PH_CORP_PIN; GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_SPCK] = ICC_SEL_CODE_PH_SP_PIN; +// TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM @ +// ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_PCK. // See nsIIccProvider::CARD_CONTACT_TYPE_* this.GECKO_CARDCONTACT_TYPE_ADN = 0; @@ -2682,24 +2691,6 @@ PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK] = GECKO_CARDSTATE_RUIM_COR PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK] = GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED; PERSONSUBSTATE[CARD_PERSOSUBSTATE_RUIM_RUIM_PUK] = GECKO_CARDSTATE_RUIM_PUK_REQUIRED; -this.GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK = {}; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK] = CARD_PERSOSUBSTATE_SIM_NETWORK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK1] = CARD_PERSOSUBSTATE_RUIM_NETWORK1; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK2] = CARD_PERSOSUBSTATE_RUIM_NETWORK2; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_HNCK] = CARD_PERSOSUBSTATE_RUIM_HRPD; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_CCK] = CARD_PERSOSUBSTATE_SIM_CORPORATE; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_SPCK] = CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_RCCK] = CARD_PERSOSUBSTATE_RUIM_CORPORATE; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_RSPCK] = CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK_PUK] = CARD_PERSOSUBSTATE_SIM_NETWORK_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK1_PUK] = CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_NCK2_PUK] = CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_HNCK_PUK] = CARD_PERSOSUBSTATE_RUIM_HRPD_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_CCK_PUK] = CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_SPCK_PUK] = CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_RCCK_PUK] = CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK; -GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[GECKO_CARDLOCK_RSPCK_PUK] = CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK; - // See nsIMobileConnection::NETWORK_SELECTION_MODE_* this.GECKO_NETWORK_SELECTION_UNKNOWN = -1; this.GECKO_NETWORK_SELECTION_AUTOMATIC = 0; diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index c6b342040a24..bc697cb6c3bc 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -616,23 +616,25 @@ RilObject.prototype = { this.enterICCPUK2(options); break; case GECKO_CARDLOCK_NCK: + case GECKO_CARDLOCK_NSCK: case GECKO_CARDLOCK_NCK1: case GECKO_CARDLOCK_NCK2: case GECKO_CARDLOCK_HNCK: case GECKO_CARDLOCK_CCK: case GECKO_CARDLOCK_SPCK: + case GECKO_CARDLOCK_PCK: case GECKO_CARDLOCK_RCCK: case GECKO_CARDLOCK_RSPCK: case GECKO_CARDLOCK_NCK_PUK: + case GECKO_CARDLOCK_NSCK_PUK: case GECKO_CARDLOCK_NCK1_PUK: case GECKO_CARDLOCK_NCK2_PUK: case GECKO_CARDLOCK_HNCK_PUK: case GECKO_CARDLOCK_CCK_PUK: case GECKO_CARDLOCK_SPCK_PUK: + case GECKO_CARDLOCK_PCK_PUK: case GECKO_CARDLOCK_RCCK_PUK: // Fall through. case GECKO_CARDLOCK_RSPCK_PUK: - options.personlization = - GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[options.lockType]; this.enterDepersonalization(options); break; default: @@ -690,7 +692,7 @@ RilObject.prototype = { enterDepersonalization: function(options) { let Buf = this.context.Buf; Buf.newParcel(REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE, options); - Buf.writeInt32(options.personlization); + Buf.writeInt32(1); Buf.writeString(options.password); Buf.sendParcel(); }, @@ -863,8 +865,11 @@ RilObject.prototype = { case GECKO_CARDLOCK_PUK: case GECKO_CARDLOCK_PUK2: case GECKO_CARDLOCK_NCK: + case GECKO_CARDLOCK_NSCK: case GECKO_CARDLOCK_CCK: // Fall through. case GECKO_CARDLOCK_SPCK: + // TODO: Bug 1116072: identify the mapping between RIL_PERSOSUBSTATE_SIM_SIM + // @ ril.h and TS 27.007, clause 8.65 for GECKO_CARDLOCK_SPCK. options.selCode = GECKO_CARDLOCK_TO_SEL_CODE[options.lockType]; break; default: diff --git a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js index 3928a93a99f2..ba35594441f0 100644 --- a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js +++ b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js @@ -270,7 +270,7 @@ add_test(function test_icc_unlock_card_lock_depersonalization() { let ril = context.RIL; let buf = context.Buf; - function do_test(aLock, aPassword) { + function do_test(aPassword) { buf.sendParcel = function fakeSendParcel() { // Request Type. do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE); @@ -279,32 +279,18 @@ add_test(function test_icc_unlock_card_lock_depersonalization() { this.readInt32(); // Data - do_check_eq(this.readInt32(), GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock]); - do_check_eq(this.readString(), aPassword); + let parcel = this.readStringList(); + do_check_eq(parcel.length, 1); + do_check_eq(parcel[0], aPassword); }; ril.iccUnlockCardLock({ - lockType: aLock, + lockType: GECKO_CARDLOCK_NCK, password: aPassword }); } - do_test(GECKO_CARDLOCK_NCK, "12345678"); - do_test(GECKO_CARDLOCK_NCK1, "12345678"); - do_test(GECKO_CARDLOCK_NCK2, "12345678"); - do_test(GECKO_CARDLOCK_HNCK, "12345678"); - do_test(GECKO_CARDLOCK_CCK, "12345678"); - do_test(GECKO_CARDLOCK_SPCK, "12345678"); - do_test(GECKO_CARDLOCK_RCCK, "12345678"); - do_test(GECKO_CARDLOCK_RSPCK, "12345678"); - do_test(GECKO_CARDLOCK_NCK_PUK, "12345678"); - do_test(GECKO_CARDLOCK_NCK1_PUK, "12345678"); - do_test(GECKO_CARDLOCK_NCK2_PUK, "12345678"); - do_test(GECKO_CARDLOCK_HNCK_PUK, "12345678"); - do_test(GECKO_CARDLOCK_CCK_PUK, "12345678"); - do_test(GECKO_CARDLOCK_SPCK_PUK, "12345678"); - do_test(GECKO_CARDLOCK_RCCK_PUK, "12345678"); - do_test(GECKO_CARDLOCK_RSPCK_PUK, "12345678"); + do_test("12345678"); run_next_test(); }); From 5e6dc413704aacbc2d8f96e4722d38a8c18a66e8 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Wed, 7 Jan 2015 23:57:18 -0800 Subject: [PATCH 164/224] Bumping gaia.json for 1 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/d12c38494e18 Author: Kevin Grandon Desc: Revert "Bug 1115508 - [Flame][Built-in&System Keyboard]The utility bubble always shows even at lock screen." This reverts commit 168002188cce6dcbd69f10773b8b91abb5d9943b. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index fc9b05a8c4f3..48e2dd6f0c8b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "48e52543ad483405db9ae2e527cf0dd926e8b68b", + "revision": "d12c38494e18d362257d3a436451c082cfc8e9f8", "repo_path": "integration/gaia-central" } From 8ca32dd55657e0de5536400bd2e52b1a6d6815a4 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 00:01:57 -0800 Subject: [PATCH 165/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 96c5f7d9ea36..117405b7d3da 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 58e019b7bde8..c7432f8391fe 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 72b078980856..0e9c6ebfa2bd 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 77a930be4e5c..46e845776059 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 58e019b7bde8..c7432f8391fe 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 5475389c6328..f3e1ca1fbbb1 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 8240ac40a906..b1102d91049f 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 3d0ef43d3c5e..078f7f16855e 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 21f0d612c6e2..3e25597a84f6 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 2f22c0a47f88..9dc91c995164 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 a44be947f538..a305fa09c7d5 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From d0d460bb5bbdadeb2f2711c549754d4f684dbd75 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 00:12:18 -0800 Subject: [PATCH 166/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/4f1169743fcf Author: Justin D'Arcangelo Desc: Merge pull request #27207 from justindarc/bug1092966 Bug 1092966 - FM Radio app to follow text selection pattern ======== https://hg.mozilla.org/integration/gaia-central/rev/82e1f38f2d1e Author: Justin D'Arcangelo Desc: Bug 1092966 - FM Radio app to follow text selection pattern --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 48e2dd6f0c8b..a7b4221267ad 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "d12c38494e18d362257d3a436451c082cfc8e9f8", + "revision": "4f1169743fcfcecc37cd23107e0403a049bb6335", "repo_path": "integration/gaia-central" } From 0497628e68735becf3f707f106d8194d28c59f2b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 00:13:57 -0800 Subject: [PATCH 167/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 117405b7d3da..f33b76927798 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index c7432f8391fe..126ebfe5b1f4 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 0e9c6ebfa2bd..20cbaa93c95d 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 46e845776059..3de0af75f1bc 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 c7432f8391fe..126ebfe5b1f4 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index f3e1ca1fbbb1..2de7ce7bcc28 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index b1102d91049f..b6cd6771ac9d 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 078f7f16855e..b71b95253860 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 3e25597a84f6..073f5523a666 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 9dc91c995164..21b5334b16c1 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 a305fa09c7d5..aa90843ab6b8 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From bf707b103f6ac398e2f0bebe71d2eb63865c105b Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Thu, 8 Jan 2015 16:33:50 +0800 Subject: [PATCH 168/224] Bug 1115603 - Part 1: Add nsITelephonyCallInfo (interface). r=hsinyi --- dom/telephony/nsITelephonyCallInfo.idl | 73 ++++++++++++++++ dom/telephony/nsITelephonyService.idl | 111 ++++--------------------- 2 files changed, 90 insertions(+), 94 deletions(-) create mode 100644 dom/telephony/nsITelephonyCallInfo.idl diff --git a/dom/telephony/nsITelephonyCallInfo.idl b/dom/telephony/nsITelephonyCallInfo.idl new file mode 100644 index 000000000000..3561ec4e0668 --- /dev/null +++ b/dom/telephony/nsITelephonyCallInfo.idl @@ -0,0 +1,73 @@ +/* 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 "nsISupports.idl" + +[scriptable, uuid(3ea2d155-8ea2-42be-85d7-bd8ede8afc40)] +interface nsITelephonyCallInfo : nsISupports +{ + /** + * Indicate the RIL client, 0 ~ (number of client - 1). + */ + readonly attribute unsigned long clientId; + + /** + * Call identifier assigned by the RIL. + */ + readonly attribute unsigned long callIndex; + + /** + * One of the nsITelephonyService::CALL_STATE_* values. + */ + readonly attribute unsigned short callState; + + /** + * Number of the other party. + */ + readonly attribute DOMString number; + + /** + * Presentation of the call number. + * One of the nsITelephonyService::CALL_PRESENTATION_* values. + */ + readonly attribute unsigned short numberPresentation; + + /** + * Name of the other party. + */ + readonly attribute DOMString name; + + /** + * Presentation of the call name. + * One of the nsITelephonyService::CALL_PRESENTATION_* values. + */ + readonly attribute unsigned short namePresentation; + + /** + * Indicates whether this call is outgoing or incoming. + */ + readonly attribute boolean isOutgoing; + + /** + * Indicates whether this call is an emergency call. + */ + readonly attribute boolean isEmergency; + + /** + * Indicates whether this call is a conference call. + */ + readonly attribute boolean isConference; + + /** + * Indicates whether this call can be switched between states of + * nsITelephonyService::CALL_STATE_CONNECTED and + * nsITelephonyService::CALL_STATE_HELD. + */ + readonly attribute boolean isSwitchable; + + /** + * Indicates whether this call be be added into a conference. + */ + readonly attribute boolean isMergeable; +}; diff --git a/dom/telephony/nsITelephonyService.idl b/dom/telephony/nsITelephonyService.idl index 7a84cf4fb24a..f4d72d586292 100644 --- a/dom/telephony/nsITelephonyService.idl +++ b/dom/telephony/nsITelephonyService.idl @@ -5,54 +5,28 @@ #include "nsISupports.idl" interface nsIMobileCallForwardingOptions; +interface nsITelephonyCallInfo; -[scriptable, uuid(464d4cf8-454a-4cdb-9329-bfe7ede97103)] +[scriptable, uuid(3cdc0b98-0c5f-489d-9190-083d137f40da)] interface nsITelephonyListener : nsISupports { /** - * Notified when a telephony call changes state. - * - * @param clientId - Indicate the RIL client, 0 ~ (number of client - 1). - * @param callIndex - * Call identifier assigned by the RIL. - * @param callState - * One of the nsITelephonyService::CALL_STATE_* values. - * @param number - * Number of the other party. - * @param numberPresentation - * Presentation of the call number. - * One of the nsITelephonyProvider::CALL_PRESENTATION_* values. - * @param name - * Name of the other party. - * @param namePresentation - * Presentation of the call name. - * One of the nsITelephonyProvider::CALL_PRESENTATION_* values. - * @param isOutgoing - * Indicates whether this call is outgoing or incoming. - * @param isEmergency - * Indicates whether this call is an emergency call. - * @param isConference - * Indicates whether this call is a conference call. - * @param isSwitchable - * Indicates whether this call can be switched between states of - * nsITelephonyService::CALL_STATE_CONNECTED and - * nsITelephonyService::CALL_STATE_HELD. - * @param isMergeable - * Indicates whether this call be be added into a conference. + * Called when enumeration asked by nsITelephonyService::enumerateCalls + * is completed. */ - void callStateChanged(in unsigned long clientId, - in unsigned long callIndex, - in unsigned short callState, - in AString number, - in unsigned short numberPresentation, - in AString name, - in unsigned short namePresentation, - in boolean isOutgoing, - in boolean isEmergency, - in boolean isConference, - in boolean isSwitchable, - in boolean isMergeable); + void enumerateCallStateComplete(); + + /** + * Called when nsITelephonyService is asked to enumerate the current + * telephony call state (nsITelephonyService::enumerateCalls). This is + * called once per call that is currently managed by the RIL. + */ + void enumerateCallState(in nsITelephonyCallInfo info); + + /** + * Notified when a telephony call changes state. + */ + void callStateChanged(in nsITelephonyCallInfo info); /** * Called when participants of a conference call have been updated, and the @@ -65,57 +39,6 @@ interface nsITelephonyListener : nsISupports */ void conferenceCallStateChanged(in unsigned short callState); - /** - * Called when enumeration asked by nsITelephonyService::enumerateCalls - * is completed. - */ - void enumerateCallStateComplete(); - - /** - * Called when nsITelephonyService is asked to enumerate the current - * telephony call state (nsITelephonyService::enumerateCalls). This is - * called once per call that is currently managed by the RIL. - * - * @param clientId - Indicate the RIL client, 0 ~ (number of client - 1). - * @param callIndex - * Call identifier assigned by the RIL. - * @param callState - * One of the nsITelephonyService::CALL_STATE_* values. - * @param number - * Number of the other party. - * @param numberPresentation - * Presentation of the call number. - * One of the nsITelephonyProvider::CALL_PRESENTATION_* values. - * @param name - * Name of the other party. - * @param namePresentation - * Presentation of the call name. - * One of the nsITelephonyProvider::CALL_PRESENTATION_* values. - * @param isOutgoing - * Indicates whether this call is outgoing or incoming. - * @param isConference - * Indicates whether this call is a conference call. - * @param isSwitchable - * Indicates whether this call can be switched between states of - * nsITelephonyService::CALL_STATE_CONNECTED and - * nsITelephonyService::CALL_STATE_HELD. - * @param isMergeable - * Indicates whether this call be be added into a conference. - */ - void enumerateCallState(in unsigned long clientId, - in unsigned long callIndex, - in unsigned short callState, - in AString number, - in unsigned short numberPresentation, - in AString name, - in unsigned short namePresentation, - in boolean isOutgoing, - in boolean isEmergency, - in boolean isConference, - in boolean isSwitchable, - in boolean isMergeable); - /** * Notify when RIL receives supplementary service notification. * From 6ed87aa37ec45f1c8a48fed19b17a98f80c2107a Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Thu, 8 Jan 2015 16:33:51 +0800 Subject: [PATCH 169/224] Bug 1115603 - Part 2: Implement nsITelephonyCallInfo and use it (dom). r=hsinyi --- dom/telephony/Telephony.cpp | 184 +++++++++++++++------------- dom/telephony/Telephony.h | 7 ++ dom/telephony/TelephonyCallInfo.cpp | 126 +++++++++++++++++++ dom/telephony/TelephonyCallInfo.h | 53 ++++++++ dom/telephony/moz.build | 3 + 5 files changed, 287 insertions(+), 86 deletions(-) create mode 100644 dom/telephony/TelephonyCallInfo.cpp create mode 100644 dom/telephony/TelephonyCallInfo.h diff --git a/dom/telephony/Telephony.cpp b/dom/telephony/Telephony.cpp index 774b81f7fde9..cd61702bcb79 100644 --- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -235,6 +235,22 @@ Telephony::DialInternal(uint32_t aServiceId, const nsAString& aNumber, return promise.forget(); } +already_AddRefed +Telephony::CreateCallId(nsITelephonyCallInfo *aInfo) +{ + nsAutoString number; + nsAutoString name; + uint16_t numberPresentation; + uint16_t namePresentation; + + aInfo->GetNumber(number); + aInfo->GetName(name); + aInfo->GetNumberPresentation(&numberPresentation); + aInfo->GetNamePresentation(&namePresentation); + + return CreateCallId(number, numberPresentation, name, namePresentation); +} + already_AddRefed Telephony::CreateCallId(const nsAString& aNumber, uint16_t aNumberPresentation, const nsAString& aName, uint16_t aNamePresentation) @@ -310,6 +326,81 @@ Telephony::GetCallFromEverywhere(uint32_t aServiceId, uint32_t aCallIndex) return call.forget(); } +nsresult +Telephony::HandleCallInfo(nsITelephonyCallInfo* aInfo) +{ + uint32_t serviceId; + uint32_t callIndex; + uint16_t callState; + bool isEmergency; + bool isConference; + bool isSwitchable; + bool isMergeable; + + aInfo->GetClientId(&serviceId); + aInfo->GetCallIndex(&callIndex); + aInfo->GetCallState(&callState); + aInfo->GetIsEmergency(&isEmergency); + aInfo->GetIsConference(&isConference); + aInfo->GetIsSwitchable(&isSwitchable); + aInfo->GetIsMergeable(&isMergeable); + + nsRefPtr call = GetCallFromEverywhere(serviceId, callIndex); + + if (!call) { + nsRefPtr id = CreateCallId(aInfo); + call = CreateCall(id, serviceId, callIndex, callState, isEmergency, + isConference, isSwitchable, isMergeable); + + if (call && callState == nsITelephonyService::CALL_STATE_INCOMING) { + nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("incoming"), call); + NS_ENSURE_SUCCESS(rv, rv); + } + } else { + call->UpdateEmergency(isEmergency); + call->UpdateSwitchable(isSwitchable); + call->UpdateMergeable(isMergeable); + + nsAutoString number; + aInfo->GetNumber(number); + nsRefPtr id = call->Id(); + id->UpdateNumber(number); + + // State changed. + if (call->CallState() != callState) { + if (callState == nsITelephonyService::CALL_STATE_DISCONNECTED) { + call->ChangeStateInternal(callState, true); + return NS_OK; + } + + // We don't fire the statechange event on a call in conference here. + // Instead, the event will be fired later in + // TelephonyCallGroup::ChangeState(). Thus the sequence of firing the + // statechange events is guaranteed: first on TelephonyCallGroup then on + // individual TelephonyCall objects. + bool fireEvent = !isConference; + call->ChangeStateInternal(callState, fireEvent); + } + + // Group changed. + nsRefPtr group = call->GetGroup(); + + if (!group && isConference) { + // Add to conference. + NS_ASSERTION(mCalls.Contains(call), "Should in mCalls"); + mGroup->AddCall(call); + RemoveCall(call); + } else if (group && !isConference) { + // Remove from conference. + NS_ASSERTION(mGroup->CallsArray().Contains(call), "Should in mGroup"); + mGroup->RemoveCall(call); + AddCall(call); + } + } + + return NS_OK; +} + NS_IMPL_CYCLE_COLLECTION_CLASS(Telephony) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony, @@ -508,67 +599,15 @@ Telephony::GetReady(ErrorResult& aRv) const // nsITelephonyListener NS_IMETHODIMP -Telephony::CallStateChanged(uint32_t aServiceId, uint32_t aCallIndex, - uint16_t aCallState, const nsAString& aNumber, - uint16_t aNumberPresentation, const nsAString& aName, - uint16_t aNamePresentation, bool aIsOutgoing, - bool aIsEmergency, bool aIsConference, - bool aIsSwitchable, bool aIsMergeable) +Telephony::CallStateChanged(nsITelephonyCallInfo* aInfo) { - nsRefPtr modifiedCall - = GetCallFromEverywhere(aServiceId, aCallIndex); + return HandleCallInfo(aInfo); +} - if (modifiedCall) { - modifiedCall->UpdateEmergency(aIsEmergency); - modifiedCall->UpdateSwitchable(aIsSwitchable); - modifiedCall->UpdateMergeable(aIsMergeable); - nsRefPtr id = modifiedCall->Id(); - id->UpdateNumber(aNumber); - - if (modifiedCall->CallState() != aCallState) { - if (aCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) { - modifiedCall->ChangeStateInternal(aCallState, true); - return NS_OK; - } - - // We don't fire the statechange event on a call in conference here. - // Instead, the event will be fired later in - // TelephonyCallGroup::ChangeState(). Thus the sequence of firing the - // statechange events is guaranteed: first on TelephonyCallGroup then on - // individual TelephonyCall objects. - bool fireEvent = !aIsConference; - modifiedCall->ChangeStateInternal(aCallState, fireEvent); - } - - nsRefPtr group = modifiedCall->GetGroup(); - - if (!group && aIsConference) { - // Add to conference. - NS_ASSERTION(mCalls.Contains(modifiedCall), "Should in mCalls"); - mGroup->AddCall(modifiedCall); - RemoveCall(modifiedCall); - } else if (group && !aIsConference) { - // Remove from conference. - NS_ASSERTION(mGroup->CallsArray().Contains(modifiedCall), "Should in mGroup"); - mGroup->RemoveCall(modifiedCall); - AddCall(modifiedCall); - } - - return NS_OK; - } - - nsRefPtr id = CreateCallId(aNumber, aNumberPresentation, - aName, aNamePresentation); - nsRefPtr call = - CreateCall(id, aServiceId, aCallIndex, aCallState, - aIsEmergency, aIsConference, aIsSwitchable, aIsMergeable); - - if (call && aCallState == nsITelephonyService::CALL_STATE_INCOMING) { - nsresult rv = DispatchCallEvent(NS_LITERAL_STRING("incoming"), call); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; +NS_IMETHODIMP +Telephony::EnumerateCallState(nsITelephonyCallInfo* aInfo) +{ + return HandleCallInfo(aInfo); } NS_IMETHODIMP @@ -606,33 +645,6 @@ Telephony::EnumerateCallStateComplete() return NS_OK; } -NS_IMETHODIMP -Telephony::EnumerateCallState(uint32_t aServiceId, uint32_t aCallIndex, - uint16_t aCallState, const nsAString& aNumber, - uint16_t aNumberPresentation, const nsAString& aName, - uint16_t aNamePresentation, bool aIsOutgoing, - bool aIsEmergency, bool aIsConference, - bool aIsSwitchable, bool aIsMergeable) -{ - // We request calls enumeration in constructor, and the asynchronous result - // will be sent back through the callback function EnumerateCallState(). - // However, it is likely to have call state changes, i.e. CallStateChanged() - // being called, before the enumeration result comes back. We'd make sure - // we don't somehow add duplicates due to the race condition. - nsRefPtr call = GetCallFromEverywhere(aServiceId, aCallIndex); - if (call) { - return NS_OK; - } - - // Didn't know anything about this call before now. - nsRefPtr id = CreateCallId(aNumber, aNumberPresentation, - aName, aNamePresentation); - call = CreateCall(id, aServiceId, aCallIndex, aCallState, - aIsEmergency, aIsConference, aIsSwitchable, aIsMergeable); - - return NS_OK; -} - NS_IMETHODIMP Telephony::SupplementaryServiceNotification(uint32_t aServiceId, int32_t aCallIndex, diff --git a/dom/telephony/Telephony.h b/dom/telephony/Telephony.h index 0c8d08bb985b..3e54d8edcc2e 100644 --- a/dom/telephony/Telephony.h +++ b/dom/telephony/Telephony.h @@ -11,6 +11,7 @@ #include "mozilla/dom/Promise.h" #include "mozilla/dom/telephony/TelephonyCommon.h" +#include "nsITelephonyCallInfo.h" #include "nsITelephonyService.h" // Need to include TelephonyCall.h because we have inline methods that @@ -182,6 +183,9 @@ private: DialInternal(uint32_t aServiceId, const nsAString& aNumber, bool aEmergency, ErrorResult& aRv); + already_AddRefed + CreateCallId(nsITelephonyCallInfo *aInfo); + already_AddRefed CreateCallId(const nsAString& aNumber, uint16_t aNumberPresentation = nsITelephonyService::CALL_PRESENTATION_ALLOWED, @@ -208,6 +212,9 @@ private: already_AddRefed GetCallFromEverywhere(uint32_t aServiceId, uint32_t aCallIndex); + + nsresult + HandleCallInfo(nsITelephonyCallInfo* aInfo); }; } // namespace dom diff --git a/dom/telephony/TelephonyCallInfo.cpp b/dom/telephony/TelephonyCallInfo.cpp new file mode 100644 index 000000000000..2bd220448975 --- /dev/null +++ b/dom/telephony/TelephonyCallInfo.cpp @@ -0,0 +1,126 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/telephony/TelephonyCallInfo.h" + +namespace mozilla { +namespace dom { +namespace telephony { + +NS_IMPL_ISUPPORTS(TelephonyCallInfo, nsITelephonyCallInfo) + +TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId, + uint32_t aCallIndex, + uint16_t aCallState, + const nsAString& aNumber, + uint16_t aNumberPresentation, + const nsAString& aName, + uint16_t aNamePresentation, + bool aIsOutgoing, + bool aIsEmergency, + bool aIsConference, + bool aIsSwitchable, + bool aIsMergeable) + : mClientId(aClientId), + mCallIndex(aCallIndex), + mCallState(aCallState), + mNumber(aNumber), + mNumberPresentation(aNumberPresentation), + mName(aName), + mNamePresentation(aNamePresentation), + mIsOutgoing(aIsOutgoing), + mIsEmergency(aIsEmergency), + mIsConference(aIsConference), + mIsSwitchable(aIsSwitchable), + mIsMergeable(aIsMergeable) +{ +} + +NS_IMETHODIMP +TelephonyCallInfo::GetClientId(uint32_t* aClientId) +{ + *aClientId = mClientId; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetCallIndex(uint32_t* aCallIndex) +{ + *aCallIndex = mCallIndex; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetCallState(uint16_t* aCallState) +{ + *aCallState = mCallState; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetNumber(nsAString& aNumber) +{ + aNumber = mNumber; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetNumberPresentation(uint16_t* aNumberPresentation) +{ + *aNumberPresentation = mNumberPresentation; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetName(nsAString& aName) +{ + aName = mName; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetNamePresentation(uint16_t* aNamePresentation) +{ + *aNamePresentation = mNamePresentation; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetIsOutgoing(bool* aIsOutgoing) +{ + *aIsOutgoing = mIsOutgoing; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetIsEmergency(bool* aIsEmergency) +{ + *aIsEmergency = mIsEmergency; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetIsConference(bool* aIsConference) +{ + *aIsConference = mIsConference; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetIsSwitchable(bool* aIsSwitchable) +{ + *aIsSwitchable = mIsSwitchable; + return NS_OK; +} + +NS_IMETHODIMP +TelephonyCallInfo::GetIsMergeable(bool* aIsMergeable) +{ + *aIsMergeable = mIsMergeable; + return NS_OK; +} + +} // namespace telephony +} // namespace dom +} // namespace mozilla diff --git a/dom/telephony/TelephonyCallInfo.h b/dom/telephony/TelephonyCallInfo.h new file mode 100644 index 000000000000..4f6dc40dc8c6 --- /dev/null +++ b/dom/telephony/TelephonyCallInfo.h @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_TelephonyCallInfo_h +#define mozilla_dom_TelephonyCallInfo_h + +#include "nsITelephonyCallInfo.h" +#include "nsString.h" +#include "mozilla/Attributes.h" + +namespace mozilla { +namespace dom { +namespace telephony { + +class TelephonyCallInfo MOZ_FINAL : public nsITelephonyCallInfo +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITELEPHONYCALLINFO + + TelephonyCallInfo(uint32_t aClientId, uint32_t aCallIndex, + uint16_t aCallState, const nsAString& aNumber, + uint16_t aNumberPresentation, const nsAString& aName, + uint16_t aNamePresentation, bool aIsOutgoing, + bool aIsEmergency, bool aIsConference, + bool aIsSwitchable, bool aIsMergeable); + +private: + // Don't try to use the default constructor. + TelephonyCallInfo() {} + + ~TelephonyCallInfo() {} + + uint32_t mClientId; + uint32_t mCallIndex; + uint16_t mCallState; + nsString mNumber; + uint16_t mNumberPresentation; + nsString mName; + uint16_t mNamePresentation; + bool mIsOutgoing; + bool mIsEmergency; + bool mIsConference; + bool mIsSwitchable; + bool mIsMergeable; +}; + +} // namespace telephony +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_TelephonyCallInfo_h diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index 9edcd35264cf..a05167c8ec3d 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -5,6 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPIDL_SOURCES += [ + 'nsITelephonyCallInfo.idl', 'nsITelephonyService.idl', ] @@ -24,6 +25,7 @@ EXPORTS.mozilla.dom.telephony += [ 'ipc/TelephonyChild.h', 'ipc/TelephonyParent.h', 'TelephonyCallback.h', + 'TelephonyCallInfo.h', 'TelephonyCommon.h', 'TelephonyDialCallback.h', ] @@ -39,6 +41,7 @@ UNIFIED_SOURCES += [ 'TelephonyCallback.cpp', 'TelephonyCallGroup.cpp', 'TelephonyCallId.cpp', + 'TelephonyCallInfo.cpp', 'TelephonyDialCallback.cpp', 'USSDSession.cpp', ] From 40e2fdb7520a3d684277571b0baf82491abe928b Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Thu, 8 Jan 2015 16:33:51 +0800 Subject: [PATCH 170/224] Bug 1115603 - Part 3: Implement nsITelephonyCallInfo and use it (ril). r=hsinyi --- dom/telephony/gonk/TelephonyService.js | 78 ++++++++++++++++---------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/dom/telephony/gonk/TelephonyService.js b/dom/telephony/gonk/TelephonyService.js index 04a117389bf2..4f926f1234ea 100644 --- a/dom/telephony/gonk/TelephonyService.js +++ b/dom/telephony/gonk/TelephonyService.js @@ -20,10 +20,13 @@ XPCOMUtils.defineLazyGetter(this, "RIL", function () { const GONK_TELEPHONYSERVICE_CONTRACTID = "@mozilla.org/telephony/gonktelephonyservice;1"; + const GONK_TELEPHONYSERVICE_CID = Components.ID("{67d26434-d063-4d28-9f48-5b3189788155}"); const MOBILECALLFORWARDINGOPTIONS_CID = Components.ID("{79b5988b-9436-48d8-a652-88fa033f146c}"); +const TELEPHONYCALLINFO_CID = + Components.ID("{d9e8b358-a02c-4cf3-9fc7-816c2e8d46e4}"); const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown"; @@ -114,6 +117,45 @@ MobileCallForwardingOptions.prototype = { serviceClass: Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE }; +function TelephonyCallInfo(aCall) { + this.clientId = aCall.clientId; + this.callIndex = aCall.callIndex; + this.callState = aCall.state; + this.number = aCall.number; + this.numberPresentation = aCall.numberPresentation; + this.name = aCall.name; + this.namePresentation = aCall.namePresentation; + this.isOutgoing = aCall.isOutgoing; + this.isEmergency = aCall.isEmergency; + this.isConference = aCall.isConference; + this.isSwitchable = aCall.isSwitchable; + this.isMergeable = aCall.isMergeable; +} +TelephonyCallInfo.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyCallInfo]), + classID: TELEPHONYCALLINFO_CID, + classInfo: XPCOMUtils.generateCI({ + classID: TELEPHONYCALLINFO_CID, + classDescription: "TelephonyCallInfo", + interfaces: [Ci.nsITelephonyCallInfo] + }), + + // nsITelephonyCallInfo + + clientId: 0, + callIndex: 0, + callState: nsITelephonyService.CALL_STATE_UNKNOWN, + number: "", + numberPresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED, + name: "", + namePresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED, + isOutgoing: true, + isEmergency: false, + isConference: false, + isSwitchable: true, + isMergeable: true +}; + function TelephonyService() { this._numClients = gRadioInterfaceLayer.numRadioInterfaces; this._listeners = []; @@ -383,12 +425,8 @@ TelephonyService.prototype = { } for (let i = 0, indexes = Object.keys(calls); i < indexes.length; ++i) { let call = calls[indexes[i]]; - aListener.enumerateCallState(call.clientId, call.callIndex, - call.state, call.number, - call.numberPresentation, call.name, - call.namePresentation, call.isOutgoing, - call.isEmergency, call.isConference, - call.isSwitchable, call.isMergeable); + let callInfo = new TelephonyCallInfo(call); + aListener.enumerateCallState(callInfo); } } aListener.enumerateCallStateComplete(); @@ -1189,18 +1227,8 @@ TelephonyService.prototype = { if (!aCall.failCause || aCall.failCause === RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) { - this._notifyAllListeners("callStateChanged", [aClientId, - aCall.callIndex, - aCall.state, - aCall.number, - aCall.numberPresentation, - aCall.name, - aCall.namePresentation, - aCall.isOutgoing, - aCall.isEmergency, - aCall.isConference, - aCall.isSwitchable, - aCall.isMergeable]); + let callInfo = new TelephonyCallInfo(aCall); + this._notifyAllListeners("callStateChanged", [callInfo]); } else { this._notifyAllListeners("notifyError", [aClientId, aCall.callIndex, aCall.failCause]); @@ -1276,18 +1304,8 @@ TelephonyService.prototype = { this._cachedDialRequest = null; } - this._notifyAllListeners("callStateChanged", [aClientId, - call.callIndex, - call.state, - call.number, - call.numberPresentation, - call.name, - call.namePresentation, - call.isOutgoing, - call.isEmergency, - call.isConference, - call.isSwitchable, - call.isMergeable]); + let callInfo = new TelephonyCallInfo(call); + this._notifyAllListeners("callStateChanged", [callInfo]); }, notifyCdmaCallWaiting: function(aClientId, aCall) { From 741ad71bdd0acb2d54bf805df75810e4cfaa1ab3 Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Thu, 8 Jan 2015 16:33:51 +0800 Subject: [PATCH 171/224] Bug 1115603 - Part 4: Use nsITelephonyCallInfo for call data (bluetooth). r=btian --- dom/bluetooth/BluetoothRilListener.cpp | 59 +++++++++++-------------- dom/bluetooth/BluetoothRilListener.h | 4 ++ dom/bluetooth2/BluetoothRilListener.cpp | 58 +++++++++++------------- dom/bluetooth2/BluetoothRilListener.h | 3 ++ 4 files changed, 60 insertions(+), 64 deletions(-) diff --git a/dom/bluetooth/BluetoothRilListener.cpp b/dom/bluetooth/BluetoothRilListener.cpp index bc2892f5b9b2..cfade813bfb3 100644 --- a/dom/bluetooth/BluetoothRilListener.cpp +++ b/dom/bluetooth/BluetoothRilListener.cpp @@ -10,6 +10,7 @@ #include "nsIIccProvider.h" #include "nsIMobileConnectionInfo.h" #include "nsIMobileConnectionService.h" +#include "nsITelephonyCallInfo.h" #include "nsITelephonyService.h" #include "nsRadioInterfaceLayer.h" // For NS_RILCONTENTHELPER_CONTRACTID. #include "nsServiceManagerUtils.h" @@ -186,48 +187,42 @@ MobileConnectionListener::Listen(bool aStart) */ NS_IMPL_ISUPPORTS(TelephonyListener, nsITelephonyListener) -NS_IMETHODIMP -TelephonyListener::CallStateChanged(uint32_t aServiceId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +/** + * @param aSend A boolean indicates whether we need to notify headset or not + */ +nsresult +TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend) { BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); - hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, - aIsOutgoing, aIsConference, true); + uint32_t callIndex; + uint16_t callState; + nsAutoString number; + bool isOutgoing; + bool isConference; + + aInfo->GetCallIndex(&callIndex); + aInfo->GetCallState(&callState); + aInfo->GetNumber(number); + aInfo->GetIsOutgoing(&isOutgoing); + aInfo->GetIsConference(&isConference); + + hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number, + isOutgoing, isConference, aSend); return NS_OK; } NS_IMETHODIMP -TelephonyListener::EnumerateCallState(uint32_t aServiceId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString_internal& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyListener::CallStateChanged(nsITelephonyCallInfo* aInfo) { - BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); - NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + return HandleCallInfo(aInfo, true); +} - hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, - aIsOutgoing, aIsConference, false); - return NS_OK; +NS_IMETHODIMP +TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo) +{ + return HandleCallInfo(aInfo, false); } NS_IMETHODIMP diff --git a/dom/bluetooth/BluetoothRilListener.h b/dom/bluetooth/BluetoothRilListener.h index e9ca6bbe2a49..11ce91173c44 100644 --- a/dom/bluetooth/BluetoothRilListener.h +++ b/dom/bluetooth/BluetoothRilListener.h @@ -13,6 +13,7 @@ #include "nsIIccProvider.h" #include "nsIMobileConnectionService.h" +#include "nsITelephonyCallInfo.h" #include "nsITelephonyService.h" BEGIN_BLUETOOTH_NAMESPACE @@ -61,6 +62,9 @@ public: virtual ~TelephonyListener() { } bool Listen(bool aStart); + +private: + nsresult HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend); }; class BluetoothRilListener diff --git a/dom/bluetooth2/BluetoothRilListener.cpp b/dom/bluetooth2/BluetoothRilListener.cpp index bc2892f5b9b2..f6237480ecfe 100644 --- a/dom/bluetooth2/BluetoothRilListener.cpp +++ b/dom/bluetooth2/BluetoothRilListener.cpp @@ -186,48 +186,42 @@ MobileConnectionListener::Listen(bool aStart) */ NS_IMPL_ISUPPORTS(TelephonyListener, nsITelephonyListener) -NS_IMETHODIMP -TelephonyListener::CallStateChanged(uint32_t aServiceId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +/** + * @param aSend A boolean indicates whether we need to notify headset or not + */ +nsresult +TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend) { BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); - hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, - aIsOutgoing, aIsConference, true); + uint32_t callIndex; + uint16_t callState; + nsAutoString number; + bool isOutgoing; + bool isConference; + + aInfo->GetCallIndex(&callIndex); + aInfo->GetCallState(&callState); + aInfo->GetNumber(number); + aInfo->GetIsOutgoing(&isOutgoing); + aInfo->GetIsConference(&isConference); + + hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number, + isOutgoing, isConference, aSend); return NS_OK; } NS_IMETHODIMP -TelephonyListener::EnumerateCallState(uint32_t aServiceId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString_internal& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyListener::CallStateChanged(nsITelephonyCallInfo* aInfo) { - BluetoothHfpManager* hfp = BluetoothHfpManager::Get(); - NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE); + return HandleCallInfo(aInfo, true); +} - hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber, - aIsOutgoing, aIsConference, false); - return NS_OK; +NS_IMETHODIMP +TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo) +{ + return HandleCallInfo(aInfo, false); } NS_IMETHODIMP diff --git a/dom/bluetooth2/BluetoothRilListener.h b/dom/bluetooth2/BluetoothRilListener.h index e9ca6bbe2a49..7cc6e52f0176 100644 --- a/dom/bluetooth2/BluetoothRilListener.h +++ b/dom/bluetooth2/BluetoothRilListener.h @@ -61,6 +61,9 @@ public: virtual ~TelephonyListener() { } bool Listen(bool aStart); + +private: + nsresult HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend); }; class BluetoothRilListener From 61bc77de22f8baa82d84fb0a6be3eeb3f050adeb Mon Sep 17 00:00:00 2001 From: "Szu-Yu Chen [:aknow]" Date: Thu, 8 Jan 2015 16:33:51 +0800 Subject: [PATCH 172/224] Bug 1115603 - Part 5: Add serializer for nsITelephonyCallInfo (ipc). r=khuey --- dom/telephony/ipc/PTelephony.ipdl | 4 +- dom/telephony/ipc/PTelephonyRequest.ipdl | 4 +- dom/telephony/ipc/TelephonyChild.cpp | 42 +++---- dom/telephony/ipc/TelephonyChild.h | 9 +- dom/telephony/ipc/TelephonyIPCSerializer.h | 132 +++++++++++++++++++++ dom/telephony/ipc/TelephonyIPCService.cpp | 33 +----- dom/telephony/ipc/TelephonyParent.cpp | 65 +--------- dom/telephony/ipc/TelephonyTypes.ipdlh | 15 --- dom/telephony/moz.build | 1 + 9 files changed, 168 insertions(+), 137 deletions(-) create mode 100644 dom/telephony/ipc/TelephonyIPCSerializer.h diff --git a/dom/telephony/ipc/PTelephony.ipdl b/dom/telephony/ipc/PTelephony.ipdl index 862e668f0a29..daa9f5ca4d46 100644 --- a/dom/telephony/ipc/PTelephony.ipdl +++ b/dom/telephony/ipc/PTelephony.ipdl @@ -8,6 +8,8 @@ include protocol PContent; include protocol PTelephonyRequest; include TelephonyTypes; +using nsTelephonyCallInfo from "mozilla/dom/telephony/TelephonyIPCSerializer.h"; + namespace mozilla { namespace dom { namespace telephony { @@ -100,7 +102,7 @@ sync protocol PTelephony { child: NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError); - NotifyCallStateChanged(uint32_t aClientId, IPCCallStateData aData); + NotifyCallStateChanged(nsTelephonyCallInfo aInfo); NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData); diff --git a/dom/telephony/ipc/PTelephonyRequest.ipdl b/dom/telephony/ipc/PTelephonyRequest.ipdl index 29da2edaaddf..0e4c86a3666b 100644 --- a/dom/telephony/ipc/PTelephonyRequest.ipdl +++ b/dom/telephony/ipc/PTelephonyRequest.ipdl @@ -7,6 +7,8 @@ include protocol PTelephony; include TelephonyTypes; +using nsTelephonyCallInfo from "mozilla/dom/telephony/TelephonyIPCSerializer.h"; + namespace mozilla { namespace dom { namespace telephony { @@ -64,7 +66,7 @@ protocol PTelephonyRequest manager PTelephony; child: - NotifyEnumerateCallState(uint32_t aClientId, IPCCallStateData aData); + NotifyEnumerateCallState(nsTelephonyCallInfo aInfo); NotifyDialMMI(nsString aServiceCode); diff --git a/dom/telephony/ipc/TelephonyChild.cpp b/dom/telephony/ipc/TelephonyChild.cpp index ff6727e752de..e5b1d9a7b27b 100644 --- a/dom/telephony/ipc/TelephonyChild.cpp +++ b/dom/telephony/ipc/TelephonyChild.cpp @@ -58,23 +58,16 @@ TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId, } bool -TelephonyChild::RecvNotifyCallStateChanged(const uint32_t& aClientId, - const IPCCallStateData& aData) +TelephonyChild::RecvNotifyCallStateChanged(nsITelephonyCallInfo* const& aInfo) { + // Use dont_AddRef here because this instances has already been AddRef-ed in + // TelephonyIPCSerializer.h + nsCOMPtr info = dont_AddRef(aInfo); + MOZ_ASSERT(mService); - mService->CallStateChanged(aClientId, - aData.callIndex(), - aData.callState(), - aData.number(), - aData.numberPresentation(), - aData.name(), - aData.namePresentation(), - aData.isOutGoing(), - aData.isEmergency(), - aData.isConference(), - aData.isSwitchable(), - aData.isMergeable()); + mService->CallStateChanged(aInfo); + return true; } @@ -165,23 +158,16 @@ TelephonyRequestChild::Recv__delete__(const IPCTelephonyResponse& aResponse) } bool -TelephonyRequestChild::RecvNotifyEnumerateCallState(const uint32_t& aClientId, - const IPCCallStateData& aData) +TelephonyRequestChild::RecvNotifyEnumerateCallState(nsITelephonyCallInfo* const& aInfo) { + // Use dont_AddRef here because this instances has already been AddRef-ed in + // TelephonyIPCSerializer.h + nsCOMPtr info = dont_AddRef(aInfo); + MOZ_ASSERT(mListener); - mListener->EnumerateCallState(aClientId, - aData.callIndex(), - aData.callState(), - aData.number(), - aData.numberPresentation(), - aData.name(), - aData.namePresentation(), - aData.isOutGoing(), - aData.isEmergency(), - aData.isConference(), - aData.isSwitchable(), - aData.isMergeable()); + mListener->EnumerateCallState(aInfo); + return true; } diff --git a/dom/telephony/ipc/TelephonyChild.h b/dom/telephony/ipc/TelephonyChild.h index eaee17ff30f7..896e524f48da 100644 --- a/dom/telephony/ipc/TelephonyChild.h +++ b/dom/telephony/ipc/TelephonyChild.h @@ -6,9 +6,10 @@ #ifndef mozilla_dom_telephony_TelephonyChild_h #define mozilla_dom_telephony_TelephonyChild_h -#include "mozilla/dom/telephony/TelephonyCommon.h" #include "mozilla/dom/telephony/PTelephonyChild.h" #include "mozilla/dom/telephony/PTelephonyRequestChild.h" +#include "mozilla/dom/telephony/TelephonyCommon.h" +#include "nsITelephonyCallInfo.h" #include "nsITelephonyService.h" BEGIN_TELEPHONY_NAMESPACE @@ -37,8 +38,7 @@ protected: const nsString& aError) MOZ_OVERRIDE; virtual bool - RecvNotifyCallStateChanged(const uint32_t& aClientId, - const IPCCallStateData& aData) MOZ_OVERRIDE; + RecvNotifyCallStateChanged(nsITelephonyCallInfo* const& aInfo) MOZ_OVERRIDE; virtual bool RecvNotifyCdmaCallWaiting(const uint32_t& aClientId, @@ -76,8 +76,7 @@ protected: Recv__delete__(const IPCTelephonyResponse& aResponse) MOZ_OVERRIDE; virtual bool - RecvNotifyEnumerateCallState(const uint32_t& aClientId, - const IPCCallStateData& aData) MOZ_OVERRIDE; + RecvNotifyEnumerateCallState(nsITelephonyCallInfo* const& aInfo) MOZ_OVERRIDE; virtual bool RecvNotifyDialMMI(const nsString& aServiceCode) MOZ_OVERRIDE; diff --git a/dom/telephony/ipc/TelephonyIPCSerializer.h b/dom/telephony/ipc/TelephonyIPCSerializer.h new file mode 100644 index 000000000000..08d5928a81c0 --- /dev/null +++ b/dom/telephony/ipc/TelephonyIPCSerializer.h @@ -0,0 +1,132 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_telephony_TelephonyIPCSerializer_h +#define mozilla_dom_telephony_TelephonyIPCSerializer_h + +#include "ipc/IPCMessageUtils.h" +#include "mozilla/dom/telephony/TelephonyCallInfo.h" +#include "nsITelephonyCallInfo.h" + +using mozilla::AutoJSContext; +using mozilla::dom::telephony::TelephonyCallInfo; + +typedef nsITelephonyCallInfo* nsTelephonyCallInfo; + +namespace IPC { + +/** + * nsITelephonyCallInfo Serialize/De-serialize. + */ +template <> +struct ParamTraits +{ + typedef nsITelephonyCallInfo* paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + bool isNull = !aParam; + WriteParam(aMsg, isNull); + // If it is a null object, then we are done. + if (isNull) { + return; + } + + uint32_t clientId; + uint32_t callIndex; + uint16_t callState; + nsString number; + uint16_t numberPresentation; + nsString name; + uint16_t namePresentation; + bool isOutgoing; + bool isEmergency; + bool isConference; + bool isSwitchable; + bool isMergeable; + + aParam->GetClientId(&clientId); + aParam->GetCallIndex(&callIndex); + aParam->GetCallState(&callState); + aParam->GetNumber(number); + aParam->GetNumberPresentation(&numberPresentation); + aParam->GetName(name); + aParam->GetNamePresentation(&namePresentation); + aParam->GetIsOutgoing(&isOutgoing); + aParam->GetIsEmergency(&isEmergency); + aParam->GetIsConference(&isConference); + aParam->GetIsSwitchable(&isSwitchable); + aParam->GetIsMergeable(&isMergeable); + + WriteParam(aMsg, clientId); + WriteParam(aMsg, callIndex); + WriteParam(aMsg, callState); + WriteParam(aMsg, number); + WriteParam(aMsg, numberPresentation); + WriteParam(aMsg, name); + WriteParam(aMsg, namePresentation); + WriteParam(aMsg, isOutgoing); + WriteParam(aMsg, isEmergency); + WriteParam(aMsg, isConference); + WriteParam(aMsg, isSwitchable); + WriteParam(aMsg, isMergeable); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + // Check if is the null pointer we have transfered. + bool isNull; + if (!ReadParam(aMsg, aIter, &isNull)) { + return false; + } + + if (isNull) { + *aResult = nullptr; + return true; + } + + uint32_t clientId; + uint32_t callIndex; + uint16_t callState; + nsString number; + uint16_t numberPresentation; + nsString name; + uint16_t namePresentation; + bool isOutgoing; + bool isEmergency; + bool isConference; + bool isSwitchable; + bool isMergeable; + + // It's not important to us where it fails, but rather if it fails + if (!(ReadParam(aMsg, aIter, &clientId) && + ReadParam(aMsg, aIter, &callIndex) && + ReadParam(aMsg, aIter, &callState) && + ReadParam(aMsg, aIter, &number) && + ReadParam(aMsg, aIter, &numberPresentation) && + ReadParam(aMsg, aIter, &name) && + ReadParam(aMsg, aIter, &namePresentation) && + ReadParam(aMsg, aIter, &isOutgoing) && + ReadParam(aMsg, aIter, &isEmergency) && + ReadParam(aMsg, aIter, &isConference) && + ReadParam(aMsg, aIter, &isSwitchable) && + ReadParam(aMsg, aIter, &isMergeable))) { + return false; + } + + nsCOMPtr info = + new TelephonyCallInfo(clientId, callIndex, callState, number, + numberPresentation, name, namePresentation, + isOutgoing, isEmergency, isConference, + isSwitchable, isMergeable); + + info.forget(aResult); + + return true; + } +}; + + +} // namespace IPC + +#endif // mozilla_dom_telephony_TelephonyIPCSerializer_h diff --git a/dom/telephony/ipc/TelephonyIPCService.cpp b/dom/telephony/ipc/TelephonyIPCService.cpp index 69dd58457659..e0ad5825563e 100644 --- a/dom/telephony/ipc/TelephonyIPCService.cpp +++ b/dom/telephony/ipc/TelephonyIPCService.cpp @@ -9,6 +9,8 @@ #include "mozilla/dom/telephony/TelephonyChild.h" #include "mozilla/Preferences.h" +#include "nsITelephonyCallInfo.h" + USING_TELEPHONY_NAMESPACE using namespace mozilla::dom; @@ -384,24 +386,10 @@ TelephonyIPCService::SetSpeakerEnabled(bool aEnabled) // nsITelephonyListener NS_IMETHODIMP -TelephonyIPCService::CallStateChanged(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyIPCService::CallStateChanged(nsITelephonyCallInfo* aInfo) { for (uint32_t i = 0; i < mListeners.Length(); i++) { - mListeners[i]->CallStateChanged(aClientId, aCallIndex, aCallState, aNumber, - aNumberPresentation, aName, aNamePresentation, - aIsOutgoing, aIsEmergency, aIsConference, - aIsSwitchable, aIsMergeable); + mListeners[i]->CallStateChanged(aInfo); } return NS_OK; } @@ -422,18 +410,7 @@ TelephonyIPCService::EnumerateCallStateComplete() } NS_IMETHODIMP -TelephonyIPCService::EnumerateCallState(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyIPCService::EnumerateCallState(nsITelephonyCallInfo* aInfo) { MOZ_CRASH("Not a EnumerateCalls request!"); } diff --git a/dom/telephony/ipc/TelephonyParent.cpp b/dom/telephony/ipc/TelephonyParent.cpp index 82217ae54cdb..70fce4ecd690 100644 --- a/dom/telephony/ipc/TelephonyParent.cpp +++ b/dom/telephony/ipc/TelephonyParent.cpp @@ -294,26 +294,11 @@ TelephonyParent::RecvSetSpeakerEnabled(const bool& aEnabled) // nsITelephonyListener NS_IMETHODIMP -TelephonyParent::CallStateChanged(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyParent::CallStateChanged(nsITelephonyCallInfo* aInfo) { NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), - aNumberPresentation, nsString(aName), aNamePresentation, - aIsOutgoing, aIsEmergency, aIsConference, - aIsSwitchable, aIsMergeable); - return SendNotifyCallStateChanged(aClientId, data) ? NS_OK : NS_ERROR_FAILURE; + return SendNotifyCallStateChanged(aInfo) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP @@ -332,18 +317,7 @@ TelephonyParent::EnumerateCallStateComplete() } NS_IMETHODIMP -TelephonyParent::EnumerateCallState(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyParent::EnumerateCallState(nsITelephonyCallInfo* aInfo) { MOZ_CRASH("Not a EnumerateCalls request!"); } @@ -428,18 +402,7 @@ TelephonyRequestParent::SendResponse(const IPCTelephonyResponse& aResponse) // nsITelephonyListener NS_IMETHODIMP -TelephonyRequestParent::CallStateChanged(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyRequestParent::CallStateChanged(nsITelephonyCallInfo* aInfo) { MOZ_CRASH("Not a TelephonyParent!"); } @@ -459,27 +422,11 @@ TelephonyRequestParent::EnumerateCallStateComplete() } NS_IMETHODIMP -TelephonyRequestParent::EnumerateCallState(uint32_t aClientId, - uint32_t aCallIndex, - uint16_t aCallState, - const nsAString& aNumber, - uint16_t aNumberPresentation, - const nsAString& aName, - uint16_t aNamePresentation, - bool aIsOutgoing, - bool aIsEmergency, - bool aIsConference, - bool aIsSwitchable, - bool aIsMergeable) +TelephonyRequestParent::EnumerateCallState(nsITelephonyCallInfo* aInfo) { NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE); - IPCCallStateData data(aCallIndex, aCallState, nsString(aNumber), - aNumberPresentation, nsString(aName), aNamePresentation, - aIsOutgoing, aIsEmergency, aIsConference, - aIsSwitchable, aIsMergeable); - return SendNotifyEnumerateCallState(aClientId, data) ? NS_OK - : NS_ERROR_FAILURE; + return SendNotifyEnumerateCallState(aInfo) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP diff --git a/dom/telephony/ipc/TelephonyTypes.ipdlh b/dom/telephony/ipc/TelephonyTypes.ipdlh index 533ef5890a41..34194f427cfc 100644 --- a/dom/telephony/ipc/TelephonyTypes.ipdlh +++ b/dom/telephony/ipc/TelephonyTypes.ipdlh @@ -11,21 +11,6 @@ namespace mozilla { namespace dom { namespace telephony { -struct IPCCallStateData -{ - uint32_t callIndex; - uint16_t callState; - nsString number; - uint16_t numberPresentation; - nsString name; - uint16_t namePresentation; - bool isOutGoing; - bool isEmergency; - bool isConference; - bool isSwitchable; - bool isMergeable; -}; - struct IPCCdmaWaitingCallData { nsString number; diff --git a/dom/telephony/moz.build b/dom/telephony/moz.build index a05167c8ec3d..e2dbba00f6cb 100644 --- a/dom/telephony/moz.build +++ b/dom/telephony/moz.build @@ -23,6 +23,7 @@ EXPORTS.mozilla.dom += [ EXPORTS.mozilla.dom.telephony += [ 'ipc/TelephonyChild.h', + 'ipc/TelephonyIPCSerializer.h', 'ipc/TelephonyParent.h', 'TelephonyCallback.h', 'TelephonyCallInfo.h', From c5574448a2dd32e36e92233383bd0e7e70d18855 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 00:57:23 -0800 Subject: [PATCH 173/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/d1109115b15a Author: viorelaioia Desc: Merge pull request #27199 from JohanLorenzo/bug-1097754 Bug 1097754 - test_dialer_receive_call_with_locked_screen.py sometimes d... ======== https://hg.mozilla.org/integration/gaia-central/rev/0f14187d0944 Author: Johan Lorenzo Desc: Bug 1097754 - test_dialer_receive_call_with_locked_screen.py sometimes doesn't wait until the callscreen arrives at the bottom of the screen --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index a7b4221267ad..74c4400600e3 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "4f1169743fcfcecc37cd23107e0403a049bb6335", + "revision": "d1109115b15af7f5c47b632c07098a240593426c", "repo_path": "integration/gaia-central" } From 534c896f1af9c096791353d5d4ce9fdee75ceaae Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 01:07:03 -0800 Subject: [PATCH 174/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index f33b76927798..2f9eac2b2ea6 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 126ebfe5b1f4..574002537fc1 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 20cbaa93c95d..493624bc8157 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 3de0af75f1bc..03765e00c5bd 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 126ebfe5b1f4..574002537fc1 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 2de7ce7bcc28..94064d0fc65e 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index b6cd6771ac9d..fafd197d48ab 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index b71b95253860..4bdaff474666 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 073f5523a666..c01bebc90059 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 21b5334b16c1..49b934e0a7d8 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 aa90843ab6b8..7d47267eda62 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From ea95b7f2c2d9eeac2203383a647816f3705c09bd Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 01:27:18 -0800 Subject: [PATCH 175/224] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/7aec56174120 Author: EragonJ (E.J.) Desc: Merge pull request #26930 from EragonJ/bug-1101186 Bug 1101186 - On rebooting the device with Airplane Mode on Gaia sends ======== https://hg.mozilla.org/integration/gaia-central/rev/d10072cafdfc Author: EragonJ Desc: Bug 1101186 - On rebooting the device with Airplane Mode on Gaia sends radio on followed by radio off ======== https://hg.mozilla.org/integration/gaia-central/rev/948da9b99818 Author: viorelaioia Desc: Merge pull request #27197 from bebef1987/phone Bug 1118728 - Update Phone app object to wait for the app to launch ======== https://hg.mozilla.org/integration/gaia-central/rev/b61cb99b3226 Author: bebef1987 Desc: Bug 1118728 - Update Phone app object to wait for the app to launch --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 74c4400600e3..99515d03943f 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "d1109115b15af7f5c47b632c07098a240593426c", + "revision": "7aec56174120513148753fbd8d3708976157fed2", "repo_path": "integration/gaia-central" } From e276b9bdf410c4c93f0c2c30d8d4ff515b34b296 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 01:36:59 -0800 Subject: [PATCH 176/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 2f9eac2b2ea6..bc36b9de5be4 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 574002537fc1..e7dd7bf93965 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 493624bc8157..c9ceb544fed3 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 03765e00c5bd..ed593f360216 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 574002537fc1..e7dd7bf93965 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 94064d0fc65e..9652347f0cac 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index fafd197d48ab..ad544c0cf432 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 4bdaff474666..b4e69455cc36 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 c01bebc90059..88f9ff2d24a9 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 49b934e0a7d8..18b3c2f8680c 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 7d47267eda62..a9d2ce26f2da 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a25d50ba57ed26837594219fe61365823b78dc80 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 03:17:20 -0800 Subject: [PATCH 177/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/2a543baac83c Author: Florin Strugariu Desc: Merge pull request #27228 from chirarobert/bug_1119143 Bug 1119143 - [v2.2] Fix rocketbar test failures ======== https://hg.mozilla.org/integration/gaia-central/rev/1986c6d4beb9 Author: Robert Chira Desc: Bug 1119143 - [v2.2] Fix rocketbar test failures --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 99515d03943f..3519456c49b4 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "7aec56174120513148753fbd8d3708976157fed2", + "revision": "2a543baac83ce53bce3b2afd5ba9b7f3fc45d254", "repo_path": "integration/gaia-central" } From f091699c21aa110cf13dc375372639b862bbbee7 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 03:27:00 -0800 Subject: [PATCH 178/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index bc36b9de5be4..54ef34857511 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index e7dd7bf93965..8d8f47e867b7 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 c9ceb544fed3..1b09f93f863a 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 ed593f360216..ccccefe483fc 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 e7dd7bf93965..8d8f47e867b7 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 9652347f0cac..8f06a19bba7d 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index ad544c0cf432..50a98ee48876 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index b4e69455cc36..d185b4f49454 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 88f9ff2d24a9..a2f6c12c5f38 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 18b3c2f8680c..74e4b2939131 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 a9d2ce26f2da..b4b37a781d2b 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a0ca7df33da454216c7ddd81a02d8243044e0e46 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 03:32:15 -0800 Subject: [PATCH 179/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/ab648f53c084 Author: Jose M. Cantera Desc: Merge pull request #26912 from jmcanterafonseca/pick_vcard_final Bug 1007932 send vcard in an MMS ======== https://hg.mozilla.org/integration/gaia-central/rev/906adda15970 Author: Jose M. Cantera Desc: Bug 1007932 send vcard in an MMS --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 3519456c49b4..66d28637b408 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "2a543baac83ce53bce3b2afd5ba9b7f3fc45d254", + "revision": "ab648f53c084251ff1e6561dcc808e55b82a37bc", "repo_path": "integration/gaia-central" } From 71cc3b2fd9d3fd5e2724760372c90784fb2127e9 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 03:41:54 -0800 Subject: [PATCH 180/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 54ef34857511..9faea567d24b 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 8d8f47e867b7..267d2bd7cfe9 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 1b09f93f863a..538fb572bb61 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 ccccefe483fc..cfcb1a8f2dc2 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 8d8f47e867b7..267d2bd7cfe9 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 8f06a19bba7d..7d6384b98493 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 50a98ee48876..eaa55dd8594d 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index d185b4f49454..87e259f74c71 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 a2f6c12c5f38..adac88e70ba0 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 74e4b2939131..5c8fddd522cf 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 b4b37a781d2b..2c1215d585b7 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From e4dbfa800c56df59102d12d13e3a7b9e5fc5bfe2 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 04:08:50 -0800 Subject: [PATCH 181/224] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 3 ++- b2g/config/emulator/sources.xml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 267d2bd7cfe9..a68a39affab2 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -28,7 +28,7 @@ - + @@ -102,6 +102,7 @@ + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 267d2bd7cfe9..a68a39affab2 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -28,7 +28,7 @@ - + @@ -102,6 +102,7 @@ + From 3686fc6c78254aace0bcf5aa02c491c5559090e1 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 05:07:14 -0800 Subject: [PATCH 182/224] Bumping gaia.json for 3 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/818cae6e045e Author: Chris Lord Desc: Merge pull request #27164 from Cwiiis/bug1118311-fix-dragging-expanded-group Bug 1118311 - Fix dragging expanded groups. r=kgrandon ======== https://hg.mozilla.org/integration/gaia-central/rev/98beac756f50 Author: Chris Lord Desc: Bug 1118311 - Test that dragging an expanded group positions correctly. r=kgrandon ======== https://hg.mozilla.org/integration/gaia-central/rev/1e1f9eaa14ed Author: Chris Lord Desc: Bug 1118311 - Fix dragging expanded groups. r=kgrandon --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 66d28637b408..346c88cbfbdd 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "ab648f53c084251ff1e6561dcc808e55b82a37bc", + "revision": "818cae6e045eae54a72767c81c72d36b9002b022", "repo_path": "integration/gaia-central" } From c05f6f4de2ccc0b47c000c0b6db47790d41cd38f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 05:17:01 -0800 Subject: [PATCH 183/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 9faea567d24b..a2ce881378ae 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index a68a39affab2..6ffd4ec3db9f 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 538fb572bb61..953d7b318afd 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 cfcb1a8f2dc2..4add13eaf8ed 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 a68a39affab2..6ffd4ec3db9f 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 7d6384b98493..31cc018314ac 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index eaa55dd8594d..96e9ad13f21c 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 87e259f74c71..d3c2c37b5373 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 adac88e70ba0..862e7e03d8e5 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 5c8fddd522cf..0c16f512d0ee 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 2c1215d585b7..f9ae63ada4a6 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 5c8e9cc45f9dd19386c5d6447cd8a31a28388b4d Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 8 Jan 2015 08:37:47 -0500 Subject: [PATCH 184/224] Bug 1056337 - Touch CLOBBER. --- CLOBBER | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLOBBER b/CLOBBER index d15932f19fab..2908296d8207 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. -Bug 1066383 - Clobber needed due to build system not reliably picking up an IDL removal. +Bug 1056337 - Change default compiler for B2G ICS builds. From d1f5859df220919c99a10f7f134acefef4de0492 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 05:45:11 -0800 Subject: [PATCH 185/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index a2ce881378ae..a7f885d562da 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 6ffd4ec3db9f..052d3ab02c6d 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 953d7b318afd..009b63f68a55 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 4add13eaf8ed..b9f6eba49978 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 6ffd4ec3db9f..052d3ab02c6d 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 31cc018314ac..d493d9324a47 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 96e9ad13f21c..987ae3616cdd 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index d3c2c37b5373..6d5fd3901531 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 862e7e03d8e5..5176fb665da5 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -16,7 +16,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 0c16f512d0ee..53fa1f4da961 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index f9ae63ada4a6..6a1e75427b73 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -18,7 +18,7 @@ - + From 3cf7829b11d4ede8e94edf941e59d34f2c19226c Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Wed, 7 Jan 2015 03:41:00 -0500 Subject: [PATCH 186/224] Bug 1118698 - Add namespace for automic functions to prevent redefine error. r=ajones --- media/libstagefright/stubs/include/cutils/atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/media/libstagefright/stubs/include/cutils/atomic.h b/media/libstagefright/stubs/include/cutils/atomic.h index 3de84ee34407..e22550177957 100644 --- a/media/libstagefright/stubs/include/cutils/atomic.h +++ b/media/libstagefright/stubs/include/cutils/atomic.h @@ -10,6 +10,7 @@ // makes the totally unsafe. However we're only using the demuxer in a single // thread. +namespace stagefright { static inline int32_t android_atomic_dec(volatile int32_t* aValue) { @@ -47,5 +48,6 @@ android_atomic_cmpxchg(int32_t aOld, int32_t aNew, volatile int32_t* aValue) } return aOld; } +} #endif From d4c92cf531ea641391c82b24416895bc177409d1 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Wed, 7 Jan 2015 18:47:19 -0800 Subject: [PATCH 187/224] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/ad68423bdf19 Author: George Desc: Merge pull request #27113 from cctuan/1115508 Bug 1115508 - [Flame][Built-in&System Keyboard]The utility bubble always shows even at lock screen. ======== https://hg.mozilla.org/integration/gaia-central/rev/85d2a7dfe25d Author: cctuan Desc: Bug 1115508 - [Flame][Built-in&System Keyboard]The utility bubble always shows even at lock screen. ======== https://hg.mozilla.org/integration/gaia-central/rev/f919d73b9524 Author: George Desc: Merge pull request #27150 from cctuan/1110963-m bug 1110963 - add marionette test ======== https://hg.mozilla.org/integration/gaia-central/rev/9611095fa7c1 Author: cctuan Desc: bug 1110963 - add marionette test --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 4be048a9ad09..3b847f031e84 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "29234256286a82d8a0495afef70dd4129f459024", + "revision": "ad68423bdf19616552beb6d4fb10bc61b927eb48", "repo_path": "integration/gaia-central" } From a3c1c0bd941a2f97de07f84e086f7acf26ae0e82 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Wed, 7 Jan 2015 18:48:57 -0800 Subject: [PATCH 188/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 428053f78763..509d045f51fe 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 455966e80bde..2b9a5a2aba90 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 ec167f2d3fcd..e551a03dbeda 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 b5ee1cab0aaa..91965e4f61a2 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 455966e80bde..2b9a5a2aba90 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index f64b616912e4..2f189ab8802e 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 679d9492460c..860368b414fb 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 6ab7c274d71d..3fe4b95aefa4 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 27ad637716fe..9b6dcf81e889 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 5bb91c2d2535..82f56f9805ec 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 965562c3ab13..355f891fd2ca 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a0ad5829231dbe4246f86d483a3a1f35725bb725 Mon Sep 17 00:00:00 2001 From: Shawn Ku Date: Thu, 8 Jan 2015 11:47:02 +0800 Subject: [PATCH 189/224] Bug 1119090 - B2G RIL: There is no missed call information when receive a missed call during active call. r=aknow --- dom/system/gonk/ril_worker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index bc697cb6c3bc..790cb7e3b562 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -4131,7 +4131,7 @@ RilObject.prototype = { _addVoiceCall: function(newCall) { newCall.number = this._formatInternationalNumber(newCall.number, newCall.toa); - newCall.isOutgoing = !(newCall.state == CALL_STATE_INCOMING); + newCall.isOutgoing = !newCall.isMT; newCall.isConference = false; this.currentCalls[newCall.callIndex] = newCall; From 4ae7d4780a80bfb31aa2e1f94be5846a5a99de97 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:44:49 +0800 Subject: [PATCH 190/224] Bug 1102703 - Extend internal interfaces to sync with android lollipop and bluez 5.26 (core). r=btian, f=tzimmermann --- dom/bluetooth/BluetoothCommon.h | 16 ++++++++ dom/bluetooth/BluetoothInterface.h | 17 +++++++++ .../bluedroid/BluetoothDaemonInterface.cpp | 21 +++++++++- .../bluedroid/BluetoothDaemonInterface.h | 12 +++++- .../bluedroid/BluetoothHALInterface.cpp | 38 +++++++++++++++++++ .../bluedroid/BluetoothHALInterface.h | 12 +++++- .../bluedroid/BluetoothServiceBluedroid.cpp | 11 +++++- .../bluedroid/BluetoothServiceBluedroid.h | 3 ++ 8 files changed, 126 insertions(+), 4 deletions(-) diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h index fa10f3ecaefd..6e491536ef77 100644 --- a/dom/bluetooth/BluetoothCommon.h +++ b/dom/bluetooth/BluetoothCommon.h @@ -235,6 +235,22 @@ struct BluetoothProperty { BluetoothRemoteInfo mRemoteInfo; }; +/* Physical transport for GATT connections to remote dual-mode devices */ +enum BluetoothTransport { + TRANSPORT_AUTO, /* No preference of physical transport */ + TRANSPORT_BREDR, /* Prefer BR/EDR transport */ + TRANSPORT_LE /* Prefer LE transport */ +}; + +struct BluetoothActivityEnergyInfo { + uint8_t mStatus; + uint8_t mStackState; /* stack reported state */ + uint64_t mTxTime; /* in ms */ + uint64_t mRxTime; /* in ms */ + uint64_t mIdleTime; /* in ms */ + uint64_t mEnergyUsed; /* a product of mA, V and ms */ +}; + enum BluetoothSocketType { RFCOMM = 1, SCO = 2, diff --git a/dom/bluetooth/BluetoothInterface.h b/dom/bluetooth/BluetoothInterface.h index 684c66c91ae5..dffd39ff9da0 100644 --- a/dom/bluetooth/BluetoothInterface.h +++ b/dom/bluetooth/BluetoothInterface.h @@ -495,6 +495,9 @@ public: virtual void LeTestModeNotification(BluetoothStatus aStatus, uint16_t aNumPackets) { } + virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo) + { } + protected: BluetoothNotificationHandler() { } @@ -535,6 +538,8 @@ public: virtual void RemoveBond() { } virtual void CancelBond() { } + virtual void GetConnectionState() { } + virtual void PinReply() { } virtual void SspReply() { } @@ -542,6 +547,8 @@ public: virtual void DutModeSend() { } virtual void LeTestMode() { } + + virtual void ReadEnergyInfo() { } }; class BluetoothInterface @@ -591,12 +598,18 @@ public: /* Bonds */ virtual void CreateBond(const nsAString& aBdAddr, + BluetoothTransport aTransport, BluetoothResultHandler* aRes) = 0; virtual void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes) = 0; virtual void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes) = 0; + /* Connection */ + + virtual void GetConnectionState(const nsAString& aBdAddr, + BluetoothResultHandler* aRes) = 0; + /* Authentication */ virtual void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -619,6 +632,10 @@ public: virtual void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes) = 0; + /* Energy Info */ + + virtual void ReadEnergyInfo(BluetoothResultHandler* aRes) = 0; + /* Profile Interfaces */ virtual BluetoothSocketInterface* GetBluetoothSocketInterface() = 0; diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp index d7f0b19224d4..4a8b24505c27 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp @@ -406,6 +406,7 @@ public: } nsresult CreateBondCmd(const nsAString& aBdAddr, + BluetoothTransport aTransport, BluetoothResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); @@ -2017,10 +2018,11 @@ BluetoothDaemonInterface::CancelDiscovery(BluetoothResultHandler* aRes) void BluetoothDaemonInterface::CreateBond(const nsAString& aBdAddr, + BluetoothTransport aTransport, BluetoothResultHandler* aRes) { static_cast - (mProtocol)->CreateBondCmd(aBdAddr, aRes); + (mProtocol)->CreateBondCmd(aBdAddr, aTransport, aRes); } void @@ -2039,6 +2041,15 @@ BluetoothDaemonInterface::CancelBond(const nsAString& aBdAddr, (mProtocol)->CancelBondCmd(aBdAddr, aRes); } +/* Connection */ + +void +BluetoothDaemonInterface::GetConnectionState(const nsAString& aBdAddr, + BluetoothResultHandler* aRes) +{ + // NO-OP: no corresponding interface of current BlueZ +} + /* Authentication */ void @@ -2090,6 +2101,14 @@ BluetoothDaemonInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, (mProtocol)->LeTestModeCmd(aOpcode, aBuf, aLen, aRes); } +/* Energy Information */ + +void +BluetoothDaemonInterface::ReadEnergyInfo(BluetoothResultHandler* aRes) +{ + // NO-OP: no corresponding interface of current BlueZ +} + void BluetoothDaemonInterface::DispatchError(BluetoothResultHandler* aRes, BluetoothStatus aStatus) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h index b543b0318557..dc094f5e91c9 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h @@ -71,10 +71,16 @@ public: /* Bonds */ - void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); + void CreateBond(const nsAString& aBdAddr, BluetoothTransport aTransport, + BluetoothResultHandler* aRes); void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); + /* Connection */ + + void GetConnectionState(const nsAString& aBdAddr, + BluetoothResultHandler* aRes); + /* Authentication */ void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -96,6 +102,10 @@ public: void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes); + /* Energy Information */ + + void ReadEnergyInfo(BluetoothResultHandler* aRes); + /* Profile Interfaces */ BluetoothSocketInterface* GetBluetoothSocketInterface() MOZ_OVERRIDE; diff --git a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp index e7527181e2e7..ba4f49378795 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp @@ -176,6 +176,11 @@ struct BluetoothCallback BluetoothStatus, uint16_t> LeTestModeNotification; + typedef BluetoothNotificationHALRunnable1 + EnergyInfoNotification; + // Bluedroid callbacks static const bt_property_t* @@ -665,6 +670,7 @@ BluetoothHALInterface::CancelDiscovery(BluetoothResultHandler* aRes) void BluetoothHALInterface::CreateBond(const nsAString& aBdAddr, + BluetoothTransport aTransport, BluetoothResultHandler* aRes) { bt_bdaddr_t bdAddr; @@ -723,6 +729,23 @@ BluetoothHALInterface::CancelBond(const nsAString& aBdAddr, } } +/* Connection */ + +void +BluetoothHALInterface::GetConnectionState(const nsAString& aBdAddr, + BluetoothResultHandler* aRes) +{ + // TODO: to be implemented + + int status = BT_STATUS_UNSUPPORTED; + + if (aRes) { + DispatchBluetoothHALResult(aRes, + &BluetoothResultHandler::GetConnectionState, + ConvertDefault(status, STATUS_FAIL)); + } +} + /* Authentication */ void @@ -831,6 +854,21 @@ BluetoothHALInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, } } +/* Energy Information */ +void +BluetoothHALInterface::ReadEnergyInfo(BluetoothResultHandler* aRes) +{ + // TODO: to be implemented + + int status = BT_STATUS_UNSUPPORTED; + + if (aRes) { + DispatchBluetoothHALResult(aRes, + &BluetoothResultHandler::ReadEnergyInfo, + ConvertDefault(status, STATUS_FAIL)); + } +} + /* Profile Interfaces */ template diff --git a/dom/bluetooth/bluedroid/BluetoothHALInterface.h b/dom/bluetooth/bluedroid/BluetoothHALInterface.h index 9c81eab79c7a..a0f0505cafc2 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothHALInterface.h @@ -59,10 +59,16 @@ public: /* Bonds */ - void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); + void CreateBond(const nsAString& aBdAddr, BluetoothTransport aTransport, + BluetoothResultHandler* aRes); void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); + /* Connection */ + + void GetConnectionState(const nsAString& aBdAddr, + BluetoothResultHandler* aRes); + /* Authentication */ void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -84,6 +90,10 @@ public: void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes); + /* Energy Information */ + + void ReadEnergyInfo(BluetoothResultHandler* aRes); + /* Profile Interfaces */ BluetoothSocketInterface* GetBluetoothSocketInterface(); diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 81ead9071a5b..b6fd6af1e357 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -693,7 +693,7 @@ BluetoothServiceBluedroid::CreatePairedDeviceInternal( sBondingRunnableArray.AppendElement(aRunnable); - sBtInterface->CreateBond(aDeviceAddress, + sBtInterface->CreateBond(aDeviceAddress, TRANSPORT_AUTO, new CreateBondResultHandler(aRunnable)); return NS_OK; @@ -1623,3 +1623,12 @@ BluetoothServiceBluedroid::LeTestModeNotification(BluetoothStatus aStatus, // FIXME: This will be implemented in the later patchset } + +void +BluetoothServiceBluedroid::EnergyInfoNotification( + const BluetoothActivityEnergyInfo& aInfo) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // FIXME: This will be implemented in the later patchset +} diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h index f9f3c0dc00f7..9600cf6bcd05 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h @@ -212,6 +212,9 @@ public: virtual void LeTestModeNotification(BluetoothStatus aStatus, uint16_t aNumPackets) MOZ_OVERRIDE; + virtual void EnergyInfoNotification( + const BluetoothActivityEnergyInfo& aInfo) MOZ_OVERRIDE; + protected: static nsresult StartGonkBluetooth(); static nsresult StopGonkBluetooth(); From 08634bb1297f4f9f2a7145f5415f5cd6a29b1034 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:46:10 +0800 Subject: [PATCH 191/224] Bug 1102703 - Extend internal interfaces to sync with android lollipop and bluez 5.26 (a2dp). r=shawnjohnjr --- dom/bluetooth/BluetoothInterface.h | 6 ++++++ dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/dom/bluetooth/BluetoothInterface.h b/dom/bluetooth/BluetoothInterface.h index dffd39ff9da0..261a78e4804f 100644 --- a/dom/bluetooth/BluetoothInterface.h +++ b/dom/bluetooth/BluetoothInterface.h @@ -263,6 +263,12 @@ public: const nsAString& aBdAddr) { } + virtual void + AudioConfigNotification(const nsAString& aBdAddr, + uint32_t aSampleRate, + uint8_t aChannelCount) + { } + protected: BluetoothA2dpNotificationHandler() { } diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp index 5bd82e7c893e..019d3fa43369 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp @@ -75,6 +75,12 @@ struct BluetoothA2dpHALCallback BluetoothA2dpAudioState, const nsAString&> AudioStateNotification; + typedef BluetoothNotificationHALRunnable3< + A2dpNotificationHandlerWrapper, void, + nsString, uint32_t, uint8_t, + const nsAString&, uint32_t, uint8_t> + AudioConfigNotification; + // Bluedroid A2DP callbacks static void From 08507e26e0e850d02d472bbcd4ee7d7e5b65bb39 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:46:43 +0800 Subject: [PATCH 192/224] Bug 1102703 - Extend internal interfaces to sync with android lollipop and bluez 5.26 (handsfree). r=btian, r=tzimmermann --- dom/bluetooth/BluetoothCommon.h | 6 + dom/bluetooth/BluetoothInterface.h | 66 +++- .../BluetoothDaemonHandsfreeInterface.cpp | 372 ++++++++++++++++-- .../BluetoothDaemonHandsfreeInterface.h | 105 +++-- .../BluetoothHandsfreeHALInterface.cpp | 161 +++++--- .../BluetoothHandsfreeHALInterface.h | 22 +- .../bluedroid/hfp/BluetoothHfpManager.cpp | 52 +-- .../bluedroid/hfp/BluetoothHfpManager.h | 31 +- 8 files changed, 656 insertions(+), 159 deletions(-) diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h index 6e491536ef77..cdee8da18c73 100644 --- a/dom/bluetooth/BluetoothCommon.h +++ b/dom/bluetooth/BluetoothCommon.h @@ -322,6 +322,12 @@ enum BluetoothHandsfreeNetworkState { HFP_NETWORK_STATE_AVAILABLE }; +enum BluetoothHandsfreeWbsConfig { + HFP_WBS_NONE, /* Neither CVSD nor mSBC codec, but other optional codec.*/ + HFP_WBS_NO, /* CVSD */ + HFP_WBS_YES /* mSBC */ +}; + enum BluetoothHandsfreeNRECState { HFP_NREC_STOPPED, HFP_NREC_STARTED diff --git a/dom/bluetooth/BluetoothInterface.h b/dom/bluetooth/BluetoothInterface.h index 261a78e4804f..b9122c6608d6 100644 --- a/dom/bluetooth/BluetoothInterface.h +++ b/dom/bluetooth/BluetoothInterface.h @@ -80,59 +80,72 @@ public: { } virtual void - VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState) + VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState, + const nsAString& aBdAddr) { } virtual void - AnswerCallNotification() + AnswerCallNotification(const nsAString& aBdAddr) { } virtual void - HangupCallNotification() + HangupCallNotification(const nsAString& aBdAddr) { } virtual void - VolumeNotification(BluetoothHandsfreeVolumeType aType, int aVolume) + VolumeNotification(BluetoothHandsfreeVolumeType aType, + int aVolume, + const nsAString& aBdAddr) { } virtual void - DialCallNotification(const nsAString& aNumber) + DialCallNotification(const nsAString& aNumber, + const nsAString& aBdAddr) { } virtual void - DtmfNotification(char aDtmf) + DtmfNotification(char aDtmf, + const nsAString& aBdAddr) { } virtual void - NRECNotification(BluetoothHandsfreeNRECState aNrec) + NRECNotification(BluetoothHandsfreeNRECState aNrec, + const nsAString& aBdAddr) { } virtual void - CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) + WbsNotification(BluetoothHandsfreeWbsConfig aWbs, + const nsAString& aBdAddr) { } virtual void - CnumNotification() + CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, + const nsAString& aBdAddr) { } virtual void - CindNotification() + CnumNotification(const nsAString& aBdAddr) { } virtual void - CopsNotification() + CindNotification(const nsAString& aBdAddr) { } virtual void - ClccNotification() + CopsNotification(const nsAString& aBdAddr) { } virtual void - UnknownAtNotification(const nsACString& aAtString) + ClccNotification(const nsAString& aBdAddr) { } virtual void - KeyPressedNotification() + UnknownAtNotification(const nsACString& aAtString, + const nsAString& aBdAddr) + { } + + virtual void + KeyPressedNotification(const nsAString& aBdAddr) { } protected: @@ -173,6 +186,8 @@ public: virtual void AtResponse() { } virtual void ClccResponse() { } virtual void PhoneStateChange() { } + + virtual void ConfigureWbs() { } }; class BluetoothHandsfreeInterface @@ -180,7 +195,7 @@ class BluetoothHandsfreeInterface public: virtual void Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - BluetoothHandsfreeResultHandler* aRes) = 0; + int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) = 0; virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0; /* Connect / Disconnect */ @@ -196,12 +211,15 @@ public: /* Voice Recognition */ - virtual void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0; + virtual void StartVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) = 0; + virtual void StopVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) = 0; /* Volume */ virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; /* Device status */ @@ -213,15 +231,17 @@ public: /* Responses */ - virtual void CopsResponse(const char* aCops, + virtual void CopsResponse(const char* aCops, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void FormattedAtResponse(const char* aRsp, + virtual void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, + virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, + int aErrorCode, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -229,6 +249,7 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; /* Phone State */ @@ -239,6 +260,11 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes) = 0; + /* Wide Band Speech */ + virtual void ConfigureWbs(const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes) = 0; + protected: BluetoothHandsfreeInterface(); virtual ~BluetoothHandsfreeInterface(); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp index 506c776c11d1..bd956a6e96a7 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp @@ -17,6 +17,9 @@ BEGIN_BLUETOOTH_NAMESPACE BluetoothHandsfreeNotificationHandler* BluetoothDaemonHandsfreeModule::sNotificationHandler; +nsString BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress( + NS_ConvertUTF8toUTF16(BLUETOOTH_ADDRESS_NONE)); + void BluetoothDaemonHandsfreeModule::SetNotificationHandler( BluetoothHandsfreeNotificationHandler* aNotificationHandler) @@ -409,6 +412,19 @@ BluetoothDaemonHandsfreeModule::PhoneStateChangeCmd( return NS_OK; } +nsresult +BluetoothDaemonHandsfreeModule::ConfigureWbsCmd( + const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // TODO: to be implemented + + return NS_ERROR_NOT_IMPLEMENTED; +} + // Responses // @@ -662,6 +678,12 @@ public: if (NS_FAILED(rv)) { return rv; } + + if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) { + sConnectedDeviceAddress = aArg2; + } else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) { + sConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE); + } WarnAboutTrailingData(); return NS_OK; } @@ -686,8 +708,7 @@ public: { } nsresult - operator () (BluetoothHandsfreeAudioState& aArg1, - nsString& aArg2) const + operator () (BluetoothHandsfreeAudioState& aArg1, nsString& aArg2) const { BluetoothDaemonPDU& pdu = GetPDU(); @@ -717,31 +738,104 @@ BluetoothDaemonHandsfreeModule::AudioStateNtf( AudioStateInitOp(aPDU)); } +// Init operator class for VoiceRecognitionNotification +class BluetoothDaemonHandsfreeModule::VoiceRecognitionInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + VoiceRecognitionInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (BluetoothHandsfreeVoiceRecognitionState& aArg1, + nsString& aArg2) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read state */ + nsresult rv = UnpackPDU(pdu, aArg1); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { VoiceRecognitionNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, - UnpackPDUInitOp(aPDU)); + VoiceRecognitionInitOp(aPDU)); } +// Init operator class for AnswerCallNotification +class BluetoothDaemonHandsfreeModule::AnswerCallInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + AnswerCallInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::AnswerCallNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { AnswerCallNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, - UnpackPDUInitOp(aPDU)); + AnswerCallInitOp(aPDU)); } +// Init operator class for HangupCallNotification +class BluetoothDaemonHandsfreeModule::HangupCallInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + HangupCallInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::HangupCallNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { HangupCallNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::HangupCallNotification, - UnpackPDUInitOp(aPDU)); + HangupCallInitOp(aPDU)); } // Init operator class for VolumeNotification @@ -754,7 +848,8 @@ public: { } nsresult - operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2) const + operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2, + nsString& aArg3) const { BluetoothDaemonPDU& pdu = GetPDU(); @@ -769,6 +864,10 @@ public: if (NS_FAILED(rv)) { return rv; } + + /* Read address */ + // TODO + aArg3 = sConnectedDeviceAddress; WarnAboutTrailingData(); return NS_OK; } @@ -793,13 +892,19 @@ public: { } nsresult - operator () (nsString& aArg1) const + operator () (nsString& aArg1, nsString& aArg2) const { + BluetoothDaemonPDU& pdu = GetPDU(); + /* Read number */ - nsresult rv = UnpackPDU(GetPDU(), UnpackString0(aArg1)); + nsresult rv = UnpackPDU(pdu, UnpackString0(aArg1)); if (NS_FAILED(rv)) { return rv; } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; WarnAboutTrailingData(); return NS_OK; } @@ -814,67 +919,239 @@ BluetoothDaemonHandsfreeModule::DialCallNtf( DialCallInitOp(aPDU)); } +// Init operator class for DtmfNotification +class BluetoothDaemonHandsfreeModule::DtmfInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + DtmfInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (char& aArg1, nsString& aArg2) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read tone */ + nsresult rv = UnpackPDU(pdu, aArg1); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::DtmfNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { DtmfNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::DtmfNotification, - UnpackPDUInitOp(aPDU)); + DtmfInitOp(aPDU)); } +// Init operator class for NRECNotification +class BluetoothDaemonHandsfreeModule::NRECInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + NRECInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (BluetoothHandsfreeNRECState& aArg1, nsString& aArg2) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read state */ + nsresult rv = UnpackPDU(pdu, aArg1); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::NRECNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { NRECNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::NRECNotification, - UnpackPDUInitOp(aPDU)); + NRECInitOp(aPDU)); } +// Init operator class for CallHoldNotification +class BluetoothDaemonHandsfreeModule::CallHoldInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + CallHoldInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (BluetoothHandsfreeCallHoldType& aArg1, nsString& aArg2) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read type */ + nsresult rv = UnpackPDU(pdu, aArg1); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::CallHoldNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CallHoldNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CallHoldNotification, - UnpackPDUInitOp(aPDU)); + CallHoldInitOp(aPDU)); } +// Init operator class for CnumNotification +class BluetoothDaemonHandsfreeModule::CnumInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + CnumInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::CnumNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CnumNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CnumNotification, - UnpackPDUInitOp(aPDU)); + CnumInitOp(aPDU)); } +// Init operator class for CindNotification +class BluetoothDaemonHandsfreeModule::CindInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + CindInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::CindNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CindNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CindNotification, - UnpackPDUInitOp(aPDU)); + CindInitOp(aPDU)); } +// Init operator class for CopsNotification +class BluetoothDaemonHandsfreeModule::CopsInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + CopsInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::CopsNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CopsNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CopsNotification, - UnpackPDUInitOp(aPDU)); + CopsInitOp(aPDU)); } +// Init operator class for ClccNotification +class BluetoothDaemonHandsfreeModule::ClccInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + ClccInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::ClccNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { ClccNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::ClccNotification, - UnpackPDUInitOp(aPDU)); + ClccInitOp(aPDU)); } // Init operator class for UnknownAtNotification @@ -887,13 +1164,19 @@ public: { } nsresult - operator () (nsCString& aArg1) const + operator () (nsCString& aArg1, nsString& aArg2) const { + BluetoothDaemonPDU& pdu = GetPDU(); + /* Read string */ - nsresult rv = UnpackPDU(GetPDU(), UnpackCString0(aArg1)); + nsresult rv = UnpackPDU(pdu, UnpackCString0(aArg1)); if (NS_FAILED(rv)) { return rv; } + + /* Read address */ + // TODO + aArg2 = sConnectedDeviceAddress; WarnAboutTrailingData(); return NS_OK; } @@ -908,13 +1191,35 @@ BluetoothDaemonHandsfreeModule::UnknownAtNtf( UnknownAtInitOp(aPDU)); } +// Init operator class for KeyPressedNotification +class BluetoothDaemonHandsfreeModule::KeyPressedInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + KeyPressedInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + // TODO + aArg1 = sConnectedDeviceAddress; + WarnAboutTrailingData(); + return NS_OK; + } +}; + void BluetoothDaemonHandsfreeModule::KeyPressedNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { KeyPressedNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, - UnpackPDUInitOp(aPDU)); + KeyPressedInitOp(aPDU)); } void @@ -997,7 +1302,7 @@ private: void BluetoothDaemonHandsfreeInterface::Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - BluetoothHandsfreeResultHandler* aRes) + int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) { // Set notification handler _before_ registering the module. It could // happen that we receive notifications, before the result handler runs. @@ -1110,7 +1415,7 @@ BluetoothDaemonHandsfreeInterface::DisconnectAudio( void BluetoothDaemonHandsfreeInterface::StartVoiceRecognition( - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1119,7 +1424,7 @@ BluetoothDaemonHandsfreeInterface::StartVoiceRecognition( void BluetoothDaemonHandsfreeInterface::StopVoiceRecognition( - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1130,7 +1435,7 @@ BluetoothDaemonHandsfreeInterface::StopVoiceRecognition( void BluetoothDaemonHandsfreeInterface::VolumeControl( - BluetoothHandsfreeVolumeType aType, int aVolume, + BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1156,7 +1461,8 @@ BluetoothDaemonHandsfreeInterface::DeviceStatusNotification( void BluetoothDaemonHandsfreeInterface::CopsResponse( - const char* aCops, BluetoothHandsfreeResultHandler* aRes) + const char* aCops, const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1168,7 +1474,7 @@ BluetoothDaemonHandsfreeInterface::CindResponse( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1178,7 +1484,8 @@ BluetoothDaemonHandsfreeInterface::CindResponse( void BluetoothDaemonHandsfreeInterface::FormattedAtResponse( - const char* aRsp, BluetoothHandsfreeResultHandler* aRes) + const char* aRsp, const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1188,7 +1495,7 @@ BluetoothDaemonHandsfreeInterface::FormattedAtResponse( void BluetoothDaemonHandsfreeInterface::AtResponse( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1203,6 +1510,7 @@ BluetoothDaemonHandsfreeInterface::ClccResponse( BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); @@ -1227,6 +1535,18 @@ BluetoothDaemonHandsfreeInterface::PhoneStateChange( aType, aRes); } +/* Wide Band Speech */ + +void +BluetoothDaemonHandsfreeInterface::ConfigureWbs( + const nsAString& aBdAddr, BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes) +{ + MOZ_ASSERT(mModule); + + mModule->ConfigureWbsCmd(aBdAddr, aConfig, aRes); +} + void BluetoothDaemonHandsfreeInterface::DispatchError( BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h index 71a233d7b237..6b8d4b46b0ea 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h @@ -111,6 +111,12 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); + /* Wide Band Speech */ + + nsresult ConfigureWbsCmd(const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes); + protected: nsresult Send(BluetoothDaemonPDU* aPDU, BluetoothHandsfreeResultHandler* aRes); @@ -213,60 +219,93 @@ protected: const nsAString&> AudioStateNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 VoiceRecognitionNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 AnswerCallNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 HangupCallNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable3 VolumeNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 DialCallNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 DtmfNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 NRECNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 CallHoldNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 CnumNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 CindNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 CopsNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 ClccNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable2 UnknownAtNotification; - typedef BluetoothNotificationRunnable0 + typedef BluetoothNotificationRunnable1 KeyPressedNotification; - class AudioStateInitOp; class ConnectionStateInitOp; + class AudioStateInitOp; + class VoiceRecognitionInitOp; + class AnswerCallInitOp; + class HangupCallInitOp; + class VolumeInitOp; class DialCallInitOp; + class DtmfInitOp; + class NRECInitOp; + class CallHoldInitOp; + class CnumInitOp; + class CindInitOp; + class CopsInitOp; + class ClccInitOp; class VolumeInitOp; class UnknownAtInitOp; + class KeyPressedInitOp; void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); @@ -321,6 +360,7 @@ protected: void* aUserData); static BluetoothHandsfreeNotificationHandler* sNotificationHandler; + static nsString sConnectedDeviceAddress; }; class BluetoothDaemonHandsfreeInterface MOZ_FINAL @@ -341,7 +381,7 @@ public: void Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - BluetoothHandsfreeResultHandler* aRes); + int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes); void Cleanup(BluetoothHandsfreeResultHandler* aRes); /* Connect / Disconnect */ @@ -357,12 +397,15 @@ public: /* Voice Recognition */ - void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); - void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); + void StartVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); + void StopVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); /* Volume */ void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -374,15 +417,17 @@ public: /* Responses */ - void CopsResponse(const char* aCops, + void CopsResponse(const char* aCops, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); - void FormattedAtResponse(const char* aRsp, + void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -390,6 +435,7 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -400,6 +446,11 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); + /* Wide Band Speech */ + void ConfigureWbs(const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes); + private: void DispatchError(BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus); diff --git a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp index b996363d59b8..9c6f62cbf5bf 100644 --- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp @@ -75,62 +75,78 @@ struct BluetoothHandsfreeHALCallback BluetoothHandsfreeAudioState, const nsAString&> AudioStateNotification; - typedef BluetoothNotificationHALRunnable1< + typedef BluetoothNotificationHALRunnable2< HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeVoiceRecognitionState> + BluetoothHandsfreeVoiceRecognitionState, nsString, + BluetoothHandsfreeVoiceRecognitionState, const nsAString&> VoiceRecognitionNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> AnswerCallNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> HangupCallNotification; + typedef BluetoothNotificationHALRunnable3< + HandsfreeNotificationHandlerWrapper, void, + BluetoothHandsfreeVolumeType, int, nsString, + BluetoothHandsfreeVolumeType, int, const nsAString&> + VolumeNotification; + typedef BluetoothNotificationHALRunnable2< HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeVolumeType, int> - VolumeNotification; - - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, nsString, const nsAString&> + nsString, nsString, const nsAString&, const nsAString&> DialCallNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, char> + typedef BluetoothNotificationHALRunnable2< + HandsfreeNotificationHandlerWrapper, void, + char, nsString, char, const nsAString&> DtmfNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeNRECState> + typedef BluetoothNotificationHALRunnable2< + HandsfreeNotificationHandlerWrapper, void, + BluetoothHandsfreeNRECState, nsString, + BluetoothHandsfreeNRECState, const nsAString&> NRECNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType> + typedef BluetoothNotificationHALRunnable2< + HandsfreeNotificationHandlerWrapper, void, + BluetoothHandsfreeCallHoldType, nsString, + BluetoothHandsfreeCallHoldType, const nsAString&> CallHoldNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> CnumNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> CindNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> CopsNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> ClccNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, nsCString, const nsACString&> + typedef BluetoothNotificationHALRunnable2< + HandsfreeNotificationHandlerWrapper, void, + nsCString, nsString, const nsACString&, const nsAString&> UnknownAtNotification; - typedef BluetoothNotificationHALRunnable0< - HandsfreeNotificationHandlerWrapper, void> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, + nsString, const nsAString&> KeyPressedNotification; // Bluedroid Handsfree callbacks @@ -138,6 +154,14 @@ struct BluetoothHandsfreeHALCallback static void ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr) { + if (aState == BTHF_CONNECTION_STATE_CONNECTED && aBdAddr) { + memcpy(&sConnectedDeviceAddress, aBdAddr, + sizeof(sConnectedDeviceAddress)); + } else if (aState == BTHF_CONNECTION_STATE_DISCONNECTED) { + memset(&sConnectedDeviceAddress, 0, + sizeof(sConnectedDeviceAddress)); + } + ConnectionStateNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::ConnectionStateNotification, aState, aBdAddr); @@ -156,21 +180,23 @@ struct BluetoothHandsfreeHALCallback { VoiceRecognitionNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, - aState); + aState, &sConnectedDeviceAddress); } static void AnswerCall() { AnswerCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::AnswerCallNotification); + &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, + &sConnectedDeviceAddress); } static void HangupCall() { HangupCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::HangupCallNotification); + &BluetoothHandsfreeNotificationHandler::HangupCallNotification, + &sConnectedDeviceAddress); } static void @@ -178,63 +204,71 @@ struct BluetoothHandsfreeHALCallback { VolumeNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VolumeNotification, - aType, aVolume); + aType, aVolume, &sConnectedDeviceAddress); } static void DialCall(char* aNumber) { DialCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber); + &BluetoothHandsfreeNotificationHandler::DialCallNotification, + aNumber, &sConnectedDeviceAddress); } static void Dtmf(char aDtmf) { DtmfNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf); + &BluetoothHandsfreeNotificationHandler::DtmfNotification, + aDtmf, &sConnectedDeviceAddress); } static void NoiseReductionEchoCancellation(bthf_nrec_t aNrec) { NRECNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec); + &BluetoothHandsfreeNotificationHandler::NRECNotification, + aNrec, &sConnectedDeviceAddress); } static void CallHold(bthf_chld_type_t aChld) { CallHoldNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld); + &BluetoothHandsfreeNotificationHandler::CallHoldNotification, + aChld, &sConnectedDeviceAddress); } static void Cnum() { CnumNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CnumNotification); + &BluetoothHandsfreeNotificationHandler::CnumNotification, + &sConnectedDeviceAddress); } static void Cind() { CindNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CindNotification); + &BluetoothHandsfreeNotificationHandler::CindNotification, + &sConnectedDeviceAddress); } static void Cops() { CopsNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CopsNotification); + &BluetoothHandsfreeNotificationHandler::CopsNotification, + &sConnectedDeviceAddress); } static void Clcc() { ClccNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::ClccNotification); + &BluetoothHandsfreeNotificationHandler::ClccNotification, + &sConnectedDeviceAddress); } static void @@ -242,15 +276,22 @@ struct BluetoothHandsfreeHALCallback { UnknownAtNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::UnknownAtNotification, - aAtString); + aAtString, &sConnectedDeviceAddress); } static void KeyPressed() { KeyPressedNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::KeyPressedNotification); + &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, + &sConnectedDeviceAddress); } + + static bt_bdaddr_t sConnectedDeviceAddress; +}; + +bt_bdaddr_t BluetoothHandsfreeHALCallback::sConnectedDeviceAddress = { + {0, 0, 0, 0, 0, 0} }; // Interface @@ -269,7 +310,7 @@ BluetoothHandsfreeHALInterface::~BluetoothHandsfreeHALInterface() void BluetoothHandsfreeHALInterface::Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - BluetoothHandsfreeResultHandler* aRes) + int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) { static bthf_callbacks_t sCallbacks = { sizeof(sCallbacks), @@ -400,6 +441,7 @@ BluetoothHandsfreeHALInterface::DisconnectAudio( void BluetoothHandsfreeHALInterface::StartVoiceRecognition( + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status = mInterface->start_voice_recognition(); @@ -413,6 +455,7 @@ BluetoothHandsfreeHALInterface::StartVoiceRecognition( void BluetoothHandsfreeHALInterface::StopVoiceRecognition( + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status = mInterface->stop_voice_recognition(); @@ -428,7 +471,7 @@ BluetoothHandsfreeHALInterface::StopVoiceRecognition( void BluetoothHandsfreeHALInterface::VolumeControl( - BluetoothHandsfreeVolumeType aType, int aVolume, + BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; @@ -478,7 +521,8 @@ BluetoothHandsfreeHALInterface::DeviceStatusNotification( void BluetoothHandsfreeHALInterface::CopsResponse( - const char* aCops, BluetoothHandsfreeResultHandler* aRes) + const char* aCops, const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) { bt_status_t status = mInterface->cops_response(aCops); @@ -494,6 +538,7 @@ BluetoothHandsfreeHALInterface::CindResponse( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; @@ -516,7 +561,8 @@ BluetoothHandsfreeHALInterface::CindResponse( void BluetoothHandsfreeHALInterface::FormattedAtResponse( - const char* aRsp, BluetoothHandsfreeResultHandler* aRes) + const char* aRsp, const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes) { bt_status_t status = mInterface->formatted_at_response(aRsp); @@ -530,6 +576,7 @@ BluetoothHandsfreeHALInterface::FormattedAtResponse( void BluetoothHandsfreeHALInterface::AtResponse( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; @@ -557,6 +604,7 @@ BluetoothHandsfreeHALInterface::ClccResponse( BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; @@ -613,4 +661,23 @@ BluetoothHandsfreeHALInterface::PhoneStateChange(int aNumActive, int aNumHeld, } } +/* Wide Band Speech */ + +void +BluetoothHandsfreeHALInterface::ConfigureWbs( + const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes) +{ + // TODO: to be implemented + + bt_status_t status = BT_STATUS_UNSUPPORTED; + + if (aRes) { + DispatchBluetoothHandsfreeHALResult( + aRes, &BluetoothHandsfreeResultHandler::ConfigureWbs, + ConvertDefault(status, STATUS_FAIL)); + } +} + END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h index f53d4251fb65..905d3a89c12a 100644 --- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h @@ -23,6 +23,7 @@ public: friend class BluetoothHALInterface; void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler, + int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes); void Cleanup(BluetoothHandsfreeResultHandler* aRes); @@ -39,12 +40,15 @@ public: /* Voice Recognition */ - void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); - void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); + void StartVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); + void StopVoiceRecognition(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); /* Volume */ void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -56,15 +60,16 @@ public: /* Responses */ - void CopsResponse(const char* aCops, + void CopsResponse(const char* aCops, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, - int aRoam, int aBattChg, + int aRoam, int aBattChg, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); - void FormattedAtResponse(const char* aRsp, + void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -72,6 +77,7 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -82,6 +88,12 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); + /* Wide Band Speech */ + + void ConfigureWbs(const nsAString& aBdAddr, + BluetoothHandsfreeWbsConfig aConfig, + BluetoothHandsfreeResultHandler* aRes); + protected: BluetoothHandsfreeHALInterface(const bthf_interface_t* aInterface); ~BluetoothHandsfreeHALInterface(); diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp index 00866f59dee5..e36add11e458 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ -57,6 +57,8 @@ namespace { static int sBusyToneInterval = 3700; //unit: ms } // anonymous namespace +const int BluetoothHfpManager::MAX_NUM_CLIENTS = 1; + static bool IsValidDtmf(const char aChar) { // Valid DTMF: [*#0-9ABCD] @@ -308,7 +310,7 @@ public: { BluetoothHfpManager* hfpManager = BluetoothHfpManager::Get(); - mInterface->Init(hfpManager, this); + mInterface->Init(hfpManager, BluetoothHfpManager::MAX_NUM_CLIENTS, this); } private: @@ -638,8 +640,9 @@ BluetoothHfpManager::HandleVolumeChanged(nsISupports* aSubject) // Only send volume back when there's a connected headset if (IsConnected()) { NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); - sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, - new VolumeControlResultHandler()); + sBluetoothHfpInterface->VolumeControl( + HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, mDeviceAddress, + new VolumeControlResultHandler()); } } @@ -767,7 +770,7 @@ BluetoothHfpManager::SendCLCC(Call& aCall, int aIndex) sBluetoothHfpInterface->ClccResponse( aIndex, aCall.mDirection, callState, HFP_CALL_MODE_VOICE, HFP_CALL_MPTY_TYPE_SINGLE, aCall.mNumber, - aCall.mType, new ClccResponseResultHandler()); + aCall.mType, mDeviceAddress, new ClccResponseResultHandler()); } class FormattedAtResponseResultHandler MOZ_FINAL @@ -787,7 +790,7 @@ BluetoothHfpManager::SendLine(const char* aMessage) NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); sBluetoothHfpInterface->FormattedAtResponse( - aMessage, new FormattedAtResponseResultHandler()); + aMessage, mDeviceAddress, new FormattedAtResponseResultHandler()); } class AtResponseResultHandler MOZ_FINAL @@ -807,7 +810,7 @@ BluetoothHfpManager::SendResponse(BluetoothHandsfreeAtResponse aResponseCode) NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); sBluetoothHfpInterface->AtResponse( - aResponseCode, 0, new AtResponseResultHandler()); + aResponseCode, 0, mDeviceAddress, new AtResponseResultHandler()); } class PhoneStateChangeResultHandler MOZ_FINAL @@ -1361,7 +1364,7 @@ BluetoothHfpManager::AudioStateNotification( } void -BluetoothHfpManager::AnswerCallNotification() +BluetoothHfpManager::AnswerCallNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1369,7 +1372,7 @@ BluetoothHfpManager::AnswerCallNotification() } void -BluetoothHfpManager::HangupCallNotification() +BluetoothHfpManager::HangupCallNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1378,7 +1381,7 @@ BluetoothHfpManager::HangupCallNotification() void BluetoothHfpManager::VolumeNotification( - BluetoothHandsfreeVolumeType aType, int aVolume) + BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1405,7 +1408,7 @@ BluetoothHfpManager::VolumeNotification( } void -BluetoothHfpManager::DtmfNotification(char aDtmf) +BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1417,7 +1420,8 @@ BluetoothHfpManager::DtmfNotification(char aDtmf) } void -BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) +BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, + const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1435,7 +1439,8 @@ BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) NotifyDialer(NS_ConvertUTF8toUTF16(message)); } -void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber) +void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber, + const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1476,7 +1481,7 @@ void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber) } void -BluetoothHfpManager::CnumNotification() +BluetoothHfpManager::CnumNotification(const nsAString& aBdAddress) { static const uint8_t sAddressType[] { [HFP_CALL_ADDRESS_TYPE_UNKNOWN] = 0x81, @@ -1510,7 +1515,7 @@ public: }; void -BluetoothHfpManager::CindNotification() +BluetoothHfpManager::CindNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1521,9 +1526,11 @@ BluetoothHfpManager::CindNotification() BluetoothHandsfreeCallState callState = ConvertToBluetoothHandsfreeCallState(GetCallSetupState()); - sBluetoothHfpInterface->CindResponse(mService, numActive, numHeld, - callState, mSignal, mRoam, mBattChg, - new CindResponseResultHandler()); + sBluetoothHfpInterface->CindResponse( + mService, numActive, numHeld, + callState, mSignal, mRoam, mBattChg, + aBdAddress, + new CindResponseResultHandler()); } class CopsResponseResultHandler MOZ_FINAL @@ -1538,7 +1545,7 @@ public: }; void -BluetoothHfpManager::CopsNotification() +BluetoothHfpManager::CopsNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1546,11 +1553,11 @@ BluetoothHfpManager::CopsNotification() sBluetoothHfpInterface->CopsResponse( NS_ConvertUTF16toUTF8(mOperatorName).get(), - new CopsResponseResultHandler()); + aBdAddress, new CopsResponseResultHandler()); } void -BluetoothHfpManager::ClccNotification() +BluetoothHfpManager::ClccNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1571,7 +1578,8 @@ BluetoothHfpManager::ClccNotification() } void -BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString) +BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString, + const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); @@ -1581,7 +1589,7 @@ BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString) } void -BluetoothHfpManager::KeyPressedNotification() +BluetoothHfpManager::KeyPressedNotification(const nsAString& aBdAddress) { MOZ_ASSERT(NS_IsMainThread()); diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h index 4cafcfe52504..30d4d688a2ea 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ -77,6 +77,8 @@ class BluetoothHfpManager : public BluetoothHfpManagerBase public: BT_DECL_HFP_MGR_BASE + static const int MAX_NUM_CLIENTS; + void OnConnectError(); void OnDisconnectError(); @@ -117,19 +119,24 @@ public: const nsAString& aBdAddress) MOZ_OVERRIDE; void AudioStateNotification(BluetoothHandsfreeAudioState aState, const nsAString& aBdAddress) MOZ_OVERRIDE; - void AnswerCallNotification() MOZ_OVERRIDE; - void HangupCallNotification() MOZ_OVERRIDE; + void AnswerCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void HangupCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; void VolumeNotification(BluetoothHandsfreeVolumeType aType, - int aVolume) MOZ_OVERRIDE; - void DtmfNotification(char aDtmf) MOZ_OVERRIDE; - void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) MOZ_OVERRIDE; - void DialCallNotification(const nsAString& aNumber) MOZ_OVERRIDE; - void CnumNotification() MOZ_OVERRIDE; - void CindNotification() MOZ_OVERRIDE; - void CopsNotification() MOZ_OVERRIDE; - void ClccNotification() MOZ_OVERRIDE; - void UnknownAtNotification(const nsACString& aAtString) MOZ_OVERRIDE; - void KeyPressedNotification() MOZ_OVERRIDE; + int aVolume, + const nsAString& aBdAddress) MOZ_OVERRIDE; + void DtmfNotification(char aDtmf, + const nsAString& aBdAddress) MOZ_OVERRIDE; + void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, + const nsAString& aBdAddress) MOZ_OVERRIDE; + void DialCallNotification(const nsAString& aNumber, + const nsAString& aBdAddress) MOZ_OVERRIDE; + void CnumNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void CindNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void CopsNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void ClccNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void UnknownAtNotification(const nsACString& aAtString, + const nsAString& aBdAddress) MOZ_OVERRIDE; + void KeyPressedNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; private: class GetVolumeTask; From 29b4ba484cc71234bb4f8916b92ef3f1a6fd3408 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:47:12 +0800 Subject: [PATCH 193/224] Bug 1102703 - Porting bluetooth interface of android lollipop (core). r=btian, r=tzimmermann, r=shawnjohnjr --- .../bluedroid/BluetoothHALHelpers.cpp | 33 ++++++ dom/bluetooth/bluedroid/BluetoothHALHelpers.h | 20 ++++ .../bluedroid/BluetoothHALInterface.cpp | 100 +++++++++++++++++- 3 files changed, 148 insertions(+), 5 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp b/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp index e7445a989313..1494e975159d 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp @@ -211,6 +211,39 @@ Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut) } #endif // ANDROID_VERSION >= 18 +#if ANDROID_VERSION >= 21 +nsresult +Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut) +{ + nsresult rv = Convert(aIn.status, aOut.mStatus); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn.ctrl_state, aOut.mStackState); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn.tx_time, aOut.mTxTime); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn.rx_time, aOut.mRxTime); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn.idle_time, aOut.mIdleTime); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn.energy_used, aOut.mEnergyUsed); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} +#endif // ANDROID_VERSION >= 21 + nsresult Convert(const bt_property_t& aIn, BluetoothProperty& aOut) { diff --git a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h index 81c71025e2a0..ad6565075787 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h @@ -765,6 +765,26 @@ Convert(btrc_remote_features_t aIn, unsigned long& aOut) } #endif // ANDROID_VERSION >= 19 +#if ANDROID_VERSION >= 21 +inline nsresult +Convert(BluetoothTransport aIn, int& aOut) +{ + static const int sTransport[] = { + CONVERT(TRANSPORT_AUTO, 0), + CONVERT(TRANSPORT_BREDR, 1), + CONVERT(TRANSPORT_LE, 2) + }; + if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sTransport))) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sTransport[aIn]; + return NS_OK; +} + +nsresult +Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut); +#endif // ANDROID_VERSION >= 21 + /* |ConvertArray| is a helper for converting arrays. Pass an * instance of this structure as the first argument to |Convert| * to convert an array. The output type has to support the array diff --git a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp index ba4f49378795..eedd057f0eb1 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp @@ -318,8 +318,57 @@ struct BluetoothCallback &BluetoothNotificationHandler::LeTestModeNotification, aStatus, aNumPackets); } + +#if ANDROID_VERSION >= 21 + static void + EnergyInfo(bt_activity_energy_info* aEnergyInfo) + { + if (NS_WARN_IF(!aEnergyInfo)) { + return; + } + + EnergyInfoNotification::Dispatch( + &BluetoothNotificationHandler::EnergyInfoNotification, + *aEnergyInfo); + } +#endif }; +#if ANDROID_VERSION >= 21 +struct BluetoothOsCallout +{ + static bool + SetWakeAlarm(uint64_t aDelayMilliseconds, + bool aShouldWake, + void (* aAlarmCallback)(void*), + void* aData) + { + // FIXME: need to be implemented in later patches + // HAL wants to manage an wake_alarm but Gecko cannot fulfill it for now. + // Simply pass the request until a proper implementation has been added. + return true; + } + + static int + AcquireWakeLock(const char* aLockName) + { + // FIXME: need to be implemented in later patches + // HAL wants to manage an wake_lock but Gecko cannot fulfill it for now. + // Simply pass the request until a proper implementation has been added. + return BT_STATUS_SUCCESS; + } + + static int + ReleaseWakeLock(const char* aLockName) + { + // FIXME: need to be implemented in later patches + // HAL wants to manage an wake_lock but Gecko cannot fulfill it for now. + // Simply pass the request until a proper implementation has been added. + return BT_STATUS_SUCCESS; + } +}; +#endif + // Interface // @@ -414,14 +463,35 @@ BluetoothHALInterface::Init( BluetoothCallback::ThreadEvt, BluetoothCallback::DutModeRecv, #if ANDROID_VERSION >= 18 - BluetoothCallback::LeTestMode + BluetoothCallback::LeTestMode, +#endif +#if ANDROID_VERSION >= 21 + BluetoothCallback::EnergyInfo #endif }; +#if ANDROID_VERSION >= 21 + static bt_os_callouts_t sBluetoothOsCallouts = { + sizeof(sBluetoothOsCallouts), + BluetoothOsCallout::SetWakeAlarm, + BluetoothOsCallout::AcquireWakeLock, + BluetoothOsCallout::ReleaseWakeLock + }; +#endif + sNotificationHandler = aNotificationHandler; int status = mInterface->init(&sBluetoothCallbacks); +#if ANDROID_VERSION >= 21 + if (status == BT_STATUS_SUCCESS) { + status = mInterface->set_os_callouts(&sBluetoothOsCallouts); + if (status != BT_STATUS_SUCCESS) { + mInterface->cleanup(); + } + } +#endif + if (aRes) { DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Init, ConvertDefault(status, STATUS_FAIL)); @@ -676,8 +746,16 @@ BluetoothHALInterface::CreateBond(const nsAString& aBdAddr, bt_bdaddr_t bdAddr; int status; +#if ANDROID_VERSION >= 21 + int transport = 0; /* TRANSPORT_AUTO */ + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) && + NS_SUCCEEDED(Convert(aTransport, transport))) { + status = mInterface->create_bond(&bdAddr, transport); +#else if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { status = mInterface->create_bond(&bdAddr); +#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -735,9 +813,19 @@ void BluetoothHALInterface::GetConnectionState(const nsAString& aBdAddr, BluetoothResultHandler* aRes) { - // TODO: to be implemented + int status; - int status = BT_STATUS_UNSUPPORTED; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->get_connection_state(&bdAddr); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = BT_STATUS_UNSUPPORTED; +#endif if (aRes) { DispatchBluetoothHALResult(aRes, @@ -858,9 +946,11 @@ BluetoothHALInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, void BluetoothHALInterface::ReadEnergyInfo(BluetoothResultHandler* aRes) { - // TODO: to be implemented - +#if ANDROID_VERSION >= 21 + int status = mInterface->read_energy_info(); +#else int status = BT_STATUS_UNSUPPORTED; +#endif if (aRes) { DispatchBluetoothHALResult(aRes, From 07061fec3cb186dfd9f2d9fab5573257f5194c9a Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:47:42 +0800 Subject: [PATCH 194/224] Bug 1102703 - Porting bluetooth interface of android lollipop (a2dp). r=shawnjohnjr --- .../bluedroid/BluetoothA2dpHALInterface.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp index 019d3fa43369..f719869fee91 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp @@ -98,6 +98,16 @@ struct BluetoothA2dpHALCallback &BluetoothA2dpNotificationHandler::AudioStateNotification, aState, aBdAddr); } + +#if ANDROID_VERSION >= 21 + static void + AudioConfig(bt_bdaddr_t *aBdAddr, uint32_t aSampleRate, uint8_t aChannelCount) + { + AudioConfigNotification::Dispatch( + &BluetoothA2dpNotificationHandler::AudioConfigNotification, + aBdAddr, aSampleRate, aChannelCount); + } +#endif }; // Interface @@ -121,7 +131,10 @@ BluetoothA2dpHALInterface::Init( static btav_callbacks_t sCallbacks = { sizeof(sCallbacks), BluetoothA2dpHALCallback::ConnectionState, - BluetoothA2dpHALCallback::AudioState + BluetoothA2dpHALCallback::AudioState, +#if ANDROID_VERSION >= 21 + BluetoothA2dpHALCallback::AudioConfig +#endif }; sA2dpNotificationHandler = aNotificationHandler; From ee6dcf6c1d4a74fd414d6357b872e70ac9f47e1b Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:48:21 +0800 Subject: [PATCH 195/224] Bug 1102703 - Porting bluetooth interface of android lollipop (handsfree). r=shawnjohnjr, r=btian, r=tzimmermann --- dom/bluetooth/bluedroid/BluetoothHALHelpers.h | 30 ++ .../BluetoothHandsfreeHALInterface.cpp | 286 +++++++++++++++++- 2 files changed, 310 insertions(+), 6 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h index ad6565075787..4827f7f3c735 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h @@ -783,6 +783,36 @@ Convert(BluetoothTransport aIn, int& aOut) nsresult Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut); + +inline nsresult +Convert(bthf_wbs_config_t aIn, BluetoothHandsfreeWbsConfig& aOut) +{ + static const BluetoothHandsfreeWbsConfig sWbsConfig[] = { + CONVERT(BTHF_WBS_NONE, HFP_WBS_NONE), + CONVERT(BTHF_WBS_NO, HFP_WBS_NO), + CONVERT(BTHF_WBS_YES, HFP_WBS_YES) + }; + if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sWbsConfig[aIn]; + return NS_OK; +} + +inline nsresult +Convert(BluetoothHandsfreeWbsConfig aIn, bthf_wbs_config_t& aOut) +{ + static const bthf_wbs_config_t sWbsConfig[] = { + CONVERT(HFP_WBS_NONE, BTHF_WBS_NONE), + CONVERT(HFP_WBS_NO, BTHF_WBS_NO), + CONVERT(HFP_WBS_YES, BTHF_WBS_YES) + }; + if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sWbsConfig[aIn]; + return NS_OK; +} #endif // ANDROID_VERSION >= 21 /* |ConvertArray| is a helper for converting arrays. Pass an diff --git a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp index 9c6f62cbf5bf..373a887d1c20 100644 --- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp @@ -113,6 +113,12 @@ struct BluetoothHandsfreeHALCallback BluetoothHandsfreeNRECState, const nsAString&> NRECNotification; + typedef BluetoothNotificationHALRunnable2< + HandsfreeNotificationHandlerWrapper, void, + BluetoothHandsfreeWbsConfig, nsString, + BluetoothHandsfreeWbsConfig, const nsAString&> + WbsNotification; + typedef BluetoothNotificationHALRunnable2< HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType, nsString, @@ -154,6 +160,7 @@ struct BluetoothHandsfreeHALCallback static void ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr) { +#if ANDROID_VERSION < 21 if (aState == BTHF_CONNECTION_STATE_CONNECTED && aBdAddr) { memcpy(&sConnectedDeviceAddress, aBdAddr, sizeof(sConnectedDeviceAddress)); @@ -161,6 +168,7 @@ struct BluetoothHandsfreeHALCallback memset(&sConnectedDeviceAddress, 0, sizeof(sConnectedDeviceAddress)); } +#endif ConnectionStateNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::ConnectionStateNotification, @@ -175,6 +183,15 @@ struct BluetoothHandsfreeHALCallback aState, aBdAddr); } +#if ANDROID_VERSION >= 21 + static void + VoiceRecognition(bthf_vr_state_t aState, bt_bdaddr_t* aBdAddr) + { + VoiceRecognitionNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, + aState, aBdAddr); + } +#else static void VoiceRecognition(bthf_vr_state_t aState) { @@ -182,7 +199,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, aState, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + AnswerCall(bt_bdaddr_t* aBdAddr) + { + AnswerCallNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, + aBdAddr); + } +#else static void AnswerCall() { @@ -190,7 +217,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + HangupCall(bt_bdaddr_t* aBdAddr) + { + HangupCallNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::HangupCallNotification, + aBdAddr); + } +#else static void HangupCall() { @@ -198,7 +235,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::HangupCallNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Volume(bthf_volume_type_t aType, int aVolume, bt_bdaddr_t* aBdAddr) + { + VolumeNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::VolumeNotification, + aType, aVolume, aBdAddr); + } +#else static void Volume(bthf_volume_type_t aType, int aVolume) { @@ -206,7 +253,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::VolumeNotification, aType, aVolume, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + DialCall(char* aNumber, bt_bdaddr_t* aBdAddr) + { + DialCallNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::DialCallNotification, + aNumber, aBdAddr); + } +#else static void DialCall(char* aNumber) { @@ -214,7 +271,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Dtmf(char aDtmf, bt_bdaddr_t* aBdAddr) + { + DtmfNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::DtmfNotification, + aDtmf, aBdAddr); + } +#else static void Dtmf(char aDtmf) { @@ -222,7 +289,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + NoiseReductionEchoCancellation(bthf_nrec_t aNrec, bt_bdaddr_t* aBdAddr) + { + NRECNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::NRECNotification, + aNrec, aBdAddr); + } +#else static void NoiseReductionEchoCancellation(bthf_nrec_t aNrec) { @@ -230,7 +307,27 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + WideBandSpeech(bthf_wbs_config_t aWbs, bt_bdaddr_t* aBdAddr) + { + WbsNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::WbsNotification, + aWbs, aBdAddr); + } +#endif + +#if ANDROID_VERSION >= 21 + static void + CallHold(bthf_chld_type_t aChld, bt_bdaddr_t* aBdAddr) + { + CallHoldNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::CallHoldNotification, + aChld, aBdAddr); + } +#else static void CallHold(bthf_chld_type_t aChld) { @@ -238,7 +335,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Cnum(bt_bdaddr_t* aBdAddr) + { + CnumNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::CnumNotification, + aBdAddr); + } +#else static void Cnum() { @@ -246,7 +353,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::CnumNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Cind(bt_bdaddr_t* aBdAddr) + { + CindNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::CindNotification, + aBdAddr); + } +#else static void Cind() { @@ -254,7 +371,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::CindNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Cops(bt_bdaddr_t* aBdAddr) + { + CopsNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::CopsNotification, + aBdAddr); + } +#else static void Cops() { @@ -262,7 +389,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::CopsNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + Clcc(bt_bdaddr_t* aBdAddr) + { + ClccNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::ClccNotification, + aBdAddr); + } +#else static void Clcc() { @@ -270,7 +407,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::ClccNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + UnknownAt(char* aAtString, bt_bdaddr_t* aBdAddr) + { + UnknownAtNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::UnknownAtNotification, + aAtString, aBdAddr); + } +#else static void UnknownAt(char* aAtString) { @@ -278,7 +425,17 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::UnknownAtNotification, aAtString, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION >= 21 + static void + KeyPressed(bt_bdaddr_t* aBdAddr) + { + KeyPressedNotification::Dispatch( + &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, + aBdAddr); + } +#else static void KeyPressed() { @@ -286,13 +443,23 @@ struct BluetoothHandsfreeHALCallback &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, &sConnectedDeviceAddress); } +#endif +#if ANDROID_VERSION < 21 + /* |sConnectedDeviceAddress| stores Bluetooth device address of the + * connected device. Before Android Lollipop, we maintain this address by + * ourselves through ConnectionState(); after Android Lollipop, every callback + * carries this address directly so we don't have to keep it. + */ static bt_bdaddr_t sConnectedDeviceAddress; +#endif }; +#if ANDROID_VERSION < 21 bt_bdaddr_t BluetoothHandsfreeHALCallback::sConnectedDeviceAddress = { {0, 0, 0, 0, 0, 0} }; +#endif // Interface // @@ -323,6 +490,9 @@ BluetoothHandsfreeHALInterface::Init( BluetoothHandsfreeHALCallback::DialCall, BluetoothHandsfreeHALCallback::Dtmf, BluetoothHandsfreeHALCallback::NoiseReductionEchoCancellation, +#if ANDROID_VERSION >= 21 + BluetoothHandsfreeHALCallback::WideBandSpeech, +#endif BluetoothHandsfreeHALCallback::CallHold, BluetoothHandsfreeHALCallback::Cnum, BluetoothHandsfreeHALCallback::Cind, @@ -334,7 +504,11 @@ BluetoothHandsfreeHALInterface::Init( sHandsfreeNotificationHandler = aNotificationHandler; +#if ANDROID_VERSION >= 21 + bt_status_t status = mInterface->init(&sCallbacks, aMaxNumClients); +#else bt_status_t status = mInterface->init(&sCallbacks); +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -444,7 +618,19 @@ BluetoothHandsfreeHALInterface::StartVoiceRecognition( const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status = mInterface->start_voice_recognition(); + bt_status_t status; + +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->start_voice_recognition(&bdAddr); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = mInterface->start_voice_recognition(); +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -458,7 +644,19 @@ BluetoothHandsfreeHALInterface::StopVoiceRecognition( const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status = mInterface->stop_voice_recognition(); + bt_status_t status; + +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->stop_voice_recognition(&bdAddr); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = mInterface->stop_voice_recognition(); +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -477,8 +675,16 @@ BluetoothHandsfreeHALInterface::VolumeControl( bt_status_t status; bthf_volume_type_t type = BTHF_VOLUME_TYPE_SPK; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aType, type)) && + NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->volume_control(type, aVolume, &bdAddr); +#else if (NS_SUCCEEDED(Convert(aType, type))) { status = mInterface->volume_control(type, aVolume); +#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -524,7 +730,19 @@ BluetoothHandsfreeHALInterface::CopsResponse( const char* aCops, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status = mInterface->cops_response(aCops); + bt_status_t status; + +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->cops_response(aCops, &bdAddr); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = mInterface->cops_response(aCops); +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -544,10 +762,20 @@ BluetoothHandsfreeHALInterface::CindResponse( bt_status_t status; bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState)) && + NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->cind_response(aSvc, aNumActive, aNumHeld, + callSetupState, aSignal, + aRoam, aBattChg, &bdAddr); +#else if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState))) { status = mInterface->cind_response(aSvc, aNumActive, aNumHeld, callSetupState, aSignal, aRoam, aBattChg); +#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -564,7 +792,19 @@ BluetoothHandsfreeHALInterface::FormattedAtResponse( const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status = mInterface->formatted_at_response(aRsp); + bt_status_t status; + +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->formatted_at_response(aRsp, &bdAddr); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = mInterface->formatted_at_response(aRsp); +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -582,8 +822,16 @@ BluetoothHandsfreeHALInterface::AtResponse( bt_status_t status; bthf_at_response_t responseCode = BTHF_AT_RESPONSE_ERROR; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aResponseCode, responseCode)) && + NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->at_response(responseCode, aErrorCode, &bdAddr); +#else if (NS_SUCCEEDED(Convert(aResponseCode, responseCode))) { status = mInterface->at_response(responseCode, aErrorCode); +#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -614,6 +862,19 @@ BluetoothHandsfreeHALInterface::ClccResponse( bthf_call_mpty_type_t mpty = BTHF_CALL_MPTY_TYPE_SINGLE; bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + + if (NS_SUCCEEDED(Convert(aDir, dir)) && + NS_SUCCEEDED(Convert(aState, state)) && + NS_SUCCEEDED(Convert(aMode, mode)) && + NS_SUCCEEDED(Convert(aMpty, mpty)) && + NS_SUCCEEDED(Convert(aType, type)) && + NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { + status = mInterface->clcc_response(aIndex, dir, state, mode, mpty, + NS_ConvertUTF16toUTF8(aNumber).get(), + type, &bdAddr); +#else if (NS_SUCCEEDED(Convert(aDir, dir)) && NS_SUCCEEDED(Convert(aState, state)) && NS_SUCCEEDED(Convert(aMode, mode)) && @@ -622,6 +883,7 @@ BluetoothHandsfreeHALInterface::ClccResponse( status = mInterface->clcc_response(aIndex, dir, state, mode, mpty, NS_ConvertUTF16toUTF8(aNumber).get(), type); +#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -669,9 +931,21 @@ BluetoothHandsfreeHALInterface::ConfigureWbs( BluetoothHandsfreeWbsConfig aConfig, BluetoothHandsfreeResultHandler* aRes) { - // TODO: to be implemented + bt_status_t status; - bt_status_t status = BT_STATUS_UNSUPPORTED; +#if ANDROID_VERSION >= 21 + bt_bdaddr_t bdAddr; + bthf_wbs_config_t wbsConfig; + + if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) && + NS_SUCCEEDED(Convert(aConfig, wbsConfig))) { + status = mInterface->configure_wbs(&bdAddr, wbsConfig); + } else { + status = BT_STATUS_PARM_INVALID; + } +#else + status = BT_STATUS_UNSUPPORTED; +#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( From 068ab4fe5535b0b27bc749c4de094ffef3e8fd36 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:49:17 +0800 Subject: [PATCH 196/224] Bug 1102703 - Porting bluetooth interface of bluez 5.26 (core). r=btian, f=tzimmermann --- .../BluetoothDaemonA2dpInterface.cpp | 4 ++- .../bluedroid/BluetoothDaemonA2dpInterface.h | 3 +++ .../BluetoothDaemonHandsfreeInterface.cpp | 3 ++- .../BluetoothDaemonHandsfreeInterface.h | 1 + .../bluedroid/BluetoothDaemonHelpers.cpp | 6 +++++ .../bluedroid/BluetoothDaemonHelpers.h | 3 +++ .../bluedroid/BluetoothDaemonInterface.cpp | 27 ++++++++++++++++--- .../BluetoothDaemonSocketInterface.cpp | 2 ++ .../BluetoothDaemonSocketInterface.h | 2 ++ 9 files changed, 45 insertions(+), 6 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp index 7c958e7cc656..a212ba82c23c 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp @@ -14,6 +14,8 @@ BEGIN_BLUETOOTH_NAMESPACE // A2DP module // +const int BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS = 1; + BluetoothA2dpNotificationHandler* BluetoothDaemonA2dpModule::sNotificationHandler; @@ -342,7 +344,7 @@ BluetoothDaemonA2dpInterface::Init( } nsresult rv = mModule->RegisterModule(BluetoothDaemonA2dpModule::SERVICE_ID, - 0x00, res); + 0x00, BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS, res); if (NS_FAILED(rv) && aRes) { DispatchError(aRes, STATUS_FAIL); } diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h index 3a70b62714e9..bccf183cc57a 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h @@ -28,9 +28,12 @@ public: OPCODE_DISCONNECT = 0x02 }; + static const int MAX_NUM_CLIENTS; + virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode, + uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) = 0; virtual nsresult UnregisterModule(uint8_t aId, diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp index bd956a6e96a7..a0dc78e6dc99 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp @@ -1318,7 +1318,8 @@ BluetoothDaemonHandsfreeInterface::Init( } nsresult rv = mModule->RegisterModule( - BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH, res); + BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH, + aMaxNumClients, res); if (NS_FAILED(rv) && aRes) { DispatchError(aRes, STATUS_FAIL); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h index 6b8d4b46b0ea..69c713a2f2e0 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h @@ -43,6 +43,7 @@ public: virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode, + uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) = 0; virtual nsresult UnregisterModule(uint8_t aId, diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp index 316721343627..2e2e9c9713c5 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp @@ -1259,6 +1259,12 @@ PackPDU(BluetoothSocketType aIn, BluetoothDaemonPDU& aPDU) return PackPDU(PackConversion(aIn), aPDU); } +nsresult +PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU) +{ + return PackPDU(PackConversion(aIn), aPDU); +} + nsresult PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU) { diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h index c0d8cc58d643..2e4174e1497c 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h @@ -418,6 +418,9 @@ PackPDU(BluetoothSspPairingVariant aIn, BluetoothDaemonPDU& aPDU); nsresult PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU); +nsresult +PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU); + nsresult PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp index 4a8b24505c27..85812a31b983 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp @@ -31,13 +31,18 @@ public: // nsresult RegisterModuleCmd(uint8_t aId, uint8_t aMode, + uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu(new BluetoothDaemonPDU(0x00, 0x01, 0)); +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU(aId, aMode, aMaxNumClients, *pdu); +#else nsresult rv = PackPDU(aId, aMode, *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -188,6 +193,9 @@ static BluetoothNotificationHandler* sNotificationHandler; class BluetoothDaemonCoreModule { public: + + static const int MAX_NUM_CLIENTS; + virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; nsresult EnableCmd(BluetoothResultHandler* aRes) @@ -413,8 +421,13 @@ public: nsAutoPtr pdu(new BluetoothDaemonPDU(0x01, 0x0d, 0)); +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + PackConversion(aBdAddr), aTransport, *pdu); +#else nsresult rv = PackPDU( PackConversion(aBdAddr), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -1354,6 +1367,8 @@ private: }; +const int BluetoothDaemonCoreModule::MAX_NUM_CLIENTS = 1; + // // Protocol handling // @@ -1418,7 +1433,7 @@ class BluetoothDaemonProtocol MOZ_FINAL public: BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection); - nsresult RegisterModule(uint8_t aId, uint8_t aMode, + nsresult RegisterModule(uint8_t aId, uint8_t aMode, uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE; nsresult UnregisterModule(uint8_t aId, @@ -1465,9 +1480,11 @@ BluetoothDaemonProtocol::BluetoothDaemonProtocol( nsresult BluetoothDaemonProtocol::RegisterModule(uint8_t aId, uint8_t aMode, + uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) { - return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, aRes); + return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, + aMaxNumClients, aRes); } nsresult @@ -1747,7 +1764,8 @@ public: if (!mRegisteredSocketModule) { mRegisteredSocketModule = true; // Init, step 4: Register Socket module - mInterface->mProtocol->RegisterModuleCmd(0x02, 0x00, this); + mInterface->mProtocol->RegisterModuleCmd(0x02, 0x00, + BluetoothDaemonSocketModule::MAX_NUM_CLIENTS, this); } else if (mRes) { // Init, step 5: Signal success to caller mRes->Init(); @@ -1786,7 +1804,8 @@ BluetoothDaemonInterface::OnConnectSuccess(enum Channel aChannel) // Init, step 3: Register Core module nsresult rv = mProtocol->RegisterModuleCmd( - 0x01, 0x00, new InitResultHandler(this, res)); + 0x01, 0x00, BluetoothDaemonCoreModule::MAX_NUM_CLIENTS, + new InitResultHandler(this, res)); if (NS_FAILED(rv) && res) { DispatchError(res, STATUS_FAIL); } diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp index 7acfae65f502..7022d19a3f15 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp @@ -15,6 +15,8 @@ BEGIN_BLUETOOTH_NAMESPACE // Socket module // +const int BluetoothDaemonSocketModule::MAX_NUM_CLIENTS = 1; + // Commands // diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h index 08243fa1d667..cda13c52774e 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h @@ -20,6 +20,8 @@ class BlutoothDaemonInterface; class BluetoothDaemonSocketModule { public: + static const int MAX_NUM_CLIENTS; + virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; // Commands From 057addefc5f49c2ea2af7c0e4c5c523f5ef888ad Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:49:49 +0800 Subject: [PATCH 197/224] Bug 1102703 - Porting bluetooth interface of bluez 5.26 (a2dp). r=btian, f=tzimmermann --- .../BluetoothDaemonA2dpInterface.cpp | 49 +++++++++++++++++++ .../bluedroid/BluetoothDaemonA2dpInterface.h | 11 ++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp index a212ba82c23c..93dfed534c20 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp @@ -262,6 +262,52 @@ BluetoothDaemonA2dpModule::AudioStateNtf( AudioStateInitOp(aPDU)); } +// Init operator class for AudioConfigNotification +class BluetoothDaemonA2dpModule::AudioConfigInitOp MOZ_FINAL + : private PDUInitOp +{ +public: + AudioConfigInitOp(BluetoothDaemonPDU& aPDU) + : PDUInitOp(aPDU) + { } + + nsresult + operator () (nsString& aArg1, uint32_t aArg2, uint8_t aArg3) const + { + BluetoothDaemonPDU& pdu = GetPDU(); + + /* Read address */ + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read sample rate */ + rv = UnpackPDU(pdu, aArg2); + if (NS_FAILED(rv)) { + return rv; + } + + /* Read channel count */ + rv = UnpackPDU(pdu, aArg3); + if (NS_FAILED(rv)) { + return rv; + } + WarnAboutTrailingData(); + return NS_OK; + } +}; + +void +BluetoothDaemonA2dpModule::AudioConfigNtf( + const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) +{ + AudioConfigNotification::Dispatch( + &BluetoothA2dpNotificationHandler::AudioConfigNotification, + AudioConfigInitOp(aPDU)); +} + void BluetoothDaemonA2dpModule::HandleNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU, @@ -271,6 +317,9 @@ BluetoothDaemonA2dpModule::HandleNtf( const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = { INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::ConnectionStateNtf), INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::AudioStateNtf), +#if ANDROID_VERSION >= 21 + INIT_ARRAY_AT(2, &BluetoothDaemonA2dpModule::AudioConfigNtf), +#endif }; MOZ_ASSERT(!NS_IsMainThread()); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h index bccf183cc57a..6e63ac3a412a 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h @@ -105,8 +105,14 @@ protected: const nsAString&> AudioStateNotification; - class AudioStateInitOp; + typedef BluetoothNotificationRunnable3 + AudioConfigNotification; + class ConnectionStateInitOp; + class AudioStateInitOp; + class AudioConfigInitOp; void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); @@ -114,6 +120,9 @@ protected: void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); + void AudioConfigNtf(const BluetoothDaemonPDUHeader& aHeader, + BluetoothDaemonPDU& aPDU); + void HandleNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU, void* aUserData); From 0003a363adfcdba3f26d99c12037225f1745c938 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:50:21 +0800 Subject: [PATCH 198/224] Bug 1102703 - Porting bluetooth interface of bluez 5.26 (handsfree). r=btian, f=tzimmermann --- .../BluetoothDaemonHandsfreeInterface.cpp | 273 +++++++++++++++--- .../BluetoothDaemonHandsfreeInterface.h | 22 +- .../bluedroid/BluetoothDaemonHelpers.h | 39 +++ 3 files changed, 282 insertions(+), 52 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp index a0dc78e6dc99..52d0b840d96a 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp @@ -17,8 +17,10 @@ BEGIN_BLUETOOTH_NAMESPACE BluetoothHandsfreeNotificationHandler* BluetoothDaemonHandsfreeModule::sNotificationHandler; +#if ANDROID_VERSION < 21 nsString BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress( NS_ConvertUTF8toUTF16(BLUETOOTH_ADDRESS_NONE)); +#endif void BluetoothDaemonHandsfreeModule::SetNotificationHandler( @@ -150,15 +152,23 @@ BluetoothDaemonHandsfreeModule::DisconnectAudioCmd( nsresult BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd( - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION, - 0)); // No payload + 6)); // Address (BlueZ 5.25) - nsresult rv = Send(pdu, aRes); + nsresult rv; +#if ANDROID_VERSION >= 21 + rv = PackPDU( + PackConversion(aRemoteAddr), *pdu); + if (NS_FAILED(rv)) { + return rv; + } +#endif + rv = Send(pdu, aRes); if (NS_FAILED(rv)) { return rv; } @@ -168,15 +178,23 @@ BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd( nsresult BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd( - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION, - 0)); // No payload + 6)); // Address (BlueZ 5.25) - nsresult rv = Send(pdu, aRes); + nsresult rv; +#if ANDROID_VERSION >= 21 + rv = PackPDU( + PackConversion(aRemoteAddr), *pdu); + if (NS_FAILED(rv)) { + return rv; + } +#endif + rv = Send(pdu, aRes); if (NS_FAILED(rv)) { return rv; } @@ -187,16 +205,23 @@ BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd( nsresult BluetoothDaemonHandsfreeModule::VolumeControlCmd( BluetoothHandsfreeVolumeType aType, int aVolume, - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL, 1 + // Volume type - 1)); // Volume + 1 + // Volume + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + aType, PackConversion(aVolume), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(aType, PackConversion(aVolume), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -239,15 +264,23 @@ BluetoothDaemonHandsfreeModule::DeviceStatusNotificationCmd( nsresult BluetoothDaemonHandsfreeModule::CopsResponseCmd( - const char* aCops, BluetoothHandsfreeResultHandler* aRes) + const char* aCops, const nsAString& aRemoteAddr, + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_COPS_RESPONSE, - 0)); // Dynamically allocated + 0 + // Dynamically allocated + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + PackCString0(nsDependentCString(aCops)), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(PackCString0(nsDependentCString(aCops)), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -264,6 +297,7 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); @@ -276,8 +310,20 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( 1 + // Call state 1 + // Signal strength 1 + // Roaming - 1)); // Battery level + 1 + // Battery level + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + PackConversion(aSvc), + PackConversion(aNumActive), + PackConversion(aNumHeld), + aCallSetupState, + PackConversion(aSignal), + PackConversion(aRoam), + PackConversion(aBattChg), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(PackConversion(aSvc), PackConversion(aNumActive), PackConversion(aNumHeld), @@ -285,6 +331,7 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( PackConversion(aSignal), PackConversion(aRoam), PackConversion(aBattChg), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -298,15 +345,23 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( nsresult BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd( - const char* aRsp, BluetoothHandsfreeResultHandler* aRes) + const char* aRsp, const nsAString& aRemoteAddr, + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE, - 0)); // Dynamically allocated + 0 + // Dynamically allocated + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + PackCString0(nsDependentCString(aRsp)), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(PackCString0(nsDependentCString(aRsp)), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -321,17 +376,24 @@ BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd( nsresult BluetoothDaemonHandsfreeModule::AtResponseCmd( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_AT_RESPONSE, 1 + // AT Response code - 1)); // Error code + 1 + // Error code + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + aResponseCode, PackConversion(aErrorCode), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(aResponseCode, PackConversion(aErrorCode), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -349,7 +411,7 @@ BluetoothDaemonHandsfreeModule::ClccResponseCmd( BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, BluetoothHandsfreeCallMode aMode, BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - BluetoothHandsfreeResultHandler* aRes) + const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); @@ -363,11 +425,20 @@ BluetoothDaemonHandsfreeModule::ClccResponseCmd( 1 + // Call mode 1 + // Call MPTY 1 + // Address type - number.Length() + 1)); // Number string + \0 + number.Length() + 1 + // Number string + \0 + 6)); // Address (BlueZ 5.25) +#if ANDROID_VERSION >= 21 + nsresult rv = PackPDU( + PackConversion(aIndex), + aDir, aState, aMode, aMpty, aType, + PackCString0(number), + PackConversion(aRemoteAddr), *pdu); +#else nsresult rv = PackPDU(PackConversion(aIndex), aDir, aState, aMode, aMpty, aType, PackCString0(number), *pdu); +#endif if (NS_FAILED(rv)) { return rv; } @@ -679,11 +750,13 @@ public: return rv; } +#if ANDROID_VERSION < 21 if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) { sConnectedDeviceAddress = aArg2; } else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) { sConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE); } +#endif WarnAboutTrailingData(); return NS_OK; } @@ -760,8 +833,15 @@ public: } /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg2 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -791,8 +871,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -822,8 +909,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -866,8 +960,15 @@ public: } /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg3)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg3 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -896,15 +997,26 @@ public: { BluetoothDaemonPDU& pdu = GetPDU(); - /* Read number */ - nsresult rv = UnpackPDU(pdu, UnpackString0(aArg1)); + nsresult rv; + /* Read address + * It's a little weird to parse aArg2(aBdAddr) before parsing + * aArg1(aNumber), but this order is defined in BlueZ 5.25 anyway. + */ +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); if (NS_FAILED(rv)) { return rv; } - - /* Read address */ - // TODO +#else aArg2 = sConnectedDeviceAddress; +#endif + + /* Read number */ + rv = UnpackPDU(pdu, UnpackString0(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } WarnAboutTrailingData(); return NS_OK; } @@ -940,8 +1052,15 @@ public: } /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg2 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -977,8 +1096,15 @@ public: } /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg2 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1014,8 +1140,15 @@ public: } /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg2 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1045,8 +1178,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1076,8 +1216,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1107,8 +1254,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1138,8 +1292,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1168,15 +1329,26 @@ public: { BluetoothDaemonPDU& pdu = GetPDU(); - /* Read string */ - nsresult rv = UnpackPDU(pdu, UnpackCString0(aArg1)); + nsresult rv; + /* Read address + * It's a little weird to parse aArg2(aBdAddr) before parsing + * aArg1(aAtString), but this order is defined in BlueZ 5.25 anyway. + */ +#if ANDROID_VERSION >= 21 + rv = UnpackPDU( + pdu, UnpackConversion(aArg2)); if (NS_FAILED(rv)) { return rv; } - - /* Read address */ - // TODO +#else aArg2 = sConnectedDeviceAddress; +#endif + + /* Read string */ + rv = UnpackPDU(pdu, UnpackCString0(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } WarnAboutTrailingData(); return NS_OK; } @@ -1206,8 +1378,15 @@ public: BluetoothDaemonPDU& pdu = GetPDU(); /* Read address */ - // TODO +#if ANDROID_VERSION >= 21 + nsresult rv = UnpackPDU( + pdu, UnpackConversion(aArg1)); + if (NS_FAILED(rv)) { + return rv; + } +#else aArg1 = sConnectedDeviceAddress; +#endif WarnAboutTrailingData(); return NS_OK; } @@ -1420,7 +1599,7 @@ BluetoothDaemonHandsfreeInterface::StartVoiceRecognition( { MOZ_ASSERT(mModule); - mModule->StartVoiceRecognitionCmd(aRes); + mModule->StartVoiceRecognitionCmd(aBdAddr, aRes); } void @@ -1429,7 +1608,7 @@ BluetoothDaemonHandsfreeInterface::StopVoiceRecognition( { MOZ_ASSERT(mModule); - mModule->StopVoiceRecognitionCmd(aRes); + mModule->StopVoiceRecognitionCmd(aBdAddr, aRes); } /* Volume */ @@ -1441,7 +1620,7 @@ BluetoothDaemonHandsfreeInterface::VolumeControl( { MOZ_ASSERT(mModule); - mModule->VolumeControlCmd(aType, aVolume, aRes); + mModule->VolumeControlCmd(aType, aVolume, aBdAddr, aRes); } /* Device status */ @@ -1467,7 +1646,7 @@ BluetoothDaemonHandsfreeInterface::CopsResponse( { MOZ_ASSERT(mModule); - mModule->CopsResponseCmd(aCops, aRes); + mModule->CopsResponseCmd(aCops, aBdAddr, aRes); } void @@ -1480,7 +1659,7 @@ BluetoothDaemonHandsfreeInterface::CindResponse( MOZ_ASSERT(mModule); mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld, aCallSetupState, - aSignal, aRoam, aBattChg, aRes); + aSignal, aRoam, aBattChg, aBdAddr, aRes); } void @@ -1490,7 +1669,7 @@ BluetoothDaemonHandsfreeInterface::FormattedAtResponse( { MOZ_ASSERT(mModule); - mModule->FormattedAtResponseCmd(aRsp, aRes); + mModule->FormattedAtResponseCmd(aRsp, aBdAddr, aRes); } void @@ -1500,7 +1679,7 @@ BluetoothDaemonHandsfreeInterface::AtResponse( { MOZ_ASSERT(mModule); - mModule->AtResponseCmd(aResponseCode, aErrorCode, aRes); + mModule->AtResponseCmd(aResponseCode, aErrorCode, aBdAddr, aRes); } void @@ -1517,7 +1696,7 @@ BluetoothDaemonHandsfreeInterface::ClccResponse( MOZ_ASSERT(mModule); mModule->ClccResponseCmd(aIndex, aDir, aState, aMode, aMpty, aNumber, - aType, aRes); + aType, aBdAddr, aRes); } /* Phone State */ diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h index 69c713a2f2e0..8da6315bf61d 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h @@ -67,12 +67,15 @@ public: /* Voice Recognition */ - nsresult StartVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes); - nsresult StopVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes); + nsresult StartVoiceRecognitionCmd(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); + nsresult StopVoiceRecognitionCmd(const nsAString& aBdAddr, + BluetoothHandsfreeResultHandler* aRes); /* Volume */ nsresult VolumeControlCmd(BluetoothHandsfreeVolumeType aType, int aVolume, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -85,16 +88,17 @@ public: /* Responses */ - nsresult CopsResponseCmd(const char* aCops, + nsresult CopsResponseCmd(const char* aCops, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); nsresult CindResponseCmd(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); - nsresult FormattedAtResponseCmd(const char* aRsp, + nsresult FormattedAtResponseCmd(const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); nsresult AtResponseCmd(BluetoothHandsfreeAtResponse aResponseCode, - int aErrorCode, + int aErrorCode, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); nsresult ClccResponseCmd(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -102,6 +106,7 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, + const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -361,7 +366,14 @@ protected: void* aUserData); static BluetoothHandsfreeNotificationHandler* sNotificationHandler; +#if ANDROID_VERSION < 21 + /* |sConnectedDeviceAddress| stores Bluetooth device address of the + * connected device. Before BlueZ 5.25, we maintain this address by ourselves + * through ConnectionStateNtf(); after BlueZ 5.25, every callback carries + * this address directly so we don't have to keep it. + */ static nsString sConnectedDeviceAddress; +#endif }; class BluetoothDaemonHandsfreeInterface MOZ_FINAL diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h index 2e4174e1497c..acc75c97368d 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h @@ -621,6 +621,45 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, return PackPDU(aIn7, aPDU); } +template +inline nsresult +PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, + const T4& aIn4, const T5& aIn5, const T6& aIn6, + const T7& aIn7, const T8& aIn8, BluetoothDaemonPDU& aPDU) +{ + nsresult rv = PackPDU(aIn1, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn2, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn3, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn4, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn5, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn6, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + rv = PackPDU(aIn7, aPDU); + if (NS_FAILED(rv)) { + return rv; + } + return PackPDU(aIn8, aPDU); +} + // // Unpacking // From c8d7126abbd1a9697ed76accab3b0ed77e3a7e20 Mon Sep 17 00:00:00 2001 From: Bruce Sun Date: Thu, 8 Jan 2015 11:51:06 +0800 Subject: [PATCH 199/224] Bug 1102703 - Enable MOZ_B2G_BT and MOZ_B2G_BT_BLUEDROID. r=shawnjohnjr --- configure.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.in b/configure.in index 9d1af15d8231..f1dcf1dd0343 100644 --- a/configure.in +++ b/configure.in @@ -290,6 +290,11 @@ if test -n "$gonkdir" ; then AC_SUBST(MOZ_AUDIO_OFFLOAD) AC_DEFINE(MOZ_AUDIO_OFFLOAD) MOZ_FMP4= + MOZ_B2G_BT=1 + MOZ_B2G_BT_BLUEDROID=1 + if test -d "$gonkdir/system/bluetoothd"; then + MOZ_B2G_BT_DAEMON=1 + fi ;; *) AC_MSG_ERROR([Unsupported platform version: $ANDROID_VERSION]) From fc5aaa82aae3ca1c43943a3a6bd8ffca430cea7d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Wed, 7 Jan 2015 20:17:19 -0800 Subject: [PATCH 200/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/48e52543ad48 Author: Greg Weng Desc: Merge pull request #27146 from snowmantw/bug1117981 Bug 1119097 - Lockscreen doesn't show updated time after rebooting, if the battery was pulled out first ======== https://hg.mozilla.org/integration/gaia-central/rev/fed853ccbf5a Author: Greg Weng Desc: Bug 1117981 - Lockscreen doesn't show updated time after being woken up from sleep --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 3b847f031e84..fc9b05a8c4f3 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "ad68423bdf19616552beb6d4fb10bc61b927eb48", + "revision": "48e52543ad483405db9ae2e527cf0dd926e8b68b", "repo_path": "integration/gaia-central" } From 887d1e7037cbd465a867ef59f5e1749786d91113 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Wed, 7 Jan 2015 20:26:58 -0800 Subject: [PATCH 201/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 509d045f51fe..96c5f7d9ea36 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2b9a5a2aba90..58e019b7bde8 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 e551a03dbeda..72b078980856 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 91965e4f61a2..77a930be4e5c 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 2b9a5a2aba90..58e019b7bde8 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 2f189ab8802e..5475389c6328 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 860368b414fb..8240ac40a906 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 3fe4b95aefa4..3d0ef43d3c5e 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 9b6dcf81e889..21f0d612c6e2 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 82f56f9805ec..2f22c0a47f88 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 355f891fd2ca..a44be947f538 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From cb3533a9d31ea6956a2be7ceb1215a83815c742f Mon Sep 17 00:00:00 2001 From: Giovanny Andres Gongora Granada Date: Thu, 8 Jan 2015 14:43:10 +0800 Subject: [PATCH 202/224] Bug 1116371 - Correct #endif comment in BluetoothMessageUtils.h, r=btian --- dom/bluetooth/ipc/BluetoothMessageUtils.h | 2 +- dom/bluetooth2/ipc/BluetoothMessageUtils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/bluetooth/ipc/BluetoothMessageUtils.h b/dom/bluetooth/ipc/BluetoothMessageUtils.h index e4dd8004ce16..46a557210111 100644 --- a/dom/bluetooth/ipc/BluetoothMessageUtils.h +++ b/dom/bluetooth/ipc/BluetoothMessageUtils.h @@ -22,4 +22,4 @@ struct ParamTraits } // namespace IPC -#endif // mozilla_dom_bluetooth_ipc_bluetoothchild_h__ +#endif // mozilla_dom_bluetooth_ipc_bluetoothmessageutils_h__ diff --git a/dom/bluetooth2/ipc/BluetoothMessageUtils.h b/dom/bluetooth2/ipc/BluetoothMessageUtils.h index 28ae9d5757f4..6bf01b59f2e0 100644 --- a/dom/bluetooth2/ipc/BluetoothMessageUtils.h +++ b/dom/bluetooth2/ipc/BluetoothMessageUtils.h @@ -30,4 +30,4 @@ struct ParamTraits } // namespace IPC -#endif // mozilla_dom_bluetooth_ipc_bluetoothchild_h__ +#endif // mozilla_dom_bluetooth_ipc_bluetoothmessageutils_h__ From fd5034e58123b5f1e1d56ebbf7783434cb2cbe24 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 05:52:15 -0800 Subject: [PATCH 203/224] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/358cd24485ad Author: Florin Strugariu Desc: Merge pull request #27206 from yzen/bug-1073651 Bug 1073651 - re-enabling test_a11y_keyboard_key_names gaia ui test. ======== https://hg.mozilla.org/integration/gaia-central/rev/df39054c1322 Author: Yura Zenevich Desc: Bug 1073651 - re-enabling test_a11y_keyboard_key_names gaia ui test. ======== https://hg.mozilla.org/integration/gaia-central/rev/0807815fc020 Author: autolander Desc: Bug 1093755 - merge pull request #27120 from albertopq:1093755-rocketbar-tray to mozilla-b2g:master ======== https://hg.mozilla.org/integration/gaia-central/rev/1173da327146 Author: albertopq Desc: Bug 1093755 - Closing search when opening utility tray --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 346c88cbfbdd..7a4762145983 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "818cae6e045eae54a72767c81c72d36b9002b022", + "revision": "358cd24485ad705a005a5c1db2736310b11e6e1b", "repo_path": "integration/gaia-central" } From e618cc6d82d8f88086da641cd77a40f16287771b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 06:01:56 -0800 Subject: [PATCH 204/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index a7f885d562da..da536749a350 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 052d3ab02c6d..517b54ea0916 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 009b63f68a55..c5e8106667d6 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 b9f6eba49978..535b1439f5c4 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 052d3ab02c6d..517b54ea0916 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index d493d9324a47..55ba6caaa058 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 987ae3616cdd..4939a58b9203 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 6d5fd3901531..c833c5056477 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 5176fb665da5..024d891b34c8 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 53fa1f4da961..628875a9fc7d 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 6a1e75427b73..2f9ee3905e7c 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 110509b6d2e10a6d1da7bc75a7feb5e70b2818ee Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 06:12:14 -0800 Subject: [PATCH 205/224] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/6e25caf02250 Author: Florin Strugariu Desc: Merge pull request #27204 from davehunt/bug1074117-search Bug 1074117 - Use expected conditions and optimise element lookups in search app object ======== https://hg.mozilla.org/integration/gaia-central/rev/8004d2f300e0 Author: Dave Hunt Desc: Bug 1074117 - Use expected conditions and optimise element lookups in search app object. r=fstrugariu ======== https://hg.mozilla.org/integration/gaia-central/rev/c11cfe9c843c Author: Guillaume C. Marty Desc: Merge pull request #27157 from gmarty/Bug-1111998-The-Play-icon-overlap-the-search-box-on-notification-bar Bug 1111998 - [Flame][Notifications]The Play icon overlap the search box... ======== https://hg.mozilla.org/integration/gaia-central/rev/989e49566302 Author: Guillaume Marty Desc: Bug 1111998 - [Flame][Notifications]The Play icon overlap the search box on notification bar --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7a4762145983..140c0a734779 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "358cd24485ad705a005a5c1db2736310b11e6e1b", + "revision": "6e25caf0225063a3548175bc36106a2da511eb41", "repo_path": "integration/gaia-central" } From 5a8cce02270c22b17b58b270c1896e9909c3c10f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 06:16:59 -0800 Subject: [PATCH 206/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index da536749a350..8aa68c87ac06 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 517b54ea0916..8d5c8e7dc2ab 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 c5e8106667d6..eae58ef46cc9 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 535b1439f5c4..b45b88e01d9e 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 517b54ea0916..8d5c8e7dc2ab 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 55ba6caaa058..225a371f5365 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 4939a58b9203..93d071700228 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index c833c5056477..d7644e87917f 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 024d891b34c8..6912192dff4c 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 628875a9fc7d..375257ae8105 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 2f9ee3905e7c..969afaf7e80e 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a2f3921cf694f08d5f5a5965e84d7079d9382e09 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 06:57:15 -0800 Subject: [PATCH 207/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/a5e6436c2d1b Author: Miller Medeiros Desc: Merge pull request #27234 from rohan013/b1035643 Bug 1035643 - Change content ellipsis color to gray in location field r=millermedeiros ======== https://hg.mozilla.org/integration/gaia-central/rev/aaa460315210 Author: Rohan Rawat Desc: Bug 1035643 - Change content ellipsis color to gray in location field --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 140c0a734779..109d117457ad 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "6e25caf0225063a3548175bc36106a2da511eb41", + "revision": "a5e6436c2d1bc9e66f2fe1b6dfcfac30c36ad7f4", "repo_path": "integration/gaia-central" } From 783c7547821ff121d9d591a9e18b4960a77887d4 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 07:01:54 -0800 Subject: [PATCH 208/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 8aa68c87ac06..82d8a82116e4 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 8d5c8e7dc2ab..aff885861443 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 eae58ef46cc9..36f27c54ec60 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 b45b88e01d9e..7e5c2bcdf32f 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 8d5c8e7dc2ab..aff885861443 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 225a371f5365..bc20524ff483 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 93d071700228..18542f1147af 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index d7644e87917f..f4cc7fbef633 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 6912192dff4c..e71f8f47ce3d 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 375257ae8105..004c9c6a8133 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 969afaf7e80e..2eee59b8a794 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 0adb188a2b249dbe8c9fcfda04720a907575209a Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 8 Jan 2015 10:22:18 -0500 Subject: [PATCH 209/224] Backed out 10 changesets (bug 1102703) for B2G JB bustage. Backed out changeset fae7478f55e5 (bug 1102703) Backed out changeset d9d1879fc90f (bug 1102703) Backed out changeset b61bf281e991 (bug 1102703) Backed out changeset f62155e4fb9c (bug 1102703) Backed out changeset ff47d1b9e86c (bug 1102703) Backed out changeset ece26b235282 (bug 1102703) Backed out changeset 9f067e4973eb (bug 1102703) Backed out changeset db035be5bc6c (bug 1102703) Backed out changeset 411ab2917e49 (bug 1102703) Backed out changeset 50eed0f4edc7 (bug 1102703) --- configure.in | 5 - dom/bluetooth/BluetoothCommon.h | 22 - dom/bluetooth/BluetoothInterface.h | 89 +-- .../bluedroid/BluetoothA2dpHALInterface.cpp | 21 +- .../BluetoothDaemonA2dpInterface.cpp | 53 +- .../bluedroid/BluetoothDaemonA2dpInterface.h | 14 +- .../BluetoothDaemonHandsfreeInterface.cpp | 618 ++---------------- .../BluetoothDaemonHandsfreeInterface.h | 128 +--- .../bluedroid/BluetoothDaemonHelpers.cpp | 6 - .../bluedroid/BluetoothDaemonHelpers.h | 42 -- .../bluedroid/BluetoothDaemonInterface.cpp | 48 +- .../bluedroid/BluetoothDaemonInterface.h | 12 +- .../BluetoothDaemonSocketInterface.cpp | 2 - .../BluetoothDaemonSocketInterface.h | 2 - .../bluedroid/BluetoothHALHelpers.cpp | 33 - dom/bluetooth/bluedroid/BluetoothHALHelpers.h | 50 -- .../bluedroid/BluetoothHALInterface.cpp | 130 +--- .../bluedroid/BluetoothHALInterface.h | 12 +- .../BluetoothHandsfreeHALInterface.cpp | 441 ++----------- .../BluetoothHandsfreeHALInterface.h | 22 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 11 +- .../bluedroid/BluetoothServiceBluedroid.h | 3 - .../bluedroid/hfp/BluetoothHfpManager.cpp | 52 +- .../bluedroid/hfp/BluetoothHfpManager.h | 31 +- 24 files changed, 212 insertions(+), 1635 deletions(-) diff --git a/configure.in b/configure.in index f1dcf1dd0343..9d1af15d8231 100644 --- a/configure.in +++ b/configure.in @@ -290,11 +290,6 @@ if test -n "$gonkdir" ; then AC_SUBST(MOZ_AUDIO_OFFLOAD) AC_DEFINE(MOZ_AUDIO_OFFLOAD) MOZ_FMP4= - MOZ_B2G_BT=1 - MOZ_B2G_BT_BLUEDROID=1 - if test -d "$gonkdir/system/bluetoothd"; then - MOZ_B2G_BT_DAEMON=1 - fi ;; *) AC_MSG_ERROR([Unsupported platform version: $ANDROID_VERSION]) diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h index cdee8da18c73..fa10f3ecaefd 100644 --- a/dom/bluetooth/BluetoothCommon.h +++ b/dom/bluetooth/BluetoothCommon.h @@ -235,22 +235,6 @@ struct BluetoothProperty { BluetoothRemoteInfo mRemoteInfo; }; -/* Physical transport for GATT connections to remote dual-mode devices */ -enum BluetoothTransport { - TRANSPORT_AUTO, /* No preference of physical transport */ - TRANSPORT_BREDR, /* Prefer BR/EDR transport */ - TRANSPORT_LE /* Prefer LE transport */ -}; - -struct BluetoothActivityEnergyInfo { - uint8_t mStatus; - uint8_t mStackState; /* stack reported state */ - uint64_t mTxTime; /* in ms */ - uint64_t mRxTime; /* in ms */ - uint64_t mIdleTime; /* in ms */ - uint64_t mEnergyUsed; /* a product of mA, V and ms */ -}; - enum BluetoothSocketType { RFCOMM = 1, SCO = 2, @@ -322,12 +306,6 @@ enum BluetoothHandsfreeNetworkState { HFP_NETWORK_STATE_AVAILABLE }; -enum BluetoothHandsfreeWbsConfig { - HFP_WBS_NONE, /* Neither CVSD nor mSBC codec, but other optional codec.*/ - HFP_WBS_NO, /* CVSD */ - HFP_WBS_YES /* mSBC */ -}; - enum BluetoothHandsfreeNRECState { HFP_NREC_STOPPED, HFP_NREC_STARTED diff --git a/dom/bluetooth/BluetoothInterface.h b/dom/bluetooth/BluetoothInterface.h index b9122c6608d6..684c66c91ae5 100644 --- a/dom/bluetooth/BluetoothInterface.h +++ b/dom/bluetooth/BluetoothInterface.h @@ -80,72 +80,59 @@ public: { } virtual void - VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState, - const nsAString& aBdAddr) + VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState) { } virtual void - AnswerCallNotification(const nsAString& aBdAddr) + AnswerCallNotification() { } virtual void - HangupCallNotification(const nsAString& aBdAddr) + HangupCallNotification() { } virtual void - VolumeNotification(BluetoothHandsfreeVolumeType aType, - int aVolume, - const nsAString& aBdAddr) + VolumeNotification(BluetoothHandsfreeVolumeType aType, int aVolume) { } virtual void - DialCallNotification(const nsAString& aNumber, - const nsAString& aBdAddr) + DialCallNotification(const nsAString& aNumber) { } virtual void - DtmfNotification(char aDtmf, - const nsAString& aBdAddr) + DtmfNotification(char aDtmf) { } virtual void - NRECNotification(BluetoothHandsfreeNRECState aNrec, - const nsAString& aBdAddr) + NRECNotification(BluetoothHandsfreeNRECState aNrec) { } virtual void - WbsNotification(BluetoothHandsfreeWbsConfig aWbs, - const nsAString& aBdAddr) + CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) { } virtual void - CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, - const nsAString& aBdAddr) + CnumNotification() { } virtual void - CnumNotification(const nsAString& aBdAddr) + CindNotification() { } virtual void - CindNotification(const nsAString& aBdAddr) + CopsNotification() { } virtual void - CopsNotification(const nsAString& aBdAddr) + ClccNotification() { } virtual void - ClccNotification(const nsAString& aBdAddr) + UnknownAtNotification(const nsACString& aAtString) { } virtual void - UnknownAtNotification(const nsACString& aAtString, - const nsAString& aBdAddr) - { } - - virtual void - KeyPressedNotification(const nsAString& aBdAddr) + KeyPressedNotification() { } protected: @@ -186,8 +173,6 @@ public: virtual void AtResponse() { } virtual void ClccResponse() { } virtual void PhoneStateChange() { } - - virtual void ConfigureWbs() { } }; class BluetoothHandsfreeInterface @@ -195,7 +180,7 @@ class BluetoothHandsfreeInterface public: virtual void Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) = 0; + BluetoothHandsfreeResultHandler* aRes) = 0; virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0; /* Connect / Disconnect */ @@ -211,15 +196,12 @@ public: /* Voice Recognition */ - virtual void StartVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void StopVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes) = 0; + virtual void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0; + virtual void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0; /* Volume */ virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; /* Device status */ @@ -231,17 +213,15 @@ public: /* Responses */ - virtual void CopsResponse(const char* aCops, const nsAString& aBdAddr, + virtual void CopsResponse(const char* aCops, BluetoothHandsfreeResultHandler* aRes) = 0; virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, + virtual void FormattedAtResponse(const char* aRsp, BluetoothHandsfreeResultHandler* aRes) = 0; - virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, - int aErrorCode, const nsAString& aBdAddr, + virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, BluetoothHandsfreeResultHandler* aRes) = 0; virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -249,7 +229,6 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) = 0; /* Phone State */ @@ -260,11 +239,6 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes) = 0; - /* Wide Band Speech */ - virtual void ConfigureWbs(const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes) = 0; - protected: BluetoothHandsfreeInterface(); virtual ~BluetoothHandsfreeInterface(); @@ -289,12 +263,6 @@ public: const nsAString& aBdAddr) { } - virtual void - AudioConfigNotification(const nsAString& aBdAddr, - uint32_t aSampleRate, - uint8_t aChannelCount) - { } - protected: BluetoothA2dpNotificationHandler() { } @@ -527,9 +495,6 @@ public: virtual void LeTestModeNotification(BluetoothStatus aStatus, uint16_t aNumPackets) { } - virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo) - { } - protected: BluetoothNotificationHandler() { } @@ -570,8 +535,6 @@ public: virtual void RemoveBond() { } virtual void CancelBond() { } - virtual void GetConnectionState() { } - virtual void PinReply() { } virtual void SspReply() { } @@ -579,8 +542,6 @@ public: virtual void DutModeSend() { } virtual void LeTestMode() { } - - virtual void ReadEnergyInfo() { } }; class BluetoothInterface @@ -630,18 +591,12 @@ public: /* Bonds */ virtual void CreateBond(const nsAString& aBdAddr, - BluetoothTransport aTransport, BluetoothResultHandler* aRes) = 0; virtual void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes) = 0; virtual void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes) = 0; - /* Connection */ - - virtual void GetConnectionState(const nsAString& aBdAddr, - BluetoothResultHandler* aRes) = 0; - /* Authentication */ virtual void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -664,10 +619,6 @@ public: virtual void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes) = 0; - /* Energy Info */ - - virtual void ReadEnergyInfo(BluetoothResultHandler* aRes) = 0; - /* Profile Interfaces */ virtual BluetoothSocketInterface* GetBluetoothSocketInterface() = 0; diff --git a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp index f719869fee91..5bd82e7c893e 100644 --- a/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothA2dpHALInterface.cpp @@ -75,12 +75,6 @@ struct BluetoothA2dpHALCallback BluetoothA2dpAudioState, const nsAString&> AudioStateNotification; - typedef BluetoothNotificationHALRunnable3< - A2dpNotificationHandlerWrapper, void, - nsString, uint32_t, uint8_t, - const nsAString&, uint32_t, uint8_t> - AudioConfigNotification; - // Bluedroid A2DP callbacks static void @@ -98,16 +92,6 @@ struct BluetoothA2dpHALCallback &BluetoothA2dpNotificationHandler::AudioStateNotification, aState, aBdAddr); } - -#if ANDROID_VERSION >= 21 - static void - AudioConfig(bt_bdaddr_t *aBdAddr, uint32_t aSampleRate, uint8_t aChannelCount) - { - AudioConfigNotification::Dispatch( - &BluetoothA2dpNotificationHandler::AudioConfigNotification, - aBdAddr, aSampleRate, aChannelCount); - } -#endif }; // Interface @@ -131,10 +115,7 @@ BluetoothA2dpHALInterface::Init( static btav_callbacks_t sCallbacks = { sizeof(sCallbacks), BluetoothA2dpHALCallback::ConnectionState, - BluetoothA2dpHALCallback::AudioState, -#if ANDROID_VERSION >= 21 - BluetoothA2dpHALCallback::AudioConfig -#endif + BluetoothA2dpHALCallback::AudioState }; sA2dpNotificationHandler = aNotificationHandler; diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp index 93dfed534c20..7c958e7cc656 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp @@ -14,8 +14,6 @@ BEGIN_BLUETOOTH_NAMESPACE // A2DP module // -const int BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS = 1; - BluetoothA2dpNotificationHandler* BluetoothDaemonA2dpModule::sNotificationHandler; @@ -262,52 +260,6 @@ BluetoothDaemonA2dpModule::AudioStateNtf( AudioStateInitOp(aPDU)); } -// Init operator class for AudioConfigNotification -class BluetoothDaemonA2dpModule::AudioConfigInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - AudioConfigInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1, uint32_t aArg2, uint8_t aArg3) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read sample rate */ - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read channel count */ - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - -void -BluetoothDaemonA2dpModule::AudioConfigNtf( - const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) -{ - AudioConfigNotification::Dispatch( - &BluetoothA2dpNotificationHandler::AudioConfigNotification, - AudioConfigInitOp(aPDU)); -} - void BluetoothDaemonA2dpModule::HandleNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU, @@ -317,9 +269,6 @@ BluetoothDaemonA2dpModule::HandleNtf( const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = { INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::ConnectionStateNtf), INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::AudioStateNtf), -#if ANDROID_VERSION >= 21 - INIT_ARRAY_AT(2, &BluetoothDaemonA2dpModule::AudioConfigNtf), -#endif }; MOZ_ASSERT(!NS_IsMainThread()); @@ -393,7 +342,7 @@ BluetoothDaemonA2dpInterface::Init( } nsresult rv = mModule->RegisterModule(BluetoothDaemonA2dpModule::SERVICE_ID, - 0x00, BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS, res); + 0x00, res); if (NS_FAILED(rv) && aRes) { DispatchError(aRes, STATUS_FAIL); } diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h index 6e63ac3a412a..3a70b62714e9 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h @@ -28,12 +28,9 @@ public: OPCODE_DISCONNECT = 0x02 }; - static const int MAX_NUM_CLIENTS; - virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode, - uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) = 0; virtual nsresult UnregisterModule(uint8_t aId, @@ -105,14 +102,8 @@ protected: const nsAString&> AudioStateNotification; - typedef BluetoothNotificationRunnable3 - AudioConfigNotification; - - class ConnectionStateInitOp; class AudioStateInitOp; - class AudioConfigInitOp; + class ConnectionStateInitOp; void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); @@ -120,9 +111,6 @@ protected: void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); - void AudioConfigNtf(const BluetoothDaemonPDUHeader& aHeader, - BluetoothDaemonPDU& aPDU); - void HandleNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU, void* aUserData); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp index 52d0b840d96a..506c776c11d1 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp @@ -17,11 +17,6 @@ BEGIN_BLUETOOTH_NAMESPACE BluetoothHandsfreeNotificationHandler* BluetoothDaemonHandsfreeModule::sNotificationHandler; -#if ANDROID_VERSION < 21 -nsString BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress( - NS_ConvertUTF8toUTF16(BLUETOOTH_ADDRESS_NONE)); -#endif - void BluetoothDaemonHandsfreeModule::SetNotificationHandler( BluetoothHandsfreeNotificationHandler* aNotificationHandler) @@ -152,23 +147,15 @@ BluetoothDaemonHandsfreeModule::DisconnectAudioCmd( nsresult BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd( - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION, - 6)); // Address (BlueZ 5.25) + 0)); // No payload - nsresult rv; -#if ANDROID_VERSION >= 21 - rv = PackPDU( - PackConversion(aRemoteAddr), *pdu); - if (NS_FAILED(rv)) { - return rv; - } -#endif - rv = Send(pdu, aRes); + nsresult rv = Send(pdu, aRes); if (NS_FAILED(rv)) { return rv; } @@ -178,23 +165,15 @@ BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd( nsresult BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd( - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION, - 6)); // Address (BlueZ 5.25) + 0)); // No payload - nsresult rv; -#if ANDROID_VERSION >= 21 - rv = PackPDU( - PackConversion(aRemoteAddr), *pdu); - if (NS_FAILED(rv)) { - return rv; - } -#endif - rv = Send(pdu, aRes); + nsresult rv = Send(pdu, aRes); if (NS_FAILED(rv)) { return rv; } @@ -205,23 +184,16 @@ BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd( nsresult BluetoothDaemonHandsfreeModule::VolumeControlCmd( BluetoothHandsfreeVolumeType aType, int aVolume, - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL, 1 + // Volume type - 1 + // Volume - 6)); // Address (BlueZ 5.25) + 1)); // Volume -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - aType, PackConversion(aVolume), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(aType, PackConversion(aVolume), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -264,23 +236,15 @@ BluetoothDaemonHandsfreeModule::DeviceStatusNotificationCmd( nsresult BluetoothDaemonHandsfreeModule::CopsResponseCmd( - const char* aCops, const nsAString& aRemoteAddr, - BluetoothHandsfreeResultHandler* aRes) + const char* aCops, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_COPS_RESPONSE, - 0 + // Dynamically allocated - 6)); // Address (BlueZ 5.25) + 0)); // Dynamically allocated -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - PackCString0(nsDependentCString(aCops)), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(PackCString0(nsDependentCString(aCops)), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -297,7 +261,6 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); @@ -310,20 +273,8 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( 1 + // Call state 1 + // Signal strength 1 + // Roaming - 1 + // Battery level - 6)); // Address (BlueZ 5.25) + 1)); // Battery level -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - PackConversion(aSvc), - PackConversion(aNumActive), - PackConversion(aNumHeld), - aCallSetupState, - PackConversion(aSignal), - PackConversion(aRoam), - PackConversion(aBattChg), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(PackConversion(aSvc), PackConversion(aNumActive), PackConversion(aNumHeld), @@ -331,7 +282,6 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( PackConversion(aSignal), PackConversion(aRoam), PackConversion(aBattChg), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -345,23 +295,15 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd( nsresult BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd( - const char* aRsp, const nsAString& aRemoteAddr, - BluetoothHandsfreeResultHandler* aRes) + const char* aRsp, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE, - 0 + // Dynamically allocated - 6)); // Address (BlueZ 5.25) + 0)); // Dynamically allocated -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - PackCString0(nsDependentCString(aRsp)), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(PackCString0(nsDependentCString(aRsp)), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -376,24 +318,17 @@ BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd( nsresult BluetoothDaemonHandsfreeModule::AtResponseCmd( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu( new BluetoothDaemonPDU(SERVICE_ID, OPCODE_AT_RESPONSE, 1 + // AT Response code - 1 + // Error code - 6)); // Address (BlueZ 5.25) + 1)); // Error code -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - aResponseCode, PackConversion(aErrorCode), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(aResponseCode, PackConversion(aErrorCode), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -411,7 +346,7 @@ BluetoothDaemonHandsfreeModule::ClccResponseCmd( BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, BluetoothHandsfreeCallMode aMode, BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); @@ -425,20 +360,11 @@ BluetoothDaemonHandsfreeModule::ClccResponseCmd( 1 + // Call mode 1 + // Call MPTY 1 + // Address type - number.Length() + 1 + // Number string + \0 - 6)); // Address (BlueZ 5.25) + number.Length() + 1)); // Number string + \0 -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - PackConversion(aIndex), - aDir, aState, aMode, aMpty, aType, - PackCString0(number), - PackConversion(aRemoteAddr), *pdu); -#else nsresult rv = PackPDU(PackConversion(aIndex), aDir, aState, aMode, aMpty, aType, PackCString0(number), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -483,19 +409,6 @@ BluetoothDaemonHandsfreeModule::PhoneStateChangeCmd( return NS_OK; } -nsresult -BluetoothDaemonHandsfreeModule::ConfigureWbsCmd( - const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // TODO: to be implemented - - return NS_ERROR_NOT_IMPLEMENTED; -} - // Responses // @@ -749,14 +662,6 @@ public: if (NS_FAILED(rv)) { return rv; } - -#if ANDROID_VERSION < 21 - if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) { - sConnectedDeviceAddress = aArg2; - } else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) { - sConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE); - } -#endif WarnAboutTrailingData(); return NS_OK; } @@ -781,7 +686,8 @@ public: { } nsresult - operator () (BluetoothHandsfreeAudioState& aArg1, nsString& aArg2) const + operator () (BluetoothHandsfreeAudioState& aArg1, + nsString& aArg2) const { BluetoothDaemonPDU& pdu = GetPDU(); @@ -811,125 +717,31 @@ BluetoothDaemonHandsfreeModule::AudioStateNtf( AudioStateInitOp(aPDU)); } -// Init operator class for VoiceRecognitionNotification -class BluetoothDaemonHandsfreeModule::VoiceRecognitionInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - VoiceRecognitionInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothHandsfreeVoiceRecognitionState& aArg1, - nsString& aArg2) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { VoiceRecognitionNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, - VoiceRecognitionInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for AnswerCallNotification -class BluetoothDaemonHandsfreeModule::AnswerCallInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - AnswerCallInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::AnswerCallNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { AnswerCallNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, - AnswerCallInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for HangupCallNotification -class BluetoothDaemonHandsfreeModule::HangupCallInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - HangupCallInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::HangupCallNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { HangupCallNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::HangupCallNotification, - HangupCallInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } // Init operator class for VolumeNotification @@ -942,8 +754,7 @@ public: { } nsresult - operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2, - nsString& aArg3) const + operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2) const { BluetoothDaemonPDU& pdu = GetPDU(); @@ -958,17 +769,6 @@ public: if (NS_FAILED(rv)) { return rv; } - - /* Read address */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg3)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg3 = sConnectedDeviceAddress; -#endif WarnAboutTrailingData(); return NS_OK; } @@ -993,27 +793,10 @@ public: { } nsresult - operator () (nsString& aArg1, nsString& aArg2) const + operator () (nsString& aArg1) const { - BluetoothDaemonPDU& pdu = GetPDU(); - - nsresult rv; - /* Read address - * It's a little weird to parse aArg2(aBdAddr) before parsing - * aArg1(aNumber), but this order is defined in BlueZ 5.25 anyway. - */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - /* Read number */ - rv = UnpackPDU(pdu, UnpackString0(aArg1)); + nsresult rv = UnpackPDU(GetPDU(), UnpackString0(aArg1)); if (NS_FAILED(rv)) { return rv; } @@ -1031,288 +814,67 @@ BluetoothDaemonHandsfreeModule::DialCallNtf( DialCallInitOp(aPDU)); } -// Init operator class for DtmfNotification -class BluetoothDaemonHandsfreeModule::DtmfInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - DtmfInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (char& aArg1, nsString& aArg2) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read tone */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::DtmfNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { DtmfNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::DtmfNotification, - DtmfInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for NRECNotification -class BluetoothDaemonHandsfreeModule::NRECInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - NRECInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothHandsfreeNRECState& aArg1, nsString& aArg2) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read state */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::NRECNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { NRECNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::NRECNotification, - NRECInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for CallHoldNotification -class BluetoothDaemonHandsfreeModule::CallHoldInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - CallHoldInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (BluetoothHandsfreeCallHoldType& aArg1, nsString& aArg2) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read type */ - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - - /* Read address */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::CallHoldNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CallHoldNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CallHoldNotification, - CallHoldInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for CnumNotification -class BluetoothDaemonHandsfreeModule::CnumInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - CnumInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::CnumNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CnumNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CnumNotification, - CnumInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for CindNotification -class BluetoothDaemonHandsfreeModule::CindInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - CindInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::CindNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CindNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CindNotification, - CindInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for CopsNotification -class BluetoothDaemonHandsfreeModule::CopsInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - CopsInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::CopsNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { CopsNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::CopsNotification, - CopsInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } -// Init operator class for ClccNotification -class BluetoothDaemonHandsfreeModule::ClccInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - ClccInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::ClccNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { ClccNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::ClccNotification, - ClccInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } // Init operator class for UnknownAtNotification @@ -1325,27 +887,10 @@ public: { } nsresult - operator () (nsCString& aArg1, nsString& aArg2) const + operator () (nsCString& aArg1) const { - BluetoothDaemonPDU& pdu = GetPDU(); - - nsresult rv; - /* Read address - * It's a little weird to parse aArg2(aBdAddr) before parsing - * aArg1(aAtString), but this order is defined in BlueZ 5.25 anyway. - */ -#if ANDROID_VERSION >= 21 - rv = UnpackPDU( - pdu, UnpackConversion(aArg2)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg2 = sConnectedDeviceAddress; -#endif - /* Read string */ - rv = UnpackPDU(pdu, UnpackCString0(aArg1)); + nsresult rv = UnpackPDU(GetPDU(), UnpackCString0(aArg1)); if (NS_FAILED(rv)) { return rv; } @@ -1363,42 +908,13 @@ BluetoothDaemonHandsfreeModule::UnknownAtNtf( UnknownAtInitOp(aPDU)); } -// Init operator class for KeyPressedNotification -class BluetoothDaemonHandsfreeModule::KeyPressedInitOp MOZ_FINAL - : private PDUInitOp -{ -public: - KeyPressedInitOp(BluetoothDaemonPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult - operator () (nsString& aArg1) const - { - BluetoothDaemonPDU& pdu = GetPDU(); - - /* Read address */ -#if ANDROID_VERSION >= 21 - nsresult rv = UnpackPDU( - pdu, UnpackConversion(aArg1)); - if (NS_FAILED(rv)) { - return rv; - } -#else - aArg1 = sConnectedDeviceAddress; -#endif - WarnAboutTrailingData(); - return NS_OK; - } -}; - void BluetoothDaemonHandsfreeModule::KeyPressedNtf( const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU) { KeyPressedNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, - KeyPressedInitOp(aPDU)); + UnpackPDUInitOp(aPDU)); } void @@ -1481,7 +997,7 @@ private: void BluetoothDaemonHandsfreeInterface::Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { // Set notification handler _before_ registering the module. It could // happen that we receive notifications, before the result handler runs. @@ -1497,8 +1013,7 @@ BluetoothDaemonHandsfreeInterface::Init( } nsresult rv = mModule->RegisterModule( - BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH, - aMaxNumClients, res); + BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH, res); if (NS_FAILED(rv) && aRes) { DispatchError(aRes, STATUS_FAIL); @@ -1595,32 +1110,32 @@ BluetoothDaemonHandsfreeInterface::DisconnectAudio( void BluetoothDaemonHandsfreeInterface::StartVoiceRecognition( - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->StartVoiceRecognitionCmd(aBdAddr, aRes); + mModule->StartVoiceRecognitionCmd(aRes); } void BluetoothDaemonHandsfreeInterface::StopVoiceRecognition( - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->StopVoiceRecognitionCmd(aBdAddr, aRes); + mModule->StopVoiceRecognitionCmd(aRes); } /* Volume */ void BluetoothDaemonHandsfreeInterface::VolumeControl( - BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr, + BluetoothHandsfreeVolumeType aType, int aVolume, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->VolumeControlCmd(aType, aVolume, aBdAddr, aRes); + mModule->VolumeControlCmd(aType, aVolume, aRes); } /* Device status */ @@ -1641,12 +1156,11 @@ BluetoothDaemonHandsfreeInterface::DeviceStatusNotification( void BluetoothDaemonHandsfreeInterface::CopsResponse( - const char* aCops, const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes) + const char* aCops, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->CopsResponseCmd(aCops, aBdAddr, aRes); + mModule->CopsResponseCmd(aCops, aRes); } void @@ -1654,32 +1168,31 @@ BluetoothDaemonHandsfreeInterface::CindResponse( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) -{ - MOZ_ASSERT(mModule); - - mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld, aCallSetupState, - aSignal, aRoam, aBattChg, aBdAddr, aRes); -} - -void -BluetoothDaemonHandsfreeInterface::FormattedAtResponse( - const char* aRsp, const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->FormattedAtResponseCmd(aRsp, aBdAddr, aRes); + mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld, aCallSetupState, + aSignal, aRoam, aBattChg, aRes); +} + +void +BluetoothDaemonHandsfreeInterface::FormattedAtResponse( + const char* aRsp, BluetoothHandsfreeResultHandler* aRes) +{ + MOZ_ASSERT(mModule); + + mModule->FormattedAtResponseCmd(aRsp, aRes); } void BluetoothDaemonHandsfreeInterface::AtResponse( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); - mModule->AtResponseCmd(aResponseCode, aErrorCode, aBdAddr, aRes); + mModule->AtResponseCmd(aResponseCode, aErrorCode, aRes); } void @@ -1690,13 +1203,12 @@ BluetoothDaemonHandsfreeInterface::ClccResponse( BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { MOZ_ASSERT(mModule); mModule->ClccResponseCmd(aIndex, aDir, aState, aMode, aMpty, aNumber, - aType, aBdAddr, aRes); + aType, aRes); } /* Phone State */ @@ -1715,18 +1227,6 @@ BluetoothDaemonHandsfreeInterface::PhoneStateChange( aType, aRes); } -/* Wide Band Speech */ - -void -BluetoothDaemonHandsfreeInterface::ConfigureWbs( - const nsAString& aBdAddr, BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes) -{ - MOZ_ASSERT(mModule); - - mModule->ConfigureWbsCmd(aBdAddr, aConfig, aRes); -} - void BluetoothDaemonHandsfreeInterface::DispatchError( BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h index 8da6315bf61d..71a233d7b237 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h @@ -43,7 +43,6 @@ public: virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode, - uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) = 0; virtual nsresult UnregisterModule(uint8_t aId, @@ -67,15 +66,12 @@ public: /* Voice Recognition */ - nsresult StartVoiceRecognitionCmd(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); - nsresult StopVoiceRecognitionCmd(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); + nsresult StartVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes); + nsresult StopVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes); /* Volume */ nsresult VolumeControlCmd(BluetoothHandsfreeVolumeType aType, int aVolume, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -88,17 +84,16 @@ public: /* Responses */ - nsresult CopsResponseCmd(const char* aCops, const nsAString& aBdAddr, + nsresult CopsResponseCmd(const char* aCops, BluetoothHandsfreeResultHandler* aRes); nsresult CindResponseCmd(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); - nsresult FormattedAtResponseCmd(const char* aRsp, const nsAString& aBdAddr, + nsresult FormattedAtResponseCmd(const char* aRsp, BluetoothHandsfreeResultHandler* aRes); nsresult AtResponseCmd(BluetoothHandsfreeAtResponse aResponseCode, - int aErrorCode, const nsAString& aBdAddr, + int aErrorCode, BluetoothHandsfreeResultHandler* aRes); nsresult ClccResponseCmd(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -106,7 +101,6 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -117,12 +111,6 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); - /* Wide Band Speech */ - - nsresult ConfigureWbsCmd(const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes); - protected: nsresult Send(BluetoothDaemonPDU* aPDU, BluetoothHandsfreeResultHandler* aRes); @@ -225,93 +213,60 @@ protected: const nsAString&> AudioStateNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 VoiceRecognitionNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 AnswerCallNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 HangupCallNotification; - typedef BluetoothNotificationRunnable3 + typedef BluetoothNotificationRunnable2 VolumeNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 DialCallNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 DtmfNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 NRECNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 CallHoldNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 CnumNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 CindNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 CopsNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 ClccNotification; - typedef BluetoothNotificationRunnable2 + typedef BluetoothNotificationRunnable1 UnknownAtNotification; - typedef BluetoothNotificationRunnable1 + typedef BluetoothNotificationRunnable0 KeyPressedNotification; - class ConnectionStateInitOp; class AudioStateInitOp; - class VoiceRecognitionInitOp; - class AnswerCallInitOp; - class HangupCallInitOp; - class VolumeInitOp; + class ConnectionStateInitOp; class DialCallInitOp; - class DtmfInitOp; - class NRECInitOp; - class CallHoldInitOp; - class CnumInitOp; - class CindInitOp; - class CopsInitOp; - class ClccInitOp; class VolumeInitOp; class UnknownAtInitOp; - class KeyPressedInitOp; void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU); @@ -366,14 +321,6 @@ protected: void* aUserData); static BluetoothHandsfreeNotificationHandler* sNotificationHandler; -#if ANDROID_VERSION < 21 - /* |sConnectedDeviceAddress| stores Bluetooth device address of the - * connected device. Before BlueZ 5.25, we maintain this address by ourselves - * through ConnectionStateNtf(); after BlueZ 5.25, every callback carries - * this address directly so we don't have to keep it. - */ - static nsString sConnectedDeviceAddress; -#endif }; class BluetoothDaemonHandsfreeInterface MOZ_FINAL @@ -394,7 +341,7 @@ public: void Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes); + BluetoothHandsfreeResultHandler* aRes); void Cleanup(BluetoothHandsfreeResultHandler* aRes); /* Connect / Disconnect */ @@ -410,15 +357,12 @@ public: /* Voice Recognition */ - void StartVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); - void StopVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); + void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); + void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); /* Volume */ void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -430,17 +374,15 @@ public: /* Responses */ - void CopsResponse(const char* aCops, const nsAString& aBdAddr, + void CopsResponse(const char* aCops, BluetoothHandsfreeResultHandler* aRes); void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); - void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, + void FormattedAtResponse(const char* aRsp, BluetoothHandsfreeResultHandler* aRes); void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -448,7 +390,6 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -459,11 +400,6 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); - /* Wide Band Speech */ - void ConfigureWbs(const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes); - private: void DispatchError(BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus); diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp index 2e2e9c9713c5..316721343627 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp @@ -1259,12 +1259,6 @@ PackPDU(BluetoothSocketType aIn, BluetoothDaemonPDU& aPDU) return PackPDU(PackConversion(aIn), aPDU); } -nsresult -PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU) -{ - return PackPDU(PackConversion(aIn), aPDU); -} - nsresult PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU) { diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h index acc75c97368d..c0d8cc58d643 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h @@ -418,9 +418,6 @@ PackPDU(BluetoothSspPairingVariant aIn, BluetoothDaemonPDU& aPDU); nsresult PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU); -nsresult -PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU); - nsresult PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU); @@ -621,45 +618,6 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, return PackPDU(aIn7, aPDU); } -template -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, const T8& aIn8, BluetoothDaemonPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn7, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn8, aPDU); -} - // // Unpacking // diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp index 85812a31b983..d7f0b19224d4 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp @@ -31,18 +31,13 @@ public: // nsresult RegisterModuleCmd(uint8_t aId, uint8_t aMode, - uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu(new BluetoothDaemonPDU(0x00, 0x01, 0)); -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU(aId, aMode, aMaxNumClients, *pdu); -#else nsresult rv = PackPDU(aId, aMode, *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -193,9 +188,6 @@ static BluetoothNotificationHandler* sNotificationHandler; class BluetoothDaemonCoreModule { public: - - static const int MAX_NUM_CLIENTS; - virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; nsresult EnableCmd(BluetoothResultHandler* aRes) @@ -414,20 +406,14 @@ public: } nsresult CreateBondCmd(const nsAString& aBdAddr, - BluetoothTransport aTransport, BluetoothResultHandler* aRes) { MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr pdu(new BluetoothDaemonPDU(0x01, 0x0d, 0)); -#if ANDROID_VERSION >= 21 - nsresult rv = PackPDU( - PackConversion(aBdAddr), aTransport, *pdu); -#else nsresult rv = PackPDU( PackConversion(aBdAddr), *pdu); -#endif if (NS_FAILED(rv)) { return rv; } @@ -1367,8 +1353,6 @@ private: }; -const int BluetoothDaemonCoreModule::MAX_NUM_CLIENTS = 1; - // // Protocol handling // @@ -1433,7 +1417,7 @@ class BluetoothDaemonProtocol MOZ_FINAL public: BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection); - nsresult RegisterModule(uint8_t aId, uint8_t aMode, uint32_t aMaxNumClients, + nsresult RegisterModule(uint8_t aId, uint8_t aMode, BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE; nsresult UnregisterModule(uint8_t aId, @@ -1480,11 +1464,9 @@ BluetoothDaemonProtocol::BluetoothDaemonProtocol( nsresult BluetoothDaemonProtocol::RegisterModule(uint8_t aId, uint8_t aMode, - uint32_t aMaxNumClients, BluetoothSetupResultHandler* aRes) { - return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, - aMaxNumClients, aRes); + return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, aRes); } nsresult @@ -1764,8 +1746,7 @@ public: if (!mRegisteredSocketModule) { mRegisteredSocketModule = true; // Init, step 4: Register Socket module - mInterface->mProtocol->RegisterModuleCmd(0x02, 0x00, - BluetoothDaemonSocketModule::MAX_NUM_CLIENTS, this); + mInterface->mProtocol->RegisterModuleCmd(0x02, 0x00, this); } else if (mRes) { // Init, step 5: Signal success to caller mRes->Init(); @@ -1804,8 +1785,7 @@ BluetoothDaemonInterface::OnConnectSuccess(enum Channel aChannel) // Init, step 3: Register Core module nsresult rv = mProtocol->RegisterModuleCmd( - 0x01, 0x00, BluetoothDaemonCoreModule::MAX_NUM_CLIENTS, - new InitResultHandler(this, res)); + 0x01, 0x00, new InitResultHandler(this, res)); if (NS_FAILED(rv) && res) { DispatchError(res, STATUS_FAIL); } @@ -2037,11 +2017,10 @@ BluetoothDaemonInterface::CancelDiscovery(BluetoothResultHandler* aRes) void BluetoothDaemonInterface::CreateBond(const nsAString& aBdAddr, - BluetoothTransport aTransport, BluetoothResultHandler* aRes) { static_cast - (mProtocol)->CreateBondCmd(aBdAddr, aTransport, aRes); + (mProtocol)->CreateBondCmd(aBdAddr, aRes); } void @@ -2060,15 +2039,6 @@ BluetoothDaemonInterface::CancelBond(const nsAString& aBdAddr, (mProtocol)->CancelBondCmd(aBdAddr, aRes); } -/* Connection */ - -void -BluetoothDaemonInterface::GetConnectionState(const nsAString& aBdAddr, - BluetoothResultHandler* aRes) -{ - // NO-OP: no corresponding interface of current BlueZ -} - /* Authentication */ void @@ -2120,14 +2090,6 @@ BluetoothDaemonInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, (mProtocol)->LeTestModeCmd(aOpcode, aBuf, aLen, aRes); } -/* Energy Information */ - -void -BluetoothDaemonInterface::ReadEnergyInfo(BluetoothResultHandler* aRes) -{ - // NO-OP: no corresponding interface of current BlueZ -} - void BluetoothDaemonInterface::DispatchError(BluetoothResultHandler* aRes, BluetoothStatus aStatus) diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h index dc094f5e91c9..b543b0318557 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h @@ -71,16 +71,10 @@ public: /* Bonds */ - void CreateBond(const nsAString& aBdAddr, BluetoothTransport aTransport, - BluetoothResultHandler* aRes); + void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); - /* Connection */ - - void GetConnectionState(const nsAString& aBdAddr, - BluetoothResultHandler* aRes); - /* Authentication */ void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -102,10 +96,6 @@ public: void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes); - /* Energy Information */ - - void ReadEnergyInfo(BluetoothResultHandler* aRes); - /* Profile Interfaces */ BluetoothSocketInterface* GetBluetoothSocketInterface() MOZ_OVERRIDE; diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp index 7022d19a3f15..7acfae65f502 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp @@ -15,8 +15,6 @@ BEGIN_BLUETOOTH_NAMESPACE // Socket module // -const int BluetoothDaemonSocketModule::MAX_NUM_CLIENTS = 1; - // Commands // diff --git a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h index cda13c52774e..08243fa1d667 100644 --- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h @@ -20,8 +20,6 @@ class BlutoothDaemonInterface; class BluetoothDaemonSocketModule { public: - static const int MAX_NUM_CLIENTS; - virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0; // Commands diff --git a/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp b/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp index 1494e975159d..e7445a989313 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.cpp @@ -211,39 +211,6 @@ Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut) } #endif // ANDROID_VERSION >= 18 -#if ANDROID_VERSION >= 21 -nsresult -Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut) -{ - nsresult rv = Convert(aIn.status, aOut.mStatus); - if (NS_FAILED(rv)) { - return rv; - } - rv = Convert(aIn.ctrl_state, aOut.mStackState); - if (NS_FAILED(rv)) { - return rv; - } - rv = Convert(aIn.tx_time, aOut.mTxTime); - if (NS_FAILED(rv)) { - return rv; - } - rv = Convert(aIn.rx_time, aOut.mRxTime); - if (NS_FAILED(rv)) { - return rv; - } - rv = Convert(aIn.idle_time, aOut.mIdleTime); - if (NS_FAILED(rv)) { - return rv; - } - rv = Convert(aIn.energy_used, aOut.mEnergyUsed); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; -} -#endif // ANDROID_VERSION >= 21 - nsresult Convert(const bt_property_t& aIn, BluetoothProperty& aOut) { diff --git a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h index 4827f7f3c735..81c71025e2a0 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALHelpers.h +++ b/dom/bluetooth/bluedroid/BluetoothHALHelpers.h @@ -765,56 +765,6 @@ Convert(btrc_remote_features_t aIn, unsigned long& aOut) } #endif // ANDROID_VERSION >= 19 -#if ANDROID_VERSION >= 21 -inline nsresult -Convert(BluetoothTransport aIn, int& aOut) -{ - static const int sTransport[] = { - CONVERT(TRANSPORT_AUTO, 0), - CONVERT(TRANSPORT_BREDR, 1), - CONVERT(TRANSPORT_LE, 2) - }; - if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sTransport))) { - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sTransport[aIn]; - return NS_OK; -} - -nsresult -Convert(const bt_activity_energy_info& aIn, BluetoothActivityEnergyInfo& aOut); - -inline nsresult -Convert(bthf_wbs_config_t aIn, BluetoothHandsfreeWbsConfig& aOut) -{ - static const BluetoothHandsfreeWbsConfig sWbsConfig[] = { - CONVERT(BTHF_WBS_NONE, HFP_WBS_NONE), - CONVERT(BTHF_WBS_NO, HFP_WBS_NO), - CONVERT(BTHF_WBS_YES, HFP_WBS_YES) - }; - if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sWbsConfig[aIn]; - return NS_OK; -} - -inline nsresult -Convert(BluetoothHandsfreeWbsConfig aIn, bthf_wbs_config_t& aOut) -{ - static const bthf_wbs_config_t sWbsConfig[] = { - CONVERT(HFP_WBS_NONE, BTHF_WBS_NONE), - CONVERT(HFP_WBS_NO, BTHF_WBS_NO), - CONVERT(HFP_WBS_YES, BTHF_WBS_YES) - }; - if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sWbsConfig))) { - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sWbsConfig[aIn]; - return NS_OK; -} -#endif // ANDROID_VERSION >= 21 - /* |ConvertArray| is a helper for converting arrays. Pass an * instance of this structure as the first argument to |Convert| * to convert an array. The output type has to support the array diff --git a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp index eedd057f0eb1..e7527181e2e7 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHALInterface.cpp @@ -176,11 +176,6 @@ struct BluetoothCallback BluetoothStatus, uint16_t> LeTestModeNotification; - typedef BluetoothNotificationHALRunnable1 - EnergyInfoNotification; - // Bluedroid callbacks static const bt_property_t* @@ -318,57 +313,8 @@ struct BluetoothCallback &BluetoothNotificationHandler::LeTestModeNotification, aStatus, aNumPackets); } - -#if ANDROID_VERSION >= 21 - static void - EnergyInfo(bt_activity_energy_info* aEnergyInfo) - { - if (NS_WARN_IF(!aEnergyInfo)) { - return; - } - - EnergyInfoNotification::Dispatch( - &BluetoothNotificationHandler::EnergyInfoNotification, - *aEnergyInfo); - } -#endif }; -#if ANDROID_VERSION >= 21 -struct BluetoothOsCallout -{ - static bool - SetWakeAlarm(uint64_t aDelayMilliseconds, - bool aShouldWake, - void (* aAlarmCallback)(void*), - void* aData) - { - // FIXME: need to be implemented in later patches - // HAL wants to manage an wake_alarm but Gecko cannot fulfill it for now. - // Simply pass the request until a proper implementation has been added. - return true; - } - - static int - AcquireWakeLock(const char* aLockName) - { - // FIXME: need to be implemented in later patches - // HAL wants to manage an wake_lock but Gecko cannot fulfill it for now. - // Simply pass the request until a proper implementation has been added. - return BT_STATUS_SUCCESS; - } - - static int - ReleaseWakeLock(const char* aLockName) - { - // FIXME: need to be implemented in later patches - // HAL wants to manage an wake_lock but Gecko cannot fulfill it for now. - // Simply pass the request until a proper implementation has been added. - return BT_STATUS_SUCCESS; - } -}; -#endif - // Interface // @@ -463,35 +409,14 @@ BluetoothHALInterface::Init( BluetoothCallback::ThreadEvt, BluetoothCallback::DutModeRecv, #if ANDROID_VERSION >= 18 - BluetoothCallback::LeTestMode, -#endif -#if ANDROID_VERSION >= 21 - BluetoothCallback::EnergyInfo + BluetoothCallback::LeTestMode #endif }; -#if ANDROID_VERSION >= 21 - static bt_os_callouts_t sBluetoothOsCallouts = { - sizeof(sBluetoothOsCallouts), - BluetoothOsCallout::SetWakeAlarm, - BluetoothOsCallout::AcquireWakeLock, - BluetoothOsCallout::ReleaseWakeLock - }; -#endif - sNotificationHandler = aNotificationHandler; int status = mInterface->init(&sBluetoothCallbacks); -#if ANDROID_VERSION >= 21 - if (status == BT_STATUS_SUCCESS) { - status = mInterface->set_os_callouts(&sBluetoothOsCallouts); - if (status != BT_STATUS_SUCCESS) { - mInterface->cleanup(); - } - } -#endif - if (aRes) { DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Init, ConvertDefault(status, STATUS_FAIL)); @@ -740,22 +665,13 @@ BluetoothHALInterface::CancelDiscovery(BluetoothResultHandler* aRes) void BluetoothHALInterface::CreateBond(const nsAString& aBdAddr, - BluetoothTransport aTransport, BluetoothResultHandler* aRes) { bt_bdaddr_t bdAddr; int status; -#if ANDROID_VERSION >= 21 - int transport = 0; /* TRANSPORT_AUTO */ - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) && - NS_SUCCEEDED(Convert(aTransport, transport))) { - status = mInterface->create_bond(&bdAddr, transport); -#else if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { status = mInterface->create_bond(&bdAddr); -#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -807,33 +723,6 @@ BluetoothHALInterface::CancelBond(const nsAString& aBdAddr, } } -/* Connection */ - -void -BluetoothHALInterface::GetConnectionState(const nsAString& aBdAddr, - BluetoothResultHandler* aRes) -{ - int status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->get_connection_state(&bdAddr); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = BT_STATUS_UNSUPPORTED; -#endif - - if (aRes) { - DispatchBluetoothHALResult(aRes, - &BluetoothResultHandler::GetConnectionState, - ConvertDefault(status, STATUS_FAIL)); - } -} - /* Authentication */ void @@ -942,23 +831,6 @@ BluetoothHALInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, } } -/* Energy Information */ -void -BluetoothHALInterface::ReadEnergyInfo(BluetoothResultHandler* aRes) -{ -#if ANDROID_VERSION >= 21 - int status = mInterface->read_energy_info(); -#else - int status = BT_STATUS_UNSUPPORTED; -#endif - - if (aRes) { - DispatchBluetoothHALResult(aRes, - &BluetoothResultHandler::ReadEnergyInfo, - ConvertDefault(status, STATUS_FAIL)); - } -} - /* Profile Interfaces */ template diff --git a/dom/bluetooth/bluedroid/BluetoothHALInterface.h b/dom/bluetooth/bluedroid/BluetoothHALInterface.h index a0f0505cafc2..9c81eab79c7a 100644 --- a/dom/bluetooth/bluedroid/BluetoothHALInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothHALInterface.h @@ -59,16 +59,10 @@ public: /* Bonds */ - void CreateBond(const nsAString& aBdAddr, BluetoothTransport aTransport, - BluetoothResultHandler* aRes); + void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes); - /* Connection */ - - void GetConnectionState(const nsAString& aBdAddr, - BluetoothResultHandler* aRes); - /* Authentication */ void PinReply(const nsAString& aBdAddr, bool aAccept, @@ -90,10 +84,6 @@ public: void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen, BluetoothResultHandler* aRes); - /* Energy Information */ - - void ReadEnergyInfo(BluetoothResultHandler* aRes); - /* Profile Interfaces */ BluetoothSocketInterface* GetBluetoothSocketInterface(); diff --git a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp index 373a887d1c20..b996363d59b8 100644 --- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.cpp @@ -75,84 +75,62 @@ struct BluetoothHandsfreeHALCallback BluetoothHandsfreeAudioState, const nsAString&> AudioStateNotification; - typedef BluetoothNotificationHALRunnable2< + typedef BluetoothNotificationHALRunnable1< HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeVoiceRecognitionState, nsString, - BluetoothHandsfreeVoiceRecognitionState, const nsAString&> + BluetoothHandsfreeVoiceRecognitionState> VoiceRecognitionNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> AnswerCallNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> HangupCallNotification; - typedef BluetoothNotificationHALRunnable3< + typedef BluetoothNotificationHALRunnable2< HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeVolumeType, int, nsString, - BluetoothHandsfreeVolumeType, int, const nsAString&> + BluetoothHandsfreeVolumeType, int> VolumeNotification; - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - nsString, nsString, const nsAString&, const nsAString&> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, nsString, const nsAString&> DialCallNotification; - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - char, nsString, char, const nsAString&> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, char> DtmfNotification; - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeNRECState, nsString, - BluetoothHandsfreeNRECState, const nsAString&> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeNRECState> NRECNotification; - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeWbsConfig, nsString, - BluetoothHandsfreeWbsConfig, const nsAString&> - WbsNotification; - - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - BluetoothHandsfreeCallHoldType, nsString, - BluetoothHandsfreeCallHoldType, const nsAString&> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType> CallHoldNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> CnumNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> CindNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> CopsNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> ClccNotification; - typedef BluetoothNotificationHALRunnable2< - HandsfreeNotificationHandlerWrapper, void, - nsCString, nsString, const nsACString&, const nsAString&> + typedef BluetoothNotificationHALRunnable1< + HandsfreeNotificationHandlerWrapper, void, nsCString, const nsACString&> UnknownAtNotification; - typedef BluetoothNotificationHALRunnable1< - HandsfreeNotificationHandlerWrapper, void, - nsString, const nsAString&> + typedef BluetoothNotificationHALRunnable0< + HandsfreeNotificationHandlerWrapper, void> KeyPressedNotification; // Bluedroid Handsfree callbacks @@ -160,16 +138,6 @@ struct BluetoothHandsfreeHALCallback static void ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr) { -#if ANDROID_VERSION < 21 - if (aState == BTHF_CONNECTION_STATE_CONNECTED && aBdAddr) { - memcpy(&sConnectedDeviceAddress, aBdAddr, - sizeof(sConnectedDeviceAddress)); - } else if (aState == BTHF_CONNECTION_STATE_DISCONNECTED) { - memset(&sConnectedDeviceAddress, 0, - sizeof(sConnectedDeviceAddress)); - } -#endif - ConnectionStateNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::ConnectionStateNotification, aState, aBdAddr); @@ -183,284 +151,108 @@ struct BluetoothHandsfreeHALCallback aState, aBdAddr); } -#if ANDROID_VERSION >= 21 - static void - VoiceRecognition(bthf_vr_state_t aState, bt_bdaddr_t* aBdAddr) - { - VoiceRecognitionNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, - aState, aBdAddr); - } -#else static void VoiceRecognition(bthf_vr_state_t aState) { VoiceRecognitionNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification, - aState, &sConnectedDeviceAddress); + aState); } -#endif -#if ANDROID_VERSION >= 21 - static void - AnswerCall(bt_bdaddr_t* aBdAddr) - { - AnswerCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, - aBdAddr); - } -#else static void AnswerCall() { AnswerCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::AnswerCallNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::AnswerCallNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - HangupCall(bt_bdaddr_t* aBdAddr) - { - HangupCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::HangupCallNotification, - aBdAddr); - } -#else static void HangupCall() { HangupCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::HangupCallNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::HangupCallNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - Volume(bthf_volume_type_t aType, int aVolume, bt_bdaddr_t* aBdAddr) - { - VolumeNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::VolumeNotification, - aType, aVolume, aBdAddr); - } -#else static void Volume(bthf_volume_type_t aType, int aVolume) { VolumeNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::VolumeNotification, - aType, aVolume, &sConnectedDeviceAddress); + aType, aVolume); } -#endif -#if ANDROID_VERSION >= 21 - static void - DialCall(char* aNumber, bt_bdaddr_t* aBdAddr) - { - DialCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DialCallNotification, - aNumber, aBdAddr); - } -#else static void DialCall(char* aNumber) { DialCallNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DialCallNotification, - aNumber, &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber); } -#endif -#if ANDROID_VERSION >= 21 - static void - Dtmf(char aDtmf, bt_bdaddr_t* aBdAddr) - { - DtmfNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DtmfNotification, - aDtmf, aBdAddr); - } -#else static void Dtmf(char aDtmf) { DtmfNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::DtmfNotification, - aDtmf, &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf); } -#endif -#if ANDROID_VERSION >= 21 - static void - NoiseReductionEchoCancellation(bthf_nrec_t aNrec, bt_bdaddr_t* aBdAddr) - { - NRECNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::NRECNotification, - aNrec, aBdAddr); - } -#else static void NoiseReductionEchoCancellation(bthf_nrec_t aNrec) { NRECNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::NRECNotification, - aNrec, &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec); } -#endif -#if ANDROID_VERSION >= 21 - static void - WideBandSpeech(bthf_wbs_config_t aWbs, bt_bdaddr_t* aBdAddr) - { - WbsNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::WbsNotification, - aWbs, aBdAddr); - } -#endif - -#if ANDROID_VERSION >= 21 - static void - CallHold(bthf_chld_type_t aChld, bt_bdaddr_t* aBdAddr) - { - CallHoldNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CallHoldNotification, - aChld, aBdAddr); - } -#else static void CallHold(bthf_chld_type_t aChld) { CallHoldNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CallHoldNotification, - aChld, &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld); } -#endif -#if ANDROID_VERSION >= 21 - static void - Cnum(bt_bdaddr_t* aBdAddr) - { - CnumNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CnumNotification, - aBdAddr); - } -#else static void Cnum() { CnumNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CnumNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::CnumNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - Cind(bt_bdaddr_t* aBdAddr) - { - CindNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CindNotification, - aBdAddr); - } -#else static void Cind() { CindNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CindNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::CindNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - Cops(bt_bdaddr_t* aBdAddr) - { - CopsNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CopsNotification, - aBdAddr); - } -#else static void Cops() { CopsNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::CopsNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::CopsNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - Clcc(bt_bdaddr_t* aBdAddr) - { - ClccNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::ClccNotification, - aBdAddr); - } -#else static void Clcc() { ClccNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::ClccNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::ClccNotification); } -#endif -#if ANDROID_VERSION >= 21 - static void - UnknownAt(char* aAtString, bt_bdaddr_t* aBdAddr) - { - UnknownAtNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::UnknownAtNotification, - aAtString, aBdAddr); - } -#else static void UnknownAt(char* aAtString) { UnknownAtNotification::Dispatch( &BluetoothHandsfreeNotificationHandler::UnknownAtNotification, - aAtString, &sConnectedDeviceAddress); + aAtString); } -#endif -#if ANDROID_VERSION >= 21 - static void - KeyPressed(bt_bdaddr_t* aBdAddr) - { - KeyPressedNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, - aBdAddr); - } -#else static void KeyPressed() { KeyPressedNotification::Dispatch( - &BluetoothHandsfreeNotificationHandler::KeyPressedNotification, - &sConnectedDeviceAddress); + &BluetoothHandsfreeNotificationHandler::KeyPressedNotification); } -#endif - -#if ANDROID_VERSION < 21 - /* |sConnectedDeviceAddress| stores Bluetooth device address of the - * connected device. Before Android Lollipop, we maintain this address by - * ourselves through ConnectionState(); after Android Lollipop, every callback - * carries this address directly so we don't have to keep it. - */ - static bt_bdaddr_t sConnectedDeviceAddress; -#endif }; -#if ANDROID_VERSION < 21 -bt_bdaddr_t BluetoothHandsfreeHALCallback::sConnectedDeviceAddress = { - {0, 0, 0, 0, 0, 0} -}; -#endif - // Interface // @@ -477,7 +269,7 @@ BluetoothHandsfreeHALInterface::~BluetoothHandsfreeHALInterface() void BluetoothHandsfreeHALInterface::Init( BluetoothHandsfreeNotificationHandler* aNotificationHandler, - int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) + BluetoothHandsfreeResultHandler* aRes) { static bthf_callbacks_t sCallbacks = { sizeof(sCallbacks), @@ -490,9 +282,6 @@ BluetoothHandsfreeHALInterface::Init( BluetoothHandsfreeHALCallback::DialCall, BluetoothHandsfreeHALCallback::Dtmf, BluetoothHandsfreeHALCallback::NoiseReductionEchoCancellation, -#if ANDROID_VERSION >= 21 - BluetoothHandsfreeHALCallback::WideBandSpeech, -#endif BluetoothHandsfreeHALCallback::CallHold, BluetoothHandsfreeHALCallback::Cnum, BluetoothHandsfreeHALCallback::Cind, @@ -504,11 +293,7 @@ BluetoothHandsfreeHALInterface::Init( sHandsfreeNotificationHandler = aNotificationHandler; -#if ANDROID_VERSION >= 21 - bt_status_t status = mInterface->init(&sCallbacks, aMaxNumClients); -#else bt_status_t status = mInterface->init(&sCallbacks); -#endif if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -615,22 +400,9 @@ BluetoothHandsfreeHALInterface::DisconnectAudio( void BluetoothHandsfreeHALInterface::StartVoiceRecognition( - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->start_voice_recognition(&bdAddr); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = mInterface->start_voice_recognition(); -#endif + bt_status_t status = mInterface->start_voice_recognition(); if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -641,22 +413,9 @@ BluetoothHandsfreeHALInterface::StartVoiceRecognition( void BluetoothHandsfreeHALInterface::StopVoiceRecognition( - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->stop_voice_recognition(&bdAddr); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = mInterface->stop_voice_recognition(); -#endif + bt_status_t status = mInterface->stop_voice_recognition(); if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -669,22 +428,14 @@ BluetoothHandsfreeHALInterface::StopVoiceRecognition( void BluetoothHandsfreeHALInterface::VolumeControl( - BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr, + BluetoothHandsfreeVolumeType aType, int aVolume, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; bthf_volume_type_t type = BTHF_VOLUME_TYPE_SPK; -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aType, type)) && - NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->volume_control(type, aVolume, &bdAddr); -#else if (NS_SUCCEEDED(Convert(aType, type))) { status = mInterface->volume_control(type, aVolume); -#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -727,22 +478,9 @@ BluetoothHandsfreeHALInterface::DeviceStatusNotification( void BluetoothHandsfreeHALInterface::CopsResponse( - const char* aCops, const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes) + const char* aCops, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->cops_response(aCops, &bdAddr); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = mInterface->cops_response(aCops); -#endif + bt_status_t status = mInterface->cops_response(aCops); if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -756,26 +494,15 @@ BluetoothHandsfreeHALInterface::CindResponse( int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, int aRoam, int aBattChg, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE; -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState)) && - NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->cind_response(aSvc, aNumActive, aNumHeld, - callSetupState, aSignal, - aRoam, aBattChg, &bdAddr); -#else if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState))) { status = mInterface->cind_response(aSvc, aNumActive, aNumHeld, callSetupState, aSignal, aRoam, aBattChg); -#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -789,22 +516,9 @@ BluetoothHandsfreeHALInterface::CindResponse( void BluetoothHandsfreeHALInterface::FormattedAtResponse( - const char* aRsp, const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes) + const char* aRsp, BluetoothHandsfreeResultHandler* aRes) { - bt_status_t status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->formatted_at_response(aRsp, &bdAddr); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = mInterface->formatted_at_response(aRsp); -#endif + bt_status_t status = mInterface->formatted_at_response(aRsp); if (aRes) { DispatchBluetoothHandsfreeHALResult( @@ -816,22 +530,13 @@ BluetoothHandsfreeHALInterface::FormattedAtResponse( void BluetoothHandsfreeHALInterface::AtResponse( BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; bthf_at_response_t responseCode = BTHF_AT_RESPONSE_ERROR; -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aResponseCode, responseCode)) && - NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->at_response(responseCode, aErrorCode, &bdAddr); -#else if (NS_SUCCEEDED(Convert(aResponseCode, responseCode))) { status = mInterface->at_response(responseCode, aErrorCode); -#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -852,7 +557,6 @@ BluetoothHandsfreeHALInterface::ClccResponse( BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes) { bt_status_t status; @@ -862,19 +566,6 @@ BluetoothHandsfreeHALInterface::ClccResponse( bthf_call_mpty_type_t mpty = BTHF_CALL_MPTY_TYPE_SINGLE; bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN; -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - - if (NS_SUCCEEDED(Convert(aDir, dir)) && - NS_SUCCEEDED(Convert(aState, state)) && - NS_SUCCEEDED(Convert(aMode, mode)) && - NS_SUCCEEDED(Convert(aMpty, mpty)) && - NS_SUCCEEDED(Convert(aType, type)) && - NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) { - status = mInterface->clcc_response(aIndex, dir, state, mode, mpty, - NS_ConvertUTF16toUTF8(aNumber).get(), - type, &bdAddr); -#else if (NS_SUCCEEDED(Convert(aDir, dir)) && NS_SUCCEEDED(Convert(aState, state)) && NS_SUCCEEDED(Convert(aMode, mode)) && @@ -883,7 +574,6 @@ BluetoothHandsfreeHALInterface::ClccResponse( status = mInterface->clcc_response(aIndex, dir, state, mode, mpty, NS_ConvertUTF16toUTF8(aNumber).get(), type); -#endif } else { status = BT_STATUS_PARM_INVALID; } @@ -923,35 +613,4 @@ BluetoothHandsfreeHALInterface::PhoneStateChange(int aNumActive, int aNumHeld, } } -/* Wide Band Speech */ - -void -BluetoothHandsfreeHALInterface::ConfigureWbs( - const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes) -{ - bt_status_t status; - -#if ANDROID_VERSION >= 21 - bt_bdaddr_t bdAddr; - bthf_wbs_config_t wbsConfig; - - if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) && - NS_SUCCEEDED(Convert(aConfig, wbsConfig))) { - status = mInterface->configure_wbs(&bdAddr, wbsConfig); - } else { - status = BT_STATUS_PARM_INVALID; - } -#else - status = BT_STATUS_UNSUPPORTED; -#endif - - if (aRes) { - DispatchBluetoothHandsfreeHALResult( - aRes, &BluetoothHandsfreeResultHandler::ConfigureWbs, - ConvertDefault(status, STATUS_FAIL)); - } -} - END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h index 905d3a89c12a..f53d4251fb65 100644 --- a/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothHandsfreeHALInterface.h @@ -23,7 +23,6 @@ public: friend class BluetoothHALInterface; void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler, - int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes); void Cleanup(BluetoothHandsfreeResultHandler* aRes); @@ -40,15 +39,12 @@ public: /* Voice Recognition */ - void StartVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); - void StopVoiceRecognition(const nsAString& aBdAddr, - BluetoothHandsfreeResultHandler* aRes); + void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); + void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes); /* Volume */ void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Device status */ @@ -60,16 +56,15 @@ public: /* Responses */ - void CopsResponse(const char* aCops, const nsAString& aBdAddr, + void CopsResponse(const char* aCops, BluetoothHandsfreeResultHandler* aRes); void CindResponse(int aSvc, int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState, int aSignal, - int aRoam, int aBattChg, const nsAString& aBdAddr, + int aRoam, int aBattChg, BluetoothHandsfreeResultHandler* aRes); - void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr, + void FormattedAtResponse(const char* aRsp, BluetoothHandsfreeResultHandler* aRes); void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState, @@ -77,7 +72,6 @@ public: BluetoothHandsfreeCallMptyType aMpty, const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType, - const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes); /* Phone State */ @@ -88,12 +82,6 @@ public: BluetoothHandsfreeCallAddressType aType, BluetoothHandsfreeResultHandler* aRes); - /* Wide Band Speech */ - - void ConfigureWbs(const nsAString& aBdAddr, - BluetoothHandsfreeWbsConfig aConfig, - BluetoothHandsfreeResultHandler* aRes); - protected: BluetoothHandsfreeHALInterface(const bthf_interface_t* aInterface); ~BluetoothHandsfreeHALInterface(); diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index b6fd6af1e357..81ead9071a5b 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -693,7 +693,7 @@ BluetoothServiceBluedroid::CreatePairedDeviceInternal( sBondingRunnableArray.AppendElement(aRunnable); - sBtInterface->CreateBond(aDeviceAddress, TRANSPORT_AUTO, + sBtInterface->CreateBond(aDeviceAddress, new CreateBondResultHandler(aRunnable)); return NS_OK; @@ -1623,12 +1623,3 @@ BluetoothServiceBluedroid::LeTestModeNotification(BluetoothStatus aStatus, // FIXME: This will be implemented in the later patchset } - -void -BluetoothServiceBluedroid::EnergyInfoNotification( - const BluetoothActivityEnergyInfo& aInfo) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // FIXME: This will be implemented in the later patchset -} diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h index 9600cf6bcd05..f9f3c0dc00f7 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h @@ -212,9 +212,6 @@ public: virtual void LeTestModeNotification(BluetoothStatus aStatus, uint16_t aNumPackets) MOZ_OVERRIDE; - virtual void EnergyInfoNotification( - const BluetoothActivityEnergyInfo& aInfo) MOZ_OVERRIDE; - protected: static nsresult StartGonkBluetooth(); static nsresult StopGonkBluetooth(); diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp index e36add11e458..00866f59dee5 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp @@ -57,8 +57,6 @@ namespace { static int sBusyToneInterval = 3700; //unit: ms } // anonymous namespace -const int BluetoothHfpManager::MAX_NUM_CLIENTS = 1; - static bool IsValidDtmf(const char aChar) { // Valid DTMF: [*#0-9ABCD] @@ -310,7 +308,7 @@ public: { BluetoothHfpManager* hfpManager = BluetoothHfpManager::Get(); - mInterface->Init(hfpManager, BluetoothHfpManager::MAX_NUM_CLIENTS, this); + mInterface->Init(hfpManager, this); } private: @@ -640,9 +638,8 @@ BluetoothHfpManager::HandleVolumeChanged(nsISupports* aSubject) // Only send volume back when there's a connected headset if (IsConnected()) { NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); - sBluetoothHfpInterface->VolumeControl( - HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, mDeviceAddress, - new VolumeControlResultHandler()); + sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, + new VolumeControlResultHandler()); } } @@ -770,7 +767,7 @@ BluetoothHfpManager::SendCLCC(Call& aCall, int aIndex) sBluetoothHfpInterface->ClccResponse( aIndex, aCall.mDirection, callState, HFP_CALL_MODE_VOICE, HFP_CALL_MPTY_TYPE_SINGLE, aCall.mNumber, - aCall.mType, mDeviceAddress, new ClccResponseResultHandler()); + aCall.mType, new ClccResponseResultHandler()); } class FormattedAtResponseResultHandler MOZ_FINAL @@ -790,7 +787,7 @@ BluetoothHfpManager::SendLine(const char* aMessage) NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); sBluetoothHfpInterface->FormattedAtResponse( - aMessage, mDeviceAddress, new FormattedAtResponseResultHandler()); + aMessage, new FormattedAtResponseResultHandler()); } class AtResponseResultHandler MOZ_FINAL @@ -810,7 +807,7 @@ BluetoothHfpManager::SendResponse(BluetoothHandsfreeAtResponse aResponseCode) NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface); sBluetoothHfpInterface->AtResponse( - aResponseCode, 0, mDeviceAddress, new AtResponseResultHandler()); + aResponseCode, 0, new AtResponseResultHandler()); } class PhoneStateChangeResultHandler MOZ_FINAL @@ -1364,7 +1361,7 @@ BluetoothHfpManager::AudioStateNotification( } void -BluetoothHfpManager::AnswerCallNotification(const nsAString& aBdAddress) +BluetoothHfpManager::AnswerCallNotification() { MOZ_ASSERT(NS_IsMainThread()); @@ -1372,7 +1369,7 @@ BluetoothHfpManager::AnswerCallNotification(const nsAString& aBdAddress) } void -BluetoothHfpManager::HangupCallNotification(const nsAString& aBdAddress) +BluetoothHfpManager::HangupCallNotification() { MOZ_ASSERT(NS_IsMainThread()); @@ -1381,7 +1378,7 @@ BluetoothHfpManager::HangupCallNotification(const nsAString& aBdAddress) void BluetoothHfpManager::VolumeNotification( - BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddress) + BluetoothHandsfreeVolumeType aType, int aVolume) { MOZ_ASSERT(NS_IsMainThread()); @@ -1408,7 +1405,7 @@ BluetoothHfpManager::VolumeNotification( } void -BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress) +BluetoothHfpManager::DtmfNotification(char aDtmf) { MOZ_ASSERT(NS_IsMainThread()); @@ -1420,8 +1417,7 @@ BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress) } void -BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, - const nsAString& aBdAddress) +BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) { MOZ_ASSERT(NS_IsMainThread()); @@ -1439,8 +1435,7 @@ BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, NotifyDialer(NS_ConvertUTF8toUTF16(message)); } -void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber, - const nsAString& aBdAddress) +void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber) { MOZ_ASSERT(NS_IsMainThread()); @@ -1481,7 +1476,7 @@ void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber, } void -BluetoothHfpManager::CnumNotification(const nsAString& aBdAddress) +BluetoothHfpManager::CnumNotification() { static const uint8_t sAddressType[] { [HFP_CALL_ADDRESS_TYPE_UNKNOWN] = 0x81, @@ -1515,7 +1510,7 @@ public: }; void -BluetoothHfpManager::CindNotification(const nsAString& aBdAddress) +BluetoothHfpManager::CindNotification() { MOZ_ASSERT(NS_IsMainThread()); @@ -1526,11 +1521,9 @@ BluetoothHfpManager::CindNotification(const nsAString& aBdAddress) BluetoothHandsfreeCallState callState = ConvertToBluetoothHandsfreeCallState(GetCallSetupState()); - sBluetoothHfpInterface->CindResponse( - mService, numActive, numHeld, - callState, mSignal, mRoam, mBattChg, - aBdAddress, - new CindResponseResultHandler()); + sBluetoothHfpInterface->CindResponse(mService, numActive, numHeld, + callState, mSignal, mRoam, mBattChg, + new CindResponseResultHandler()); } class CopsResponseResultHandler MOZ_FINAL @@ -1545,7 +1538,7 @@ public: }; void -BluetoothHfpManager::CopsNotification(const nsAString& aBdAddress) +BluetoothHfpManager::CopsNotification() { MOZ_ASSERT(NS_IsMainThread()); @@ -1553,11 +1546,11 @@ BluetoothHfpManager::CopsNotification(const nsAString& aBdAddress) sBluetoothHfpInterface->CopsResponse( NS_ConvertUTF16toUTF8(mOperatorName).get(), - aBdAddress, new CopsResponseResultHandler()); + new CopsResponseResultHandler()); } void -BluetoothHfpManager::ClccNotification(const nsAString& aBdAddress) +BluetoothHfpManager::ClccNotification() { MOZ_ASSERT(NS_IsMainThread()); @@ -1578,8 +1571,7 @@ BluetoothHfpManager::ClccNotification(const nsAString& aBdAddress) } void -BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString, - const nsAString& aBdAddress) +BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString) { MOZ_ASSERT(NS_IsMainThread()); @@ -1589,7 +1581,7 @@ BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString, } void -BluetoothHfpManager::KeyPressedNotification(const nsAString& aBdAddress) +BluetoothHfpManager::KeyPressedNotification() { MOZ_ASSERT(NS_IsMainThread()); diff --git a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h index 30d4d688a2ea..4cafcfe52504 100644 --- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h +++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h @@ -77,8 +77,6 @@ class BluetoothHfpManager : public BluetoothHfpManagerBase public: BT_DECL_HFP_MGR_BASE - static const int MAX_NUM_CLIENTS; - void OnConnectError(); void OnDisconnectError(); @@ -119,24 +117,19 @@ public: const nsAString& aBdAddress) MOZ_OVERRIDE; void AudioStateNotification(BluetoothHandsfreeAudioState aState, const nsAString& aBdAddress) MOZ_OVERRIDE; - void AnswerCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; - void HangupCallNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + void AnswerCallNotification() MOZ_OVERRIDE; + void HangupCallNotification() MOZ_OVERRIDE; void VolumeNotification(BluetoothHandsfreeVolumeType aType, - int aVolume, - const nsAString& aBdAddress) MOZ_OVERRIDE; - void DtmfNotification(char aDtmf, - const nsAString& aBdAddress) MOZ_OVERRIDE; - void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld, - const nsAString& aBdAddress) MOZ_OVERRIDE; - void DialCallNotification(const nsAString& aNumber, - const nsAString& aBdAddress) MOZ_OVERRIDE; - void CnumNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; - void CindNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; - void CopsNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; - void ClccNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; - void UnknownAtNotification(const nsACString& aAtString, - const nsAString& aBdAddress) MOZ_OVERRIDE; - void KeyPressedNotification(const nsAString& aBdAddress) MOZ_OVERRIDE; + int aVolume) MOZ_OVERRIDE; + void DtmfNotification(char aDtmf) MOZ_OVERRIDE; + void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld) MOZ_OVERRIDE; + void DialCallNotification(const nsAString& aNumber) MOZ_OVERRIDE; + void CnumNotification() MOZ_OVERRIDE; + void CindNotification() MOZ_OVERRIDE; + void CopsNotification() MOZ_OVERRIDE; + void ClccNotification() MOZ_OVERRIDE; + void UnknownAtNotification(const nsACString& aAtString) MOZ_OVERRIDE; + void KeyPressedNotification() MOZ_OVERRIDE; private: class GetVolumeTask; From 9ec39370aaddb01c155f6b92e3a29db86bd94e1f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 07:42:16 -0800 Subject: [PATCH 210/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/351d3daeacc5 Author: Chris Lord Desc: Merge pull request #27246 from Cwiiis/bug1118311-followup Bug 1118311 - Fix linter error in previous patch. r=me ======== https://hg.mozilla.org/integration/gaia-central/rev/56522e161f27 Author: Chris Lord Desc: Bug 1118311 - Fix linter error in previous patch. r=me --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 109d117457ad..4ed0d34d532b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "a5e6436c2d1bc9e66f2fe1b6dfcfac30c36ad7f4", + "revision": "351d3daeacc53b00b68356b0e6547a3f6840ee67", "repo_path": "integration/gaia-central" } From ce58edc4e2ba2f24c53e150445c49cc2c4559ced Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 07:51:56 -0800 Subject: [PATCH 211/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 82d8a82116e4..b451b39f69a7 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index aff885861443..85c376f912f6 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 36f27c54ec60..c42ac9c59009 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 7e5c2bcdf32f..cef8e48f24d4 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 aff885861443..85c376f912f6 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index bc20524ff483..76afbf0578ce 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 18542f1147af..1a38f0f89b00 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index f4cc7fbef633..3cf697a5cbdc 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 e71f8f47ce3d..8f4eb8b95858 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 004c9c6a8133..776c1f242df0 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 2eee59b8a794..b13ff3091123 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From ec2a43f407067bfa8a4839367e5c0bb4ff287093 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 07:57:15 -0800 Subject: [PATCH 212/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/f66829c60c08 Author: Salvador de la Puente González Desc: Merge pull request #25656 from lodr/bug-1091486-change-to-mms-when-entering-email-thread Bug 1091486 - [SMS] Switch to MMS when entering a email recipient thread r=azasypkin ======== https://hg.mozilla.org/integration/gaia-central/rev/68a8e0b91b55 Author: Salvador de la Puente Desc: Bug 1091486 - [SMS] Switch to MMS when entering a email recipient thread --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 4ed0d34d532b..1bb03cebb597 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "351d3daeacc53b00b68356b0e6547a3f6840ee67", + "revision": "f66829c60c0849eb9f1c457bfc9c41fa25bc9f67", "repo_path": "integration/gaia-central" } From 85e251fe30e9d5abbd298c50de36b03a93dd363e Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 08:06:56 -0800 Subject: [PATCH 213/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index b451b39f69a7..025289eb3c61 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 85c376f912f6..b0254799ebe5 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 c42ac9c59009..7303060d00ea 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 cef8e48f24d4..dc86c6011de1 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 85c376f912f6..b0254799ebe5 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 76afbf0578ce..a5ce5d20b551 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 1a38f0f89b00..27ce25a2d921 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 3cf697a5cbdc..3e5938fc2aad 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 8f4eb8b95858..8f260be4a9c9 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 776c1f242df0..abdc2d2f8db9 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 b13ff3091123..acc34286c41b 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 84252339d2bd68884af87c611cc44ca506d9e525 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 09:32:15 -0800 Subject: [PATCH 214/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/d6080ec6a270 Author: Kevin Grandon Desc: Merge pull request #27218 from KevinGrandon/bug_1118270_bump_package_json Bug 1118270 - Bump gaia node modules for raptor bump ======== https://hg.mozilla.org/integration/gaia-central/rev/06a64bae25ed Author: Kevin Grandon Desc: Bug 1118270 - Bump gaia node modules for raptor bump r=kgrandon --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 1bb03cebb597..f4e07141d61b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "f66829c60c0849eb9f1c457bfc9c41fa25bc9f67", + "revision": "d6080ec6a27038c80158a869473938ef80f11d57", "repo_path": "integration/gaia-central" } From 2c874ee0bc341d6ddd8c76b3a29fc655cbf96bcd Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 09:36:55 -0800 Subject: [PATCH 215/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 025289eb3c61..ef0742315f5a 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index b0254799ebe5..55f1a3b9a0ec 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 7303060d00ea..0b781237e4e9 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 dc86c6011de1..771d78ffc44d 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 b0254799ebe5..55f1a3b9a0ec 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index a5ce5d20b551..be3e321723c3 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 27ce25a2d921..a4638f8f0229 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 3e5938fc2aad..5c92e08e188d 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 8f260be4a9c9..697958a4d8e9 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 abdc2d2f8db9..8d3bfa207964 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 acc34286c41b..8035ce0a80b6 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 44c0587ba50388641684c25cd8c6db9d099f9cc5 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 09:43:57 -0800 Subject: [PATCH 216/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index ef0742315f5a..4e3b1d737b2a 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 55f1a3b9a0ec..b37adb6792bf 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -25,7 +25,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 0b781237e4e9..f829416b6b6f 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 771d78ffc44d..ff0e5365b39d 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 55f1a3b9a0ec..b37adb6792bf 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -25,7 +25,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index be3e321723c3..447c4576bd36 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index a4638f8f0229..d120441cf496 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 5c92e08e188d..ea7a8f67071e 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 8d3bfa207964..f0fc688d291d 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -20,7 +20,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 8035ce0a80b6..8c6e7f31a7a1 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -22,7 +22,7 @@ - + From 9d9e763d45e45719fe2de07820ac4b3f30696ff5 Mon Sep 17 00:00:00 2001 From: Kai Engert Date: Thu, 8 Jan 2015 19:40:05 +0100 Subject: [PATCH 217/224] Bug 1107731, upgrade Mozilla 37 to use NSS 3.18 (this is beta 5), r=wtc --- security/nss/TAG-INFO | 2 +- security/nss/cmd/certutil/certutil.c | 34 +++++-- security/nss/cmd/certutil/keystuff.c | 3 - security/nss/coreconf/coreconf.dep | 1 + security/nss/doc/certutil.xml | 17 ++++ security/nss/doc/html/certutil.html | 4 +- security/nss/doc/nroff/certutil.1 | 97 ++++++++++++++++++- .../lib/libpkix/include/pkix_errorstrings.h | 1 - .../pkix_pl_nss/pki/pkix_pl_x500name.c | 55 ----------- security/nss/lib/nss/nss.h | 8 +- security/nss/lib/pki/pki3hack.c | 7 ++ security/nss/lib/pki/tdcache.c | 2 + security/nss/lib/softoken/sdb.c | 2 - security/nss/lib/softoken/softkver.h | 8 +- security/nss/lib/ssl/ssl3con.c | 11 ++- security/nss/lib/util/nssutil.h | 8 +- security/nss/tests/dbtests/dbtests.sh | 20 +++- 17 files changed, 185 insertions(+), 95 deletions(-) diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index 4a3280063321..3254890c95e5 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_17_3_RTM +NSS_3_18_BETA5 diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index 55b6a0c3982f..2f3273d9d6f0 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -971,19 +971,19 @@ PrintSyntax(char *progName) FPS "Usage: %s -N [-d certdir] [-P dbprefix] [-f pwfile] [--empty-password]\n", progName); FPS "Usage: %s -T [-d certdir] [-P dbprefix] [-h token-name]\n" "\t\t [-f pwfile] [-0 SSO-password]\n", progName); - FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", + FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", progName); FPS "\t%s -B -i batch-file\n", progName); FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n" "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n" - "\t\t [-f pwfile] [-d certdir] [-P dbprefix]\n" + "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n" "\t\t [-1 | --keyUsage [keyUsageKeyword,..]] [-2] [-3] [-4]\n" "\t\t [-5 | --nsCertType [nsCertTypeKeyword,...]]\n" "\t\t [-6 | --extKeyUsage [extKeyUsageKeyword,...]] [-7 emailAddrs]\n" "\t\t [-8 dns-names] [-a]\n", progName); FPS "\t%s -D -n cert-name [-d certdir] [-P dbprefix]\n", progName); - FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", + FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", progName); FPS "\t%s -F -n nickname [-d certdir] [-P dbprefix]\n", progName); @@ -1010,14 +1010,15 @@ PrintSyntax(char *progName) progName); FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n"); FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n"); - FPS "\t%s -L [-n cert-name] [--email email-address] [-X] [-r] [-a]\n", + FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n", progName); - FPS "\t\t [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n"); + FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n"); FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName); FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n" - "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile] [-g key-size]\n", + "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n" + "\t\t [-g key-size] [-Z hashAlg]\n", progName); FPS "\t%s -V -n cert-name -u usage [-b time] [-e] [-a]\n" "\t\t[-X] [-d certdir] [-P dbprefix]\n", @@ -1027,7 +1028,7 @@ PrintSyntax(char *progName) FPS "\t%s -S -n cert-name -s subj [-c issuer-name | -x] -t trustargs\n" "\t\t [-k key-type-or-id] [-q key-params] [-h token-name] [-g key-size]\n" "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n" - "\t\t [-f pwfile] [-d certdir] [-P dbprefix]\n" + "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n" "\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6] [-7 emailAddrs]\n" "\t\t [-8 DNS-names]\n" "\t\t [--extAIA] [--extSIA] [--extCP] [--extPM] [--extPC] [--extIA]\n" @@ -1137,6 +1138,11 @@ static void luC(enum usage_level ul, const char *command) " -d certdir"); FPS "%-20s Cert & Key database prefix\n", " -P dbprefix"); + FPS "%-20s \n" + "%-20s Specify the hash algorithm to use. Possible keywords:\n" + "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n" + "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n", + " -Z hashAlg", "", "", ""); FPS "%-20s \n" "%-20s Create key usage extension. Possible keywords:\n" "%-20s \"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\",\n" @@ -1336,6 +1342,8 @@ static void luL(enum usage_level ul, const char *command) "-L"); if (ul == usage_selected && !is_my_command) return; + FPS "%-20s Name of token to search (\"all\" for all tokens)\n", + " -h token-name "); FPS "%-20s Pretty print named cert (list all if unspecified)\n", " -n cert-name"); FPS "%-20s \n" @@ -1388,6 +1396,8 @@ static void luN(enum usage_level ul, const char *command) " -d certdir"); FPS "%-20s Cert & Key database prefix\n", " -P dbprefix"); + FPS "%-20s Specify the password file\n", + " -f password-file"); FPS "%-20s use empty password when creating a new database\n", " --empty-password"); FPS "\n"); @@ -1473,6 +1483,11 @@ static void luR(enum usage_level ul, const char *command) " -P dbprefix"); FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n", " -p phone"); + FPS "%-20s \n" + "%-20s Specify the hash algorithm to use. Possible keywords:\n" + "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n" + "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n", + " -Z hashAlg", "", "", ""); FPS "%-20s Output the cert request in ASCII (RFC1113); default is binary\n", " -a"); FPS "%-20s \n", @@ -1634,6 +1649,11 @@ static void luS(enum usage_level ul, const char *command) " -P dbprefix"); FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n", " -p phone"); + FPS "%-20s \n" + "%-20s Specify the hash algorithm to use. Possible keywords:\n" + "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n" + "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n", + " -Z hashAlg", "", "", ""); FPS "%-20s Create key usage extension\n", " -1 "); FPS "%-20s Create basic constraint extension\n", diff --git a/security/nss/cmd/certutil/keystuff.c b/security/nss/cmd/certutil/keystuff.c index 2665dd44677e..0cdd0343332b 100644 --- a/security/nss/cmd/certutil/keystuff.c +++ b/security/nss/cmd/certutil/keystuff.c @@ -494,7 +494,6 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, CK_FLAGS opFlagsOff, secuPWData *pwdata) { CK_MECHANISM_TYPE mechanism; - SECOidTag algtag; PK11RSAGenParams rsaparams; SECKEYPQGParams * dsaparams = NULL; void * params; @@ -529,12 +528,10 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size, rsaparams.keySizeInBits = size; rsaparams.pe = publicExponent; mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; - algtag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; params = &rsaparams; break; case dsaKey: mechanism = CKM_DSA_KEY_PAIR_GEN; - algtag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; if (pqgFile) { dsaparams = getpqgfromfile(size, pqgFile); if (dsaparams == NULL) diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 5182f75552c8..590d1bfaeee3 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,3 +10,4 @@ */ #error "Do not include this header file." + diff --git a/security/nss/doc/certutil.xml b/security/nss/doc/certutil.xml index b89fa49258fa..40582001b194 100644 --- a/security/nss/doc/certutil.xml +++ b/security/nss/doc/certutil.xml @@ -459,6 +459,23 @@ of the attribute codes: Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes. + + -Z hashAlg + + Specify the hash algorithm to use with the -C, -S or -R command options. Possible keywords: + + MD2 + MD4 + MD5 + SHA1 + SHA224 + SHA256 + SHA384 + SHA512 + + + + -0 SSO_password Set a site security officer password on a token. diff --git a/security/nss/doc/html/certutil.html b/security/nss/doc/html/certutil.html index 907f90be2170..9e612695f546 100644 --- a/security/nss/doc/html/certutil.html +++ b/security/nss/doc/html/certutil.html @@ -1,4 +1,4 @@ -CERTUTIL

Name

certutil — Manage keys and certificate in both NSS databases and other NSS tokens

Synopsis

certutil [options] [[arguments]]

STATUS

This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477 +CERTUTIL

Name

certutil — Manage keys and certificate in both NSS databases and other NSS tokens

Synopsis

certutil [options] [[arguments]]

STATUS

This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477

Description

The Certificate Database Tool, certutil, is a command-line utility that can create and modify certificate and key databases. It can specifically list, generate, modify, or delete certificates, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key database.

Certificate issuance, part of the key and certificate management process, requires that keys and certificates be created in the key database. This document discusses certificate and key database management. For information on the security module database management, see the modutil manpage.

Command Options and Arguments

Running certutil always requires one and only one command option to specify the type of certificate operation. Each command option may take zero or more arguments. The command option -H will list all the command options and their relevant arguments.

Command Options

-A

Add an existing certificate to a certificate database. The certificate database should already exist; if one is not present, this command option will initialize one by default.

-B

Run a series of commands from the specified batch file. This requires the -i argument.

-C

Create a new binary certificate file from a binary certificate request file. Use the -i argument to specify the certificate request file. If this argument is not used, certutil prompts for a filename.

-D

Delete a certificate from the certificate database.

-E

Add an email certificate to the certificate database.

-F

Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the -d argument. Use the -k argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the -k argument, the option looks for an RSA key matching the specified nickname.

@@ -61,7 +61,7 @@ of the attribute codes: the certificate or adding it to a database. Express the offset in integers, using a minus sign (-) to indicate a negative offset. If this argument is not used, the validity period begins at the current system time. The length - of the validity period is set with the -v argument.

-X

Force the key and certificate database to open in read-write mode. This is used with the -U and -L command options.

-x

Use certutil to generate the signature for a certificate being created or added to a database, rather than obtaining a signature from a separate CA.

-y exp

Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.

-z noise-file

Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.

-0 SSO_password

Set a site security officer password on a token.

-1 | --keyUsage keyword,keyword

Set an X.509 V3 Certificate Type Extension in the certificate. There are several available keywords:

  • + of the validity period is set with the -v argument.

-X

Force the key and certificate database to open in read-write mode. This is used with the -U and -L command options.

-x

Use certutil to generate the signature for a certificate being created or added to a database, rather than obtaining a signature from a separate CA.

-y exp

Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.

-z noise-file

Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.

-Z hashAlg

Specify the hash algorithm to use with the -C, -S or -R command options. Possible keywords:

  • MD2

  • MD4

  • MD5

  • SHA1

  • SHA224

  • SHA256

  • SHA384

  • SHA512

-0 SSO_password

Set a site security officer password on a token.

-1 | --keyUsage keyword,keyword

Set an X.509 V3 Certificate Type Extension in the certificate. There are several available keywords:

  • digitalSignature

  • nonRepudiation diff --git a/security/nss/doc/nroff/certutil.1 b/security/nss/doc/nroff/certutil.1 index 7ae5db01a3a5..2234176425db 100644 --- a/security/nss/doc/nroff/certutil.1 +++ b/security/nss/doc/nroff/certutil.1 @@ -2,12 +2,12 @@ .\" Title: CERTUTIL .\" Author: [see the "Authors" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 29 July 2014 +.\" Date: 7 January 2015 .\" Manual: NSS Security Tools .\" Source: nss-tools .\" Language: English .\" -.TH "CERTUTIL" "1" "29 July 2014" "nss-tools" "NSS Security Tools" +.TH "CERTUTIL" "1" "7 January 2015" "nss-tools" "NSS Security Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -619,6 +619,99 @@ Set an alternate exponent value to use in generating a new RSA public key for th Read a seed value from the specified file to generate a new private and public key pair\&. This argument makes it possible to use hardware\-generated seed values or manually create a value from the keyboard\&. The minimum file size is 20 bytes\&. .RE .PP +\-Z hashAlg +.RS 4 +Specify the hash algorithm to use with the \-C, \-S or \-R command options\&. Possible keywords: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +MD2 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +MD4 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +MD5 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +SHA1 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +SHA224 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +SHA256 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +SHA384 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +SHA512 +.RE +.RE +.PP \-0 SSO_password .RS 4 Set a site security officer password on a token\&. diff --git a/security/nss/lib/libpkix/include/pkix_errorstrings.h b/security/nss/lib/libpkix/include/pkix_errorstrings.h index c9910e7ab091..d3fea945411d 100755 --- a/security/nss/lib/libpkix/include/pkix_errorstrings.h +++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h @@ -1093,7 +1093,6 @@ PKIX_ERRORENTRY(X500NAMEGETSECNAMEFAILED,pkix_pl_X500Name_GetSECName failed,0), PKIX_ERRORENTRY(X500NAMEHASHCODEFAILED,PKIX_PL_X500Name_Hashcode failed,0), PKIX_ERRORENTRY(X500NAMEMATCHFAILED,PKIX_PL_X500Name_Match failed,0), PKIX_ERRORENTRY(X500NAMETOSTRINGFAILED,PKIX_PL_X500Name_ToString failed,0), -PKIX_ERRORENTRY(X500NAMETOSTRINGHELPERFAILED,pkix_pl_X500Name_ToString_Helper failed,0), PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0), PKIX_ERRORENTRY(INVALIDOCSPHTTPMETHOD,Unsupported HTTP Method for OCSP retrieval,0), PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0) diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c index e5ca4724e0e1..e37439cf0142 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c @@ -12,61 +12,6 @@ /* --Private-X500Name-Functions------------------------------------- */ -/* - * FUNCTION: pkix_pl_X500Name_ToString_Helper - * DESCRIPTION: - * - * Helper function that creates a string representation of the X500Name - * pointed to by "name" and stores it at "pString". - * - * PARAMETERS - * "name" - * Address of X500Name whose string representation is desired. - * Must be non-NULL. - * "pString" - * Address where object pointer will be stored. Must be non-NULL. - * "plContext" - Platform-specific context pointer. - * THREAD SAFETY: - * Thread Safe (see Thread Safety Definitions in Programmer's Guide) - * RETURNS: - * Returns NULL if the function succeeds. - * Returns a X500Name Error if the function fails in a non-fatal way. - * Returns a Fatal Error if the function fails in an unrecoverable way. - */ -static PKIX_Error * -pkix_pl_X500Name_ToString_Helper( - PKIX_PL_X500Name *name, - PKIX_PL_String **pString, - void *plContext) -{ - CERTName *nssDN = NULL; - char *utf8String = NULL; - PKIX_UInt32 utf8Length; - - PKIX_ENTER(X500NAME, "pkix_pl_X500Name_ToString_Helper"); - PKIX_NULLCHECK_TWO(name, pString); - nssDN = &name->nssDN; - - /* this should really be called CERT_NameToUTF8 */ - utf8String = CERT_NameToAsciiInvertible(nssDN, CERT_N2A_INVERTIBLE); - if (!utf8String){ - PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED); - } - - PKIX_X500NAME_DEBUG("\t\tCalling PL_strlen).\n"); - utf8Length = PL_strlen(utf8String); - - PKIX_CHECK(PKIX_PL_String_Create - (PKIX_UTF8, utf8String, utf8Length, pString, plContext), - PKIX_STRINGCREATEFAILED); - -cleanup: - - PR_Free(utf8String); - - PKIX_RETURN(X500NAME); -} - /* * FUNCTION: pkix_pl_X500Name_Destroy * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 6facd8e2c2cc..c5fd3252598e 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -33,12 +33,12 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.17.3" _NSS_ECC_STRING _NSS_CUSTOMIZED +#define NSS_VERSION "3.18" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta" #define NSS_VMAJOR 3 -#define NSS_VMINOR 17 -#define NSS_VPATCH 3 +#define NSS_VMINOR 18 +#define NSS_VPATCH 0 #define NSS_VBUILD 0 -#define NSS_BETA PR_FALSE +#define NSS_BETA PR_TRUE #ifndef RC_INVOKED diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index 7430ca9f4a2f..953d73800c45 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -856,6 +856,8 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) CERTCertificate *cc = NULL; CERTCertTrust certTrust; + /* make sure object does not go away until we finish */ + nssPKIObject_AddRef(&c->object); nssPKIObject_Lock(&c->object); dc = c->decoding; @@ -905,6 +907,7 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) loser: nssPKIObject_Unlock(&c->object); + nssPKIObject_Destroy(&c->object); return cc; } @@ -1271,6 +1274,7 @@ DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject) int failureCount = 0; /* actual deletion failures by devices */ int index; + nssPKIObject_AddRef(tObject); nssPKIObject_Lock(tObject); /* Keep going even if a module fails to delete. */ for (index = 0; index < tObject->numInstances; index++) { @@ -1304,6 +1308,7 @@ DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject) } nssPKIObject_Unlock(tObject); + nssPKIObject_Destroy(tObject); return failureCount == 0 ? PR_SUCCESS : PR_FAILURE; } @@ -1330,6 +1335,7 @@ STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c) * loop so that once it's failed the other gets set. */ NSSRWLock_LockRead(td->tokensLock); + nssPKIObject_AddRef(cobject); nssPKIObject_Lock(cobject); for (i = 0; i < cobject->numInstances; i++) { nssCryptokiObject *cInstance = cobject->instances[i]; @@ -1344,6 +1350,7 @@ STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c) } } nssPKIObject_Unlock(cobject); + nssPKIObject_Destroy(cobject); NSSRWLock_UnlockRead(td->tokensLock); return nssrv; } diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index 4d3ebbaabe35..bb55027aeafd 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -391,6 +391,7 @@ remove_token_certs(const void *k, void *v, void *a) nssPKIObject *object = &c->object; struct token_cert_dtor *dtor = a; PRUint32 i; + nssPKIObject_AddRef(object); nssPKIObject_Lock(object); for (i=0; inumInstances; i++) { if (object->instances[i]->token == dtor->token) { @@ -409,6 +410,7 @@ remove_token_certs(const void *k, void *v, void *a) } } nssPKIObject_Unlock(object); + nssPKIObject_Destroy(object); return; } diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c index ffb221bdb64c..83150bb38b14 100644 --- a/security/nss/lib/softoken/sdb.c +++ b/security/nss/lib/softoken/sdb.c @@ -1691,8 +1691,6 @@ void sdb_SetForkState(PRBool forked) */ static const char INIT_CMD[] = "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)"; -static const char ALTER_CMD[] = - "ALTER TABLE %s ADD COLUMN a%x"; CK_RV sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index ad3995e313da..c3f1a03920e5 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -25,11 +25,11 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.17.3" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.18" SOFTOKEN_ECC_STRING " Beta" #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 17 -#define SOFTOKEN_VPATCH 3 +#define SOFTOKEN_VMINOR 18 +#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 -#define SOFTOKEN_BETA PR_FALSE +#define SOFTOKEN_BETA PR_TRUE #endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index c6d1e0e5f671..761e4360e581 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -904,7 +904,7 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion, if (peerVersion < ss->vrange.min || (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) { - PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); return SECFailure; } @@ -6287,7 +6287,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (rv != SECSuccess) { desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure; - errCode = SSL_ERROR_NO_CYPHER_OVERLAP; + errCode = SSL_ERROR_UNSUPPORTED_VERSION; goto alert_loser; } isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); @@ -7699,7 +7699,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (rv != SECSuccess) { desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure; - errCode = SSL_ERROR_NO_CYPHER_OVERLAP; + errCode = SSL_ERROR_UNSUPPORTED_VERSION; goto alert_loser; } @@ -8472,8 +8472,9 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) rv = ssl3_NegotiateVersion(ss, version, PR_TRUE); if (rv != SECSuccess) { /* send back which ever alert client will understand. */ - desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure; - errCode = SSL_ERROR_NO_CYPHER_OVERLAP; + desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version + : handshake_failure; + errCode = SSL_ERROR_UNSUPPORTED_VERSION; goto alert_loser; } diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index 3ac626dbd582..03bd6da90265 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,12 +19,12 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.17.3" +#define NSSUTIL_VERSION "3.18 Beta" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 17 -#define NSSUTIL_VPATCH 3 +#define NSSUTIL_VMINOR 18 +#define NSSUTIL_VPATCH 0 #define NSSUTIL_VBUILD 0 -#define NSSUTIL_BETA PR_FALSE +#define NSSUTIL_BETA PR_TRUE SEC_BEGIN_PROTOS diff --git a/security/nss/tests/dbtests/dbtests.sh b/security/nss/tests/dbtests/dbtests.sh index b09a2bad6abf..18c69a01e4a7 100755 --- a/security/nss/tests/dbtests/dbtests.sh +++ b/security/nss/tests/dbtests/dbtests.sh @@ -168,19 +168,29 @@ dbtest_main() cat $RONLY_DIR/* > /dev/null fi - ${BINDIR}/dbtest -d $RONLY_DIR + # skipping the next two tests when user is root, + # otherwise they would fail due to rooty powers + if [ $UID -ne 0 ] then + ${BINDIR}/dbtest -d $RONLY_DIR ret=$? if [ $ret -ne 46 ]; then - html_failed "Dbtest r/w succeeded in an readonly directory $ret" + html_failed "Dbtest r/w succeeded in a readonly directory $ret" else html_passed "Dbtest r/w didn't work in an readonly dir $ret" fi - ${BINDIR}/certutil -D -n "TestUser" -d . + else + html_passed "Skipping Dbtest r/w in a readonly dir because user is root" + fi + if [ $UID -ne 0 ] then + ${BINDIR}/certutil -D -n "TestUser" -d . ret=$? if [ $ret -ne 255 ]; then - html_failed "Certutil succeeded in deleting a cert in an readonly directory $ret" + html_failed "Certutil succeeded in deleting a cert in a readonly directory $ret" else - html_passed "Certutil didn't work in an readonly dir $ret" + html_passed "Certutil didn't work in an readonly dir $ret" + fi + else + html_passed "Skipping Certutil delete cert in a readonly directory test because user is root" fi Echo "test opening the database ronly in a readonly directory" From e7d2f9cd128e70e72ef7f501bb40de455526e9ec Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 8 Jan 2015 10:56:07 -0800 Subject: [PATCH 218/224] bug 1101194 - follow-up to fix bustage in TestCertDB r=bustage on a CLOSED TREE Turns out there was a code path that resulted in attempting to acquire a lock on the DataStorage mutex when one had already been acquired, resulting in deadlock. This fixes it. --- security/manager/boot/src/DataStorage.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/security/manager/boot/src/DataStorage.cpp b/security/manager/boot/src/DataStorage.cpp index b0da36fcbbfb..516100f1b59a 100644 --- a/security/manager/boot/src/DataStorage.cpp +++ b/security/manager/boot/src/DataStorage.cpp @@ -111,12 +111,6 @@ private: DataStorage::Reader::~Reader() { - { - MutexAutoLock lock(mDataStorage->mMutex); - Telemetry::Accumulate(Telemetry::DATA_STORAGE_ENTRIES, - mDataStorage->mPersistentDataTable.Count()); - } - // Notify that calls to Get can proceed. { MonitorAutoLock readyLock(mDataStorage->mReadyMonitor); @@ -209,6 +203,9 @@ DataStorage::Reader::Run() } } } while (true); + + Telemetry::Accumulate(Telemetry::DATA_STORAGE_ENTRIES, + mDataStorage->mPersistentDataTable.Count()); } return NS_OK; From 08557c5100120611a914aad7ccb05444fc5eb7de Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Thu, 8 Jan 2015 13:52:19 -0800 Subject: [PATCH 219/224] Bug 1073003 - Fix warnings causing errors in emulator build. r=nfroyd --- dom/media/omx/OmxDecoder.cpp | 1 + dom/svg/nsSVGBoolean.cpp | 2 +- dom/system/gonk/AudioManager.cpp | 1 + ipc/chromium/src/base/logging.h | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dom/media/omx/OmxDecoder.cpp b/dom/media/omx/OmxDecoder.cpp index 9a6e6d9175c2..c84c2f70b078 100644 --- a/dom/media/omx/OmxDecoder.cpp +++ b/dom/media/omx/OmxDecoder.cpp @@ -36,6 +36,7 @@ #include #define OD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "OmxDecoder", __VA_ARGS__) +#undef LOG #ifdef PR_LOGGING PRLogModuleInfo *gOmxDecoderLog; #define LOG(type, msg...) PR_LOG(gOmxDecoderLog, type, (msg)) diff --git a/dom/svg/nsSVGBoolean.cpp b/dom/svg/nsSVGBoolean.cpp index bd89d4266e0d..1909433ea1db 100644 --- a/dom/svg/nsSVGBoolean.cpp +++ b/dom/svg/nsSVGBoolean.cpp @@ -56,7 +56,7 @@ GetValueFromAtom(const nsIAtom* aValueAsAtom, bool *aValue) nsresult nsSVGBoolean::SetBaseValueAtom(const nsIAtom* aValue, nsSVGElement *aSVGElement) { - bool val; + bool val = false; nsresult rv = GetValueFromAtom(aValue, &val); if (NS_FAILED(rv)) { diff --git a/dom/system/gonk/AudioManager.cpp b/dom/system/gonk/AudioManager.cpp index 39469270d10b..5fe1e7a77f46 100644 --- a/dom/system/gonk/AudioManager.cpp +++ b/dom/system/gonk/AudioManager.cpp @@ -51,6 +51,7 @@ using namespace mozilla::hal; using namespace mozilla; using namespace mozilla::dom::bluetooth; +#undef LOG #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AudioManager" , ## args) #define HEADPHONES_STATUS_HEADSET MOZ_UTF16("headset") diff --git a/ipc/chromium/src/base/logging.h b/ipc/chromium/src/base/logging.h index c27bd435530f..e36dce93ee2d 100644 --- a/ipc/chromium/src/base/logging.h +++ b/ipc/chromium/src/base/logging.h @@ -108,6 +108,7 @@ const mozilla::EmptyLog& operator <<(const mozilla::EmptyLog& log, const T&) #define DCHECK(condition) while (false && (condition)) mozilla::EmptyLog() #endif +#undef LOG_ASSERT #define LOG_ASSERT(cond) CHECK(0) #define DLOG_ASSERT(cond) DCHECK(0) From cd8a21055562cca41741b1ae14f65186fada07ad Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Thu, 8 Jan 2015 13:52:20 -0800 Subject: [PATCH 220/224] Bug 1073003 - Fix warnings in stlport causing errors in emulator build. r=bzbarsky --- build/stlport/stlport/stl/_istream.c | 1 - build/stlport/stlport/stl/_slist.c | 1 - build/stlport/stlport/stl/config/features.h | 3 ++- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build/stlport/stlport/stl/_istream.c b/build/stlport/stlport/stl/_istream.c index ab327b296911..724ad24b7386 100644 --- a/build/stlport/stlport/stl/_istream.c +++ b/build/stlport/stlport/stl/_istream.c @@ -1145,7 +1145,6 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) { if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); - typedef _STLP_PRIV _Constant_unary_fun _Const_bool; typedef _STLP_PRIV _Constant_binary_fun _Const_streamsize; const streamsize __maxss = (numeric_limits::max)(); diff --git a/build/stlport/stlport/stl/_slist.c b/build/stlport/stlport/stl/_slist.c index ba158d00c5d5..107b600b4ca1 100644 --- a/build/stlport/stlport/stl/_slist.c +++ b/build/stlport/stlport/stl/_slist.c @@ -148,7 +148,6 @@ template void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x, _StrictWeakOrdering __comp) { typedef _Slist_node<_Tp> _Node; - typedef _STLP_PRIV _Slist_node_base _Node_base; if (__that.get_allocator() == __x.get_allocator()) { typename slist<_Tp, _Alloc>::iterator __ite(__that.before_begin()); while (__ite._M_node->_M_next && !__x.empty()) { diff --git a/build/stlport/stlport/stl/config/features.h b/build/stlport/stlport/stl/config/features.h index c1eb53c87017..16694801445d 100644 --- a/build/stlport/stlport/stl/config/features.h +++ b/build/stlport/stlport/stl/config/features.h @@ -308,7 +308,8 @@ /* Some compiler support 0 size array so we use negative size array to generate * a compilation time error. */ -# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1]; +//# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1]; +# define _STLP_STATIC_ASSERT(expr) static_assert(expr, "static_assert failed"); #endif /* apple mpw exception handling bug */ From a6ca66e5306c274648ff73e1978a2b6b00591a80 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Thu, 8 Jan 2015 13:52:22 -0800 Subject: [PATCH 221/224] Bug 1073003 - Create an stlport modifications patch and update README.mozilla r=nfroyd (on a CLOSED TREE) --- build/stlport/README.mozilla | 3 + build/stlport/fix-warnings-as-errors.patch | 70 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 build/stlport/fix-warnings-as-errors.patch diff --git a/build/stlport/README.mozilla b/build/stlport/README.mozilla index dddf18c03717..ca2500f41f8a 100644 --- a/build/stlport/README.mozilla +++ b/build/stlport/README.mozilla @@ -7,3 +7,6 @@ The overrides/ directory contains Mozilla-specific overrides to the standard The following patches are applied on top: - android-mozilla-config.patch: Adjusts Android-specific configuration to the mozilla codebase use of the STL. + +- fix-warnings-as-errors.patch: Fixes warnings which were causing the + B2G emulator-ICS build to fail (related to bug 1073003). diff --git a/build/stlport/fix-warnings-as-errors.patch b/build/stlport/fix-warnings-as-errors.patch new file mode 100644 index 000000000000..ae6f8b2ad17d --- /dev/null +++ b/build/stlport/fix-warnings-as-errors.patch @@ -0,0 +1,70 @@ +# HG changeset patch +# Parent f89b28ea7c7b7fcb54c34e74fcb047626300bfba +# User Dave Hylands +Bug 1073003 - Fix warnings in stlport causing errors in emulator build. + +diff --git a/build/stlport/stlport/stl/_istream.c b/build/stlport/stlport/stl/_istream.c +--- a/build/stlport/stlport/stl/_istream.c ++++ b/build/stlport/stlport/stl/_istream.c +@@ -1140,17 +1140,16 @@ basic_istream<_CharT, _Traits>::ignore(s + template + basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) { + sentry __sentry(*this, _No_Skip_WS()); + this->_M_gcount = 0; + + if (__sentry) { + basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); +- typedef _STLP_PRIV _Constant_unary_fun _Const_bool; + typedef _STLP_PRIV _Constant_binary_fun + _Const_streamsize; + const streamsize __maxss = (numeric_limits::max)(); + + if (__n == (numeric_limits::max)()) { + if (__buf->gptr() != __buf->egptr()) + _M_gcount = _M_ignore_buffered(this, __buf, + __maxss, _Const_streamsize(__maxss), +diff --git a/build/stlport/stlport/stl/_slist.c b/build/stlport/stlport/stl/_slist.c +--- a/build/stlport/stlport/stl/_slist.c ++++ b/build/stlport/stlport/stl/_slist.c +@@ -143,17 +143,16 @@ void _Slist_unique(slist<_Tp, _Alloc>& _ + } + } + } + + template + void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) { + typedef _Slist_node<_Tp> _Node; +- typedef _STLP_PRIV _Slist_node_base _Node_base; + if (__that.get_allocator() == __x.get_allocator()) { + typename slist<_Tp, _Alloc>::iterator __ite(__that.before_begin()); + while (__ite._M_node->_M_next && !__x.empty()) { + if (__comp(__x.front(), __STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data)) { + _STLP_VERBOSE_ASSERT(!__comp(__STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data, __x.front()), + _StlMsg_INVALID_STRICT_WEAK_PREDICATE) + __that.splice_after(__ite, __x, __x.before_begin()); + } +diff --git a/build/stlport/stlport/stl/config/features.h b/build/stlport/stlport/stl/config/features.h +--- a/build/stlport/stlport/stl/config/features.h ++++ b/build/stlport/stlport/stl/config/features.h +@@ -303,17 +303,18 @@ + # undef _STLP_NO_DEFAULT_NON_TYPE_PARAM + # define _STLP_NO_DEFAULT_NON_TYPE_PARAM 1 + #endif + + #if !defined (_STLP_STATIC_ASSERT) + /* Some compiler support 0 size array so we use negative size array to generate + * a compilation time error. + */ +-# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1]; ++//# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1]; ++# define _STLP_STATIC_ASSERT(expr) static_assert(expr, "static_assert failed"); + #endif + + /* apple mpw exception handling bug */ + #ifndef _STLP_MPWFIX_TRY + # define _STLP_MPWFIX_TRY + #endif + #ifndef _STLP_MPWFIX_CATCH + # define _STLP_MPWFIX_CATCH From 1ced3909469cb39dd4695fc20e12f2fd2aadee7b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 14:42:18 -0800 Subject: [PATCH 222/224] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/85bbbd703dba Author: Julien Wajsberg Desc: Merge pull request #27205 from julienw/1118829-fix-debug-in-firefox Bug 1118829 - Restore DESKTOP=1 DEBUG=0 functionality in Firefox r=ocham... ======== https://hg.mozilla.org/integration/gaia-central/rev/4793c9f3c7c0 Author: Julien Wajsberg Desc: Bug 1118829 - Restore DESKTOP=1 DEBUG=0 functionality in Firefox r=ochameau --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f4e07141d61b..bab9fc8a9258 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "d6080ec6a27038c80158a869473938ef80f11d57", + "revision": "85bbbd703dba85b58c5b9d5902bc784c9f763c1d", "repo_path": "integration/gaia-central" } From aa829cbf9d1740d8ad3eeb352934bd6a40bbfbe1 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Thu, 8 Jan 2015 14:43:56 -0800 Subject: [PATCH 223/224] Bumping manifests a=b2g-bump --- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/flame/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 4e3b1d737b2a..e50fe2a66d5d 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index b37adb6792bf..d7b10dcb8f63 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 f829416b6b6f..951e212a44b6 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 ff0e5365b39d..7458b8f60279 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 b37adb6792bf..d7b10dcb8f63 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 447c4576bd36..746645e499c7 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index d120441cf496..be5372019978 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index ea7a8f67071e..34e9dd19ed3a 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 697958a4d8e9..6d2a6fb4c279 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 f0fc688d291d..fe1213882a3e 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 8c6e7f31a7a1..5cb1b14dea80 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 205b7f2a3ff477118dd8dbd8ccad103afe28e7e7 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 8 Jan 2015 15:46:15 -0800 Subject: [PATCH 224/224] Bug 1073003 - wError bustage fix in non-unified builds r=me a=bustage --HG-- extra : amend_source : 8054a3a25f0adf4caea5b70f2b75a94665a6e59d --- dom/media/webrtc/MediaEngineGonkVideoSource.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp index 0415029748c8..81443e512c3e 100644 --- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp +++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp @@ -24,6 +24,7 @@ using namespace mozilla::dom; using namespace mozilla::gfx; using namespace android; +#undef LOG #ifdef PR_LOGGING extern PRLogModuleInfo* GetMediaManagerLog(); #define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)