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 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 #undef UPDATE_COUNTERS_FOR_SPACE | 543 #undef UPDATE_COUNTERS_FOR_SPACE |
544 #undef UPDATE_FRAGMENTATION_FOR_SPACE | 544 #undef UPDATE_FRAGMENTATION_FOR_SPACE |
545 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE | 545 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE |
546 | 546 |
547 #if defined(DEBUG) | 547 #if defined(DEBUG) |
548 ReportStatisticsAfterGC(); | 548 ReportStatisticsAfterGC(); |
549 #endif // DEBUG | 549 #endif // DEBUG |
550 #ifdef ENABLE_DEBUGGER_SUPPORT | 550 #ifdef ENABLE_DEBUGGER_SUPPORT |
551 isolate_->debug()->AfterGarbageCollection(); | 551 isolate_->debug()->AfterGarbageCollection(); |
552 #endif // ENABLE_DEBUGGER_SUPPORT | 552 #endif // ENABLE_DEBUGGER_SUPPORT |
| 553 |
| 554 error_object_list_.DeferredFormatStackTrace(isolate()); |
553 } | 555 } |
554 | 556 |
555 | 557 |
556 void Heap::CollectAllGarbage(int flags, const char* gc_reason) { | 558 void Heap::CollectAllGarbage(int flags, const char* gc_reason) { |
557 // Since we are ignoring the return value, the exact choice of space does | 559 // Since we are ignoring the return value, the exact choice of space does |
558 // not matter, so long as we do not specify NEW_SPACE, which would not | 560 // not matter, so long as we do not specify NEW_SPACE, which would not |
559 // cause a full GC. | 561 // cause a full GC. |
560 mark_compact_collector_.SetFlags(flags); | 562 mark_compact_collector_.SetFlags(flags); |
561 CollectGarbage(OLD_POINTER_SPACE, gc_reason); | 563 CollectGarbage(OLD_POINTER_SPACE, gc_reason); |
562 mark_compact_collector_.SetFlags(kNoGCFlags); | 564 mark_compact_collector_.SetFlags(kNoGCFlags); |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 | 1343 |
1342 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( | 1344 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
1343 &IsUnscavengedHeapObject); | 1345 &IsUnscavengedHeapObject); |
1344 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( | 1346 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
1345 &scavenge_visitor); | 1347 &scavenge_visitor); |
1346 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1348 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
1347 | 1349 |
1348 UpdateNewSpaceReferencesInExternalStringTable( | 1350 UpdateNewSpaceReferencesInExternalStringTable( |
1349 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1351 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
1350 | 1352 |
| 1353 error_object_list_.UpdateReferencesInNewSpace(this); |
| 1354 |
1351 promotion_queue_.Destroy(); | 1355 promotion_queue_.Destroy(); |
1352 | 1356 |
1353 LiveObjectList::UpdateReferencesForScavengeGC(); | 1357 LiveObjectList::UpdateReferencesForScavengeGC(); |
1354 if (!FLAG_watch_ic_patching) { | 1358 if (!FLAG_watch_ic_patching) { |
1355 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1359 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
1356 } | 1360 } |
1357 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1361 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
1358 | 1362 |
1359 ScavengeWeakObjectRetainer weak_object_retainer(this); | 1363 ScavengeWeakObjectRetainer weak_object_retainer(this); |
1360 ProcessWeakReferences(&weak_object_retainer); | 1364 ProcessWeakReferences(&weak_object_retainer); |
(...skipping 4545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5906 } | 5910 } |
5907 | 5911 |
5908 | 5912 |
5909 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { | 5913 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { |
5910 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); | 5914 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); |
5911 v->Synchronize(VisitorSynchronization::kSymbolTable); | 5915 v->Synchronize(VisitorSynchronization::kSymbolTable); |
5912 if (mode != VISIT_ALL_IN_SCAVENGE && | 5916 if (mode != VISIT_ALL_IN_SCAVENGE && |
5913 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { | 5917 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
5914 // Scavenge collections have special processing for this. | 5918 // Scavenge collections have special processing for this. |
5915 external_string_table_.Iterate(v); | 5919 external_string_table_.Iterate(v); |
| 5920 error_object_list_.Iterate(v); |
5916 } | 5921 } |
5917 v->Synchronize(VisitorSynchronization::kExternalStringsTable); | 5922 v->Synchronize(VisitorSynchronization::kExternalStringsTable); |
5918 } | 5923 } |
5919 | 5924 |
5920 | 5925 |
5921 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 5926 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { |
5922 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 5927 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); |
5923 v->Synchronize(VisitorSynchronization::kStrongRootList); | 5928 v->Synchronize(VisitorSynchronization::kStrongRootList); |
5924 | 5929 |
5925 v->VisitPointer(BitCast<Object**>(&hidden_symbol_)); | 5930 v->VisitPointer(BitCast<Object**>(&hidden_symbol_)); |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6446 PrintF("min_in_mutator=%d ", get_min_in_mutator()); | 6451 PrintF("min_in_mutator=%d ", get_min_in_mutator()); |
6447 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", | 6452 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", |
6448 get_max_alive_after_gc()); | 6453 get_max_alive_after_gc()); |
6449 PrintF("\n\n"); | 6454 PrintF("\n\n"); |
6450 } | 6455 } |
6451 | 6456 |
6452 isolate_->global_handles()->TearDown(); | 6457 isolate_->global_handles()->TearDown(); |
6453 | 6458 |
6454 external_string_table_.TearDown(); | 6459 external_string_table_.TearDown(); |
6455 | 6460 |
| 6461 error_object_list_.TearDown(); |
| 6462 |
6456 new_space_.TearDown(); | 6463 new_space_.TearDown(); |
6457 | 6464 |
6458 if (old_pointer_space_ != NULL) { | 6465 if (old_pointer_space_ != NULL) { |
6459 old_pointer_space_->TearDown(); | 6466 old_pointer_space_->TearDown(); |
6460 delete old_pointer_space_; | 6467 delete old_pointer_space_; |
6461 old_pointer_space_ = NULL; | 6468 old_pointer_space_ = NULL; |
6462 } | 6469 } |
6463 | 6470 |
6464 if (old_data_space_ != NULL) { | 6471 if (old_data_space_ != NULL) { |
6465 old_data_space_->TearDown(); | 6472 old_data_space_->TearDown(); |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7351 if (new_space_strings_[i] == heap_->the_hole_value()) { | 7358 if (new_space_strings_[i] == heap_->the_hole_value()) { |
7352 continue; | 7359 continue; |
7353 } | 7360 } |
7354 if (heap_->InNewSpace(new_space_strings_[i])) { | 7361 if (heap_->InNewSpace(new_space_strings_[i])) { |
7355 new_space_strings_[last++] = new_space_strings_[i]; | 7362 new_space_strings_[last++] = new_space_strings_[i]; |
7356 } else { | 7363 } else { |
7357 old_space_strings_.Add(new_space_strings_[i]); | 7364 old_space_strings_.Add(new_space_strings_[i]); |
7358 } | 7365 } |
7359 } | 7366 } |
7360 new_space_strings_.Rewind(last); | 7367 new_space_strings_.Rewind(last); |
| 7368 new_space_strings_.Trim(); |
| 7369 |
7361 last = 0; | 7370 last = 0; |
7362 for (int i = 0; i < old_space_strings_.length(); ++i) { | 7371 for (int i = 0; i < old_space_strings_.length(); ++i) { |
7363 if (old_space_strings_[i] == heap_->the_hole_value()) { | 7372 if (old_space_strings_[i] == heap_->the_hole_value()) { |
7364 continue; | 7373 continue; |
7365 } | 7374 } |
7366 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); | 7375 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); |
7367 old_space_strings_[last++] = old_space_strings_[i]; | 7376 old_space_strings_[last++] = old_space_strings_[i]; |
7368 } | 7377 } |
7369 old_space_strings_.Rewind(last); | 7378 old_space_strings_.Rewind(last); |
| 7379 old_space_strings_.Trim(); |
7370 #ifdef VERIFY_HEAP | 7380 #ifdef VERIFY_HEAP |
7371 if (FLAG_verify_heap) { | 7381 if (FLAG_verify_heap) { |
7372 Verify(); | 7382 Verify(); |
7373 } | 7383 } |
7374 #endif | 7384 #endif |
7375 } | 7385 } |
7376 | 7386 |
7377 | 7387 |
7378 void ExternalStringTable::TearDown() { | 7388 void ExternalStringTable::TearDown() { |
7379 new_space_strings_.Free(); | 7389 new_space_strings_.Free(); |
7380 old_space_strings_.Free(); | 7390 old_space_strings_.Free(); |
7381 } | 7391 } |
7382 | 7392 |
7383 | 7393 |
| 7394 // Update all references. |
| 7395 void ErrorObjectList::UpdateReferences() { |
| 7396 for (int i = 0; i < list_.length(); i++) { |
| 7397 HeapObject* object = HeapObject::cast(list_[i]); |
| 7398 MapWord first_word = object->map_word(); |
| 7399 if (first_word.IsForwardingAddress()) { |
| 7400 list_[i] = first_word.ToForwardingAddress(); |
| 7401 } |
| 7402 } |
| 7403 } |
| 7404 |
| 7405 |
| 7406 // Unforwarded objects in new space are dead and removed from the list. |
| 7407 void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) { |
| 7408 if (!nested_) { |
| 7409 int write_index = 0; |
| 7410 for (int i = 0; i < list_.length(); i++) { |
| 7411 MapWord first_word = HeapObject::cast(list_[i])->map_word(); |
| 7412 if (first_word.IsForwardingAddress()) { |
| 7413 list_[write_index++] = first_word.ToForwardingAddress(); |
| 7414 } |
| 7415 } |
| 7416 list_.Rewind(write_index); |
| 7417 } else { |
| 7418 // If a GC is triggered during DeferredFormatStackTrace, we do not move |
| 7419 // objects in the list, just remove dead ones, as to not confuse the |
| 7420 // loop in DeferredFormatStackTrace. |
| 7421 for (int i = 0; i < list_.length(); i++) { |
| 7422 MapWord first_word = HeapObject::cast(list_[i])->map_word(); |
| 7423 list_[i] = first_word.IsForwardingAddress() |
| 7424 ? first_word.ToForwardingAddress() |
| 7425 : heap->the_hole_value(); |
| 7426 } |
| 7427 } |
| 7428 } |
| 7429 |
| 7430 |
| 7431 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) { |
| 7432 // If formatting the stack trace causes a GC, this method will be |
| 7433 // recursively called. In that case, skip the recursive call, since |
| 7434 // the loop modifies the list while iterating over it. |
| 7435 if (nested_) return; |
| 7436 nested_ = true; |
| 7437 HandleScope scope(isolate); |
| 7438 Handle<String> stack_key = isolate->factory()->stack_symbol(); |
| 7439 int write_index = 0; |
| 7440 int budget = kBudgetPerGC; |
| 7441 for (int i = 0; i < list_.length(); i++) { |
| 7442 Object* object = list_[i]; |
| 7443 // Skip possible holes in the list. |
| 7444 if (object->IsTheHole()) continue; |
| 7445 if (isolate->heap()->InNewSpace(object) || budget == 0) { |
| 7446 list_[write_index++] = object; |
| 7447 continue; |
| 7448 } |
| 7449 |
| 7450 // Fire the stack property getter, if it is a getter defined in native code. |
| 7451 LookupResult lookup(isolate); |
| 7452 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup); |
| 7453 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue; |
| 7454 Object* callback = lookup.GetCallbackObject(); |
| 7455 if (!callback->IsAccessorPair()) continue; |
| 7456 Object* getter_obj = AccessorPair::cast(callback)->getter(); |
| 7457 if (!getter_obj->IsJSFunction()) continue; |
| 7458 JSFunction* getter_fun = JSFunction::cast(getter_obj); |
| 7459 String* key = isolate->heap()->hidden_stack_trace_symbol(); |
| 7460 if (key != getter_fun->GetHiddenProperty(key)) continue; |
| 7461 bool has_exception = false; |
| 7462 Execution::Call(Handle<Object>(getter_fun, isolate), |
| 7463 Handle<Object>(object, isolate), |
| 7464 0, |
| 7465 NULL, |
| 7466 &has_exception); |
| 7467 ASSERT(!has_exception); |
| 7468 budget--; |
| 7469 } |
| 7470 list_.Rewind(write_index); |
| 7471 list_.Trim(); |
| 7472 nested_ = false; |
| 7473 } |
| 7474 |
| 7475 |
| 7476 void ErrorObjectList::RemoveUnmarked(Heap* heap) { |
| 7477 for (int i = 0; i < list_.length(); i++) { |
| 7478 HeapObject* object = HeapObject::cast(list_[i]); |
| 7479 if (!Marking::MarkBitFrom(object).Get()) { |
| 7480 list_[i] = heap->the_hole_value(); |
| 7481 } |
| 7482 } |
| 7483 } |
| 7484 |
| 7485 |
| 7486 void ErrorObjectList::TearDown() { |
| 7487 list_.Free(); |
| 7488 } |
| 7489 |
| 7490 |
7384 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { | 7491 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { |
7385 chunk->set_next_chunk(chunks_queued_for_free_); | 7492 chunk->set_next_chunk(chunks_queued_for_free_); |
7386 chunks_queued_for_free_ = chunk; | 7493 chunks_queued_for_free_ = chunk; |
7387 } | 7494 } |
7388 | 7495 |
7389 | 7496 |
7390 void Heap::FreeQueuedChunks() { | 7497 void Heap::FreeQueuedChunks() { |
7391 if (chunks_queued_for_free_ == NULL) return; | 7498 if (chunks_queued_for_free_ == NULL) return; |
7392 MemoryChunk* next; | 7499 MemoryChunk* next; |
7393 MemoryChunk* chunk; | 7500 MemoryChunk* chunk; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7502 static_cast<int>(object_sizes_last_time_[index])); | 7609 static_cast<int>(object_sizes_last_time_[index])); |
7503 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7610 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
7504 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7611 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7505 | 7612 |
7506 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7613 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7507 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7614 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7508 ClearObjectStats(); | 7615 ClearObjectStats(); |
7509 } | 7616 } |
7510 | 7617 |
7511 } } // namespace v8::internal | 7618 } } // namespace v8::internal |
OLD | NEW |