author | Jim Blandy <jimb@mozilla.com> |
Fri, 19 Sep 2014 15:10:01 -0700 | |
changeset 206327 | ed38f85902f7ce99667ea02f737beff9008f1ea1 |
parent 206326 | ef6d81ac0bba5aea6cc3cae4aa91b4ed8910c4c8 |
child 206328 | b7f417116d90fa33207fa6bea0829cd48c0704d0 |
push id | 27524 |
push user | cbook@mozilla.com |
push date | Mon, 22 Sep 2014 10:59:09 +0000 |
treeherder | mozilla-central@53f7f5b6d7bf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | terrence |
bugs | 1063247 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/public/Debug.h +++ b/js/public/Debug.h @@ -6,16 +6,17 @@ // Interfaces by which the embedding can interact with the Debugger API. #ifndef js_Debug_h #define js_Debug_h #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/MemoryReporting.h" #include "mozilla/Move.h" #include "jspubtd.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" namespace js { @@ -244,13 +245,26 @@ class BuilderOrigin : public Builder { public: BuilderOrigin(JSContext *cx, js::Debugger *debugger_) : Builder(cx, debugger_) { } JSObject *unwrap(Object &object) { return unwrapAny(object); } }; + +// Finding the size of blocks allocated with malloc +// ------------------------------------------------ +// +// Debugger.Memory wants to be able to report how many bytes items in memory are +// consuming. To do this, it needs a function that accepts a pointer to a block, +// and returns the number of bytes allocated to that block. SpiderMonkey itself +// doesn't know which function is appropriate to use, but the embedding does. + +// Tell Debuggers in |runtime| to use |mallocSizeOf| to find the size of +// malloc'd blocks. +void SetDebuggerMallocSizeOf(JSRuntime *runtime, mozilla::MallocSizeOf mallocSizeOf); + } // namespace dbg } // namespace JS #endif /* js_Debug_h */
--- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2007,16 +2007,29 @@ IsSimdAvailable(JSContext *cx, unsigned bool available = false; #else bool available = cx->jitSupportsSimd(); #endif args.rval().set(BooleanValue(available)); return true; } +static bool +ByteSize(JSContext *cx, unsigned argc, Value *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + mozilla::MallocSizeOf mallocSizeOf = cx->runtime()->debuggerMallocSizeOf; + JS::ubi::Node node = args.get(0); + if (node) + args.rval().set(NumberValue(node.size(mallocSizeOf))); + else + args.rval().setUndefined(); + return true; +} + static const JSFunctionSpecWithHelp TestingFunctions[] = { JS_FN_HELP("gc", ::GC, 0, 0, "gc([obj] | 'compartment' [, 'shrinking'])", " Run the garbage collector. When obj is given, GC only its compartment.\n" " If 'compartment' is given, GC any compartments that were scheduled for\n" " GC via schedulegc.\n" " If 'shrinking' is passes as the optional second argument, perform a\n" " shrinking GC rather than a normal GC."), @@ -2329,16 +2342,21 @@ static const JSFunctionSpecWithHelp Test JS_FN_HELP("getBacktrace", GetBacktrace, 1, 0, "getBacktrace([options])", " Return the current stack as a string. Takes an optional options object,\n" " which may contain any or all of the boolean properties\n" " options.args - show arguments to each function\n" " options.locals - show local variables in each frame\n" " options.thisprops - show the properties of the 'this' object of each frame\n"), + JS_FN_HELP("byteSize", ByteSize, 1, 0, +"byteSize(value)", +" Return the size in bytes occupied by |value|, or |undefined| if value\n" +" is not allocated in memory.\n"), + JS_FS_HELP_END }; static const JSPropertySpec TestingProperties[] = { JS_PSG("timesAccessed", TimesAccessed, 0), JS_PS_END };
--- a/js/src/configure.in +++ b/js/src/configure.in @@ -1731,16 +1731,17 @@ ia64*-hpux*) dnl but we work around it here. PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952" dnl XXX: should be -LTCG:PGOPTIMIZE, but that fails on libxul. dnl Probably also a compiler bug, but what can you do? PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE" LDFLAGS="$LDFLAGS -DYNAMICBASE" fi AC_DEFINE(HAVE_SNPRINTF) + AC_DEFINE(HAVE__MSIZE) AC_DEFINE(_WINDOWS) AC_DEFINE(WIN32) AC_DEFINE(XP_WIN) AC_DEFINE(XP_WIN32) AC_DEFINE(HW_THREADS) AC_DEFINE(STDC_HEADERS) AC_DEFINE(WIN32_LEAN_AND_MEAN) TARGET_MD_ARCH=win32 @@ -3907,18 +3908,18 @@ dnl top-level configure may override thi MOZ_CONFIG_ICU() MOZ_SUBCONFIGURE_ICU() dnl ======================================================== dnl JavaScript shell dnl ======================================================== -AC_HAVE_FUNCS(setlocale) -AC_HAVE_FUNCS(localeconv) +AC_CHECK_HEADERS(malloc.h malloc/malloc.h) +AC_CHECK_FUNCS(setlocale localeconv malloc_size malloc_usable_size) AC_SUBST(MOZILLA_VERSION) AC_SUBST(ac_configure_args) AC_SUBST(TOOLCHAIN_PREFIX) if test -n "$JS_STANDALONE"; then
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -17,16 +17,22 @@ # include <process.h> #endif #include <errno.h> #include <fcntl.h> #if defined(XP_WIN) # include <io.h> /* for isatty() */ #endif #include <locale.h> +#ifdef HAVE_MALLOC_H /* for malloc_usable_size on Linux, _msize on Windows */ +#include <malloc.h> +#endif +#ifdef HAVE_MALLOC_MALLOC_H +#include <malloc/malloc.h> /* for malloc_size on OSX */ +#endif #include <math.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #ifdef XP_UNIX @@ -52,16 +58,17 @@ #endif #include "jswrapper.h" #include "prmjtime.h" #include "builtin/TestingFunctions.h" #include "frontend/Parser.h" #include "jit/arm/Simulator-arm.h" #include "jit/Ion.h" +#include "js/Debug.h" #include "js/OldDebugAPI.h" #include "js/StructuredClone.h" #include "perf/jsperf.h" #include "shell/jsheaptools.h" #include "shell/jsoptparse.h" #include "shell/OSObject.h" #include "vm/ArgumentsObject.h" #include "vm/Debugger.h" @@ -5843,16 +5850,36 @@ MaybeOverrideOutFileFromEnv(const char* /* Pretend we can always preserve wrappers for dummy DOM objects. */ static bool DummyPreserveWrapperCallback(JSContext *cx, JSObject *obj) { return true; } +size_t +ShellMallocSizeOf(const void *constPtr) +{ + // Match the type that all the library functions we might use here expect. + void *ptr = (void *) constPtr; + + if (!ptr) + return 0; + +#if defined(HAVE_MALLOC_USABLE_SIZE) + return malloc_usable_size(ptr); +#elif defined(HAVE_MALLOC_SIZE) + return malloc_size(ptr); +#elif HAVE__MSIZE + return _msize(ptr); +#else + return 0; +#endif +} + int main(int argc, char **argv, char **envp) { sArgc = argc; sArgv = argv; JSRuntime *rt; JSContext *cx; @@ -6090,16 +6117,18 @@ main(int argc, char **argv, char **envp) JS_SetSecurityCallbacks(rt, &ShellPrincipals::securityCallbacks); JS_InitDestroyPrincipalsCallback(rt, ShellPrincipals::destroy); JS_SetInterruptCallback(rt, ShellInterruptCallback); JS::SetAsmJSCacheOps(rt, &asmJSCacheOps); JS_SetNativeStackQuota(rt, gMaxStackSize); + JS::dbg::SetDebuggerMallocSizeOf(rt, ShellMallocSizeOf); + if (!offThreadState.init()) return 1; if (!InitWatchdog(rt)) return 1; cx = NewContext(rt); if (!cx)
--- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -10,16 +10,17 @@ #include "mozilla/Move.h" #include "mozilla/Vector.h" #include <stdlib.h> #include "jscompartment.h" #include "gc/Marking.h" +#include "js/Debug.h" #include "js/UbiNode.h" #include "js/UbiNodeTraverse.h" #include "vm/Debugger.h" #include "vm/GlobalObject.h" #include "vm/SavedStacks.h" #include "vm/Debugger-inl.h" @@ -244,16 +245,21 @@ DebuggerMemory::setMaxAllocationsLogLeng args.rval().setUndefined(); return true; } /* Debugger.Memory.prototype.takeCensus */ +void +JS::dbg::SetDebuggerMallocSizeOf(JSRuntime *rt, mozilla::MallocSizeOf mallocSizeOf) { + rt->debuggerMallocSizeOf = mallocSizeOf; +} + namespace js { namespace dbg { // Common data for census traversals. struct Census { JSContext * const cx; Zone::ZoneSet debuggeeZones; Zone *atomsZone;
--- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -116,16 +116,22 @@ PerThreadData::init() return true; } static const JSWrapObjectCallbacks DefaultWrapObjectCallbacks = { TransparentObjectWrapper, nullptr }; +static size_t +ReturnZeroSize(const void *p) +{ + return 0; +} + JSRuntime::JSRuntime(JSRuntime *parentRuntime) : JS::shadow::Runtime( #ifdef JSGC_GENERATIONAL &gc.storeBuffer #endif ), mainThread(this), parentRuntime(parentRuntime), @@ -218,17 +224,18 @@ JSRuntime::JSRuntime(JSRuntime *parentRu ctypesActivityCallback(nullptr), forkJoinWarmup(0), offthreadIonCompilationEnabled_(true), parallelParsingEnabled_(true), #ifdef DEBUG enteredPolicy(nullptr), #endif largeAllocationFailureCallback(nullptr), - oomCallback(nullptr) + oomCallback(nullptr), + debuggerMallocSizeOf(ReturnZeroSize) { liveRuntimesCount++; /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ JS_INIT_CLIST(&onNewGlobalObjectWatchers); PodArrayZero(nativeStackQuota); PodZero(&asmJSCacheOps);
--- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1397,16 +1397,22 @@ struct JSRuntime : public JS::shadow::Ru if (MOZ_LIKELY(!!p2)) return p2; if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { reportAllocationOverflow(); return nullptr; } return (T *)onOutOfMemoryCanGC(p, newSize * sizeof(T)); } + + /* + * Debugger.Memory functions like takeCensus use this embedding-provided + * function to assess the size of malloc'd blocks of memory. + */ + mozilla::MallocSizeOf debuggerMallocSizeOf; }; namespace js { // When entering JIT code, the calling JSContext* is stored into the thread's // PerThreadData. This function retrieves the JSContext with the pre-condition // that the caller is JIT code or C++ called directly from JIT code. This // function should not be called from arbitrary locations since the JSContext
--- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -22,16 +22,17 @@ #include "js/Vector.h" #include "vm/ScopeObject.h" #include "vm/Shape.h" #include "vm/String.h" #include "vm/Symbol.h" #include "jsobjinlines.h" +using JS::HandleValue; using JS::Value; using JS::ubi::Concrete; using JS::ubi::Edge; using JS::ubi::EdgeRange; using JS::ubi::Node; using JS::ubi::TracerConcrete; using JS::ubi::TracerConcreteWithCompartment;