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 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 pages_in_old_space + pages_in_compaction_space); | 434 pages_in_old_space + pages_in_compaction_space); |
435 | 435 |
436 delete compaction_space; | 436 delete compaction_space; |
437 delete old_space; | 437 delete old_space; |
438 | 438 |
439 memory_allocator->TearDown(); | 439 memory_allocator->TearDown(); |
440 delete memory_allocator; | 440 delete memory_allocator; |
441 } | 441 } |
442 | 442 |
443 | 443 |
| 444 TEST(CompactionSpaceUsingExternalMemory) { |
| 445 const int kObjectSize = 512; |
| 446 |
| 447 Isolate* isolate = CcTest::i_isolate(); |
| 448 Heap* heap = isolate->heap(); |
| 449 MemoryAllocator* allocator = new MemoryAllocator(isolate); |
| 450 CHECK(allocator != nullptr); |
| 451 CHECK(allocator->SetUp(heap->MaxReserved(), heap->MaxExecutableSize())); |
| 452 TestMemoryAllocatorScope test_scope(isolate, allocator); |
| 453 |
| 454 CompactionSpace* compaction_space = |
| 455 new CompactionSpace(heap, OLD_SPACE, NOT_EXECUTABLE); |
| 456 CHECK(compaction_space != NULL); |
| 457 CHECK(compaction_space->SetUp()); |
| 458 |
| 459 OldSpace* old_space = new OldSpace(heap, OLD_SPACE, NOT_EXECUTABLE); |
| 460 CHECK(old_space != NULL); |
| 461 CHECK(old_space->SetUp()); |
| 462 |
| 463 // The linear allocation area already counts as used bytes, making |
| 464 // exact testing impossible. |
| 465 heap->DisableInlineAllocation(); |
| 466 |
| 467 // Test: |
| 468 // * Allocate a backing store in old_space. |
| 469 // * Compute the number num_rest_objects of kObjectSize objects that fit into |
| 470 // of available memory. |
| 471 // kNumRestObjects. |
| 472 // * Add the rest of available memory to the compaction space. |
| 473 // * Allocate kNumRestObjects in the compaction space. |
| 474 // * Allocate one object more. |
| 475 // * Merge the compaction space and compare the expected number of pages. |
| 476 |
| 477 // Allocate a single object in old_space to initialize a backing page. |
| 478 old_space->AllocateRawUnaligned(kObjectSize).ToObjectChecked(); |
| 479 // Compute the number of objects that fit into the rest in old_space. |
| 480 intptr_t rest = static_cast<int>(old_space->Available()); |
| 481 CHECK_GT(rest, 0); |
| 482 intptr_t num_rest_objects = rest / kObjectSize; |
| 483 // After allocating num_rest_objects in compaction_space we allocate a bit |
| 484 // more. |
| 485 const intptr_t kAdditionalCompactionMemory = kObjectSize; |
| 486 // We expect a single old_space page. |
| 487 const intptr_t kExpectedInitialOldSpacePages = 1; |
| 488 // We expect a single additional page in compaction space because we mostly |
| 489 // use external memory. |
| 490 const intptr_t kExpectedCompactionPages = 1; |
| 491 // We expect two pages to be reachable from old_space in the end. |
| 492 const intptr_t kExpectedOldSpacePagesAfterMerge = 2; |
| 493 |
| 494 Object* chunk = |
| 495 old_space->AllocateRawUnaligned(static_cast<int>(rest)).ToObjectChecked(); |
| 496 CHECK_EQ(old_space->CountTotalPages(), kExpectedInitialOldSpacePages); |
| 497 CHECK(chunk != nullptr); |
| 498 CHECK(chunk->IsHeapObject()); |
| 499 |
| 500 CHECK_EQ(compaction_space->CountTotalPages(), 0); |
| 501 CHECK_EQ(compaction_space->Capacity(), 0); |
| 502 // Make the rest of memory available for compaction. |
| 503 compaction_space->AddExternalMemory(HeapObject::cast(chunk)->address(), |
| 504 static_cast<int>(rest)); |
| 505 CHECK_EQ(compaction_space->CountTotalPages(), 0); |
| 506 CHECK_EQ(compaction_space->Capacity(), rest); |
| 507 while (num_rest_objects-- > 0) { |
| 508 compaction_space->AllocateRawUnaligned(kObjectSize).ToObjectChecked(); |
| 509 } |
| 510 // We only used external memory so far. |
| 511 CHECK_EQ(compaction_space->CountTotalPages(), 0); |
| 512 // Additional allocation. |
| 513 compaction_space->AllocateRawUnaligned(kAdditionalCompactionMemory) |
| 514 .ToObjectChecked(); |
| 515 // Now the compaction space shouldve also acquired a page. |
| 516 CHECK_EQ(compaction_space->CountTotalPages(), kExpectedCompactionPages); |
| 517 |
| 518 old_space->MergeCompactionSpace(compaction_space); |
| 519 CHECK_EQ(old_space->CountTotalPages(), kExpectedOldSpacePagesAfterMerge); |
| 520 |
| 521 delete compaction_space; |
| 522 delete old_space; |
| 523 |
| 524 allocator->TearDown(); |
| 525 delete allocator; |
| 526 } |
| 527 |
| 528 |
444 TEST(LargeObjectSpace) { | 529 TEST(LargeObjectSpace) { |
445 v8::V8::Initialize(); | 530 v8::V8::Initialize(); |
446 | 531 |
447 LargeObjectSpace* lo = CcTest::heap()->lo_space(); | 532 LargeObjectSpace* lo = CcTest::heap()->lo_space(); |
448 CHECK(lo != NULL); | 533 CHECK(lo != NULL); |
449 | 534 |
450 int lo_size = Page::kPageSize; | 535 int lo_size = Page::kPageSize; |
451 | 536 |
452 Object* obj = lo->AllocateRaw(lo_size, NOT_EXECUTABLE).ToObjectChecked(); | 537 Object* obj = lo->AllocateRaw(lo_size, NOT_EXECUTABLE).ToObjectChecked(); |
453 CHECK(obj->IsHeapObject()); | 538 CHECK(obj->IsHeapObject()); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 | 627 |
543 // Turn the allocation into a proper object so isolate teardown won't | 628 // Turn the allocation into a proper object so isolate teardown won't |
544 // crash. | 629 // crash. |
545 HeapObject* free_space = NULL; | 630 HeapObject* free_space = NULL; |
546 CHECK(allocation.To(&free_space)); | 631 CHECK(allocation.To(&free_space)); |
547 new_space->heap()->CreateFillerObjectAt(free_space->address(), 80); | 632 new_space->heap()->CreateFillerObjectAt(free_space->address(), 80); |
548 } | 633 } |
549 } | 634 } |
550 isolate->Dispose(); | 635 isolate->Dispose(); |
551 } | 636 } |
OLD | NEW |