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 // We need to reference JS global objects from snapshot's root. | 1981 ExtractJSGlobalProxy(JSGlobalProxy::cast(obj)); |
1982 // We use JSGlobalProxy because this is what embedder (e.g. browser) | |
1983 // uses for the global object. | |
1984 JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); | |
1985 Object* object = proxy->map()->prototype(); | |
1986 bool is_debug_object = false; | |
1987 #ifdef ENABLE_DEBUGGER_SUPPORT | |
1988 is_debug_object = object->IsGlobalObject() && | |
1989 Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object)); | |
1990 #endif | |
1991 if (!is_debug_object) { | |
1992 SetUserGlobalReference(object); | |
1993 } | |
1994 } else if (obj->IsJSObject()) { | 1982 } else if (obj->IsJSObject()) { |
1995 JSObject* js_obj = JSObject::cast(obj); | 1983 ExtractJSObject(entry, JSObject::cast(obj)); |
1996 ExtractClosureReferences(js_obj, entry); | |
1997 ExtractPropertyReferences(js_obj, entry); | |
1998 ExtractElementReferences(js_obj, entry); | |
1999 ExtractInternalReferences(js_obj, entry); | |
2000 SetPropertyReference( | |
2001 obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); | |
2002 if (obj->IsJSFunction()) { | |
2003 JSFunction* js_fun = JSFunction::cast(js_obj); | |
2004 Object* proto_or_map = js_fun->prototype_or_initial_map(); | |
2005 if (!proto_or_map->IsTheHole()) { | |
2006 if (!proto_or_map->IsMap()) { | |
2007 SetPropertyReference( | |
2008 obj, entry, | |
2009 heap_->prototype_symbol(), proto_or_map, | |
2010 NULL, | |
2011 JSFunction::kPrototypeOrInitialMapOffset); | |
2012 } else { | |
2013 SetPropertyReference( | |
2014 obj, entry, | |
2015 heap_->prototype_symbol(), js_fun->prototype()); | |
2016 } | |
2017 } | |
2018 SharedFunctionInfo* shared_info = js_fun->shared(); | |
2019 // JSFunction has either bindings or literals and never both. | |
2020 bool bound = shared_info->bound(); | |
2021 TagObject(js_fun->literals_or_bindings(), | |
2022 bound ? "(function bindings)" : "(function literals)"); | |
2023 SetInternalReference(js_fun, entry, | |
2024 bound ? "bindings" : "literals", | |
2025 js_fun->literals_or_bindings(), | |
2026 JSFunction::kLiteralsOffset); | |
2027 TagObject(shared_info, "(shared function info)"); | |
2028 SetInternalReference(js_fun, entry, | |
2029 "shared", shared_info, | |
2030 JSFunction::kSharedFunctionInfoOffset); | |
2031 TagObject(js_fun->unchecked_context(), "(context)"); | |
2032 SetInternalReference(js_fun, entry, | |
2033 "context", js_fun->unchecked_context(), | |
2034 JSFunction::kContextOffset); | |
2035 for (int i = JSFunction::kNonWeakFieldsEndOffset; | |
2036 i < JSFunction::kSize; | |
2037 i += kPointerSize) { | |
2038 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); | |
2039 } | |
2040 } else if (obj->IsGlobalObject()) { | |
2041 GlobalObject* global_obj = GlobalObject::cast(obj); | |
2042 SetInternalReference(global_obj, entry, | |
2043 "builtins", global_obj->builtins(), | |
2044 GlobalObject::kBuiltinsOffset); | |
2045 SetInternalReference(global_obj, entry, | |
2046 "global_context", global_obj->global_context(), | |
2047 GlobalObject::kGlobalContextOffset); | |
2048 SetInternalReference(global_obj, entry, | |
2049 "global_receiver", global_obj->global_receiver(), | |
2050 GlobalObject::kGlobalReceiverOffset); | |
2051 } | |
2052 TagObject(js_obj->properties(), "(object properties)"); | |
2053 SetInternalReference(obj, entry, | |
2054 "properties", js_obj->properties(), | |
2055 JSObject::kPropertiesOffset); | |
2056 TagObject(js_obj->elements(), "(object elements)"); | |
2057 SetInternalReference(obj, entry, | |
2058 "elements", js_obj->elements(), | |
2059 JSObject::kElementsOffset); | |
2060 } else if (obj->IsString()) { | 1984 } else if (obj->IsString()) { |
2061 if (obj->IsConsString()) { | 1985 ExtractString(entry, String::cast(obj)); |
2062 ConsString* cs = ConsString::cast(obj); | |
2063 SetInternalReference(obj, entry, 1, cs->first()); | |
2064 SetInternalReference(obj, entry, 2, cs->second()); | |
2065 } | |
2066 if (obj->IsSlicedString()) { | |
2067 SlicedString* ss = SlicedString::cast(obj); | |
2068 SetInternalReference(obj, entry, "parent", ss->parent()); | |
2069 } | |
2070 extract_indexed_refs = false; | 1986 extract_indexed_refs = false; |
2071 } else if (obj->IsContext()) { | 1987 } else if (obj->IsContext()) { |
2072 Context* context = Context::cast(obj); | 1988 ExtractContext(entry, Context::cast(obj)); |
2073 #define EXTRACT_CONTEXT_FIELD(index, type, name) \ | |
2074 SetInternalReference(context, entry, #name, context->get(Context::index), \ | |
2075 FixedArray::OffsetOfElementAt(Context::index)); | |
2076 EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); | |
2077 EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); | |
2078 EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); | |
2079 EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global); | |
2080 if (obj->IsGlobalContext()) { | |
2081 TagObject(context->jsfunction_result_caches(), | |
2082 "(context func. result caches)"); | |
2083 TagObject(context->normalized_map_cache(), "(context norm. map cache)"); | |
2084 TagObject(context->runtime_context(), "(runtime context)"); | |
2085 TagObject(context->data(), "(context data)"); | |
2086 GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); | |
2087 #undef EXTRACT_CONTEXT_FIELD | |
2088 for (int i = Context::FIRST_WEAK_SLOT; | |
2089 i < Context::GLOBAL_CONTEXT_SLOTS; | |
2090 ++i) { | |
2091 SetWeakReference(obj, entry, | |
2092 i, context->get(i), | |
2093 FixedArray::OffsetOfElementAt(i)); | |
2094 } | |
2095 } | |
2096 } else if (obj->IsMap()) { | 1989 } else if (obj->IsMap()) { |
2097 Map* map = Map::cast(obj); | 1990 ExtractMap(entry, Map::cast(obj)); |
2098 SetInternalReference(obj, entry, | |
2099 "prototype", map->prototype(), Map::kPrototypeOffset); | |
2100 SetInternalReference(obj, entry, | |
2101 "constructor", map->constructor(), | |
2102 Map::kConstructorOffset); | |
2103 if (!map->instance_descriptors()->IsEmpty()) { | |
2104 TagObject(map->instance_descriptors(), "(map descriptors)"); | |
2105 SetInternalReference(obj, entry, | |
2106 "descriptors", map->instance_descriptors(), | |
2107 Map::kInstanceDescriptorsOrBitField3Offset); | |
2108 } | |
2109 TagObject(map->prototype_transitions(), "(prototype transitions)"); | |
2110 SetInternalReference(obj, entry, | |
2111 "prototype_transitions", map->prototype_transitions(), | |
2112 Map::kPrototypeTransitionsOffset); | |
2113 SetInternalReference(obj, entry, | |
2114 "code_cache", map->code_cache(), | |
2115 Map::kCodeCacheOffset); | |
2116 } else if (obj->IsSharedFunctionInfo()) { | 1991 } else if (obj->IsSharedFunctionInfo()) { |
2117 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 1992 ExtractSharedFunctionInfo(entry, SharedFunctionInfo::cast(obj)); |
2118 SetInternalReference(obj, entry, | |
2119 "name", shared->name(), | |
2120 SharedFunctionInfo::kNameOffset); | |
2121 TagObject(shared->code(), "(code)"); | |
2122 SetInternalReference(obj, entry, | |
2123 "code", shared->code(), | |
2124 SharedFunctionInfo::kCodeOffset); | |
2125 TagObject(shared->scope_info(), "(function scope info)"); | |
2126 SetInternalReference(obj, entry, | |
2127 "scope_info", shared->scope_info(), | |
2128 SharedFunctionInfo::kScopeInfoOffset); | |
2129 SetInternalReference(obj, entry, | |
2130 "instance_class_name", shared->instance_class_name(), | |
2131 SharedFunctionInfo::kInstanceClassNameOffset); | |
2132 SetInternalReference(obj, entry, | |
2133 "script", shared->script(), | |
2134 SharedFunctionInfo::kScriptOffset); | |
2135 TagObject(shared->construct_stub(), "(code)"); | |
2136 SetInternalReference(obj, entry, | |
2137 "construct_stub", shared->construct_stub(), | |
2138 SharedFunctionInfo::kConstructStubOffset); | |
2139 SetInternalReference(obj, entry, | |
2140 "function_data", shared->function_data(), | |
2141 SharedFunctionInfo::kFunctionDataOffset); | |
2142 SetInternalReference(obj, entry, | |
2143 "debug_info", shared->debug_info(), | |
2144 SharedFunctionInfo::kDebugInfoOffset); | |
2145 SetInternalReference(obj, entry, | |
2146 "inferred_name", shared->inferred_name(), | |
2147 SharedFunctionInfo::kInferredNameOffset); | |
2148 SetInternalReference(obj, entry, | |
2149 "this_property_assignments", | |
2150 shared->this_property_assignments(), | |
2151 SharedFunctionInfo::kThisPropertyAssignmentsOffset); | |
2152 SetWeakReference(obj, entry, | |
2153 1, shared->initial_map(), | |
2154 SharedFunctionInfo::kInitialMapOffset); | |
2155 } else if (obj->IsScript()) { | 1993 } else if (obj->IsScript()) { |
2156 Script* script = Script::cast(obj); | 1994 ExtractScript(entry, Script::cast(obj)); |
2157 SetInternalReference(obj, entry, | |
2158 "source", script->source(), | |
2159 Script::kSourceOffset); | |
2160 SetInternalReference(obj, entry, | |
2161 "name", script->name(), | |
2162 Script::kNameOffset); | |
2163 SetInternalReference(obj, entry, | |
2164 "data", script->data(), | |
2165 Script::kDataOffset); | |
2166 SetInternalReference(obj, entry, | |
2167 "context_data", script->context_data(), | |
2168 Script::kContextOffset); | |
2169 TagObject(script->line_ends(), "(script line ends)"); | |
2170 SetInternalReference(obj, entry, | |
2171 "line_ends", script->line_ends(), | |
2172 Script::kLineEndsOffset); | |
2173 } else if (obj->IsCodeCache()) { | 1995 } else if (obj->IsCodeCache()) { |
2174 CodeCache* code_cache = CodeCache::cast(obj); | 1996 ExtractCodeCache(entry, CodeCache::cast(obj)); |
2175 TagObject(code_cache->default_cache(), "(default code cache)"); | |
2176 SetInternalReference(obj, entry, | |
2177 "default_cache", code_cache->default_cache(), | |
2178 CodeCache::kDefaultCacheOffset); | |
2179 TagObject(code_cache->normal_type_cache(), "(code type cache)"); | |
2180 SetInternalReference(obj, entry, | |
2181 "type_cache", code_cache->normal_type_cache(), | |
2182 CodeCache::kNormalTypeCacheOffset); | |
2183 } else if (obj->IsCode()) { | 1997 } else if (obj->IsCode()) { |
2184 Code* code = Code::cast(obj); | 1998 ExtractCode(entry, Code::cast(obj)); |
2185 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); | |
2186 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); | |
2187 } | 1999 } |
2188 if (extract_indexed_refs) { | 2000 if (extract_indexed_refs) { |
2189 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); | 2001 SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset); |
2190 IndexedReferencesExtractor refs_extractor(this, obj, entry); | 2002 IndexedReferencesExtractor refs_extractor(this, obj, entry); |
2191 obj->Iterate(&refs_extractor); | 2003 obj->Iterate(&refs_extractor); |
2192 } | 2004 } |
2193 } | 2005 } |
2194 | 2006 |
2195 | 2007 |
| 2008 void V8HeapExplorer::ExtractJSGlobalProxy(JSGlobalProxy* proxy) { |
| 2009 // We need to reference JS global objects from snapshot's root. |
| 2010 // We use JSGlobalProxy because this is what embedder (e.g. browser) |
| 2011 // uses for the global object. |
| 2012 Object* object = proxy->map()->prototype(); |
| 2013 bool is_debug_object = false; |
| 2014 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 2015 is_debug_object = object->IsGlobalObject() && |
| 2016 Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object)); |
| 2017 #endif |
| 2018 if (!is_debug_object) { |
| 2019 SetUserGlobalReference(object); |
| 2020 } |
| 2021 } |
| 2022 |
| 2023 |
| 2024 void V8HeapExplorer::ExtractJSObject(HeapEntry* entry, JSObject* js_obj) { |
| 2025 HeapObject* obj = js_obj; |
| 2026 ExtractClosureReferences(js_obj, entry); |
| 2027 ExtractPropertyReferences(js_obj, entry); |
| 2028 ExtractElementReferences(js_obj, entry); |
| 2029 ExtractInternalReferences(js_obj, entry); |
| 2030 SetPropertyReference( |
| 2031 obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype()); |
| 2032 if (obj->IsJSFunction()) { |
| 2033 JSFunction* js_fun = JSFunction::cast(js_obj); |
| 2034 Object* proto_or_map = js_fun->prototype_or_initial_map(); |
| 2035 if (!proto_or_map->IsTheHole()) { |
| 2036 if (!proto_or_map->IsMap()) { |
| 2037 SetPropertyReference( |
| 2038 obj, entry, |
| 2039 heap_->prototype_symbol(), proto_or_map, |
| 2040 NULL, |
| 2041 JSFunction::kPrototypeOrInitialMapOffset); |
| 2042 } else { |
| 2043 SetPropertyReference( |
| 2044 obj, entry, |
| 2045 heap_->prototype_symbol(), js_fun->prototype()); |
| 2046 } |
| 2047 } |
| 2048 SharedFunctionInfo* shared_info = js_fun->shared(); |
| 2049 // JSFunction has either bindings or literals and never both. |
| 2050 bool bound = shared_info->bound(); |
| 2051 TagObject(js_fun->literals_or_bindings(), |
| 2052 bound ? "(function bindings)" : "(function literals)"); |
| 2053 SetInternalReference(js_fun, entry, |
| 2054 bound ? "bindings" : "literals", |
| 2055 js_fun->literals_or_bindings(), |
| 2056 JSFunction::kLiteralsOffset); |
| 2057 TagObject(shared_info, "(shared function info)"); |
| 2058 SetInternalReference(js_fun, entry, |
| 2059 "shared", shared_info, |
| 2060 JSFunction::kSharedFunctionInfoOffset); |
| 2061 TagObject(js_fun->unchecked_context(), "(context)"); |
| 2062 SetInternalReference(js_fun, entry, |
| 2063 "context", js_fun->unchecked_context(), |
| 2064 JSFunction::kContextOffset); |
| 2065 for (int i = JSFunction::kNonWeakFieldsEndOffset; |
| 2066 i < JSFunction::kSize; |
| 2067 i += kPointerSize) { |
| 2068 SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); |
| 2069 } |
| 2070 } else if (obj->IsGlobalObject()) { |
| 2071 GlobalObject* global_obj = GlobalObject::cast(obj); |
| 2072 SetInternalReference(global_obj, entry, |
| 2073 "builtins", global_obj->builtins(), |
| 2074 GlobalObject::kBuiltinsOffset); |
| 2075 SetInternalReference(global_obj, entry, |
| 2076 "global_context", global_obj->global_context(), |
| 2077 GlobalObject::kGlobalContextOffset); |
| 2078 SetInternalReference(global_obj, entry, |
| 2079 "global_receiver", global_obj->global_receiver(), |
| 2080 GlobalObject::kGlobalReceiverOffset); |
| 2081 } |
| 2082 TagObject(js_obj->properties(), "(object properties)"); |
| 2083 SetInternalReference(obj, entry, |
| 2084 "properties", js_obj->properties(), |
| 2085 JSObject::kPropertiesOffset); |
| 2086 TagObject(js_obj->elements(), "(object elements)"); |
| 2087 SetInternalReference(obj, entry, |
| 2088 "elements", js_obj->elements(), |
| 2089 JSObject::kElementsOffset); |
| 2090 } |
| 2091 |
| 2092 |
| 2093 void V8HeapExplorer::ExtractString(HeapEntry* entry, String* string) { |
| 2094 if (string->IsConsString()) { |
| 2095 ConsString* cs = ConsString::cast(string); |
| 2096 SetInternalReference(cs, entry, 1, cs->first()); |
| 2097 SetInternalReference(cs, entry, 2, cs->second()); |
| 2098 } |
| 2099 if (string->IsSlicedString()) { |
| 2100 SlicedString* ss = SlicedString::cast(string); |
| 2101 SetInternalReference(ss, entry, "parent", ss->parent()); |
| 2102 } |
| 2103 } |
| 2104 |
| 2105 |
| 2106 void V8HeapExplorer::ExtractContext(HeapEntry* entry, Context* context) { |
| 2107 #define EXTRACT_CONTEXT_FIELD(index, type, name) \ |
| 2108 SetInternalReference(context, entry, #name, context->get(Context::index), \ |
| 2109 FixedArray::OffsetOfElementAt(Context::index)); |
| 2110 EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); |
| 2111 EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); |
| 2112 EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); |
| 2113 EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global); |
| 2114 if (context->IsGlobalContext()) { |
| 2115 TagObject(context->jsfunction_result_caches(), |
| 2116 "(context func. result caches)"); |
| 2117 TagObject(context->normalized_map_cache(), "(context norm. map cache)"); |
| 2118 TagObject(context->runtime_context(), "(runtime context)"); |
| 2119 TagObject(context->data(), "(context data)"); |
| 2120 GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); |
| 2121 #undef EXTRACT_CONTEXT_FIELD |
| 2122 for (int i = Context::FIRST_WEAK_SLOT; |
| 2123 i < Context::GLOBAL_CONTEXT_SLOTS; |
| 2124 ++i) { |
| 2125 SetWeakReference(context, entry, i, context->get(i), |
| 2126 FixedArray::OffsetOfElementAt(i)); |
| 2127 } |
| 2128 } |
| 2129 } |
| 2130 |
| 2131 |
| 2132 void V8HeapExplorer::ExtractMap(HeapEntry* entry, Map* map) { |
| 2133 SetInternalReference(map, entry, |
| 2134 "prototype", map->prototype(), Map::kPrototypeOffset); |
| 2135 SetInternalReference(map, entry, |
| 2136 "constructor", map->constructor(), |
| 2137 Map::kConstructorOffset); |
| 2138 if (!map->instance_descriptors()->IsEmpty()) { |
| 2139 TagObject(map->instance_descriptors(), "(map descriptors)"); |
| 2140 SetInternalReference(map, entry, |
| 2141 "descriptors", map->instance_descriptors(), |
| 2142 Map::kInstanceDescriptorsOrBitField3Offset); |
| 2143 } |
| 2144 TagObject(map->prototype_transitions(), "(prototype transitions)"); |
| 2145 SetInternalReference(map, entry, |
| 2146 "prototype_transitions", map->prototype_transitions(), |
| 2147 Map::kPrototypeTransitionsOffset); |
| 2148 SetInternalReference(map, entry, |
| 2149 "code_cache", map->code_cache(), |
| 2150 Map::kCodeCacheOffset); |
| 2151 } |
| 2152 |
| 2153 |
| 2154 void V8HeapExplorer::ExtractSharedFunctionInfo( |
| 2155 HeapEntry* entry, SharedFunctionInfo* shared) { |
| 2156 HeapObject* obj = shared; |
| 2157 SetInternalReference(obj, entry, |
| 2158 "name", shared->name(), |
| 2159 SharedFunctionInfo::kNameOffset); |
| 2160 TagObject(shared->code(), "(code)"); |
| 2161 SetInternalReference(obj, entry, |
| 2162 "code", shared->code(), |
| 2163 SharedFunctionInfo::kCodeOffset); |
| 2164 TagObject(shared->scope_info(), "(function scope info)"); |
| 2165 SetInternalReference(obj, entry, |
| 2166 "scope_info", shared->scope_info(), |
| 2167 SharedFunctionInfo::kScopeInfoOffset); |
| 2168 SetInternalReference(obj, entry, |
| 2169 "instance_class_name", shared->instance_class_name(), |
| 2170 SharedFunctionInfo::kInstanceClassNameOffset); |
| 2171 SetInternalReference(obj, entry, |
| 2172 "script", shared->script(), |
| 2173 SharedFunctionInfo::kScriptOffset); |
| 2174 TagObject(shared->construct_stub(), "(code)"); |
| 2175 SetInternalReference(obj, entry, |
| 2176 "construct_stub", shared->construct_stub(), |
| 2177 SharedFunctionInfo::kConstructStubOffset); |
| 2178 SetInternalReference(obj, entry, |
| 2179 "function_data", shared->function_data(), |
| 2180 SharedFunctionInfo::kFunctionDataOffset); |
| 2181 SetInternalReference(obj, entry, |
| 2182 "debug_info", shared->debug_info(), |
| 2183 SharedFunctionInfo::kDebugInfoOffset); |
| 2184 SetInternalReference(obj, entry, |
| 2185 "inferred_name", shared->inferred_name(), |
| 2186 SharedFunctionInfo::kInferredNameOffset); |
| 2187 SetInternalReference(obj, entry, |
| 2188 "this_property_assignments", |
| 2189 shared->this_property_assignments(), |
| 2190 SharedFunctionInfo::kThisPropertyAssignmentsOffset); |
| 2191 SetWeakReference(obj, entry, |
| 2192 1, shared->initial_map(), |
| 2193 SharedFunctionInfo::kInitialMapOffset); |
| 2194 } |
| 2195 |
| 2196 |
| 2197 void V8HeapExplorer::ExtractScript(HeapEntry* entry, Script* script) { |
| 2198 HeapObject* obj = script; |
| 2199 SetInternalReference(obj, entry, |
| 2200 "source", script->source(), |
| 2201 Script::kSourceOffset); |
| 2202 SetInternalReference(obj, entry, |
| 2203 "name", script->name(), |
| 2204 Script::kNameOffset); |
| 2205 SetInternalReference(obj, entry, |
| 2206 "data", script->data(), |
| 2207 Script::kDataOffset); |
| 2208 SetInternalReference(obj, entry, |
| 2209 "context_data", script->context_data(), |
| 2210 Script::kContextOffset); |
| 2211 TagObject(script->line_ends(), "(script line ends)"); |
| 2212 SetInternalReference(obj, entry, |
| 2213 "line_ends", script->line_ends(), |
| 2214 Script::kLineEndsOffset); |
| 2215 } |
| 2216 |
| 2217 |
| 2218 void V8HeapExplorer::ExtractCodeCache(HeapEntry* entry, CodeCache* code_cache) { |
| 2219 TagObject(code_cache->default_cache(), "(default code cache)"); |
| 2220 SetInternalReference(code_cache, entry, |
| 2221 "default_cache", code_cache->default_cache(), |
| 2222 CodeCache::kDefaultCacheOffset); |
| 2223 TagObject(code_cache->normal_type_cache(), "(code type cache)"); |
| 2224 SetInternalReference(code_cache, entry, |
| 2225 "type_cache", code_cache->normal_type_cache(), |
| 2226 CodeCache::kNormalTypeCacheOffset); |
| 2227 } |
| 2228 |
| 2229 |
| 2230 void V8HeapExplorer::ExtractCode(HeapEntry* entry, Code* code) { |
| 2231 TagObject(code->unchecked_relocation_info(), "(code relocation info)"); |
| 2232 TagObject(code->unchecked_deoptimization_data(), "(code deopt data)"); |
| 2233 } |
| 2234 |
| 2235 |
2196 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, | 2236 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, |
2197 HeapEntry* entry) { | 2237 HeapEntry* entry) { |
2198 if (!js_obj->IsJSFunction()) return; | 2238 if (!js_obj->IsJSFunction()) return; |
2199 | 2239 |
2200 JSFunction* func = JSFunction::cast(js_obj); | 2240 JSFunction* func = JSFunction::cast(js_obj); |
2201 if (func->shared()->bound()) { | 2241 if (func->shared()->bound()) { |
2202 FixedArray* bindings = func->function_bindings(); | 2242 FixedArray* bindings = func->function_bindings(); |
2203 SetNativeBindReference(js_obj, entry, "bound_this", | 2243 SetNativeBindReference(js_obj, entry, "bound_this", |
2204 bindings->get(JSFunction::kBoundThisIndex)); | 2244 bindings->get(JSFunction::kBoundThisIndex)); |
2205 SetNativeBindReference(js_obj, entry, "bound_function", | 2245 SetNativeBindReference(js_obj, entry, "bound_function", |
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3978 | 4018 |
3979 | 4019 |
3980 void HeapSnapshotJSONSerializer::SortHashMap( | 4020 void HeapSnapshotJSONSerializer::SortHashMap( |
3981 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 4021 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3982 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 4022 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3983 sorted_entries->Add(p); | 4023 sorted_entries->Add(p); |
3984 sorted_entries->Sort(SortUsingEntryValue); | 4024 sorted_entries->Sort(SortUsingEntryValue); |
3985 } | 4025 } |
3986 | 4026 |
3987 } } // namespace v8::internal | 4027 } } // namespace v8::internal |
OLD | NEW |