Skip to content

Commit

Permalink
Add GetAllocationSite which try to recover allocation site of a given…
Browse files Browse the repository at this point in the history
… object.
  • Loading branch information
nbp committed Feb 11, 2013
1 parent 641bc07 commit 861435e
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
60 changes: 60 additions & 0 deletions js/src/jsfriendapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
#include "jswrapper.h"
#include "jsweakmap.h"
#include "jswatchpoint.h"
#include "jsinfer.h"

#include "builtin/TestingFunctions.h"

#include "jsobjinlines.h"
#include "jsinferinlines.h"

using namespace js;
using namespace JS;
Expand Down Expand Up @@ -1373,4 +1375,62 @@ StopWatchingLeaks(JSContext *cx)
ReleaseWatchedSet(rt->defaultFreeOp());
}

JS_FRIEND_API(JSBool)
GetAllocationSite(JSContext *cx, JSHandleObject object, JSMutableHandleValue loc)
{
using namespace js::types;
loc.setUndefined();

TypeObject *obj = object->getType(cx);
if (!obj)
return true;

AllocationSiteKey location;
AllocationSiteTable *allocSites = cx->compartment->types.allocationSiteTable;
if (!allocSites)
return true;

/* Match the TypeObject to find the allocation site of the object. */
for (AllocationSiteTable::Range r = allocSites->all(); !r.empty(); r.popFront()) {
if (r.front().value == obj) {
location.script = r.front().key.script;
location.offset = r.front().key.offset;
location.kind = r.front().key.kind;
break;
}
}

RootedValue objectCtor(cx, UndefinedValue());
RootedObject global(cx, JS_GetGlobalObject(cx));
if (!JS_GetProperty(cx, global, "Object", objectCtor.address()))
return false;
if (!objectCtor.isObject())
return false;

RootedObject locObj(cx, JS_New(cx, &objectCtor.toObject(), 0, NULL));
if (!locObj)
return false;

const char *filename = JS_GetScriptFilename(cx, location.script);
if (!filename)
return false;

RootedValue v(cx);
RootedString filenameStr(cx, JS_NewStringCopyZ(cx, filename));
if (!filenameStr)
return false;

v.setString(filenameStr);
if (!JS_SetProperty(cx, locObj, "filename", v.address()))
return false;

jsbytecode *pc = location.script->code + location.offset;
v.setInt32(JS_PCToLineNumber(cx, location.script, pc));
if (!JS_SetProperty(cx, locObj, "line", v.address()))
return false;

loc.setObject(*locObj);
return true;
}

} /* namespace js */
4 changes: 4 additions & 0 deletions js/src/jsfriendapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,10 @@ LiveWatchedObjects(JSContext *cx, JSMutableHandleValue watched);
extern JS_FRIEND_API(void)
StopWatchingLeaks(JSContext *cx);

/* Attempt to recover the location where the object has been allocated. */
extern JS_FRIEND_API(JSBool)
GetAllocationSite(JSContext *cx, JSHandleObject object, JSMutableHandleValue loc);

} /* namespace js */

#endif /* jsfriendapi_h___ */
28 changes: 28 additions & 0 deletions js/src/shell/js.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,30 @@ DumpObject(JSContext *cx, unsigned argc, jsval *vp)

#endif /* DEBUG */

static JSBool
GetAllocationSite(JSContext *cx, unsigned argc, jsval *vp)
{
if (argc < 1) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
"watchForLeak", "0", "s");
return false;
}

RootedValue target(cx, JS_ARGV(cx, vp)[0]);
if (!target.isObject()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
"argument", "not an object");
return false;
}

RootedObject obj(cx, &target.toObject());
RootedValue allocSite(cx, UndefinedValue());
if (!js::GetAllocationSite(cx, obj, &allocSite))
return false;
JS_SET_RVAL(cx, vp, allocSite);
return true;
}

static JSBool
BuildDate(JSContext *cx, unsigned argc, jsval *vp)
{
Expand Down Expand Up @@ -3771,6 +3795,10 @@ static JSFunctionSpecWithHelp shell_functions[] = {
"stopWatchingLeaks()",
" Clear meta-data needed for tracking logical leaks."),

JS_FN_HELP("getAllocationSite", GetAllocationSite, 0, 0,
"getAllocationSite(object)",
" Attempt to recover the location of the allocation of the given object."),

JS_FN_HELP("build", BuildDate, 0, 0,
"build()",
" Show build date and time."),
Expand Down

0 comments on commit 861435e

Please sign in to comment.