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

Side by Side Diff: src/heap.cc

Issue 6745033: On store buffer overflow we mark individidual pages for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #endif 53 #endif
54 54
55 55
56 namespace v8 { 56 namespace v8 {
57 namespace internal { 57 namespace internal {
58 58
59 59
60 String* Heap::hidden_symbol_; 60 String* Heap::hidden_symbol_;
61 Object* Heap::roots_[Heap::kRootListLength]; 61 Object* Heap::roots_[Heap::kRootListLength];
62 Object* Heap::global_contexts_list_; 62 Object* Heap::global_contexts_list_;
63 StoreBufferRebuilder Heap::store_buffer_rebuilder_;
63 64
64 65
65 NewSpace Heap::new_space_; 66 NewSpace Heap::new_space_;
66 OldSpace* Heap::old_pointer_space_ = NULL; 67 OldSpace* Heap::old_pointer_space_ = NULL;
67 OldSpace* Heap::old_data_space_ = NULL; 68 OldSpace* Heap::old_data_space_ = NULL;
68 OldSpace* Heap::code_space_ = NULL; 69 OldSpace* Heap::code_space_ = NULL;
69 MapSpace* Heap::map_space_ = NULL; 70 MapSpace* Heap::map_space_ = NULL;
70 CellSpace* Heap::cell_space_ = NULL; 71 CellSpace* Heap::cell_space_ = NULL;
71 LargeObjectSpace* Heap::lo_space_ = NULL; 72 LargeObjectSpace* Heap::lo_space_ = NULL;
72 73
(...skipping 16 matching lines...) Expand all
89 int Heap::initial_semispace_size_ = 128*KB; 90 int Heap::initial_semispace_size_ = 128*KB;
90 intptr_t Heap::code_range_size_ = 0; 91 intptr_t Heap::code_range_size_ = 0;
91 intptr_t Heap::max_executable_size_ = max_old_generation_size_; 92 intptr_t Heap::max_executable_size_ = max_old_generation_size_;
92 #elif defined(V8_TARGET_ARCH_X64) 93 #elif defined(V8_TARGET_ARCH_X64)
93 static const int default_max_semispace_size_ = 16*MB; 94 static const int default_max_semispace_size_ = 16*MB;
94 intptr_t Heap::max_old_generation_size_ = 1*GB; 95 intptr_t Heap::max_old_generation_size_ = 1*GB;
95 int Heap::initial_semispace_size_ = 1*MB; 96 int Heap::initial_semispace_size_ = 1*MB;
96 intptr_t Heap::code_range_size_ = 512*MB; 97 intptr_t Heap::code_range_size_ = 512*MB;
97 intptr_t Heap::max_executable_size_ = 256*MB; 98 intptr_t Heap::max_executable_size_ = 256*MB;
98 #else 99 #else
99 static const int default_max_semispace_size_ = 8*MB; 100 static const int default_max_semispace_size_ = 4*MB;
100 intptr_t Heap::max_old_generation_size_ = 512*MB; 101 intptr_t Heap::max_old_generation_size_ = 512*MB;
101 int Heap::initial_semispace_size_ = 512*KB; 102 int Heap::initial_semispace_size_ = 512*KB;
102 intptr_t Heap::code_range_size_ = 0; 103 intptr_t Heap::code_range_size_ = 0;
103 intptr_t Heap::max_executable_size_ = 128*MB; 104 intptr_t Heap::max_executable_size_ = 128*MB;
104 #endif 105 #endif
105 106
106 // Allow build-time customization of the max semispace size. Building 107 // Allow build-time customization of the max semispace size. Building
107 // V8 with snapshots and a non-default max semispace size is much 108 // V8 with snapshots and a non-default max semispace size is much
108 // easier if you can define it as part of the build environment. 109 // easier if you can define it as part of the build environment.
109 #if defined(V8_MAX_SEMISPACE_SIZE) 110 #if defined(V8_MAX_SEMISPACE_SIZE)
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 if (collector == SCAVENGER && 474 if (collector == SCAVENGER &&
474 IncrementalMarking::state() != IncrementalMarking::STOPPED) { 475 IncrementalMarking::state() != IncrementalMarking::STOPPED) {
475 if (FLAG_trace_incremental_marking) { 476 if (FLAG_trace_incremental_marking) {
476 PrintF("[IncrementalMarking] Scavenge during marking.\n"); 477 PrintF("[IncrementalMarking] Scavenge during marking.\n");
477 } 478 }
478 } 479 }
479 480
480 if (collector == MARK_COMPACTOR && 481 if (collector == MARK_COMPACTOR &&
481 !MarkCompactCollector::PreciseSweepingRequired() && 482 !MarkCompactCollector::PreciseSweepingRequired() &&
482 IncrementalMarking::state() == IncrementalMarking::MARKING && 483 IncrementalMarking::state() == IncrementalMarking::MARKING &&
484 !IncrementalMarking::should_hurry() &&
483 FLAG_incremental_marking_steps) { 485 FLAG_incremental_marking_steps) {
484 if (FLAG_trace_incremental_marking) { 486 if (FLAG_trace_incremental_marking) {
485 PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); 487 PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
486 } 488 }
487 collector = SCAVENGER; 489 collector = SCAVENGER;
488 } 490 }
489 491
492 IncrementalMarking::set_should_hurry(false);
Vyacheslav Egorov (Chromium) 2011/03/28 15:13:19 I think nicer place to clean the flag is in the In
Erik Corry 2011/03/28 15:56:07 Done and made it private.
493
490 bool next_gc_likely_to_collect_more = false; 494 bool next_gc_likely_to_collect_more = false;
491 495
492 { GCTracer tracer; 496 { GCTracer tracer;
493 GarbageCollectionPrologue(); 497 GarbageCollectionPrologue();
494 // The GC count was incremented in the prologue. Tell the tracer about 498 // The GC count was incremented in the prologue. Tell the tracer about
495 // it. 499 // it.
496 tracer.set_gc_count(gc_count_); 500 tracer.set_gc_count(gc_count_);
497 501
498 // Tell the tracer which collector we've selected. 502 // Tell the tracer which collector we've selected.
499 tracer.set_collector(collector); 503 tracer.set_collector(collector);
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 if (new_space_.Capacity() < new_space_.MaximumCapacity() && 948 if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
945 survived_since_last_expansion_ > new_space_.Capacity()) { 949 survived_since_last_expansion_ > new_space_.Capacity()) {
946 // Grow the size of new space if there is room to grow and enough 950 // Grow the size of new space if there is room to grow and enough
947 // data has survived scavenge since the last expansion. 951 // data has survived scavenge since the last expansion.
948 new_space_.Grow(); 952 new_space_.Grow();
949 survived_since_last_expansion_ = 0; 953 survived_since_last_expansion_ = 0;
950 } 954 }
951 } 955 }
952 956
953 957
958 void Heap::ScavengeStoreBufferCallback(MemoryChunk* page,
959 StoreBufferEvent event) {
960 store_buffer_rebuilder_.Callback(page, event);
961 }
962
963
964 void StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) {
965 if (event == kStoreBufferStartScanningPagesEvent) {
966 start_of_current_page_ = NULL;
967 current_page_ = NULL;
968 } else if (event == kStoreBufferScanningPageEvent) {
969 if (current_page_ != NULL) {
970 // If this page already overflowed the store buffer during this iteration.
971 if (current_page_->scan_on_scavenge()) {
972 // Then we should wipe out the entries that have been added for it.
973 StoreBuffer::SetTop(start_of_current_page_);
974 } else if (StoreBuffer::Top() - start_of_current_page_ >=
975 (StoreBuffer::Limit() - StoreBuffer::Top()) >> 2) {
976 // Did we find too many pointers in the previous page? The heuristic is
977 // that no page can take more then 1/5 the remaining slots in the store
978 // buffer.
979 current_page_->set_scan_on_scavenge(true);
980 StoreBuffer::SetTop(start_of_current_page_);
981 } else {
982 // In this case the page we scanned took a reasonable number of slots in
983 // the store buffer. It has now been rehabilitated and is no longer
984 // marked scan_on_scavenge.
985 ASSERT(!current_page_->scan_on_scavenge());
986 }
987 }
988 start_of_current_page_ = StoreBuffer::Top();
989 current_page_ = page;
990 } else if (event == kStoreBufferFullEvent) {
991 // The current page overflowed the store buffer again. Wipe out its entries
992 // in the store buffer and mark it scan-on-scavenge again. This may happen
993 // several times while scanning.
994 if (current_page_ == NULL) {
995 // Store Buffer overflowed while scanning promoted objects. These are not
996 // in any particular page, though they are likely to be clustered by the
997 // allocation routines.
998 StoreBuffer::HandleFullness();
999 } else {
1000 // Store Buffer overflowed while scanning a particular old space page for
1001 // pointers to new space.
1002 ASSERT(current_page_ == page);
1003 ASSERT(page != NULL);
1004 current_page_->set_scan_on_scavenge(true);
1005 ASSERT(start_of_current_page_ != StoreBuffer::Top());
1006 StoreBuffer::SetTop(start_of_current_page_);
1007 }
1008 } else {
1009 UNREACHABLE();
1010 }
1011 }
1012
1013
954 void Heap::Scavenge() { 1014 void Heap::Scavenge() {
955 #ifdef DEBUG 1015 #ifdef DEBUG
956 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); 1016 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers();
957 #endif 1017 #endif
958 1018
959 gc_state_ = SCAVENGE; 1019 gc_state_ = SCAVENGE;
960 1020
961 // Implements Cheney's copying algorithm 1021 // Implements Cheney's copying algorithm
962 LOG(ResourceEvent("scavenge", "begin")); 1022 LOG(ResourceEvent("scavenge", "begin"));
963 1023
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 #ifdef DEBUG 1061 #ifdef DEBUG
1002 StoreBuffer::Clean(); 1062 StoreBuffer::Clean();
1003 #endif 1063 #endif
1004 1064
1005 ScavengeVisitor scavenge_visitor; 1065 ScavengeVisitor scavenge_visitor;
1006 // Copy roots. 1066 // Copy roots.
1007 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); 1067 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
1008 1068
1009 // Copy objects reachable from the old generation. 1069 // Copy objects reachable from the old generation.
1010 { 1070 {
1011 StoreBufferRebuildScope scope; 1071 StoreBufferRebuildScope scope(&ScavengeStoreBufferCallback);
1012 StoreBuffer::IteratePointersToNewSpace(&ScavengeObject); 1072 StoreBuffer::IteratePointersToNewSpace(&ScavengeObject);
1013 } 1073 }
1014 1074
1015 // Copy objects reachable from cells by scavenging cell values directly. 1075 // Copy objects reachable from cells by scavenging cell values directly.
1016 HeapObjectIterator cell_iterator(cell_space_); 1076 HeapObjectIterator cell_iterator(cell_space_);
1017 for (HeapObject* cell = cell_iterator.Next(); 1077 for (HeapObject* cell = cell_iterator.Next();
1018 cell != NULL; cell = cell_iterator.Next()) { 1078 cell != NULL; cell = cell_iterator.Next()) {
1019 if (cell->IsJSGlobalPropertyCell()) { 1079 if (cell->IsJSGlobalPropertyCell()) {
1020 Address value_address = 1080 Address value_address =
1021 reinterpret_cast<Address>(cell) + 1081 reinterpret_cast<Address>(cell) +
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 // The addresses new_space_front and new_space_.top() define a 1258 // The addresses new_space_front and new_space_.top() define a
1199 // queue of unprocessed copied objects. Process them until the 1259 // queue of unprocessed copied objects. Process them until the
1200 // queue is empty. 1260 // queue is empty.
1201 while (new_space_front < new_space_.top()) { 1261 while (new_space_front < new_space_.top()) {
1202 HeapObject* object = HeapObject::FromAddress(new_space_front); 1262 HeapObject* object = HeapObject::FromAddress(new_space_front);
1203 new_space_front += NewSpaceScavenger::IterateBody(object->map(), object); 1263 new_space_front += NewSpaceScavenger::IterateBody(object->map(), object);
1204 } 1264 }
1205 1265
1206 // Promote and process all the to-be-promoted objects. 1266 // Promote and process all the to-be-promoted objects.
1207 { 1267 {
1208 StoreBufferRebuildScope scope; 1268 StoreBufferRebuildScope scope(&ScavengeStoreBufferCallback);
1209 while (!promotion_queue.is_empty()) { 1269 while (!promotion_queue.is_empty()) {
1210 HeapObject* target; 1270 HeapObject* target;
1211 int size; 1271 int size;
1212 promotion_queue.remove(&target, &size); 1272 promotion_queue.remove(&target, &size);
1213 1273
1214 // Promoted object might be already partially visited 1274 // Promoted object might be already partially visited
1215 // during old space pointer iteration. Thus we search specificly 1275 // during old space pointer iteration. Thus we search specificly
1216 // for pointers to from semispace instead of looking for pointers 1276 // for pointers to from semispace instead of looking for pointers
1217 // to new space. 1277 // to new space.
1218 ASSERT(!target->IsMap()); 1278 ASSERT(!target->IsMap());
(...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after
3970 } 4030 }
3971 4031
3972 4032
3973 static void VerifyPointers( 4033 static void VerifyPointers(
3974 PagedSpace* space, 4034 PagedSpace* space,
3975 PointerRegionCallback visit_pointer_region) { 4035 PointerRegionCallback visit_pointer_region) {
3976 PageIterator it(space); 4036 PageIterator it(space);
3977 4037
3978 while (it.has_next()) { 4038 while (it.has_next()) {
3979 Page* page = it.next(); 4039 Page* page = it.next();
3980 Address start = page->ObjectAreaStart(); 4040 Heap::IteratePointersOnPage(
3981 Address end = page->ObjectAreaEnd(); 4041 reinterpret_cast<PagedSpace*>(page->owner()),
3982 4042 &Heap::IteratePointersToNewSpace,
3983 Heap::IteratePointersToNewSpace(start, 4043 &DummyScavengePointer,
3984 end, 4044 page);
3985 &DummyScavengePointer);
3986 } 4045 }
3987 } 4046 }
3988 4047
3989 4048
3990 static void VerifyPointers(LargeObjectSpace* space) { 4049 static void VerifyPointers(LargeObjectSpace* space) {
3991 LargeObjectIterator it(space); 4050 LargeObjectIterator it(space);
3992 for (HeapObject* object = it.next(); object != NULL; object = it.next()) { 4051 for (HeapObject* object = it.next(); object != NULL; object = it.next()) {
3993 if (object->IsFixedArray()) { 4052 if (object->IsFixedArray()) {
3994 Address slot_address = object->address(); 4053 Address slot_address = object->address();
3995 Address end = object->address() + object->Size(); 4054 Address end = object->address() + object->Size();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4186 } 4245 }
4187 4246
4188 4247
4189 void Heap::IterateAndMarkPointersToFromSpace(Address start, 4248 void Heap::IterateAndMarkPointersToFromSpace(Address start,
4190 Address end, 4249 Address end,
4191 ObjectSlotCallback callback) { 4250 ObjectSlotCallback callback) {
4192 Address slot_address = start; 4251 Address slot_address = start;
4193 while (slot_address < end) { 4252 while (slot_address < end) {
4194 Object** slot = reinterpret_cast<Object**>(slot_address); 4253 Object** slot = reinterpret_cast<Object**>(slot_address);
4195 Object* object = *slot; 4254 Object* object = *slot;
4196 // In normal store buffer operation we use this function to process the 4255 // If the store buffer becomes overfull we mark pages as being exempt from
4197 // promotion queue and we never scan an object twice so we will not see 4256 // the store buffer. These pages are scanned to find pointers that point
4198 // pointers that have already been updated to point to to-space. But 4257 // to the new space. In that case we may hit newly promoted objects and
4199 // in the case of store buffer overflow we scan the entire old space to 4258 // fix the pointers before the promotion queue gets to them. Thus the 'if'.
4200 // find pointers that point to new-space and in that case we may hit
4201 // newly promoted objects and fix the pointers before the promotion
4202 // queue gets to them.
4203 ASSERT(StoreBuffer::store_buffer_mode() !=
4204 StoreBuffer::kStoreBufferFunctional ||
4205 !Heap::InToSpace(object));
4206 if (Heap::InFromSpace(object)) { 4259 if (Heap::InFromSpace(object)) {
4207 callback(reinterpret_cast<HeapObject**>(slot), HeapObject::cast(object)); 4260 callback(reinterpret_cast<HeapObject**>(slot), HeapObject::cast(object));
4208 if (Heap::InNewSpace(*slot)) { 4261 if (Heap::InNewSpace(*slot)) {
4209 ASSERT(Heap::InToSpace(*slot)); 4262 ASSERT(Heap::InToSpace(*slot));
4210 ASSERT((*slot)->IsHeapObject()); 4263 ASSERT((*slot)->IsHeapObject());
4211 ASSERT(StoreBuffer::CellIsInStoreBuffer(
4212 reinterpret_cast<Address>(slot)));
4213 } 4264 }
4214 } 4265 }
4215 slot_address += kPointerSize; 4266 slot_address += kPointerSize;
4216 } 4267 }
4217 } 4268 }
4218 4269
4219 4270
4220 #ifdef DEBUG 4271 #ifdef DEBUG
4221 typedef bool (*CheckStoreBufferFilter)(Object** addr); 4272 typedef bool (*CheckStoreBufferFilter)(Object** addr);
4222 4273
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4283 while (!(*obj_start)->IsMap()) obj_start--; 4334 while (!(*obj_start)->IsMap()) obj_start--;
4284 UNREACHABLE(); 4335 UNREACHABLE();
4285 } 4336 }
4286 } 4337 }
4287 } 4338 }
4288 4339
4289 4340
4290 // Check that the store buffer contains all intergenerational pointers by 4341 // Check that the store buffer contains all intergenerational pointers by
4291 // scanning a page and ensuring that all pointers to young space are in the 4342 // scanning a page and ensuring that all pointers to young space are in the
4292 // store buffer. 4343 // store buffer.
4293 void Heap::OldPointerSpaceCheckStoreBuffer( 4344 void Heap::OldPointerSpaceCheckStoreBuffer() {
4294 ExpectedPageWatermarkState watermark_state) {
4295 OldSpace* space = old_pointer_space(); 4345 OldSpace* space = old_pointer_space();
4296 PageIterator pages(space); 4346 PageIterator pages(space);
4297 4347
4298 StoreBuffer::SortUniq(); 4348 StoreBuffer::SortUniq();
4299 4349
4300 while (pages.has_next()) { 4350 while (pages.has_next()) {
4301 Page* page = pages.next(); 4351 Page* page = pages.next();
4302 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart()); 4352 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart());
4303 4353
4304 Address end = page->ObjectAreaEnd(); 4354 Address end = page->ObjectAreaEnd();
4305 4355
4306 Object*** store_buffer_position = StoreBuffer::Start(); 4356 Object*** store_buffer_position = StoreBuffer::Start();
4307 Object*** store_buffer_top = StoreBuffer::Top(); 4357 Object*** store_buffer_top = StoreBuffer::Top();
4308 4358
4309 Object** limit = reinterpret_cast<Object**>(end); 4359 Object** limit = reinterpret_cast<Object**>(end);
4310 CheckStoreBuffer(current, 4360 CheckStoreBuffer(current,
4311 limit, 4361 limit,
4312 &store_buffer_position, 4362 &store_buffer_position,
4313 store_buffer_top, 4363 store_buffer_top,
4314 &EverythingsAPointer, 4364 &EverythingsAPointer,
4315 space->top(), 4365 space->top(),
4316 space->limit()); 4366 space->limit());
4317 } 4367 }
4318 } 4368 }
4319 4369
4320 4370
4321 void Heap::MapSpaceCheckStoreBuffer( 4371 void Heap::MapSpaceCheckStoreBuffer() {
4322 ExpectedPageWatermarkState watermark_state) {
4323 MapSpace* space = map_space(); 4372 MapSpace* space = map_space();
4324 PageIterator pages(space); 4373 PageIterator pages(space);
4325 4374
4326 StoreBuffer::SortUniq(); 4375 StoreBuffer::SortUniq();
4327 4376
4328 while (pages.has_next()) { 4377 while (pages.has_next()) {
4329 Page* page = pages.next(); 4378 Page* page = pages.next();
4330 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart()); 4379 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart());
4331 4380
4332 Address end = page->ObjectAreaEnd(); 4381 Address end = page->ObjectAreaEnd();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4383 // be marked with a free space or filler. Because the free space and filler 4432 // be marked with a free space or filler. Because the free space and filler
4384 // maps do not move we can always recognize these even after a compaction. 4433 // maps do not move we can always recognize these even after a compaction.
4385 // Normal objects like FixedArrays and JSObjects should not contain references 4434 // Normal objects like FixedArrays and JSObjects should not contain references
4386 // to these maps. The special garbage section (see comment in spaces.h) is 4435 // to these maps. The special garbage section (see comment in spaces.h) is
4387 // skipped since it can contain absolutely anything. Any objects that are 4436 // skipped since it can contain absolutely anything. Any objects that are
4388 // allocated during iteration may or may not be visited by the iteration, but 4437 // allocated during iteration may or may not be visited by the iteration, but
4389 // they will not be partially visited. 4438 // they will not be partially visited.
4390 void Heap::IteratePointers( 4439 void Heap::IteratePointers(
4391 PagedSpace* space, 4440 PagedSpace* space,
4392 PointerRegionCallback visit_pointer_region, 4441 PointerRegionCallback visit_pointer_region,
4393 ObjectSlotCallback copy_object_func, 4442 ObjectSlotCallback copy_object_func) {
4394 ExpectedPageWatermarkState expected_page_watermark_state) {
4395 4443
4396 PageIterator pages(space); 4444 PageIterator pages(space);
4397 4445
4398 while (pages.has_next()) { 4446 while (pages.has_next()) {
4399 Page* page = pages.next(); 4447 Page* page = pages.next();
4400 Address start = page->ObjectAreaStart(); 4448 IteratePointersOnPage(space, visit_pointer_region, copy_object_func, page);
4401 Address limit = page->ObjectAreaEnd();
4402
4403 Address end = start;
4404
4405 Object* free_space_map = Heap::free_space_map();
4406 Object* two_pointer_filler_map = Heap::two_pointer_filler_map();
4407
4408 while (end < limit) {
4409 Object* o = *reinterpret_cast<Object**>(end);
4410 // Skip fillers but not things that look like fillers in the special
4411 // garbage section which can contain anything.
4412 if (o == free_space_map ||
4413 o == two_pointer_filler_map ||
4414 end == space->top()) {
4415 if (start != end) {
4416 // After calling this the special garbage section may have moved.
4417 visit_pointer_region(start, end, copy_object_func);
4418 if (end >= space->top() && end < space->limit()) {
4419 end = space->limit();
4420 start = end;
4421 continue;
4422 }
4423 }
4424 if (end == space->top()) {
4425 start = end = space->limit();
4426 } else {
4427 // At this point we are either at the start of a filler or we are at
4428 // the point where the space->top() used to be before the
4429 // visit_pointer_region call above. Either way we can skip the
4430 // object at the current spot: We don't promise to visit objects
4431 // allocated during heap traversal, and if space->top() moved then it
4432 // must be because an object was allocated at this point.
4433 start = end + HeapObject::FromAddress(end)->Size();
4434 end = start;
4435 }
4436 } else {
4437 ASSERT(o != free_space_map);
4438 ASSERT(o != two_pointer_filler_map);
4439 ASSERT(end < space->top() || end >= space->limit());
4440 end += kPointerSize;
4441 }
4442 }
4443 ASSERT(end == limit);
4444 if (start != end) {
4445 visit_pointer_region(start, end, copy_object_func);
4446 }
4447 } 4449 }
4448 } 4450 }
4449 4451
4450 4452
4453 void Heap::IteratePointersOnPage(
4454 PagedSpace* space,
4455 PointerRegionCallback visit_pointer_region,
4456 ObjectSlotCallback copy_object_func,
4457 Page* page) {
4458 Address visitable_start = page->ObjectAreaStart();
4459 Address end_of_page = page->ObjectAreaEnd();
4460
4461 Address visitable_end = visitable_start;
4462
4463 Object* free_space_map = Heap::free_space_map();
4464 Object* two_pointer_filler_map = Heap::two_pointer_filler_map();
4465
4466 while (visitable_end < end_of_page) {
4467 Object* o = *reinterpret_cast<Object**>(visitable_end);
4468 // Skip fillers but not things that look like fillers in the special
4469 // garbage section which can contain anything.
4470 if (o == free_space_map ||
4471 o == two_pointer_filler_map ||
4472 visitable_end == space->top()) {
4473 if (visitable_start != visitable_end) {
4474 // After calling this the special garbage section may have moved.
4475 visit_pointer_region(visitable_start, visitable_end, copy_object_func);
4476 if (visitable_end >= space->top() && visitable_end < space->limit()) {
4477 visitable_end = space->limit();
4478 visitable_start = visitable_end;
4479 continue;
4480 }
4481 }
4482 if (visitable_end == space->top() && visitable_end != space->limit()) {
4483 visitable_start = visitable_end = space->limit();
4484 } else {
4485 // At this point we are either at the start of a filler or we are at
4486 // the point where the space->top() used to be before the
4487 // visit_pointer_region call above. Either way we can skip the
4488 // object at the current spot: We don't promise to visit objects
4489 // allocated during heap traversal, and if space->top() moved then it
4490 // must be because an object was allocated at this point.
4491 visitable_start =
4492 visitable_end + HeapObject::FromAddress(visitable_end)->Size();
4493 visitable_end = visitable_start;
4494 }
4495 } else {
4496 ASSERT(o != free_space_map);
4497 ASSERT(o != two_pointer_filler_map);
4498 ASSERT(visitable_end < space->top() || visitable_end >= space->limit());
4499 visitable_end += kPointerSize;
4500 }
4501 }
4502 ASSERT(visitable_end == end_of_page);
4503 if (visitable_start != visitable_end) {
4504 visit_pointer_region(visitable_start, visitable_end, copy_object_func);
4505 }
4506 }
4507
4508
4451 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { 4509 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
4452 IterateStrongRoots(v, mode); 4510 IterateStrongRoots(v, mode);
4453 IterateWeakRoots(v, mode); 4511 IterateWeakRoots(v, mode);
4454 } 4512 }
4455 4513
4456 4514
4457 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { 4515 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
4458 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); 4516 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
4459 v->Synchronize("symbol_table"); 4517 v->Synchronize("symbol_table");
4460 if (mode != VISIT_ALL_IN_SCAVENGE) { 4518 if (mode != VISIT_ALL_IN_SCAVENGE) {
(...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after
5600 void ExternalStringTable::TearDown() { 5658 void ExternalStringTable::TearDown() {
5601 new_space_strings_.Free(); 5659 new_space_strings_.Free();
5602 old_space_strings_.Free(); 5660 old_space_strings_.Free();
5603 } 5661 }
5604 5662
5605 5663
5606 List<Object*> ExternalStringTable::new_space_strings_; 5664 List<Object*> ExternalStringTable::new_space_strings_;
5607 List<Object*> ExternalStringTable::old_space_strings_; 5665 List<Object*> ExternalStringTable::old_space_strings_;
5608 5666
5609 } } // namespace v8::internal 5667 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698