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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 obj, entry, | 2006 obj, entry, |
2005 heap_->prototype_symbol(), proto_or_map, | 2007 heap_->prototype_symbol(), proto_or_map, |
2006 NULL, | 2008 NULL, |
2007 JSFunction::kPrototypeOrInitialMapOffset); | 2009 JSFunction::kPrototypeOrInitialMapOffset); |
2008 } else { | 2010 } else { |
2009 SetPropertyReference( | 2011 SetPropertyReference( |
2010 obj, entry, | 2012 obj, entry, |
2011 heap_->prototype_symbol(), js_fun->prototype()); | 2013 heap_->prototype_symbol(), js_fun->prototype()); |
2012 } | 2014 } |
2013 } | 2015 } |
| 2016 SharedFunctionInfo* shared_info = js_fun->shared(); |
| 2017 // JSFunction has either bindings or literals and never both. |
| 2018 bool bound = shared_info->bound(); |
| 2019 TagObject(js_fun->literals_or_bindings(), |
| 2020 bound ? "(function bindings)" : "(function literals)"); |
2014 SetInternalReference(js_fun, entry, | 2021 SetInternalReference(js_fun, entry, |
2015 "shared", js_fun->shared(), | 2022 bound ? "bindings" : "literals", |
| 2023 js_fun->literals_or_bindings(), |
| 2024 JSFunction::kLiteralsOffset); |
| 2025 SetInternalReference(js_fun, entry, |
| 2026 "shared", shared_info, |
2016 JSFunction::kSharedFunctionInfoOffset); | 2027 JSFunction::kSharedFunctionInfoOffset); |
2017 TagObject(js_fun->unchecked_context(), "(context)"); | 2028 TagObject(js_fun->unchecked_context(), "(context)"); |
2018 SetInternalReference(js_fun, entry, | 2029 SetInternalReference(js_fun, entry, |
2019 "context", js_fun->unchecked_context(), | 2030 "context", js_fun->unchecked_context(), |
2020 JSFunction::kContextOffset); | 2031 JSFunction::kContextOffset); |
2021 TagObject(js_fun->literals_or_bindings(), | |
2022 "(function literals_or_bindings)"); | |
2023 SetInternalReference(js_fun, entry, | |
2024 "literals_or_bindings", | |
2025 js_fun->literals_or_bindings(), | |
2026 JSFunction::kLiteralsOffset); | |
2027 for (int i = JSFunction::kNonWeakFieldsEndOffset; | 2032 for (int i = JSFunction::kNonWeakFieldsEndOffset; |
2028 i < JSFunction::kSize; | 2033 i < JSFunction::kSize; |
2029 i += kPointerSize) { | 2034 i += kPointerSize) { |
2030 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); | 2035 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); |
2031 } | 2036 } |
2032 } | 2037 } |
2033 TagObject(js_obj->properties(), "(object properties)"); | 2038 TagObject(js_obj->properties(), "(object properties)"); |
2034 SetInternalReference(obj, entry, | 2039 SetInternalReference(obj, entry, |
2035 "properties", js_obj->properties(), | 2040 "properties", js_obj->properties(), |
2036 JSObject::kPropertiesOffset); | 2041 JSObject::kPropertiesOffset); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 SetInternalReference(obj, entry, | 2124 SetInternalReference(obj, entry, |
2120 "data", script->data(), | 2125 "data", script->data(), |
2121 Script::kDataOffset); | 2126 Script::kDataOffset); |
2122 SetInternalReference(obj, entry, | 2127 SetInternalReference(obj, entry, |
2123 "context_data", script->context_data(), | 2128 "context_data", script->context_data(), |
2124 Script::kContextOffset); | 2129 Script::kContextOffset); |
2125 TagObject(script->line_ends(), "(script line ends)"); | 2130 TagObject(script->line_ends(), "(script line ends)"); |
2126 SetInternalReference(obj, entry, | 2131 SetInternalReference(obj, entry, |
2127 "line_ends", script->line_ends(), | 2132 "line_ends", script->line_ends(), |
2128 Script::kLineEndsOffset); | 2133 Script::kLineEndsOffset); |
2129 } else if (obj->IsDescriptorArray()) { | |
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()) { | 2134 } else if (obj->IsCodeCache()) { |
2141 CodeCache* code_cache = CodeCache::cast(obj); | 2135 CodeCache* code_cache = CodeCache::cast(obj); |
2142 TagObject(code_cache->default_cache(), "(default code cache)"); | 2136 TagObject(code_cache->default_cache(), "(default code cache)"); |
2143 SetInternalReference(obj, entry, | 2137 SetInternalReference(obj, entry, |
2144 "default_cache", code_cache->default_cache(), | 2138 "default_cache", code_cache->default_cache(), |
2145 CodeCache::kDefaultCacheOffset); | 2139 CodeCache::kDefaultCacheOffset); |
2146 TagObject(code_cache->normal_type_cache(), "(code type cache)"); | 2140 TagObject(code_cache->normal_type_cache(), "(code type cache)"); |
2147 SetInternalReference(obj, entry, | 2141 SetInternalReference(obj, entry, |
2148 "type_cache", code_cache->normal_type_cache(), | 2142 "type_cache", code_cache->normal_type_cache(), |
2149 CodeCache::kNormalTypeCacheOffset); | 2143 CodeCache::kNormalTypeCacheOffset); |
2150 } else if (obj->IsCode()) { | 2144 } else if (obj->IsCode()) { |
2151 Code* code = Code::cast(obj); | 2145 Code* code = Code::cast(obj); |
2152 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); | 2146 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); |
2153 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); | 2147 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); |
2154 } | 2148 } |
2155 if (extract_indexed_refs) { | 2149 if (extract_indexed_refs) { |
2156 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | 2150 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); |
2157 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 2151 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
2158 obj->Iterate(&refs_extractor); | 2152 obj->Iterate(&refs_extractor); |
2159 } | 2153 } |
2160 } | 2154 } |
2161 | 2155 |
2162 | 2156 |
2163 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, | 2157 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
2164 HeapEntry* entry) { | 2158 HeapEntry* entry) { |
2165 if (js_obj->IsJSFunction()) { | 2159 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 | 2160 |
| 2161 JSFunction* func = JSFunction::cast(js_obj); |
| 2162 Context* context = func->context(); |
| 2163 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 2164 |
| 2165 if (func->shared()->bound()) { |
| 2166 FixedArray* bindings = func->function_bindings(); |
| 2167 SetNativeBindReference(js_obj, entry, "bound_this", |
| 2168 bindings->get(JSFunction::kBoundThisIndex)); |
| 2169 SetNativeBindReference(js_obj, entry, "bound_function", |
| 2170 bindings->get(JSFunction::kBoundFunctionIndex)); |
| 2171 for (int i = JSFunction::kBoundArgumentsStartIndex; |
| 2172 i < bindings->length(); i++) { |
| 2173 const char* reference_name = collection_->names()->GetFormatted( |
| 2174 "bound_argument_%d", |
| 2175 i - JSFunction::kBoundArgumentsStartIndex); |
| 2176 SetNativeBindReference(js_obj, entry, reference_name, |
| 2177 bindings->get(i)); |
| 2178 } |
| 2179 } else { |
2170 // Add context allocated locals. | 2180 // Add context allocated locals. |
2171 int context_locals = scope_info->ContextLocalCount(); | 2181 int context_locals = scope_info->ContextLocalCount(); |
2172 for (int i = 0; i < context_locals; ++i) { | 2182 for (int i = 0; i < context_locals; ++i) { |
2173 String* local_name = scope_info->ContextLocalName(i); | 2183 String* local_name = scope_info->ContextLocalName(i); |
2174 int idx = Context::MIN_CONTEXT_SLOTS + i; | 2184 int idx = Context::MIN_CONTEXT_SLOTS + i; |
2175 SetClosureReference(js_obj, entry, local_name, context->get(idx)); | 2185 SetClosureReference(js_obj, entry, local_name, context->get(idx)); |
2176 } | 2186 } |
2177 | 2187 |
2178 // Add function variable. | 2188 // Add function variable. |
2179 if (scope_info->HasFunctionName()) { | 2189 if (scope_info->HasFunctionName()) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, | 2447 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, |
2438 parent_obj, | 2448 parent_obj, |
2439 parent_entry, | 2449 parent_entry, |
2440 collection_->names()->GetName(reference_name), | 2450 collection_->names()->GetName(reference_name), |
2441 child_obj, | 2451 child_obj, |
2442 child_entry); | 2452 child_entry); |
2443 } | 2453 } |
2444 } | 2454 } |
2445 | 2455 |
2446 | 2456 |
| 2457 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, |
| 2458 HeapEntry* parent_entry, |
| 2459 const char* reference_name, |
| 2460 Object* child_obj) { |
| 2461 HeapEntry* child_entry = GetEntry(child_obj); |
| 2462 if (child_entry != NULL) { |
| 2463 filler_->SetNamedReference(HeapGraphEdge::kShortcut, |
| 2464 parent_obj, |
| 2465 parent_entry, |
| 2466 reference_name, |
| 2467 child_obj, |
| 2468 child_entry); |
| 2469 } |
| 2470 } |
| 2471 |
| 2472 |
2447 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, | 2473 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, |
2448 HeapEntry* parent_entry, | 2474 HeapEntry* parent_entry, |
2449 int index, | 2475 int index, |
2450 Object* child_obj) { | 2476 Object* child_obj) { |
2451 HeapEntry* child_entry = GetEntry(child_obj); | 2477 HeapEntry* child_entry = GetEntry(child_obj); |
2452 if (child_entry != NULL) { | 2478 if (child_entry != NULL) { |
2453 filler_->SetIndexedReference(HeapGraphEdge::kElement, | 2479 filler_->SetIndexedReference(HeapGraphEdge::kElement, |
2454 parent_obj, | 2480 parent_obj, |
2455 parent_entry, | 2481 parent_entry, |
2456 index, | 2482 index, |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3727 | 3753 |
3728 | 3754 |
3729 void HeapSnapshotJSONSerializer::SortHashMap( | 3755 void HeapSnapshotJSONSerializer::SortHashMap( |
3730 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3756 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3731 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3757 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3732 sorted_entries->Add(p); | 3758 sorted_entries->Add(p); |
3733 sorted_entries->Sort(SortUsingEntryValue); | 3759 sorted_entries->Sort(SortUsingEntryValue); |
3734 } | 3760 } |
3735 | 3761 |
3736 } } // namespace v8::internal | 3762 } } // namespace v8::internal |
OLD | NEW |