Created
January 16, 2012 18:15
-
-
Save nmaier/1622116 to your computer and use it in GitHub Desktop.
Firefox gc-object-logging (+ winconsole) (based on http://philikon.wordpress.com/2011/03/09/javascript-perf-avoid-creating-objects-2/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp | |
--- a/browser/app/nsBrowserApp.cpp | |
+++ b/browser/app/nsBrowserApp.cpp | |
@@ -69,16 +69,20 @@ | |
#define strcasecmp _stricmp | |
#endif | |
#include "BinaryPath.h" | |
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL | |
#include "mozilla/Telemetry.h" | |
+#if defined(XP_WIN) && !MOZ_WINCONSOLE | |
+#error woot | |
+#endif | |
+ | |
static void Output(const char *fmt, ... ) | |
{ | |
va_list ap; | |
va_start(ap, fmt); | |
#if defined(XP_WIN) && !MOZ_WINCONSOLE | |
PRUnichar msg[2048]; | |
_vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap); | |
diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in | |
--- a/config/autoconf.mk.in | |
+++ b/config/autoconf.mk.in | |
@@ -175,16 +175,17 @@ VPX_ARM_ASM = @VPX_ARM_ASM@ | |
VPX_NEED_OBJ_INT_EXTRACT = @VPX_NEED_OBJ_INT_EXTRACT@ | |
LIBJPEG_TURBO_AS = @LIBJPEG_TURBO_AS@ | |
LIBJPEG_TURBO_ASFLAGS = @LIBJPEG_TURBO_ASFLAGS@ | |
LIBJPEG_TURBO_X86_ASM = @LIBJPEG_TURBO_X86_ASM@ | |
LIBJPEG_TURBO_X64_ASM = @LIBJPEG_TURBO_X64_ASM@ | |
NS_PRINTING = @NS_PRINTING@ | |
MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@ | |
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@ | |
+MOZ_WINCONSOLE = @MOZ_WINCONSOLE@ | |
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@ | |
MOC = @MOC@ | |
RCC = @RCC@ | |
MOZ_NSS_PATCH = @MOZ_NSS_PATCH@ | |
MOZ_WEBGL = @MOZ_WEBGL@ | |
MOZ_ANGLE = @MOZ_ANGLE@ | |
MOZ_DIRECTX_SDK_PATH = @MOZ_DIRECTX_SDK_PATH@ | |
MOZ_DIRECTX_SDK_CPU_SUFFIX = @MOZ_DIRECTX_SDK_CPU_SUFFIX@ | |
diff --git a/configure.in b/configure.in | |
--- a/configure.in | |
+++ b/configure.in | |
@@ -6018,16 +6018,17 @@ fi | |
dnl ======================================================== | |
dnl = Breakpad crash reporting (on by default on supported platforms) | |
dnl ======================================================== | |
case $target in | |
i?86-*-mingw*|x86_64-*-mingw*) | |
MOZ_CRASHREPORTER=1 | |
+ MOZ_WINCONSOLE=1 | |
;; | |
i?86-apple-darwin*|powerpc-apple-darwin*|x86_64-apple-darwin*) | |
MOZ_CRASHREPORTER=1 | |
;; | |
i?86-*-linux*|x86_64-*-linux*|arm-*-linux*) | |
if test "$MOZ_ENABLE_GTK2"; then | |
MOZ_CRASHREPORTER=1 | |
fi | |
@@ -6056,17 +6057,19 @@ if test -n "$MOZ_CRASHREPORTER"; then | |
MOZ_CHECK_HEADERS([curl/curl.h], [], [AC_MSG_ERROR([Couldn't find curl/curl.h which is required for the crash reporter. Use --disable-crashreporter to disable the crash reporter.])]) | |
fi | |
if (test "$OS_ARCH" != "$HOST_OS_ARCH"); then | |
AC_MSG_ERROR([Breakpad tools do not support compiling on $HOST_OS_ARCH while targeting $OS_ARCH. Use --disable-crashreporter.]) | |
fi | |
fi | |
- | |
+if test -n "$MOZ_WINCONSOLE"; then | |
+ AC_DEFINE(MOZ_WINCONSOLE) | |
+fi | |
MOZ_ARG_WITH_STRING(crashreporter-enable-percent, | |
[ --with-crashreporter-enable-percent=NN | |
Enable sending crash reports by default on NN% of users. (default=100)], | |
[ val=`echo $withval | sed 's/[^0-9]//g'` | |
MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"]) | |
if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then | |
MOZ_CRASHREPORTER_ENABLE_PERCENT=100 | |
@@ -8428,16 +8431,17 @@ AC_SUBST(MOZ_PROFILELOCKING) | |
AC_SUBST(ENABLE_TESTS) | |
AC_SUBST(IBMBIDI) | |
AC_SUBST(MOZ_UNIVERSALCHARDET) | |
AC_SUBST(ACCESSIBILITY) | |
AC_SUBST(MOZ_SPELLCHECK) | |
AC_SUBST(MOZ_JAVA_COMPOSITOR) | |
AC_SUBST(MOZ_USER_DIR) | |
AC_SUBST(MOZ_CRASHREPORTER) | |
+AC_SUBST(MOZ_WINCONSOLE) | |
AC_SUBST(MOZ_MAINTENANCE_SERVICE) | |
AC_SUBST(MOZ_UPDATER) | |
AC_SUBST(MOZ_ANGLE) | |
AC_SUBST(MOZ_DIRECTX_SDK_PATH) | |
AC_SUBST(MOZ_DIRECTX_SDK_CPU_SUFFIX) | |
AC_SUBST(MOZ_D3DX9_VERSION) | |
AC_SUBST(MOZ_D3DX9_CAB) | |
AC_SUBST(MOZ_D3DCOMPILER_CAB) | |
diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h | |
--- a/js/src/jsgcinlines.h | |
+++ b/js/src/jsgcinlines.h | |
@@ -423,61 +423,93 @@ TryNewGCThing(JSContext *cx, js::gc::All | |
} | |
} /* namespace gc */ | |
} /* namespace js */ | |
inline JSObject * | |
js_NewGCObject(JSContext *cx, js::gc::AllocKind kind) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCObject %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST); | |
return js::gc::NewGCThing<JSObject>(cx, kind, js::gc::Arena::thingSize(kind)); | |
} | |
inline JSObject * | |
js_TryNewGCObject(JSContext *cx, js::gc::AllocKind kind) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("TryNewGCObject %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST); | |
return js::gc::TryNewGCThing<JSObject>(cx, kind, js::gc::Arena::thingSize(kind)); | |
} | |
inline JSString * | |
js_NewGCString(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCString %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<JSString>(cx, js::gc::FINALIZE_STRING, sizeof(JSString)); | |
} | |
inline JSShortString * | |
js_NewGCShortString(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCShortString %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<JSShortString>(cx, js::gc::FINALIZE_SHORT_STRING, sizeof(JSShortString)); | |
} | |
inline JSExternalString * | |
js_NewGCExternalString(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCExtString %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<JSExternalString>(cx, js::gc::FINALIZE_EXTERNAL_STRING, | |
sizeof(JSExternalString)); | |
} | |
inline JSScript * | |
js_NewGCScript(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCScript %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<JSScript>(cx, js::gc::FINALIZE_SCRIPT, sizeof(JSScript)); | |
} | |
inline js::Shape * | |
js_NewGCShape(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCShape %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<js::Shape>(cx, js::gc::FINALIZE_SHAPE, sizeof(js::Shape)); | |
} | |
inline js::BaseShape * | |
js_NewGCBaseShape(JSContext *cx) | |
{ | |
+ if (cx->hasfp() && cx->fp()->isScriptFrame()) { | |
+ printf("NewGCBaseShape %s:%d\n", cx->fp()->script()->filename, | |
+ js_PCToLineNumber(cx, cx->fp()->script(), js_GetCurrentBytecodePC(cx))); | |
+ } | |
return js::gc::NewGCThing<js::BaseShape>(cx, js::gc::FINALIZE_BASE_SHAPE, sizeof(js::BaseShape)); | |
} | |
#if JS_HAS_XML_SUPPORT | |
extern JSXML * | |
js_NewGCXML(JSContext *cx); | |
#endif | |
diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js | |
--- a/modules/libpref/src/init/all.js | |
+++ b/modules/libpref/src/init/all.js | |
@@ -629,22 +629,22 @@ pref("privacy.donottrackheader.enabled", | |
pref("dom.event.contextmenu.enabled", true); | |
pref("javascript.enabled", true); | |
pref("javascript.options.strict", false); | |
#ifdef DEBUG | |
pref("javascript.options.strict.debug", true); | |
#endif | |
pref("javascript.options.relimit", true); | |
-pref("javascript.options.methodjit.content", true); | |
-pref("javascript.options.methodjit.chrome", true); | |
+pref("javascript.options.methodjit.content", false); | |
+pref("javascript.options.methodjit.chrome", false); | |
pref("javascript.options.pccounts.content", false); | |
pref("javascript.options.pccounts.chrome", false); | |
pref("javascript.options.methodjit_always", false); | |
-pref("javascript.options.jit_hardening", true); | |
+pref("javascript.options.jit_hardening", false); | |
pref("javascript.options.typeinference", true); | |
// This preference limits the memory usage of javascript. | |
// If you want to change these values for your device, | |
// please find Bug 417052 comment 17 and Bug 456721 | |
// Comment 32 and Bug 613551. | |
pref("javascript.options.mem.high_water_mark", 128); | |
pref("javascript.options.mem.max", -1); | |
pref("javascript.options.mem.gc_per_compartment", true); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os, sys, re | |
from itertools import chain | |
from collections import Counter, defaultdict | |
groups = defaultdict(Counter) | |
files = defaultdict(Counter) | |
# dta specific | |
r = re.compile(r"^(?:Try)?NewGC(.+?)\s(.+?/dta.+)$") | |
with open(sys.argv[1]) as fp: | |
for l in fp: | |
m = r.search(l.strip()) | |
if not m: | |
continue | |
t, f = m.groups() | |
_f, _l = f.rsplit(":", 1) | |
_t = "line {0}, {1}".format(_l, t) | |
groups[t][f] += 1 | |
files[_f][_t] += 1 | |
for k,g in chain(groups.iteritems(), files.iteritems()): | |
g = sorted(([f,c] for (f,c) in g.items() if c > 1000), | |
key=lambda x: x[1], | |
reverse=True) | |
if not g: | |
continue | |
print k | |
for i in g: | |
print "{1:>10}: {0}".format(*i) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Logging is verrry slow and verrry noisy.
Also expect a lot of crap to be logged.
Repeat after me: Not all GCThings are bad, just those that can be avoided without impacting performance.
Prime examples for optimizations are tight inner loops that use forEach/for each/Iterator. Not only are plain loops (usually) faster, also less GC objects are used.