Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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) { | 418 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { |
| 419 set_owner(semi_space); | 419 set_owner(semi_space); |
| 420 set_next_chunk(this); | 420 set_next_chunk(this); |
| 421 set_prev_chunk(this); | 421 set_prev_chunk(this); |
| 422 // Flags marks this invalid page as not being in new-space. | |
| 423 // All real new-space pages will be in new-space. | |
| 424 SetFlags(0, ~0); | |
| 422 } | 425 } |
| 423 | 426 |
| 424 | 427 |
| 425 MemoryChunk* MemoryChunk::Initialize(Heap* heap, | 428 MemoryChunk* MemoryChunk::Initialize(Heap* heap, |
| 426 Address base, | 429 Address base, |
| 427 size_t size, | 430 size_t size, |
| 428 Executability executable, | 431 Executability executable, |
| 429 Space* owner) { | 432 Space* owner) { |
| 430 MemoryChunk* chunk = FromAddress(base); | 433 MemoryChunk* chunk = FromAddress(base); |
| 431 | 434 |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 957 if (!from_space_.Grow()) { | 960 if (!from_space_.Grow()) { |
| 958 // If we managed to grow to space but couldn't grow from space, | 961 // If we managed to grow to space but couldn't grow from space, |
| 959 // attempt to shrink to space. | 962 // attempt to shrink to space. |
| 960 if (!to_space_.ShrinkTo(from_space_.Capacity())) { | 963 if (!to_space_.ShrinkTo(from_space_.Capacity())) { |
| 961 // We are in an inconsistent state because we could not | 964 // We are in an inconsistent state because we could not |
| 962 // commit/uncommit memory from new space. | 965 // commit/uncommit memory from new space. |
| 963 V8::FatalProcessOutOfMemory("Failed to grow new space."); | 966 V8::FatalProcessOutOfMemory("Failed to grow new space."); |
| 964 } | 967 } |
| 965 } | 968 } |
| 966 } | 969 } |
| 967 allocation_info_.limit = to_space_.high(); | 970 allocation_info_.limit = to_space_.page_high(); |
| 968 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 971 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 969 } | 972 } |
| 970 | 973 |
| 971 | 974 |
| 972 void NewSpace::Shrink() { | 975 void NewSpace::Shrink() { |
| 973 int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt()); | 976 int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt()); |
| 974 int rounded_new_capacity = | 977 int rounded_new_capacity = |
| 975 RoundUp(new_capacity, static_cast<int>(OS::AllocateAlignment())); | 978 RoundUp(new_capacity, static_cast<int>(OS::AllocateAlignment())); |
| 976 if (rounded_new_capacity < Capacity() && | 979 if (rounded_new_capacity < Capacity() && |
| 977 to_space_.ShrinkTo(rounded_new_capacity)) { | 980 to_space_.ShrinkTo(rounded_new_capacity)) { |
| 978 // Only shrink from space if we managed to shrink to space. | 981 // Only shrink from space if we managed to shrink to space. |
| 979 if (!from_space_.ShrinkTo(rounded_new_capacity)) { | 982 if (!from_space_.ShrinkTo(rounded_new_capacity)) { |
| 980 // If we managed to shrink to space but couldn't shrink from | 983 // If we managed to shrink to space but couldn't shrink from |
| 981 // space, attempt to grow to space again. | 984 // space, attempt to grow to space again. |
| 982 if (!to_space_.GrowTo(from_space_.Capacity())) { | 985 if (!to_space_.GrowTo(from_space_.Capacity())) { |
| 983 // We are in an inconsistent state because we could not | 986 // We are in an inconsistent state because we could not |
| 984 // commit/uncommit memory from new space. | 987 // commit/uncommit memory from new space. |
| 985 V8::FatalProcessOutOfMemory("Failed to shrink new space."); | 988 V8::FatalProcessOutOfMemory("Failed to shrink new space."); |
| 986 } | 989 } |
| 987 } | 990 } |
| 988 } | 991 } |
| 989 allocation_info_.limit = to_space_.high(); | 992 allocation_info_.limit = to_space_.page_high(); |
| 993 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | |
| 994 } | |
| 995 | |
| 996 | |
| 997 void NewSpace::UpdateAllocationInfo() { | |
| 998 allocation_info_.top = to_space_.page_low(); | |
| 999 allocation_info_.limit = to_space_.page_high(); | |
| 990 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1000 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 991 } | 1001 } |
| 992 | 1002 |
| 993 | 1003 |
| 994 void NewSpace::ResetAllocationInfo() { | 1004 void NewSpace::ResetAllocationInfo() { |
| 995 to_space_.Reset(); | 1005 to_space_.Reset(); |
| 996 allocation_info_.top = to_space_.page_low(); | 1006 UpdateAllocationInfo(); |
| 997 allocation_info_.limit = to_space_.high(); | 1007 // Clear all mark-bits in the to-space. |
| 998 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1008 NewSpacePageIterator it(to_space_.space_low(), to_space_.space_high()); |
| 1009 while (it.has_next()) { | |
| 1010 NewSpacePage* page = it.next(); | |
| 1011 page->markbits()->Clear(); | |
| 1012 } | |
| 1013 } | |
| 1014 | |
| 1015 | |
| 1016 bool NewSpace::AddFreshPage() { | |
| 1017 Address top = allocation_info_.top; | |
| 1018 if (top == NewSpacePage::FromLimit(top)->body()) { | |
| 1019 // The current page is already empty. Don't try to make another. | |
| 1020 return false; | |
|
Erik Corry
2011/06/07 08:49:55
Why did AddFreshPage get called if the current pag
Lasse Reichstein
2011/06/07 09:36:06
Possibly because the size asked for was too large
| |
| 1021 } | |
| 1022 if (!to_space_.AdvancePage()) { | |
| 1023 // Failed to use a new page in to-space. | |
|
Erik Corry
2011/06/07 08:49:55
Failed to get?
Lasse Reichstein
2011/06/07 09:36:06
Done.
| |
| 1024 return false; | |
| 1025 } | |
| 1026 // Clear remainder of current pag. | |
|
Erik Corry
2011/06/07 08:49:55
pag -> page
Lasse Reichstein
2011/06/07 09:36:06
Done.
| |
| 1027 int remaining_in_page = | |
| 1028 static_cast<int>(NewSpacePage::FromLimit(top)->body_limit() - top); | |
| 1029 heap()->CreateFillerObjectAt(top, remaining_in_page); | |
| 1030 UpdateAllocationInfo(); | |
| 1031 return true; | |
| 999 } | 1032 } |
| 1000 | 1033 |
| 1001 | 1034 |
| 1002 #ifdef DEBUG | 1035 #ifdef DEBUG |
| 1003 // We do not use the SemispaceIterator because verification doesn't assume | 1036 // We do not use the SemispaceIterator because verification doesn't assume |
| 1004 // that it works (it depends on the invariants we are checking). | 1037 // that it works (it depends on the invariants we are checking). |
| 1005 void NewSpace::Verify() { | 1038 void NewSpace::Verify() { |
| 1006 // The allocation pointer should be in the space or at the very end. | 1039 // The allocation pointer should be in the space or at the very end. |
| 1007 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1040 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 1008 | 1041 |
| 1009 // There should be objects packed in from the low address up to the | 1042 // There should be objects packed in from the low address up to the |
| 1010 // allocation pointer. | 1043 // allocation pointer. |
| 1011 Address current = to_space_.low(); | 1044 NewSpacePage* page = to_space_.first_page(); |
| 1012 while (current < top()) { | 1045 NewSpacePage* end_page = to_space_.current_page(); |
| 1046 Address current = page->body(); | |
| 1047 Address limit = page->body_limit(); | |
| 1048 CHECK_EQ(current, to_space_.space_low()); | |
| 1049 CHECK(end_page->ContainsLimit(top())); | |
| 1050 if (page == end_page) limit = top(); | |
| 1051 while (current < limit) { | |
| 1013 HeapObject* object = HeapObject::FromAddress(current); | 1052 HeapObject* object = HeapObject::FromAddress(current); |
| 1014 | 1053 |
| 1015 // The first word should be a map, and we expect all map pointers to | 1054 // The first word should be a map, and we expect all map pointers to |
| 1016 // be in map space. | 1055 // be in map space. |
| 1017 Map* map = object->map(); | 1056 Map* map = object->map(); |
| 1018 CHECK(map->IsMap()); | 1057 CHECK(map->IsMap()); |
| 1019 CHECK(heap()->map_space()->Contains(map)); | 1058 CHECK(heap()->map_space()->Contains(map)); |
| 1020 | 1059 |
| 1021 // The object should not be code or a map. | 1060 // The object should not be code or a map. |
| 1022 CHECK(!object->IsMap()); | 1061 CHECK(!object->IsMap()); |
| 1023 CHECK(!object->IsCode()); | 1062 CHECK(!object->IsCode()); |
| 1024 | 1063 |
| 1025 // The object itself should look OK. | 1064 // The object itself should look OK. |
| 1026 object->Verify(); | 1065 object->Verify(); |
| 1027 | 1066 |
| 1028 // All the interior pointers should be contained in the heap. | 1067 // All the interior pointers should be contained in the heap. |
| 1029 VerifyPointersVisitor visitor; | 1068 VerifyPointersVisitor visitor; |
| 1030 int size = object->Size(); | 1069 int size = object->Size(); |
| 1031 object->IterateBody(map->instance_type(), size, &visitor); | 1070 object->IterateBody(map->instance_type(), size, &visitor); |
| 1032 | 1071 |
| 1033 current += size; | 1072 current += size; |
| 1073 // Move to next page if necessary. | |
| 1074 if (current == page->body_limit() && current != top()) { | |
| 1075 page = page->next_page(); | |
| 1076 // Next page should be valid. | |
| 1077 CHECK(!page->is_anchor()); | |
| 1078 current = page->body(); | |
| 1079 limit = (page == end_page) ? top() : page->body_limit(); | |
|
Erik Corry
2011/06/07 08:49:55
This ternary operator together with the if above c
Lasse Reichstein
2011/06/07 09:36:06
Rewritten.
| |
| 1080 } | |
| 1034 } | 1081 } |
| 1035 | 1082 |
| 1036 // The allocation pointer should not be in the middle of an object. | 1083 // The allocation pointer should not be in the middle of an object. |
| 1037 ASSERT(current == top()); | 1084 ASSERT(current == top()); |
| 1038 | 1085 |
| 1039 // Check semi-spaces. | 1086 // Check semi-spaces. |
| 1040 ASSERT_EQ(from_space_.id(), kFromSpace); | 1087 ASSERT_EQ(from_space_.id(), kFromSpace); |
| 1041 ASSERT_EQ(to_space_.id(), kToSpace); | 1088 ASSERT_EQ(to_space_.id(), kToSpace); |
| 1042 from_space_.Verify(); | 1089 from_space_.Verify(); |
| 1043 to_space_.Verify(); | 1090 to_space_.Verify(); |
| 1044 } | 1091 } |
| 1045 #endif | 1092 #endif |
| 1046 | 1093 |
| 1047 | 1094 |
| 1048 bool SemiSpace::Commit() { | 1095 bool SemiSpace::Commit() { |
| 1049 ASSERT(!is_committed()); | 1096 ASSERT(!is_committed()); |
| 1097 // TODO(gc): Rewrite completely when switching to n-page new-space. | |
| 1098 // Create one page. | |
| 1099 int pagesize = Page::kPageSize; | |
| 1050 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1100 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
| 1051 start_, capacity_, executable())) { | 1101 start_, pagesize, executable())) { |
| 1052 return false; | 1102 return false; |
| 1053 } | 1103 } |
| 1054 committed_ = true; | |
| 1055 // TODO(gc): When more than one page is present, initialize and | |
| 1056 // chain them all. | |
| 1057 NewSpacePage* page = NewSpacePage::Initialize(heap(), start_, this); | 1104 NewSpacePage* page = NewSpacePage::Initialize(heap(), start_, this); |
| 1058 page->InsertAfter(&anchor_); | 1105 page->InsertAfter(&anchor_); |
| 1059 current_page_ = anchor_.next_page(); | 1106 |
| 1107 // Maybe create a second. | |
| 1108 if (capacity_ >= 2 * pagesize) { | |
| 1109 Address last_page_address = | |
| 1110 start_ + ((capacity_ - pagesize) & ~Page::kPageAlignmentMask); | |
| 1111 if (heap()->isolate()->memory_allocator()->CommitBlock( | |
| 1112 last_page_address, pagesize, executable())) { | |
| 1113 NewSpacePage* last_page = NewSpacePage::Initialize(heap(), | |
| 1114 last_page_address, | |
| 1115 this); | |
| 1116 last_page->InsertAfter(page); | |
| 1117 } else { | |
| 1118 UNREACHABLE(); // TODO(gc): Don't rely on this. Splitting the commit | |
| 1119 // is only temporary. | |
| 1120 } | |
| 1121 } | |
| 1122 | |
| 1123 committed_ = true; | |
| 1124 Reset(); | |
| 1060 return true; | 1125 return true; |
| 1061 } | 1126 } |
| 1062 | 1127 |
| 1063 | 1128 |
| 1064 bool SemiSpace::Uncommit() { | 1129 bool SemiSpace::Uncommit() { |
| 1065 ASSERT(is_committed()); | 1130 ASSERT(is_committed()); |
| 1066 if (!heap()->isolate()->memory_allocator()->UncommitBlock( | 1131 // TODO(gc): Rewrite completely when switching to n-page new-space. |
| 1067 start_, capacity_)) { | 1132 NewSpacePage* last_page = anchor()->prev_page(); |
| 1068 return false; | 1133 while (last_page != anchor()) { |
| 1134 NewSpacePage* temp_page = last_page->prev_page(); | |
| 1135 last_page->Unlink(); | |
| 1136 if (!heap()->isolate()->memory_allocator()->UncommitBlock( | |
| 1137 last_page->address(), Page::kPageSize)) { | |
| 1138 return false; | |
| 1139 } | |
| 1140 last_page = temp_page; | |
| 1069 } | 1141 } |
| 1142 | |
| 1070 committed_ = false; | 1143 committed_ = false; |
| 1071 return true; | 1144 return true; |
| 1072 } | 1145 } |
| 1073 | 1146 |
| 1074 | 1147 |
| 1075 void SemiSpace::Reset() { | 1148 void SemiSpace::Reset() { |
| 1076 ASSERT(anchor_.next_page() != &anchor_); | 1149 ASSERT(anchor_.next_page() != &anchor_); |
| 1077 current_page_ = anchor_.next_page(); | 1150 current_page_ = anchor_.next_page(); |
| 1078 } | 1151 } |
| 1079 | 1152 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1105 bool SemiSpace::Setup(Address start, | 1178 bool SemiSpace::Setup(Address start, |
| 1106 int initial_capacity, | 1179 int initial_capacity, |
| 1107 int maximum_capacity) { | 1180 int maximum_capacity) { |
| 1108 // Creates a space in the young generation. The constructor does not | 1181 // Creates a space in the young generation. The constructor does not |
| 1109 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of | 1182 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of |
| 1110 // memory of size 'capacity' when set up, and does not grow or shrink | 1183 // memory of size 'capacity' when set up, and does not grow or shrink |
| 1111 // otherwise. In the mark-compact collector, the memory region of the from | 1184 // otherwise. In the mark-compact collector, the memory region of the from |
| 1112 // space is used as the marking stack. It requires contiguous memory | 1185 // space is used as the marking stack. It requires contiguous memory |
| 1113 // addresses. | 1186 // addresses. |
| 1114 ASSERT(maximum_capacity >= Page::kPageSize); | 1187 ASSERT(maximum_capacity >= Page::kPageSize); |
| 1115 if (initial_capacity < Page::kPageSize) { | 1188 initial_capacity_ = initial_capacity & ~Page::kPageAlignmentMask; |
| 1116 initial_capacity = Page::kPageSize; | |
| 1117 } else { | |
| 1118 initial_capacity &= ~Page::kPageAlignmentMask; | |
| 1119 } | |
| 1120 initial_capacity_ = initial_capacity; | |
| 1121 capacity_ = initial_capacity; | 1189 capacity_ = initial_capacity; |
| 1122 maximum_capacity_ = maximum_capacity; | 1190 maximum_capacity_ = maximum_capacity; |
| 1123 committed_ = false; | 1191 committed_ = false; |
| 1124 start_ = start; | 1192 start_ = start; |
| 1125 address_mask_ = ~(maximum_capacity - 1); | 1193 address_mask_ = ~(maximum_capacity - 1); |
| 1126 object_mask_ = address_mask_ | kHeapObjectTagMask; | 1194 object_mask_ = address_mask_ | kHeapObjectTagMask; |
| 1127 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag; | 1195 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag; |
| 1128 age_mark_ = start_; | 1196 age_mark_ = start_; |
| 1129 | 1197 |
| 1130 return Commit(); | 1198 return Commit(); |
| 1131 } | 1199 } |
| 1132 | 1200 |
| 1133 | 1201 |
| 1134 void SemiSpace::TearDown() { | 1202 void SemiSpace::TearDown() { |
| 1135 start_ = NULL; | 1203 start_ = NULL; |
| 1136 capacity_ = 0; | 1204 capacity_ = 0; |
| 1137 } | 1205 } |
| 1138 | 1206 |
| 1139 | 1207 |
| 1140 bool SemiSpace::Grow() { | 1208 bool SemiSpace::Grow() { |
| 1141 return false; // TODO(gc): Temporary hack while semispaces are only one page. | 1209 return false; // TODO(gc): Temporary hack while semispaces are only one page. |
| 1142 // Double the semispace size but only up to maximum capacity. | 1210 // Double the semispace size but only up to maximum capacity. |
| 1143 int maximum_extra = maximum_capacity_ - capacity_; | 1211 int maximum_extra = maximum_capacity_ - capacity_; |
| 1144 int extra = Min(RoundUp(capacity_, static_cast<int>(OS::AllocateAlignment())), | 1212 int extra = Min(RoundUp(capacity_, static_cast<int>(OS::AllocateAlignment())), |
| 1145 maximum_extra); | 1213 maximum_extra); |
| 1146 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1214 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
| 1147 high(), extra, executable())) { | 1215 space_high(), extra, executable())) { |
| 1148 return false; | 1216 return false; |
| 1149 } | 1217 } |
| 1150 capacity_ += extra; | 1218 capacity_ += extra; |
| 1151 return true; | 1219 return true; |
| 1152 } | 1220 } |
| 1153 | 1221 |
| 1154 | 1222 |
| 1155 bool SemiSpace::GrowTo(int new_capacity) { | 1223 bool SemiSpace::GrowTo(int new_capacity) { |
| 1156 return false; // TODO(gc): Temporary hack while semispaces are only one page. | 1224 return false; // TODO(gc): Temporary hack while semispaces are only one page. |
| 1157 ASSERT(new_capacity <= maximum_capacity_); | 1225 ASSERT(new_capacity <= maximum_capacity_); |
| 1158 ASSERT(new_capacity > capacity_); | 1226 ASSERT(new_capacity > capacity_); |
| 1159 size_t delta = new_capacity - capacity_; | 1227 size_t delta = new_capacity - capacity_; |
| 1160 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1228 ASSERT(IsAligned(delta, OS::AllocateAlignment())); |
| 1161 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1229 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
| 1162 high(), delta, executable())) { | 1230 space_high(), delta, executable())) { |
| 1163 return false; | 1231 return false; |
| 1164 } | 1232 } |
| 1165 capacity_ = new_capacity; | 1233 capacity_ = new_capacity; |
| 1166 return true; | 1234 return true; |
| 1167 } | 1235 } |
| 1168 | 1236 |
| 1169 | 1237 |
| 1170 bool SemiSpace::ShrinkTo(int new_capacity) { | 1238 bool SemiSpace::ShrinkTo(int new_capacity) { |
| 1171 return false; // TODO(gc): Temporary hack while semispaces are only one page. | 1239 return false; // TODO(gc): Temporary hack while semispaces are only one page. |
| 1172 ASSERT(new_capacity >= initial_capacity_); | 1240 ASSERT(new_capacity >= initial_capacity_); |
| 1173 ASSERT(new_capacity < capacity_); | 1241 ASSERT(new_capacity < capacity_); |
| 1174 size_t delta = capacity_ - new_capacity; | 1242 size_t delta = capacity_ - new_capacity; |
| 1175 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1243 ASSERT(IsAligned(delta, OS::AllocateAlignment())); |
| 1176 if (!heap()->isolate()->memory_allocator()->UncommitBlock( | 1244 if (!heap()->isolate()->memory_allocator()->UncommitBlock( |
| 1177 high() - delta, delta)) { | 1245 space_high() - delta, delta)) { |
| 1178 return false; | 1246 return false; |
| 1179 } | 1247 } |
| 1180 capacity_ = new_capacity; | 1248 capacity_ = new_capacity; |
| 1181 return true; | 1249 return true; |
| 1182 } | 1250 } |
| 1183 | 1251 |
| 1184 | 1252 |
| 1185 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { | 1253 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { |
| 1186 anchor_.set_owner(this); | 1254 anchor_.set_owner(this); |
| 1187 // Fixup back-pointers to anchor. Address of anchor changes | 1255 // Fixup back-pointers to anchor. Address of anchor changes |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1221 CHECK(page->semi_space() == this); | 1289 CHECK(page->semi_space() == this); |
| 1222 CHECK(page->InNewSpace()); | 1290 CHECK(page->InNewSpace()); |
| 1223 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE | 1291 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE |
| 1224 : MemoryChunk::IN_TO_SPACE)); | 1292 : MemoryChunk::IN_TO_SPACE)); |
| 1225 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE | 1293 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE |
| 1226 : MemoryChunk::IN_FROM_SPACE)); | 1294 : MemoryChunk::IN_FROM_SPACE)); |
| 1227 CHECK(page->prev_page()->next_page() == page); | 1295 CHECK(page->prev_page()->next_page() == page); |
| 1228 page = page->next_page(); | 1296 page = page->next_page(); |
| 1229 } | 1297 } |
| 1230 } | 1298 } |
| 1299 | |
| 1300 | |
| 1301 void SemiSpace::ValidateRange(Address start, Address end) { | |
| 1302 // Addresses belong to same semi-space | |
| 1303 NewSpacePage* page = NewSpacePage::FromAddress(start); | |
| 1304 NewSpacePage* end_page = NewSpacePage::FromLimit(end); | |
| 1305 SemiSpace* space = page->semi_space(); | |
| 1306 CHECK_EQ(space, end_page->semi_space()); | |
| 1307 // Start address is before end address, either on same page, | |
| 1308 // or end address is on a later page in the linked list of | |
| 1309 // semi-space pages. | |
| 1310 if (page == end_page) { | |
| 1311 CHECK(start <= end); | |
| 1312 } else { | |
| 1313 while (page != end_page) { | |
| 1314 page = page->next_page(); | |
| 1315 CHECK_NE(page, space->anchor()); | |
| 1316 } | |
| 1317 } | |
| 1318 } | |
| 1231 #endif | 1319 #endif |
| 1232 | 1320 |
| 1233 | 1321 |
| 1234 // ----------------------------------------------------------------------------- | 1322 // ----------------------------------------------------------------------------- |
| 1235 // SemiSpaceIterator implementation. | 1323 // SemiSpaceIterator implementation. |
| 1236 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) { | 1324 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) { |
| 1237 Initialize(space, space->bottom(), space->top(), NULL); | 1325 Initialize(space->bottom(), space->top(), NULL); |
| 1238 } | 1326 } |
| 1239 | 1327 |
| 1240 | 1328 |
| 1241 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, | 1329 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, |
| 1242 HeapObjectCallback size_func) { | 1330 HeapObjectCallback size_func) { |
| 1243 Initialize(space, space->bottom(), space->top(), size_func); | 1331 Initialize(space->bottom(), space->top(), size_func); |
| 1244 } | 1332 } |
| 1245 | 1333 |
| 1246 | 1334 |
| 1247 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, Address start) { | 1335 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, Address start) { |
| 1248 Initialize(space, start, space->top(), NULL); | 1336 Initialize(start, space->top(), NULL); |
| 1249 } | 1337 } |
| 1250 | 1338 |
| 1251 | 1339 |
| 1252 void SemiSpaceIterator::Initialize(NewSpace* space, | 1340 SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) { |
| 1253 Address start, | 1341 Initialize(from, to, NULL); |
| 1342 } | |
| 1343 | |
| 1344 | |
| 1345 void SemiSpaceIterator::Initialize(Address start, | |
| 1254 Address end, | 1346 Address end, |
| 1255 HeapObjectCallback size_func) { | 1347 HeapObjectCallback size_func) { |
| 1256 ASSERT(space->ToSpaceContains(start)); | 1348 #ifdef DEBUG |
| 1257 ASSERT(space->ToSpaceLow() <= end | 1349 SemiSpace::ValidateRange(start, end); |
| 1258 && end <= space->ToSpaceHigh()); | 1350 #endif |
| 1259 space_ = &space->to_space_; | 1351 NewSpacePage* page = NewSpacePage::FromAddress(start); |
| 1260 current_ = start; | 1352 current_ = start; |
| 1261 NewSpacePage* page = NewSpacePage::FromAddress(start); | |
| 1262 current_page_limit_ = page->body() + page->body_size(); | |
| 1263 if (current_page_limit_ > end) current_page_limit_ = end; | |
| 1264 limit_ = end; | 1353 limit_ = end; |
| 1354 current_page_limit_ = page->body_limit(); | |
| 1265 size_func_ = size_func; | 1355 size_func_ = size_func; |
| 1266 } | 1356 } |
| 1267 | 1357 |
| 1268 | 1358 |
| 1269 #ifdef DEBUG | 1359 #ifdef DEBUG |
| 1270 // heap_histograms is shared, always clear it before using it. | 1360 // heap_histograms is shared, always clear it before using it. |
| 1271 static void ClearHistograms() { | 1361 static void ClearHistograms() { |
| 1272 Isolate* isolate = Isolate::Current(); | 1362 Isolate* isolate = Isolate::Current(); |
| 1273 // We reset the name each time, though it hasn't changed. | 1363 // We reset the name each time, though it hasn't changed. |
| 1274 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); | 1364 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2352 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { | 2442 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { |
| 2353 if (obj->IsCode()) { | 2443 if (obj->IsCode()) { |
| 2354 Code* code = Code::cast(obj); | 2444 Code* code = Code::cast(obj); |
| 2355 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2445 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2356 } | 2446 } |
| 2357 } | 2447 } |
| 2358 } | 2448 } |
| 2359 #endif // DEBUG | 2449 #endif // DEBUG |
| 2360 | 2450 |
| 2361 } } // namespace v8::internal | 2451 } } // namespace v8::internal |
| OLD | NEW |