| 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 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 } | 1085 } |
| 1086 | 1086 |
| 1087 // Check semi-spaces. | 1087 // Check semi-spaces. |
| 1088 ASSERT_EQ(from_space_.id(), kFromSpace); | 1088 ASSERT_EQ(from_space_.id(), kFromSpace); |
| 1089 ASSERT_EQ(to_space_.id(), kToSpace); | 1089 ASSERT_EQ(to_space_.id(), kToSpace); |
| 1090 from_space_.Verify(); | 1090 from_space_.Verify(); |
| 1091 to_space_.Verify(); | 1091 to_space_.Verify(); |
| 1092 } | 1092 } |
| 1093 #endif | 1093 #endif |
| 1094 | 1094 |
| 1095 | |
| 1096 bool SemiSpace::Commit() { | |
| 1097 ASSERT(!is_committed()); | |
| 1098 int pages = capacity_ / Page::kPageSize; | |
| 1099 if (!heap()->isolate()->memory_allocator()->CommitBlock(start_, | |
| 1100 capacity_, | |
| 1101 executable())) { | |
| 1102 return false; | |
| 1103 } | |
| 1104 | |
| 1105 NewSpacePage* page = anchor(); | |
| 1106 for (int i = 0; i < pages; i++) { | |
| 1107 NewSpacePage* new_page = | |
| 1108 NewSpacePage::Initialize(heap(), start_ + i * Page::kPageSize, this); | |
| 1109 new_page->InsertAfter(page); | |
| 1110 page = new_page; | |
| 1111 } | |
| 1112 | |
| 1113 committed_ = true; | |
| 1114 Reset(); | |
| 1115 return true; | |
| 1116 } | |
| 1117 | |
| 1118 | |
| 1119 bool SemiSpace::Uncommit() { | |
| 1120 ASSERT(is_committed()); | |
| 1121 if (!heap()->isolate()->memory_allocator()->UncommitBlock(start_, | |
| 1122 capacity_)) { | |
| 1123 return false; | |
| 1124 } | |
| 1125 anchor()->set_next_page(anchor()); | |
| 1126 anchor()->set_prev_page(anchor()); | |
| 1127 | |
| 1128 committed_ = false; | |
| 1129 return true; | |
| 1130 } | |
| 1131 | |
| 1132 | |
| 1133 void SemiSpace::Reset() { | |
| 1134 ASSERT(anchor_.next_page() != &anchor_); | |
| 1135 current_page_ = anchor_.next_page(); | |
| 1136 } | |
| 1137 | |
| 1138 | |
| 1139 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { | |
| 1140 // We won't be swapping semispaces without data in them. | |
| 1141 ASSERT(from->anchor_.next_page() != &from->anchor_); | |
| 1142 ASSERT(to->anchor_.next_page() != &to->anchor_); | |
| 1143 | |
| 1144 // Swap bits. | |
| 1145 SemiSpace tmp = *from; | |
| 1146 *from = *to; | |
| 1147 *to = tmp; | |
| 1148 | |
| 1149 // Fixup back-pointers to the page list anchor now that its address | |
| 1150 // has changed. | |
| 1151 // Swap to/from-space bits on pages. | |
| 1152 // Copy GC flags from old active space (from-space) to new (to-space). | |
| 1153 intptr_t flags = from->current_page()->GetFlags(); | |
| 1154 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask); | |
| 1155 | |
| 1156 from->FlipPages(0, 0); | |
| 1157 } | |
| 1158 | |
| 1159 | |
| 1160 // ----------------------------------------------------------------------------- | 1095 // ----------------------------------------------------------------------------- |
| 1161 // SemiSpace implementation | 1096 // SemiSpace implementation |
| 1162 | 1097 |
| 1163 bool SemiSpace::Setup(Address start, | 1098 bool SemiSpace::Setup(Address start, |
| 1164 int initial_capacity, | 1099 int initial_capacity, |
| 1165 int maximum_capacity) { | 1100 int maximum_capacity) { |
| 1166 // Creates a space in the young generation. The constructor does not | 1101 // Creates a space in the young generation. The constructor does not |
| 1167 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of | 1102 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of |
| 1168 // memory of size 'capacity' when set up, and does not grow or shrink | 1103 // memory of size 'capacity' when set up, and does not grow or shrink |
| 1169 // otherwise. In the mark-compact collector, the memory region of the from | 1104 // otherwise. In the mark-compact collector, the memory region of the from |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 | 1179 |
| 1245 bool becomes_to_space = (id_ == kFromSpace); | 1180 bool becomes_to_space = (id_ == kFromSpace); |
| 1246 id_ = becomes_to_space ? kToSpace : kFromSpace; | 1181 id_ = becomes_to_space ? kToSpace : kFromSpace; |
| 1247 NewSpacePage* page = anchor_.next_page(); | 1182 NewSpacePage* page = anchor_.next_page(); |
| 1248 while (page != &anchor_) { | 1183 while (page != &anchor_) { |
| 1249 page->set_owner(this); | 1184 page->set_owner(this); |
| 1250 page->SetFlags(flags, mask); | 1185 page->SetFlags(flags, mask); |
| 1251 if (becomes_to_space) { | 1186 if (becomes_to_space) { |
| 1252 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); | 1187 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
| 1253 page->SetFlag(MemoryChunk::IN_TO_SPACE); | 1188 page->SetFlag(MemoryChunk::IN_TO_SPACE); |
| 1189 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| 1254 } else { | 1190 } else { |
| 1255 page->SetFlag(MemoryChunk::IN_FROM_SPACE); | 1191 page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
| 1256 page->ClearFlag(MemoryChunk::IN_TO_SPACE); | 1192 page->ClearFlag(MemoryChunk::IN_TO_SPACE); |
| 1257 } | 1193 } |
| 1258 ASSERT(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); | 1194 ASSERT(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); |
| 1259 ASSERT(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || | 1195 ASSERT(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || |
| 1260 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); | 1196 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); |
| 1261 page = page->next_page(); | 1197 page = page->next_page(); |
| 1262 } | 1198 } |
| 1263 } | 1199 } |
| 1264 | 1200 |
| 1201 |
| 1202 bool SemiSpace::Commit() { |
| 1203 ASSERT(!is_committed()); |
| 1204 int pages = capacity_ / Page::kPageSize; |
| 1205 if (!heap()->isolate()->memory_allocator()->CommitBlock(start_, |
| 1206 capacity_, |
| 1207 executable())) { |
| 1208 return false; |
| 1209 } |
| 1210 |
| 1211 NewSpacePage* page = anchor(); |
| 1212 for (int i = 0; i < pages; i++) { |
| 1213 NewSpacePage* new_page = |
| 1214 NewSpacePage::Initialize(heap(), start_ + i * Page::kPageSize, this); |
| 1215 new_page->InsertAfter(page); |
| 1216 page = new_page; |
| 1217 } |
| 1218 |
| 1219 committed_ = true; |
| 1220 Reset(); |
| 1221 return true; |
| 1222 } |
| 1223 |
| 1224 |
| 1225 bool SemiSpace::Uncommit() { |
| 1226 ASSERT(is_committed()); |
| 1227 if (!heap()->isolate()->memory_allocator()->UncommitBlock(start_, |
| 1228 capacity_)) { |
| 1229 return false; |
| 1230 } |
| 1231 anchor()->set_next_page(anchor()); |
| 1232 anchor()->set_prev_page(anchor()); |
| 1233 |
| 1234 committed_ = false; |
| 1235 return true; |
| 1236 } |
| 1237 |
| 1238 |
| 1239 void SemiSpace::Reset() { |
| 1240 ASSERT(anchor_.next_page() != &anchor_); |
| 1241 current_page_ = anchor_.next_page(); |
| 1242 } |
| 1243 |
| 1244 |
| 1245 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { |
| 1246 // We won't be swapping semispaces without data in them. |
| 1247 ASSERT(from->anchor_.next_page() != &from->anchor_); |
| 1248 ASSERT(to->anchor_.next_page() != &to->anchor_); |
| 1249 |
| 1250 // Swap bits. |
| 1251 SemiSpace tmp = *from; |
| 1252 *from = *to; |
| 1253 *to = tmp; |
| 1254 |
| 1255 // Fixup back-pointers to the page list anchor now that its address |
| 1256 // has changed. |
| 1257 // Swap to/from-space bits on pages. |
| 1258 // Copy GC flags from old active space (from-space) to new (to-space). |
| 1259 intptr_t flags = from->current_page()->GetFlags(); |
| 1260 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask); |
| 1261 |
| 1262 from->FlipPages(0, 0); |
| 1263 } |
| 1264 |
| 1265 |
| 1266 void SemiSpace::set_age_mark(Address mark) { |
| 1267 ASSERT(NewSpacePage::FromLimit(mark)->semi_space() == this); |
| 1268 age_mark_ = mark; |
| 1269 // Mark all pages up to the one containing mark. |
| 1270 NewSpacePageIterator it(space_low(), mark); |
| 1271 while (it.has_next()) { |
| 1272 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| 1273 } |
| 1274 } |
| 1275 |
| 1276 |
| 1265 #ifdef DEBUG | 1277 #ifdef DEBUG |
| 1266 void SemiSpace::Print() { } | 1278 void SemiSpace::Print() { } |
| 1267 | 1279 |
| 1268 | 1280 |
| 1269 void SemiSpace::Verify() { | 1281 void SemiSpace::Verify() { |
| 1270 bool is_from_space = (id_ == kFromSpace); | 1282 bool is_from_space = (id_ == kFromSpace); |
| 1271 NewSpacePage* page = anchor_.next_page(); | 1283 NewSpacePage* page = anchor_.next_page(); |
| 1272 CHECK(anchor_.semi_space() == this); | 1284 CHECK(anchor_.semi_space() == this); |
| 1273 while (page != &anchor_) { | 1285 while (page != &anchor_) { |
| 1274 CHECK(page->semi_space() == this); | 1286 CHECK(page->semi_space() == this); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 | 1558 |
| 1547 | 1559 |
| 1548 void NewSpace::RecordPromotion(HeapObject* obj) { | 1560 void NewSpace::RecordPromotion(HeapObject* obj) { |
| 1549 InstanceType type = obj->map()->instance_type(); | 1561 InstanceType type = obj->map()->instance_type(); |
| 1550 ASSERT(0 <= type && type <= LAST_TYPE); | 1562 ASSERT(0 <= type && type <= LAST_TYPE); |
| 1551 promoted_histogram_[type].increment_number(1); | 1563 promoted_histogram_[type].increment_number(1); |
| 1552 promoted_histogram_[type].increment_bytes(obj->Size()); | 1564 promoted_histogram_[type].increment_bytes(obj->Size()); |
| 1553 } | 1565 } |
| 1554 #endif // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 1566 #endif // defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
| 1555 | 1567 |
| 1556 | |
| 1557 // ----------------------------------------------------------------------------- | 1568 // ----------------------------------------------------------------------------- |
| 1558 // Free lists for old object spaces implementation | 1569 // Free lists for old object spaces implementation |
| 1559 | 1570 |
| 1560 void FreeListNode::set_size(Heap* heap, int size_in_bytes) { | 1571 void FreeListNode::set_size(Heap* heap, int size_in_bytes) { |
| 1561 ASSERT(size_in_bytes > 0); | 1572 ASSERT(size_in_bytes > 0); |
| 1562 ASSERT(IsAligned(size_in_bytes, kPointerSize)); | 1573 ASSERT(IsAligned(size_in_bytes, kPointerSize)); |
| 1563 | 1574 |
| 1564 // We write a map and possibly size information to the block. If the block | 1575 // We write a map and possibly size information to the block. If the block |
| 1565 // is big enough to be a FreeSpace with at least one extra word (the next | 1576 // is big enough to be a FreeSpace with at least one extra word (the next |
| 1566 // pointer), we set its map to be the free space map and its size to an | 1577 // pointer), we set its map to be the free space map and its size to an |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2428 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { | 2439 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { |
| 2429 if (obj->IsCode()) { | 2440 if (obj->IsCode()) { |
| 2430 Code* code = Code::cast(obj); | 2441 Code* code = Code::cast(obj); |
| 2431 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2442 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2432 } | 2443 } |
| 2433 } | 2444 } |
| 2434 } | 2445 } |
| 2435 #endif // DEBUG | 2446 #endif // DEBUG |
| 2436 | 2447 |
| 2437 } } // namespace v8::internal | 2448 } } // namespace v8::internal |
| OLD | NEW |