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

Side by Side Diff: src/heap.cc

Issue 11880018: Reland r13188, r13194, r13256 (Deferred formatting of error stack trace during GC). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.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 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
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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 1372
1371 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( 1373 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
1372 &IsUnscavengedHeapObject); 1374 &IsUnscavengedHeapObject);
1373 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( 1375 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1374 &scavenge_visitor); 1376 &scavenge_visitor);
1375 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1377 new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1376 1378
1377 UpdateNewSpaceReferencesInExternalStringTable( 1379 UpdateNewSpaceReferencesInExternalStringTable(
1378 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1380 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1379 1381
1382 error_object_list_.UpdateReferencesInNewSpace(this);
1383
1380 promotion_queue_.Destroy(); 1384 promotion_queue_.Destroy();
1381 1385
1382 LiveObjectList::UpdateReferencesForScavengeGC(); 1386 LiveObjectList::UpdateReferencesForScavengeGC();
1383 if (!FLAG_watch_ic_patching) { 1387 if (!FLAG_watch_ic_patching) {
1384 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); 1388 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
1385 } 1389 }
1386 incremental_marking()->UpdateMarkingDequeAfterScavenge(); 1390 incremental_marking()->UpdateMarkingDequeAfterScavenge();
1387 1391
1388 ScavengeWeakObjectRetainer weak_object_retainer(this); 1392 ScavengeWeakObjectRetainer weak_object_retainer(this);
1389 ProcessWeakReferences(&weak_object_retainer); 1393 ProcessWeakReferences(&weak_object_retainer);
(...skipping 4562 matching lines...) Expand 10 before | Expand all | Expand 10 after
5952 } 5956 }
5953 5957
5954 5958
5955 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { 5959 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
5956 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); 5960 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
5957 v->Synchronize(VisitorSynchronization::kSymbolTable); 5961 v->Synchronize(VisitorSynchronization::kSymbolTable);
5958 if (mode != VISIT_ALL_IN_SCAVENGE && 5962 if (mode != VISIT_ALL_IN_SCAVENGE &&
5959 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { 5963 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
5960 // Scavenge collections have special processing for this. 5964 // Scavenge collections have special processing for this.
5961 external_string_table_.Iterate(v); 5965 external_string_table_.Iterate(v);
5966 error_object_list_.Iterate(v);
5962 } 5967 }
5963 v->Synchronize(VisitorSynchronization::kExternalStringsTable); 5968 v->Synchronize(VisitorSynchronization::kExternalStringsTable);
5964 } 5969 }
5965 5970
5966 5971
5967 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { 5972 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
5968 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); 5973 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
5969 v->Synchronize(VisitorSynchronization::kStrongRootList); 5974 v->Synchronize(VisitorSynchronization::kStrongRootList);
5970 5975
5971 v->VisitPointer(BitCast<Object**>(&hidden_symbol_)); 5976 v->VisitPointer(BitCast<Object**>(&hidden_symbol_));
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
6325 PrintF("min_in_mutator=%d ", get_min_in_mutator()); 6330 PrintF("min_in_mutator=%d ", get_min_in_mutator());
6326 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", 6331 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
6327 get_max_alive_after_gc()); 6332 get_max_alive_after_gc());
6328 PrintF("\n\n"); 6333 PrintF("\n\n");
6329 } 6334 }
6330 6335
6331 isolate_->global_handles()->TearDown(); 6336 isolate_->global_handles()->TearDown();
6332 6337
6333 external_string_table_.TearDown(); 6338 external_string_table_.TearDown();
6334 6339
6340 error_object_list_.TearDown();
6341
6335 new_space_.TearDown(); 6342 new_space_.TearDown();
6336 6343
6337 if (old_pointer_space_ != NULL) { 6344 if (old_pointer_space_ != NULL) {
6338 old_pointer_space_->TearDown(); 6345 old_pointer_space_->TearDown();
6339 delete old_pointer_space_; 6346 delete old_pointer_space_;
6340 old_pointer_space_ = NULL; 6347 old_pointer_space_ = NULL;
6341 } 6348 }
6342 6349
6343 if (old_data_space_ != NULL) { 6350 if (old_data_space_ != NULL) {
6344 old_data_space_->TearDown(); 6351 old_data_space_->TearDown();
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
7231 if (new_space_strings_[i] == heap_->the_hole_value()) { 7238 if (new_space_strings_[i] == heap_->the_hole_value()) {
7232 continue; 7239 continue;
7233 } 7240 }
7234 if (heap_->InNewSpace(new_space_strings_[i])) { 7241 if (heap_->InNewSpace(new_space_strings_[i])) {
7235 new_space_strings_[last++] = new_space_strings_[i]; 7242 new_space_strings_[last++] = new_space_strings_[i];
7236 } else { 7243 } else {
7237 old_space_strings_.Add(new_space_strings_[i]); 7244 old_space_strings_.Add(new_space_strings_[i]);
7238 } 7245 }
7239 } 7246 }
7240 new_space_strings_.Rewind(last); 7247 new_space_strings_.Rewind(last);
7248 new_space_strings_.Trim();
7249
7241 last = 0; 7250 last = 0;
7242 for (int i = 0; i < old_space_strings_.length(); ++i) { 7251 for (int i = 0; i < old_space_strings_.length(); ++i) {
7243 if (old_space_strings_[i] == heap_->the_hole_value()) { 7252 if (old_space_strings_[i] == heap_->the_hole_value()) {
7244 continue; 7253 continue;
7245 } 7254 }
7246 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); 7255 ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
7247 old_space_strings_[last++] = old_space_strings_[i]; 7256 old_space_strings_[last++] = old_space_strings_[i];
7248 } 7257 }
7249 old_space_strings_.Rewind(last); 7258 old_space_strings_.Rewind(last);
7259 old_space_strings_.Trim();
7250 #ifdef VERIFY_HEAP 7260 #ifdef VERIFY_HEAP
7251 if (FLAG_verify_heap) { 7261 if (FLAG_verify_heap) {
7252 Verify(); 7262 Verify();
7253 } 7263 }
7254 #endif 7264 #endif
7255 } 7265 }
7256 7266
7257 7267
7258 void ExternalStringTable::TearDown() { 7268 void ExternalStringTable::TearDown() {
7259 new_space_strings_.Free(); 7269 new_space_strings_.Free();
7260 old_space_strings_.Free(); 7270 old_space_strings_.Free();
7261 } 7271 }
7262 7272
7263 7273
7274 // Update all references.
7275 void ErrorObjectList::UpdateReferences() {
7276 for (int i = 0; i < list_.length(); i++) {
7277 HeapObject* object = HeapObject::cast(list_[i]);
7278 MapWord first_word = object->map_word();
7279 if (first_word.IsForwardingAddress()) {
7280 list_[i] = first_word.ToForwardingAddress();
7281 }
7282 }
7283 }
7284
7285
7286 // Unforwarded objects in new space are dead and removed from the list.
7287 void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) {
7288 if (!nested_) {
7289 int write_index = 0;
7290 for (int i = 0; i < list_.length(); i++) {
7291 MapWord first_word = HeapObject::cast(list_[i])->map_word();
7292 if (first_word.IsForwardingAddress()) {
7293 list_[write_index++] = first_word.ToForwardingAddress();
7294 }
7295 }
7296 list_.Rewind(write_index);
7297 } else {
7298 // If a GC is triggered during DeferredFormatStackTrace, we do not move
7299 // objects in the list, just remove dead ones, as to not confuse the
7300 // loop in DeferredFormatStackTrace.
7301 for (int i = 0; i < list_.length(); i++) {
7302 MapWord first_word = HeapObject::cast(list_[i])->map_word();
7303 list_[i] = first_word.IsForwardingAddress()
7304 ? first_word.ToForwardingAddress()
7305 : heap->the_hole_value();
7306 }
7307 }
7308 }
7309
7310
7311 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) {
7312 // If formatting the stack trace causes a GC, this method will be
7313 // recursively called. In that case, skip the recursive call, since
7314 // the loop modifies the list while iterating over it.
7315 if (nested_ || isolate->has_pending_exception()) return;
7316 nested_ = true;
7317 HandleScope scope(isolate);
7318 Handle<String> stack_key = isolate->factory()->stack_symbol();
7319 int write_index = 0;
7320 int budget = kBudgetPerGC;
7321 for (int i = 0; i < list_.length(); i++) {
7322 Object* object = list_[i];
7323 JSFunction* getter_fun;
7324
7325 { AssertNoAllocation assert;
7326 // Skip possible holes in the list.
7327 if (object->IsTheHole()) continue;
7328 if (isolate->heap()->InNewSpace(object) || budget == 0) {
7329 list_[write_index++] = object;
7330 continue;
7331 }
7332
7333 // Check whether the stack property is backed by the original getter.
7334 LookupResult lookup(isolate);
7335 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup);
7336 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue;
7337 Object* callback = lookup.GetCallbackObject();
7338 if (!callback->IsAccessorPair()) continue;
7339 Object* getter_obj = AccessorPair::cast(callback)->getter();
7340 if (!getter_obj->IsJSFunction()) continue;
7341 getter_fun = JSFunction::cast(getter_obj);
7342 String* key = isolate->heap()->hidden_stack_trace_symbol();
7343 if (key != getter_fun->GetHiddenProperty(key)) continue;
7344 }
7345
7346 budget--;
7347 HandleScope scope(isolate);
7348 bool has_exception = false;
7349 Handle<Map> map(HeapObject::cast(object)->map(), isolate);
7350 Handle<Object> object_handle(object, isolate);
7351 Handle<Object> getter_handle(getter_fun, isolate);
7352 Execution::Call(getter_handle, object_handle, 0, NULL, &has_exception);
7353 CHECK(*map == HeapObject::cast(*object_handle)->map());
7354 if (has_exception) {
7355 // Hit an exception (most likely a stack overflow).
7356 // Wrap up this pass and retry after another GC.
7357 isolate->clear_pending_exception();
7358 // We use the handle since calling the getter might have caused a GC.
7359 list_[write_index++] = *object_handle;
7360 budget = 0;
7361 }
7362 }
7363 list_.Rewind(write_index);
7364 list_.Trim();
7365 nested_ = false;
7366 }
7367
7368
7369 void ErrorObjectList::RemoveUnmarked(Heap* heap) {
7370 for (int i = 0; i < list_.length(); i++) {
7371 HeapObject* object = HeapObject::cast(list_[i]);
7372 if (!Marking::MarkBitFrom(object).Get()) {
7373 list_[i] = heap->the_hole_value();
7374 }
7375 }
7376 }
7377
7378
7379 void ErrorObjectList::TearDown() {
7380 list_.Free();
7381 }
7382
7383
7264 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { 7384 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
7265 chunk->set_next_chunk(chunks_queued_for_free_); 7385 chunk->set_next_chunk(chunks_queued_for_free_);
7266 chunks_queued_for_free_ = chunk; 7386 chunks_queued_for_free_ = chunk;
7267 } 7387 }
7268 7388
7269 7389
7270 void Heap::FreeQueuedChunks() { 7390 void Heap::FreeQueuedChunks() {
7271 if (chunks_queued_for_free_ == NULL) return; 7391 if (chunks_queued_for_free_ == NULL) return;
7272 MemoryChunk* next; 7392 MemoryChunk* next;
7273 MemoryChunk* chunk; 7393 MemoryChunk* chunk;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
7382 static_cast<int>(object_sizes_last_time_[index])); 7502 static_cast<int>(object_sizes_last_time_[index]));
7383 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 7503 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
7384 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7504 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7385 7505
7386 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7506 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7387 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7507 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7388 ClearObjectStats(); 7508 ClearObjectStats();
7389 } 7509 }
7390 7510
7391 } } // namespace v8::internal 7511 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698