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

Side by Side Diff: src/spaces.cc

Issue 7027030: Changes that anticipate making semispaces contain more than one page. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 6 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/spaces.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 389
390 void Page::InitializeAsAnchor(PagedSpace* owner) { 390 void Page::InitializeAsAnchor(PagedSpace* owner) {
391 set_owner(owner); 391 set_owner(owner);
392 set_prev_page(this); 392 set_prev_page(this);
393 set_next_page(this); 393 set_next_page(this);
394 } 394 }
395 395
396 396
397 NewSpacePage* NewSpacePage::Initialize(Heap* heap, 397 NewSpacePage* NewSpacePage::Initialize(Heap* heap,
398 Address start, 398 Address start,
399 SemiSpaceId semispace_id) { 399 SemiSpace* semi_space) {
400 MemoryChunk* chunk = MemoryChunk::Initialize(heap, 400 MemoryChunk* chunk = MemoryChunk::Initialize(heap,
401 start, 401 start,
402 Page::kPageSize, 402 Page::kPageSize,
403 NOT_EXECUTABLE, 403 NOT_EXECUTABLE,
404 heap->new_space()); 404 semi_space);
405 chunk->set_next_chunk(NULL); 405 chunk->set_next_chunk(NULL);
406 chunk->set_prev_chunk(NULL); 406 chunk->set_prev_chunk(NULL);
407 chunk->initialize_scan_on_scavenge(true); 407 chunk->initialize_scan_on_scavenge(true);
408 bool in_to_space = (semispace_id != kFromSpace); 408 bool in_to_space = (semi_space->id() != kFromSpace);
409 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE 409 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE
410 : MemoryChunk::IN_FROM_SPACE); 410 : MemoryChunk::IN_FROM_SPACE);
411 ASSERT(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE 411 ASSERT(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE
412 : MemoryChunk::IN_TO_SPACE)); 412 : MemoryChunk::IN_TO_SPACE));
413 heap->incremental_marking()->SetNewSpacePageFlags(chunk); 413 heap->incremental_marking()->SetNewSpacePageFlags(chunk);
414 return static_cast<NewSpacePage*>(chunk); 414 return static_cast<NewSpacePage*>(chunk);
415 } 415 }
416 416
417 417
418 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) {
419 set_owner(semi_space);
420 set_next_chunk(this);
421 set_prev_chunk(this);
422 }
423
424
418 MemoryChunk* MemoryChunk::Initialize(Heap* heap, 425 MemoryChunk* MemoryChunk::Initialize(Heap* heap,
419 Address base, 426 Address base,
420 size_t size, 427 size_t size,
421 Executability executable, 428 Executability executable,
422 Space* owner) { 429 Space* owner) {
423 MemoryChunk* chunk = FromAddress(base); 430 MemoryChunk* chunk = FromAddress(base);
424 431
425 ASSERT(base == chunk->address()); 432 ASSERT(base == chunk->address());
426 433
427 chunk->heap_ = heap; 434 chunk->heap_ = heap;
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 heap()->isolate()->memory_allocator()->Unprotect(ToSpaceLow(), Capacity(), 939 heap()->isolate()->memory_allocator()->Unprotect(ToSpaceLow(), Capacity(),
933 to_space_.executable()); 940 to_space_.executable());
934 heap()->isolate()->memory_allocator()->Unprotect(FromSpaceLow(), Capacity(), 941 heap()->isolate()->memory_allocator()->Unprotect(FromSpaceLow(), Capacity(),
935 from_space_.executable()); 942 from_space_.executable());
936 } 943 }
937 944
938 #endif 945 #endif
939 946
940 947
941 void NewSpace::Flip() { 948 void NewSpace::Flip() {
942 SemiSpace tmp = from_space_; 949 SemiSpace::Swap(&from_space_, &to_space_);
943 from_space_ = to_space_;
944 to_space_ = tmp;
945
946 // Copy GC flags from old active space (from-space) to new (to-space).
947 intptr_t flags = from_space_.current_page()->GetFlags();
948 to_space_.Flip(flags, NewSpacePage::kCopyOnFlipFlagsMask);
949
950 from_space_.Flip(0, 0);
951 } 950 }
952 951
953 952
954 void NewSpace::Grow() { 953 void NewSpace::Grow() {
955 ASSERT(Capacity() < MaximumCapacity()); 954 ASSERT(Capacity() < MaximumCapacity());
956 if (to_space_.Grow()) { 955 if (to_space_.Grow()) {
957 // Only grow from space if we managed to grow to space. 956 // Only grow from space if we managed to grow to space.
958 if (!from_space_.Grow()) { 957 if (!from_space_.Grow()) {
959 // If we managed to grow to space but couldn't grow from space, 958 // If we managed to grow to space but couldn't grow from space,
960 // attempt to shrink to space. 959 // attempt to shrink to space.
(...skipping 25 matching lines...) Expand all
986 V8::FatalProcessOutOfMemory("Failed to shrink new space."); 985 V8::FatalProcessOutOfMemory("Failed to shrink new space.");
987 } 986 }
988 } 987 }
989 } 988 }
990 allocation_info_.limit = to_space_.high(); 989 allocation_info_.limit = to_space_.high();
991 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 990 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
992 } 991 }
993 992
994 993
995 void NewSpace::ResetAllocationInfo() { 994 void NewSpace::ResetAllocationInfo() {
996 allocation_info_.top = to_space_.low(); 995 to_space_.Reset();
996 allocation_info_.top = to_space_.page_low();
997 allocation_info_.limit = to_space_.high(); 997 allocation_info_.limit = to_space_.high();
998 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 998 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
999 } 999 }
1000 1000
1001 1001
1002 #ifdef DEBUG 1002 #ifdef DEBUG
1003 // We do not use the SemispaceIterator because verification doesn't assume 1003 // We do not use the SemispaceIterator because verification doesn't assume
1004 // that it works (it depends on the invariants we are checking). 1004 // that it works (it depends on the invariants we are checking).
1005 void NewSpace::Verify() { 1005 void NewSpace::Verify() {
1006 // The allocation pointer should be in the space or at the very end. 1006 // The allocation pointer should be in the space or at the very end.
1007 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1007 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1008 1008
1009 // There should be objects packed in from the low address up to the 1009 // There should be objects packed in from the low address up to the
1010 // allocation pointer. 1010 // allocation pointer.
1011 Address current = to_space_.low(); 1011 Address current = to_space_.low();
1012 while (current < top()) { 1012 while (current < top()) {
1013 HeapObject* object = HeapObject::FromAddress(current); 1013 HeapObject* object = HeapObject::FromAddress(current);
1014 1014
1015 // The first word should be a map, and we expect all map pointers to 1015 // The first word should be a map, and we expect all map pointers to
1016 // be in map space. 1016 // be in map space.
1017 Map* map = object->map(); 1017 Map* map = object->map();
1018 ASSERT(map->IsMap()); 1018 CHECK(map->IsMap());
1019 ASSERT(heap()->map_space()->Contains(map)); 1019 CHECK(heap()->map_space()->Contains(map));
1020 1020
1021 // The object should not be code or a map. 1021 // The object should not be code or a map.
1022 ASSERT(!object->IsMap()); 1022 CHECK(!object->IsMap());
1023 ASSERT(!object->IsCode()); 1023 CHECK(!object->IsCode());
1024 1024
1025 // The object itself should look OK. 1025 // The object itself should look OK.
1026 object->Verify(); 1026 object->Verify();
1027 1027
1028 // All the interior pointers should be contained in the heap. 1028 // All the interior pointers should be contained in the heap.
1029 VerifyPointersVisitor visitor; 1029 VerifyPointersVisitor visitor;
1030 int size = object->Size(); 1030 int size = object->Size();
1031 object->IterateBody(map->instance_type(), size, &visitor); 1031 object->IterateBody(map->instance_type(), size, &visitor);
1032 1032
1033 current += size; 1033 current += size;
1034 } 1034 }
1035 1035
1036 // The allocation pointer should not be in the middle of an object. 1036 // The allocation pointer should not be in the middle of an object.
1037 ASSERT(current == top()); 1037 ASSERT(current == top());
1038
1039 // Check semi-spaces.
1040 ASSERT_EQ(from_space_.id(), kFromSpace);
1041 ASSERT_EQ(to_space_.id(), kToSpace);
1042 from_space_.Verify();
1043 to_space_.Verify();
1038 } 1044 }
1039 #endif 1045 #endif
1040 1046
1041 1047
1042 bool SemiSpace::Commit() { 1048 bool SemiSpace::Commit() {
1043 ASSERT(!is_committed()); 1049 ASSERT(!is_committed());
1044 if (!heap()->isolate()->memory_allocator()->CommitBlock( 1050 if (!heap()->isolate()->memory_allocator()->CommitBlock(
1045 start_, capacity_, executable())) { 1051 start_, capacity_, executable())) {
1046 return false; 1052 return false;
1047 } 1053 }
1048 committed_ = true; 1054 committed_ = true;
1049 // TODO(gc): When more than one page is present, initialize and 1055 // TODO(gc): When more than one page is present, initialize and
1050 // chain them all. 1056 // chain them all.
1051 current_page_ = NewSpacePage::Initialize(heap(), start_, id_); 1057 NewSpacePage* page = NewSpacePage::Initialize(heap(), start_, this);
1058 page->InsertAfter(&anchor_);
1059 current_page_ = anchor_.next_page();
1052 return true; 1060 return true;
1053 } 1061 }
1054 1062
1055 1063
1056 bool SemiSpace::Uncommit() { 1064 bool SemiSpace::Uncommit() {
1057 ASSERT(is_committed()); 1065 ASSERT(is_committed());
1058 if (!heap()->isolate()->memory_allocator()->UncommitBlock( 1066 if (!heap()->isolate()->memory_allocator()->UncommitBlock(
1059 start_, capacity_)) { 1067 start_, capacity_)) {
1060 return false; 1068 return false;
1061 } 1069 }
1062 committed_ = false; 1070 committed_ = false;
1063 return true; 1071 return true;
1064 } 1072 }
1065 1073
1066 1074
1075 void SemiSpace::Reset() {
1076 ASSERT(anchor_.next_page() != &anchor_);
1077 current_page_ = anchor_.next_page();
1078 }
1079
1080
1081 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
1082 // We won't be swapping semispaces without data in them.
1083 ASSERT(from->anchor_.next_page() != &from->anchor_);
1084 ASSERT(to->anchor_.next_page() != &to->anchor_);
1085
1086 // Swap bits.
1087 SemiSpace tmp = *from;
1088 *from = *to;
1089 *to = tmp;
1090
1091 // Fixup back-pointers to the page list anchor now that its address
1092 // has changed.
1093 // Swap to/from-space bits on pages.
1094 // Copy GC flags from old active space (from-space) to new (to-space).
1095 intptr_t flags = from->current_page()->GetFlags();
1096 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask);
1097
1098 from->FlipPages(0, 0);
1099 }
1100
1101
1067 // ----------------------------------------------------------------------------- 1102 // -----------------------------------------------------------------------------
1068 // SemiSpace implementation 1103 // SemiSpace implementation
1069 1104
1070 bool SemiSpace::Setup(Address start, 1105 bool SemiSpace::Setup(Address start,
1071 int initial_capacity, 1106 int initial_capacity,
1072 int maximum_capacity) { 1107 int maximum_capacity) {
1073 // Creates a space in the young generation. The constructor does not 1108 // Creates a space in the young generation. The constructor does not
1074 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of 1109 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of
1075 // memory of size 'capacity' when set up, and does not grow or shrink 1110 // memory of size 'capacity' when set up, and does not grow or shrink
1076 // otherwise. In the mark-compact collector, the memory region of the from 1111 // otherwise. In the mark-compact collector, the memory region of the from
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 ASSERT(IsAligned(delta, OS::AllocateAlignment())); 1175 ASSERT(IsAligned(delta, OS::AllocateAlignment()));
1141 if (!heap()->isolate()->memory_allocator()->UncommitBlock( 1176 if (!heap()->isolate()->memory_allocator()->UncommitBlock(
1142 high() - delta, delta)) { 1177 high() - delta, delta)) {
1143 return false; 1178 return false;
1144 } 1179 }
1145 capacity_ = new_capacity; 1180 capacity_ = new_capacity;
1146 return true; 1181 return true;
1147 } 1182 }
1148 1183
1149 1184
1150 void SemiSpace::Flip(intptr_t flags, intptr_t mask) { 1185 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) {
1186 anchor_.set_owner(this);
1187 // Fixup back-pointers to anchor. Address of anchor changes
1188 // when we swap.
1189 anchor_.prev_page()->set_next_page(&anchor_);
1190 anchor_.next_page()->set_prev_page(&anchor_);
1191
1151 bool becomes_to_space = (id_ == kFromSpace); 1192 bool becomes_to_space = (id_ == kFromSpace);
1152 id_ = becomes_to_space ? kToSpace : kFromSpace; 1193 id_ = becomes_to_space ? kToSpace : kFromSpace;
1153 NewSpacePage* page = NewSpacePage::FromAddress(start_); 1194 NewSpacePage* page = anchor_.next_page();
1154 while (page != NULL) { 1195 while (page != &anchor_) {
1196 page->set_owner(this);
1155 page->SetFlags(flags, mask); 1197 page->SetFlags(flags, mask);
1156 if (becomes_to_space) { 1198 if (becomes_to_space) {
1157 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); 1199 page->ClearFlag(MemoryChunk::IN_FROM_SPACE);
1158 page->SetFlag(MemoryChunk::IN_TO_SPACE); 1200 page->SetFlag(MemoryChunk::IN_TO_SPACE);
1159 } else { 1201 } else {
1160 page->SetFlag(MemoryChunk::IN_FROM_SPACE); 1202 page->SetFlag(MemoryChunk::IN_FROM_SPACE);
1161 page->ClearFlag(MemoryChunk::IN_TO_SPACE); 1203 page->ClearFlag(MemoryChunk::IN_TO_SPACE);
1162 } 1204 }
1163 page = page->next_page(); 1205 page = page->next_page();
1164 } 1206 }
1165 } 1207 }
1166 1208
1167 #ifdef DEBUG 1209 #ifdef DEBUG
1168 void SemiSpace::Print() { } 1210 void SemiSpace::Print() { }
1169 1211
1170 1212
1171 void SemiSpace::Verify() { } 1213 void SemiSpace::Verify() {
1214 bool is_from_space = (id_ == kFromSpace);
1215 NewSpacePage* page = anchor_.next_page();
1216 CHECK(anchor_.semi_space() == this);
1217 while (page != &anchor_) {
1218 CHECK(page->semi_space() == this);
1219 CHECK(page->InNewSpace());
1220 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE
1221 : MemoryChunk::IN_TO_SPACE));
1222 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE
1223 : MemoryChunk::IN_FROM_SPACE));
1224 CHECK(page->prev_page()->next_page() == page);
1225 page = page->next_page();
1226 }
1227 }
1172 #endif 1228 #endif
1173 1229
1174 1230
1175 // ----------------------------------------------------------------------------- 1231 // -----------------------------------------------------------------------------
1176 // SemiSpaceIterator implementation. 1232 // SemiSpaceIterator implementation.
1177 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) { 1233 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) {
1178 Initialize(space, space->bottom(), space->top(), NULL); 1234 Initialize(space, space->bottom(), space->top(), NULL);
1179 } 1235 }
1180 1236
1181 1237
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { 2349 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
2294 if (obj->IsCode()) { 2350 if (obj->IsCode()) {
2295 Code* code = Code::cast(obj); 2351 Code* code = Code::cast(obj);
2296 isolate->code_kind_statistics()[code->kind()] += code->Size(); 2352 isolate->code_kind_statistics()[code->kind()] += code->Size();
2297 } 2353 }
2298 } 2354 }
2299 } 2355 }
2300 #endif // DEBUG 2356 #endif // DEBUG
2301 2357
2302 } } // namespace v8::internal 2358 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698