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(GlobalContext, "unexpected: GlobalContext") \
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()->global_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)
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
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)
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)
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static Object * GetPath(int obj_id1, int obj_id2, Handle< JSObject > instance_filter)
static FixedArray * cast(Object *obj)
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)