99#include " vm/dart_api_state.h"
1010#include " vm/flag_list.h"
1111#include " vm/heap/become.h"
12+ #include " vm/heap/pages.h"
1213#include " vm/heap/pointer_block.h"
1314#include " vm/heap/safepoint.h"
1415#include " vm/heap/verifier.h"
@@ -867,30 +868,40 @@ class CheckStoreBufferVisitor : public ObjectVisitor,
867868 if (raw_obj->IsPseudoObject ()) return ;
868869 RELEASE_ASSERT (raw_obj->IsOldObject ());
869870
870- if (raw_obj->untag ()->IsCardRemembered ()) {
871- RELEASE_ASSERT (!raw_obj->untag ()->IsRemembered ());
872- // TODO(rmacnak): Verify card tables.
873- return ;
874- }
875-
876871 RELEASE_ASSERT (raw_obj->untag ()->IsRemembered () ==
877872 in_store_buffer_->Contains (raw_obj));
878873
879874 visiting_ = raw_obj;
880875 is_remembered_ = raw_obj->untag ()->IsRemembered ();
876+ is_card_remembered_ = raw_obj->untag ()->IsCardRemembered ();
877+ if (is_card_remembered_) {
878+ RELEASE_ASSERT (!is_remembered_);
879+ }
881880 raw_obj->untag ()->VisitPointers (this );
882881 }
883882
884883 void VisitPointers (ObjectPtr* from, ObjectPtr* to) {
885884 for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
886885 ObjectPtr raw_obj = *ptr;
887886 if (raw_obj->IsHeapObject () && raw_obj->IsNewObject ()) {
888- if (!is_remembered_) {
887+ if (is_card_remembered_) {
888+ if (!OldPage::Of (visiting_)->IsCardRemembered (ptr)) {
889+ FATAL3 (
890+ " Old object %#" Px " references new object %#" Px
891+ " , but the "
892+ " slot's card is not remembered. Consider using rr to watch the "
893+ " slot %p and reverse-continue to find the store with a missing "
894+ " barrier.\n " ,
895+ static_cast <uword>(visiting_), static_cast <uword>(raw_obj),
896+ ptr);
897+ }
898+ } else if (!is_remembered_) {
889899 FATAL3 (
890900 " Old object %#" Px " references new object %#" Px
891- " , but it is not"
892- " in any store buffer. Consider using rr to watch the slot %p and"
893- " reverse-continue to find the store with a missing barrier.\n " ,
901+ " , but it is "
902+ " not in any store buffer. Consider using rr to watch the "
903+ " slot %p and reverse-continue to find the store with a missing "
904+ " barrier.\n " ,
894905 static_cast <uword>(visiting_), static_cast <uword>(raw_obj), ptr);
895906 }
896907 RELEASE_ASSERT (to_->Contains (UntaggedObject::ToAddr (raw_obj)));
@@ -904,12 +915,24 @@ class CheckStoreBufferVisitor : public ObjectVisitor,
904915 for (CompressedObjectPtr* ptr = from; ptr <= to; ptr++) {
905916 ObjectPtr raw_obj = ptr->Decompress (heap_base);
906917 if (raw_obj->IsHeapObject () && raw_obj->IsNewObject ()) {
907- if (!is_remembered_) {
918+ if (is_card_remembered_) {
919+ if (!OldPage::Of (visiting_)->IsCardRemembered (ptr)) {
920+ FATAL3 (
921+ " Old object %#" Px " references new object %#" Px
922+ " , but the "
923+ " slot's card is not remembered. Consider using rr to watch the "
924+ " slot %p and reverse-continue to find the store with a missing "
925+ " barrier.\n " ,
926+ static_cast <uword>(visiting_), static_cast <uword>(raw_obj),
927+ ptr);
928+ }
929+ } else if (!is_remembered_) {
908930 FATAL3 (
909931 " Old object %#" Px " references new object %#" Px
910- " , but it is not"
911- " in any store buffer. Consider using rr to watch the slot %p and"
912- " reverse-continue to find the store with a missing barrier.\n " ,
932+ " , but it is "
933+ " not in any store buffer. Consider using rr to watch the "
934+ " slot %p and reverse-continue to find the store with a missing "
935+ " barrier.\n " ,
913936 static_cast <uword>(visiting_), static_cast <uword>(raw_obj), ptr);
914937 }
915938 RELEASE_ASSERT (to_->Contains (UntaggedObject::ToAddr (raw_obj)));
@@ -922,6 +945,7 @@ class CheckStoreBufferVisitor : public ObjectVisitor,
922945 const SemiSpace* const to_;
923946 ObjectPtr visiting_;
924947 bool is_remembered_;
948+ bool is_card_remembered_;
925949};
926950
927951void Scavenger::VerifyStoreBuffers () {
0 commit comments