| 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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 NOT_EXECUTABLE, | 403 NOT_EXECUTABLE, |
| 404 semi_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 = (semi_space->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 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); |
| 414 return static_cast<NewSpacePage*>(chunk); | 414 heap->incremental_marking()->SetNewSpacePageFlags(page); |
| 415 return page; |
| 415 } | 416 } |
| 416 | 417 |
| 417 | 418 |
| 418 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { | 419 void NewSpacePage::InitializeAsAnchor(SemiSpace* semi_space) { |
| 419 set_owner(semi_space); | 420 set_owner(semi_space); |
| 420 set_next_chunk(this); | 421 set_next_chunk(this); |
| 421 set_prev_chunk(this); | 422 set_prev_chunk(this); |
| 422 // Flags marks this invalid page as not being in new-space. | 423 // Flags marks this invalid page as not being in new-space. |
| 423 // All real new-space pages will be in new-space. | 424 // All real new-space pages will be in new-space. |
| 424 SetFlags(0, ~0); | 425 SetFlags(0, ~0); |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 if (!from_space_.Grow()) { | 961 if (!from_space_.Grow()) { |
| 961 // If we managed to grow to space but couldn't grow from space, | 962 // If we managed to grow to space but couldn't grow from space, |
| 962 // attempt to shrink to space. | 963 // attempt to shrink to space. |
| 963 if (!to_space_.ShrinkTo(from_space_.Capacity())) { | 964 if (!to_space_.ShrinkTo(from_space_.Capacity())) { |
| 964 // We are in an inconsistent state because we could not | 965 // We are in an inconsistent state because we could not |
| 965 // commit/uncommit memory from new space. | 966 // commit/uncommit memory from new space. |
| 966 V8::FatalProcessOutOfMemory("Failed to grow new space."); | 967 V8::FatalProcessOutOfMemory("Failed to grow new space."); |
| 967 } | 968 } |
| 968 } | 969 } |
| 969 } | 970 } |
| 970 allocation_info_.limit = to_space_.page_high(); | |
| 971 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 971 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 972 } | 972 } |
| 973 | 973 |
| 974 | 974 |
| 975 void NewSpace::Shrink() { | 975 void NewSpace::Shrink() { |
| 976 int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt()); | 976 int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt()); |
| 977 int rounded_new_capacity = | 977 int rounded_new_capacity = |
| 978 RoundUp(new_capacity, static_cast<int>(OS::AllocateAlignment())); | 978 RoundUp(new_capacity, static_cast<int>(OS::AllocateAlignment())); |
| 979 if (rounded_new_capacity < Capacity() && | 979 if (rounded_new_capacity < Capacity() && |
| 980 to_space_.ShrinkTo(rounded_new_capacity)) { | 980 to_space_.ShrinkTo(rounded_new_capacity)) { |
| 981 // Only shrink from space if we managed to shrink to space. | 981 // Only shrink from space if we managed to shrink to space. |
| 982 if (!from_space_.ShrinkTo(rounded_new_capacity)) { | 982 if (!from_space_.ShrinkTo(rounded_new_capacity)) { |
| 983 // 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 |
| 984 // space, attempt to grow to space again. | 984 // space, attempt to grow to space again. |
| 985 if (!to_space_.GrowTo(from_space_.Capacity())) { | 985 if (!to_space_.GrowTo(from_space_.Capacity())) { |
| 986 // We are in an inconsistent state because we could not | 986 // We are in an inconsistent state because we could not |
| 987 // commit/uncommit memory from new space. | 987 // commit/uncommit memory from new space. |
| 988 V8::FatalProcessOutOfMemory("Failed to shrink new space."); | 988 V8::FatalProcessOutOfMemory("Failed to shrink new space."); |
| 989 } | 989 } |
| 990 } | 990 } |
| 991 } | 991 } |
| 992 allocation_info_.limit = to_space_.page_high(); | 992 allocation_info_.limit = to_space_.page_high(); |
| 993 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 993 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 void NewSpace::UpdateAllocationInfo() { | 997 void NewSpace::UpdateAllocationInfo() { |
| 998 allocation_info_.top = to_space_.page_low(); | 998 allocation_info_.top = to_space_.page_low(); |
| 999 allocation_info_.limit = to_space_.page_high(); | 999 allocation_info_.limit = to_space_.page_high(); |
| 1000 |
| 1001 // Lower limit during incremental marking. |
| 1002 if (heap()->incremental_marking()->IsMarking() && |
| 1003 inline_allocation_limit_step() != 0) { |
| 1004 Address new_limit = |
| 1005 allocation_info_.top + inline_allocation_limit_step(); |
| 1006 allocation_info_.limit = Min(new_limit, allocation_info_.limit); |
| 1007 } |
| 1000 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1008 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 1001 } | 1009 } |
| 1002 | 1010 |
| 1003 | 1011 |
| 1004 void NewSpace::ResetAllocationInfo() { | 1012 void NewSpace::ResetAllocationInfo() { |
| 1005 to_space_.Reset(); | 1013 to_space_.Reset(); |
| 1006 UpdateAllocationInfo(); | 1014 UpdateAllocationInfo(); |
| 1007 // Clear all mark-bits in the to-space. | 1015 // Clear all mark-bits in the to-space. |
| 1008 NewSpacePageIterator it(to_space_.space_low(), to_space_.space_high()); | 1016 NewSpacePageIterator it(to_space_.space_low(), to_space_.space_high()); |
| 1009 while (it.has_next()) { | 1017 while (it.has_next()) { |
| 1010 NewSpacePage* page = it.next(); | 1018 NewSpacePage* page = it.next(); |
| 1011 page->markbits()->Clear(); | 1019 page->markbits()->Clear(); |
| 1012 } | 1020 } |
| 1013 } | 1021 } |
| 1014 | 1022 |
| 1015 | 1023 |
| 1016 bool NewSpace::AddFreshPage() { | 1024 bool NewSpace::AddFreshPage() { |
| 1017 Address top = allocation_info_.top; | 1025 Address top = allocation_info_.top; |
| 1018 if (top == NewSpacePage::FromLimit(top)->body()) { | 1026 if (NewSpacePage::IsAtStart(top)) { |
| 1019 // The current page is already empty. Don't try to make another. | 1027 // The current page is already empty. Don't try to make another. |
| 1020 | 1028 |
| 1021 // We should only get here if someone asks to allocate more | 1029 // We should only get here if someone asks to allocate more |
| 1022 // than what can be stored in a single page. | 1030 // than what can be stored in a single page. |
| 1023 // TODO(gc): Change the limit on new-space allocation to prevent this | 1031 // TODO(gc): Change the limit on new-space allocation to prevent this |
| 1024 // from happening (all such allocations should go directly to LOSpace). | 1032 // from happening (all such allocations should go directly to LOSpace). |
| 1025 return false; | 1033 return false; |
| 1026 } | 1034 } |
| 1027 if (!to_space_.AdvancePage()) { | 1035 if (!to_space_.AdvancePage()) { |
| 1028 // Failed to get a new page in to-space. | 1036 // Failed to get a new page in to-space. |
| 1029 return false; | 1037 return false; |
| 1030 } | 1038 } |
| 1031 // Clear remainder of current page. | 1039 // Clear remainder of current page. |
| 1032 int remaining_in_page = | 1040 int remaining_in_page = |
| 1033 static_cast<int>(NewSpacePage::FromLimit(top)->body_limit() - top); | 1041 static_cast<int>(NewSpacePage::FromLimit(top)->body_limit() - top); |
| 1034 heap()->CreateFillerObjectAt(top, remaining_in_page); | 1042 heap()->CreateFillerObjectAt(top, remaining_in_page); |
| 1043 |
| 1035 UpdateAllocationInfo(); | 1044 UpdateAllocationInfo(); |
| 1036 return true; | 1045 return true; |
| 1037 } | 1046 } |
| 1038 | 1047 |
| 1039 | 1048 |
| 1040 #ifdef DEBUG | 1049 #ifdef DEBUG |
| 1041 // We do not use the SemiSpaceIterator because verification doesn't assume | 1050 // We do not use the SemiSpaceIterator because verification doesn't assume |
| 1042 // that it works (it depends on the invariants we are checking). | 1051 // that it works (it depends on the invariants we are checking). |
| 1043 void NewSpace::Verify() { | 1052 void NewSpace::Verify() { |
| 1044 // The allocation pointer should be in the space or at the very end. | 1053 // The allocation pointer should be in the space or at the very end. |
| 1045 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1054 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 1046 | 1055 |
| 1047 // There should be objects packed in from the low address up to the | 1056 // There should be objects packed in from the low address up to the |
| 1048 // allocation pointer. | 1057 // allocation pointer. |
| 1049 NewSpacePage* page = to_space_.first_page(); | 1058 Address current = to_space_.first_page()->body(); |
| 1050 Address current = page->body(); | |
| 1051 CHECK_EQ(current, to_space_.space_low()); | 1059 CHECK_EQ(current, to_space_.space_low()); |
| 1052 | 1060 |
| 1053 while (current != top()) { | 1061 while (current != top()) { |
| 1054 if (current == page->body_limit()) { | 1062 if (!NewSpacePage::IsAtEnd(current)) { |
| 1063 // The allocation pointer should not be in the middle of an object. |
| 1064 CHECK(!NewSpacePage::FromLimit(current)->ContainsLimit(top()) || |
| 1065 current < top()); |
| 1066 |
| 1067 HeapObject* object = HeapObject::FromAddress(current); |
| 1068 |
| 1069 // The first word should be a map, and we expect all map pointers to |
| 1070 // be in map space. |
| 1071 Map* map = object->map(); |
| 1072 CHECK(map->IsMap()); |
| 1073 CHECK(heap()->map_space()->Contains(map)); |
| 1074 |
| 1075 // The object should not be code or a map. |
| 1076 CHECK(!object->IsMap()); |
| 1077 CHECK(!object->IsCode()); |
| 1078 |
| 1079 // The object itself should look OK. |
| 1080 object->Verify(); |
| 1081 |
| 1082 // All the interior pointers should be contained in the heap. |
| 1083 VerifyPointersVisitor visitor; |
| 1084 int size = object->Size(); |
| 1085 object->IterateBody(map->instance_type(), size, &visitor); |
| 1086 |
| 1087 current += size; |
| 1088 } else { |
| 1055 // At end of page, switch to next page. | 1089 // At end of page, switch to next page. |
| 1056 page = page->next_page(); | 1090 NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page(); |
| 1057 // Next page should be valid. | 1091 // Next page should be valid. |
| 1058 CHECK(!page->is_anchor()); | 1092 CHECK(!page->is_anchor()); |
| 1059 current = page->body(); | 1093 current = page->body(); |
| 1060 } | 1094 } |
| 1061 // The allocation pointer should not be in the middle of an object. | |
| 1062 CHECK(!page->ContainsLimit(top()) || current < top()); | |
| 1063 | |
| 1064 HeapObject* object = HeapObject::FromAddress(current); | |
| 1065 | |
| 1066 // The first word should be a map, and we expect all map pointers to | |
| 1067 // be in map space. | |
| 1068 Map* map = object->map(); | |
| 1069 CHECK(map->IsMap()); | |
| 1070 CHECK(heap()->map_space()->Contains(map)); | |
| 1071 | |
| 1072 // The object should not be code or a map. | |
| 1073 CHECK(!object->IsMap()); | |
| 1074 CHECK(!object->IsCode()); | |
| 1075 | |
| 1076 // The object itself should look OK. | |
| 1077 object->Verify(); | |
| 1078 | |
| 1079 // All the interior pointers should be contained in the heap. | |
| 1080 VerifyPointersVisitor visitor; | |
| 1081 int size = object->Size(); | |
| 1082 object->IterateBody(map->instance_type(), size, &visitor); | |
| 1083 | |
| 1084 current += size; | |
| 1085 } | 1095 } |
| 1086 | 1096 |
| 1087 // Check semi-spaces. | 1097 // Check semi-spaces. |
| 1088 ASSERT_EQ(from_space_.id(), kFromSpace); | 1098 ASSERT_EQ(from_space_.id(), kFromSpace); |
| 1089 ASSERT_EQ(to_space_.id(), kToSpace); | 1099 ASSERT_EQ(to_space_.id(), kToSpace); |
| 1090 from_space_.Verify(); | 1100 from_space_.Verify(); |
| 1091 to_space_.Verify(); | 1101 to_space_.Verify(); |
| 1092 } | 1102 } |
| 1093 #endif | 1103 #endif |
| 1094 | 1104 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1119 } | 1129 } |
| 1120 | 1130 |
| 1121 | 1131 |
| 1122 void SemiSpace::TearDown() { | 1132 void SemiSpace::TearDown() { |
| 1123 start_ = NULL; | 1133 start_ = NULL; |
| 1124 capacity_ = 0; | 1134 capacity_ = 0; |
| 1125 } | 1135 } |
| 1126 | 1136 |
| 1127 | 1137 |
| 1128 bool SemiSpace::Grow() { | 1138 bool SemiSpace::Grow() { |
| 1129 return false; // TODO(gc): Temporary hack while semispaces are only one page. | |
| 1130 // Double the semispace size but only up to maximum capacity. | 1139 // Double the semispace size but only up to maximum capacity. |
| 1131 int maximum_extra = maximum_capacity_ - capacity_; | 1140 ASSERT(static_cast<size_t>(Page::kPageSize) > OS::AllocateAlignment()); |
| 1132 int extra = Min(RoundUp(capacity_, static_cast<int>(OS::AllocateAlignment())), | 1141 int new_capacity = Min(maximum_capacity_, |
| 1133 maximum_extra); | 1142 RoundUp(capacity_ * 2, static_cast<int>(Page::kPageSize))); |
| 1134 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1143 return GrowTo(new_capacity); |
| 1135 space_high(), extra, executable())) { | |
| 1136 return false; | |
| 1137 } | |
| 1138 capacity_ += extra; | |
| 1139 return true; | |
| 1140 } | 1144 } |
| 1141 | 1145 |
| 1142 | 1146 |
| 1143 bool SemiSpace::GrowTo(int new_capacity) { | 1147 bool SemiSpace::GrowTo(int new_capacity) { |
| 1144 return false; // TODO(gc): Temporary hack while semispaces are only one page. | |
| 1145 ASSERT(new_capacity <= maximum_capacity_); | 1148 ASSERT(new_capacity <= maximum_capacity_); |
| 1146 ASSERT(new_capacity > capacity_); | 1149 ASSERT(new_capacity > capacity_); |
| 1150 int pages_before = capacity_ / Page::kPageSize; |
| 1147 size_t delta = new_capacity - capacity_; | 1151 size_t delta = new_capacity - capacity_; |
| 1148 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1152 ASSERT(IsAligned(delta, OS::AllocateAlignment())); |
| 1149 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1153 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
| 1150 space_high(), delta, executable())) { | 1154 space_high(), delta, executable())) { |
| 1151 return false; | 1155 return false; |
| 1152 } | 1156 } |
| 1153 capacity_ = new_capacity; | 1157 capacity_ = new_capacity; |
| 1158 int pages_after = capacity_ / Page::kPageSize; |
| 1159 NewSpacePage* last_page = anchor()->prev_page(); |
| 1160 ASSERT(last_page != anchor()); |
| 1161 for (int i = pages_before; i < pages_after; i++) { |
| 1162 Address page_address = start_ + i * Page::kPageSize; |
| 1163 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), |
| 1164 page_address, |
| 1165 this); |
| 1166 new_page->InsertAfter(last_page); |
| 1167 new_page->markbits()->Clear(); |
| 1168 // Duplicate the flags that was set on the old page. |
| 1169 new_page->SetFlags(last_page->GetFlags(), |
| 1170 NewSpacePage::kCopyOnFlipFlagsMask); |
| 1171 last_page = new_page; |
| 1172 } |
| 1154 return true; | 1173 return true; |
| 1155 } | 1174 } |
| 1156 | 1175 |
| 1157 | 1176 |
| 1158 bool SemiSpace::ShrinkTo(int new_capacity) { | 1177 bool SemiSpace::ShrinkTo(int new_capacity) { |
| 1159 return false; // TODO(gc): Temporary hack while semispaces are only one page. | |
| 1160 ASSERT(new_capacity >= initial_capacity_); | 1178 ASSERT(new_capacity >= initial_capacity_); |
| 1161 ASSERT(new_capacity < capacity_); | 1179 ASSERT(new_capacity < capacity_); |
| 1162 size_t delta = capacity_ - new_capacity; | 1180 size_t delta = capacity_ - new_capacity; |
| 1163 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1181 ASSERT(IsAligned(delta, OS::AllocateAlignment())); |
| 1164 if (!heap()->isolate()->memory_allocator()->UncommitBlock( | 1182 if (!heap()->isolate()->memory_allocator()->UncommitBlock( |
| 1165 space_high() - delta, delta)) { | 1183 space_high() - delta, delta)) { |
| 1166 return false; | 1184 return false; |
| 1167 } | 1185 } |
| 1168 capacity_ = new_capacity; | 1186 capacity_ = new_capacity; |
| 1187 |
| 1188 int pages_after = capacity_ / Page::kPageSize; |
| 1189 NewSpacePage* new_last_page = |
| 1190 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize); |
| 1191 new_last_page->set_next_page(anchor()); |
| 1192 anchor()->set_next_page(new_last_page); |
| 1193 ASSERT(current_page_ == first_page()); |
| 1194 |
| 1169 return true; | 1195 return true; |
| 1170 } | 1196 } |
| 1171 | 1197 |
| 1172 | 1198 |
| 1173 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { | 1199 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { |
| 1174 anchor_.set_owner(this); | 1200 anchor_.set_owner(this); |
| 1175 // Fixup back-pointers to anchor. Address of anchor changes | 1201 // Fixup back-pointers to anchor. Address of anchor changes |
| 1176 // when we swap. | 1202 // when we swap. |
| 1177 anchor_.prev_page()->set_next_page(&anchor_); | 1203 anchor_.prev_page()->set_next_page(&anchor_); |
| 1178 anchor_.next_page()->set_prev_page(&anchor_); | 1204 anchor_.next_page()->set_prev_page(&anchor_); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 bool is_from_space = (id_ == kFromSpace); | 1308 bool is_from_space = (id_ == kFromSpace); |
| 1283 NewSpacePage* page = anchor_.next_page(); | 1309 NewSpacePage* page = anchor_.next_page(); |
| 1284 CHECK(anchor_.semi_space() == this); | 1310 CHECK(anchor_.semi_space() == this); |
| 1285 while (page != &anchor_) { | 1311 while (page != &anchor_) { |
| 1286 CHECK(page->semi_space() == this); | 1312 CHECK(page->semi_space() == this); |
| 1287 CHECK(page->InNewSpace()); | 1313 CHECK(page->InNewSpace()); |
| 1288 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE | 1314 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE |
| 1289 : MemoryChunk::IN_TO_SPACE)); | 1315 : MemoryChunk::IN_TO_SPACE)); |
| 1290 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE | 1316 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE |
| 1291 : MemoryChunk::IN_FROM_SPACE)); | 1317 : MemoryChunk::IN_FROM_SPACE)); |
| 1318 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); |
| 1319 if (!is_from_space) { |
| 1320 // The pointers-from-here-are-interesting flag isn't updated dynamically |
| 1321 // on from-space pages, so it might be out of sync with the marking state. |
| 1322 if (page->heap()->incremental_marking()->IsMarking()) { |
| 1323 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1324 } else { |
| 1325 CHECK(!page->IsFlagSet( |
| 1326 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); |
| 1327 } |
| 1328 } |
| 1329 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); |
| 1292 CHECK(page->prev_page()->next_page() == page); | 1330 CHECK(page->prev_page()->next_page() == page); |
| 1293 page = page->next_page(); | 1331 page = page->next_page(); |
| 1294 } | 1332 } |
| 1295 } | 1333 } |
| 1296 | 1334 |
| 1297 | 1335 |
| 1298 void SemiSpace::ValidateRange(Address start, Address end) { | 1336 void SemiSpace::AssertValidRange(Address start, Address end) { |
| 1299 // Addresses belong to same semi-space | 1337 // Addresses belong to same semi-space |
| 1300 NewSpacePage* page = NewSpacePage::FromAddress(start); | 1338 NewSpacePage* page = NewSpacePage::FromAddress(start); |
| 1301 NewSpacePage* end_page = NewSpacePage::FromLimit(end); | 1339 NewSpacePage* end_page = NewSpacePage::FromLimit(end); |
| 1302 SemiSpace* space = page->semi_space(); | 1340 SemiSpace* space = page->semi_space(); |
| 1303 CHECK_EQ(space, end_page->semi_space()); | 1341 CHECK_EQ(space, end_page->semi_space()); |
| 1304 // Start address is before end address, either on same page, | 1342 // Start address is before end address, either on same page, |
| 1305 // or end address is on a later page in the linked list of | 1343 // or end address is on a later page in the linked list of |
| 1306 // semi-space pages. | 1344 // semi-space pages. |
| 1307 if (page == end_page) { | 1345 if (page == end_page) { |
| 1308 CHECK(start <= end); | 1346 CHECK(start <= end); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1335 | 1373 |
| 1336 | 1374 |
| 1337 SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) { | 1375 SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) { |
| 1338 Initialize(from, to, NULL); | 1376 Initialize(from, to, NULL); |
| 1339 } | 1377 } |
| 1340 | 1378 |
| 1341 | 1379 |
| 1342 void SemiSpaceIterator::Initialize(Address start, | 1380 void SemiSpaceIterator::Initialize(Address start, |
| 1343 Address end, | 1381 Address end, |
| 1344 HeapObjectCallback size_func) { | 1382 HeapObjectCallback size_func) { |
| 1345 #ifdef DEBUG | 1383 SemiSpace::AssertValidRange(start, end); |
| 1346 SemiSpace::ValidateRange(start, end); | |
| 1347 #endif | |
| 1348 NewSpacePage* page = NewSpacePage::FromAddress(start); | |
| 1349 current_ = start; | 1384 current_ = start; |
| 1350 limit_ = end; | 1385 limit_ = end; |
| 1351 current_page_limit_ = page->body_limit(); | |
| 1352 size_func_ = size_func; | 1386 size_func_ = size_func; |
| 1353 } | 1387 } |
| 1354 | 1388 |
| 1355 | 1389 |
| 1356 #ifdef DEBUG | 1390 #ifdef DEBUG |
| 1357 // heap_histograms is shared, always clear it before using it. | 1391 // heap_histograms is shared, always clear it before using it. |
| 1358 static void ClearHistograms() { | 1392 static void ClearHistograms() { |
| 1359 Isolate* isolate = Isolate::Current(); | 1393 Isolate* isolate = Isolate::Current(); |
| 1360 // We reset the name each time, though it hasn't changed. | 1394 // We reset the name each time, though it hasn't changed. |
| 1361 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); | 1395 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { | 2454 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { |
| 2421 if (obj->IsCode()) { | 2455 if (obj->IsCode()) { |
| 2422 Code* code = Code::cast(obj); | 2456 Code* code = Code::cast(obj); |
| 2423 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2457 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2424 } | 2458 } |
| 2425 } | 2459 } |
| 2426 } | 2460 } |
| 2427 #endif // DEBUG | 2461 #endif // DEBUG |
| 2428 | 2462 |
| 2429 } } // namespace v8::internal | 2463 } } // namespace v8::internal |
| OLD | NEW |