Bugzilla@Mozilla
New Account
|
Log In
or
Remember
[x]
|
Forgot Password
Login:
[x]
Home
|
New
|
Browse
|
Search
|
[
help
]
|
Reports
|
Product Dashboard
Attachment 211214 Details for
Bug 326225
[patch]
add idl constants, support type names and pointer addresses
326225.1 (text/plain), 15.14 KB, created by
timeless
(
hide
)
Description:
add idl constants, support type names and pointer addresses
Filename:
MIME Type:
Creator:
timeless
Size:
15.14 KB
patch
obsolete
>Index: src/jsfun.h >=================================================================== >RCS file: /cvsroot/mozilla/js/src/jsfun.h,v >retrieving revision 3.24 >diff -up -r3.24 src/jsfun.h >--- src/jsfun.h >+++ src/jsfun.h >@@ -80,9 +80,15 @@ extern JS_FRIEND_DATA(JSClass) js_Functi > /* > * NB: jsapi.h and jsobj.h must be included before any call to this macro. > */ >+#ifdef EXPORT_JS_API > #define JSVAL_IS_FUNCTION(cx, v) \ > (!JSVAL_IS_PRIMITIVE(v) && \ > OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) >+#else >+#define JSVAL_IS_FUNCTION(cx, v) \ >+ (!JSVAL_IS_PRIMITIVE(v) && \ >+ JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v))) >+#endif > > extern JSBool > js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, >Index: jsd/jsd_xpc.cpp >=================================================================== >RCS file: /cvsroot/mozilla/js/jsd/jsd_xpc.cpp,v >retrieving revision 1.72 >diff -up -r1.72 jsd/jsd_xpc.cpp >--- jsd/jsd_xpc.cpp >+++ jsd/jsd_xpc.cpp >@@ -50,6 +50,11 @@ > #include "jsdebug.h" > #include "nsReadableUtils.h" > #include "nsCRT.h" >+#include "nsPrintfCString.h" >+ >+#include "nsIOutputStream.h" >+#include "nsISupportsPrimitives.h" >+#include "nsDataHashtable.h" > > /* XXX this stuff is used by NestEventLoop, a temporary hack to be refactored > * later */ >@@ -2056,8 +2114,10 @@ jsdValue::GetJsType (PRUint32 *_rval) > *_rval = TYPE_FUNCTION; > else if (JSVAL_IS_OBJECT(val)) > *_rval = TYPE_OBJECT; >- else >- NS_ASSERTION (0, "Value has no discernible type."); >+ else { >+ NS_ERROR ("Value has no discernible type."); >+ return NS_ERROR_UNEXPECTED; >+ } > > return NS_OK; > } >@@ -2276,6 +2344,45 @@ jsdValue::GetWrappedValue() > return NS_OK; > } > >+static PRUint32 calculateJSValSize(jsval val, JSContext *cx) >+{ >+ if (JSVAL_IS_NULL(val)) >+ return sizeof(jsval); >+ if (JSVAL_IS_BOOLEAN(val)) >+ return sizeof(jsval); >+ if (JSVAL_IS_DOUBLE(val)) >+ return sizeof(jsdouble) + sizeof(jsval); >+ if (JSVAL_IS_INT(val)) >+ return sizeof(jsval); >+ if (JSVAL_IS_STRING(val)) >+ return sizeof(jschar) * JS_GetStringLength(JSVAL_TO_STRING(val)); >+ if (JSVAL_IS_VOID(val)) >+ return sizeof(jsval); >+ >+ JS_BeginRequest(cx); >+ PRUint32 size = 0; >+ if (JSVAL_IS_FUNCTION(cx, val)) >+ size = JS_GetFunctionTotalSize(cx, JS_ValueToFunction(cx, val)); >+ else if (JSVAL_IS_OBJECT(val)) >+ size = JS_GetObjectTotalSize(cx, JSVAL_TO_OBJECT(val)); >+ JS_EndRequest(cx); >+ >+ return size; >+} >+ >+NS_IMETHODIMP >+jsdValue::GetSize(PRUint32 *aSize) >+{ >+ ASSERT_VALID_EPHEMERAL; >+ jsval val = JSD_GetValueWrappedJSVal (mCx, mValue); >+ PRUint32 size = calculateJSValSize(val, JSD_GetDefaultJSContext (mCx)); >+ *aSize = size; >+ if (!size) >+ return NS_ERROR_UNEXPECTED; >+ >+ return NS_OK; >+} >+ > /****************************************************************************** > * debugger service implementation > ******************************************************************************/ >@@ -3233,6 +3600,311 @@ jsdService::SetFunctionHook (jsdICallHoo > *aHook = mFunctionHook; > NS_IF_ADDREF(*aHook); > >+ return NS_OK; >+} >+ >+struct ObjectCreationInfo { >+ uintN minSize; >+ uintN maxSize; >+ uintN count; >+ PRInt64 totalSize; >+}; >+ >+const char objectTypeNames[][16] = { >+ "unknown,", >+ "null,", >+ "boolean,", >+ "double,", >+ "integer,", >+ "string,", >+ "void,", >+ "function,", >+ "object,", >+ 0 >+}; >+ >+const PRUint32 objectTypeNamesLength[] = { >+ 9, >+ 6, >+ 9, >+ 8, >+ 9, >+ 8, >+ 6, >+ 11, >+ 8, >+ 0 >+}; >+ >+static void annotateJSValType(nsAFlatCString &type, jsval val, JSContext *cx) >+{ >+ PRUint32 kind = 0; >+ if (JSVAL_IS_NULL(val)) >+ kind = 1; >+ else if (JSVAL_IS_BOOLEAN(val)) >+ kind = 2; >+ else if (JSVAL_IS_DOUBLE(val)) >+ kind = 3; >+ else if (JSVAL_IS_INT(val)) >+ kind = 4; >+ else if (JSVAL_IS_STRING(val)) >+ kind = 5; >+ else if (JSVAL_IS_VOID(val)) >+ kind = 6; >+ else { >+ JS_BeginRequest(cx); >+ if (JSVAL_IS_FUNCTION(cx, val)) >+ kind = 7; >+ JS_EndRequest(cx); >+ if (!kind) { >+ if (JSVAL_IS_OBJECT(val)) >+ kind = 8; >+ } >+ } >+ type.Append(objectTypeNames[kind]); >+} >+ >+static void annotateJSValName(nsAFlatCString &name, jsval val, JSContext *cx, JSDContext *dx, JSDValue *dval) >+{ >+ PRUint32 kind = 0; >+ if (JSVAL_IS_NULL(val)) >+ kind = 1; >+ else if (JSVAL_IS_BOOLEAN(val)) >+ kind = 2; >+ else if (JSVAL_IS_DOUBLE(val)) >+ kind = 3; >+ else if (JSVAL_IS_INT(val)) >+ kind = 4; >+ else if (JSVAL_IS_STRING(val)) >+ kind = 5; >+ else if (JSVAL_IS_VOID(val)) >+ kind = 6; >+ else { >+ JS_BeginRequest(cx); >+ if (JSVAL_IS_FUNCTION(cx, val)) >+ kind = 7; >+ JS_EndRequest(cx); >+ if (!kind) { >+ if (JSVAL_IS_OBJECT(val)) >+ kind = 8; >+ } >+ } >+ switch (kind) { >+ case 7: >+ name.Append(JSD_GetValueFunctionName(dx, dval)); >+ break; >+ case 8: >+ name.Append(JSD_GetValueClassName(dx, dval)); >+ break; >+ default: >+ name.Append(objectTypeNames[kind]); >+ } >+} >+ >+static void FormatSpaceString(nsCAutoString &lineItem, ObjectCreationInfo *oci) >+{ >+ lineItem.AppendInt(oci->count); >+ lineItem.AppendLiteral(","); >+ if (oci->minSize) { >+ lineItem.AppendInt(oci->minSize); >+ lineItem.AppendLiteral(","); >+ lineItem.AppendInt(oci->maxSize); >+ lineItem.AppendLiteral(","); >+ } >+ lineItem.AppendInt(oci->totalSize); >+ lineItem.AppendLiteral("\r\n"); >+} >+ >+static PLDHashOperator PR_CALLBACK >+ObjectsSpaceStreamWriter(const nsACString &aKey, ObjectCreationInfo *&oci, void *aClosure) >+{ >+ /* Count,Min,Max,Total */ >+ nsIOutputStream* stream = (nsIOutputStream*) aClosure; >+ PRUint32 written; >+ nsCAutoString lineItem(aKey); >+ FormatSpaceString(lineItem, oci); >+ stream->Write(lineItem.get(), lineItem.Length(), &written); >+ return PL_DHASH_NEXT; >+} >+ >+static PLDHashOperator >+ObjectsSpaceStringWriter(const nsACString &aKey, ObjectCreationInfo *&oci, void *aClosure) >+{ >+ nsISupportsCString* string = (nsISupportsCString*) aClosure; >+ nsCAutoString report; >+ string->GetData(report); >+ nsCAutoString lineItem(aKey); >+ FormatSpaceString(lineItem, oci); >+ report.Append(lineItem); >+ string->SetData(report); >+ return PL_DHASH_NEXT; >+} >+ >+static PLDHashOperator >+ObjectsSpaceDestructor(const nsACString &aKey, ObjectCreationInfo *&oci, void *aClosure) >+{ >+ free(oci); >+ return PL_DHASH_NEXT; >+} >+ >+void >+Write(nsIOutputStream* stream, nsISupportsCString *string, const nsAFlatCString &lineItem, nsAFlatCString &report) >+{ >+ PRUint32 written; >+ if (stream) >+ stream->Write(lineItem.get(), lineItem.Length(), &written); >+ /* yes, this can work really poorly on oom */ >+ report.Append(lineItem); >+} >+ >+NS_IMETHODIMP >+jsdService::ReportLiveObjects(nsISupports *reportSink, PRUint32 flags) >+{ >+ /** >+ * flags >+ * 0x1 Distinguish lines >+ * 0x2 Distinguish types >+ * 0x4 Distinguish sizes >+ * 0x8 Distinguish names >+ * 0x10 Distinguish objects >+ */ >+ NS_ENSURE_ARG_POINTER(reportSink); >+ nsCAutoString report; >+ nsCAutoString lineItem; >+ nsDataHashtable<nsCStringHashKey,ObjectCreationInfo*> objectSpaceTable; >+ jsval val; >+ JSDObject *dobject, *iter = 0; >+ JSContext *cx = JSD_GetDefaultJSContext (mCx); >+ ObjectCreationInfo *oci = nsnull; >+ nsCOMPtr<nsIOutputStream> stream(do_QueryInterface(reportSink)); >+ nsCOMPtr<nsISupportsCString> string(do_QueryInterface(reportSink)); >+ int stateful = 2; >+ >+ if (!stream && !string) >+ return NS_ERROR_NOT_IMPLEMENTED; >+ >+ NS_NAMED_LITERAL_CSTRING(unknownFilename, "\"_unknown_\","); >+ nsCAutoString header("File,Line,"); >+ if (flags & jsdIDebuggerService::DISTINGUISH_TYPES) >+ header.AppendLiteral("Type,"); >+ NS_NAMED_LITERAL_CSTRING(sizeHeader, "Object,Size,\r\n"); >+ if (flags & jsdIDebuggerService::DISTINGUISH_NAMES) { >+ header.AppendLiteral("Name,"); >+ } >+ if ((flags & jsdIDebuggerService::DISTINGUISH_OBJECTS) || >+ !objectSpaceTable.Init(2048)) { >+ stateful = 1; >+ flags |= jsdIDebuggerService::DISTINGUISH_SIZES; >+ header.Append(sizeHeader); >+ Write(stream, string, header, report); >+ } >+ >+ PRUint32 size; >+ /* stateful: >+ * 2 - standard operation >+ * 1 - low memory >+ * 0 - done >+ */ >+ JSD_LockObjectSubsystem(mCx); >+ dobject = JSD_IterateObjects(mCx, &iter); >+ while (dobject) { >+ if (const char* url = JSD_GetObjectNewURL(mCx, dobject)) { >+ lineItem.AssignLiteral("\""); >+ lineItem.Append(url); >+ lineItem.AppendLiteral("\","); >+ } else { >+ lineItem.Assign(unknownFilename); >+ } >+ if (flags & jsdIDebuggerService::DISTINGUISH_LINES) { >+ lineItem.AppendInt(JSD_GetObjectNewLineNumber(mCx, dobject)); >+ lineItem.AppendLiteral(","); >+ } >+ val = OBJECT_TO_JSVAL(JSD_GetWrappedObject(mCx, dobject)); >+ if (flags & jsdIDebuggerService::DISTINGUISH_TYPES) >+ annotateJSValType(lineItem, val, cx); >+ size = calculateJSValSize(val, cx); >+ if (flags & jsdIDebuggerService::DISTINGUISH_NAMES) { >+ annotateJSValName(lineItem, val, cx, mCx, JSD_GetValueForObject(mCx, dobject)); >+ lineItem.AppendLiteral(","); >+ } >+ if (flags & jsdIDebuggerService::DISTINGUISH_OBJECTS) { >+ nsPrintfCString pointer("%p,",(void*)val); >+ lineItem.Append(pointer); >+ } >+ if (flags & jsdIDebuggerService::DISTINGUISH_SIZES) { >+ lineItem.AppendInt(size); >+ lineItem.AppendLiteral(","); >+ } >+ if (stateful == 2) { >+ if (!objectSpaceTable.Get(lineItem, &oci)) >+ oci = nsnull; >+ if (!oci) { >+ oci = (ObjectCreationInfo*)malloc(sizeof ObjectCreationInfo); >+ if (!oci) { >+ stateful = 1; >+ flags |= jsdIDebuggerService::DISTINGUISH_SIZES; >+ iter = nsnull; >+ dobject = JSD_IterateObjects(mCx, &iter); >+ objectSpaceTable.Enumerate(ObjectsSpaceDestructor, nsnull); >+ JSD_UnlockObjectSubsystem(mCx); >+ if (string) >+ string->SetData(EmptyCString()); >+ if (flags & jsdIDebuggerService::DISTINGUISH_NAMES) { >+ header.AppendLiteral("Name,"); >+ } >+ header.Append(sizeHeader); >+ Write(stream, string, header, report); >+ JSD_LockObjectSubsystem(mCx); >+ continue; >+ } >+ if (~flags & jsdIDebuggerService::DISTINGUISH_SIZES) { >+ oci->minSize = size; >+ oci->maxSize = size; >+ } else { >+ oci->minSize = oci->maxSize = 0; >+ } >+ oci->count = 0; >+ oci->totalSize = LL_ZERO; >+ objectSpaceTable.Put(lineItem, oci); >+ } >+ if (~flags & jsdIDebuggerService::DISTINGUISH_SIZES) { >+ oci->minSize = PR_MIN(oci->minSize, size); >+ oci->maxSize = PR_MAX(oci->maxSize, size); >+ } >+ PRUint64 delta; >+ LL_UI2L(delta, size); >+ LL_ADD(oci->totalSize, oci->totalSize, delta); >+ ++oci->count; >+ } else if (stateful == 1) { >+ JSD_UnlockObjectSubsystem(mCx); >+ lineItem.AppendLiteral("\r\n"); >+ Write(stream, string, lineItem, report); >+ JSD_LockObjectSubsystem(mCx); >+ } >+ dobject = JSD_IterateObjects(mCx, &iter); >+ } >+ JSD_UnlockObjectSubsystem(mCx); >+ if (stateful == 2) { >+ if (flags & jsdIDebuggerService::DISTINGUISH_SIZES) >+ header.AppendLiteral("Size,"); >+ header.AppendLiteral("Count,"); >+ if (~flags & jsdIDebuggerService::DISTINGUISH_SIZES) >+ header.AppendLiteral("Min,Max,"); >+ header.AppendLiteral("Total,"); >+ header.AppendLiteral("\r\n"); >+ Write(stream, string, header, report); >+ if (stream) >+ objectSpaceTable.Enumerate(ObjectsSpaceStreamWriter, stream); >+ if (string) { >+ string->SetData(report); >+ objectSpaceTable.Enumerate(ObjectsSpaceStringWriter, string); >+ } >+ objectSpaceTable.Enumerate(ObjectsSpaceDestructor, nsnull); >+ } else if (stateful == 1) { >+ if (string) { >+ string->SetData(report); >+ } >+ } > return NS_OK; > } > >Index: jsd/idl/jsdIDebuggerService.idl >=================================================================== >RCS file: /cvsroot/mozilla/js/jsd/idl/jsdIDebuggerService.idl,v >retrieving revision 1.32 >diff -up -r1.32 jsd/idl/jsdIDebuggerService.idl >--- jsd/idl/jsdIDebuggerService.idl >+++ jsd/idl/jsdIDebuggerService.idl >@@ -382,6 +383,37 @@ interface jsdIDebuggerService : nsISuppo > * nested. your code can use it for sanity checks. > */ > unsigned long exitNestedEventLoop (); >+ >+ /** >+ * List allocations by line >+ */ >+ const unsigned long DISTINGUISH_LINES = 0x1; >+ /** >+ * List allocations by type >+ */ >+ const unsigned long DISTINGUISH_TYPES = 0x2; >+ /** >+ * List allocations by size >+ */ >+ const unsigned long DISTINGUISH_SIZES = 0x4; >+ /** >+ * List allocations by name >+ */ >+ const unsigned long DISTINGUISH_NAMES = 0x8; >+ /** >+ * List individual objects >+ */ >+ const unsigned long DISTINGUISH_OBJECTS = 0x10; >+ /** >+ * Report the size and allocation location of objects >+ * @param reportSink The sink into which the resulting output will be sent. >+ * This function will try to send it as a very long single >+ * lump of data. >+ * @param flags Bit field of flag modifiers. >+ * @see DISTINGUISH_ bits above. >+ * @throws NS_ERROR_NOT_IMPLEMENTED if the sink object type isn't supported >+ */ >+ void reportLiveObjects(in nsISupports reportSink, in unsigned long flags); > }; > > /* callback interfaces */ >@@ -1143,6 +1181,12 @@ interface jsdIValue : jsdIEphemeral > * defined error code. > */ > void getWrappedValue(); >+ >+ /** >+ * Retrieves the size of the object (including space required for slots, >+ * but excluding space required by objects referenced by the object). >+ */ >+ readonly attribute unsigned long size; > }; > > /**
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Flags:
timeless
: review? (
caillon
)
Actions:
View
|
Diff
|
Review
Attachments on
bug 326225
:
210998
|
211022
|
211033
| 211214
Privacy Policy