28 #ifdef LIVE_OBJECT_LIST
50 typedef int (*RawComparer)(
const void*,
const void*);
53 #ifdef CHECK_ALL_OBJECT_TYPES
55 #define DEBUG_LIVE_OBJECT_TYPES(v) \
56 v(Smi, "unexpected: Smi") \
58 v(CodeCache, "unexpected: CodeCache") \
59 v(BreakPointInfo, "unexpected: BreakPointInfo") \
60 v(DebugInfo, "unexpected: DebugInfo") \
61 v(TypeSwitchInfo, "unexpected: TypeSwitchInfo") \
62 v(SignatureInfo, "unexpected: SignatureInfo") \
63 v(Script, "unexpected: Script") \
64 v(ObjectTemplateInfo, "unexpected: ObjectTemplateInfo") \
65 v(FunctionTemplateInfo, "unexpected: FunctionTemplateInfo") \
66 v(CallHandlerInfo, "unexpected: CallHandlerInfo") \
67 v(InterceptorInfo, "unexpected: InterceptorInfo") \
68 v(AccessCheckInfo, "unexpected: AccessCheckInfo") \
69 v(AccessorInfo, "unexpected: AccessorInfo") \
70 v(ExternalTwoByteString, "unexpected: ExternalTwoByteString") \
71 v(ExternalAsciiString, "unexpected: ExternalAsciiString") \
72 v(ExternalString, "unexpected: ExternalString") \
73 v(SeqTwoByteString, "unexpected: SeqTwoByteString") \
74 v(SeqAsciiString, "unexpected: SeqAsciiString") \
75 v(SeqString, "unexpected: SeqString") \
76 v(JSFunctionResultCache, "unexpected: JSFunctionResultCache") \
77 v(NativeContext, "unexpected: NativeContext") \
78 v(MapCache, "unexpected: MapCache") \
79 v(CodeCacheHashTable, "unexpected: CodeCacheHashTable") \
80 v(CompilationCacheTable, "unexpected: CompilationCacheTable") \
81 v(SymbolTable, "unexpected: SymbolTable") \
82 v(Dictionary, "unexpected: Dictionary") \
83 v(HashTable, "unexpected: HashTable") \
84 v(DescriptorArray, "unexpected: DescriptorArray") \
85 v(ExternalFloatArray, "unexpected: ExternalFloatArray") \
86 v(ExternalUnsignedIntArray, "unexpected: ExternalUnsignedIntArray") \
87 v(ExternalIntArray, "unexpected: ExternalIntArray") \
88 v(ExternalUnsignedShortArray, "unexpected: ExternalUnsignedShortArray") \
89 v(ExternalShortArray, "unexpected: ExternalShortArray") \
90 v(ExternalUnsignedByteArray, "unexpected: ExternalUnsignedByteArray") \
91 v(ExternalByteArray, "unexpected: ExternalByteArray") \
92 v(JSValue, "unexpected: JSValue")
95 #define DEBUG_LIVE_OBJECT_TYPES(v)
99 #define FOR_EACH_LIVE_OBJECT_TYPE(v) \
100 DEBUG_LIVE_OBJECT_TYPES(v) \
102 v(JSArray, "JSArray") \
103 v(JSRegExp, "JSRegExp") \
104 v(JSFunction, "JSFunction") \
105 v(JSGlobalObject, "JSGlobal") \
106 v(JSBuiltinsObject, "JSBuiltins") \
107 v(GlobalObject, "Global") \
108 v(JSGlobalProxy, "JSGlobalProxy") \
109 v(JSObject, "JSObject") \
111 v(Context, "meta: Context") \
112 v(ByteArray, "meta: ByteArray") \
113 v(ExternalPixelArray, "meta: PixelArray") \
114 v(ExternalArray, "meta: ExternalArray") \
115 v(FixedArray, "meta: FixedArray") \
116 v(String, "String") \
117 v(HeapNumber, "HeapNumber") \
119 v(Code, "meta: Code") \
120 v(Map, "meta: Map") \
121 v(Oddball, "Oddball") \
122 v(Foreign, "meta: Foreign") \
123 v(SharedFunctionInfo, "meta: SharedFunctionInfo") \
124 v(Struct, "meta: Struct") \
126 v(HeapObject, "HeapObject")
130 #define DECLARE_OBJECT_TYPE_ENUM(type, name) kType##type,
131 FOR_EACH_LIVE_OBJECT_TYPE(DECLARE_OBJECT_TYPE_ENUM)
134 #undef DECLARE_OBJECT_TYPE_ENUM
138 LiveObjectType GetObjectType(HeapObject* heap_obj) {
140 #define CHECK_FOR_OBJECT_TYPE(type, name) \
141 if (heap_obj->Is##type()) return kType##type;
142 FOR_EACH_LIVE_OBJECT_TYPE(CHECK_FOR_OBJECT_TYPE)
143 #undef CHECK_FOR_OBJECT_TYPE
146 return kInvalidLiveObjType;
150 inline const char* GetObjectTypeDesc(LiveObjectType type) {
151 static const char*
const name[kNumberOfTypes] = {
152 #define DEFINE_OBJECT_TYPE_NAME(type, name) name,
153 FOR_EACH_LIVE_OBJECT_TYPE(DEFINE_OBJECT_TYPE_NAME)
155 #undef DEFINE_OBJECT_TYPE_NAME
157 ASSERT(type < kNumberOfTypes);
162 const char* GetObjectTypeDesc(HeapObject* heap_obj) {
163 LiveObjectType type = GetObjectType(heap_obj);
164 return GetObjectTypeDesc(type);
168 bool IsOfType(LiveObjectType type, HeapObject* obj) {
174 #define CHECK_OBJECT_TYPE(type_, name) \
175 if (obj->Is##type_()) return (type == kType##type_);
177 FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
178 #undef CHECK_OBJECT_TYPE
187 SmartArrayPointer<char> s =
190 const char* key_str = *s;
191 switch (key_str[0]) {
193 if (strcmp(key_str,
"cell") == 0)
return CELL_SPACE;
194 if (strcmp(key_str,
"code") == 0)
return CODE_SPACE;
197 if (strcmp(key_str,
"lo") == 0)
return LO_SPACE;
200 if (strcmp(key_str,
"map") == 0)
return MAP_SPACE;
203 if (strcmp(key_str,
"new") == 0)
return NEW_SPACE;
210 return kInvalidSpace;
217 return heap->InSpace(heap_obj, space);
227 int last_space =
static_cast<int>(
LO_SPACE);
228 for (
int sp = first_space;
sp < last_space;
sp++) {
229 if (heap->InSpace(heap_obj, static_cast<AllocationSpace>(
sp))) {
238 static LiveObjectType FindTypeFor(String* type_str) {
239 SmartArrayPointer<char> s =
242 #define CHECK_OBJECT_TYPE(type_, name) { \
243 const char* type_desc = GetObjectTypeDesc(kType##type_); \
244 const char* key_str = *s; \
245 if (strstr(type_desc, key_str) != NULL) return kType##type_; \
247 FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
248 #undef CHECK_OBJECT_TYPE
250 return kInvalidLiveObjType;
256 explicit LolFilter(Handle<JSObject> filter_obj);
258 inline bool is_active()
const {
return is_active_; }
259 inline bool Matches(HeapObject* obj) {
260 return !is_active() || MatchesSlow(obj);
264 void InitTypeFilter(Handle<JSObject> filter_obj);
265 void InitSpaceFilter(Handle<JSObject> filter_obj);
266 void InitPropertyFilter(Handle<JSObject> filter_obj);
267 bool MatchesSlow(HeapObject* obj);
270 LiveObjectType type_;
272 Handle<String> prop_;
276 LolFilter::LolFilter(Handle<JSObject> filter_obj)
278 type_(kInvalidLiveObjType),
279 space_(kInvalidSpace),
281 if (filter_obj.is_null())
return;
283 InitTypeFilter(filter_obj);
284 InitSpaceFilter(filter_obj);
285 InitPropertyFilter(filter_obj);
289 void LolFilter::InitTypeFilter(Handle<JSObject> filter_obj) {
290 Handle<String> type_sym =
FACTORY->LookupAsciiSymbol(
"type");
291 MaybeObject* maybe_result = filter_obj->GetProperty(*type_sym);
293 if (maybe_result->ToObject(&type_obj)) {
294 if (type_obj->IsString()) {
296 type_ = FindTypeFor(type_str);
297 if (type_ != kInvalidLiveObjType) {
305 void LolFilter::InitSpaceFilter(Handle<JSObject> filter_obj) {
306 Handle<String> space_sym =
FACTORY->LookupAsciiSymbol(
"space");
307 MaybeObject* maybe_result = filter_obj->GetProperty(*space_sym);
309 if (maybe_result->ToObject(&space_obj)) {
310 if (space_obj->IsString()) {
312 space_ = FindSpaceFor(space_str);
313 if (space_ != kInvalidSpace) {
321 void LolFilter::InitPropertyFilter(Handle<JSObject> filter_obj) {
322 Handle<String> prop_sym =
FACTORY->LookupAsciiSymbol(
"prop");
323 MaybeObject* maybe_result = filter_obj->GetProperty(*prop_sym);
325 if (maybe_result->ToObject(&prop_obj)) {
326 if (prop_obj->IsString()) {
334 bool LolFilter::MatchesSlow(HeapObject* obj) {
335 if ((type_ != kInvalidLiveObjType) && !IsOfType(type_, obj)) {
338 if ((space_ != kInvalidSpace) && !InSpace(space_, obj)) {
341 if (!prop_.is_null() && obj->IsJSObject()) {
343 obj->Lookup(*prop_, &result);
344 if (!result.IsProperty()) {
354 LolIterator(LiveObjectList* older, LiveObjectList* newer)
366 while ((elements_ ==
NULL) && !Done()) {
367 SetCurrent(curr_->prev_);
371 inline bool Done()
const {
372 return (curr_ == older_);
378 if (index_ >= count_) {
381 SetCurrent(curr_->prev_);
383 if (elements_ !=
NULL)
break;
390 inline int Id()
const {
391 return elements_[index_].id_;
393 inline HeapObject* Obj()
const {
394 return elements_[index_].obj_;
397 inline int LolObjCount()
const {
398 if (curr_ !=
NULL)
return curr_->obj_count_;
403 inline void SetCurrent(LiveObjectList* new_curr) {
406 elements_ = curr_->elements_;
407 count_ = curr_->obj_count_;
412 LiveObjectList* older_;
413 LiveObjectList* newer_;
414 LiveObjectList* curr_;
415 LiveObjectList::Element* elements_;
421 class LolForwardIterator :
public LolIterator {
423 LolForwardIterator(LiveObjectList* first, LiveObjectList* last)
424 : LolIterator(first, last) {
431 while ((elements_ ==
NULL) && !Done()) {
432 SetCurrent(curr_->next_);
436 inline bool Done()
const {
437 return (curr_ == newer_);
443 if (index_ >= count_) {
446 SetCurrent(curr_->next_);
448 if (elements_ !=
NULL)
break;
459 static int CompactString(
char* str) {
463 while (*dst !=
'\0') {
466 if ((ch & 0x80) != 0) {
471 if (prev_ch !=
' ') *dst++ =
' ';
486 static void GenerateObjectDesc(HeapObject* obj,
489 Vector<char> buffer_v(buffer, buffer_size);
491 if (obj->IsJSArray()) {
493 double length = jsarray->length()->Number();
496 reinterpret_cast<void*>(obj),
497 GetObjectTypeDesc(obj),
500 }
else if (obj->IsString()) {
504 const int kMaxCharToDump = 80;
505 const int kMaxBufferSize = kMaxCharToDump * 2;
510 char* str_cstr = *str_sp;
511 int length = CompactString(str_cstr);
514 reinterpret_cast<void*>(obj),
515 GetObjectTypeDesc(obj),
517 (length > kMaxCharToDump) ?
"..." :
"");
519 }
else if (obj->IsJSFunction() || obj->IsSharedFunctionInfo()) {
520 SharedFunctionInfo* sinfo;
521 if (obj->IsJSFunction()) {
523 sinfo = func->shared();
528 String* name = sinfo->DebugName();
529 SmartArrayPointer<char> name_sp =
531 char* name_cstr = *name_sp;
533 HeapStringAllocator string_allocator;
534 StringStream stream(&string_allocator);
535 sinfo->SourceCodePrint(&stream, 50);
536 SmartArrayPointer<const char> source_sp = stream.ToCString();
537 const char* source_cstr = *source_sp;
541 reinterpret_cast<void*>(obj),
542 GetObjectTypeDesc(obj),
546 }
else if (obj->IsFixedArray()) {
551 reinterpret_cast<void*>(obj),
552 GetObjectTypeDesc(obj),
558 reinterpret_cast<void*>(obj),
559 GetObjectTypeDesc(obj));
565 static bool AddObjDetail(Handle<FixedArray> arr,
568 Handle<HeapObject> target,
569 const char* desc_str,
570 Handle<String> id_sym,
571 Handle<String> desc_sym,
572 Handle<String> size_sym,
573 Handle<JSObject> detail,
575 Handle<Object> error) {
576 Isolate* isolate = Isolate::Current();
577 Factory* factory = isolate->factory();
578 detail = factory->NewJSObject(isolate->object_function());
579 if (detail->IsFailure()) {
586 if (desc_str ==
NULL) {
587 ASSERT(!target.is_null());
588 HeapObject* obj = *target;
589 GenerateObjectDesc(obj, buffer,
sizeof(buffer));
593 desc = factory->NewStringFromAscii(
CStrVector(desc_str));
594 if (desc->IsFailure()) {
599 { MaybeObject* maybe_result = detail->SetProperty(*id_sym,
603 if (maybe_result->IsFailure())
return false;
605 { MaybeObject* maybe_result = detail->SetProperty(*desc_sym,
609 if (maybe_result->IsFailure())
return false;
611 { MaybeObject* maybe_result = detail->SetProperty(*size_sym,
615 if (maybe_result->IsFailure())
return false;
618 arr->set(index, *detail);
625 virtual ~DumpWriter() {}
627 virtual void ComputeTotalCountAndSize(LolFilter* filter,
630 virtual bool Write(Handle<FixedArray> elements_arr,
634 Handle<Object> error) = 0;
638 class LolDumpWriter:
public DumpWriter {
640 LolDumpWriter(LiveObjectList* older, LiveObjectList* newer)
641 : older_(older), newer_(newer) {
644 void ComputeTotalCountAndSize(LolFilter* filter,
int* count,
int* size) {
648 LolIterator it(older_, newer_);
649 for (it.Init(); !it.Done(); it.Next()) {
650 HeapObject* heap_obj = it.Obj();
651 if (!filter->Matches(heap_obj)) {
655 *size += heap_obj->Size();
660 bool Write(Handle<FixedArray> elements_arr,
664 Handle<Object> error) {
670 Isolate* isolate = Isolate::Current();
671 Factory* factory = isolate->factory();
674 Handle<String> id_sym = factory->LookupAsciiSymbol(
"id");
675 Handle<String> desc_sym = factory->LookupAsciiSymbol(
"desc");
676 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
679 Handle<JSObject> detail;
681 Handle<HeapObject> target;
683 LiveObjectList* first_lol = (older_ !=
NULL) ?
684 older_->next_ : LiveObjectList::first_;
685 LiveObjectList* last_lol = (newer_ !=
NULL) ? newer_->next_ :
NULL;
687 LolForwardIterator it(first_lol, last_lol);
688 for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
689 HeapObject* heap_obj = it.Obj();
692 if (!filter->Matches(heap_obj)) {
697 if (count >= start) {
698 target = Handle<HeapObject>(heap_obj);
699 bool success = AddObjDetail(elements_arr,
710 if (!success)
return false;
718 LiveObjectList* older_;
719 LiveObjectList* newer_;
723 class RetainersDumpWriter:
public DumpWriter {
725 RetainersDumpWriter(Handle<HeapObject> target,
726 Handle<JSObject> instance_filter,
727 Handle<JSFunction> args_function)
729 instance_filter_(instance_filter),
730 args_function_(args_function) {
733 void ComputeTotalCountAndSize(LolFilter* filter,
int* count,
int* size) {
734 Handle<FixedArray> retainers_arr;
735 Handle<Object> error;
738 LiveObjectList::GetRetainers(target_,
750 bool Write(Handle<FixedArray> elements_arr,
754 Handle<Object> error) {
759 count = LiveObjectList::GetRetainers(target_,
776 Handle<HeapObject> target_;
777 Handle<JSObject> instance_filter_;
778 Handle<JSFunction> args_function_;
782 class LiveObjectSummary {
784 explicit LiveObjectSummary(LolFilter* filter)
788 found_weak_root_(
false),
790 memset(counts_, 0,
sizeof(counts_[0]) * kNumberOfEntries);
791 memset(sizes_, 0,
sizeof(sizes_[0]) * kNumberOfEntries);
794 void Add(HeapObject* heap_obj) {
795 int size = heap_obj->Size();
796 LiveObjectType type = GetObjectType(heap_obj);
797 ASSERT(type != kInvalidLiveObjType);
799 sizes_[type] += size;
804 void set_found_root() { found_root_ =
true; }
805 void set_found_weak_root() { found_weak_root_ =
true; }
807 inline int Count(LiveObjectType type) {
808 return counts_[type];
810 inline int Size(LiveObjectType type) {
813 inline int total_count() {
816 inline int total_size() {
819 inline bool found_root() {
822 inline bool found_weak_root() {
823 return found_weak_root_;
825 int GetNumberOfEntries() {
827 for (
int i = 0; i < kNumberOfEntries; i++) {
828 if (counts_[i]) entries++;
833 inline LolFilter* filter() {
return filter_; }
835 static const int kNumberOfEntries = kNumberOfTypes;
838 int counts_[kNumberOfEntries];
839 int sizes_[kNumberOfEntries];
843 bool found_weak_root_;
850 class SummaryWriter {
852 virtual ~SummaryWriter() {}
853 virtual void Write(LiveObjectSummary* summary) = 0;
858 class LolSummaryWriter:
public SummaryWriter {
860 LolSummaryWriter(LiveObjectList* older_lol,
861 LiveObjectList* newer_lol)
862 : older_(older_lol), newer_(newer_lol) {
865 void Write(LiveObjectSummary* summary) {
866 LolFilter* filter = summary->filter();
869 LolIterator it(older_, newer_);
870 for (it.Init(); !it.Done(); it.Next()) {
871 HeapObject* heap_obj = it.Obj();
872 if (!filter->Matches(heap_obj)) {
875 summary->Add(heap_obj);
880 LiveObjectList* older_;
881 LiveObjectList* newer_;
886 class RetainersSummaryWriter:
public SummaryWriter {
888 RetainersSummaryWriter(Handle<HeapObject> target,
889 Handle<JSObject> instance_filter,
890 Handle<JSFunction> args_function)
892 instance_filter_(instance_filter),
893 args_function_(args_function) {
896 void Write(LiveObjectSummary* summary) {
897 Handle<FixedArray> retainers_arr;
898 Handle<Object> error;
899 int dummy_total_count;
900 LiveObjectList::GetRetainers(target_,
913 Handle<HeapObject> target_;
914 Handle<JSObject> instance_filter_;
915 Handle<JSFunction> args_function_;
919 uint32_t LiveObjectList::next_element_id_ = 1;
920 int LiveObjectList::list_count_ = 0;
921 int LiveObjectList::last_id_ = 0;
922 LiveObjectList* LiveObjectList::first_ =
NULL;
923 LiveObjectList* LiveObjectList::last_ =
NULL;
926 LiveObjectList::LiveObjectList(LiveObjectList* prev,
int capacity)
931 elements_ = NewArray<Element>(capacity);
938 LiveObjectList::~LiveObjectList() {
939 DeleteArray<Element>(elements_);
944 int LiveObjectList::GetTotalObjCountAndSize(
int* size_p) {
947 LiveObjectList* lol =
this;
950 if (size_p !=
NULL) {
951 Element* elements = lol->elements_;
952 for (
int i = 0; i < lol->obj_count_; i++) {
953 HeapObject* heap_obj = elements[i].obj_;
954 size += heap_obj->Size();
957 count += lol->obj_count_;
959 }
while (lol !=
NULL);
961 if (size_p !=
NULL) {
970 bool LiveObjectList::Add(HeapObject* obj) {
973 if ((prev() !=
NULL) && (prev()->Find(obj) !=
NULL)) {
976 ASSERT(obj_count_ <= capacity_);
977 if (obj_count_ == capacity_) {
982 Element& element = elements_[obj_count_++];
983 element.id_ = next_element_id_++;
990 int LiveObjectList::CompareElement(
const Element* a,
const Element* b) {
991 const HeapObject* obj1 = a->obj_;
992 const HeapObject* obj2 = b->obj_;
996 return (obj1 > obj2) ? 1 : (obj1 == obj2) ? 0 : -1;
1001 LiveObjectList::Element* LiveObjectList::Find(HeapObject* obj) {
1002 LiveObjectList* lol =
this;
1004 Element* result =
NULL;
1008 while ((result ==
NULL) && (lol !=
NULL)) {
1009 result =
reinterpret_cast<Element*
>(
1010 bsearch(&key, lol->elements_, lol->obj_count_,
1012 reinterpret_cast<RawComparer>(CompareElement)));
1023 void LiveObjectList::NullifyMostRecent(HeapObject* obj) {
1024 LiveObjectList* lol = last();
1026 Element* result =
NULL;
1030 while (lol !=
NULL) {
1031 result =
reinterpret_cast<Element*
>(
1032 bsearch(&key, lol->elements_, lol->obj_count_,
1034 reinterpret_cast<RawComparer>(CompareElement)));
1035 if (result !=
NULL) {
1039 int i = result - lol->elements_;
1047 for (i--; i > 0; i--) {
1048 Element* element = &lol->elements_[i];
1049 HeapObject* curr_obj = element->obj_;
1050 if (curr_obj != obj) {
1057 NullifyNonLivePointer(&result->obj_);
1066 void LiveObjectList::Sort() {
1067 if (obj_count_ > 0) {
1068 Vector<Element> elements_v(elements_, obj_count_);
1069 elements_v.Sort(CompareElement);
1075 void LiveObjectList::SortAll() {
1076 LiveObjectList* lol = last();
1077 while (lol !=
NULL) {
1085 static int CountHeapObjects() {
1088 HeapIterator iterator;
1089 HeapObject* heap_obj =
NULL;
1090 while ((heap_obj = iterator.next()) !=
NULL) {
1099 Isolate* isolate = Isolate::Current();
1100 Factory* factory = isolate->factory();
1101 HandleScope scope(isolate);
1104 int total_count = CountHeapObjects();
1105 int count = total_count;
1108 LiveObjectList* last_lol = last();
1109 if (last_lol !=
NULL) {
1110 count -= last_lol->TotalObjCount();
1113 LiveObjectList* lol;
1116 lol =
new LiveObjectList(last_lol, count);
1125 HeapIterator iterator;
1126 HeapObject* heap_obj =
NULL;
1127 bool failed =
false;
1128 while (!failed && (heap_obj = iterator.next()) !=
NULL) {
1129 failed = !lol->Add(heap_obj);
1130 size += heap_obj->Size();
1137 if (last_ !=
NULL) {
1145 if (FLAG_verify_lol) {
1151 Handle<String> id_sym = factory->LookupAsciiSymbol(
"id");
1152 Handle<String> count_sym = factory->LookupAsciiSymbol(
"count");
1153 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
1155 Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
1158 { MaybeObject* maybe_result = result->SetProperty(*id_sym,
1162 if (maybe_result->IsFailure())
return maybe_result;
1164 { MaybeObject* maybe_result = result->SetProperty(*count_sym,
1168 if (maybe_result->IsFailure())
return maybe_result;
1170 { MaybeObject* maybe_result = result->SetProperty(*size_sym,
1174 if (maybe_result->IsFailure())
return maybe_result;
1186 LiveObjectList* lol = last();
1187 while (lol !=
NULL) {
1188 if (lol->id() == id) {
1195 if (lol ==
NULL)
return false;
1200 ASSERT(list_count_ >= 0);
1201 if (lol->obj_count_ == 0) {
1203 LiveObjectList* next = lol->next_;
1204 LiveObjectList* prev = lol->prev_;
1207 next->prev_ = lol->prev_;
1213 prev->next_ = lol->next_;
1215 first_ = lol->next_;
1226 if (list_count_ == 0) {
1238 Handle<JSObject> filter_obj) {
1239 if ((older_id < 0) || (newer_id < 0) || (last() ==
NULL)) {
1242 if (newer_id < older_id) {
1244 int temp = older_id;
1245 older_id = newer_id;
1249 LiveObjectList* newer_lol = FindLolForId(newer_id, last());
1250 LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
1254 if ((newer_id != 0) && (newer_lol ==
NULL)) {
1257 if ((older_id != 0) && (older_lol ==
NULL)) {
1261 LolFilter filter(filter_obj);
1262 LolDumpWriter writer(older_lol, newer_lol);
1263 return DumpPrivate(&writer, start_idx, dump_limit, &filter);
1267 MaybeObject* LiveObjectList::DumpPrivate(DumpWriter* writer,
1270 LolFilter* filter) {
1271 Isolate* isolate = Isolate::Current();
1272 Factory* factory = isolate->factory();
1274 HandleScope scope(isolate);
1279 writer->ComputeTotalCountAndSize(filter, &count, &size);
1282 if ((start < 0) || (start >= count)) {
1286 int remaining_count = count - start;
1287 if (dump_limit > remaining_count) {
1288 dump_limit = remaining_count;
1292 Handle<FixedArray> elements_arr = factory->NewFixedArray(dump_limit);
1293 if (elements_arr->IsFailure())
return Object::cast(*elements_arr);
1296 Handle<Object> error;
1297 bool success = writer->Write(elements_arr,
1304 MaybeObject* maybe_result;
1307 Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
1311 Handle<String> count_sym = factory->LookupAsciiSymbol(
"count");
1312 maybe_result = body->SetProperty(*count_sym,
1316 if (maybe_result->IsFailure())
return maybe_result;
1320 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
1321 maybe_result = body->SetProperty(*size_sym,
1325 if (maybe_result->IsFailure())
return maybe_result;
1329 Handle<String> first_sym = factory->LookupAsciiSymbol(
"first_index");
1330 maybe_result = body->SetProperty(*first_sym,
1334 if (maybe_result->IsFailure())
return maybe_result;
1337 Handle<JSObject> elements = factory->NewJSObject(isolate->array_function());
1338 if (elements->IsFailure())
return Object::cast(*elements);
1341 if (maybe_result->IsFailure())
return maybe_result;
1344 Handle<String> elements_sym = factory->LookupAsciiSymbol(
"elements");
1345 maybe_result = body->SetProperty(*elements_sym,
1349 if (maybe_result->IsFailure())
return maybe_result;
1357 Handle<JSObject> filter_obj) {
1358 if ((older_id < 0) || (newer_id < 0) || (last() ==
NULL)) {
1361 if (newer_id < older_id) {
1363 int temp = older_id;
1364 older_id = newer_id;
1368 LiveObjectList* newer_lol = FindLolForId(newer_id, last());
1369 LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
1373 if ((newer_id != 0) && (newer_lol ==
NULL)) {
1376 if ((older_id != 0) && (older_lol ==
NULL)) {
1380 LolFilter filter(filter_obj);
1381 LolSummaryWriter writer(older_lol, newer_lol);
1382 return SummarizePrivate(&writer, &filter,
false);
1389 MaybeObject* LiveObjectList::SummarizePrivate(SummaryWriter* writer,
1391 bool is_tracking_roots) {
1393 MaybeObject* maybe_result;
1395 LiveObjectSummary summary(filter);
1396 writer->Write(&summary);
1398 Isolate* isolate = Isolate::Current();
1399 Factory* factory = isolate->factory();
1418 Handle<String> desc_sym = factory->LookupAsciiSymbol(
"desc");
1419 Handle<String> count_sym = factory->LookupAsciiSymbol(
"count");
1420 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
1421 Handle<String> summary_sym = factory->LookupAsciiSymbol(
"summary");
1424 int entries_count = summary.GetNumberOfEntries();
1425 Handle<FixedArray> summary_arr =
1426 factory->NewFixedArray(entries_count);
1427 if (summary_arr->IsFailure())
return Object::cast(*summary_arr);
1430 for (
int i = 0; i < LiveObjectSummary::kNumberOfEntries; i++) {
1432 Handle<JSObject> detail = factory->NewJSObject(isolate->object_function());
1436 LiveObjectType type =
static_cast<LiveObjectType
>(i);
1437 int count = summary.Count(type);
1439 const char* desc_cstr = GetObjectTypeDesc(type);
1440 Handle<String> desc = factory->LookupAsciiSymbol(desc_cstr);
1441 int size = summary.Size(type);
1443 maybe_result = detail->SetProperty(*desc_sym,
1447 if (maybe_result->IsFailure())
return maybe_result;
1448 maybe_result = detail->SetProperty(*count_sym,
1452 if (maybe_result->IsFailure())
return maybe_result;
1453 maybe_result = detail->SetProperty(*size_sym,
1457 if (maybe_result->IsFailure())
return maybe_result;
1459 summary_arr->set(idx++, *detail);
1464 Handle<JSObject> summary_obj =
1465 factory->NewJSObject(isolate->array_function());
1466 if (summary_obj->IsFailure())
return Object::cast(*summary_obj);
1469 if (maybe_result->IsFailure())
return maybe_result;
1472 Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
1476 int total_count = summary.total_count();
1477 int total_size = summary.total_size();
1478 maybe_result = body->SetProperty(*count_sym,
1482 if (maybe_result->IsFailure())
return maybe_result;
1484 maybe_result = body->SetProperty(*size_sym,
1488 if (maybe_result->IsFailure())
return maybe_result;
1490 if (is_tracking_roots) {
1491 int found_root = summary.found_root();
1492 int found_weak_root = summary.found_weak_root();
1493 Handle<String> root_sym = factory->LookupAsciiSymbol(
"found_root");
1494 Handle<String> weak_root_sym =
1495 factory->LookupAsciiSymbol(
"found_weak_root");
1496 maybe_result = body->SetProperty(*root_sym,
1500 if (maybe_result->IsFailure())
return maybe_result;
1501 maybe_result = body->SetProperty(*weak_root_sym,
1505 if (maybe_result->IsFailure())
return maybe_result;
1508 maybe_result = body->SetProperty(*summary_sym,
1512 if (maybe_result->IsFailure())
return maybe_result;
1522 Isolate* isolate = Isolate::Current();
1523 Factory* factory = isolate->factory();
1525 HandleScope scope(isolate);
1526 MaybeObject* maybe_result;
1528 int total_count = LiveObjectList::list_count();
1529 int dump_count = total_count;
1532 if (total_count == 0) {
1534 }
else if ((start_idx < 0) || (start_idx >= total_count)) {
1537 dump_count -= start_idx;
1540 if (dump_count > dump_limit) {
1541 dump_count = dump_limit;
1545 Handle<FixedArray> list = factory->NewFixedArray(dump_count);
1549 Handle<String> id_sym = factory->LookupAsciiSymbol(
"id");
1550 Handle<String> count_sym = factory->LookupAsciiSymbol(
"count");
1551 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
1555 LiveObjectList* lol = first_;
1556 while ((lol !=
NULL) && (idx < start_idx)) {
1557 if (lol->id() != 0) {
1563 while ((lol !=
NULL) && (dump_limit != 0)) {
1564 if (lol->id() != 0) {
1567 count = lol->GetTotalObjCountAndSize(&size);
1569 Handle<JSObject> detail =
1570 factory->NewJSObject(isolate->object_function());
1573 maybe_result = detail->SetProperty(*id_sym,
1577 if (maybe_result->IsFailure())
return maybe_result;
1578 maybe_result = detail->SetProperty(*count_sym,
1582 if (maybe_result->IsFailure())
return maybe_result;
1583 maybe_result = detail->SetProperty(*size_sym,
1587 if (maybe_result->IsFailure())
return maybe_result;
1588 list->set(idx++, *detail);
1595 Handle<JSObject> lols = factory->NewJSObject(isolate->array_function());
1598 if (maybe_result->IsFailure())
return maybe_result;
1600 Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
1603 maybe_result = result->SetProperty(*count_sym,
1607 if (maybe_result->IsFailure())
return maybe_result;
1609 Handle<String> first_sym = factory->LookupAsciiSymbol(
"first_index");
1610 maybe_result = result->SetProperty(*first_sym,
1614 if (maybe_result->IsFailure())
return maybe_result;
1616 Handle<String> lists_sym = factory->LookupAsciiSymbol(
"lists");
1617 maybe_result = result->SetProperty(*lists_sym,
1621 if (maybe_result->IsFailure())
return maybe_result;
1629 LiveObjectList* lol = last();
1633 next_element_id_ = 1;
1643 Element* element = FindElementFor<int>(GetElementId, obj_id);
1644 if (element !=
NULL) {
1647 return HEAP->undefined_value();
1655 Element* element = FindElementFor<HeapObject*>(GetElementObj, hobj);
1656 if (element !=
NULL) {
1657 return element->id_;
1665 SmartArrayPointer<char> addr_str =
1668 Isolate* isolate = Isolate::Current();
1672 static_cast<int>(
StringToInt(isolate->unicode_cache(), *address, 16));
1679 class LolVisitor:
public ObjectVisitor {
1681 LolVisitor(HeapObject* target, Handle<HeapObject> handle_to_skip)
1682 : target_(target), handle_to_skip_(handle_to_skip), found_(
false) {}
1684 void VisitPointer(
Object** p) { CheckPointer(p); }
1688 for (
Object** p = start; !found() && p < end; p++) CheckPointer(p);
1691 inline bool found()
const {
return found_; }
1692 inline bool reset() {
return found_ =
false; }
1695 inline void CheckPointer(
Object** p) {
1702 if (!handle_to_skip_.is_null() &&
1703 handle_to_skip_.location() ==
reinterpret_cast<HeapObject**
>(p)) {
1710 HeapObject* target_;
1711 Handle<HeapObject> handle_to_skip_;
1716 inline bool AddRootRetainerIfFound(
const LolVisitor& visitor,
1718 LiveObjectSummary* summary,
1719 void (*SetRootFound)(LiveObjectSummary* s),
1723 Handle<FixedArray> retainers_arr,
1726 const char* root_name,
1727 Handle<String> id_sym,
1728 Handle<String> desc_sym,
1729 Handle<String> size_sym,
1730 Handle<Object> error) {
1734 Handle<JSObject> detail;
1735 Handle<String> desc;
1736 Handle<HeapObject> retainer;
1738 if (visitor.found()) {
1739 if (!filter->is_active()) {
1742 SetRootFound(summary);
1743 }
else if ((*total_count > start) && ((*index) < dump_limit)) {
1745 if (!retainers_arr.is_null()) {
1746 return AddObjDetail(retainers_arr,
1765 inline void SetFoundRoot(LiveObjectSummary* summary) {
1766 summary->set_found_root();
1770 inline void SetFoundWeakRoot(LiveObjectSummary* summary) {
1771 summary->set_found_weak_root();
1775 int LiveObjectList::GetRetainers(Handle<HeapObject> target,
1776 Handle<JSObject> instance_filter,
1777 Handle<FixedArray> retainers_arr,
1782 LiveObjectSummary* summary,
1783 JSFunction* arguments_function,
1784 Handle<Object> error) {
1788 Handle<JSObject> detail;
1789 Handle<String> desc;
1790 Handle<HeapObject> retainer;
1792 Isolate* isolate = Isolate::Current();
1793 Factory* factory = isolate->factory();
1796 Handle<String> id_sym = factory->LookupAsciiSymbol(
"id");
1797 Handle<String> desc_sym = factory->LookupAsciiSymbol(
"desc");
1798 Handle<String> size_sym = factory->LookupAsciiSymbol(
"size");
1800 NoHandleAllocation ha;
1803 Handle<JSObject> last_obj;
1808 LolVisitor lol_visitor(*target, target);
1809 isolate->heap()->IterateStrongRoots(&lol_visitor,
VISIT_ALL);
1810 if (!AddRootRetainerIfFound(lol_visitor,
1828 lol_visitor.reset();
1829 isolate->heap()->IterateWeakRoots(&lol_visitor,
VISIT_ALL);
1830 if (!AddRootRetainerIfFound(lol_visitor,
1849 LolIterator it(
NULL, last());
1850 for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
1851 HeapObject* heap_obj = it.Obj();
1854 if (heap_obj->IsJSObject()) {
1858 if (obj->IsJSContextExtensionObject() ||
1859 obj->map()->constructor() == arguments_function) {
1864 if (obj->ReferencesObject(*target)) {
1867 if (!instance_filter->IsUndefined()) {
1870 Object* prototype = V->GetPrototype();
1871 if (prototype->IsNull()) {
1874 if (*instance_filter == prototype) {
1884 if (filter->Matches(heap_obj)) {
1890 last_obj = Handle<JSObject>(obj);
1893 if (summary !=
NULL) {
1894 summary->Add(heap_obj);
1895 }
else if ((*total_count > start) && (index < dump_limit)) {
1897 if (!retainers_arr.is_null()) {
1898 retainer = Handle<HeapObject>(heap_obj);
1899 bool success = AddObjDetail(retainers_arr,
1910 if (!success)
return -1;
1923 if (*total_count == 1 && !last_obj.is_null() && *last_obj == *target) {
1933 Handle<JSObject> instance_filter,
1937 Handle<JSObject> filter_obj) {
1938 Isolate* isolate = Isolate::Current();
1939 Factory* factory = isolate->factory();
1940 Heap* heap = isolate->heap();
1942 HandleScope scope(isolate);
1946 if (heap_obj == heap->undefined_value()) {
1950 Handle<HeapObject> target = Handle<HeapObject>(heap_obj);
1953 JSObject* arguments_boilerplate =
1954 isolate->context()->native_context()->arguments_boilerplate();
1955 JSFunction* arguments_function =
1958 Handle<JSFunction> args_function = Handle<JSFunction>(arguments_function);
1959 LolFilter filter(filter_obj);
1962 RetainersSummaryWriter writer(target, instance_filter, args_function);
1963 return SummarizePrivate(&writer, &filter,
true);
1966 RetainersDumpWriter writer(target, instance_filter, args_function);
1968 MaybeObject* maybe_result =
1969 DumpPrivate(&writer, start, dump_limit, &filter);
1970 if (!maybe_result->ToObject(&body_obj)) {
1971 return maybe_result;
1975 Handle<JSObject> body = Handle<JSObject>(
JSObject::cast(body_obj));
1976 Handle<String> id_sym = factory->LookupAsciiSymbol(
"id");
1977 maybe_result = body->SetProperty(*id_sym,
1981 if (maybe_result->IsFailure())
return maybe_result;
1991 return HEAP->undefined_value();
1994 EmbeddedVector<char, 128> temp_filename;
1995 static int temp_count = 0;
1996 const char* path_prefix =
".";
1998 Isolate* isolate = Isolate::Current();
1999 Factory* factory = isolate->factory();
2000 Heap* heap = isolate->heap();
2002 if (FLAG_lol_workdir) {
2003 path_prefix = FLAG_lol_workdir;
2005 OS::SNPrintF(temp_filename,
"%s/lol-print-%d", path_prefix, ++temp_count);
2007 FILE* f =
OS::FOpen(temp_filename.start(),
"w+");
2012 Inspector::DumpObjectType(f, obj);
2016 #else // !OBJECT_PRINT
2018 #endif // !OBJECT_PRINT
2025 MemoryMappedExternalResource* resource =
2026 new MemoryMappedExternalResource(temp_filename.start(),
true);
2027 if (resource->exists() && !resource->is_empty()) {
2028 ASSERT(resource->IsAscii());
2029 Handle<String> dump_string =
2030 factory->NewExternalStringFromAscii(resource);
2031 heap->external_string_table()->AddString(*dump_string);
2032 return *dump_string;
2036 return HEAP->undefined_value();
2040 class LolPathTracer:
public PathTracer {
2042 LolPathTracer(FILE* out,
2044 WhatToFind what_to_find)
2048 void ProcessResults();
2054 void LolPathTracer::ProcessResults() {
2055 if (found_target_) {
2056 PrintF(out_,
"=====================================\n");
2057 PrintF(out_,
"==== Path to object ====\n");
2058 PrintF(out_,
"=====================================\n\n");
2060 ASSERT(!object_stack_.is_empty());
2062 for (
int i = 0, index = 0; i < object_stack_.length(); i++) {
2063 Object* obj = object_stack_[i];
2067 if (prev && prev->IsJSObject() &&
2068 (obj != search_target_)) {
2070 if (obj->IsFixedArray() &&
2075 }
else if (obj->IsHeapObject() &&
2084 if (i > 0)
PrintF(out_,
"\n |\n |\n V\n\n");
2087 PrintF(out_,
"[%d] ", ++index);
2091 if (
id > 0)
PrintF(out_,
"@%d ",
id);
2095 Inspector::DumpObjectType(out_, obj);
2099 #else // !OBJECT_PRINT
2100 obj->ShortPrint(out_);
2102 #endif // !OBJECT_PRINT
2106 PrintF(out_,
"=====================================\n\n");
2112 Object* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) {
2113 EmbeddedVector<char, 128> temp_filename;
2114 static int temp_count = 0;
2115 const char* path_prefix =
".";
2117 if (FLAG_lol_workdir) {
2118 path_prefix = FLAG_lol_workdir;
2120 OS::SNPrintF(temp_filename,
"%s/lol-getpath-%d", path_prefix, ++temp_count);
2122 FILE* f =
OS::FOpen(temp_filename.start(),
"w+");
2124 Isolate* isolate = Isolate::Current();
2125 Factory* factory = isolate->factory();
2126 Heap* heap = isolate->heap();
2129 bool prev_verbosity = FLAG_use_verbose_printer;
2130 FLAG_use_verbose_printer =
false;
2136 LolPathTracer tracer(f, obj2, LolPathTracer::FIND_FIRST);
2143 List<ObjectGroup*>* groups = isolate->global_handles()->object_groups();
2144 for (
int i = 0; i < groups->length(); i++) {
2145 ObjectGroup* group = groups->at(i);
2146 if (group ==
NULL)
continue;
2148 bool found_group =
false;
2149 for (
size_t j = 0; j < group->length_; j++) {
2150 Object*
object = *(group->objects_[j]);
2160 "obj %p is a member of object group %p {\n",
2161 reinterpret_cast<void*>(obj2),
2162 reinterpret_cast<void*>(group));
2163 for (
size_t j = 0; j < group->length_; j++) {
2164 Object*
object = *(group->objects_[j]);
2165 if (!object->IsHeapObject())
continue;
2176 GenerateObjectDesc(hobj, buffer,
sizeof(buffer));
2177 PrintF(f,
" %s", buffer);
2188 PrintF(f,
"path from roots to obj %p\n", reinterpret_cast<void*>(obj2));
2190 found = tracer.found();
2193 PrintF(f,
" No paths found. Checking symbol tables ...\n");
2194 SymbolTable* symbol_table =
HEAP->raw_unchecked_symbol_table();
2195 tracer.VisitPointers(reinterpret_cast<Object**>(&symbol_table),
2196 reinterpret_cast<Object**>(&symbol_table)+1);
2197 found = tracer.found();
2199 symbol_table->IteratePrefix(&tracer);
2200 found = tracer.found();
2205 PrintF(f,
" No paths found. Checking weak roots ...\n");
2207 isolate->global_handles()->IterateWeakRoots(&tracer);
2208 found = tracer.found();
2212 PrintF(f,
"path from obj %p to obj %p:\n",
2213 reinterpret_cast<void*>(obj1), reinterpret_cast<void*>(obj2));
2214 tracer.TracePathFrom(reinterpret_cast<Object**>(&obj1));
2215 found = tracer.found();
2219 PrintF(f,
" No paths found\n\n");
2228 FLAG_use_verbose_printer = prev_verbosity;
2232 MemoryMappedExternalResource* resource =
2233 new MemoryMappedExternalResource(temp_filename.start(),
true);
2234 if (resource->exists() && !resource->is_empty()) {
2235 ASSERT(resource->IsAscii());
2236 Handle<String> path_string =
2237 factory->NewExternalStringFromAscii(resource);
2238 heap->external_string_table()->AddString(*path_string);
2239 return *path_string;
2243 return heap->undefined_value();
2249 Handle<JSObject> instance_filter) {
2253 HeapObject* obj1 =
NULL;
2256 if (obj1 ==
HEAP->undefined_value()) {
2262 if (obj2 ==
HEAP->undefined_value()) {
2266 return GetPathPrivate(obj1, obj2);
2270 void LiveObjectList::DoProcessNonLive(HeapObject* obj) {
2273 Element* element = last()->Find(obj);
2274 if (element !=
NULL) {
2275 NullifyNonLivePointer(&element->obj_);
2280 void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) {
2281 LiveObjectList* lol = last();
2282 while (lol !=
NULL) {
2283 Element* elements = lol->elements_;
2284 int count = lol->obj_count_;
2285 for (
int i = 0; i < count; i++) {
2286 HeapObject** p = &elements[i].obj_;
2287 v->VisitPointer(reinterpret_cast<Object** >(p));
2296 void LiveObjectList::PurgeDuplicates() {
2297 bool is_sorted =
false;
2298 LiveObjectList* lol = last();
2303 int total_count = lol->TotalObjCount();
2308 Element* elements = NewArray<Element>(total_count);
2313 memcpy(&elements[count], lol->elements_, lol->obj_count_ *
sizeof(Element));
2314 count += lol->obj_count_;
2317 qsort(elements, total_count,
sizeof(Element),
2318 reinterpret_cast<RawComparer>(CompareElement));
2320 ASSERT(count == total_count);
2324 for (
int i = 0; i < total_count; ) {
2325 Element* curr = &elements[i];
2326 HeapObject* curr_obj = curr->obj_;
2330 while (!done && (j < total_count)) {
2333 if (curr_obj->IsHeapObject()) {
2334 Element* next = &elements[j];
2335 HeapObject* next_obj = next->obj_;
2336 if (next_obj->IsHeapObject()) {
2337 if (curr_obj != next_obj) {
2355 NullifyMostRecent(curr_obj);
2369 DeleteArray<Element>(elements);
2374 void LiveObjectList::GCEpiloguePrivate() {
2392 LiveObjectList* prev =
NULL;
2393 LiveObjectList* next =
NULL;
2396 for (LiveObjectList* lol = last(); lol; lol = prev) {
2397 Element* elements = lol->elements_;
2402 while (i < lol->obj_count_) {
2403 Element& element = elements[i];
2404 if (!element.obj_->IsHeapObject()) {
2407 element = elements[lol->obj_count_ - 1];
2416 int new_count = lol->obj_count_;
2419 if (new_count == 0) {
2420 DeleteArray<Element>(elements);
2421 lol->elements_ =
NULL;
2423 ASSERT(lol->obj_count_ == 0);
2426 if (lol->id_ == 0) {
2429 next->prev_ = lol->prev_;
2445 int diff = lol->capacity_ - new_count;
2446 const int kMaxUnusedSpace = 64;
2447 if (diff > kMaxUnusedSpace) {
2449 Element* new_elements = NewArray<Element>(new_count);
2450 memcpy(new_elements, elements, new_count *
sizeof(Element));
2452 DeleteArray<Element>(elements);
2453 lol->elements_ = new_elements;
2454 lol->capacity_ = new_count;
2456 ASSERT(lol->obj_count_ == new_count);
2466 if (FLAG_verify_lol) {
2474 void LiveObjectList::Verify(
bool match_heap_exactly) {
2475 OS::Print(
"Verifying the LiveObjectList database:\n");
2477 LiveObjectList* lol = last();
2479 OS::Print(
" No lol database to verify\n");
2483 OS::Print(
" Preparing the lol database ...\n");
2484 int total_count = lol->TotalObjCount();
2486 Element* elements = NewArray<Element>(total_count);
2490 OS::Print(
" Copying the lol database ...\n");
2491 while (lol !=
NULL) {
2492 memcpy(&elements[count], lol->elements_, lol->obj_count_ *
sizeof(Element));
2493 count += lol->obj_count_;
2496 qsort(elements, total_count,
sizeof(Element),
2497 reinterpret_cast<RawComparer>(CompareElement));
2499 ASSERT(count == total_count);
2508 int number_of_heap_objects = 0;
2509 int number_of_matches = 0;
2510 int number_not_in_heap = total_count;
2511 int number_not_in_lol = 0;
2516 HeapIterator iterator;
2517 HeapObject* heap_obj =
NULL;
2518 while ((heap_obj = iterator.next()) !=
NULL) {
2519 number_of_heap_objects++;
2523 key.obj_ = heap_obj;
2525 Element* result =
reinterpret_cast<Element*
>(
2526 bsearch(&key, elements, total_count,
sizeof(Element),
2527 reinterpret_cast<RawComparer>(CompareElement)));
2529 if (result !=
NULL) {
2530 number_of_matches++;
2531 number_not_in_heap--;
2536 result->obj_ =
reinterpret_cast<HeapObject*
>(heap_obj->address());
2539 number_not_in_lol++;
2540 if (match_heap_exactly) {
2541 OS::Print(
"heap object %p NOT in lol database\n", heap_obj);
2545 if (number_of_heap_objects % 1000 == 0) {
2553 if (number_not_in_heap) {
2555 for (
int i = 0; (i < total_count) && (found < number_not_in_heap); i++) {
2556 Element& element = elements[i];
2557 if (element.obj_->IsHeapObject()) {
2558 OS::Print(
"lol database object [%d of %d] %p NOT in heap\n",
2559 i, total_count, element.obj_);
2565 DeleteArray<Element>(elements);
2567 OS::Print(
"number of objects in lol database %d\n", total_count);
2568 OS::Print(
"number of heap objects .......... %d\n", number_of_heap_objects);
2569 OS::Print(
"number of matches ............... %d\n", number_of_matches);
2570 OS::Print(
"number NOT in heap .............. %d\n", number_not_in_heap);
2571 OS::Print(
"number NOT in lol database ...... %d\n", number_not_in_lol);
2573 if (number_of_matches != total_count) {
2575 "NOT all lol database objects match heap objects.\n");
2577 if (number_not_in_heap != 0) {
2578 OS::Print(
" *** ERROR: %d lol database objects not found in heap.\n",
2579 number_not_in_heap);
2581 if (match_heap_exactly) {
2582 if (!(number_not_in_lol == 0)) {
2583 OS::Print(
" *** ERROR: %d heap objects NOT found in lol database.\n",
2588 ASSERT(number_of_matches == total_count);
2589 ASSERT(number_not_in_heap == 0);
2590 ASSERT(number_not_in_lol == (number_of_heap_objects - total_count));
2591 if (match_heap_exactly) {
2592 ASSERT(total_count == number_of_heap_objects);
2593 ASSERT(number_not_in_lol == 0);
2596 OS::Print(
" Verify the lol database is sorted ...\n");
2598 while (lol !=
NULL) {
2599 Element* elements = lol->elements_;
2600 for (
int i = 0; i < lol->obj_count_ - 1; i++) {
2601 if (elements[i].obj_ >= elements[i+1].obj_) {
2602 OS::Print(
" *** ERROR: lol %p obj[%d] %p > obj[%d] %p\n",
2603 lol, i, elements[i].obj_, i+1, elements[i+1].obj_);
2613 void LiveObjectList::VerifyNotInFromSpace() {
2614 OS::Print(
"VerifyNotInFromSpace() ...\n");
2615 LolIterator it(
NULL, last());
2618 for (it.Init(); !it.Done(); it.Next()) {
2619 HeapObject* heap_obj = it.Obj();
2620 if (heap->InFromSpace(heap_obj)) {
2621 OS::Print(
" ERROR: VerifyNotInFromSpace: [%d] obj %p in From space %p\n",
2626 #endif // VERIFY_LOL
2631 #endif // LIVE_OBJECT_LIST
#define SLOW_ASSERT(condition)
void PrintF(const char *format,...)
static Object * GetObjId(Handle< String > address)
static String * cast(Object *obj)
static Smi * FromInt(int value)
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
static bool Delete(int id)
static Failure * Exception()
#define ASSERT(condition)
static MaybeObject * Summarize(int id1, int id2, Handle< JSObject > filter_obj)
static SharedFunctionInfo * cast(Object *obj)
static MaybeObject * Info(int start_idx, int dump_limit)
double StringToInt(UnicodeCache *unicode_cache, String *str, int radix)
static FILE * FOpen(const char *path, const char *mode)
static MaybeObject * Dump(int id1, int id2, int start_idx, int dump_limit, Handle< JSObject > filter_obj)
static MaybeObject * GetObjRetainers(int obj_id, Handle< JSObject > instance_filter, bool verbose, int start, int count, Handle< JSObject > filter_obj)
activate correct semantics for inheriting readonliness false
Vector< const char > CStrVector(const char *data)
static JSArray * cast(Object *obj)
static void Print(const char *format,...)
static int SNPrintF(Vector< char > str, const char *format,...)
static Object * cast(Object *value)
static Object * GetPath(int obj_id1, int obj_id2, Handle< JSObject > instance_filter)
static FixedArray * cast(Object *obj)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static Object * GetObj(int obj_id)
static MaybeObject * Capture()
static Object * PrintObj(int obj_id)
static const int kMaxValue
static JSObject * cast(Object *obj)
static JSFunction * cast(Object *obj)