void JSVM::DumpJavascriptObjects() { ATOMIC_LOGINFOF("--- JS Objects ---"); ATOMIC_LOGINFOF("Stash Count: %u, Total Stash: %u, Total Unstash: %u", stashCount_, totalStashCount_, totalUnstashCount_); HashMap<StringHash, String> strLookup; HashMap<StringHash, unsigned> totalClassCount; HashMap<StringHash, unsigned> stashedClassCount; HashMap<StringHash, int> maxRefCount; StringHash refCountedTypeHash("RefCounted"); strLookup[refCountedTypeHash] = "RefCounted"; duk_push_global_stash(ctx_); duk_get_prop_index(ctx_, -1, JS_GLOBALSTASH_INDEX_REFCOUNTED_REGISTRY); HashMap<void*, RefCounted*>::ConstIterator itr = heapToObject_.Begin(); while (itr != heapToObject_.End()) { void* heapPtr = itr->first_; RefCounted* refCounted = itr->second_; // TODO: need a lookup for refcounted classid to typename const String& className = refCounted->IsObject() ? ((Object*)refCounted)->GetTypeName() : "RefCounted"; StringHash typeHash = refCounted->IsObject() ? ((Object*)refCounted)->GetType() : refCountedTypeHash; strLookup.InsertNew(typeHash, className); totalClassCount.InsertNew(typeHash, 0); totalClassCount[typeHash]++; maxRefCount.InsertNew(typeHash, 0); if (refCounted->Refs() > maxRefCount[typeHash]) maxRefCount[typeHash] = refCounted->Refs(); duk_push_pointer(ctx_, refCounted); duk_get_prop(ctx_, -2); if (!duk_is_undefined(ctx_, -1)) { stashedClassCount.InsertNew(typeHash, 0); stashedClassCount[typeHash]++; } duk_pop(ctx_); itr++; } HashMap<StringHash, String>::ConstIterator itr2 = strLookup.Begin(); while (itr2 != strLookup.End()) { StringHash typeHash = itr2->first_; const String& className = itr2->second_; unsigned totalCount = totalClassCount[typeHash]; unsigned stashedCount = stashedClassCount[typeHash]; int _maxRefCount = maxRefCount[typeHash]; ATOMIC_LOGINFOF("Classname: %s, Total: %u, Stashed: %u, Max Refs: %i", className.CString(), totalCount, stashedCount, _maxRefCount); itr2++; } duk_pop_2(ctx_); }