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

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: Created 8 years 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 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 1349
1348 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( 1350 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
1349 &IsUnscavengedHeapObject); 1351 &IsUnscavengedHeapObject);
1350 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( 1352 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1351 &scavenge_visitor); 1353 &scavenge_visitor);
1352 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1354 new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1353 1355
1354 UpdateNewSpaceReferencesInExternalStringTable( 1356 UpdateNewSpaceReferencesInExternalStringTable(
1355 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1357 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1356 1358
1359 error_object_list_.UpdateReferencesInNewSpace(this);
1360
1357 promotion_queue_.Destroy(); 1361 promotion_queue_.Destroy();
1358 1362
1359 LiveObjectList::UpdateReferencesForScavengeGC(); 1363 LiveObjectList::UpdateReferencesForScavengeGC();
1360 if (!FLAG_watch_ic_patching) { 1364 if (!FLAG_watch_ic_patching) {
1361 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); 1365 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
1362 } 1366 }
1363 incremental_marking()->UpdateMarkingDequeAfterScavenge(); 1367 incremental_marking()->UpdateMarkingDequeAfterScavenge();
1364 1368
1365 ScavengeWeakObjectRetainer weak_object_retainer(this); 1369 ScavengeWeakObjectRetainer weak_object_retainer(this);
1366 ProcessWeakReferences(&weak_object_retainer); 1370 ProcessWeakReferences(&weak_object_retainer);
(...skipping 4496 matching lines...) Expand 10 before | Expand all | Expand 10 after
5863 } 5867 }
5864 5868
5865 5869
5866 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { 5870 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
5867 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); 5871 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
5868 v->Synchronize(VisitorSynchronization::kSymbolTable); 5872 v->Synchronize(VisitorSynchronization::kSymbolTable);
5869 if (mode != VISIT_ALL_IN_SCAVENGE && 5873 if (mode != VISIT_ALL_IN_SCAVENGE &&
5870 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { 5874 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) {
5871 // Scavenge collections have special processing for this. 5875 // Scavenge collections have special processing for this.
5872 external_string_table_.Iterate(v); 5876 external_string_table_.Iterate(v);
5877 error_object_list_.Iterate(v);
5873 } 5878 }
5874 v->Synchronize(VisitorSynchronization::kExternalStringsTable); 5879 v->Synchronize(VisitorSynchronization::kExternalStringsTable);
5875 } 5880 }
5876 5881
5877 5882
5878 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { 5883 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
5879 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); 5884 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
5880 v->Synchronize(VisitorSynchronization::kStrongRootList); 5885 v->Synchronize(VisitorSynchronization::kStrongRootList);
5881 5886
5882 v->VisitPointer(BitCast<Object**>(&hidden_symbol_)); 5887 v->VisitPointer(BitCast<Object**>(&hidden_symbol_));
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
6236 PrintF("min_in_mutator=%d ", get_min_in_mutator()); 6241 PrintF("min_in_mutator=%d ", get_min_in_mutator());
6237 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", 6242 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
6238 get_max_alive_after_gc()); 6243 get_max_alive_after_gc());
6239 PrintF("\n\n"); 6244 PrintF("\n\n");
6240 } 6245 }
6241 6246
6242 isolate_->global_handles()->TearDown(); 6247 isolate_->global_handles()->TearDown();
6243 6248
6244 external_string_table_.TearDown(); 6249 external_string_table_.TearDown();
6245 6250
6251 error_object_list_.TearDown();
6252
6246 new_space_.TearDown(); 6253 new_space_.TearDown();
6247 6254
6248 if (old_pointer_space_ != NULL) { 6255 if (old_pointer_space_ != NULL) {
6249 old_pointer_space_->TearDown(); 6256 old_pointer_space_->TearDown();
6250 delete old_pointer_space_; 6257 delete old_pointer_space_;
6251 old_pointer_space_ = NULL; 6258 old_pointer_space_ = NULL;
6252 } 6259 }
6253 6260
6254 if (old_data_space_ != NULL) { 6261 if (old_data_space_ != NULL) {
6255 old_data_space_->TearDown(); 6262 old_data_space_->TearDown();
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
7142 if (new_space_strings_[i] == heap_->the_hole_value()) { 7149 if (new_space_strings_[i] == heap_->the_hole_value()) {
7143 continue; 7150 continue;
7144 } 7151 }
7145 if (heap_->InNewSpace(new_space_strings_[i])) { 7152 if (heap_->InNewSpace(new_space_strings_[i])) {
7146 new_space_strings_[last++] = new_space_strings_[i]; 7153 new_space_strings_[last++] = new_space_strings_[i];
7147 } else { 7154 } else {
7148 old_space_strings_.Add(new_space_strings_[i]); 7155 old_space_strings_.Add(new_space_strings_[i]);
7149 } 7156 }
7150 } 7157 }
7151 new_space_strings_.Rewind(last); 7158 new_space_strings_.Rewind(last);
7159 new_space_strings_.Trim();
7160
7152 last = 0; 7161 last = 0;
7153 for (int i = 0; i < old_space_strings_.length(); ++i) { 7162 for (int i = 0; i < old_space_strings_.length(); ++i) {
7154 if (old_space_strings_[i] == heap_->the_hole_value()) { 7163 if (old_space_strings_[i] == heap_->the_hole_value()) {
7155 continue; 7164 continue;
7156 } 7165 }
7157 ASSERT(!heap_->InNewSpace(old_space_strings_[i])); 7166 ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
7158 old_space_strings_[last++] = old_space_strings_[i]; 7167 old_space_strings_[last++] = old_space_strings_[i];
7159 } 7168 }
7160 old_space_strings_.Rewind(last); 7169 old_space_strings_.Rewind(last);
7170 old_space_strings_.Trim();
7161 #ifdef VERIFY_HEAP 7171 #ifdef VERIFY_HEAP
7162 if (FLAG_verify_heap) { 7172 if (FLAG_verify_heap) {
7163 Verify(); 7173 Verify();
7164 } 7174 }
7165 #endif 7175 #endif
7166 } 7176 }
7167 7177
7168 7178
7169 void ExternalStringTable::TearDown() { 7179 void ExternalStringTable::TearDown() {
7170 new_space_strings_.Free(); 7180 new_space_strings_.Free();
7171 old_space_strings_.Free(); 7181 old_space_strings_.Free();
7172 } 7182 }
7173 7183
7174 7184
7185 // Update all references.
7186 void ErrorObjectList::UpdateReferences() {
7187 for (int i = 0; i < list_.length(); i++) {
7188 HeapObject* object = HeapObject::cast(list_[i]);
7189 MapWord first_word = object->map_word();
7190 if (first_word.IsForwardingAddress()) {
7191 list_[i] = first_word.ToForwardingAddress();
7192 }
7193 }
7194 }
7195
7196
7197 // Unforwarded objects in new space are dead and removed from the list.
7198 void ErrorObjectList::UpdateReferencesInNewSpace(Heap* heap) {
7199 if (!nested_) {
7200 int write_index = 0;
7201 for (int i = 0; i < list_.length(); i++) {
7202 MapWord first_word = HeapObject::cast(list_[i])->map_word();
7203 if (first_word.IsForwardingAddress()) {
7204 list_[write_index++] = first_word.ToForwardingAddress();
7205 }
7206 }
7207 list_.Rewind(write_index);
7208 } else {
7209 // If a GC is triggered during DeferredFormatStackTrace, we do not move
7210 // objects in the list, just remove dead ones, as to not confuse the
7211 // loop in DeferredFormatStackTrace.
7212 for (int i = 0; i < list_.length(); i++) {
7213 MapWord first_word = HeapObject::cast(list_[i])->map_word();
7214 list_[i] = first_word.IsForwardingAddress()
7215 ? first_word.ToForwardingAddress()
7216 : heap->the_hole_value();
7217 }
7218 }
7219 }
7220
7221
7222 void ErrorObjectList::DeferredFormatStackTrace(Isolate* isolate) {
7223 // If formatting the stack trace causes a GC, this method will be
7224 // recursively called. In that case, skip the recursive call, since
7225 // the loop modifies the list while iterating over it.
7226 if (nested_) return;
7227 nested_ = true;
7228 HandleScope scope(isolate);
7229 Handle<String> stack_key = isolate->factory()->stack_symbol();
7230 int write_index = 0;
7231 int budget = kBudgetPerGC;
7232 for (int i = 0; i < list_.length(); i++) {
7233 Object* object = list_[i];
7234 // Skip possible holes in the list.
7235 if (object->IsTheHole()) continue;
7236 if (isolate->heap()->InNewSpace(object) || budget == 0) {
7237 list_[write_index++] = object;
7238 continue;
7239 }
7240
7241 // Fire the stack property getter, if it is the original marked getter.
7242 LookupResult lookup(isolate);
7243 JSObject::cast(object)->LocalLookupRealNamedProperty(*stack_key, &lookup);
7244 if (!lookup.IsFound() || lookup.type() != CALLBACKS) continue;
7245 Object* callback = lookup.GetCallbackObject();
7246 if (!callback->IsAccessorPair()) continue;
7247 Object* getter_obj = AccessorPair::cast(callback)->getter();
7248 if (!getter_obj->IsJSFunction()) continue;
7249 JSFunction* getter_fun = JSFunction::cast(getter_obj);
7250 String* key = isolate->heap()->hidden_stack_trace_symbol();
7251 if (key != getter_fun->GetHiddenProperty(key)) continue;
7252 bool has_exception = false;
7253 Execution::Call(Handle<Object>(getter_fun, isolate),
7254 Handle<Object>(object, isolate),
7255 0,
7256 NULL,
7257 &has_exception);
7258 ASSERT(!has_exception);
7259 budget--;
7260 }
7261 list_.Rewind(write_index);
7262 list_.Trim();
7263 nested_ = false;
7264 }
7265
7266
7267 void ErrorObjectList::RemoveUnmarked(Heap* heap) {
7268 for (int i = 0; i < list_.length(); i++) {
7269 HeapObject* object = HeapObject::cast(list_[i]);
7270 if (!Marking::MarkBitFrom(object).Get()) {
7271 list_[i] = heap->the_hole_value();
7272 }
7273 }
7274 }
7275
7276
7277 void ErrorObjectList::TearDown() {
7278 list_.Free();
7279 }
7280
7281
7175 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { 7282 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) {
7176 chunk->set_next_chunk(chunks_queued_for_free_); 7283 chunk->set_next_chunk(chunks_queued_for_free_);
7177 chunks_queued_for_free_ = chunk; 7284 chunks_queued_for_free_ = chunk;
7178 } 7285 }
7179 7286
7180 7287
7181 void Heap::FreeQueuedChunks() { 7288 void Heap::FreeQueuedChunks() {
7182 if (chunks_queued_for_free_ == NULL) return; 7289 if (chunks_queued_for_free_ == NULL) return;
7183 MemoryChunk* next; 7290 MemoryChunk* next;
7184 MemoryChunk* chunk; 7291 MemoryChunk* chunk;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
7293 static_cast<int>(object_sizes_last_time_[index])); 7400 static_cast<int>(object_sizes_last_time_[index]));
7294 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 7401 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
7295 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7402 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7296 7403
7297 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7404 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7298 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7405 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7299 ClearObjectStats(); 7406 ClearObjectStats();
7300 } 7407 }
7301 7408
7302 } } // namespace v8::internal 7409 } } // 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