OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1971 int next_index_; | 1971 int next_index_; |
1972 }; | 1972 }; |
1973 | 1973 |
1974 | 1974 |
1975 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { | 1975 void V8HeapExplorer::ExtractReferences(HeapObject* obj) { |
1976 HeapEntry* entry = GetEntry(obj); | 1976 HeapEntry* entry = GetEntry(obj); |
1977 if (entry == NULL) return; // No interest in this object. | 1977 if (entry == NULL) return; // No interest in this object. |
1978 | 1978 |
1979 bool extract_indexed_refs = true; | 1979 bool extract_indexed_refs = true; |
1980 if (obj->IsJSGlobalProxy()) { | 1980 if (obj->IsJSGlobalProxy()) { |
1981 ExtractJSGlobalProxy(JSGlobalProxy::cast(obj)); | 1981 ExtractJSGlobalProxyReferences(JSGlobalProxy::cast(obj)); |
1982 } else if (obj->IsJSObject()) { | 1982 } else if (obj->IsJSObject()) { |
1983 ExtractJSObject(entry, JSObject::cast(obj)); | 1983 ExtractJSObjectReferences(entry, JSObject::cast(obj)); |
1984 } else if (obj->IsString()) { | 1984 } else if (obj->IsString()) { |
1985 ExtractString(entry, String::cast(obj)); | 1985 ExtractStringReferences(entry, String::cast(obj)); |
1986 extract_indexed_refs = false; | 1986 extract_indexed_refs = false; |
1987 } else if (obj->IsContext()) { | 1987 } else if (obj->IsContext()) { |
1988 ExtractContext(entry, Context::cast(obj)); | 1988 ExtractContextReferences(entry, Context::cast(obj)); |
1989 } else if (obj->IsMap()) { | 1989 } else if (obj->IsMap()) { |
1990 ExtractMap(entry, Map::cast(obj)); | 1990 ExtractMapReferences(entry, Map::cast(obj)); |
1991 } else if (obj->IsSharedFunctionInfo()) { | 1991 } else if (obj->IsSharedFunctionInfo()) { |
1992 ExtractSharedFunctionInfo(entry, SharedFunctionInfo::cast(obj)); | 1992 ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj)); |
1993 } else if (obj->IsScript()) { | 1993 } else if (obj->IsScript()) { |
1994 ExtractScript(entry, Script::cast(obj)); | 1994 ExtractScriptReferences(entry, Script::cast(obj)); |
1995 } else if (obj->IsCodeCache()) { | 1995 } else if (obj->IsCodeCache()) { |
1996 ExtractCodeCache(entry, CodeCache::cast(obj)); | 1996 ExtractCodeCacheReferences(entry, CodeCache::cast(obj)); |
1997 } else if (obj->IsCode()) { | 1997 } else if (obj->IsCode()) { |
1998 ExtractCode(entry, Code::cast(obj)); | 1998 ExtractCodeReferences(entry, Code::cast(obj)); |
| 1999 } else if (obj->IsJSGlobalPropertyCell()) { |
| 2000 ExtractJSGlobalPropertyCellReferences( |
| 2001 entry, JSGlobalPropertyCell::cast(obj)); |
| 2002 extract_indexed_refs = false; |
1999 } | 2003 } |
2000 if (extract_indexed_refs) { | 2004 if (extract_indexed_refs) { |
2001 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | 2005 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); |
2002 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 2006 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
2003 obj->Iterate(&refs_extractor); | 2007 obj->Iterate(&refs_extractor); |
2004 } | 2008 } |
2005 } | 2009 } |
2006 | 2010 |
2007 | 2011 |
2008 void V8HeapExplorer::ExtractJSGlobalProxy(JSGlobalProxy* proxy) { | 2012 void V8HeapExplorer::ExtractJSGlobalProxyReferences(JSGlobalProxy* proxy) { |
2009 // We need to reference JS global objects from snapshot's root. | 2013 // We need to reference JS global objects from snapshot's root. |
2010 // We use JSGlobalProxy because this is what embedder (e.g. browser) | 2014 // We use JSGlobalProxy because this is what embedder (e.g. browser) |
2011 // uses for the global object. | 2015 // uses for the global object. |
2012 Object* object = proxy->map()->prototype(); | 2016 Object* object = proxy->map()->prototype(); |
2013 bool is_debug_object = false; | 2017 bool is_debug_object = false; |
2014 #ifdef ENABLE_DEBUGGER_SUPPORT | 2018 #ifdef ENABLE_DEBUGGER_SUPPORT |
2015 is_debug_object = object->IsGlobalObject() && | 2019 is_debug_object = object->IsGlobalObject() && |
2016 Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object)); | 2020 Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object)); |
2017 #endif | 2021 #endif |
2018 if (!is_debug_object) { | 2022 if (!is_debug_object) { |
2019 SetUserGlobalReference(object); | 2023 SetUserGlobalReference(object); |
2020 } | 2024 } |
2021 } | 2025 } |
2022 | 2026 |
2023 | 2027 |
2024 void V8HeapExplorer::ExtractJSObject(HeapEntry* entry, JSObject* js_obj) { | 2028 void V8HeapExplorer::ExtractJSObjectReferences( |
| 2029 HeapEntry* entry, JSObject* js_obj) { |
2025 HeapObject* obj = js_obj; | 2030 HeapObject* obj = js_obj; |
2026 ExtractClosureReferences(js_obj, entry); | 2031 ExtractClosureReferences(js_obj, entry); |
2027 ExtractPropertyReferences(js_obj, entry); | 2032 ExtractPropertyReferences(js_obj, entry); |
2028 ExtractElementReferences(js_obj, entry); | 2033 ExtractElementReferences(js_obj, entry); |
2029 ExtractInternalReferences(js_obj, entry); | 2034 ExtractInternalReferences(js_obj, entry); |
2030 SetPropertyReference( | 2035 SetPropertyReference( |
2031 obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); | 2036 obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); |
2032 if (obj->IsJSFunction()) { | 2037 if (obj->IsJSFunction()) { |
2033 JSFunction* js_fun = JSFunction::cast(js_obj); | 2038 JSFunction* js_fun = JSFunction::cast(js_obj); |
2034 Object* proto_or_map = js_fun->prototype_or_initial_map(); | 2039 Object* proto_or_map = js_fun->prototype_or_initial_map(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2083 SetInternalReference(obj, entry, | 2088 SetInternalReference(obj, entry, |
2084 "properties", js_obj->properties(), | 2089 "properties", js_obj->properties(), |
2085 JSObject::kPropertiesOffset); | 2090 JSObject::kPropertiesOffset); |
2086 TagObject(js_obj->elements(), "(object elements)"); | 2091 TagObject(js_obj->elements(), "(object elements)"); |
2087 SetInternalReference(obj, entry, | 2092 SetInternalReference(obj, entry, |
2088 "elements", js_obj->elements(), | 2093 "elements", js_obj->elements(), |
2089 JSObject::kElementsOffset); | 2094 JSObject::kElementsOffset); |
2090 } | 2095 } |
2091 | 2096 |
2092 | 2097 |
2093 void V8HeapExplorer::ExtractString(HeapEntry* entry, String* string) { | 2098 void V8HeapExplorer::ExtractStringReferences(HeapEntry* entry, String* string) { |
2094 if (string->IsConsString()) { | 2099 if (string->IsConsString()) { |
2095 ConsString* cs = ConsString::cast(string); | 2100 ConsString* cs = ConsString::cast(string); |
2096 SetInternalReference(cs, entry, 1, cs->first()); | 2101 SetInternalReference(cs, entry, "first", cs->first()); |
2097 SetInternalReference(cs, entry, 2, cs->second()); | 2102 SetInternalReference(cs, entry, "second", cs->second()); |
2098 } | 2103 } else if (string->IsSlicedString()) { |
2099 if (string->IsSlicedString()) { | |
2100 SlicedString* ss = SlicedString::cast(string); | 2104 SlicedString* ss = SlicedString::cast(string); |
2101 SetInternalReference(ss, entry, "parent", ss->parent()); | 2105 SetInternalReference(ss, entry, "parent", ss->parent()); |
2102 } | 2106 } |
2103 } | 2107 } |
2104 | 2108 |
2105 | 2109 |
2106 void V8HeapExplorer::ExtractContext(HeapEntry* entry, Context* context) { | 2110 void V8HeapExplorer::ExtractContextReferences( |
| 2111 HeapEntry* entry, Context* context) { |
2107 #define EXTRACT_CONTEXT_FIELD(index, type, name) \ | 2112 #define EXTRACT_CONTEXT_FIELD(index, type, name) \ |
2108 SetInternalReference(context, entry, #name, context->get(Context::index), \ | 2113 SetInternalReference(context, entry, #name, context->get(Context::index), \ |
2109 FixedArray::OffsetOfElementAt(Context::index)); | 2114 FixedArray::OffsetOfElementAt(Context::index)); |
2110 EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); | 2115 EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); |
2111 EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); | 2116 EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); |
2112 EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); | 2117 EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); |
2113 EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global); | 2118 EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global); |
2114 if (context->IsGlobalContext()) { | 2119 if (context->IsGlobalContext()) { |
2115 TagObject(context->jsfunction_result_caches(), | 2120 TagObject(context->jsfunction_result_caches(), |
2116 "(context func. result caches)"); | 2121 "(context func. result caches)"); |
2117 TagObject(context->normalized_map_cache(), "(context norm. map cache)"); | 2122 TagObject(context->normalized_map_cache(), "(context norm. map cache)"); |
2118 TagObject(context->runtime_context(), "(runtime context)"); | 2123 TagObject(context->runtime_context(), "(runtime context)"); |
2119 TagObject(context->data(), "(context data)"); | 2124 TagObject(context->data(), "(context data)"); |
2120 GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); | 2125 GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); |
2121 #undef EXTRACT_CONTEXT_FIELD | 2126 #undef EXTRACT_CONTEXT_FIELD |
2122 for (int i = Context::FIRST_WEAK_SLOT; | 2127 for (int i = Context::FIRST_WEAK_SLOT; |
2123 i < Context::GLOBAL_CONTEXT_SLOTS; | 2128 i < Context::GLOBAL_CONTEXT_SLOTS; |
2124 ++i) { | 2129 ++i) { |
2125 SetWeakReference(context, entry, i, context->get(i), | 2130 SetWeakReference(context, entry, i, context->get(i), |
2126 FixedArray::OffsetOfElementAt(i)); | 2131 FixedArray::OffsetOfElementAt(i)); |
2127 } | 2132 } |
2128 } | 2133 } |
2129 } | 2134 } |
2130 | 2135 |
2131 | 2136 |
2132 void V8HeapExplorer::ExtractMap(HeapEntry* entry, Map* map) { | 2137 void V8HeapExplorer::ExtractMapReferences(HeapEntry* entry, Map* map) { |
2133 SetInternalReference(map, entry, | 2138 SetInternalReference(map, entry, |
2134 "prototype", map->prototype(), Map::kPrototypeOffset); | 2139 "prototype", map->prototype(), Map::kPrototypeOffset); |
2135 SetInternalReference(map, entry, | 2140 SetInternalReference(map, entry, |
2136 "constructor", map->constructor(), | 2141 "constructor", map->constructor(), |
2137 Map::kConstructorOffset); | 2142 Map::kConstructorOffset); |
2138 if (!map->instance_descriptors()->IsEmpty()) { | 2143 if (!map->instance_descriptors()->IsEmpty()) { |
2139 TagObject(map->instance_descriptors(), "(map descriptors)"); | 2144 TagObject(map->instance_descriptors(), "(map descriptors)"); |
2140 SetInternalReference(map, entry, | 2145 SetInternalReference(map, entry, |
2141 "descriptors", map->instance_descriptors(), | 2146 "descriptors", map->instance_descriptors(), |
2142 Map::kInstanceDescriptorsOrBitField3Offset); | 2147 Map::kInstanceDescriptorsOrBitField3Offset); |
2143 } | 2148 } |
2144 TagObject(map->prototype_transitions(), "(prototype transitions)"); | 2149 TagObject(map->prototype_transitions(), "(prototype transitions)"); |
2145 SetInternalReference(map, entry, | 2150 SetInternalReference(map, entry, |
2146 "prototype_transitions", map->prototype_transitions(), | 2151 "prototype_transitions", map->prototype_transitions(), |
2147 Map::kPrototypeTransitionsOffset); | 2152 Map::kPrototypeTransitionsOffset); |
2148 SetInternalReference(map, entry, | 2153 SetInternalReference(map, entry, |
2149 "code_cache", map->code_cache(), | 2154 "code_cache", map->code_cache(), |
2150 Map::kCodeCacheOffset); | 2155 Map::kCodeCacheOffset); |
2151 } | 2156 } |
2152 | 2157 |
2153 | 2158 |
2154 void V8HeapExplorer::ExtractSharedFunctionInfo( | 2159 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( |
2155 HeapEntry* entry, SharedFunctionInfo* shared) { | 2160 HeapEntry* entry, SharedFunctionInfo* shared) { |
2156 HeapObject* obj = shared; | 2161 HeapObject* obj = shared; |
2157 SetInternalReference(obj, entry, | 2162 SetInternalReference(obj, entry, |
2158 "name", shared->name(), | 2163 "name", shared->name(), |
2159 SharedFunctionInfo::kNameOffset); | 2164 SharedFunctionInfo::kNameOffset); |
2160 TagObject(shared->code(), "(code)"); | 2165 TagObject(shared->code(), "(code)"); |
2161 SetInternalReference(obj, entry, | 2166 SetInternalReference(obj, entry, |
2162 "code", shared->code(), | 2167 "code", shared->code(), |
2163 SharedFunctionInfo::kCodeOffset); | 2168 SharedFunctionInfo::kCodeOffset); |
2164 TagObject(shared->scope_info(), "(function scope info)"); | 2169 TagObject(shared->scope_info(), "(function scope info)"); |
(...skipping 22 matching lines...) Expand all Loading... |
2187 SetInternalReference(obj, entry, | 2192 SetInternalReference(obj, entry, |
2188 "this_property_assignments", | 2193 "this_property_assignments", |
2189 shared->this_property_assignments(), | 2194 shared->this_property_assignments(), |
2190 SharedFunctionInfo::kThisPropertyAssignmentsOffset); | 2195 SharedFunctionInfo::kThisPropertyAssignmentsOffset); |
2191 SetWeakReference(obj, entry, | 2196 SetWeakReference(obj, entry, |
2192 1, shared->initial_map(), | 2197 1, shared->initial_map(), |
2193 SharedFunctionInfo::kInitialMapOffset); | 2198 SharedFunctionInfo::kInitialMapOffset); |
2194 } | 2199 } |
2195 | 2200 |
2196 | 2201 |
2197 void V8HeapExplorer::ExtractScript(HeapEntry* entry, Script* script) { | 2202 void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry, Script* script) { |
2198 HeapObject* obj = script; | 2203 HeapObject* obj = script; |
2199 SetInternalReference(obj, entry, | 2204 SetInternalReference(obj, entry, |
2200 "source", script->source(), | 2205 "source", script->source(), |
2201 Script::kSourceOffset); | 2206 Script::kSourceOffset); |
2202 SetInternalReference(obj, entry, | 2207 SetInternalReference(obj, entry, |
2203 "name", script->name(), | 2208 "name", script->name(), |
2204 Script::kNameOffset); | 2209 Script::kNameOffset); |
2205 SetInternalReference(obj, entry, | 2210 SetInternalReference(obj, entry, |
2206 "data", script->data(), | 2211 "data", script->data(), |
2207 Script::kDataOffset); | 2212 Script::kDataOffset); |
2208 SetInternalReference(obj, entry, | 2213 SetInternalReference(obj, entry, |
2209 "context_data", script->context_data(), | 2214 "context_data", script->context_data(), |
2210 Script::kContextOffset); | 2215 Script::kContextOffset); |
2211 TagObject(script->line_ends(), "(script line ends)"); | 2216 TagObject(script->line_ends(), "(script line ends)"); |
2212 SetInternalReference(obj, entry, | 2217 SetInternalReference(obj, entry, |
2213 "line_ends", script->line_ends(), | 2218 "line_ends", script->line_ends(), |
2214 Script::kLineEndsOffset); | 2219 Script::kLineEndsOffset); |
2215 } | 2220 } |
2216 | 2221 |
2217 | 2222 |
2218 void V8HeapExplorer::ExtractCodeCache(HeapEntry* entry, CodeCache* code_cache) { | 2223 void V8HeapExplorer::ExtractCodeCacheReferences( |
| 2224 HeapEntry* entry, CodeCache* code_cache) { |
2219 TagObject(code_cache->default_cache(), "(default code cache)"); | 2225 TagObject(code_cache->default_cache(), "(default code cache)"); |
2220 SetInternalReference(code_cache, entry, | 2226 SetInternalReference(code_cache, entry, |
2221 "default_cache", code_cache->default_cache(), | 2227 "default_cache", code_cache->default_cache(), |
2222 CodeCache::kDefaultCacheOffset); | 2228 CodeCache::kDefaultCacheOffset); |
2223 TagObject(code_cache->normal_type_cache(), "(code type cache)"); | 2229 TagObject(code_cache->normal_type_cache(), "(code type cache)"); |
2224 SetInternalReference(code_cache, entry, | 2230 SetInternalReference(code_cache, entry, |
2225 "type_cache", code_cache->normal_type_cache(), | 2231 "type_cache", code_cache->normal_type_cache(), |
2226 CodeCache::kNormalTypeCacheOffset); | 2232 CodeCache::kNormalTypeCacheOffset); |
2227 } | 2233 } |
2228 | 2234 |
2229 | 2235 |
2230 void V8HeapExplorer::ExtractCode(HeapEntry* entry, Code* code) { | 2236 void V8HeapExplorer::ExtractCodeReferences(HeapEntry* entry, Code* code) { |
2231 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); | 2237 TagObject(code->relocation_info(), "(code relocation info)"); |
2232 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); | 2238 SetInternalReference(code, entry, |
| 2239 "relocation_info", code->relocation_info(), |
| 2240 Code::kRelocationInfoOffset); |
| 2241 SetInternalReference(code, entry, |
| 2242 "handler_table", code->handler_table(), |
| 2243 Code::kHandlerTableOffset); |
| 2244 TagObject(code->deoptimization_data(), "(code deopt data)"); |
| 2245 SetInternalReference(code, entry, |
| 2246 "deoptimization_data", code->deoptimization_data(), |
| 2247 Code::kDeoptimizationDataOffset); |
| 2248 SetInternalReference(code, entry, |
| 2249 "type_feedback_info", code->type_feedback_info(), |
| 2250 Code::kTypeFeedbackInfoOffset); |
| 2251 SetInternalReference(code, entry, |
| 2252 "gc_metadata", code->gc_metadata(), |
| 2253 Code::kGCMetadataOffset); |
2233 } | 2254 } |
2234 | 2255 |
2235 | 2256 |
| 2257 void V8HeapExplorer::ExtractJSGlobalPropertyCellReferences( |
| 2258 HeapEntry* entry, JSGlobalPropertyCell* cell) { |
| 2259 SetInternalReference(cell, entry, "value", cell->value()); |
| 2260 } |
| 2261 |
| 2262 |
2236 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, | 2263 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
2237 HeapEntry* entry) { | 2264 HeapEntry* entry) { |
2238 if (!js_obj->IsJSFunction()) return; | 2265 if (!js_obj->IsJSFunction()) return; |
2239 | 2266 |
2240 JSFunction* func = JSFunction::cast(js_obj); | 2267 JSFunction* func = JSFunction::cast(js_obj); |
2241 if (func->shared()->bound()) { | 2268 if (func->shared()->bound()) { |
2242 FixedArray* bindings = func->function_bindings(); | 2269 FixedArray* bindings = func->function_bindings(); |
2243 SetNativeBindReference(js_obj, entry, "bound_this", | 2270 SetNativeBindReference(js_obj, entry, "bound_this", |
2244 bindings->get(JSFunction::kBoundThisIndex)); | 2271 bindings->get(JSFunction::kBoundThisIndex)); |
2245 SetNativeBindReference(js_obj, entry, "bound_function", | 2272 SetNativeBindReference(js_obj, entry, "bound_function", |
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4018 | 4045 |
4019 | 4046 |
4020 void HeapSnapshotJSONSerializer::SortHashMap( | 4047 void HeapSnapshotJSONSerializer::SortHashMap( |
4021 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 4048 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
4022 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 4049 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
4023 sorted_entries->Add(p); | 4050 sorted_entries->Add(p); |
4024 sorted_entries->Sort(SortUsingEntryValue); | 4051 sorted_entries->Sort(SortUsingEntryValue); |
4025 } | 4052 } |
4026 | 4053 |
4027 } } // namespace v8::internal | 4054 } } // namespace v8::internal |
OLD | NEW |