template <class T> void do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop_not_null(p);
   if (_young_gen->is_in_reserved(obj)) {
     assert(_card_table->addr_is_marked_precise(p), "Found unmarked precise oop");
     _card_table->set_card_newgen(p);
   }
 }
 template <class T> void do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop_not_null(p);
   if (_young_gen->is_in_reserved(obj) &&
       !_card_table->addr_is_marked_imprecise(p)) {
     // Don't overwrite the first missing card mark
     if (_unmarked_addr == NULL) {
       _unmarked_addr = (HeapWord*)p;
       _unmarked_card = _card_table->byte_for(p);
     }
   }
 }
 // Card marks are not precise. The current system can leave us with
 // a mismash of precise marks and beginning of object marks. This means
 // we test for missing precise marks first. If any are found, we don't
 // fail unless the object head is also unmarked.
 virtual void do_object(oop obj) {
   CheckForUnmarkedOops object_check(_young_gen, _card_table);
   obj->oop_iterate(&object_check);
   if (object_check.has_unmarked_oop()) {
     assert(_card_table->addr_is_marked_imprecise(obj), "Found unmarked young_gen object");
   }
 }