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

Side by Side Diff: src/heap.cc

Issue 11377158: Fire 'stack' getter of error objects after GC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments. Created 8 years, 1 month 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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 if (!getter_fun->shared()->native()) continue;
Vyacheslav Egorov (Google) 2012/11/20 17:30:42 I don't think this can guard you well enough. Here
7460 bool has_exception = false;
7461 Execution::Call(Handle<Object>(getter_fun, isolate),
7462 Handle<Object>(object, isolate),
7463 0,
7464 NULL,
7465 &has_exception);
7466 ASSERT(!has_exception);
7467 budget--;
7468 }
7469 list_.Rewind(write_index);
7470 list_.Trim();
7471 nested_ = false;
7472 }
7473
7474
7475 void ErrorObjectList::RemoveUnmarked(Heap* heap) {
7476 for (int i = 0; i < list_.length(); i++) {
7477 HeapObject* object = HeapObject::cast(list_[i]);
7478 if (!Marking::MarkBitFrom(object).Get()) {
7479 list_[i] = heap->the_hole_value();
7480 }
7481 }
7482 }
7483
7484
7485 void ErrorObjectList::TearDown() {
7486 list_.Free();
7487 }
7488
7489
7384 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { 7490 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
7385 chunk->set_next_chunk(chunks_queued_for_free_); 7491 chunk->set_next_chunk(chunks_queued_for_free_);
7386 chunks_queued_for_free_ = chunk; 7492 chunks_queued_for_free_ = chunk;
7387 } 7493 }
7388 7494
7389 7495
7390 void Heap::FreeQueuedChunks() { 7496 void Heap::FreeQueuedChunks() {
7391 if (chunks_queued_for_free_ == NULL) return; 7497 if (chunks_queued_for_free_ == NULL) return;
7392 MemoryChunk* next; 7498 MemoryChunk* next;
7393 MemoryChunk* chunk; 7499 MemoryChunk* chunk;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
7502 static_cast<int>(object_sizes_last_time_[index])); 7608 static_cast<int>(object_sizes_last_time_[index]));
7503 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 7609 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
7504 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7610 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7505 7611
7506 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7612 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7507 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7613 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7508 ClearObjectStats(); 7614 ClearObjectStats();
7509 } 7615 }
7510 7616
7511 } } // namespace v8::internal 7617 } } // 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