OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 #include <utility> | 29 #include <utility> |
30 | 30 |
31 #include "src/compilation-cache.h" | 31 #include "src/compilation-cache.h" |
32 #include "src/context-measure.h" | 32 #include "src/context-measure.h" |
33 #include "src/deoptimizer.h" | 33 #include "src/deoptimizer.h" |
| 34 #include "src/elements.h" |
34 #include "src/execution.h" | 35 #include "src/execution.h" |
35 #include "src/factory.h" | 36 #include "src/factory.h" |
36 #include "src/field-type.h" | 37 #include "src/field-type.h" |
37 #include "src/global-handles.h" | 38 #include "src/global-handles.h" |
38 #include "src/heap/gc-tracer.h" | 39 #include "src/heap/gc-tracer.h" |
39 #include "src/heap/memory-reducer.h" | 40 #include "src/heap/memory-reducer.h" |
40 #include "src/ic/ic.h" | 41 #include "src/ic/ic.h" |
41 #include "src/macro-assembler.h" | 42 #include "src/macro-assembler.h" |
42 #include "src/regexp/jsregexp.h" | 43 #include "src/regexp/jsregexp.h" |
43 #include "src/snapshot/snapshot.h" | 44 #include "src/snapshot/snapshot.h" |
(...skipping 6591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6635 // Actual checks: The page is in new space first, but is moved to old space | 6636 // Actual checks: The page is in new space first, but is moved to old space |
6636 // during a full GC. | 6637 // during a full GC. |
6637 CHECK(heap->new_space()->ContainsSlow(first_page->address())); | 6638 CHECK(heap->new_space()->ContainsSlow(first_page->address())); |
6638 CHECK(!heap->old_space()->ContainsSlow(first_page->address())); | 6639 CHECK(!heap->old_space()->ContainsSlow(first_page->address())); |
6639 heap->CollectGarbage(OLD_SPACE); | 6640 heap->CollectGarbage(OLD_SPACE); |
6640 CHECK(!heap->new_space()->ContainsSlow(first_page->address())); | 6641 CHECK(!heap->new_space()->ContainsSlow(first_page->address())); |
6641 CHECK(heap->old_space()->ContainsSlow(first_page->address())); | 6642 CHECK(heap->old_space()->ContainsSlow(first_page->address())); |
6642 } | 6643 } |
6643 } | 6644 } |
6644 | 6645 |
| 6646 TEST(Regress598319) { |
| 6647 // This test ensures that no white objects can cross the progress bar of large |
| 6648 // objects during incremental marking. It checks this by using Shift() during |
| 6649 // incremental marking. |
| 6650 CcTest::InitializeVM(); |
| 6651 v8::HandleScope scope(CcTest::isolate()); |
| 6652 Heap* heap = CcTest::heap(); |
| 6653 Isolate* isolate = heap->isolate(); |
| 6654 |
| 6655 const int kNumberOfObjects = Page::kMaxRegularHeapObjectSize / kPointerSize; |
| 6656 |
| 6657 struct Arr { |
| 6658 Arr(Isolate* isolate, int number_of_objects) { |
| 6659 root = isolate->factory()->NewFixedArray(1, TENURED); |
| 6660 { |
| 6661 // Temporary scope to avoid getting any other objects into the root set. |
| 6662 v8::HandleScope scope(CcTest::isolate()); |
| 6663 Handle<FixedArray> tmp = |
| 6664 isolate->factory()->NewFixedArray(number_of_objects); |
| 6665 root->set(0, *tmp); |
| 6666 for (int i = 0; i < get()->length(); i++) { |
| 6667 tmp = isolate->factory()->NewFixedArray(100, TENURED); |
| 6668 get()->set(i, *tmp); |
| 6669 } |
| 6670 } |
| 6671 } |
| 6672 |
| 6673 FixedArray* get() { return FixedArray::cast(root->get(0)); } |
| 6674 |
| 6675 Handle<FixedArray> root; |
| 6676 } arr(isolate, kNumberOfObjects); |
| 6677 |
| 6678 CHECK_EQ(arr.get()->length(), kNumberOfObjects); |
| 6679 CHECK(heap->lo_space()->Contains(arr.get())); |
| 6680 LargePage* page = heap->lo_space()->FindPage(arr.get()->address()); |
| 6681 CHECK_NOT_NULL(page); |
| 6682 |
| 6683 // GC to cleanup state |
| 6684 heap->CollectGarbage(OLD_SPACE); |
| 6685 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 6686 if (collector->sweeping_in_progress()) { |
| 6687 collector->EnsureSweepingCompleted(); |
| 6688 } |
| 6689 |
| 6690 CHECK(heap->lo_space()->Contains(arr.get())); |
| 6691 CHECK(Marking::IsWhite(Marking::MarkBitFrom(arr.get()))); |
| 6692 for (int i = 0; i < arr.get()->length(); i++) { |
| 6693 CHECK(Marking::IsWhite( |
| 6694 Marking::MarkBitFrom(HeapObject::cast(arr.get()->get(i))))); |
| 6695 } |
| 6696 |
| 6697 // Start incremental marking. |
| 6698 IncrementalMarking* marking = heap->incremental_marking(); |
| 6699 CHECK(marking->IsMarking() || marking->IsStopped()); |
| 6700 if (marking->IsStopped()) { |
| 6701 heap->StartIncrementalMarking(); |
| 6702 } |
| 6703 CHECK(marking->IsMarking()); |
| 6704 |
| 6705 // Check that we have not marked the interesting array during root scanning. |
| 6706 for (int i = 0; i < arr.get()->length(); i++) { |
| 6707 CHECK(Marking::IsWhite( |
| 6708 Marking::MarkBitFrom(HeapObject::cast(arr.get()->get(i))))); |
| 6709 } |
| 6710 |
| 6711 // Now we search for a state where we are in incremental marking and have |
| 6712 // only partially marked the large object. |
| 6713 while (!marking->IsComplete()) { |
| 6714 marking->Step(i::KB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 6715 if (page->IsFlagSet(Page::HAS_PROGRESS_BAR) && page->progress_bar() > 0) { |
| 6716 CHECK_NE(page->progress_bar(), arr.get()->Size()); |
| 6717 { |
| 6718 // Shift by 1, effectively moving one white object across the progress |
| 6719 // bar, meaning that we will miss marking it. |
| 6720 v8::HandleScope scope(CcTest::isolate()); |
| 6721 Handle<JSArray> js_array = isolate->factory()->NewJSArrayWithElements( |
| 6722 Handle<FixedArray>(arr.get())); |
| 6723 js_array->GetElementsAccessor()->Shift(js_array); |
| 6724 } |
| 6725 break; |
| 6726 } |
| 6727 } |
| 6728 |
| 6729 // Finish marking with bigger steps to speed up test. |
| 6730 while (!marking->IsComplete()) { |
| 6731 marking->Step(10 * i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD); |
| 6732 if (marking->IsReadyToOverApproximateWeakClosure()) { |
| 6733 marking->FinalizeIncrementally(); |
| 6734 } |
| 6735 } |
| 6736 CHECK(marking->IsComplete()); |
| 6737 |
| 6738 // All objects need to be black after marking. If a white object crossed the |
| 6739 // progress bar, we would fail here. |
| 6740 for (int i = 0; i < arr.get()->length(); i++) { |
| 6741 CHECK(Marking::IsBlack( |
| 6742 Marking::MarkBitFrom(HeapObject::cast(arr.get()->get(i))))); |
| 6743 } |
| 6744 } |
| 6745 |
6645 } // namespace internal | 6746 } // namespace internal |
6646 } // namespace v8 | 6747 } // namespace v8 |
OLD | NEW |