OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 space->set_age_mark(space->top()); | 1275 space->set_age_mark(space->top()); |
1276 } | 1276 } |
1277 | 1277 |
1278 | 1278 |
1279 static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { | 1279 static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { |
1280 PageIterator it(space, PageIterator::PAGES_IN_USE); | 1280 PageIterator it(space, PageIterator::PAGES_IN_USE); |
1281 | 1281 |
1282 // During sweeping of paged space we are trying to find longest sequences | 1282 // During sweeping of paged space we are trying to find longest sequences |
1283 // of pages without live objects and free them (instead of putting them on | 1283 // of pages without live objects and free them (instead of putting them on |
1284 // the free list). | 1284 // the free list). |
1285 Page* prev = NULL; // Page preceding current. | 1285 |
1286 Page* first_empty_page = NULL; // First empty page in a sequence. | 1286 // Page preceding current. |
1287 Page* prec_first_empty_page = NULL; // Page preceding first empty page. | 1287 Page* prev = Page::FromAddress(NULL); |
| 1288 |
| 1289 // First empty page in a sequence. |
| 1290 Page* first_empty_page = Page::FromAddress(NULL); |
| 1291 |
| 1292 // Page preceding first empty page. |
| 1293 Page* prec_first_empty_page = Page::FromAddress(NULL); |
1288 | 1294 |
1289 // If last used page of space ends with a sequence of dead objects | 1295 // If last used page of space ends with a sequence of dead objects |
1290 // we can adjust allocation top instead of puting this free area into | 1296 // we can adjust allocation top instead of puting this free area into |
1291 // the free list. Thus during sweeping we keep track of such areas | 1297 // the free list. Thus during sweeping we keep track of such areas |
1292 // and defer their deallocation until the sweeping of the next page | 1298 // and defer their deallocation until the sweeping of the next page |
1293 // is done: if one of the next pages contains live objects we have | 1299 // is done: if one of the next pages contains live objects we have |
1294 // to put such area into the free list. | 1300 // to put such area into the free list. |
1295 Address last_free_start = NULL; | 1301 Address last_free_start = NULL; |
1296 int last_free_size = 0; | 1302 int last_free_size = 0; |
1297 | 1303 |
(...skipping 26 matching lines...) Expand all Loading... |
1324 // The object is now unmarked for the call to Size() at the top of the | 1330 // The object is now unmarked for the call to Size() at the top of the |
1325 // loop. | 1331 // loop. |
1326 } | 1332 } |
1327 | 1333 |
1328 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop()) | 1334 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop()) |
1329 || (!is_previous_alive && free_start == p->ObjectAreaStart()); | 1335 || (!is_previous_alive && free_start == p->ObjectAreaStart()); |
1330 | 1336 |
1331 if (page_is_empty) { | 1337 if (page_is_empty) { |
1332 // This page is empty. Check whether we are in the middle of | 1338 // This page is empty. Check whether we are in the middle of |
1333 // sequence of empty pages and start one if not. | 1339 // sequence of empty pages and start one if not. |
1334 if (first_empty_page == NULL) { | 1340 if (!first_empty_page->is_valid()) { |
1335 first_empty_page = p; | 1341 first_empty_page = p; |
1336 prec_first_empty_page = prev; | 1342 prec_first_empty_page = prev; |
1337 } | 1343 } |
1338 | 1344 |
1339 if (!is_previous_alive) { | 1345 if (!is_previous_alive) { |
1340 // There are dead objects on this page. Update space accounting stats | 1346 // There are dead objects on this page. Update space accounting stats |
1341 // without putting anything into free list. | 1347 // without putting anything into free list. |
1342 int size_in_bytes = static_cast<int>(p->AllocationTop() - free_start); | 1348 int size_in_bytes = static_cast<int>(p->AllocationTop() - free_start); |
1343 if (size_in_bytes > 0) { | 1349 if (size_in_bytes > 0) { |
1344 dealloc(free_start, size_in_bytes, false); | 1350 dealloc(free_start, size_in_bytes, false); |
1345 } | 1351 } |
1346 } | 1352 } |
1347 } else { | 1353 } else { |
1348 // This page is not empty. Sequence of empty pages ended on the previous | 1354 // This page is not empty. Sequence of empty pages ended on the previous |
1349 // one. | 1355 // one. |
1350 if (first_empty_page != NULL) { | 1356 if (first_empty_page->is_valid()) { |
1351 space->FreePages(prec_first_empty_page, prev); | 1357 space->FreePages(prec_first_empty_page, prev); |
1352 prec_first_empty_page = first_empty_page = NULL; | 1358 prec_first_empty_page = first_empty_page = Page::FromAddress(NULL); |
1353 } | 1359 } |
1354 | 1360 |
1355 // If there is a free ending area on one of the previous pages we have | 1361 // If there is a free ending area on one of the previous pages we have |
1356 // deallocate that area and put it on the free list. | 1362 // deallocate that area and put it on the free list. |
1357 if (last_free_size > 0) { | 1363 if (last_free_size > 0) { |
1358 dealloc(last_free_start, last_free_size, true); | 1364 dealloc(last_free_start, last_free_size, true); |
1359 last_free_start = NULL; | 1365 last_free_start = NULL; |
1360 last_free_size = 0; | 1366 last_free_size = 0; |
1361 } | 1367 } |
1362 | 1368 |
1363 // If the last region of this page was not live we remember it. | 1369 // If the last region of this page was not live we remember it. |
1364 if (!is_previous_alive) { | 1370 if (!is_previous_alive) { |
1365 ASSERT(last_free_size == 0); | 1371 ASSERT(last_free_size == 0); |
1366 last_free_size = static_cast<int>(p->AllocationTop() - free_start); | 1372 last_free_size = static_cast<int>(p->AllocationTop() - free_start); |
1367 last_free_start = free_start; | 1373 last_free_start = free_start; |
1368 } | 1374 } |
1369 } | 1375 } |
1370 | 1376 |
1371 prev = p; | 1377 prev = p; |
1372 } | 1378 } |
1373 | 1379 |
1374 // We reached end of space. See if we need to adjust allocation top. | 1380 // We reached end of space. See if we need to adjust allocation top. |
1375 Address new_allocation_top = NULL; | 1381 Address new_allocation_top = NULL; |
1376 | 1382 |
1377 if (first_empty_page != NULL) { | 1383 if (first_empty_page->is_valid()) { |
1378 // Last used pages in space are empty. We can move allocation top backwards | 1384 // Last used pages in space are empty. We can move allocation top backwards |
1379 // to the beginning of first empty page. | 1385 // to the beginning of first empty page. |
1380 ASSERT(prev == space->AllocationTopPage()); | 1386 ASSERT(prev == space->AllocationTopPage()); |
1381 | 1387 |
1382 new_allocation_top = first_empty_page->ObjectAreaStart(); | 1388 new_allocation_top = first_empty_page->ObjectAreaStart(); |
1383 } | 1389 } |
1384 | 1390 |
1385 if (last_free_size > 0) { | 1391 if (last_free_size > 0) { |
1386 // There was a free ending area on the previous page. | 1392 // There was a free ending area on the previous page. |
1387 // Deallocate it without putting it into freelist and move allocation | 1393 // Deallocate it without putting it into freelist and move allocation |
1388 // top to the beginning of this free area. | 1394 // top to the beginning of this free area. |
1389 dealloc(last_free_start, last_free_size, false); | 1395 dealloc(last_free_start, last_free_size, false); |
1390 new_allocation_top = last_free_start; | 1396 new_allocation_top = last_free_start; |
1391 } | 1397 } |
1392 | 1398 |
1393 if (new_allocation_top != NULL) { | 1399 if (new_allocation_top != NULL) { |
1394 #ifdef DEBUG | 1400 #ifdef DEBUG |
1395 Page* new_allocation_top_page = Page::FromAllocationTop(new_allocation_top); | 1401 Page* new_allocation_top_page = Page::FromAllocationTop(new_allocation_top); |
1396 ASSERT(((first_empty_page == NULL) && | 1402 if (!first_empty_page->is_valid()) { |
1397 (new_allocation_top_page == space->AllocationTopPage())) || | 1403 ASSERT(new_allocation_top_page == space->AllocationTopPage()); |
1398 ((first_empty_page != NULL) && (last_free_size > 0) && | 1404 } else if (last_free_size > 0) { |
1399 (new_allocation_top_page == prec_first_empty_page)) || | 1405 ASSERT(new_allocation_top_page == prec_first_empty_page); |
1400 ((first_empty_page != NULL) && (last_free_size == 0) && | 1406 } else { |
1401 (new_allocation_top_page == first_empty_page))); | 1407 ASSERT(new_allocation_top_page == first_empty_page); |
| 1408 } |
1402 #endif | 1409 #endif |
1403 | 1410 |
1404 space->SetTop(new_allocation_top); | 1411 space->SetTop(new_allocation_top); |
1405 } | 1412 } |
1406 } | 1413 } |
1407 | 1414 |
1408 | 1415 |
1409 void MarkCompactCollector::DeallocateOldPointerBlock(Address start, | 1416 void MarkCompactCollector::DeallocateOldPointerBlock(Address start, |
1410 int size_in_bytes, | 1417 int size_in_bytes, |
1411 bool add_to_freelist) { | 1418 bool add_to_freelist) { |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 #ifdef ENABLE_LOGGING_AND_PROFILING | 2310 #ifdef ENABLE_LOGGING_AND_PROFILING |
2304 if (obj->IsCode()) { | 2311 if (obj->IsCode()) { |
2305 PROFILE(CodeDeleteEvent(obj->address())); | 2312 PROFILE(CodeDeleteEvent(obj->address())); |
2306 } else if (obj->IsJSFunction()) { | 2313 } else if (obj->IsJSFunction()) { |
2307 PROFILE(FunctionDeleteEvent(obj->address())); | 2314 PROFILE(FunctionDeleteEvent(obj->address())); |
2308 } | 2315 } |
2309 #endif | 2316 #endif |
2310 } | 2317 } |
2311 | 2318 |
2312 } } // namespace v8::internal | 2319 } } // namespace v8::internal |
OLD | NEW |