OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/object-stats.h" | 5 #include "src/heap/object-stats.h" |
6 | 6 |
7 #include "src/counters.h" | 7 #include "src/counters.h" |
8 #include "src/heap/heap-inl.h" | 8 #include "src/heap/heap-inl.h" |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
| 10 #include "src/macro-assembler.h" |
10 #include "src/utils.h" | 11 #include "src/utils.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 static base::LazyMutex object_stats_mutex = LAZY_MUTEX_INITIALIZER; | 16 static base::LazyMutex object_stats_mutex = LAZY_MUTEX_INITIALIZER; |
16 | 17 |
17 | 18 |
18 void ObjectStats::ClearObjectStats(bool clear_last_time_stats) { | 19 void ObjectStats::ClearObjectStats(bool clear_last_time_stats) { |
19 memset(object_counts_, 0, sizeof(object_counts_)); | 20 memset(object_counts_, 0, sizeof(object_counts_)); |
20 memset(object_sizes_, 0, sizeof(object_sizes_)); | 21 memset(object_sizes_, 0, sizeof(object_sizes_)); |
21 memset(over_allocated_, 0, sizeof(over_allocated_)); | 22 memset(over_allocated_, 0, sizeof(over_allocated_)); |
22 memset(size_histogram_, 0, sizeof(size_histogram_)); | 23 memset(size_histogram_, 0, sizeof(size_histogram_)); |
23 memset(over_allocated_histogram_, 0, sizeof(over_allocated_histogram_)); | 24 memset(over_allocated_histogram_, 0, sizeof(over_allocated_histogram_)); |
24 if (clear_last_time_stats) { | 25 if (clear_last_time_stats) { |
25 memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_)); | 26 memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_)); |
26 memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_)); | 27 memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_)); |
27 } | 28 } |
| 29 visited_fixed_array_sub_types_.clear(); |
28 } | 30 } |
29 | 31 |
30 static void PrintJSONArray(size_t* array, const int len) { | 32 static void PrintJSONArray(size_t* array, const int len) { |
31 PrintF("[ "); | 33 PrintF("[ "); |
32 for (int i = 0; i < len; i++) { | 34 for (int i = 0; i < len; i++) { |
33 PrintF("%zu", array[i]); | 35 PrintF("%zu", array[i]); |
34 if (i != (len - 1)) PrintF(", "); | 36 if (i != (len - 1)) PrintF(", "); |
35 } | 37 } |
36 PrintF(" ]"); | 38 PrintF(" ]"); |
37 } | 39 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 182 } |
181 if (obj->IsFixedArray()) { | 183 if (obj->IsFixedArray()) { |
182 RecordFixedArrayDetails(stats, heap, obj); | 184 RecordFixedArrayDetails(stats, heap, obj); |
183 } | 185 } |
184 if (obj->IsJSObject()) { | 186 if (obj->IsJSObject()) { |
185 RecordJSObjectDetails(stats, heap, JSObject::cast(obj)); | 187 RecordJSObjectDetails(stats, heap, JSObject::cast(obj)); |
186 } | 188 } |
187 if (obj->IsJSWeakCollection()) { | 189 if (obj->IsJSWeakCollection()) { |
188 RecordJSWeakCollectionDetails(stats, heap, JSWeakCollection::cast(obj)); | 190 RecordJSWeakCollectionDetails(stats, heap, JSWeakCollection::cast(obj)); |
189 } | 191 } |
| 192 if (obj->IsScript()) { |
| 193 RecordScriptDetails(stats, heap, Script::cast(obj)); |
| 194 } |
190 } | 195 } |
191 | 196 |
192 static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) { | 197 static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) { |
193 return array->map() != heap->fixed_cow_array_map() && | 198 return array->map()->instance_type() == FIXED_ARRAY_TYPE && |
| 199 array->map() != heap->fixed_cow_array_map() && |
194 array->map() != heap->fixed_double_array_map() && | 200 array->map() != heap->fixed_double_array_map() && |
195 array != heap->empty_fixed_array(); | 201 array != heap->empty_fixed_array() && |
| 202 array != heap->empty_byte_array() && |
| 203 array != heap->empty_literals_array() && |
| 204 array != heap->empty_sloppy_arguments_elements() && |
| 205 array != heap->empty_slow_element_dictionary() && |
| 206 array != heap->empty_descriptor_array() && |
| 207 array != heap->empty_properties_dictionary(); |
| 208 } |
| 209 |
| 210 static bool SameLiveness(HeapObject* obj1, HeapObject* obj2) { |
| 211 return ObjectMarking::Color(obj1) == ObjectMarking::Color(obj2); |
| 212 } |
| 213 |
| 214 void ObjectStatsCollector::RecordFixedArrayHelper( |
| 215 ObjectStats* stats, Heap* heap, HeapObject* parent, FixedArray* array, |
| 216 int subtype, size_t overhead) { |
| 217 if (SameLiveness(parent, array) && CanRecordFixedArray(heap, array)) { |
| 218 stats->RecordFixedArraySubTypeStats(array, subtype, array->Size(), |
| 219 overhead); |
| 220 } |
196 } | 221 } |
197 | 222 |
198 void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap, | 223 void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap, |
199 JSObject* object) { | 224 JSObject* object) { |
200 DCHECK(object->IsJSObject()); | 225 DCHECK(object->IsJSObject()); |
201 | 226 |
202 size_t overhead = 0; | 227 size_t overhead = 0; |
203 FixedArrayBase* elements = object->elements(); | 228 FixedArrayBase* elements = object->elements(); |
204 if (CanRecordFixedArray(heap, elements)) { | 229 if (CanRecordFixedArray(heap, elements)) { |
205 if (elements->IsDictionary()) { | 230 if (elements->IsDictionary() && SameLiveness(object, elements)) { |
206 SeededNumberDictionary* dict = object->element_dictionary(); | 231 SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements); |
207 int used = dict->NumberOfElements() * SeededNumberDictionary::kEntrySize; | 232 int used = dict->NumberOfElements() * SeededNumberDictionary::kEntrySize; |
208 CHECK_GE(elements->Size(), used); | 233 CHECK_GE(elements->Size(), used); |
209 overhead = elements->Size() - used; | 234 overhead = elements->Size() - used; |
210 stats->RecordFixedArraySubTypeStats(DICTIONARY_ELEMENTS_SUB_TYPE, | 235 stats->RecordFixedArraySubTypeStats( |
211 elements->Size(), overhead); | 236 elements, DICTIONARY_ELEMENTS_SUB_TYPE, elements->Size(), overhead); |
212 } else { | 237 } else { |
213 if (IsFastHoleyElementsKind(object->GetElementsKind())) { | 238 if (IsFastHoleyElementsKind(object->GetElementsKind())) { |
214 int used = object->GetFastElementsUsage() * kPointerSize; | 239 int used = object->GetFastElementsUsage() * kPointerSize; |
215 if (object->GetElementsKind() == FAST_HOLEY_DOUBLE_ELEMENTS) used *= 2; | 240 if (object->GetElementsKind() == FAST_HOLEY_DOUBLE_ELEMENTS) used *= 2; |
216 CHECK_GE(elements->Size(), used); | 241 CHECK_GE(elements->Size(), used); |
217 overhead = elements->Size() - used; | 242 overhead = elements->Size() - used; |
218 } | 243 } |
219 stats->RecordFixedArraySubTypeStats(FAST_ELEMENTS_SUB_TYPE, | 244 stats->RecordFixedArraySubTypeStats(elements, FAST_ELEMENTS_SUB_TYPE, |
220 elements->Size(), overhead); | 245 elements->Size(), overhead); |
221 } | 246 } |
222 } | 247 } |
223 | 248 |
224 overhead = 0; | 249 overhead = 0; |
225 FixedArrayBase* properties = object->properties(); | 250 FixedArrayBase* properties = object->properties(); |
226 if (CanRecordFixedArray(heap, properties)) { | 251 if (CanRecordFixedArray(heap, properties) && |
| 252 SameLiveness(object, properties)) { |
227 if (properties->IsDictionary()) { | 253 if (properties->IsDictionary()) { |
228 NameDictionary* dict = object->property_dictionary(); | 254 NameDictionary* dict = NameDictionary::cast(properties); |
229 int used = dict->NumberOfElements() * NameDictionary::kEntrySize; | 255 int used = dict->NumberOfElements() * NameDictionary::kEntrySize; |
230 CHECK_GE(properties->Size(), used); | 256 CHECK_GE(properties->Size(), used); |
231 overhead = properties->Size() - used; | 257 overhead = properties->Size() - used; |
232 stats->RecordFixedArraySubTypeStats(DICTIONARY_PROPERTIES_SUB_TYPE, | 258 stats->RecordFixedArraySubTypeStats(properties, |
| 259 DICTIONARY_PROPERTIES_SUB_TYPE, |
233 properties->Size(), overhead); | 260 properties->Size(), overhead); |
234 } else { | 261 } else { |
235 stats->RecordFixedArraySubTypeStats(FAST_PROPERTIES_SUB_TYPE, | 262 stats->RecordFixedArraySubTypeStats(properties, FAST_PROPERTIES_SUB_TYPE, |
236 properties->Size(), overhead); | 263 properties->Size(), overhead); |
237 } | 264 } |
238 } | 265 } |
239 } | 266 } |
240 | 267 |
241 void ObjectStatsCollector::RecordJSWeakCollectionDetails( | 268 void ObjectStatsCollector::RecordJSWeakCollectionDetails( |
242 ObjectStats* stats, Heap* heap, JSWeakCollection* obj) { | 269 ObjectStats* stats, Heap* heap, JSWeakCollection* obj) { |
243 if (obj->table()->IsHashTable()) { | 270 if (obj->table()->IsHashTable()) { |
244 ObjectHashTable* table = ObjectHashTable::cast(obj->table()); | 271 ObjectHashTable* table = ObjectHashTable::cast(obj->table()); |
245 int used = table->NumberOfElements() * ObjectHashTable::kEntrySize; | 272 int used = table->NumberOfElements() * ObjectHashTable::kEntrySize; |
246 size_t overhead = table->Size() - used; | 273 size_t overhead = table->Size() - used; |
247 stats->RecordFixedArraySubTypeStats(WEAK_COLLECTION_SUB_TYPE, table->Size(), | 274 RecordFixedArrayHelper(stats, heap, obj, table, WEAK_COLLECTION_SUB_TYPE, |
248 overhead); | 275 overhead); |
249 } | 276 } |
250 } | 277 } |
251 | 278 |
| 279 void ObjectStatsCollector::RecordScriptDetails(ObjectStats* stats, Heap* heap, |
| 280 Script* obj) { |
| 281 Object* infos = WeakFixedArray::cast(obj->shared_function_infos()); |
| 282 if (infos->IsWeakFixedArray()) |
| 283 RecordFixedArrayHelper(stats, heap, obj, WeakFixedArray::cast(infos), |
| 284 SHARED_FUNCTION_INFOS_SUB_TYPE, 0); |
| 285 } |
| 286 |
252 void ObjectStatsCollector::RecordMapDetails(ObjectStats* stats, Heap* heap, | 287 void ObjectStatsCollector::RecordMapDetails(ObjectStats* stats, Heap* heap, |
253 HeapObject* obj) { | 288 HeapObject* obj) { |
254 Map* map_obj = Map::cast(obj); | 289 Map* map_obj = Map::cast(obj); |
255 DCHECK(obj->map()->instance_type() == MAP_TYPE); | 290 DCHECK(obj->map()->instance_type() == MAP_TYPE); |
256 DescriptorArray* array = map_obj->instance_descriptors(); | 291 DescriptorArray* array = map_obj->instance_descriptors(); |
257 if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array()) { | 292 if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array() && |
258 int fixed_array_size = array->Size(); | 293 SameLiveness(map_obj, array)) { |
259 stats->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE, | 294 RecordFixedArrayHelper(stats, heap, map_obj, array, |
260 fixed_array_size, 0); | 295 DESCRIPTOR_ARRAY_SUB_TYPE, 0); |
261 if (array->HasEnumCache()) { | 296 if (array->HasEnumCache()) { |
262 stats->RecordFixedArraySubTypeStats(ENUM_CACHE_SUB_TYPE, | 297 RecordFixedArrayHelper(stats, heap, array, array->GetEnumCache(), |
263 array->GetEnumCache()->Size(), 0); | 298 ENUM_CACHE_SUB_TYPE, 0); |
264 } | 299 } |
265 if (array->HasEnumIndicesCache()) { | 300 if (array->HasEnumIndicesCache()) { |
266 stats->RecordFixedArraySubTypeStats( | 301 RecordFixedArrayHelper(stats, heap, array, array->GetEnumIndicesCache(), |
267 ENUM_INDICES_CACHE_SUB_TYPE, array->GetEnumIndicesCache()->Size(), 0); | 302 ENUM_INDICES_CACHE_SUB_TYPE, 0); |
268 } | 303 } |
269 } | 304 } |
270 | 305 |
271 if (map_obj->has_code_cache()) { | 306 if (map_obj->has_code_cache()) { |
272 FixedArray* cache = map_obj->code_cache(); | 307 RecordFixedArrayHelper(stats, heap, map_obj, map_obj->code_cache(), |
273 stats->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE, cache->Size(), | 308 MAP_CODE_CACHE_SUB_TYPE, 0); |
274 0); | |
275 } | 309 } |
276 } | 310 } |
277 | 311 |
278 void ObjectStatsCollector::RecordCodeDetails(ObjectStats* stats, Heap* heap, | 312 void ObjectStatsCollector::RecordCodeDetails(ObjectStats* stats, Heap* heap, |
279 HeapObject* obj) { | 313 HeapObject* obj) { |
280 int object_size = obj->Size(); | 314 int object_size = obj->Size(); |
281 DCHECK(obj->map()->instance_type() == CODE_TYPE); | 315 DCHECK(obj->map()->instance_type() == CODE_TYPE); |
282 Code* code_obj = Code::cast(obj); | 316 Code* code_obj = Code::cast(obj); |
283 stats->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(), | 317 stats->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(), |
284 object_size); | 318 object_size); |
285 Code* code = Code::cast(obj); | 319 Code* code = Code::cast(obj); |
286 if (code->deoptimization_data() != heap->empty_fixed_array()) { | 320 RecordFixedArrayHelper(stats, heap, code, code->deoptimization_data(), |
287 stats->RecordFixedArraySubTypeStats(DEOPTIMIZATION_DATA_SUB_TYPE, | 321 DEOPTIMIZATION_DATA_SUB_TYPE, 0); |
288 code->deoptimization_data()->Size(), 0); | 322 for (RelocIterator it(code); !it.done(); it.next()) { |
289 } | 323 RelocInfo::Mode mode = it.rinfo()->rmode(); |
290 FixedArrayBase* reloc_info = | 324 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
291 reinterpret_cast<FixedArrayBase*>(code->unchecked_relocation_info()); | 325 Object* target = it.rinfo()->target_object(); |
292 if (reloc_info != heap->empty_fixed_array()) { | 326 if (target->IsFixedArray()) { |
293 stats->RecordFixedArraySubTypeStats(RELOC_INFO_SUB_TYPE, | 327 RecordFixedArrayHelper(stats, heap, code, FixedArray::cast(target), |
294 code->relocation_info()->Size(), 0); | 328 EMBEDDED_OBJECT_SUB_TYPE, 0); |
295 } | 329 } |
296 FixedArrayBase* source_pos_table = | 330 } |
297 reinterpret_cast<FixedArrayBase*>(code->source_position_table()); | |
298 if (source_pos_table != heap->empty_fixed_array()) { | |
299 stats->RecordFixedArraySubTypeStats(SOURCE_POS_SUB_TYPE, | |
300 source_pos_table->Size(), 0); | |
301 } | 331 } |
302 } | 332 } |
303 | 333 |
304 void ObjectStatsCollector::RecordSharedFunctionInfoDetails(ObjectStats* stats, | 334 void ObjectStatsCollector::RecordSharedFunctionInfoDetails(ObjectStats* stats, |
305 Heap* heap, | 335 Heap* heap, |
306 HeapObject* obj) { | 336 HeapObject* obj) { |
307 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); | 337 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); |
308 if (sfi->scope_info() != heap->empty_fixed_array()) { | 338 FixedArray* scope_info = sfi->scope_info(); |
309 stats->RecordFixedArraySubTypeStats(SCOPE_INFO_SUB_TYPE, | 339 RecordFixedArrayHelper(stats, heap, sfi, scope_info, SCOPE_INFO_SUB_TYPE, 0); |
310 sfi->scope_info()->Size(), 0); | 340 FixedArray* feedback_metadata = sfi->feedback_metadata(); |
311 } | 341 RecordFixedArrayHelper(stats, heap, sfi, feedback_metadata, |
312 if (sfi->feedback_metadata() != heap->empty_fixed_array()) { | 342 TYPE_FEEDBACK_METADATA_SUB_TYPE, 0); |
313 stats->RecordFixedArraySubTypeStats(TYPE_FEEDBACK_METADATA_SUB_TYPE, | 343 |
314 sfi->feedback_metadata()->Size(), 0); | |
315 } | |
316 if (!sfi->OptimizedCodeMapIsCleared()) { | 344 if (!sfi->OptimizedCodeMapIsCleared()) { |
317 FixedArray* optimized_code_map = sfi->optimized_code_map(); | 345 FixedArray* optimized_code_map = sfi->optimized_code_map(); |
318 // Optimized code map should be small, so skip accounting. | 346 // Optimized code map should be small, so skip accounting. |
319 int len = optimized_code_map->length(); | 347 int len = optimized_code_map->length(); |
320 for (int i = SharedFunctionInfo::kEntriesStart; i < len; | 348 for (int i = SharedFunctionInfo::kEntriesStart; i < len; |
321 i += SharedFunctionInfo::kEntryLength) { | 349 i += SharedFunctionInfo::kEntryLength) { |
322 Object* slot = | 350 Object* slot = |
323 optimized_code_map->get(i + SharedFunctionInfo::kLiteralsOffset); | 351 optimized_code_map->get(i + SharedFunctionInfo::kLiteralsOffset); |
324 LiteralsArray* literals = nullptr; | 352 LiteralsArray* literals = nullptr; |
325 if (slot->IsWeakCell()) { | 353 if (slot->IsWeakCell()) { |
326 WeakCell* cell = WeakCell::cast(slot); | 354 WeakCell* cell = WeakCell::cast(slot); |
327 if (!cell->cleared()) { | 355 if (!cell->cleared()) { |
328 literals = LiteralsArray::cast(cell->value()); | 356 literals = LiteralsArray::cast(cell->value()); |
329 } | 357 } |
330 } else { | 358 } else { |
331 literals = LiteralsArray::cast(slot); | 359 literals = LiteralsArray::cast(slot); |
332 } | 360 } |
333 if (literals != nullptr) { | 361 if (literals != nullptr) { |
334 stats->RecordFixedArraySubTypeStats(LITERALS_ARRAY_SUB_TYPE, | 362 RecordFixedArrayHelper(stats, heap, sfi, literals, |
335 literals->Size(), 0); | 363 LITERALS_ARRAY_SUB_TYPE, 0); |
336 TypeFeedbackVector* tfv = literals->feedback_vector(); | 364 RecordFixedArrayHelper(stats, heap, sfi, literals->feedback_vector(), |
337 | 365 TYPE_FEEDBACK_VECTOR_SUB_TYPE, 0); |
338 stats->RecordFixedArraySubTypeStats(TYPE_FEEDBACK_VECTOR_SUB_TYPE, | |
339 tfv->Size(), 0); | |
340 } | 366 } |
341 } | 367 } |
342 } | 368 } |
343 } | 369 } |
344 | 370 |
345 void ObjectStatsCollector::RecordFixedArrayDetails(ObjectStats* stats, | 371 void ObjectStatsCollector::RecordFixedArrayDetails(ObjectStats* stats, |
346 Heap* heap, | 372 Heap* heap, |
347 HeapObject* obj) { | 373 HeapObject* obj) { |
348 FixedArray* fixed_array = FixedArray::cast(obj); | 374 FixedArray* array = FixedArray::cast(obj); |
349 if (fixed_array == heap->string_table()) { | 375 |
350 stats->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE, | 376 // Special fixed arrays. |
351 fixed_array->Size(), 0); | 377 int subtype = -1; |
| 378 if (array == heap->weak_new_space_object_to_code_list()) |
| 379 subtype = WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE; |
| 380 if (array == heap->serialized_templates()) |
| 381 subtype = SERIALIZED_TEMPLATES_SUB_TYPE; |
| 382 if (array == heap->string_table()) subtype = STRING_TABLE_SUB_TYPE; |
| 383 if (array == heap->number_string_cache()) |
| 384 subtype = NUMBER_STRING_CACHE_SUB_TYPE; |
| 385 if (array == heap->single_character_string_cache()) |
| 386 subtype = SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE; |
| 387 if (array == heap->string_split_cache()) |
| 388 subtype = STRING_SPLIT_CACHE_SUB_TYPE; |
| 389 if (array == heap->regexp_multiple_cache()) |
| 390 subtype = REGEXP_MULTIPLE_CACHE_SUB_TYPE; |
| 391 if (array->IsContext()) subtype = CONTEXT_SUB_TYPE; |
| 392 if (array->map() == heap->fixed_cow_array_map()) |
| 393 subtype = COPY_ON_WRITE_SUB_TYPE; |
| 394 if (subtype != -1) { |
| 395 stats->RecordFixedArraySubTypeStats(array, subtype, array->Size(), 0); |
352 } | 396 } |
353 if (fixed_array == heap->weak_object_to_code_table()) { | 397 |
354 WeakHashTable* table = reinterpret_cast<WeakHashTable*>(fixed_array); | 398 // Special hash maps. |
| 399 if (array == heap->weak_object_to_code_table()) { |
| 400 WeakHashTable* table = reinterpret_cast<WeakHashTable*>(array); |
355 int used = table->NumberOfElements() * WeakHashTable::kEntrySize; | 401 int used = table->NumberOfElements() * WeakHashTable::kEntrySize; |
356 CHECK_GE(fixed_array->Size(), used); | 402 CHECK_GE(array->Size(), used); |
357 size_t overhead = fixed_array->Size() - used; | 403 size_t overhead = array->Size() - used; |
358 stats->RecordFixedArraySubTypeStats(OBJECT_TO_CODE_SUB_TYPE, | 404 stats->RecordFixedArraySubTypeStats(table, OBJECT_TO_CODE_SUB_TYPE, |
359 fixed_array->Size(), overhead); | 405 table->Size(), overhead); |
360 } | 406 } |
361 if (obj->IsContext()) { | 407 if (array->IsNativeContext()) { |
362 stats->RecordFixedArraySubTypeStats(CONTEXT_SUB_TYPE, fixed_array->Size(), | 408 Context* native_ctx = Context::cast(array); |
363 0); | 409 UnseededNumberDictionary* dict = |
| 410 native_ctx->template_instantiations_cache(); |
| 411 int used = dict->NumberOfElements() * UnseededNumberDictionary::kEntrySize; |
| 412 size_t overhead = dict->Size() - used; |
| 413 RecordFixedArrayHelper(stats, heap, array, dict, |
| 414 TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE, overhead); |
364 } | 415 } |
365 if (fixed_array->map() == heap->fixed_cow_array_map()) { | 416 if (array == heap->code_stubs()) { |
366 stats->RecordFixedArraySubTypeStats(COPY_ON_WRITE_SUB_TYPE, | 417 UnseededNumberDictionary* dict = UnseededNumberDictionary::cast(array); |
367 fixed_array->Size(), 0); | 418 int used = dict->NumberOfElements() * UnseededNumberDictionary::kEntrySize; |
| 419 size_t overhead = dict->Size() - used; |
| 420 stats->RecordFixedArraySubTypeStats(dict, CODE_STUBS_TABLE_SUB_TYPE, |
| 421 dict->Size(), overhead); |
| 422 } |
| 423 if (array == heap->intrinsic_function_names()) { |
| 424 NameDictionary* dict = NameDictionary::cast(array); |
| 425 int used = dict->NumberOfElements() * NameDictionary::kEntrySize; |
| 426 size_t overhead = dict->Size() - used; |
| 427 stats->RecordFixedArraySubTypeStats(dict, INTRINSIC_FUNCTION_NAMES_SUB_TYPE, |
| 428 dict->Size(), overhead); |
368 } | 429 } |
369 } | 430 } |
370 | 431 |
371 } // namespace internal | 432 } // namespace internal |
372 } // namespace v8 | 433 } // namespace v8 |
OLD | NEW |