OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "api.h" | 8 #include "api.h" |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "codegen.h" | 10 #include "codegen.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 store_buffer_rebuilder_(store_buffer()), | 94 store_buffer_rebuilder_(store_buffer()), |
95 hidden_string_(NULL), | 95 hidden_string_(NULL), |
96 gc_safe_size_of_old_object_(NULL), | 96 gc_safe_size_of_old_object_(NULL), |
97 total_regexp_code_generated_(0), | 97 total_regexp_code_generated_(0), |
98 tracer_(NULL), | 98 tracer_(NULL), |
99 high_survival_rate_period_length_(0), | 99 high_survival_rate_period_length_(0), |
100 promoted_objects_size_(0), | 100 promoted_objects_size_(0), |
101 promotion_rate_(0), | 101 promotion_rate_(0), |
102 semi_space_copied_object_size_(0), | 102 semi_space_copied_object_size_(0), |
103 semi_space_copied_rate_(0), | 103 semi_space_copied_rate_(0), |
104 changed_to_max_semi_space_size_(false), | |
104 max_gc_pause_(0.0), | 105 max_gc_pause_(0.0), |
105 total_gc_time_ms_(0.0), | 106 total_gc_time_ms_(0.0), |
106 max_alive_after_gc_(0), | 107 max_alive_after_gc_(0), |
107 min_in_mutator_(kMaxInt), | 108 min_in_mutator_(kMaxInt), |
108 alive_after_last_gc_(0), | 109 alive_after_last_gc_(0), |
109 last_gc_end_timestamp_(0.0), | 110 last_gc_end_timestamp_(0.0), |
110 marking_time_(0.0), | 111 marking_time_(0.0), |
111 sweeping_time_(0.0), | 112 sweeping_time_(0.0), |
112 mark_compact_collector_(this), | 113 mark_compact_collector_(this), |
113 store_buffer_(this), | 114 store_buffer_(this), |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 if (FLAG_gc_verbose) Print(); | 432 if (FLAG_gc_verbose) Print(); |
432 | 433 |
433 ReportStatisticsBeforeGC(); | 434 ReportStatisticsBeforeGC(); |
434 #endif // DEBUG | 435 #endif // DEBUG |
435 | 436 |
436 store_buffer()->GCPrologue(); | 437 store_buffer()->GCPrologue(); |
437 | 438 |
438 if (isolate()->concurrent_osr_enabled()) { | 439 if (isolate()->concurrent_osr_enabled()) { |
439 isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); | 440 isolate()->optimizing_compiler_thread()->AgeBufferedOsrJobs(); |
440 } | 441 } |
442 | |
443 CheckNewSpaceExpansionCriteria(); | |
441 } | 444 } |
442 | 445 |
443 | 446 |
444 intptr_t Heap::SizeOfObjects() { | 447 intptr_t Heap::SizeOfObjects() { |
445 intptr_t total = 0; | 448 intptr_t total = 0; |
446 AllSpaces spaces(this); | 449 AllSpaces spaces(this); |
447 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { | 450 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { |
448 total += space->SizeOfObjects(); | 451 total += space->SizeOfObjects(); |
449 } | 452 } |
450 return total; | 453 return total; |
(...skipping 27 matching lines...) Expand all Loading... | |
478 void Heap::ProcessPretenuringFeedback() { | 481 void Heap::ProcessPretenuringFeedback() { |
479 if (FLAG_allocation_site_pretenuring) { | 482 if (FLAG_allocation_site_pretenuring) { |
480 int tenure_decisions = 0; | 483 int tenure_decisions = 0; |
481 int dont_tenure_decisions = 0; | 484 int dont_tenure_decisions = 0; |
482 int allocation_mementos_found = 0; | 485 int allocation_mementos_found = 0; |
483 int allocation_sites = 0; | 486 int allocation_sites = 0; |
484 int active_allocation_sites = 0; | 487 int active_allocation_sites = 0; |
485 | 488 |
486 // If the scratchpad overflowed, we have to iterate over the allocation | 489 // If the scratchpad overflowed, we have to iterate over the allocation |
487 // sites list. | 490 // sites list. |
491 // TODO(hpayer): We iterate over the whole list of allocation sites when | |
492 // we grew to the maximum semi-space size to deopt maybe tenured | |
493 // allocation sites. We could hold the maybe tenured allocation sites | |
494 // in a seperate data structure if this is a performance problem. | |
488 bool use_scratchpad = | 495 bool use_scratchpad = |
489 allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize; | 496 allocation_sites_scratchpad_length_ < kAllocationSiteScratchpadSize && |
497 !changed_to_max_semi_space_size_; | |
490 | 498 |
491 int i = 0; | 499 int i = 0; |
492 Object* list_element = allocation_sites_list(); | 500 Object* list_element = allocation_sites_list(); |
493 bool trigger_deoptimization = false; | 501 bool trigger_deoptimization = false; |
494 while (use_scratchpad ? | 502 while (use_scratchpad ? |
495 i < allocation_sites_scratchpad_length_ : | 503 i < allocation_sites_scratchpad_length_ : |
496 list_element->IsAllocationSite()) { | 504 list_element->IsAllocationSite()) { |
497 AllocationSite* site = use_scratchpad ? | 505 AllocationSite* site = use_scratchpad ? |
498 AllocationSite::cast(allocation_sites_scratchpad()->get(i)) : | 506 AllocationSite::cast(allocation_sites_scratchpad()->get(i)) : |
499 AllocationSite::cast(list_element); | 507 AllocationSite::cast(list_element); |
500 allocation_mementos_found += site->memento_found_count(); | 508 allocation_mementos_found += site->memento_found_count(); |
501 if (site->memento_found_count() > 0) { | 509 if (site->memento_found_count() > 0) { |
502 active_allocation_sites++; | 510 active_allocation_sites++; |
511 if (site->DigestPretenuringFeedback()) trigger_deoptimization = true; | |
512 if (site->GetPretenureMode() == TENURED) { | |
513 tenure_decisions++; | |
514 } else { | |
515 dont_tenure_decisions++; | |
516 } | |
517 allocation_sites++; | |
503 } | 518 } |
504 if (site->DigestPretenuringFeedback()) trigger_deoptimization = true; | 519 |
505 if (site->GetPretenureMode() == TENURED) { | |
506 tenure_decisions++; | |
507 } else { | |
508 dont_tenure_decisions++; | |
509 } | |
510 allocation_sites++; | |
511 if (use_scratchpad) { | 520 if (use_scratchpad) { |
512 i++; | 521 i++; |
513 } else { | 522 } else { |
514 list_element = site->weak_next(); | 523 list_element = site->weak_next(); |
515 } | 524 } |
516 } | 525 } |
517 | 526 |
518 if (trigger_deoptimization) { | 527 if (trigger_deoptimization) { |
519 isolate_->stack_guard()->RequestDeoptMarkedAllocationSites(); | 528 isolate_->stack_guard()->RequestDeoptMarkedAllocationSites(); |
520 } | 529 } |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1276 HeapObjectIterator data_it(heap->old_data_space()); | 1285 HeapObjectIterator data_it(heap->old_data_space()); |
1277 for (HeapObject* object = data_it.Next(); | 1286 for (HeapObject* object = data_it.Next(); |
1278 object != NULL; object = data_it.Next()) | 1287 object != NULL; object = data_it.Next()) |
1279 object->Iterate(&v); | 1288 object->Iterate(&v); |
1280 } | 1289 } |
1281 } | 1290 } |
1282 #endif // VERIFY_HEAP | 1291 #endif // VERIFY_HEAP |
1283 | 1292 |
1284 | 1293 |
1285 void Heap::CheckNewSpaceExpansionCriteria() { | 1294 void Heap::CheckNewSpaceExpansionCriteria() { |
1295 changed_to_max_semi_space_size_ = false; | |
1286 if (new_space_.Capacity() < new_space_.MaximumCapacity() && | 1296 if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
1287 survived_since_last_expansion_ > new_space_.Capacity()) { | 1297 survived_since_last_expansion_ > new_space_.Capacity()) { |
1288 // Grow the size of new space if there is room to grow, enough data | 1298 // Grow the size of new space if there is room to grow, enough data |
1289 // has survived scavenge since the last expansion and we are not in | 1299 // has survived scavenge since the last expansion and we are not in |
1290 // high promotion mode. | 1300 // high promotion mode. |
1291 new_space_.Grow(); | 1301 new_space_.Grow(); |
1292 survived_since_last_expansion_ = 0; | 1302 survived_since_last_expansion_ = 0; |
1303 if (new_space_.IsAtMaximumCapacity()) { | |
1304 changed_to_max_semi_space_size_ = true; | |
mvstanton
2014/06/02 13:31:25
Is the boolean really needed? Why not just ask new
Hannes Payer (out of office)
2014/06/02 14:56:52
As discussed offline, we need a separate flag to i
| |
1305 } | |
1293 } | 1306 } |
1294 } | 1307 } |
1295 | 1308 |
1296 | 1309 |
1297 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { | 1310 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |
1298 return heap->InNewSpace(*p) && | 1311 return heap->InNewSpace(*p) && |
1299 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 1312 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
1300 } | 1313 } |
1301 | 1314 |
1302 | 1315 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1426 | 1439 |
1427 // Implements Cheney's copying algorithm | 1440 // Implements Cheney's copying algorithm |
1428 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1441 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
1429 | 1442 |
1430 // Clear descriptor cache. | 1443 // Clear descriptor cache. |
1431 isolate_->descriptor_lookup_cache()->Clear(); | 1444 isolate_->descriptor_lookup_cache()->Clear(); |
1432 | 1445 |
1433 // Used for updating survived_since_last_expansion_ at function end. | 1446 // Used for updating survived_since_last_expansion_ at function end. |
1434 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); | 1447 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); |
1435 | 1448 |
1436 CheckNewSpaceExpansionCriteria(); | |
1437 | |
1438 SelectScavengingVisitorsTable(); | 1449 SelectScavengingVisitorsTable(); |
1439 | 1450 |
1440 incremental_marking()->PrepareForScavenge(); | 1451 incremental_marking()->PrepareForScavenge(); |
1441 | 1452 |
1442 // Flip the semispaces. After flipping, to space is empty, from space has | 1453 // Flip the semispaces. After flipping, to space is empty, from space has |
1443 // live objects. | 1454 // live objects. |
1444 new_space_.Flip(); | 1455 new_space_.Flip(); |
1445 new_space_.ResetAllocationInfo(); | 1456 new_space_.ResetAllocationInfo(); |
1446 | 1457 |
1447 // We need to sweep newly copied objects which can be either in the | 1458 // We need to sweep newly copied objects which can be either in the |
(...skipping 4969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6417 static_cast<int>(object_sizes_last_time_[index])); | 6428 static_cast<int>(object_sizes_last_time_[index])); |
6418 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6429 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
6419 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6430 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
6420 | 6431 |
6421 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6432 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
6422 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6433 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
6423 ClearObjectStats(); | 6434 ClearObjectStats(); |
6424 } | 6435 } |
6425 | 6436 |
6426 } } // namespace v8::internal | 6437 } } // namespace v8::internal |
OLD | NEW |