OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1768 name = collection_->names()->GetFormatted("%s / %s", name, tag); | 1768 name = collection_->names()->GetFormatted("%s / %s", name, tag); |
1769 } | 1769 } |
1770 return AddEntry(object, | 1770 return AddEntry(object, |
1771 HeapEntry::kObject, | 1771 HeapEntry::kObject, |
1772 name, | 1772 name, |
1773 children_count, | 1773 children_count, |
1774 retainers_count); | 1774 retainers_count); |
1775 } else if (object->IsJSFunction()) { | 1775 } else if (object->IsJSFunction()) { |
1776 JSFunction* func = JSFunction::cast(object); | 1776 JSFunction* func = JSFunction::cast(object); |
1777 SharedFunctionInfo* shared = func->shared(); | 1777 SharedFunctionInfo* shared = func->shared(); |
1778 const char* name = shared->bound() ? "native bind" : | |
1779 collection_->names()->GetName(String::cast(shared->name())); | |
1778 return AddEntry(object, | 1780 return AddEntry(object, |
1779 HeapEntry::kClosure, | 1781 HeapEntry::kClosure, |
1780 collection_->names()->GetName(String::cast(shared->name())), | 1782 name, |
1781 children_count, | 1783 children_count, |
1782 retainers_count); | 1784 retainers_count); |
1783 } else if (object->IsJSRegExp()) { | 1785 } else if (object->IsJSRegExp()) { |
1784 JSRegExp* re = JSRegExp::cast(object); | 1786 JSRegExp* re = JSRegExp::cast(object); |
1785 return AddEntry(object, | 1787 return AddEntry(object, |
1786 HeapEntry::kRegExp, | 1788 HeapEntry::kRegExp, |
1787 collection_->names()->GetName(re->Pattern()), | 1789 collection_->names()->GetName(re->Pattern()), |
1788 children_count, | 1790 children_count, |
1789 retainers_count); | 1791 retainers_count); |
1790 } else if (object->IsJSObject()) { | 1792 } else if (object->IsJSObject()) { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2011 heap_->prototype_symbol(), js_fun->prototype()); | 2013 heap_->prototype_symbol(), js_fun->prototype()); |
2012 } | 2014 } |
2013 } | 2015 } |
2014 SetInternalReference(js_fun, entry, | 2016 SetInternalReference(js_fun, entry, |
2015 "shared", js_fun->shared(), | 2017 "shared", js_fun->shared(), |
2016 JSFunction::kSharedFunctionInfoOffset); | 2018 JSFunction::kSharedFunctionInfoOffset); |
2017 TagObject(js_fun->unchecked_context(), "(context)"); | 2019 TagObject(js_fun->unchecked_context(), "(context)"); |
2018 SetInternalReference(js_fun, entry, | 2020 SetInternalReference(js_fun, entry, |
2019 "context", js_fun->unchecked_context(), | 2021 "context", js_fun->unchecked_context(), |
2020 JSFunction::kContextOffset); | 2022 JSFunction::kContextOffset); |
2021 TagObject(js_fun->literals_or_bindings(), | 2023 // JSFunction has either bindings or literals and never both. |
2022 "(function literals_or_bindings)"); | 2024 if (js_fun->shared()->bound()) { |
2023 SetInternalReference(js_fun, entry, | 2025 TagObject(js_fun->literals(), "(function literals)"); |
2024 "literals_or_bindings", | 2026 SetInternalReference(js_fun, entry, |
2025 js_fun->literals_or_bindings(), | 2027 "literals", |
2026 JSFunction::kLiteralsOffset); | 2028 js_fun->literals(), |
2029 JSFunction::kLiteralsOffset); | |
2030 } else { | |
2031 TagObject(js_fun->function_bindings(), "(function bindings)"); | |
2032 SetInternalReference(js_fun, entry, | |
2033 "bindings", | |
2034 js_fun->function_bindings(), | |
2035 JSFunction::kLiteralsOffset); | |
2036 } | |
2027 for (int i = JSFunction::kNonWeakFieldsEndOffset; | 2037 for (int i = JSFunction::kNonWeakFieldsEndOffset; |
2028 i < JSFunction::kSize; | 2038 i < JSFunction::kSize; |
2029 i += kPointerSize) { | 2039 i += kPointerSize) { |
2030 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); | 2040 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); |
2031 } | 2041 } |
2032 } | 2042 } |
2033 TagObject(js_obj->properties(), "(object properties)"); | 2043 TagObject(js_obj->properties(), "(object properties)"); |
2034 SetInternalReference(obj, entry, | 2044 SetInternalReference(obj, entry, |
2035 "properties", js_obj->properties(), | 2045 "properties", js_obj->properties(), |
2036 JSObject::kPropertiesOffset); | 2046 JSObject::kPropertiesOffset); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2119 SetInternalReference(obj, entry, | 2129 SetInternalReference(obj, entry, |
2120 "data", script->data(), | 2130 "data", script->data(), |
2121 Script::kDataOffset); | 2131 Script::kDataOffset); |
2122 SetInternalReference(obj, entry, | 2132 SetInternalReference(obj, entry, |
2123 "context_data", script->context_data(), | 2133 "context_data", script->context_data(), |
2124 Script::kContextOffset); | 2134 Script::kContextOffset); |
2125 TagObject(script->line_ends(), "(script line ends)"); | 2135 TagObject(script->line_ends(), "(script line ends)"); |
2126 SetInternalReference(obj, entry, | 2136 SetInternalReference(obj, entry, |
2127 "line_ends", script->line_ends(), | 2137 "line_ends", script->line_ends(), |
2128 Script::kLineEndsOffset); | 2138 Script::kLineEndsOffset); |
2129 } else if (obj->IsDescriptorArray()) { | |
yurys
2012/02/10 11:30:14
DescriptorArray is indistinguishable from a regula
mnaganov (inactive)
2012/02/10 12:28:21
OK, thanks!
| |
2130 DescriptorArray* desc_array = DescriptorArray::cast(obj); | |
2131 if (desc_array->length() > DescriptorArray::kContentArrayIndex) { | |
2132 Object* content_array = | |
2133 desc_array->get(DescriptorArray::kContentArrayIndex); | |
2134 TagObject(content_array, "(map descriptor content)"); | |
2135 SetInternalReference(obj, entry, | |
2136 "content", content_array, | |
2137 FixedArray::OffsetOfElementAt( | |
2138 DescriptorArray::kContentArrayIndex)); | |
2139 } | |
2140 } else if (obj->IsCodeCache()) { | 2139 } else if (obj->IsCodeCache()) { |
2141 CodeCache* code_cache = CodeCache::cast(obj); | 2140 CodeCache* code_cache = CodeCache::cast(obj); |
2142 TagObject(code_cache->default_cache(), "(default code cache)"); | 2141 TagObject(code_cache->default_cache(), "(default code cache)"); |
2143 SetInternalReference(obj, entry, | 2142 SetInternalReference(obj, entry, |
2144 "default_cache", code_cache->default_cache(), | 2143 "default_cache", code_cache->default_cache(), |
2145 CodeCache::kDefaultCacheOffset); | 2144 CodeCache::kDefaultCacheOffset); |
2146 TagObject(code_cache->normal_type_cache(), "(code type cache)"); | 2145 TagObject(code_cache->normal_type_cache(), "(code type cache)"); |
2147 SetInternalReference(obj, entry, | 2146 SetInternalReference(obj, entry, |
2148 "type_cache", code_cache->normal_type_cache(), | 2147 "type_cache", code_cache->normal_type_cache(), |
2149 CodeCache::kNormalTypeCacheOffset); | 2148 CodeCache::kNormalTypeCacheOffset); |
2150 } else if (obj->IsCode()) { | 2149 } else if (obj->IsCode()) { |
2151 Code* code = Code::cast(obj); | 2150 Code* code = Code::cast(obj); |
2152 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); | 2151 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); |
2153 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); | 2152 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); |
2154 } | 2153 } |
2155 if (extract_indexed_refs) { | 2154 if (extract_indexed_refs) { |
2156 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | 2155 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); |
2157 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 2156 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
2158 obj->Iterate(&refs_extractor); | 2157 obj->Iterate(&refs_extractor); |
2159 } | 2158 } |
2160 } | 2159 } |
2161 | 2160 |
2162 | 2161 |
2163 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, | 2162 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
2164 HeapEntry* entry) { | 2163 HeapEntry* entry) { |
2165 if (js_obj->IsJSFunction()) { | 2164 if (!js_obj->IsJSFunction()) return; |
2166 JSFunction* func = JSFunction::cast(js_obj); | |
2167 Context* context = func->context(); | |
2168 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | |
2169 | 2165 |
2166 JSFunction* func = JSFunction::cast(js_obj); | |
2167 Context* context = func->context(); | |
2168 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | |
2169 | |
2170 if (func->shared()->bound()) { | |
2171 FixedArray* bindings = func->function_bindings(); | |
2172 SetNativeBindReference(js_obj, entry, "bound this", | |
mnaganov (inactive)
2012/02/10 12:28:21
Perhaps, use underscores for names? Otherwise it m
yurys
2012/02/10 13:48:59
Makes sense. Done.
| |
2173 bindings->get(JSFunction::kBoundThisIndex)); | |
2174 SetNativeBindReference(js_obj, entry, "bound function", | |
2175 bindings->get(JSFunction::kBoundFunctionIndex)); | |
2176 for (int i = JSFunction::kBoundArgumentsStartIndex; | |
2177 i < bindings->length(); i++) { | |
2178 SetNativeBindReference(js_obj, entry, "bound argument", | |
mnaganov (inactive)
2012/02/10 12:28:21
Does it make sense to label them "bound_argument_%
yurys
2012/02/10 13:48:59
Done.
| |
2179 bindings->get(i)); | |
2180 } | |
2181 } else { | |
2170 // Add context allocated locals. | 2182 // Add context allocated locals. |
2171 int context_locals = scope_info->ContextLocalCount(); | 2183 int context_locals = scope_info->ContextLocalCount(); |
2172 for (int i = 0; i < context_locals; ++i) { | 2184 for (int i = 0; i < context_locals; ++i) { |
2173 String* local_name = scope_info->ContextLocalName(i); | 2185 String* local_name = scope_info->ContextLocalName(i); |
2174 int idx = Context::MIN_CONTEXT_SLOTS + i; | 2186 int idx = Context::MIN_CONTEXT_SLOTS + i; |
2175 SetClosureReference(js_obj, entry, local_name, context->get(idx)); | 2187 SetClosureReference(js_obj, entry, local_name, context->get(idx)); |
2176 } | 2188 } |
2177 | 2189 |
2178 // Add function variable. | 2190 // Add function variable. |
2179 if (scope_info->HasFunctionName()) { | 2191 if (scope_info->HasFunctionName()) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2437 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, | 2449 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, |
2438 parent_obj, | 2450 parent_obj, |
2439 parent_entry, | 2451 parent_entry, |
2440 collection_->names()->GetName(reference_name), | 2452 collection_->names()->GetName(reference_name), |
2441 child_obj, | 2453 child_obj, |
2442 child_entry); | 2454 child_entry); |
2443 } | 2455 } |
2444 } | 2456 } |
2445 | 2457 |
2446 | 2458 |
2459 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, | |
2460 HeapEntry* parent_entry, | |
2461 const char* reference_name, | |
2462 Object* child_obj) { | |
2463 HeapEntry* child_entry = GetEntry(child_obj); | |
2464 if (child_entry != NULL) { | |
2465 filler_->SetNamedReference(HeapGraphEdge::kShortcut, | |
2466 parent_obj, | |
2467 parent_entry, | |
2468 reference_name, | |
2469 child_obj, | |
2470 child_entry); | |
2471 } | |
2472 } | |
2473 | |
2474 | |
2447 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, | 2475 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, |
2448 HeapEntry* parent_entry, | 2476 HeapEntry* parent_entry, |
2449 int index, | 2477 int index, |
2450 Object* child_obj) { | 2478 Object* child_obj) { |
2451 HeapEntry* child_entry = GetEntry(child_obj); | 2479 HeapEntry* child_entry = GetEntry(child_obj); |
2452 if (child_entry != NULL) { | 2480 if (child_entry != NULL) { |
2453 filler_->SetIndexedReference(HeapGraphEdge::kElement, | 2481 filler_->SetIndexedReference(HeapGraphEdge::kElement, |
2454 parent_obj, | 2482 parent_obj, |
2455 parent_entry, | 2483 parent_entry, |
2456 index, | 2484 index, |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3727 | 3755 |
3728 | 3756 |
3729 void HeapSnapshotJSONSerializer::SortHashMap( | 3757 void HeapSnapshotJSONSerializer::SortHashMap( |
3730 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3758 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3731 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3759 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3732 sorted_entries->Add(p); | 3760 sorted_entries->Add(p); |
3733 sorted_entries->Sort(SortUsingEntryValue); | 3761 sorted_entries->Sort(SortUsingEntryValue); |
3734 } | 3762 } |
3735 | 3763 |
3736 } } // namespace v8::internal | 3764 } } // namespace v8::internal |
OLD | NEW |