Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: src/heap/object-stats.cc

Issue 2181623002: [heap] ObjectStats: Cleanup and more FIXED_ARRAY sub types (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/object-stats.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/macro-assembler.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 #undef ADJUST_LAST_TIME_OBJECT_COUNT 154 #undef ADJUST_LAST_TIME_OBJECT_COUNT
155 155
156 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 156 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
157 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 157 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
158 ClearObjectStats(); 158 ClearObjectStats();
159 } 159 }
160 160
161 161
162 Isolate* ObjectStats::isolate() { return heap()->isolate(); } 162 Isolate* ObjectStats::isolate() { return heap()->isolate(); }
163 163
164 void ObjectStatsCollector::CollectStatistics(ObjectStats* stats, 164 void ObjectStatsCollector::CollectStatistics(HeapObject* obj) {
165 HeapObject* obj) {
166 Map* map = obj->map(); 165 Map* map = obj->map();
167 Heap* heap = obj->GetHeap();
168 166
169 // Record for the InstanceType. 167 // Record for the InstanceType.
170 int object_size = obj->Size(); 168 int object_size = obj->Size();
171 stats->RecordObjectStats(map->instance_type(), object_size); 169 stats_->RecordObjectStats(map->instance_type(), object_size);
172 170
173 // Record specific sub types where possible. 171 // Record specific sub types where possible.
174 if (obj->IsMap()) { 172 if (obj->IsMap()) RecordMapDetails(Map::cast(obj));
175 RecordMapDetails(stats, heap, obj); 173 if (obj->IsCode()) RecordCodeDetails(Code::cast(obj));
174 if (obj->IsSharedFunctionInfo()) {
175 RecordSharedFunctionInfoDetails(SharedFunctionInfo::cast(obj));
176 } 176 }
177 if (obj->IsCode()) { 177 if (obj->IsFixedArray()) RecordFixedArrayDetails(FixedArray::cast(obj));
178 RecordCodeDetails(stats, heap, obj); 178 if (obj->IsJSObject()) RecordJSObjectDetails(JSObject::cast(obj));
179 if (obj->IsJSWeakCollection()) {
180 RecordJSWeakCollectionDetails(JSWeakCollection::cast(obj));
179 } 181 }
180 if (obj->IsSharedFunctionInfo()) { 182 if (obj->IsJSCollection()) {
181 RecordSharedFunctionInfoDetails(stats, heap, obj); 183 RecordJSCollectionDetails(JSObject::cast(obj));
182 } 184 }
183 if (obj->IsFixedArray()) { 185 if (obj->IsJSFunction()) RecordJSFunctionDetails(JSFunction::cast(obj));
184 RecordFixedArrayDetails(stats, heap, obj); 186 if (obj->IsScript()) RecordScriptDetails(Script::cast(obj));
185 } 187 }
186 if (obj->IsJSObject()) { 188
187 RecordJSObjectDetails(stats, heap, JSObject::cast(obj)); 189 void ObjectStatsCollector::CollectGlobalStatistics() {
188 } 190 // Global FixedArrays.
189 if (obj->IsJSWeakCollection()) { 191 RecordFixedArrayHelper(nullptr, heap_->weak_new_space_object_to_code_list(),
190 RecordJSWeakCollectionDetails(stats, heap, JSWeakCollection::cast(obj)); 192 WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE, 0);
191 } 193 RecordFixedArrayHelper(nullptr, heap_->serialized_templates(),
192 if (obj->IsScript()) { 194 SERIALIZED_TEMPLATES_SUB_TYPE, 0);
193 RecordScriptDetails(stats, heap, Script::cast(obj)); 195 RecordFixedArrayHelper(nullptr, heap_->number_string_cache(),
194 } 196 NUMBER_STRING_CACHE_SUB_TYPE, 0);
197 RecordFixedArrayHelper(nullptr, heap_->single_character_string_cache(),
198 SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE, 0);
199 RecordFixedArrayHelper(nullptr, heap_->string_split_cache(),
200 STRING_SPLIT_CACHE_SUB_TYPE, 0);
201 RecordFixedArrayHelper(nullptr, heap_->regexp_multiple_cache(),
202 REGEXP_MULTIPLE_CACHE_SUB_TYPE, 0);
203 RecordFixedArrayHelper(nullptr, heap_->retained_maps(),
204 RETAINED_MAPS_SUB_TYPE, 0);
205
206 // Global weak FixedArrays.
207 RecordFixedArrayHelper(
208 nullptr, WeakFixedArray::cast(heap_->noscript_shared_function_infos()),
209 NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE, 0);
210 RecordFixedArrayHelper(nullptr, WeakFixedArray::cast(heap_->script_list()),
211 SCRIPT_LIST_SUB_TYPE, 0);
212
213 // Global hash tables.
214 RecordHashTableHelper(nullptr, heap_->string_table(), STRING_TABLE_SUB_TYPE);
215 RecordHashTableHelper(nullptr, heap_->weak_object_to_code_table(),
216 OBJECT_TO_CODE_SUB_TYPE);
217 RecordHashTableHelper(nullptr, heap_->code_stubs(),
218 CODE_STUBS_TABLE_SUB_TYPE);
219 RecordHashTableHelper(nullptr, heap_->intrinsic_function_names(),
220 INTRINSIC_FUNCTION_NAMES_SUB_TYPE);
221 RecordHashTableHelper(nullptr, heap_->empty_properties_dictionary(),
222 EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE);
195 } 223 }
196 224
197 static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) { 225 static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) {
198 return array->map()->instance_type() == FIXED_ARRAY_TYPE && 226 return array->map()->instance_type() == FIXED_ARRAY_TYPE &&
199 array->map() != heap->fixed_cow_array_map() &&
200 array->map() != heap->fixed_double_array_map() && 227 array->map() != heap->fixed_double_array_map() &&
201 array != heap->empty_fixed_array() && 228 array != heap->empty_fixed_array() &&
202 array != heap->empty_byte_array() && 229 array != heap->empty_byte_array() &&
203 array != heap->empty_literals_array() && 230 array != heap->empty_literals_array() &&
204 array != heap->empty_sloppy_arguments_elements() && 231 array != heap->empty_sloppy_arguments_elements() &&
205 array != heap->empty_slow_element_dictionary() && 232 array != heap->empty_slow_element_dictionary() &&
206 array != heap->empty_descriptor_array() && 233 array != heap->empty_descriptor_array() &&
207 array != heap->empty_properties_dictionary(); 234 array != heap->empty_properties_dictionary();
208 } 235 }
209 236
210 static bool SameLiveness(HeapObject* obj1, HeapObject* obj2) { 237 static bool IsCowArray(Heap* heap, FixedArrayBase* array) {
211 return ObjectMarking::Color(obj1) == ObjectMarking::Color(obj2); 238 return array->map() == heap->fixed_cow_array_map();
212 } 239 }
213 240
214 void ObjectStatsCollector::RecordFixedArrayHelper( 241 static bool SameLiveness(HeapObject* obj1, HeapObject* obj2) {
215 ObjectStats* stats, Heap* heap, HeapObject* parent, FixedArray* array, 242 return obj1 == nullptr || obj2 == nullptr ||
216 int subtype, size_t overhead) { 243 ObjectMarking::Color(obj1) == ObjectMarking::Color(obj2);
217 if (SameLiveness(parent, array) && CanRecordFixedArray(heap, array)) { 244 }
218 stats->RecordFixedArraySubTypeStats(array, subtype, array->Size(), 245
219 overhead); 246 bool ObjectStatsCollector::RecordFixedArrayHelper(HeapObject* parent,
247 FixedArray* array,
248 int subtype,
249 size_t overhead) {
250 if (SameLiveness(parent, array) && CanRecordFixedArray(heap_, array) &&
251 !IsCowArray(heap_, array)) {
252 return stats_->RecordFixedArraySubTypeStats(array, subtype, array->Size(),
253 overhead);
254 }
255 return false;
256 }
257
258 void ObjectStatsCollector::RecursivelyRecordFixedArrayHelper(HeapObject* parent,
259 FixedArray* array,
260 int subtype) {
261 if (RecordFixedArrayHelper(parent, array, subtype, 0)) {
262 for (int i = 0; i < array->length(); i++) {
263 if (array->get(i)->IsFixedArray()) {
264 RecursivelyRecordFixedArrayHelper(
265 parent, FixedArray::cast(array->get(i)), subtype);
266 }
267 }
220 } 268 }
221 } 269 }
222 270
223 void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap, 271 template <class HashTable>
224 JSObject* object) { 272 void ObjectStatsCollector::RecordHashTableHelper(HeapObject* parent,
225 DCHECK(object->IsJSObject()); 273 HashTable* array,
274 int subtype) {
275 int used = array->NumberOfElements() * HashTable::kEntrySize;
276 CHECK_GE(array->Size(), used);
277 size_t overhead = array->Size() - used;
278 RecordFixedArrayHelper(parent, array, subtype, overhead);
279 }
226 280
281 void ObjectStatsCollector::RecordJSObjectDetails(JSObject* object) {
227 size_t overhead = 0; 282 size_t overhead = 0;
228 FixedArrayBase* elements = object->elements(); 283 FixedArrayBase* elements = object->elements();
229 if (CanRecordFixedArray(heap, elements)) { 284 if (CanRecordFixedArray(heap_, elements) && !IsCowArray(heap_, elements)) {
230 if (elements->IsDictionary() && SameLiveness(object, elements)) { 285 if (elements->IsDictionary() && SameLiveness(object, elements)) {
231 SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements); 286 SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements);
232 int used = dict->NumberOfElements() * SeededNumberDictionary::kEntrySize; 287 RecordHashTableHelper(object, dict, DICTIONARY_ELEMENTS_SUB_TYPE);
233 CHECK_GE(elements->Size(), used);
234 overhead = elements->Size() - used;
235 stats->RecordFixedArraySubTypeStats(
236 elements, DICTIONARY_ELEMENTS_SUB_TYPE, elements->Size(), overhead);
237 } else { 288 } else {
238 if (IsFastHoleyElementsKind(object->GetElementsKind())) { 289 if (IsFastHoleyElementsKind(object->GetElementsKind())) {
239 int used = object->GetFastElementsUsage() * kPointerSize; 290 int used = object->GetFastElementsUsage() * kPointerSize;
240 if (object->GetElementsKind() == FAST_HOLEY_DOUBLE_ELEMENTS) used *= 2; 291 if (object->GetElementsKind() == FAST_HOLEY_DOUBLE_ELEMENTS) used *= 2;
241 CHECK_GE(elements->Size(), used); 292 CHECK_GE(elements->Size(), used);
242 overhead = elements->Size() - used; 293 overhead = elements->Size() - used;
243 } 294 }
244 stats->RecordFixedArraySubTypeStats(elements, FAST_ELEMENTS_SUB_TYPE, 295 stats_->RecordFixedArraySubTypeStats(elements, FAST_ELEMENTS_SUB_TYPE,
245 elements->Size(), overhead); 296 elements->Size(), overhead);
246 } 297 }
247 } 298 }
248 299
249 overhead = 0; 300 overhead = 0;
250 FixedArrayBase* properties = object->properties(); 301 FixedArrayBase* properties = object->properties();
251 if (CanRecordFixedArray(heap, properties) && 302 if (CanRecordFixedArray(heap_, properties) &&
252 SameLiveness(object, properties)) { 303 SameLiveness(object, properties) && !IsCowArray(heap_, properties)) {
253 if (properties->IsDictionary()) { 304 if (properties->IsDictionary()) {
254 NameDictionary* dict = NameDictionary::cast(properties); 305 NameDictionary* dict = NameDictionary::cast(properties);
255 int used = dict->NumberOfElements() * NameDictionary::kEntrySize; 306 RecordHashTableHelper(object, dict, DICTIONARY_PROPERTIES_SUB_TYPE);
256 CHECK_GE(properties->Size(), used);
257 overhead = properties->Size() - used;
258 stats->RecordFixedArraySubTypeStats(properties,
259 DICTIONARY_PROPERTIES_SUB_TYPE,
260 properties->Size(), overhead);
261 } else { 307 } else {
262 stats->RecordFixedArraySubTypeStats(properties, FAST_PROPERTIES_SUB_TYPE, 308 stats_->RecordFixedArraySubTypeStats(properties, FAST_PROPERTIES_SUB_TYPE,
263 properties->Size(), overhead); 309 properties->Size(), overhead);
264 } 310 }
265 } 311 }
266 } 312 }
267 313
268 void ObjectStatsCollector::RecordJSWeakCollectionDetails( 314 void ObjectStatsCollector::RecordJSWeakCollectionDetails(
269 ObjectStats* stats, Heap* heap, JSWeakCollection* obj) { 315 JSWeakCollection* obj) {
270 if (obj->table()->IsHashTable()) { 316 if (obj->table()->IsHashTable()) {
271 ObjectHashTable* table = ObjectHashTable::cast(obj->table()); 317 ObjectHashTable* table = ObjectHashTable::cast(obj->table());
272 int used = table->NumberOfElements() * ObjectHashTable::kEntrySize; 318 int used = table->NumberOfElements() * ObjectHashTable::kEntrySize;
273 size_t overhead = table->Size() - used; 319 size_t overhead = table->Size() - used;
274 RecordFixedArrayHelper(stats, heap, obj, table, WEAK_COLLECTION_SUB_TYPE, 320 RecordFixedArrayHelper(obj, table, JS_WEAK_COLLECTION_SUB_TYPE, overhead);
275 overhead);
276 } 321 }
277 } 322 }
278 323
279 void ObjectStatsCollector::RecordScriptDetails(ObjectStats* stats, Heap* heap, 324 void ObjectStatsCollector::RecordJSCollectionDetails(JSObject* obj) {
280 Script* obj) { 325 if (obj->IsJSMap()) {
326 RecordHashTableHelper(nullptr,
327 OrderedHashMap::cast(JSMap::cast(obj)->table()),
328 JS_COLLECTION_SUB_TYPE);
329 }
330 if (obj->IsJSSet()) {
331 RecordHashTableHelper(nullptr,
332 OrderedHashSet::cast(JSSet::cast(obj)->table()),
333 JS_COLLECTION_SUB_TYPE);
334 }
335 }
336
337 void ObjectStatsCollector::RecordScriptDetails(Script* obj) {
281 Object* infos = WeakFixedArray::cast(obj->shared_function_infos()); 338 Object* infos = WeakFixedArray::cast(obj->shared_function_infos());
282 if (infos->IsWeakFixedArray()) 339 if (infos->IsWeakFixedArray())
283 RecordFixedArrayHelper(stats, heap, obj, WeakFixedArray::cast(infos), 340 RecordFixedArrayHelper(obj, WeakFixedArray::cast(infos),
284 SHARED_FUNCTION_INFOS_SUB_TYPE, 0); 341 SHARED_FUNCTION_INFOS_SUB_TYPE, 0);
285 } 342 }
286 343
287 void ObjectStatsCollector::RecordMapDetails(ObjectStats* stats, Heap* heap, 344 void ObjectStatsCollector::RecordMapDetails(Map* map_obj) {
288 HeapObject* obj) {
289 Map* map_obj = Map::cast(obj);
290 DCHECK(obj->map()->instance_type() == MAP_TYPE);
291 DescriptorArray* array = map_obj->instance_descriptors(); 345 DescriptorArray* array = map_obj->instance_descriptors();
292 if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array() && 346 if (map_obj->owns_descriptors() && array != heap_->empty_descriptor_array() &&
293 SameLiveness(map_obj, array)) { 347 SameLiveness(map_obj, array)) {
294 RecordFixedArrayHelper(stats, heap, map_obj, array, 348 RecordFixedArrayHelper(map_obj, array, DESCRIPTOR_ARRAY_SUB_TYPE, 0);
295 DESCRIPTOR_ARRAY_SUB_TYPE, 0);
296 if (array->HasEnumCache()) { 349 if (array->HasEnumCache()) {
297 RecordFixedArrayHelper(stats, heap, array, array->GetEnumCache(), 350 RecordFixedArrayHelper(array, array->GetEnumCache(), ENUM_CACHE_SUB_TYPE,
298 ENUM_CACHE_SUB_TYPE, 0); 351 0);
299 } 352 }
300 if (array->HasEnumIndicesCache()) { 353 if (array->HasEnumIndicesCache()) {
301 RecordFixedArrayHelper(stats, heap, array, array->GetEnumIndicesCache(), 354 RecordFixedArrayHelper(array, array->GetEnumIndicesCache(),
302 ENUM_INDICES_CACHE_SUB_TYPE, 0); 355 ENUM_INDICES_CACHE_SUB_TYPE, 0);
303 } 356 }
304 } 357 }
305 358
306 if (map_obj->has_code_cache()) { 359 if (map_obj->has_code_cache()) {
307 RecordFixedArrayHelper(stats, heap, map_obj, map_obj->code_cache(), 360 RecordFixedArrayHelper(map_obj, map_obj->code_cache(),
308 MAP_CODE_CACHE_SUB_TYPE, 0); 361 MAP_CODE_CACHE_SUB_TYPE, 0);
309 } 362 }
310 }
311 363
312 void ObjectStatsCollector::RecordCodeDetails(ObjectStats* stats, Heap* heap, 364 for (DependentCode* cur_dependent_code = map_obj->dependent_code();
313 HeapObject* obj) { 365 cur_dependent_code != heap_->empty_fixed_array();
314 int object_size = obj->Size(); 366 cur_dependent_code = DependentCode::cast(
315 DCHECK(obj->map()->instance_type() == CODE_TYPE); 367 cur_dependent_code->get(DependentCode::kNextLinkIndex))) {
316 Code* code_obj = Code::cast(obj); 368 RecordFixedArrayHelper(map_obj, cur_dependent_code, DEPENDENT_CODE_SUB_TYPE,
317 stats->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(), 369 0);
318 object_size); 370 }
319 Code* code = Code::cast(obj); 371
320 RecordFixedArrayHelper(stats, heap, code, code->deoptimization_data(), 372 if (map_obj->is_prototype_map()) {
321 DEOPTIMIZATION_DATA_SUB_TYPE, 0); 373 if (map_obj->prototype_info()->IsPrototypeInfo()) {
322 for (RelocIterator it(code); !it.done(); it.next()) { 374 PrototypeInfo* info = PrototypeInfo::cast(map_obj->prototype_info());
323 RelocInfo::Mode mode = it.rinfo()->rmode(); 375 Object* users = info->prototype_users();
324 if (mode == RelocInfo::EMBEDDED_OBJECT) { 376 if (users->IsWeakFixedArray()) {
325 Object* target = it.rinfo()->target_object(); 377 RecordFixedArrayHelper(map_obj, WeakFixedArray::cast(users),
326 if (target->IsFixedArray()) { 378 PROTOTYPE_USERS_SUB_TYPE, 0);
327 RecordFixedArrayHelper(stats, heap, code, FixedArray::cast(target),
328 EMBEDDED_OBJECT_SUB_TYPE, 0);
329 } 379 }
330 } 380 }
331 } 381 }
332 } 382 }
333 383
334 void ObjectStatsCollector::RecordSharedFunctionInfoDetails(ObjectStats* stats, 384 void ObjectStatsCollector::RecordCodeDetails(Code* code) {
335 Heap* heap, 385 stats_->RecordCodeSubTypeStats(code->kind(), code->GetAge(), code->Size());
336 HeapObject* obj) { 386 RecordFixedArrayHelper(code, code->deoptimization_data(),
337 SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj); 387 DEOPTIMIZATION_DATA_SUB_TYPE, 0);
388 RecordFixedArrayHelper(code, code->handler_table(), HANDLER_TABLE_SUB_TYPE,
389 0);
390 int const mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
391 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
392 RelocInfo::Mode mode = it.rinfo()->rmode();
393 if (mode == RelocInfo::EMBEDDED_OBJECT) {
394 Object* target = it.rinfo()->target_object();
395 if (target->IsFixedArray()) {
396 RecursivelyRecordFixedArrayHelper(code, FixedArray::cast(target),
397 EMBEDDED_OBJECT_SUB_TYPE);
398 }
399 }
400 }
401 }
402
403 void ObjectStatsCollector::RecordSharedFunctionInfoDetails(
404 SharedFunctionInfo* sfi) {
338 FixedArray* scope_info = sfi->scope_info(); 405 FixedArray* scope_info = sfi->scope_info();
339 RecordFixedArrayHelper(stats, heap, sfi, scope_info, SCOPE_INFO_SUB_TYPE, 0); 406 RecordFixedArrayHelper(sfi, scope_info, SCOPE_INFO_SUB_TYPE, 0);
340 FixedArray* feedback_metadata = sfi->feedback_metadata(); 407 TypeFeedbackMetadata* feedback_metadata = sfi->feedback_metadata();
341 RecordFixedArrayHelper(stats, heap, sfi, feedback_metadata, 408 if (!feedback_metadata->is_empty()) {
342 TYPE_FEEDBACK_METADATA_SUB_TYPE, 0); 409 RecordFixedArrayHelper(sfi, feedback_metadata,
410 TYPE_FEEDBACK_METADATA_SUB_TYPE, 0);
411 UnseededNumberDictionary* names = UnseededNumberDictionary::cast(
412 feedback_metadata->get(TypeFeedbackMetadata::kNamesTableIndex));
413 RecordHashTableHelper(sfi, names, TYPE_FEEDBACK_METADATA_SUB_TYPE);
414 }
343 415
344 if (!sfi->OptimizedCodeMapIsCleared()) { 416 if (!sfi->OptimizedCodeMapIsCleared()) {
345 FixedArray* optimized_code_map = sfi->optimized_code_map(); 417 FixedArray* optimized_code_map = sfi->optimized_code_map();
418 RecordFixedArrayHelper(sfi, optimized_code_map, OPTIMIZED_CODE_MAP_SUB_TYPE,
419 0);
346 // Optimized code map should be small, so skip accounting. 420 // Optimized code map should be small, so skip accounting.
347 int len = optimized_code_map->length(); 421 int len = optimized_code_map->length();
348 for (int i = SharedFunctionInfo::kEntriesStart; i < len; 422 for (int i = SharedFunctionInfo::kEntriesStart; i < len;
349 i += SharedFunctionInfo::kEntryLength) { 423 i += SharedFunctionInfo::kEntryLength) {
350 Object* slot = 424 Object* slot =
351 optimized_code_map->get(i + SharedFunctionInfo::kLiteralsOffset); 425 optimized_code_map->get(i + SharedFunctionInfo::kLiteralsOffset);
352 LiteralsArray* literals = nullptr; 426 LiteralsArray* literals = nullptr;
353 if (slot->IsWeakCell()) { 427 if (slot->IsWeakCell()) {
354 WeakCell* cell = WeakCell::cast(slot); 428 WeakCell* cell = WeakCell::cast(slot);
355 if (!cell->cleared()) { 429 if (!cell->cleared()) {
356 literals = LiteralsArray::cast(cell->value()); 430 literals = LiteralsArray::cast(cell->value());
357 } 431 }
358 } else { 432 } else {
359 literals = LiteralsArray::cast(slot); 433 literals = LiteralsArray::cast(slot);
360 } 434 }
361 if (literals != nullptr) { 435 if (literals != nullptr) {
362 RecordFixedArrayHelper(stats, heap, sfi, literals, 436 RecordFixedArrayHelper(sfi, literals, LITERALS_ARRAY_SUB_TYPE, 0);
363 LITERALS_ARRAY_SUB_TYPE, 0); 437 RecordFixedArrayHelper(sfi, literals->feedback_vector(),
364 RecordFixedArrayHelper(stats, heap, sfi, literals->feedback_vector(),
365 TYPE_FEEDBACK_VECTOR_SUB_TYPE, 0); 438 TYPE_FEEDBACK_VECTOR_SUB_TYPE, 0);
366 } 439 }
367 } 440 }
368 } 441 }
369 } 442 }
370 443
371 void ObjectStatsCollector::RecordFixedArrayDetails(ObjectStats* stats, 444 void ObjectStatsCollector::RecordJSFunctionDetails(JSFunction* function) {
372 Heap* heap, 445 LiteralsArray* literals = function->literals();
373 HeapObject* obj) { 446 RecordFixedArrayHelper(function, literals, LITERALS_ARRAY_SUB_TYPE, 0);
374 FixedArray* array = FixedArray::cast(obj); 447 RecordFixedArrayHelper(function, literals->feedback_vector(),
448 TYPE_FEEDBACK_VECTOR_SUB_TYPE, 0);
449 }
375 450
376 // Special fixed arrays. 451 void ObjectStatsCollector::RecordFixedArrayDetails(FixedArray* array) {
377 int subtype = -1; 452 if (array->IsContext()) {
378 if (array == heap->weak_new_space_object_to_code_list()) 453 RecordFixedArrayHelper(nullptr, array, CONTEXT_SUB_TYPE, 0);
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);
396 } 454 }
397 455 if (IsCowArray(heap_, array) && CanRecordFixedArray(heap_, array)) {
398 // Special hash maps. 456 stats_->RecordFixedArraySubTypeStats(array, COPY_ON_WRITE_SUB_TYPE,
399 if (array == heap->weak_object_to_code_table()) { 457 array->Size(), 0);
400 WeakHashTable* table = reinterpret_cast<WeakHashTable*>(array);
401 int used = table->NumberOfElements() * WeakHashTable::kEntrySize;
402 CHECK_GE(array->Size(), used);
403 size_t overhead = array->Size() - used;
404 stats->RecordFixedArraySubTypeStats(table, OBJECT_TO_CODE_SUB_TYPE,
405 table->Size(), overhead);
406 } 458 }
407 if (array->IsNativeContext()) { 459 if (array->IsNativeContext()) {
408 Context* native_ctx = Context::cast(array); 460 Context* native_ctx = Context::cast(array);
409 UnseededNumberDictionary* dict = 461 RecordHashTableHelper(array, native_ctx->template_instantiations_cache(),
410 native_ctx->template_instantiations_cache(); 462 TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE);
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);
415 }
416 if (array == heap->code_stubs()) {
417 UnseededNumberDictionary* dict = UnseededNumberDictionary::cast(array);
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);
429 } 463 }
430 } 464 }
431 465
432 } // namespace internal 466 } // namespace internal
433 } // namespace v8 467 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/object-stats.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698