bool common_range(IteratorT& lwb, IteratorT& upb, ObjectT& x1, const ConstObjectT& x2) { // lwb and upb are iterators of x1 marking the lower and upper bound of // the common range of x1 and x2. typedef typename ConstObjectT::const_iterator ConstObject_iterator; // ObjectT may be const or non const. typedef typename remove_const<ObjectT>::type PureObjectT; lwb = x1.end(); upb = x1.end(); if(icl::is_empty(x1) || icl::is_empty(x2)) return false; IteratorT x1_fst_ = x1.begin(); IteratorT x1_lst_ = x1.end(); x1_lst_--; ConstObject_iterator x2_fst_ = x2.begin(); ConstObject_iterator x2_lst_ = x2.end(); x2_lst_--; typename ObjectT::key_compare key_less; if(key_less(icl::key_value< PureObjectT>(x1_lst_), icl::key_value<ConstObjectT>(x2_fst_))) // {x1} {x2} return false; if(key_less(icl::key_value<ConstObjectT>(x2_lst_), icl::key_value< PureObjectT>(x1_fst_))) // {x2} {x1} return false; // We do have a common range lwb = x1.lower_bound(icl::key_value<ConstObjectT>(x2_fst_)); upb = x1.upper_bound(icl::key_value<ConstObjectT>(x2_lst_)); return true; }
bool intersects(const ObjectT& left, const CoObjectT& right) { typedef typename CoObjectT::const_iterator co_iterator; co_iterator right_common_lower_, right_common_upper_; if(!Set::common_range(right_common_lower_, right_common_upper_, right, left)) return false; co_iterator right_ = right_common_lower_; while(right_ != right_common_upper_) if(!(left.find(key_value<CoObjectT>(right_++))==left.end())) return true; return false; }
bool TestWrapper(ObjectT obj, ObjectT obj2, WrapperT& wrapper, WrapperT& wrapper2) { using namespace js::gc; const TenuredCell& cell = obj->asTenured(); const TenuredCell& cell2 = obj2->asTenured(); int x = 0; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += obj == obj2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += obj == wrapper2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += wrapper == obj2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += wrapper == wrapper2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); CHECK(x == 0); x += obj != obj2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += obj != wrapper2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += wrapper != obj2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); x += wrapper != wrapper2; CHECK(cell.isMarked(GRAY)); CHECK(cell2.isMarked(GRAY)); CHECK(x == 4); return true; }
void trace(JSTracer* trc) override { auto table = reinterpret_cast<typename ObjectT::UnbarrieredTable*>(object->getData()); NurseryKeysVector* keys = GetNurseryKeys(object); MOZ_ASSERT(keys); for (JSObject* obj : *keys) { MOZ_ASSERT(obj); Value key = ObjectValue(*obj); Value prior = key; MOZ_ASSERT(UnbarrieredHashPolicy::hash(key) == HashableValue::Hasher::hash(*reinterpret_cast<HashableValue*>(&key))); TraceManuallyBarrieredEdge(trc, &key, "ordered hash table key"); table->rekeyOneEntry(prior, key); } DeleteNurseryKeys(object); }