| 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 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 #undef UPDATE_COUNTERS_FOR_SPACE | 576 #undef UPDATE_COUNTERS_FOR_SPACE |
| 577 #undef UPDATE_FRAGMENTATION_FOR_SPACE | 577 #undef UPDATE_FRAGMENTATION_FOR_SPACE |
| 578 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE | 578 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE |
| 579 | 579 |
| 580 #if defined(DEBUG) | 580 #if defined(DEBUG) |
| 581 ReportStatisticsAfterGC(); | 581 ReportStatisticsAfterGC(); |
| 582 #endif // DEBUG | 582 #endif // DEBUG |
| 583 #ifdef ENABLE_DEBUGGER_SUPPORT | 583 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 584 isolate_->debug()->AfterGarbageCollection(); | 584 isolate_->debug()->AfterGarbageCollection(); |
| 585 #endif // ENABLE_DEBUGGER_SUPPORT | 585 #endif // ENABLE_DEBUGGER_SUPPORT |
| 586 | |
| 587 error_object_list_.DeferredFormatStackTrace(isolate()); | |
| 588 } | 586 } |
| 589 | 587 |
| 590 | 588 |
| 591 void Heap::CollectAllGarbage(int flags, const char* gc_reason) { | 589 void Heap::CollectAllGarbage(int flags, const char* gc_reason) { |
| 592 // Since we are ignoring the return value, the exact choice of space does | 590 // Since we are ignoring the return value, the exact choice of space does |
| 593 // not matter, so long as we do not specify NEW_SPACE, which would not | 591 // not matter, so long as we do not specify NEW_SPACE, which would not |
| 594 // cause a full GC. | 592 // cause a full GC. |
| 595 mark_compact_collector_.SetFlags(flags); | 593 mark_compact_collector_.SetFlags(flags); |
| 596 CollectGarbage(OLD_POINTER_SPACE, gc_reason); | 594 CollectGarbage(OLD_POINTER_SPACE, gc_reason); |
| 597 mark_compact_collector_.SetFlags(kNoGCFlags); | 595 mark_compact_collector_.SetFlags(kNoGCFlags); |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 | 1419 |
| 1422 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( | 1420 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
| 1423 &IsUnscavengedHeapObject); | 1421 &IsUnscavengedHeapObject); |
| 1424 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( | 1422 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
| 1425 &scavenge_visitor); | 1423 &scavenge_visitor); |
| 1426 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1424 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1427 | 1425 |
| 1428 UpdateNewSpaceReferencesInExternalStringTable( | 1426 UpdateNewSpaceReferencesInExternalStringTable( |
| 1429 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1427 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1430 | 1428 |
| 1431 error_object_list_.UpdateReferencesInNewSpace(this); | |
| 1432 | |
| 1433 promotion_queue_.Destroy(); | 1429 promotion_queue_.Destroy(); |
| 1434 | 1430 |
| 1435 if (!FLAG_watch_ic_patching) { | 1431 if (!FLAG_watch_ic_patching) { |
| 1436 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1432 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1437 } | 1433 } |
| 1438 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1434 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1439 | 1435 |
| 1440 ScavengeWeakObjectRetainer weak_object_retainer(this); | 1436 ScavengeWeakObjectRetainer weak_object_retainer(this); |
| 1441 ProcessWeakReferences(&weak_object_retainer); | 1437 ProcessWeakReferences(&weak_object_retainer); |
| 1442 | 1438 |
| (...skipping 5125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6568 } | 6564 } |
| 6569 | 6565 |
| 6570 | 6566 |
| 6571 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { | 6567 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { |
| 6572 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex])); | 6568 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex])); |
| 6573 v->Synchronize(VisitorSynchronization::kStringTable); | 6569 v->Synchronize(VisitorSynchronization::kStringTable); |
| 6574 if (mode != VISIT_ALL_IN_SCAVENGE && | 6570 if (mode != VISIT_ALL_IN_SCAVENGE && |
| 6575 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { | 6571 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
| 6576 // Scavenge collections have special processing for this. | 6572 // Scavenge collections have special processing for this. |
| 6577 external_string_table_.Iterate(v); | 6573 external_string_table_.Iterate(v); |
| 6578 error_object_list_.Iterate(v); | |
| 6579 } | 6574 } |
| 6580 v->Synchronize(VisitorSynchronization::kExternalStringsTable); | 6575 v->Synchronize(VisitorSynchronization::kExternalStringsTable); |
| 6581 } | 6576 } |
| 6582 | 6577 |
| 6583 | 6578 |
| 6584 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 6579 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { |
| 6585 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 6580 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); |
| 6586 v->Synchronize(VisitorSynchronization::kStrongRootList); | 6581 v->Synchronize(VisitorSynchronization::kStrongRootList); |
| 6587 | 6582 |
| 6588 v->VisitPointer(BitCast<Object**>(&hidden_string_)); | 6583 v->VisitPointer(BitCast<Object**>(&hidden_string_)); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6968 PrintF("total_sweeping_time=%.1f ", sweeping_time()); | 6963 PrintF("total_sweeping_time=%.1f ", sweeping_time()); |
| 6969 PrintF("\n\n"); | 6964 PrintF("\n\n"); |
| 6970 } | 6965 } |
| 6971 | 6966 |
| 6972 TearDownArrayBuffers(); | 6967 TearDownArrayBuffers(); |
| 6973 | 6968 |
| 6974 isolate_->global_handles()->TearDown(); | 6969 isolate_->global_handles()->TearDown(); |
| 6975 | 6970 |
| 6976 external_string_table_.TearDown(); | 6971 external_string_table_.TearDown(); |
| 6977 | 6972 |
| 6978 error_object_list_.TearDown(); | |
| 6979 | |
| 6980 new_space_.TearDown(); | 6973 new_space_.TearDown(); |
| 6981 | 6974 |
| 6982 if (old_pointer_space_ != NULL) { | 6975 if (old_pointer_space_ != NULL) { |
| 6983 old_pointer_space_->TearDown(); | 6976 old_pointer_space_->TearDown(); |
| 6984 delete old_pointer_space_; | 6977 delete old_pointer_space_; |
| 6985 old_pointer_space_ = NULL; | 6978 old_pointer_space_ = NULL; |
| 6986 } | 6979 } |
| 6987 | 6980 |
| 6988 if (old_data_space_ != NULL) { | 6981 if (old_data_space_ != NULL) { |
| 6989 old_data_space_->TearDown(); | 6982 old_data_space_->TearDown(); |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7922 #endif | 7915 #endif |
| 7923 } | 7916 } |
| 7924 | 7917 |
| 7925 | 7918 |
| 7926 void ExternalStringTable::TearDown() { | 7919 void ExternalStringTable::TearDown() { |
| 7927 new_space_strings_.Free(); | 7920 new_space_strings_.Free(); |
| 7928 old_space_strings_.Free(); | 7921 old_space_strings_.Free(); |
| 7929 } | 7922 } |
| 7930 | 7923 |
| 7931 | 7924 |
| 7932 // Update all references. | |
| 7933 void ErrorObjectList::UpdateReferences() { | |
| 7934 for (int i = 0; i < list_.length(); i++) { | |
| 7935 HeapObject* object = HeapObject::cast(list_[i]); | |
| 7936 MapWord first_word = object->map_word(); | |
| 7937 if (first_word.IsForwardingAddress()) { | |
| 7938 list_[i] = first_word.ToForwardingAddress(); | |
| 7939 } | |
| 7940 } | |
| 7941 } | |
| 7942 | |
| 7943 | |
| 7944 // Unforwarded objects in new space are dead and removed from the list. | |
| 7945 void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) { | |
| 7946 if (list_.is_empty()) return; | |
| 7947 if (!nested_) { | |
| 7948 int write_index = 0; | |
| 7949 for (int i = 0; i < list_.length(); i++) { | |
| 7950 MapWord first_word = HeapObject::cast(list_[i])->map_word(); | |
| 7951 if (first_word.IsForwardingAddress()) { | |
| 7952 list_[write_index++] = first_word.ToForwardingAddress(); | |
| 7953 } | |
| 7954 } | |
| 7955 list_.Rewind(write_index); | |
| 7956 } else { | |
| 7957 // If a GC is triggered during DeferredFormatStackTrace, we do not move | |
| 7958 // objects in the list, just remove dead ones, as to not confuse the | |
| 7959 // loop in DeferredFormatStackTrace. | |
| 7960 for (int i = 0; i < list_.length(); i++) { | |
| 7961 MapWord first_word = HeapObject::cast(list_[i])->map_word(); | |
| 7962 list_[i] = first_word.IsForwardingAddress() | |
| 7963 ? first_word.ToForwardingAddress() | |
| 7964 : heap->the_hole_value(); | |
| 7965 } | |
| 7966 } | |
| 7967 } | |
| 7968 | |
| 7969 | |
| 7970 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) { | |
| 7971 // If formatting the stack trace causes a GC, this method will be | |
| 7972 // recursively called. In that case, skip the recursive call, since | |
| 7973 // the loop modifies the list while iterating over it. | |
| 7974 if (nested_ || list_.is_empty() || isolate->has_pending_exception()) return; | |
| 7975 nested_ = true; | |
| 7976 HandleScope scope(isolate); | |
| 7977 Handle<String> stack_key = isolate->factory()->stack_string(); | |
| 7978 int write_index = 0; | |
| 7979 int budget = kBudgetPerGC; | |
| 7980 for (int i = 0; i < list_.length(); i++) { | |
| 7981 Object* object = list_[i]; | |
| 7982 JSFunction* getter_fun; | |
| 7983 | |
| 7984 { DisallowHeapAllocation no_gc; | |
| 7985 // Skip possible holes in the list. | |
| 7986 if (object->IsTheHole()) continue; | |
| 7987 if (isolate->heap()->InNewSpace(object) || budget == 0) { | |
| 7988 list_[write_index++] = object; | |
| 7989 continue; | |
| 7990 } | |
| 7991 | |
| 7992 // Check whether the stack property is backed by the original getter. | |
| 7993 LookupResult lookup(isolate); | |
| 7994 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup); | |
| 7995 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue; | |
| 7996 Object* callback = lookup.GetCallbackObject(); | |
| 7997 if (!callback->IsAccessorPair()) continue; | |
| 7998 Object* getter_obj = AccessorPair::cast(callback)->getter(); | |
| 7999 if (!getter_obj->IsJSFunction()) continue; | |
| 8000 getter_fun = JSFunction::cast(getter_obj); | |
| 8001 String* key = isolate->heap()->hidden_stack_trace_string(); | |
| 8002 Object* value = getter_fun->GetHiddenProperty(key); | |
| 8003 if (key != value) continue; | |
| 8004 } | |
| 8005 | |
| 8006 budget--; | |
| 8007 HandleScope scope(isolate); | |
| 8008 bool has_exception = false; | |
| 8009 #ifdef DEBUG | |
| 8010 Handle<Map> map(HeapObject::cast(object)->map(), isolate); | |
| 8011 #endif | |
| 8012 Handle<Object> object_handle(object, isolate); | |
| 8013 Handle<Object> getter_handle(getter_fun, isolate); | |
| 8014 Execution::Call(getter_handle, object_handle, 0, NULL, &has_exception); | |
| 8015 ASSERT(*map == HeapObject::cast(*object_handle)->map()); | |
| 8016 if (has_exception) { | |
| 8017 // Hit an exception (most likely a stack overflow). | |
| 8018 // Wrap up this pass and retry after another GC. | |
| 8019 isolate->clear_pending_exception(); | |
| 8020 // We use the handle since calling the getter might have caused a GC. | |
| 8021 list_[write_index++] = *object_handle; | |
| 8022 budget = 0; | |
| 8023 } | |
| 8024 } | |
| 8025 list_.Rewind(write_index); | |
| 8026 list_.Trim(); | |
| 8027 nested_ = false; | |
| 8028 } | |
| 8029 | |
| 8030 | |
| 8031 void ErrorObjectList::RemoveUnmarked(Heap* heap) { | |
| 8032 for (int i = 0; i < list_.length(); i++) { | |
| 8033 HeapObject* object = HeapObject::cast(list_[i]); | |
| 8034 if (!Marking::MarkBitFrom(object).Get()) { | |
| 8035 list_[i] = heap->the_hole_value(); | |
| 8036 } | |
| 8037 } | |
| 8038 } | |
| 8039 | |
| 8040 | |
| 8041 void ErrorObjectList::TearDown() { | |
| 8042 list_.Free(); | |
| 8043 } | |
| 8044 | |
| 8045 | |
| 8046 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { | 7925 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { |
| 8047 chunk->set_next_chunk(chunks_queued_for_free_); | 7926 chunk->set_next_chunk(chunks_queued_for_free_); |
| 8048 chunks_queued_for_free_ = chunk; | 7927 chunks_queued_for_free_ = chunk; |
| 8049 } | 7928 } |
| 8050 | 7929 |
| 8051 | 7930 |
| 8052 void Heap::FreeQueuedChunks() { | 7931 void Heap::FreeQueuedChunks() { |
| 8053 if (chunks_queued_for_free_ == NULL) return; | 7932 if (chunks_queued_for_free_ == NULL) return; |
| 8054 MemoryChunk* next; | 7933 MemoryChunk* next; |
| 8055 MemoryChunk* chunk; | 7934 MemoryChunk* chunk; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8175 if (FLAG_parallel_recompilation) { | 8054 if (FLAG_parallel_recompilation) { |
| 8176 heap_->relocation_mutex_->Lock(); | 8055 heap_->relocation_mutex_->Lock(); |
| 8177 #ifdef DEBUG | 8056 #ifdef DEBUG |
| 8178 heap_->relocation_mutex_locked_by_optimizer_thread_ = | 8057 heap_->relocation_mutex_locked_by_optimizer_thread_ = |
| 8179 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); | 8058 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); |
| 8180 #endif // DEBUG | 8059 #endif // DEBUG |
| 8181 } | 8060 } |
| 8182 } | 8061 } |
| 8183 | 8062 |
| 8184 } } // namespace v8::internal | 8063 } } // namespace v8::internal |
| OLD | NEW |