11e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Copyright 2011 the V8 project authors. All rights reserved. 21e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Redistribution and use in source and binary forms, with or without 31e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// modification, are permitted provided that the following conditions are 41e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// met: 51e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// 61e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// * Redistributions of source code must retain the above copyright 71e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// notice, this list of conditions and the following disclaimer. 81e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// * Redistributions in binary form must reproduce the above 91e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// copyright notice, this list of conditions and the following 101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// disclaimer in the documentation and/or other materials provided 111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// with the distribution. 121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// * Neither the name of Google Inc. nor the names of its 131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// contributors may be used to endorse or promote products derived 141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// from this software without specific prior written permission. 151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// 161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef LIVE_OBJECT_LIST 291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include <ctype.h> 311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include <stdlib.h> 321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "v8.h" 341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "checks.h" 361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "global-handles.h" 371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "heap.h" 381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "inspector.h" 3969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "isolate.h" 401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "list-inl.h" 41e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#include "liveobjectlist-inl.h" 421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "string-stream.h" 431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "v8utils.h" 4469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "v8conversions.h" 451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace v8 { 471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blocknamespace internal { 481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 50e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtypedef int (*RawComparer)(const void*, const void*); 51e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 52e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 53e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef CHECK_ALL_OBJECT_TYPES 54e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 55e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define DEBUG_LIVE_OBJECT_TYPES(v) \ 56e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Smi, "unexpected: Smi") \ 57e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch \ 58e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(CodeCache, "unexpected: CodeCache") \ 59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(BreakPointInfo, "unexpected: BreakPointInfo") \ 60e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(DebugInfo, "unexpected: DebugInfo") \ 61e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(TypeSwitchInfo, "unexpected: TypeSwitchInfo") \ 62e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SignatureInfo, "unexpected: SignatureInfo") \ 63e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Script, "unexpected: Script") \ 64e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ObjectTemplateInfo, "unexpected: ObjectTemplateInfo") \ 65e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(FunctionTemplateInfo, "unexpected: FunctionTemplateInfo") \ 66e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(CallHandlerInfo, "unexpected: CallHandlerInfo") \ 67e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(InterceptorInfo, "unexpected: InterceptorInfo") \ 68e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(AccessCheckInfo, "unexpected: AccessCheckInfo") \ 69e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(AccessorInfo, "unexpected: AccessorInfo") \ 70e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalTwoByteString, "unexpected: ExternalTwoByteString") \ 71e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalAsciiString, "unexpected: ExternalAsciiString") \ 72e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalString, "unexpected: ExternalString") \ 73e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SeqTwoByteString, "unexpected: SeqTwoByteString") \ 74e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SeqAsciiString, "unexpected: SeqAsciiString") \ 75e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SeqString, "unexpected: SeqString") \ 76e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSFunctionResultCache, "unexpected: JSFunctionResultCache") \ 77e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(GlobalContext, "unexpected: GlobalContext") \ 78e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(MapCache, "unexpected: MapCache") \ 79e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(CodeCacheHashTable, "unexpected: CodeCacheHashTable") \ 80e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(CompilationCacheTable, "unexpected: CompilationCacheTable") \ 81e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SymbolTable, "unexpected: SymbolTable") \ 82e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Dictionary, "unexpected: Dictionary") \ 83e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(HashTable, "unexpected: HashTable") \ 84e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(DescriptorArray, "unexpected: DescriptorArray") \ 85e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalFloatArray, "unexpected: ExternalFloatArray") \ 86e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalUnsignedIntArray, "unexpected: ExternalUnsignedIntArray") \ 87e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalIntArray, "unexpected: ExternalIntArray") \ 88e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalUnsignedShortArray, "unexpected: ExternalUnsignedShortArray") \ 89e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalShortArray, "unexpected: ExternalShortArray") \ 90e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalUnsignedByteArray, "unexpected: ExternalUnsignedByteArray") \ 91e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalByteArray, "unexpected: ExternalByteArray") \ 92e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSValue, "unexpected: JSValue") 93e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 94e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#else 95e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define DEBUG_LIVE_OBJECT_TYPES(v) 96e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif 97e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 98e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 99e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define FOR_EACH_LIVE_OBJECT_TYPE(v) \ 100e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DEBUG_LIVE_OBJECT_TYPES(v) \ 101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch \ 102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSArray, "JSArray") \ 103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSRegExp, "JSRegExp") \ 104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSFunction, "JSFunction") \ 105e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSGlobalObject, "JSGlobal") \ 106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSBuiltinsObject, "JSBuiltins") \ 107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(GlobalObject, "Global") \ 108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSGlobalProxy, "JSGlobalProxy") \ 109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(JSObject, "JSObject") \ 110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch \ 111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Context, "meta: Context") \ 112e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ByteArray, "meta: ByteArray") \ 11369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v(ExternalPixelArray, "meta: PixelArray") \ 114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(ExternalArray, "meta: ExternalArray") \ 115e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(FixedArray, "meta: FixedArray") \ 116e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(String, "String") \ 117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(HeapNumber, "HeapNumber") \ 118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch \ 119e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Code, "meta: Code") \ 120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Map, "meta: Map") \ 121e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Oddball, "Oddball") \ 122257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch v(Foreign, "meta: Foreign") \ 123e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(SharedFunctionInfo, "meta: SharedFunctionInfo") \ 124e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(Struct, "meta: Struct") \ 125e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch \ 126e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch v(HeapObject, "HeapObject") 127e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 129e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochenum /* LiveObjectType */ { 130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define DECLARE_OBJECT_TYPE_ENUM(type, name) kType##type, 131e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FOR_EACH_LIVE_OBJECT_TYPE(DECLARE_OBJECT_TYPE_ENUM) 132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kInvalidLiveObjType, 133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNumberOfTypes 134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#undef DECLARE_OBJECT_TYPE_ENUM 135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectType GetObjectType(HeapObject* heap_obj) { 139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // TODO(mlam): investigate usint Map::instance_type() instead. 140e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define CHECK_FOR_OBJECT_TYPE(type, name) \ 141e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (heap_obj->Is##type()) return kType##type; 142e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FOR_EACH_LIVE_OBJECT_TYPE(CHECK_FOR_OBJECT_TYPE) 143e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#undef CHECK_FOR_OBJECT_TYPE 144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 145e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch UNREACHABLE(); 146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return kInvalidLiveObjType; 147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 149e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 150e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochinline const char* GetObjectTypeDesc(LiveObjectType type) { 151e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const char* const name[kNumberOfTypes] = { 152e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch #define DEFINE_OBJECT_TYPE_NAME(type, name) name, 153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FOR_EACH_LIVE_OBJECT_TYPE(DEFINE_OBJECT_TYPE_NAME) 154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "invalid" 155e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch #undef DEFINE_OBJECT_TYPE_NAME 156e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch }; 157e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(type < kNumberOfTypes); 158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return name[type]; 159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 160e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochconst char* GetObjectTypeDesc(HeapObject* heap_obj) { 163e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectType type = GetObjectType(heap_obj); 164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return GetObjectTypeDesc(type); 165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool IsOfType(LiveObjectType type, HeapObject* obj) { 169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: there are types that are more general (e.g. JSObject) that would 170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // have passed the Is##type_() test for more specialized types (e.g. 171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // JSFunction). If we find a more specialized match but we're looking for 172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the general type, then we should reject the ones that matches the 173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // specialized type. 174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define CHECK_OBJECT_TYPE(type_, name) \ 175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->Is##type_()) return (type == kType##type_); 176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE) 178e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#undef CHECK_OBJECT_TYPE 179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; 181e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 182e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochconst AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1); 185e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 186e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic AllocationSpace FindSpaceFor(String* space_str) { 187589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> s = 188e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 189e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 190e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* key_str = *s; 191e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch switch (key_str[0]) { 192e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case 'c': 193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "cell") == 0) return CELL_SPACE; 194e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "code") == 0) return CODE_SPACE; 195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case 'l': 197e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "lo") == 0) return LO_SPACE; 198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 199e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case 'm': 200e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "map") == 0) return MAP_SPACE; 201e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 202e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case 'n': 203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "new") == 0) return NEW_SPACE; 204e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 205e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch case 'o': 206e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "old-pointer") == 0) return OLD_POINTER_SPACE; 207e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strcmp(key_str, "old-data") == 0) return OLD_DATA_SPACE; 208e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 209e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 210e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return kInvalidSpace; 211e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 212e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic bool InSpace(AllocationSpace space, HeapObject* heap_obj) { 21569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = ISOLATE->heap(); 216e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (space != LO_SPACE) { 21769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->InSpace(heap_obj, space); 218e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 219e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // This is an optimization to speed up the check for an object in the LO 221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // space by exclusion because we know that all object pointers passed in 222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // here are guaranteed to be in the heap. Hence, it is safe to infer 223e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // using an exclusion test. 224e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: calling Heap::InSpace(heap_obj, LO_SPACE) is too slow for our 225e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // filters. 226e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int first_space = static_cast<int>(FIRST_SPACE); 227e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int last_space = static_cast<int>(LO_SPACE); 228e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int sp = first_space; sp < last_space; sp++) { 22969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (heap->InSpace(heap_obj, static_cast<AllocationSpace>(sp))) { 230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; 231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 232e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 23369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SLOW_ASSERT(heap->InSpace(heap_obj, LO_SPACE)); 234e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 236e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 237e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 238e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic LiveObjectType FindTypeFor(String* type_str) { 239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> s = 240e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 241e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 242e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#define CHECK_OBJECT_TYPE(type_, name) { \ 243e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* type_desc = GetObjectTypeDesc(kType##type_); \ 244e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* key_str = *s; \ 245e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (strstr(type_desc, key_str) != NULL) return kType##type_; \ 246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE) 248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#undef CHECK_OBJECT_TYPE 249e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 250e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return kInvalidLiveObjType; 251e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 252e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolFilter { 255e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 256e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch explicit LolFilter(Handle<JSObject> filter_obj); 257e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 258e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool is_active() const { return is_active_; } 259e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool Matches(HeapObject* obj) { 260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return !is_active() || MatchesSlow(obj); 261e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 262e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 263e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 264e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void InitTypeFilter(Handle<JSObject> filter_obj); 265e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void InitSpaceFilter(Handle<JSObject> filter_obj); 266e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void InitPropertyFilter(Handle<JSObject> filter_obj); 267e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool MatchesSlow(HeapObject* obj); 268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 269e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool is_active_; 270e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectType type_; 271e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch AllocationSpace space_; 272e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> prop_; 273e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 274e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLolFilter::LolFilter(Handle<JSObject> filter_obj) 277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : is_active_(false), 278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch type_(kInvalidLiveObjType), 279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch space_(kInvalidSpace), 280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prop_() { 281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (filter_obj.is_null()) return; 282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InitTypeFilter(filter_obj); 284e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InitSpaceFilter(filter_obj); 285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InitPropertyFilter(filter_obj); 286e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 288e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 289e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LolFilter::InitTypeFilter(Handle<JSObject> filter_obj) { 29069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> type_sym = FACTORY->LookupAsciiSymbol("type"); 291e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result = filter_obj->GetProperty(*type_sym); 292e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* type_obj; 293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->ToObject(&type_obj)) { 294e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (type_obj->IsString()) { 295e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String* type_str = String::cast(type_obj); 296e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch type_ = FindTypeFor(type_str); 297e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (type_ != kInvalidLiveObjType) { 298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch is_active_ = true; 299e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 301e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 304e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LolFilter::InitSpaceFilter(Handle<JSObject> filter_obj) { 30669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> space_sym = FACTORY->LookupAsciiSymbol("space"); 307e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result = filter_obj->GetProperty(*space_sym); 308e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* space_obj; 309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->ToObject(&space_obj)) { 310e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (space_obj->IsString()) { 311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String* space_str = String::cast(space_obj); 312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch space_ = FindSpaceFor(space_str); 313e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (space_ != kInvalidSpace) { 314e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch is_active_ = true; 315e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 320e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 321e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LolFilter::InitPropertyFilter(Handle<JSObject> filter_obj) { 32269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> prop_sym = FACTORY->LookupAsciiSymbol("prop"); 323e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result = filter_obj->GetProperty(*prop_sym); 324e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* prop_obj; 325e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->ToObject(&prop_obj)) { 326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (prop_obj->IsString()) { 327e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prop_ = Handle<String>(String::cast(prop_obj)); 328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch is_active_ = true; 329e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 333e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochbool LolFilter::MatchesSlow(HeapObject* obj) { 335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((type_ != kInvalidLiveObjType) && !IsOfType(type_, obj)) { 336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; // Fail because obj is not of the type of interest. 337e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((space_ != kInvalidSpace) && !InSpace(space_, obj)) { 339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; // Fail because obj is not in the space of interest. 340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!prop_.is_null() && obj->IsJSObject()) { 342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LookupResult result; 343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->Lookup(*prop_, &result); 344e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!result.IsProperty()) { 345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; // Fail because obj does not have the property of interest. 346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 350e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 351e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 352e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolIterator { 353e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolIterator(LiveObjectList* older, LiveObjectList* newer) 355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : older_(older), 356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch newer_(newer), 357e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch curr_(0), 358e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements_(0), 359e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count_(0), 360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index_(0) { } 361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void Init() { 363e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(newer_); 364e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the elements_ list is empty, then move on to the next list as long 365e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // as we're not at the last list (indicated by done()). 366e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((elements_ == NULL) && !Done()) { 367e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(curr_->prev_); 368e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 370e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 371e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool Done() const { 372e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return (curr_ == older_); 373e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 374e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 375e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Object level iteration. 376e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void Next() { 377e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index_++; 378e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (index_ >= count_) { 379e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate backwards until we get to the oldest list. 380e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (!Done()) { 381e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(curr_->prev_); 382e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If we have elements to process, we're good to go. 383e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (elements_ != NULL) break; 384e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Else, we should advance to the next older list. 386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 387e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 390e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int Id() const { 391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return elements_[index_].id_; 392e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline HeapObject* Obj() const { 394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return elements_[index_].obj_; 395e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 397e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int LolObjCount() const { 398e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (curr_ != NULL) return curr_->obj_count_; 399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return 0; 400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 402e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch protected: 403e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void SetCurrent(LiveObjectList* new_curr) { 404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch curr_ = new_curr; 405e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (curr_ != NULL) { 406e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements_ = curr_->elements_; 407e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count_ = curr_->obj_count_; 408e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index_ = 0; 409e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 410e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 411e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 412e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* older_; 413e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* newer_; 414e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* curr_; 415e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList::Element* elements_; 416e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count_; 417e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int index_; 418e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 419e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 420e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolForwardIterator : public LolIterator { 422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolForwardIterator(LiveObjectList* first, LiveObjectList* last) 424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : LolIterator(first, last) { 425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void Init() { 428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(older_); 429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the elements_ list is empty, then move on to the next list as long 430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // as we're not at the last list (indicated by Done()). 431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((elements_ == NULL) && !Done()) { 432e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(curr_->next_); 433e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 435e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 436e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool Done() const { 437e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return (curr_ == newer_); 438e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 439e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 440e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Object level iteration. 441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void Next() { 442e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index_++; 443e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (index_ >= count_) { 444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Done with current list. Move on to the next. 445e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (!Done()) { // If not at the last list already, ... 446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetCurrent(curr_->next_); 447e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If we have elements to process, we're good to go. 448e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (elements_ != NULL) break; 449e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 450e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Else, we should advance to the next list. 451e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 452e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 453e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 454e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 455e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 456e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 457e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Minimizes the white space in a string. Tabs and newlines are replaced 458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// with a space where appropriate. 459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic int CompactString(char* str) { 460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char* src = str; 461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char* dst = str; 462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char prev_ch = 0; 463e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (*dst != '\0') { 464e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char ch = *src++; 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We will treat non-ASCII chars as '?'. 466e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((ch & 0x80) != 0) { 467e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ch = '?'; 468e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 469e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Compact contiguous whitespace chars into a single ' '. 470e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (isspace(ch)) { 471e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (prev_ch != ' ') *dst++ = ' '; 472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prev_ch = ' '; 473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *dst++ = ch; 476e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prev_ch = ch; 477e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 478e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return (dst - str); 479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 480e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 481e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 482e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Generates a custom description based on the specific type of 483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// object we're looking at. We only generate specialized 484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// descriptions where we can. In all other cases, we emit the 485e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// generic info. 486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic void GenerateObjectDesc(HeapObject* obj, 487e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char* buffer, 488e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int buffer_size) { 489e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Vector<char> buffer_v(buffer, buffer_size); 490e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(obj != NULL); 491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->IsJSArray()) { 492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSArray* jsarray = JSArray::cast(obj); 493e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch double length = jsarray->length()->Number(); 494e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(buffer_v, 495e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "%p <%s> len %g", 496e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj), 497e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GetObjectTypeDesc(obj), 498e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch length); 499e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 500e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (obj->IsString()) { 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch String* str = String::cast(obj); 502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Only grab up to 160 chars in case they are double byte. 503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We'll only dump 80 of them after we compact them. 504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const int kMaxCharToDump = 80; 505e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const int kMaxBufferSize = kMaxCharToDump * 2; 506589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, 507589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ROBUST_STRING_TRAVERSAL, 508589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 0, 509589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch kMaxBufferSize); 510e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char* str_cstr = *str_sp; 511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int length = CompactString(str_cstr); 512e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(buffer_v, 513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "%p <%s> '%.80s%s'", 514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj), 515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GetObjectTypeDesc(obj), 516e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch str_cstr, 517e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (length > kMaxCharToDump) ? "..." : ""); 518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (obj->IsJSFunction() || obj->IsSharedFunctionInfo()) { 520e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SharedFunctionInfo* sinfo; 521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->IsJSFunction()) { 522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSFunction* func = JSFunction::cast(obj); 523e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sinfo = func->shared(); 524e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 525e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sinfo = SharedFunctionInfo::cast(obj); 526e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 527e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 528e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch String* name = sinfo->DebugName(); 529589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> name_sp = 530e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 531e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char* name_cstr = *name_sp; 532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapStringAllocator string_allocator; 534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StringStream stream(&string_allocator); 535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sinfo->SourceCodePrint(&stream, 50); 536589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<const char> source_sp = stream.ToCString(); 537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* source_cstr = *source_sp; 538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 539e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(buffer_v, 540e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "%p <%s> '%s' %s", 541e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj), 542e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GetObjectTypeDesc(obj), 543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch name_cstr, 544e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch source_cstr); 545e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (obj->IsFixedArray()) { 547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FixedArray* fixed = FixedArray::cast(obj); 548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 549e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(buffer_v, 550e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "%p <%s> len %d", 551e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj), 552e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GetObjectTypeDesc(obj), 553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fixed->length()); 554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(buffer_v, 557e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "%p <%s>", 558e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj), 559e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GetObjectTypeDesc(obj)); 560e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 561e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 562e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 564e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Utility function for filling in a line of detail in a verbose dump. 565e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic bool AddObjDetail(Handle<FixedArray> arr, 566e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int index, 567e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int obj_id, 568e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> target, 569e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* desc_str, 570e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> id_sym, 571e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc_sym, 572e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> size_sym, 573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> detail, 574e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc, 575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) { 57669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 57769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 57869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch detail = factory->NewJSObject(isolate->object_function()); 579e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (detail->IsFailure()) { 580e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error = detail; 581e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; 582e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 583e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 584e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = 0; 585e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char buffer[512]; 586e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (desc_str == NULL) { 587e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(!target.is_null()); 588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* obj = *target; 589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GenerateObjectDesc(obj, buffer, sizeof(buffer)); 590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_str = buffer; 591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size = obj->Size(); 592e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 59369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch desc = factory->NewStringFromAscii(CStrVector(desc_str)); 594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (desc->IsFailure()) { 595e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error = desc; 596e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; 597e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 598e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 599e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = detail->SetProperty(*id_sym, 600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(obj_id), 601e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return false; 604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = detail->SetProperty(*desc_sym, 606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *desc, 607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 608e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return false; 610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = detail->SetProperty(*size_sym, 612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(size), 613e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return false; 616e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch arr->set(index, *detail); 619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 620e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 622e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 623e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass DumpWriter { 624e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual ~DumpWriter() {} 626e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 627e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void ComputeTotalCountAndSize(LolFilter* filter, 628e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* count, 629e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* size) = 0; 630e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual bool Write(Handle<FixedArray> elements_arr, 631e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 632e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 633e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 634e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) = 0; 635e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 636e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 637e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 638e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolDumpWriter: public DumpWriter { 639e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 640e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolDumpWriter(LiveObjectList* older, LiveObjectList* newer) 641e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : older_(older), newer_(newer) { 642e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 643e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 644e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) { 645e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *count = 0; 646e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *size = 0; 647e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 648e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolIterator it(older_, newer_); 649e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (it.Init(); !it.Done(); it.Next()) { 650e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = it.Obj(); 651e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!filter->Matches(heap_obj)) { 652e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 653e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 654e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 655e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *size += heap_obj->Size(); 656e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (*count)++; 657e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 658e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 659e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 660e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool Write(Handle<FixedArray> elements_arr, 661e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 662e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 663e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 664e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) { 665e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The lols are listed in latest to earliest. We want to dump from 666e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // earliest to latest. So, compute the last element to start with. 667e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int index = 0; 668e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 669e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 67069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 67169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 67269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 673e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Prefetch some needed symbols. 67469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> id_sym = factory->LookupAsciiSymbol("id"); 67569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> desc_sym = factory->LookupAsciiSymbol("desc"); 67669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 677e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 678e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill the array with the lol object details. 679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> detail; 680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc; 681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> target; 682e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 683e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* first_lol = (older_ != NULL) ? 684e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch older_->next_ : LiveObjectList::first_; 685e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* last_lol = (newer_ != NULL) ? newer_->next_ : NULL; 686e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 687e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolForwardIterator it(first_lol, last_lol); 688e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) { 689e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = it.Obj(); 690e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 691e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip objects that have been filtered out. 692e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!filter->Matches(heap_obj)) { 693e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 694e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 695e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 696e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Only report objects that are in the section of interest. 697e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (count >= start) { 698e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch target = Handle<HeapObject>(heap_obj); 699e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool success = AddObjDetail(elements_arr, 700e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index++, 701e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch it.Id(), 702e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch target, 703e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NULL, 704e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_sym, 705e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_sym, 706e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size_sym, 707e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch detail, 708e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc, 709e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 710e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!success) return false; 711e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count++; 713e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 714e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 715e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 716e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 717e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 718e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* older_; 719e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* newer_; 720e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 721e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 722e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 723e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass RetainersDumpWriter: public DumpWriter { 724e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 725e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RetainersDumpWriter(Handle<HeapObject> target, 726e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter, 727e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSFunction> args_function) 728e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : target_(target), 729e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_filter_(instance_filter), 730e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch args_function_(args_function) { 731e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 732e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 733e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) { 734e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<FixedArray> retainers_arr; 735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error; 736e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 737e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *size = -1; 738e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList::GetRetainers(target_, 739e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_filter_, 740e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainers_arr, 741e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 0, 742e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::kMaxValue, 743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count, 744e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter, 745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NULL, 746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *args_function_, 747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 748e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 749e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 750e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool Write(Handle<FixedArray> elements_arr, 751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 752e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 753e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) { 755e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dummy; 756e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count; 757e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 758e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill the retainer objects. 759e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count = LiveObjectList::GetRetainers(target_, 760e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_filter_, 761e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements_arr, 762e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start, 763e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit, 764e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &dummy, 765e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter, 766e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NULL, 767e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *args_function_, 768e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 769e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (count < 0) { 770e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; 771e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 773e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 774e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 775e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 776e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> target_; 777e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter_; 778e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSFunction> args_function_; 779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 781e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 782e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LiveObjectSummary { 783e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 784e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch explicit LiveObjectSummary(LolFilter* filter) 785e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : total_count_(0), 786e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_size_(0), 787e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found_root_(false), 788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found_weak_root_(false), 789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter_(filter) { 790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch memset(counts_, 0, sizeof(counts_[0]) * kNumberOfEntries); 791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch memset(sizes_, 0, sizeof(sizes_[0]) * kNumberOfEntries); 792e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 793e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 794e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void Add(HeapObject* heap_obj) { 795e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = heap_obj->Size(); 796e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectType type = GetObjectType(heap_obj); 797e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(type != kInvalidLiveObjType); 798e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch counts_[type]++; 799e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sizes_[type] += size; 800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_count_++; 801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_size_ += size; 802e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 803e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 804e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_found_root() { found_root_ = true; } 805e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_found_weak_root() { found_weak_root_ = true; } 806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 807e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int Count(LiveObjectType type) { 808e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return counts_[type]; 809e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 810e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int Size(LiveObjectType type) { 811e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return sizes_[type]; 812e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 813e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int total_count() { 814e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return total_count_; 815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 816e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline int total_size() { 817e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return total_size_; 818e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 819e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool found_root() { 820e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return found_root_; 821e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 822e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool found_weak_root() { 823e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return found_weak_root_; 824e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 825e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int GetNumberOfEntries() { 826e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int entries = 0; 827e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < kNumberOfEntries; i++) { 828e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (counts_[i]) entries++; 829e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 830e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return entries; 831e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 832e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 833e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline LolFilter* filter() { return filter_; } 834e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 835e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static const int kNumberOfEntries = kNumberOfTypes; 836e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 837e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 838e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int counts_[kNumberOfEntries]; 839e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sizes_[kNumberOfEntries]; 840e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count_; 841e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_size_; 842e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool found_root_; 843e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool found_weak_root_; 844e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LolFilter* filter_; 846e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 847e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 848e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 849e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Abstraction for a summary writer. 850e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass SummaryWriter { 851e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 852e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual ~SummaryWriter() {} 853e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch virtual void Write(LiveObjectSummary* summary) = 0; 854e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 855e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 856e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 857e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// A summary writer for filling in a summary of lol lists and diffs. 858e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolSummaryWriter: public SummaryWriter { 859e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LolSummaryWriter(LiveObjectList* older_lol, 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* newer_lol) 862e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : older_(older_lol), newer_(newer_lol) { 863e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 864e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 865e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void Write(LiveObjectSummary* summary) { 866e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter = summary->filter(); 867e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 868e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill the summary with the lol object details. 869e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolIterator it(older_, newer_); 870e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (it.Init(); !it.Done(); it.Next()) { 871e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = it.Obj(); 872e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!filter->Matches(heap_obj)) { 873e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 874e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 875e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary->Add(heap_obj); 876e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 877e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 878e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 879e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 880e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* older_; 881e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* newer_; 882e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 883e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 884e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 885e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// A summary writer for filling in a retainers list. 886e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass RetainersSummaryWriter: public SummaryWriter { 887e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 888e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RetainersSummaryWriter(Handle<HeapObject> target, 889e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter, 890e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSFunction> args_function) 891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : target_(target), 892e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_filter_(instance_filter), 893e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch args_function_(args_function) { 894e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 896e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void Write(LiveObjectSummary* summary) { 897e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<FixedArray> retainers_arr; 898e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error; 899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dummy_total_count; 900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList::GetRetainers(target_, 901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch instance_filter_, 902e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainers_arr, 903e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 0, 904e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::kMaxValue, 905e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &dummy_total_count, 906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary->filter(), 907e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary, 908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *args_function_, 909e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 910e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 911e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 912e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 913e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> target_; 914e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter_; 915e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSFunction> args_function_; 916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 919e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochuint32_t LiveObjectList::next_element_id_ = 1; 920e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::list_count_ = 0; 921e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::last_id_ = 0; 922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectList* LiveObjectList::first_ = NULL; 923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectList* LiveObjectList::last_ = NULL; 924e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 925e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectList::LiveObjectList(LiveObjectList* prev, int capacity) 927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : prev_(prev), 928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch next_(NULL), 929e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch capacity_(capacity), 930e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj_count_(0) { 931e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements_ = NewArray<Element>(capacity); 932e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_ = ++last_id_; 933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch list_count_++; 935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 938e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectList::~LiveObjectList() { 939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DeleteArray<Element>(elements_); 940e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete prev_; 941e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 942e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 943e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 944e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::GetTotalObjCountAndSize(int* size_p) { 945e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = 0; 946e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* lol = this; 948e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch do { 949e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Only compute total size if requested i.e. when size_p is not null. 950e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (size_p != NULL) { 951e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = lol->elements_; 952e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < lol->obj_count_; i++) { 953e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = elements[i].obj_; 954e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size += heap_obj->Size(); 955e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count += lol->obj_count_; 958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } while (lol != NULL); 960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (size_p != NULL) { 962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *size_p = size; 963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return count; 965e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 966e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 967e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Adds an object to the lol. 969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Returns true if successful, else returns false. 970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochbool LiveObjectList::Add(HeapObject* obj) { 971e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the object is already accounted for in the prev list which we inherit 972e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // from, then no need to add it to this list. 973e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((prev() != NULL) && (prev()->Find(obj) != NULL)) { 974e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 975e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 976e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(obj_count_ <= capacity_); 977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj_count_ == capacity_) { 978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The heap must have grown and we have more objects than capacity to store 979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // them. 980e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return false; // Fail this addition. 981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 982e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element& element = elements_[obj_count_++]; 983e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch element.id_ = next_element_id_++; 984e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch element.obj_ = obj; 985e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 986e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 987e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 988e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 989e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Comparator used for sorting and searching the lol. 990e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::CompareElement(const Element* a, const Element* b) { 991e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const HeapObject* obj1 = a->obj_; 992e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const HeapObject* obj2 = b->obj_; 993e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // For lol elements, it doesn't matter which comes first if 2 elements point 994e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // to the same object (which gets culled later). Hence, we only care about 995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the the greater than / less than relationships. 996e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return (obj1 > obj2) ? 1 : (obj1 == obj2) ? 0 : -1; 997e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 998e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 999e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1000e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Looks for the specified object in the lol, and returns its element if found. 1001e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochLiveObjectList::Element* LiveObjectList::Find(HeapObject* obj) { 1002e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = this; 1003e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element key; 1004e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* result = NULL; 1005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1006e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch key.obj_ = obj; 1007e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate through the chain of lol's to look for the object. 1008e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((result == NULL) && (lol != NULL)) { 1009e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch result = reinterpret_cast<Element*>( 1010e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bsearch(&key, lol->elements_, lol->obj_count_, 1011e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sizeof(Element), 1012e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<RawComparer>(CompareElement))); 1013e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 1014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1015e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return result; 1016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1019e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// "Nullifies" (convert the HeapObject* into an SMI) so that it will get cleaned 1020e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// up in the GCEpilogue, while preserving the sort order of the lol. 1021e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// NOTE: the lols need to be already sorted before NullifyMostRecent() is 1022e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// called. 1023e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::NullifyMostRecent(HeapObject* obj) { 1024e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = last(); 1025e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element key; 1026e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* result = NULL; 1027e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1028e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch key.obj_ = obj; 1029e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate through the chain of lol's to look for the object. 1030e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 1031e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch result = reinterpret_cast<Element*>( 1032e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bsearch(&key, lol->elements_, lol->obj_count_, 1033e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch sizeof(Element), 1034e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<RawComparer>(CompareElement))); 1035e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (result != NULL) { 1036e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Since there may be more than one (we are nullifying dup's after all), 1037e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // find the first in the current lol, and nullify that. The lol should 1038e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // be sorted already to make this easy (see the use of SortAll()). 1039e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int i = result - lol->elements_; 1040e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1041e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // NOTE: we sort the lol in increasing order. So, if an object has been 1042e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // "nullified" (its lowest bit will be cleared to make it look like an 1043e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // SMI), it would/should show up before the equivalent dups that have not 1044e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // yet been "nullified". Hence, we should be searching backwards for the 1045e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // first occurence of a matching object and nullify that instance. This 1046e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // will ensure that we preserve the expected sorting order. 1047e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (i--; i > 0; i--) { 1048e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* element = &lol->elements_[i]; 1049e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* curr_obj = element->obj_; 1050e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (curr_obj != obj) { 1051e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; // No more matches. Let's move on. 1052e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1053e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch result = element; // Let this earlier match be the result. 1054e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1055e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1056e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Nullify the object. 1057e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NullifyNonLivePointer(&result->obj_); 1058e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return; 1059e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1060e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 1061e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1062e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1063e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1064e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1065e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Sorts the lol. 1066e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::Sort() { 1067e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj_count_ > 0) { 1068e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Vector<Element> elements_v(elements_, obj_count_); 1069e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch elements_v.Sort(CompareElement); 1070e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1071e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1072e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1073e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1074e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Sorts all captured lols starting from the latest. 1075e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::SortAll() { 1076e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = last(); 1077e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 1078e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->Sort(); 1079e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 1080e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1081e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1083e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1084e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Counts the number of objects in the heap. 1085e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic int CountHeapObjects() { 1086e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 1087e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate over all the heap spaces and count the number of objects. 10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 1089e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = NULL; 1090e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((heap_obj = iterator.next()) != NULL) { 1091e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count++; 1092e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1093e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return count; 1094e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1095e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1096e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1097e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Captures a current snapshot of all objects in the heap. 1098e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::Capture() { 109969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 110069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 110169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 1102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Count the number of objects in the heap. 1104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count = CountHeapObjects(); 1105e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = total_count; 1106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = 0; 1107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* last_lol = last(); 1109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (last_lol != NULL) { 1110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count -= last_lol->TotalObjCount(); 1111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1112e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1113e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol; 1114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1115e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Create a lol large enough to track all the objects. 1116e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = new LiveObjectList(last_lol, count); 1117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol == NULL) { 1118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return NULL; // No memory to proceed. 1119e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1121e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The HeapIterator needs to be in its own scope because it disables 1122e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // allocation, and we need allocate below. 1123e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { 1124e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate over all the heap spaces and add the objects. 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 1126e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = NULL; 1127e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool failed = false; 1128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (!failed && (heap_obj = iterator.next()) != NULL) { 1129e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch failed = !lol->Add(heap_obj); 1130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size += heap_obj->Size(); 1131e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(!failed); 1133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->Sort(); 1135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Add the current lol to the list of lols. 1137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (last_ != NULL) { 1138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_->next_ = lol; 1139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 1140e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch first_ = lol; 1141e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1142e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_ = lol; 1143e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef VERIFY_LOL 1145e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (FLAG_verify_lol) { 1146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Verify(true); 1147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif 1149e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1150e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> id_sym = factory->LookupAsciiSymbol("id"); 115269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> count_sym = factory->LookupAsciiSymbol("count"); 115369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 1154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 115569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> result = factory->NewJSObject(isolate->object_function()); 1156e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (result->IsFailure()) return Object::cast(*result); 1157e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = result->SetProperty(*id_sym, 1159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(lol->id()), 1160e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1163e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = result->SetProperty(*count_sym, 1165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(total_count), 1166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1168e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { MaybeObject* maybe_result = result->SetProperty(*size_sym, 1171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(size), 1172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *result; 1178e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1181e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Delete doesn't actually deletes an lol. It just marks it as invisible since 1182e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// its contents are considered to be part of subsequent lists as well. The 1183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// only time we'll actually delete the lol is when we Reset() or if the lol is 1184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// invisible, and its element count reaches 0. 1185e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochbool LiveObjectList::Delete(int id) { 11863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* lol = last(); 1187e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 1188e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol->id() == id) { 1189e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 1190e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1191e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 1192e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1194e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If no lol is found for this id, then we fail to delete. 1195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol == NULL) return false; 1196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1197e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Else, mark the lol as invisible i.e. id == 0. 1198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->id_ = 0; 1199e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch list_count_--; 1200e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(list_count_ >= 0); 1201e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol->obj_count_ == 0) { 1202e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Point the next lol's prev to this lol's prev. 1203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* next = lol->next_; 1204e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* prev = lol->prev_; 1205e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Point next's prev to prev. 1206e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (next != NULL) { 1207e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch next->prev_ = lol->prev_; 1208e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 1209e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_ = lol->prev_; 1210e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1211e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Point prev's next to next. 1212e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (prev != NULL) { 1213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prev->next_ = lol->next_; 1214e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 1215e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch first_ = lol->next_; 1216e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1217e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1218e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->prev_ = NULL; 1219e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->next_ = NULL; 1220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Delete this now empty and invisible lol. 1222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete lol; 1223e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1224e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1225e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Just in case we've marked everything invisible, then clean up completely. 1226e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (list_count_ == 0) { 1227e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Reset(); 1228e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 1231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1232e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1233e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1234e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::Dump(int older_id, 1235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int newer_id, 1236e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start_idx, 1237e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 1238e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> filter_obj) { 1239e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { 1240e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: 0 is not a valid lol id. 1241e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1242e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (newer_id < older_id) { 1243e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // They are not in the expected order. Swap them. 1244e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int temp = older_id; 1245e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch older_id = newer_id; 1246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch newer_id = temp; 1247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 12493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* newer_lol = FindLolForId(newer_id, last()); 12503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* older_lol = FindLolForId(older_id, newer_lol); 1251e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1252e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the id is defined, and we can't find a LOL for it, then we have an 1253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // invalid id. 1254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((newer_id != 0) && (newer_lol == NULL)) { 1255e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: the newer lol id is invalid. 1256e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1257e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((older_id != 0) && (older_lol == NULL)) { 1258e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: the older lol id is invalid. 1259e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1261e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter filter(filter_obj); 1262e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolDumpWriter writer(older_lol, newer_lol); 1263e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return DumpPrivate(&writer, start_idx, dump_limit, &filter); 1264e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1265e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1266e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1267e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::DumpPrivate(DumpWriter* writer, 1268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 1269e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 1270e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter) { 127169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 127369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 127469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 1275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Calculate the number of entries of the dump. 1277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = -1; 1278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = -1; 1279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch writer->ComputeTotalCountAndSize(filter, &count, &size); 1280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Adjust for where to start the dump. 1282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((start < 0) || (start >= count)) { 1283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // invalid start. 1284e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1286e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int remaining_count = count - start; 1287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (dump_limit > remaining_count) { 1288e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit = remaining_count; 1289e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1290e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1291e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate an array to hold the result. 129269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<FixedArray> elements_arr = factory->NewFixedArray(dump_limit); 1293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (elements_arr->IsFailure()) return Object::cast(*elements_arr); 1294e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1295e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill in the dump. 1296e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error; 1297e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool success = writer->Write(elements_arr, 1298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start, 1299e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit, 1300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter, 1301e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 1302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!success) return Object::cast(*error); 1303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1304e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result; 1305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1306e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate the result body. 130769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> body = factory->NewJSObject(isolate->object_function()); 1308e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (body->IsFailure()) return Object::cast(*body); 1309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1310e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set the updated body.count. 131169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> count_sym = factory->LookupAsciiSymbol("count"); 1312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*count_sym, 1313e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(count), 1314e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1315e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set the updated body.size if appropriate. 1319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (size >= 0) { 132069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 1321e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*size_sym, 1322e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(size), 1323e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1324e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1325e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1327e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set body.first_index. 132969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> first_sym = factory->LookupAsciiSymbol("first_index"); 1330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*first_sym, 1331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(start), 1332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1333e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate the JSArray of the elements. 133769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> elements = factory->NewJSObject(isolate->array_function()); 1338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (elements->IsFailure()) return Object::cast(*elements); 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch maybe_result = Handle<JSArray>::cast(elements)->SetContent(*elements_arr); 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set body.elements. 134469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> elements_sym = factory->LookupAsciiSymbol("elements"); 1345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*elements_sym, 1346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *elements, 1347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1350e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1351e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *body; 1352e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1353e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::Summarize(int older_id, 1356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int newer_id, 1357e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> filter_obj) { 1358e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) { 1359e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: 0 is not a valid lol id. 1360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (newer_id < older_id) { 1362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // They are not in the expected order. Swap them. 1363e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int temp = older_id; 1364e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch older_id = newer_id; 1365e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch newer_id = temp; 1366e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1367e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* newer_lol = FindLolForId(newer_id, last()); 13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* older_lol = FindLolForId(older_id, newer_lol); 1370e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1371e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the id is defined, and we can't find a LOL for it, then we have an 1372e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // invalid id. 1373e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((newer_id != 0) && (newer_lol == NULL)) { 1374e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: the newer lol id is invalid. 1375e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1376e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((older_id != 0) && (older_lol == NULL)) { 1377e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // Fail: the older lol id is invalid. 1378e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1379e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1380e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter filter(filter_obj); 1381e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolSummaryWriter writer(older_lol, newer_lol); 1382e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return SummarizePrivate(&writer, &filter, false); 1383e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1384e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Creates a summary report for the debugger. 1387e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Note: the SummaryWriter takes care of iterating over objects and filling in 1388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// the summary. 1389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::SummarizePrivate(SummaryWriter* writer, 1390e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 1391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool is_tracking_roots) { 1392e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HandleScope scope; 1393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result; 1394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1395e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectSummary summary(filter); 1396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch writer->Write(&summary); 1397e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 139869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 139969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 140069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The result body will look like this: 1402e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // body: { 1403e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // count: <total_count>, 1404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // size: <total_size>, 1405e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // found_root: <boolean>, // optional. 1406e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // found_weak_root: <boolean>, // optional. 1407e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // summary: [ 1408e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // { 1409e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // desc: "<object type name>", 1410e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // count: <count>, 1411e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // size: size 1412e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // }, 1413e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // ... 1414e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // ] 1415e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // } 1416e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1417e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Prefetch some needed symbols. 141869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> desc_sym = factory->LookupAsciiSymbol("desc"); 141969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> count_sym = factory->LookupAsciiSymbol("count"); 142069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 142169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> summary_sym = factory->LookupAsciiSymbol("summary"); 1422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate the summary array. 1424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int entries_count = summary.GetNumberOfEntries(); 1425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<FixedArray> summary_arr = 142669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->NewFixedArray(entries_count); 1427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (summary_arr->IsFailure()) return Object::cast(*summary_arr); 1428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int idx = 0; 1430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < LiveObjectSummary::kNumberOfEntries; i++) { 1431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate the summary record. 143269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> detail = factory->NewJSObject(isolate->object_function()); 1433e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (detail->IsFailure()) return Object::cast(*detail); 1434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1435e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill in the summary record. 1436e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectType type = static_cast<LiveObjectType>(i); 1437e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = summary.Count(type); 1438e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (count) { 1439e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* desc_cstr = GetObjectTypeDesc(type); 144069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> desc = factory->LookupAsciiSymbol(desc_cstr); 1441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size = summary.Size(type); 1442e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1443e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*desc_sym, 1444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *desc, 1445e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1447e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1448e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*count_sym, 1449e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(count), 1450e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1451e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1452e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1453e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*size_sym, 1454e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(size), 1455e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1456e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1457e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary_arr->set(idx++, *detail); 1460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1463e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Wrap the summary fixed array in a JS array. 146469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> summary_obj = 146569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->NewJSObject(isolate->array_function()); 1466e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (summary_obj->IsFailure()) return Object::cast(*summary_obj); 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch maybe_result = Handle<JSArray>::cast(summary_obj)->SetContent(*summary_arr); 14693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1470e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1471e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Create the body object. 147269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> body = factory->NewJSObject(isolate->object_function()); 1473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (body->IsFailure()) return Object::cast(*body); 1474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill out the body object. 1476e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count = summary.total_count(); 1477e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_size = summary.total_size(); 1478e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*count_sym, 1479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(total_count), 1480e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1481e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1482e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*size_sym, 1485e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(total_size), 1486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1487e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1488e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1489e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1490e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (is_tracking_roots) { 1491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int found_root = summary.found_root(); 1492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int found_weak_root = summary.found_weak_root(); 149369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> root_sym = factory->LookupAsciiSymbol("found_root"); 1494e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> weak_root_sym = 149569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->LookupAsciiSymbol("found_weak_root"); 1496e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*root_sym, 1497e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(found_root), 1498e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1499e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1500e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1501e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*weak_root_sym, 1502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(found_weak_root), 1503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1505e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1506e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1507e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1508e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*summary_sym, 1509e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *summary_obj, 1510e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1512e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *body; 1515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1516e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1517e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Returns an array listing the captured lols. 1519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Note: only dumps the section starting at start_idx and only up to 1520e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// dump_limit entries. 1521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::Info(int start_idx, int dump_limit) { 152269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 152369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 152469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 152569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 1526e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result; 1527e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1528e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count = LiveObjectList::list_count(); 1529e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_count = total_count; 1530e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1531e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Adjust for where to start the dump. 1532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (total_count == 0) { 1533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start_idx = 0; // Ensure this to get an empty list. 1534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if ((start_idx < 0) || (start_idx >= total_count)) { 1535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Failure::Exception(); // invalid start. 1536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_count -= start_idx; 1538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1539e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Adjust for the dump limit. 1540e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (dump_count > dump_limit) { 1541e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_count = dump_limit; 1542e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1544e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate an array to hold the result. 154569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<FixedArray> list = factory->NewFixedArray(dump_count); 1546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (list->IsFailure()) return Object::cast(*list); 1547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Prefetch some needed symbols. 154969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> id_sym = factory->LookupAsciiSymbol("id"); 155069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> count_sym = factory->LookupAsciiSymbol("count"); 155169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 1552e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Fill the array with the lol details. 1554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int idx = 0; 1555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = first_; 1556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((lol != NULL) && (idx < start_idx)) { // Skip tail entries. 1557e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol->id() != 0) { 1558e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch idx++; 1559e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1560e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->next(); 1561e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1562e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch idx = 0; 1563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((lol != NULL) && (dump_limit != 0)) { 1564e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol->id() != 0) { 1565e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count; 1566e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int size; 1567e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count = lol->GetTotalObjCountAndSize(&size); 1568e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 156969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> detail = 157069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->NewJSObject(isolate->object_function()); 1571e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (detail->IsFailure()) return Object::cast(*detail); 1572e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*id_sym, 1574e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(lol->id()), 1575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1576e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1577e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1578e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*count_sym, 1579e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(count), 1580e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1581e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1582e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1583e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = detail->SetProperty(*size_sym, 1584e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(size), 1585e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1586e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1587e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch list->set(idx++, *detail); 1589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit--; 1590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->next(); 1592e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1593e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Return the result as a JS array. 159569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> lols = factory->NewJSObject(isolate->array_function()); 15963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch maybe_result = Handle<JSArray>::cast(lols)->SetContent(*list); 15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1599e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 160069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> result = factory->NewJSObject(isolate->object_function()); 1601e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (result->IsFailure()) return Object::cast(*result); 1602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = result->SetProperty(*count_sym, 1604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(total_count), 1605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1608e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 160969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> first_sym = factory->LookupAsciiSymbol("first_index"); 1610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = result->SetProperty(*first_sym, 1611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(start_idx), 1612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1613e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 161669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> lists_sym = factory->LookupAsciiSymbol("lists"); 1617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = result->SetProperty(*lists_sym, 1618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *lols, 1619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1620e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1622e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1623e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *result; 1624e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1626e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1627e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Deletes all captured lols. 1628e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::Reset() { 16293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* lol = last(); 1630e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Just delete the last. Each lol will delete it's prev automatically. 1631e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete lol; 1632e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1633e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch next_element_id_ = 1; 1634e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch list_count_ = 0; 1635e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_id_ = 0; 1636e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch first_ = NULL; 1637e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_ = NULL; 1638e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1639e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1640e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1641e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Gets the object for the specified obj id. 1642e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochObject* LiveObjectList::GetObj(int obj_id) { 1643e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* element = FindElementFor<int>(GetElementId, obj_id); 1644e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (element != NULL) { 1645e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Object::cast(element->obj_); 1646e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 164769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return HEAP->undefined_value(); 1648e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1649e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1650e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1651e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Gets the obj id for the specified address if valid. 1652e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::GetObjId(Object* obj) { 1653e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Make a heap object pointer from the address. 1654e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* hobj = HeapObject::cast(obj); 1655e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* element = FindElementFor<HeapObject*>(GetElementObj, hobj); 1656e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (element != NULL) { 1657e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return element->id_; 1658e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1659e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return 0; // Invalid address. 1660e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1661e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1662e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1663e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Gets the obj id for the specified address if valid. 1664e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochObject* LiveObjectList::GetObjId(Handle<String> address) { 1665589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch SmartArrayPointer<char> addr_str = 1666e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); 1667e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 166869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 166969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1670e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Extract the address value from the string. 167169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int value = 167269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static_cast<int>(StringToInt(isolate->unicode_cache(), *address, 16)); 1673e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* obj = reinterpret_cast<Object*>(value); 1674e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Smi::FromInt(GetObjId(obj)); 1675e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1676e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1677e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1678e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Helper class for copying HeapObjects. 1679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolVisitor: public ObjectVisitor { 1680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 1681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolVisitor(HeapObject* target, Handle<HeapObject> handle_to_skip) 1682e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : target_(target), handle_to_skip_(handle_to_skip), found_(false) {} 1683e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1684e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void VisitPointer(Object** p) { CheckPointer(p); } 1685e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1686e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void VisitPointers(Object** start, Object** end) { 1687e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check all HeapObject pointers in [start, end). 1688e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (Object** p = start; !found() && p < end; p++) CheckPointer(p); 1689e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1690e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1691e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool found() const { return found_; } 1692e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline bool reset() { return found_ = false; } 1693e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1694e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 1695e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch inline void CheckPointer(Object** p) { 1696e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* object = *p; 1697e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (HeapObject::cast(object) == target_) { 1698e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We may want to skip this handle because the handle may be a local 1699e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // handle in a handle scope in one of our callers. Once we return, 1700e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // that handle will be popped. Hence, we don't want to count it as 1701e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // a root that would have kept the target object alive. 1702e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!handle_to_skip_.is_null() && 1703e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch handle_to_skip_.location() == reinterpret_cast<HeapObject**>(p)) { 1704e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return; // Skip this handle. 1705e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1706e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found_ = true; 1707e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1708e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1709e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1710e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* target_; 1711e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> handle_to_skip_; 1712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool found_; 1713e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 1714e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1715e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1716e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochinline bool AddRootRetainerIfFound(const LolVisitor& visitor, 1717e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 17183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectSummary* summary, 17193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void (*SetRootFound)(LiveObjectSummary* s), 1720e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 1721e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 1722e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* total_count, 1723e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<FixedArray> retainers_arr, 1724e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* count, 1725e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* index, 1726e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* root_name, 1727e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> id_sym, 1728e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc_sym, 1729e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> size_sym, 1730e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) { 1731e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HandleScope scope; 1732e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1733e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Scratch handles. 1734e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> detail; 1735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc; 1736e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> retainer; 1737e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1738e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (visitor.found()) { 1739e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!filter->is_active()) { 1740e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (*total_count)++; 1741e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (summary) { 1742e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetRootFound(summary); 1743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if ((*total_count > start) && ((*index) < dump_limit)) { 1744e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (*count)++; 1745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!retainers_arr.is_null()) { 1746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return AddObjDetail(retainers_arr, 1747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (*index)++, 1748e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 0, 1749e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainer, 1750e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch root_name, 1751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_sym, 1752e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_sym, 1753e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size_sym, 1754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch detail, 1755e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc, 1756e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 1757e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1758e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1759e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1760e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1761e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return true; 1762e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1763e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1764e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 17653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline void SetFoundRoot(LiveObjectSummary* summary) { 1766e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary->set_found_root(); 1767e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1768e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1769e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 17703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline void SetFoundWeakRoot(LiveObjectSummary* summary) { 1771e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary->set_found_weak_root(); 1772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1773e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1774e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1775e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint LiveObjectList::GetRetainers(Handle<HeapObject> target, 1776e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter, 1777e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<FixedArray> retainers_arr, 1778e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 1779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 1780e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int* total_count, 1781e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter* filter, 17823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectSummary* summary, 1783e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSFunction* arguments_function, 1784e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Object> error) { 1785e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HandleScope scope; 1786e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1787e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Scratch handles. 1788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> detail; 1789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> desc; 1790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> retainer; 1791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 179269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 179369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 179469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1795e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Prefetch some needed symbols. 179669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> id_sym = factory->LookupAsciiSymbol("id"); 179769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> desc_sym = factory->LookupAsciiSymbol("desc"); 179869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> size_sym = factory->LookupAsciiSymbol("size"); 1799e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1800e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NoHandleAllocation ha; 1801e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 1802e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int index = 0; 1803e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> last_obj; 1804e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1805e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *total_count = 0; 1806e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1807e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate roots. 1808e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolVisitor lol_visitor(*target, target); 180969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->heap()->IterateStrongRoots(&lol_visitor, VISIT_ALL); 1810e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!AddRootRetainerIfFound(lol_visitor, 1811e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter, 1812e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary, 1813e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetFoundRoot, 1814e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start, 1815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit, 1816e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_count, 1817e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainers_arr, 1818e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &count, 1819e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &index, 1820e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "<root>", 1821e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_sym, 1822e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_sym, 1823e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size_sym, 1824e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error)) { 1825e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return -1; 1826e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1827e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1828e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol_visitor.reset(); 182969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->heap()->IterateWeakRoots(&lol_visitor, VISIT_ALL); 1830e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!AddRootRetainerIfFound(lol_visitor, 1831e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch filter, 1832e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary, 1833e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SetFoundWeakRoot, 1834e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch start, 1835e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch dump_limit, 1836e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_count, 1837e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainers_arr, 1838e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &count, 1839e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &index, 1840e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "<weak root>", 1841e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_sym, 1842e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_sym, 1843e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size_sym, 1844e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error)) { 1845e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return -1; 1846e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1847e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1848e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate the live object lists. 1849e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolIterator it(NULL, last()); 1850e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) { 1851e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = it.Obj(); 1852e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1853e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Only look at all JSObjects. 1854e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (heap_obj->IsJSObject()) { 1855e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip context extension objects and argument arrays as these are 1856e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // checked in the context of functions using them. 1857e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSObject* obj = JSObject::cast(heap_obj); 1858e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->IsJSContextExtensionObject() || 1859e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->map()->constructor() == arguments_function) { 1860e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 1861e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1862e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1863e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check if the JS object has a reference to the object looked for. 1864e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->ReferencesObject(*target)) { 1865e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check instance filter if supplied. This is normally used to avoid 1866e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // references from mirror objects (see Runtime_IsInPrototypeChain). 1867e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!instance_filter->IsUndefined()) { 1868e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* V = obj; 1869e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (true) { 1870e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* prototype = V->GetPrototype(); 1871e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (prototype->IsNull()) { 1872e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 1873e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1874e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (*instance_filter == prototype) { 1875e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj = NULL; // Don't add this object. 1876e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 1877e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1878e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch V = prototype; 1879e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1880e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1881e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1882e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj != NULL) { 1883e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip objects that have been filtered out. 1884e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (filter->Matches(heap_obj)) { 1885e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 1886e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1887e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1888e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Valid reference found add to instance array if supplied an update 1889e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // count. 1890e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_obj = Handle<JSObject>(obj); 1891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (*total_count)++; 1892e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1893e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (summary != NULL) { 1894e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch summary->Add(heap_obj); 1895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if ((*total_count > start) && (index < dump_limit)) { 1896e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count++; 1897e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!retainers_arr.is_null()) { 1898e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainer = Handle<HeapObject>(heap_obj); 1899e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool success = AddObjDetail(retainers_arr, 1900e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch index++, 1901e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch it.Id(), 1902e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch retainer, 1903e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NULL, 1904e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch id_sym, 1905e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc_sym, 1906e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch size_sym, 1907e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch detail, 1908e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch desc, 1909e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch error); 1910e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!success) return -1; 1911e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1912e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1913e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1914e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1915e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check for circular reference only. This can happen when the object is only 1919e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // referenced from mirrors and has a circular reference in which case the 1920e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // object is not really alive and would have been garbage collected if not 1921e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // referenced from the mirror. 1922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1923e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (*total_count == 1 && !last_obj.is_null() && *last_obj == *target) { 1924e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count = 0; 1925e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *total_count = 0; 1926e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1927e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1928e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return count; 1929e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1930e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1931e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1932e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochMaybeObject* LiveObjectList::GetObjRetainers(int obj_id, 1933e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter, 1934e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool verbose, 1935e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int start, 1936e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int dump_limit, 1937e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> filter_obj) { 193869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 193969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 194069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = isolate->heap(); 194169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 194269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 1943e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1944e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Get the target object. 1945e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = HeapObject::cast(GetObj(obj_id)); 194669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (heap_obj == heap->undefined_value()) { 1947e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return heap_obj; 1948e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1949e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1950e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<HeapObject> target = Handle<HeapObject>(heap_obj); 1951e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1952e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Get the constructor function for context extension and arguments array. 1953e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSObject* arguments_boilerplate = 195469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->context()->global_context()->arguments_boilerplate(); 1955e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSFunction* arguments_function = 1956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSFunction::cast(arguments_boilerplate->map()->constructor()); 1957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSFunction> args_function = Handle<JSFunction>(arguments_function); 1959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolFilter filter(filter_obj); 1960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!verbose) { 1962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RetainersSummaryWriter writer(target, instance_filter, args_function); 1963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return SummarizePrivate(&writer, &filter, true); 1964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1965e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 1966e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RetainersDumpWriter writer(target, instance_filter, args_function); 1967e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* body_obj; 1968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* maybe_result = 1969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DumpPrivate(&writer, start, dump_limit, &filter); 1970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!maybe_result->ToObject(&body_obj)) { 1971e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return maybe_result; 1972e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1973e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1974e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set body.id. 1975e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> body = Handle<JSObject>(JSObject::cast(body_obj)); 197669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> id_sym = factory->LookupAsciiSymbol("id"); 1977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch maybe_result = body->SetProperty(*id_sym, 1978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(obj_id), 1979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 1980e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode); 1981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (maybe_result->IsFailure()) return maybe_result; 1982e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1983e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *body; 1984e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1985e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 1986e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1987e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1988e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochObject* LiveObjectList::PrintObj(int obj_id) { 1989e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* obj = GetObj(obj_id); 1990e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!obj) { 199169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return HEAP->undefined_value(); 1992e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1993e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1994e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch EmbeddedVector<char, 128> temp_filename; 1995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static int temp_count = 0; 1996e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* path_prefix = "."; 1997e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 199869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 199969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 200069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = isolate->heap(); 200169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2002e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (FLAG_lol_workdir) { 2003e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch path_prefix = FLAG_lol_workdir; 2004e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(temp_filename, "%s/lol-print-%d", path_prefix, ++temp_count); 2006e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2007e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FILE* f = OS::FOpen(temp_filename.start(), "w+"); 2008e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2009e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "@%d ", LiveObjectList::GetObjId(obj)); 2010e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef OBJECT_PRINT 2011e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef INSPECTOR 2012e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Inspector::DumpObjectType(f, obj); 2013e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif // INSPECTOR 2014e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "\n"); 2015e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->Print(f); 2016e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#else // !OBJECT_PRINT 2017e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->ShortPrint(f); 2018e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif // !OBJECT_PRINT 2019e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "\n"); 2020e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Flush(f); 2021e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fclose(f); 2022e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2023e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Create a string from the temp_file. 2024e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: the mmapped resource will take care of closing the file. 2025e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MemoryMappedExternalResource* resource = 2026e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch new MemoryMappedExternalResource(temp_filename.start(), true); 2027e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (resource->exists() && !resource->is_empty()) { 2028e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(resource->IsAscii()); 2029e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> dump_string = 203069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->NewExternalStringFromAscii(resource); 203169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch heap->external_string_table()->AddString(*dump_string); 2032e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *dump_string; 2033e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2034e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete resource; 2035e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 203669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return HEAP->undefined_value(); 2037e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2038e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2039e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2040e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochclass LolPathTracer: public PathTracer { 2041e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch public: 2042e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolPathTracer(FILE* out, 2043e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* search_target, 2044e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch WhatToFind what_to_find) 2045e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch : PathTracer(search_target, what_to_find, VISIT_ONLY_STRONG), out_(out) {} 2046e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2047e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch private: 2048e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ProcessResults(); 2049e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2050e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FILE* out_; 2051e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}; 2052e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2053e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2054e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LolPathTracer::ProcessResults() { 2055e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (found_target_) { 2056e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "=====================================\n"); 2057e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "==== Path to object ====\n"); 2058e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "=====================================\n\n"); 2059e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2060e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(!object_stack_.is_empty()); 2061e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* prev = NULL; 2062e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0, index = 0; i < object_stack_.length(); i++) { 2063e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Object* obj = object_stack_[i]; 2064e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2065e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip this object if it is basically the internals of the 2066e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // previous object (which would have dumped its details already). 2067e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (prev && prev->IsJSObject() && 2068e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (obj != search_target_)) { 2069e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch JSObject* jsobj = JSObject::cast(prev); 2070e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj->IsFixedArray() && 2071e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch jsobj->properties() == FixedArray::cast(obj)) { 2072e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip this one because it would have been printed as the 2073e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // properties of the last object already. 2074e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 2075e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (obj->IsHeapObject() && 2076e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch jsobj->elements() == HeapObject::cast(obj)) { 2077e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Skip this one because it would have been printed as the 2078e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // elements of the last object already. 2079e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 2080e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2081e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2083e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Print a connecting arrow. 2084e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (i > 0) PrintF(out_, "\n |\n |\n V\n\n"); 2085e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2086e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Print the object index. 2087e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "[%d] ", ++index); 2088e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2089e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Print the LOL object ID: 2090e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int id = LiveObjectList::GetObjId(obj); 2091e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (id > 0) PrintF(out_, "@%d ", id); 2092e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2093e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef OBJECT_PRINT 2094e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef INSPECTOR 2095e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Inspector::DumpObjectType(out_, obj); 2096e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif // INSPECTOR 2097e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "\n"); 2098e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->Print(out_); 2099e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#else // !OBJECT_PRINT 2100e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->ShortPrint(out_); 2101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "\n"); 2102e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif // !OBJECT_PRINT 2103e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Flush(out_); 2104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2105e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "\n"); 2106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(out_, "=====================================\n\n"); 2107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Flush(out_); 2108e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2112e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochObject* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) { 2113e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch EmbeddedVector<char, 128> temp_filename; 2114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static int temp_count = 0; 2115e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const char* path_prefix = "."; 2116e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (FLAG_lol_workdir) { 2118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch path_prefix = FLAG_lol_workdir; 2119e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::SNPrintF(temp_filename, "%s/lol-getpath-%d", path_prefix, ++temp_count); 2121e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2122e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FILE* f = OS::FOpen(temp_filename.start(), "w+"); 2123e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 212469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = Isolate::Current(); 212569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Factory* factory = isolate->factory(); 212669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = isolate->heap(); 212769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2128e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Save the previous verbosity. 2129e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool prev_verbosity = FLAG_use_verbose_printer; 2130e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FLAG_use_verbose_printer = false; 2131e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Dump the paths. 2133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { 2134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The tracer needs to be scoped because its usage asserts no allocation, 2135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // and we need to allocate the result string below. 2136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolPathTracer tracer(f, obj2, LolPathTracer::FIND_FIRST); 2137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool found = false; 2139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj1 == NULL) { 2140e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check for ObjectGroups that references this object. 2141e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // TODO(mlam): refactor this to be more modular. 2142e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch { 214369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch List<ObjectGroup*>* groups = isolate->global_handles()->object_groups(); 2144e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < groups->length(); i++) { 2145e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ObjectGroup* group = groups->at(i); 2146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (group == NULL) continue; 2147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2148e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool found_group = false; 214969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (size_t j = 0; j < group->length_; j++) { 215069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* object = *(group->objects_[j]); 2151e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* hobj = HeapObject::cast(object); 2152e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj2 == hobj) { 2153e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found_group = true; 2154e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch break; 2155e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2156e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2157e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (found_group) { 2159e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, 2160e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "obj %p is a member of object group %p {\n", 2161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj2), 2162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(group)); 216369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (size_t j = 0; j < group->length_; j++) { 216469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* object = *(group->objects_[j]); 2165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!object->IsHeapObject()) continue; 2166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* hobj = HeapObject::cast(object); 2168e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int id = GetObjId(hobj); 2169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (id != 0) { 2170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " @%d:", id); 2171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " <no id>:"); 2173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch char buffer[512]; 2176e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch GenerateObjectDesc(hobj, buffer, sizeof(buffer)); 2177e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " %s", buffer); 2178e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (hobj == obj2) { 2179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " <==="); 2180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2181e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "\n"); 2182e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "}\n"); 2184e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2185e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2186e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2187e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2188e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "path from roots to obj %p\n", reinterpret_cast<void*>(obj2)); 218969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch heap->IterateRoots(&tracer, VISIT_ONLY_STRONG); 2190e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found = tracer.found(); 2191e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2192e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!found) { 2193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " No paths found. Checking symbol tables ...\n"); 219469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SymbolTable* symbol_table = HEAP->raw_unchecked_symbol_table(); 2195e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch tracer.VisitPointers(reinterpret_cast<Object**>(&symbol_table), 2196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<Object**>(&symbol_table)+1); 2197e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found = tracer.found(); 2198e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!found) { 2199e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch symbol_table->IteratePrefix(&tracer); 2200e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found = tracer.found(); 2201e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2202e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2203e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2204e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!found) { 2205e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " No paths found. Checking weak roots ...\n"); 2206e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check weak refs next. 220769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->global_handles()->IterateWeakRoots(&tracer); 2208e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found = tracer.found(); 2209e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2210e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2211e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2212e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, "path from obj %p to obj %p:\n", 2213e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<void*>(obj1), reinterpret_cast<void*>(obj2)); 2214e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch tracer.TracePathFrom(reinterpret_cast<Object**>(&obj1)); 2215e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found = tracer.found(); 2216e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2217e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2218e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!found) { 2219e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PrintF(f, " No paths found\n\n"); 2220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2223e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Flush and clean up the dumped file. 2224e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Flush(f); 2225e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fclose(f); 2226e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2227e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Restore the previous verbosity. 2228e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch FLAG_use_verbose_printer = prev_verbosity; 2229e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Create a string from the temp_file. 2231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: the mmapped resource will take care of closing the file. 2232e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MemoryMappedExternalResource* resource = 2233e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch new MemoryMappedExternalResource(temp_filename.start(), true); 2234e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (resource->exists() && !resource->is_empty()) { 2235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(resource->IsAscii()); 2236e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<String> path_string = 223769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch factory->NewExternalStringFromAscii(resource); 223869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch heap->external_string_table()->AddString(*path_string); 2239e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return *path_string; 2240e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2241e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete resource; 2242e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 224369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->undefined_value(); 2244e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2245e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochObject* LiveObjectList::GetPath(int obj_id1, 2248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int obj_id2, 2249e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<JSObject> instance_filter) { 2250e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HandleScope scope; 2251e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2252e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Get the target object. 2253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* obj1 = NULL; 2254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (obj_id1 != 0) { 2255e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj1 = HeapObject::cast(GetObj(obj_id1)); 225669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (obj1 == HEAP->undefined_value()) { 2257e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return obj1; 2258e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2259e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2261e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* obj2 = HeapObject::cast(GetObj(obj_id2)); 226269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (obj2 == HEAP->undefined_value()) { 2263e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return obj2; 2264e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2265e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2266e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return GetPathPrivate(obj1, obj2); 2267e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2269e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 22703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LiveObjectList::DoProcessNonLive(HeapObject* obj) { 2271e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We should only be called if we have at least one lol to search. 2272e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(last() != NULL); 2273e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* element = last()->Find(obj); 2274e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (element != NULL) { 2275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NullifyNonLivePointer(&element->obj_); 2276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) { 2281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = last(); 2282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 2283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = lol->elements_; 2284e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = lol->obj_count_; 2285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < count; i++) { 2286e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject** p = &elements[i].obj_; 22873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v->VisitPointer(reinterpret_cast<Object** >(p)); 2288e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2289e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 2290e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2291e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2292e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2294e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Purpose: Called by GCEpilogue to purge duplicates. Not to be called by 2295e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// anyone else. 2296e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::PurgeDuplicates() { 2297e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool is_sorted = false; 2298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = last(); 2299e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!lol) { 2300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return; // Nothing to purge. 2301e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2303e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count = lol->TotalObjCount(); 2304e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!total_count) { 2305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return; // Nothing to purge. 2306e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2307e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2308e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = NewArray<Element>(total_count); 2309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 2310e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Copy all the object elements into a consecutive array. 2312e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol) { 2313e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element)); 2314e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count += lol->obj_count_; 2315e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 2316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch qsort(elements, total_count, sizeof(Element), 2318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<RawComparer>(CompareElement)); 2319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2320e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(count == total_count); 2321e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2322e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate over all objects in the consolidated list and check for dups. 2323e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch total_count--; 2324e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < total_count; ) { 2325e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* curr = &elements[i]; 2326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* curr_obj = curr->obj_; 2327e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int j = i+1; 2328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bool done = false; 2329e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (!done && (j < total_count)) { 2331e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Process if the element's object is still live after the current GC. 2332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Non-live objects will be converted to SMIs i.e. not HeapObjects. 2333e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (curr_obj->IsHeapObject()) { 2334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* next = &elements[j]; 2335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* next_obj = next->obj_; 2336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (next_obj->IsHeapObject()) { 2337e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (curr_obj != next_obj) { 2338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch done = true; 2339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; // Live object but no match. Move on. 2340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2342e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // NOTE: we've just GCed the LOLs. Hence, they are no longer sorted. 2343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Since we detected at least one need to search for entries, we'll 2344e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // sort it to enable the use of NullifyMostRecent() below. We only 2345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // need to sort it once (except for one exception ... see below). 2346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!is_sorted) { 2347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SortAll(); 2348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch is_sorted = true; 2349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2350e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2351e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We have a match. Need to nullify the most recent ref to this 2352e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // object. We'll keep the oldest ref: 2353e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: we will nullify the element record in the LOL 2354e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // database, not in the local sorted copy of the elements. 2355e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NullifyMostRecent(curr_obj); 2356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2357e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2358e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Either the object was already marked for purging, or we just marked 2359e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // it. Either way, if there's more than one dup, then we need to check 2360e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the next element for another possible dup against the current as well 2361e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // before we move on. So, here we go. 2362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch j++; 2363e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2364e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2365e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We can move on to checking the match on the next element. 2366e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch i = j; 2367e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2368e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DeleteArray<Element>(elements); 2370e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2371e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2372e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2373e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Purpose: Purges dead objects and resorts the LOLs. 2374e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::GCEpiloguePrivate() { 2375e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: During the GC, ConsStrings may be collected and pointers may be 2376e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // forwarded to its constituent string. As a result, we may find dupes of 2377e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // objects references in the LOL list. 2378e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Another common way we get dups is that free chunks that have been swept 2379e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // in the oldGen heap may be kept as ByteArray objects in a free list. 2380e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // 2381e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // When we promote live objects from the youngGen, the object may be moved 2382e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // to the start of these free chunks. Since there is no free or move event 2383e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // for the free chunks, their addresses will show up 2 times: once for their 2384e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // original free ByteArray selves, and once for the newly promoted youngGen 2385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // object. Hence, we can get a duplicate address in the LOL again. 2386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // 2387e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We need to eliminate these dups because the LOL implementation expects to 2388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // only have at most one unique LOL reference to any object at any time. 2389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch PurgeDuplicates(); 2390e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // After the GC, sweep away all free'd Elements and compact. 23923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* prev = NULL; 23933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LiveObjectList* next = NULL; 2394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2395e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterating from the youngest lol to the oldest lol. 23963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (LiveObjectList* lol = last(); lol; lol = prev) { 2397e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = lol->elements_; 2398e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch prev = lol->prev(); // Save the prev. 2399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Remove any references to collected objects. 2401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int i = 0; 2402e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (i < lol->obj_count_) { 2403e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element& element = elements[i]; 2404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!element.obj_->IsHeapObject()) { 2405e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the HeapObject address was converted into a SMI, then this 2406e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // is a dead object. Copy the last element over this one. 2407e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch element = elements[lol->obj_count_ - 1]; 2408e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->obj_count_--; 2409e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // We've just moved the last element into this index. We'll revisit 2410e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // this index again. Hence, no need to increment the iterator. 2411e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2412e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch i++; // Look at the next element next. 2413e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2414e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2415e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2416e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int new_count = lol->obj_count_; 2417e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2418e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check if there are any more elements to keep after purging the dead ones. 2419e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (new_count == 0) { 2420e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DeleteArray<Element>(elements); 2421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->elements_ = NULL; 2422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->capacity_ = 0; 2423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(lol->obj_count_ == 0); 2424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the list is also invisible, the clean up the list as well. 2426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol->id_ == 0) { 2427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Point the next lol's prev to this lol's prev. 2428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (next) { 2429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch next->prev_ = lol->prev_; 2430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch last_ = lol->prev_; 2432e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2433e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Delete this now empty and invisible lol. 2435e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch delete lol; 2436e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2437e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Don't point the next to this lol since it is now deleted. 2438e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Leave the next pointer pointing to the current lol. 2439e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 2440e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2442e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2443e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If the obj_count_ is less than the capacity and the difference is 2444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // greater than a specified threshold, then we should shrink the list. 2445e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int diff = lol->capacity_ - new_count; 2446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const int kMaxUnusedSpace = 64; 2447e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (diff > kMaxUnusedSpace) { // Threshold for shrinking. 2448e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Shrink the list. 24493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Element* new_elements = NewArray<Element>(new_count); 2450e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch memcpy(new_elements, elements, new_count * sizeof(Element)); 2451e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2452e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DeleteArray<Element>(elements); 2453e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->elements_ = new_elements; 2454e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->capacity_ = new_count; 2455e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2456e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(lol->obj_count_ == new_count); 2457e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol->Sort(); // We've moved objects. Re-sort in case. 2459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Save the next (for the previous link) in case we need it later. 2462e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch next = lol; 2463e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2464e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef VERIFY_LOL 2466e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (FLAG_verify_lol) { 2467e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Verify(); 2468e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2469e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif 2470e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2471e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#ifdef VERIFY_LOL 2474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::Verify(bool match_heap_exactly) { 2475e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("Verifying the LiveObjectList database:\n"); 2476e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2477e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LiveObjectList* lol = last(); 2478e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (lol == NULL) { 2479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" No lol database to verify\n"); 2480e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return; 2481e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2482e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" Preparing the lol database ...\n"); 2484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int total_count = lol->TotalObjCount(); 2485e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = NewArray<Element>(total_count); 2487e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int count = 0; 2488e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2489e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Copy all the object elements into a consecutive array. 2490e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" Copying the lol database ...\n"); 2491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 2492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element)); 2493e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch count += lol->obj_count_; 2494e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 2495e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2496e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch qsort(elements, total_count, sizeof(Element), 2497e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<RawComparer>(CompareElement)); 2498e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2499e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(count == total_count); 2500e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2501e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Iterate over all objects in the heap and check for: 2502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // 1. object in LOL but not in heap i.e. error. 2503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // 2. object in heap but not in LOL (possibly not an error). Usually 2504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // just means that we don't have the a capture of the latest heap. 2505e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // That is unless we did this verify immediately after a capture, 2506e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // and specified match_heap_exactly = true. 2507e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2508e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int number_of_heap_objects = 0; 2509e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int number_of_matches = 0; 2510e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int number_not_in_heap = total_count; 2511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int number_not_in_lol = 0; 2512e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" Start verify ...\n"); 2514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" Verifying ..."); 2515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Flush(); 25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapIterator iterator; 2517e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = NULL; 2518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while ((heap_obj = iterator.next()) != NULL) { 2519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_of_heap_objects++; 2520e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Check if the heap_obj is in the lol. 2522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element key; 2523e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch key.obj_ = heap_obj; 2524e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2525e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* result = reinterpret_cast<Element*>( 2526e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch bsearch(&key, elements, total_count, sizeof(Element), 2527e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch reinterpret_cast<RawComparer>(CompareElement))); 2528e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2529e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (result != NULL) { 2530e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_of_matches++; 2531e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_not_in_heap--; 2532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Mark it as found by changing it into a SMI (mask off low bit). 2533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Note: we cannot use HeapObject::cast() here because it asserts that 2534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the HeapObject bit is set on the address, but we're unsetting it on 2535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // purpose here for our marking. 2536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch result->obj_ = reinterpret_cast<HeapObject*>(heap_obj->address()); 2537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 2539e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_not_in_lol++; 2540e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (match_heap_exactly) { 2541e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("heap object %p NOT in lol database\n", heap_obj); 2542e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2544e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Show some sign of life. 2545e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (number_of_heap_objects % 1000 == 0) { 2546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("."); 2547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch fflush(stdout); 2548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2549e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2550e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("\n"); 2551e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2552e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Reporting lol objects not found in the heap. 2553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (number_not_in_heap) { 2554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int found = 0; 2555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; (i < total_count) && (found < number_not_in_heap); i++) { 2556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element& element = elements[i]; 2557e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (element.obj_->IsHeapObject()) { 2558e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("lol database object [%d of %d] %p NOT in heap\n", 2559e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch i, total_count, element.obj_); 2560e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch found++; 2561e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2562e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2564e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2565e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch DeleteArray<Element>(elements); 2566e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2567e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("number of objects in lol database %d\n", total_count); 2568e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("number of heap objects .......... %d\n", number_of_heap_objects); 2569e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("number of matches ............... %d\n", number_of_matches); 2570e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("number NOT in heap .............. %d\n", number_not_in_heap); 2571e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("number NOT in lol database ...... %d\n", number_not_in_lol); 2572e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (number_of_matches != total_count) { 2574e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" *** ERROR: " 2575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch "NOT all lol database objects match heap objects.\n"); 2576e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2577e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (number_not_in_heap != 0) { 2578e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" *** ERROR: %d lol database objects not found in heap.\n", 2579e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_not_in_heap); 2580e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2581e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (match_heap_exactly) { 2582e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!(number_not_in_lol == 0)) { 2583e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" *** ERROR: %d heap objects NOT found in lol database.\n", 2584e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch number_not_in_lol); 2585e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2586e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2587e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(number_of_matches == total_count); 2589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(number_not_in_heap == 0); 2590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(number_not_in_lol == (number_of_heap_objects - total_count)); 2591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (match_heap_exactly) { 2592e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(total_count == number_of_heap_objects); 2593e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(number_not_in_lol == 0); 2594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2595e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2596e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" Verify the lol database is sorted ...\n"); 2597e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = last(); 2598e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch while (lol != NULL) { 2599e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Element* elements = lol->elements_; 2600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < lol->obj_count_ - 1; i++) { 2601e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (elements[i].obj_ >= elements[i+1].obj_) { 2602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" *** ERROR: lol %p obj[%d] %p > obj[%d] %p\n", 2603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol, i, elements[i].obj_, i+1, elements[i+1].obj_); 2604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lol = lol->prev_; 2607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2608e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" DONE verifying.\n\n\n"); 2610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 2613e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid LiveObjectList::VerifyNotInFromSpace() { 2614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print("VerifyNotInFromSpace() ...\n"); 2615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch LolIterator it(NULL, last()); 261669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = ISOLATE->heap(); 2617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int i = 0; 2618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (it.Init(); !it.Done(); it.Next()) { 2619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HeapObject* heap_obj = it.Obj(); 262069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (heap->InFromSpace(heap_obj)) { 2621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch OS::Print(" ERROR: VerifyNotInFromSpace: [%d] obj %p in From space %p\n", 26223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i++, heap_obj, Heap::new_space()->FromSpaceStart()); 2623e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2624e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 2625e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 2626e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#endif // VERIFY_LOL 2627e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 26281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 26291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} } // namespace v8::internal 26301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 26311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif // LIVE_OBJECT_LIST 2632