Flutter Engine
The Flutter Engine
Classes | Public Member Functions | List of all members
dart::RetainingPath Class Reference

Public Member Functions

 RetainingPath (Zone *zone, Isolate *isolate, const Object &from, const Object &to, TraversalRules traversal_rules)
 
 ~RetainingPath ()
 
bool WasVisited (ObjectPtr object)
 
void MarkVisited (ObjectPtr object)
 
const char * FindPath ()
 

Detailed Description

Definition at line 897 of file object_graph_copy.cc.

Constructor & Destructor Documentation

◆ RetainingPath()

dart::RetainingPath::RetainingPath ( Zone zone,
Isolate isolate,
const Object from,
const Object to,
TraversalRules  traversal_rules 
)
inline

Definition at line 949 of file object_graph_copy.cc.

954 : zone_(zone),
955 isolate_(isolate),
956 from_(from),
957 to_(to),
958 traversal_rules_(traversal_rules) {
959 isolate_->set_forward_table_new(new WeakTable());
960 isolate_->set_forward_table_old(new WeakTable());
961 }
void set_forward_table_old(WeakTable *table)
Definition: isolate.cc:2552
void set_forward_table_new(WeakTable *table)
Definition: isolate.cc:2548

◆ ~RetainingPath()

dart::RetainingPath::~RetainingPath ( )
inline

Definition at line 963 of file object_graph_copy.cc.

963 {
964 isolate_->set_forward_table_new(nullptr);
965 isolate_->set_forward_table_old(nullptr);
966 }

Member Function Documentation

◆ FindPath()

const char * dart::RetainingPath::FindPath ( )
inline

Definition at line 984 of file object_graph_copy.cc.

