26 # include "incls/_cardTableExtension.cpp.incl" |
26 # include "incls/_cardTableExtension.cpp.incl" |
27 |
27 |
28 // Checks an individual oop for missing precise marks. Mark |
28 // Checks an individual oop for missing precise marks. Mark |
29 // may be either dirty or newgen. |
29 // may be either dirty or newgen. |
30 class CheckForUnmarkedOops : public OopClosure { |
30 class CheckForUnmarkedOops : public OopClosure { |
31 PSYoungGen* _young_gen; |
31 private: |
|
32 PSYoungGen* _young_gen; |
32 CardTableExtension* _card_table; |
33 CardTableExtension* _card_table; |
33 HeapWord* _unmarked_addr; |
34 HeapWord* _unmarked_addr; |
34 jbyte* _unmarked_card; |
35 jbyte* _unmarked_card; |
35 |
36 |
36 public: |
37 protected: |
37 CheckForUnmarkedOops( PSYoungGen* young_gen, CardTableExtension* card_table ) : |
38 template <class T> void do_oop_work(T* p) { |
38 _young_gen(young_gen), _card_table(card_table), _unmarked_addr(NULL) { } |
39 oop obj = oopDesc::load_decode_heap_oop_not_null(p); |
39 |
40 if (_young_gen->is_in_reserved(obj) && |
40 virtual void do_oop(oop* p) { |
|
41 if (_young_gen->is_in_reserved(*p) && |
|
42 !_card_table->addr_is_marked_imprecise(p)) { |
41 !_card_table->addr_is_marked_imprecise(p)) { |
43 // Don't overwrite the first missing card mark |
42 // Don't overwrite the first missing card mark |
44 if (_unmarked_addr == NULL) { |
43 if (_unmarked_addr == NULL) { |
45 _unmarked_addr = (HeapWord*)p; |
44 _unmarked_addr = (HeapWord*)p; |
46 _unmarked_card = _card_table->byte_for(p); |
45 _unmarked_card = _card_table->byte_for(p); |
47 } |
46 } |
48 } |
47 } |
49 } |
48 } |
50 |
49 |
|
50 public: |
|
51 CheckForUnmarkedOops(PSYoungGen* young_gen, CardTableExtension* card_table) : |
|
52 _young_gen(young_gen), _card_table(card_table), _unmarked_addr(NULL) { } |
|
53 |
|
54 virtual void do_oop(oop* p) { CheckForUnmarkedOops::do_oop_work(p); } |
|
55 virtual void do_oop(narrowOop* p) { CheckForUnmarkedOops::do_oop_work(p); } |
|
56 |
51 bool has_unmarked_oop() { |
57 bool has_unmarked_oop() { |
52 return _unmarked_addr != NULL; |
58 return _unmarked_addr != NULL; |
53 } |
59 } |
54 }; |
60 }; |
55 |
61 |
56 // Checks all objects for the existance of some type of mark, |
62 // Checks all objects for the existance of some type of mark, |
57 // precise or imprecise, dirty or newgen. |
63 // precise or imprecise, dirty or newgen. |
58 class CheckForUnmarkedObjects : public ObjectClosure { |
64 class CheckForUnmarkedObjects : public ObjectClosure { |
59 PSYoungGen* _young_gen; |
65 private: |
|
66 PSYoungGen* _young_gen; |
60 CardTableExtension* _card_table; |
67 CardTableExtension* _card_table; |
61 |
68 |
62 public: |
69 public: |
63 CheckForUnmarkedObjects() { |
70 CheckForUnmarkedObjects() { |
64 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); |
71 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); |
73 // Card marks are not precise. The current system can leave us with |
80 // Card marks are not precise. The current system can leave us with |
74 // a mismash of precise marks and begining of object marks. This means |
81 // a mismash of precise marks and begining of object marks. This means |
75 // we test for missing precise marks first. If any are found, we don't |
82 // we test for missing precise marks first. If any are found, we don't |
76 // fail unless the object head is also unmarked. |
83 // fail unless the object head is also unmarked. |
77 virtual void do_object(oop obj) { |
84 virtual void do_object(oop obj) { |
78 CheckForUnmarkedOops object_check( _young_gen, _card_table ); |
85 CheckForUnmarkedOops object_check(_young_gen, _card_table); |
79 obj->oop_iterate(&object_check); |
86 obj->oop_iterate(&object_check); |
80 if (object_check.has_unmarked_oop()) { |
87 if (object_check.has_unmarked_oop()) { |
81 assert(_card_table->addr_is_marked_imprecise(obj), "Found unmarked young_gen object"); |
88 assert(_card_table->addr_is_marked_imprecise(obj), "Found unmarked young_gen object"); |
82 } |
89 } |
83 } |
90 } |
84 }; |
91 }; |
85 |
92 |
86 // Checks for precise marking of oops as newgen. |
93 // Checks for precise marking of oops as newgen. |
87 class CheckForPreciseMarks : public OopClosure { |
94 class CheckForPreciseMarks : public OopClosure { |
88 PSYoungGen* _young_gen; |
95 private: |
|
96 PSYoungGen* _young_gen; |
89 CardTableExtension* _card_table; |
97 CardTableExtension* _card_table; |
|
98 |
|
99 protected: |
|
100 template <class T> void do_oop_work(T* p) { |
|
101 oop obj = oopDesc::load_decode_heap_oop_not_null(p); |
|
102 if (_young_gen->is_in_reserved(obj)) { |
|
103 assert(_card_table->addr_is_marked_precise(p), "Found unmarked precise oop"); |
|
104 _card_table->set_card_newgen(p); |
|
105 } |
|
106 } |
90 |
107 |
91 public: |
108 public: |
92 CheckForPreciseMarks( PSYoungGen* young_gen, CardTableExtension* card_table ) : |
109 CheckForPreciseMarks( PSYoungGen* young_gen, CardTableExtension* card_table ) : |
93 _young_gen(young_gen), _card_table(card_table) { } |
110 _young_gen(young_gen), _card_table(card_table) { } |
94 |
111 |
95 virtual void do_oop(oop* p) { |
112 virtual void do_oop(oop* p) { CheckForPreciseMarks::do_oop_work(p); } |
96 if (_young_gen->is_in_reserved(*p)) { |
113 virtual void do_oop(narrowOop* p) { CheckForPreciseMarks::do_oop_work(p); } |
97 assert(_card_table->addr_is_marked_precise(p), "Found unmarked precise oop"); |
|
98 _card_table->set_card_newgen(p); |
|
99 } |
|
100 } |
|
101 }; |
114 }; |
102 |
115 |
103 // We get passed the space_top value to prevent us from traversing into |
116 // We get passed the space_top value to prevent us from traversing into |
104 // the old_gen promotion labs, which cannot be safely parsed. |
117 // the old_gen promotion labs, which cannot be safely parsed. |
105 void CardTableExtension::scavenge_contents(ObjectStartArray* start_array, |
118 void CardTableExtension::scavenge_contents(ObjectStartArray* start_array, |