984 {
985 MallocGrowableArray<ObjectPtr>* const working_list =
986 isolate_->pointers_to_verify_at_exit();
987 ASSERT(working_list->length() == 0);
988
989 Visitor visitor(isolate_->group(), this, working_list, traversal_rules_);
990
991 MarkVisited(from_.ptr());
992 working_list->Add(from_.ptr());
993
994 Thread* thread = Thread::Current();
995 ClassTable* class_table = isolate_->group()->class_table();
996 Closure& closure = Closure::Handle(zone_);
997 Array& array = Array::Handle(zone_);
998 Class& klass = Class::Handle(zone_);
999
1000 while (!working_list->is_empty()) {
1001 thread->CheckForSafepoint();
1002
1003 // Keep node in the list, separated by null value so that
1004 // if we are to add children, children can find it in case
1005 // they are on retaining path.
1006 ObjectPtr raw = working_list->Last();
1007 if (raw == Object::null()) {
1008 // If all children of a node were processed, then skip the separator,
1009 working_list->RemoveLast();
1010 // then skip the parent since it has already been processed too.
1011 working_list->RemoveLast();
1012 continue;
1013 }
1014
1015 if (raw == to_.ptr()) {
1016 return CollectPath(working_list);
1017 }
1018
1019 // Separator null object indicates children goes next in the working_list
1020 working_list->Add(Object::null());
1021 int length = working_list->length();
1022
1023 do { // This loop is here so that we can skip children processing
1024 const intptr_t cid = raw->GetClassId();
1025
1026 if (traversal_rules_ == TraversalRules::kInternalToIsolateGroup) {
1028 break;
1029 }
1030 if (cid == kClosureCid) {
1031 closure ^= raw;
1032 // Only context has to be checked.
1033 working_list->Add(closure.RawContext());
1034 break;
1035 }
1036 // These we are not expected to drill into as they can't be on
1037 // retaining path, they are illegal to send.
1038 klass = class_table->At(cid);
1039 if (klass.is_isolate_unsendable()) {
1040 break;
1041 }
1042 } else {
1043 ASSERT(traversal_rules_ ==
1045 // Skip classes that are illegal to send across isolate groups.
1046 // (keep the list in sync with message_snapshot.cc)
1047 bool skip = false;
1048 switch (cid) {
1049 case kClosureCid:
1050 case kFinalizerCid:
1051 case kFinalizerEntryCid:
1052 case kFunctionTypeCid:
1053 case kMirrorReferenceCid:
1054 case kNativeFinalizerCid:
1055 case kReceivePortCid:
1056 case kRecordCid:
1057 case kRecordTypeCid:
1058 case kRegExpCid:
1059 case kStackTraceCid:
1060 case kSuspendStateCid:
1061 case kUserTagCid:
1062 case kWeakPropertyCid:
1063 case kWeakReferenceCid:
1064 case kWeakArrayCid:
1065 case kDynamicLibraryCid:
1066 case kPointerCid:
1067 case kInstanceCid:
1068 skip = true;
1069 break;
1070 default:
1071 if (cid >= kNumPredefinedCids) {
1072 skip = true;
1073 }
1074 }
1075 if (skip) {
1076 break;
1077 }
1078 }
1079 if (cid == kArrayCid) {
1080 array ^= Array::RawCast(raw);
1081 visitor.VisitObject(array.GetTypeArguments());
1082 const intptr_t batch_size = (2 << 14) - 1;
1083 for (intptr_t i = 0; i < array.Length(); ++i) {
1084 ObjectPtr ptr = array.At(i);
1085 visitor.VisitObject(ptr);
1086 if ((i & batch_size) == batch_size) {
1087 thread->CheckForSafepoint();
1088 }
1089 }
1090 break;
1091 } else {
1092 raw->untag()->VisitPointers(&visitor);
1093 }
1094 } while (false);
1095
1096 // If no children were added, remove null separator and the node.
1097 // If children were added, the node will be removed once last child
1098 // is processed, only separator null remains.
1099 if (working_list->length() == length) {
1100 RELEASE_ASSERT(working_list->RemoveLast() == Object::null());
1101 RELEASE_ASSERT(working_list->RemoveLast() == raw);
1102 }
1103 }
1104 // `to` was not found in the graph rooted in `from`, empty retaining path
1105 return "";
1106 }
static bool skip(SkStream *stream, size_t amount)
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
ClassTable * class_table() const
Definition: isolate.h:496
MallocGrowableArray< ObjectPtr > * pointers_to_verify_at_exit()
Definition: isolate.h:1479
IsolateGroup * group() const
Definition: isolate.h:1037
static ObjectPtr null()
Definition: object.h:433
ObjectPtr ptr() const
Definition: object.h:332
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
void MarkVisited(ObjectPtr object)
static Thread * Current()
Definition: thread.h:362
#define ASSERT(E)
size_t length
Visitor(Ts...) -> Visitor< Ts... >
@ kInternalToIsolateGroup
@ kExternalBetweenIsolateGroups
bool CanShareObjectAcrossIsolates(ObjectPtr obj)
@ kNumPredefinedCids
Definition: class_id.h:257
const intptr_t cid
std::function< void()> closure
Definition: closure.h:14

◆ MarkVisited()

void dart::RetainingPath::MarkVisited ( ObjectPtr  object)
inline

Definition at line 976 of file object_graph_copy.cc.

976 {
977 if (object->IsNewObject()) {
978 isolate_->forward_table_new()->SetValueExclusive(object, 1);
979 } else {
980 isolate_->forward_table_old()->SetValueExclusive(object, 1);
981 }
982 }
WeakTable * forward_table_old()
Definition: isolate.h:1461
WeakTable * forward_table_new()
Definition: isolate.h:1458
void SetValueExclusive(ObjectPtr key, intptr_t val)
Definition: weak_table.cc:33

◆ WasVisited()

bool dart::RetainingPath::WasVisited ( ObjectPtr  object)
inline

Definition at line 968 of file object_graph_copy.cc.

968 {
969 if (object->IsNewObject()) {
970 return isolate_->forward_table_new()->GetValueExclusive(object) != 0;
971 } else {
972 return isolate_->forward_table_old()->GetValueExclusive(object) != 0;
973 }
974 }
intptr_t GetValueExclusive(ObjectPtr key) const
Definition: weak_table.h:109

The documentation for this class was generated from the following file: