8314502: Change the comparator taking version of GrowableArray::find to be a template method
Reviewed-by: jsjolen, sspitsyn, stefank
This commit is contained in:
parent
28026434f7
commit
14557e72ef
@ -142,6 +142,11 @@ size_t MutableNUMASpace::free_in_words() const {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MutableNUMASpace::lgrp_space_index(int lgrp_id) const {
|
||||||
|
return lgrp_spaces()->find_if([&](LGRPSpace* space) {
|
||||||
|
return space->lgrp_id() == checked_cast<uint>(lgrp_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
|
size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
|
||||||
guarantee(thr != nullptr, "No thread");
|
guarantee(thr != nullptr, "No thread");
|
||||||
@ -160,7 +165,7 @@ size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// That's the normal case, where we know the locality group of the thread.
|
// That's the normal case, where we know the locality group of the thread.
|
||||||
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
|
int i = lgrp_space_index(lgrp_id);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -179,7 +184,7 @@ size_t MutableNUMASpace::tlab_used(Thread *thr) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
|
int i = lgrp_space_index(lgrp_id);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -199,7 +204,7 @@ size_t MutableNUMASpace::unsafe_max_tlab_alloc(Thread *thr) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
|
int i = lgrp_space_index(lgrp_id);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -569,7 +574,7 @@ HeapWord* MutableNUMASpace::cas_allocate(size_t size) {
|
|||||||
thr->set_lgrp_id(lgrp_id);
|
thr->set_lgrp_id(lgrp_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
|
int i = lgrp_space_index(lgrp_id);
|
||||||
// It is possible that a new CPU has been hotplugged and
|
// It is possible that a new CPU has been hotplugged and
|
||||||
// we haven't reshaped the space accordingly.
|
// we haven't reshaped the space accordingly.
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
|
@ -93,10 +93,6 @@ class MutableNUMASpace : public MutableSpace {
|
|||||||
delete _alloc_rate;
|
delete _alloc_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool equals(void* lgrp_id_value, LGRPSpace* p) {
|
|
||||||
return *(uint*)lgrp_id_value == p->lgrp_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Report a failed allocation.
|
// Report a failed allocation.
|
||||||
void set_allocation_failed() { _allocation_failed = true; }
|
void set_allocation_failed() { _allocation_failed = true; }
|
||||||
|
|
||||||
@ -158,6 +154,8 @@ class MutableNUMASpace : public MutableSpace {
|
|||||||
void select_tails(MemRegion new_region, MemRegion intersection,
|
void select_tails(MemRegion new_region, MemRegion intersection,
|
||||||
MemRegion* bottom_region, MemRegion *top_region);
|
MemRegion* bottom_region, MemRegion *top_region);
|
||||||
|
|
||||||
|
int lgrp_space_index(int lgrp_id) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GrowableArray<LGRPSpace*>* lgrp_spaces() const { return _lgrp_spaces; }
|
GrowableArray<LGRPSpace*>* lgrp_spaces() const { return _lgrp_spaces; }
|
||||||
MutableNUMASpace(size_t alignment);
|
MutableNUMASpace(size_t alignment);
|
||||||
|
@ -119,14 +119,6 @@ void GrowableCache::recache() {
|
|||||||
_listener_fun(_this_obj,_cache);
|
_listener_fun(_this_obj,_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrowableCache::equals(void* v, GrowableElement *e2) {
|
|
||||||
GrowableElement *e1 = (GrowableElement *) v;
|
|
||||||
assert(e1 != nullptr, "e1 != nullptr");
|
|
||||||
assert(e2 != nullptr, "e2 != nullptr");
|
|
||||||
|
|
||||||
return e1->equals(e2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// class GrowableCache - public methods
|
// class GrowableCache - public methods
|
||||||
//
|
//
|
||||||
@ -163,8 +155,8 @@ GrowableElement* GrowableCache::at(int index) {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GrowableCache::find(GrowableElement* e) {
|
int GrowableCache::find(const GrowableElement* e) const {
|
||||||
return _elements->find(e, GrowableCache::equals);
|
return _elements->find_if([&](const GrowableElement* other_e) { return e->equals(other_e); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// append a copy of the element to the end of the collection
|
// append a copy of the element to the end of the collection
|
||||||
@ -216,7 +208,7 @@ void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
|
|||||||
_class_holder = OopHandle(JvmtiExport::jvmti_oop_storage(), bp._class_holder.resolve());
|
_class_holder = OopHandle(JvmtiExport::jvmti_oop_storage(), bp._class_holder.resolve());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
|
bool JvmtiBreakpoint::equals(const JvmtiBreakpoint& bp) const {
|
||||||
return _method == bp._method
|
return _method == bp._method
|
||||||
&& _bci == bp._bci;
|
&& _bci == bp._bci;
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ class GrowableElement : public CHeapObj<mtInternal> {
|
|||||||
public:
|
public:
|
||||||
virtual ~GrowableElement() {}
|
virtual ~GrowableElement() {}
|
||||||
virtual address getCacheValue() =0;
|
virtual address getCacheValue() =0;
|
||||||
virtual bool equals(GrowableElement* e) =0;
|
virtual bool equals(const GrowableElement* e) const =0;
|
||||||
virtual GrowableElement *clone() =0;
|
virtual GrowableElement* clone() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GrowableCache {
|
class GrowableCache {
|
||||||
@ -88,8 +88,6 @@ private:
|
|||||||
// (but NOT when cached elements are recomputed).
|
// (but NOT when cached elements are recomputed).
|
||||||
void (*_listener_fun)(void *, address*);
|
void (*_listener_fun)(void *, address*);
|
||||||
|
|
||||||
static bool equals(void *, GrowableElement *);
|
|
||||||
|
|
||||||
// recache all elements after size change, notify listener
|
// recache all elements after size change, notify listener
|
||||||
void recache();
|
void recache();
|
||||||
|
|
||||||
@ -104,7 +102,7 @@ public:
|
|||||||
// get the value of the index element in the collection
|
// get the value of the index element in the collection
|
||||||
GrowableElement* at(int index);
|
GrowableElement* at(int index);
|
||||||
// find the index of the element, -1 if it doesn't exist
|
// find the index of the element, -1 if it doesn't exist
|
||||||
int find(GrowableElement* e);
|
int find(const GrowableElement* e) const;
|
||||||
// append a copy of the element to the end of the collection, notify listener
|
// append a copy of the element to the end of the collection, notify listener
|
||||||
void append(GrowableElement* e);
|
void append(GrowableElement* e);
|
||||||
// remove the element at index, notify listener
|
// remove the element at index, notify listener
|
||||||
@ -165,7 +163,7 @@ public:
|
|||||||
JvmtiBreakpoint() : _method(nullptr), _bci(0) {}
|
JvmtiBreakpoint() : _method(nullptr), _bci(0) {}
|
||||||
JvmtiBreakpoint(Method* m_method, jlocation location);
|
JvmtiBreakpoint(Method* m_method, jlocation location);
|
||||||
virtual ~JvmtiBreakpoint();
|
virtual ~JvmtiBreakpoint();
|
||||||
bool equals(JvmtiBreakpoint& bp);
|
bool equals(const JvmtiBreakpoint& bp) const;
|
||||||
void copy(JvmtiBreakpoint& bp);
|
void copy(JvmtiBreakpoint& bp);
|
||||||
address getBcp() const;
|
address getBcp() const;
|
||||||
void each_method_version_do(method_action meth_act);
|
void each_method_version_do(method_action meth_act);
|
||||||
@ -177,7 +175,7 @@ public:
|
|||||||
|
|
||||||
// GrowableElement implementation
|
// GrowableElement implementation
|
||||||
address getCacheValue() { return getBcp(); }
|
address getCacheValue() { return getBcp(); }
|
||||||
bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); }
|
bool equals(const GrowableElement* e) const { return equals((const JvmtiBreakpoint&) *e); }
|
||||||
|
|
||||||
GrowableElement *clone() {
|
GrowableElement *clone() {
|
||||||
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
|
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
|
||||||
|
@ -185,6 +185,10 @@ void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
|
|||||||
PerfMemory::mark_updated();
|
PerfMemory::mark_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PerfData::name_equals(const char* name) const {
|
||||||
|
return strcmp(name, this->name()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
|
PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
|
||||||
: PerfData(ns, namep, u, v) {
|
: PerfData(ns, namep, u, v) {
|
||||||
|
|
||||||
@ -501,17 +505,9 @@ PerfDataList::~PerfDataList() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PerfDataList::by_name(void* name, PerfData* pd) {
|
|
||||||
|
|
||||||
if (pd == nullptr)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return strcmp((const char*)name, pd->name()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PerfData* PerfDataList::find_by_name(const char* name) {
|
PerfData* PerfDataList::find_by_name(const char* name) {
|
||||||
|
|
||||||
int i = _set->find((void*)name, PerfDataList::by_name);
|
int i = _set->find_if([&](PerfData* pd) { return pd->name_equals(name); });
|
||||||
|
|
||||||
if (i >= 0 && i <= _set->length())
|
if (i >= 0 && i <= _set->length())
|
||||||
return _set->at(i);
|
return _set->at(i);
|
||||||
|
@ -319,7 +319,8 @@ class PerfData : public CHeapObj<mtInternal> {
|
|||||||
// PerfData memory region. This redundancy is maintained for
|
// PerfData memory region. This redundancy is maintained for
|
||||||
// security reasons as the PerfMemory region may be in shared
|
// security reasons as the PerfMemory region may be in shared
|
||||||
// memory.
|
// memory.
|
||||||
const char* name() { return _name; }
|
const char* name() const { return _name; }
|
||||||
|
bool name_equals(const char* name) const;
|
||||||
|
|
||||||
// returns the variability classification associated with this item
|
// returns the variability classification associated with this item
|
||||||
Variability variability() { return _v; }
|
Variability variability() { return _v; }
|
||||||
@ -576,7 +577,7 @@ class PerfDataList : public CHeapObj<mtInternal> {
|
|||||||
PerfDataArray* _set;
|
PerfDataArray* _set;
|
||||||
|
|
||||||
// method to search for a instrumentation object by name
|
// method to search for a instrumentation object by name
|
||||||
static bool by_name(void* name, PerfData* pd);
|
static bool by_name(const char* name, PerfData* pd);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// we expose the implementation here to facilitate the clone
|
// we expose the implementation here to facilitate the clone
|
||||||
|
@ -71,11 +71,6 @@ void UnhandledOops::register_unhandled_oop(oop* op) {
|
|||||||
_oop_list->push(entry);
|
_oop_list->push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool match_oop_entry(void *op, UnhandledOopEntry e) {
|
|
||||||
return (e.oop_ptr() == op);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark unhandled oop as okay for GC - the containing struct has an oops_do and
|
// Mark unhandled oop as okay for GC - the containing struct has an oops_do and
|
||||||
// for some reason the oop has to be on the stack.
|
// for some reason the oop has to be on the stack.
|
||||||
// May not be called for the current thread, as in the case of
|
// May not be called for the current thread, as in the case of
|
||||||
@ -83,7 +78,9 @@ bool match_oop_entry(void *op, UnhandledOopEntry e) {
|
|||||||
void UnhandledOops::allow_unhandled_oop(oop* op) {
|
void UnhandledOops::allow_unhandled_oop(oop* op) {
|
||||||
assert (CheckUnhandledOops, "should only be called with checking option");
|
assert (CheckUnhandledOops, "should only be called with checking option");
|
||||||
|
|
||||||
int i = _oop_list->find_from_end(op, match_oop_entry);
|
int i = _oop_list->find_from_end_if([&](const UnhandledOopEntry& e) {
|
||||||
|
return e.match_oop_entry(op);
|
||||||
|
});
|
||||||
assert(i!=-1, "safe for gc oop not in unhandled_oop_list");
|
assert(i!=-1, "safe for gc oop not in unhandled_oop_list");
|
||||||
|
|
||||||
UnhandledOopEntry entry = _oop_list->at(i);
|
UnhandledOopEntry entry = _oop_list->at(i);
|
||||||
@ -105,7 +102,9 @@ void UnhandledOops::unregister_unhandled_oop(oop* op) {
|
|||||||
}
|
}
|
||||||
_level--;
|
_level--;
|
||||||
|
|
||||||
int i = _oop_list->find_from_end(op, match_oop_entry);
|
int i = _oop_list->find_from_end_if([&](const UnhandledOopEntry& e) {
|
||||||
|
return e.match_oop_entry(op);
|
||||||
|
});
|
||||||
assert(i!=-1, "oop not in unhandled_oop_list");
|
assert(i!=-1, "oop not in unhandled_oop_list");
|
||||||
_oop_list->remove_at(i);
|
_oop_list->remove_at(i);
|
||||||
}
|
}
|
||||||
|
@ -53,14 +53,17 @@ class UnhandledOopEntry : public CHeapObj<mtThread> {
|
|||||||
private:
|
private:
|
||||||
oop* _oop_ptr;
|
oop* _oop_ptr;
|
||||||
bool _ok_for_gc;
|
bool _ok_for_gc;
|
||||||
|
|
||||||
|
bool match_oop_entry(oop* op) const {
|
||||||
|
return _oop_ptr == op;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
oop* oop_ptr() { return _oop_ptr; }
|
|
||||||
UnhandledOopEntry() : _oop_ptr(nullptr), _ok_for_gc(false) {}
|
UnhandledOopEntry() : _oop_ptr(nullptr), _ok_for_gc(false) {}
|
||||||
UnhandledOopEntry(oop* op) :
|
UnhandledOopEntry(oop* op) :
|
||||||
_oop_ptr(op), _ok_for_gc(false) {}
|
_oop_ptr(op), _ok_for_gc(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class UnhandledOops : public CHeapObj<mtThread> {
|
class UnhandledOops : public CHeapObj<mtThread> {
|
||||||
friend class Thread;
|
friend class Thread;
|
||||||
private:
|
private:
|
||||||
|
@ -144,9 +144,8 @@ bool DCmdArgIter::next(TRAPS) {
|
|||||||
return _key_len != 0;
|
return _key_len != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DCmdInfo::by_name(void* cmd_name, DCmdInfo* info) {
|
bool DCmdInfo::name_equals(const char* name) const {
|
||||||
if (info == nullptr) return false;
|
return strcmp(name, this->name()) == 0;
|
||||||
return strcmp((const char*)cmd_name, info->name()) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCmdParser::add_dcmd_option(GenDCmdArgument* arg) {
|
void DCmdParser::add_dcmd_option(GenDCmdArgument* arg) {
|
||||||
|
@ -140,13 +140,12 @@ public:
|
|||||||
: _name(name), _description(description), _impact(impact), _permission(permission),
|
: _name(name), _description(description), _impact(impact), _permission(permission),
|
||||||
_num_arguments(num_arguments), _is_enabled(enabled) {}
|
_num_arguments(num_arguments), _is_enabled(enabled) {}
|
||||||
const char* name() const { return _name; }
|
const char* name() const { return _name; }
|
||||||
|
bool name_equals(const char* cmd_name) const;
|
||||||
const char* description() const { return _description; }
|
const char* description() const { return _description; }
|
||||||
const char* impact() const { return _impact; }
|
const char* impact() const { return _impact; }
|
||||||
const JavaPermission& permission() const { return _permission; }
|
const JavaPermission& permission() const { return _permission; }
|
||||||
int num_arguments() const { return _num_arguments; }
|
int num_arguments() const { return _num_arguments; }
|
||||||
bool is_enabled() const { return _is_enabled; }
|
bool is_enabled() const { return _is_enabled; }
|
||||||
|
|
||||||
static bool by_name(void* name, DCmdInfo* info);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A DCmdArgumentInfo instance provides a description of a diagnostic command
|
// A DCmdArgumentInfo instance provides a description of a diagnostic command
|
||||||
|
@ -2004,7 +2004,9 @@ JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
|
|||||||
THROW_MSG(vmSymbols::java_lang_NullPointerException(),
|
THROW_MSG(vmSymbols::java_lang_NullPointerException(),
|
||||||
"Command name cannot be null.");
|
"Command name cannot be null.");
|
||||||
}
|
}
|
||||||
int pos = info_list->find((void*)cmd_name,DCmdInfo::by_name);
|
int pos = info_list->find_if([&](DCmdInfo* info) {
|
||||||
|
return info->name_equals(cmd_name);
|
||||||
|
});
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
"Unknown diagnostic command");
|
"Unknown diagnostic command");
|
||||||
|
@ -209,17 +209,29 @@ public:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int find(void* token, bool f(void*, E)) const {
|
// Find first element that matches the given predicate.
|
||||||
|
//
|
||||||
|
// Predicate: bool predicate(const E& elem)
|
||||||
|
//
|
||||||
|
// Returns the index of the element or -1 if no element matches the predicate
|
||||||
|
template<typename Predicate>
|
||||||
|
int find_if(Predicate predicate) const {
|
||||||
for (int i = 0; i < _len; i++) {
|
for (int i = 0; i < _len; i++) {
|
||||||
if (f(token, _data[i])) return i;
|
if (predicate(_data[i])) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_from_end(void* token, bool f(void*, E)) const {
|
// Find last element that matches the given predicate.
|
||||||
|
//
|
||||||
|
// Predicate: bool predicate(const E& elem)
|
||||||
|
//
|
||||||
|
// Returns the index of the element or -1 if no element matches the predicate
|
||||||
|
template<typename Predicate>
|
||||||
|
int find_from_end_if(Predicate predicate) const {
|
||||||
// start at the end of the array
|
// start at the end of the array
|
||||||
for (int i = _len-1; i >= 0; i--) {
|
for (int i = _len-1; i >= 0; i--) {
|
||||||
if (f(token, _data[i])) return i;
|
if (predicate(_data[i])) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -601,3 +601,65 @@ TEST(GrowableArrayCHeap, sanity) {
|
|||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GrowableArrayCHeap, find_if) {
|
||||||
|
struct Element {
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
GrowableArrayCHeap<Element, mtTest> array;
|
||||||
|
array.push({1});
|
||||||
|
array.push({2});
|
||||||
|
array.push({3});
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_if([&](const Element& elem) {
|
||||||
|
return elem.value == 1;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_if([&](const Element& elem) {
|
||||||
|
return elem.value > 1;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_if([&](const Element& elem) {
|
||||||
|
return elem.value == 4;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GrowableArrayCHeap, find_from_end_if) {
|
||||||
|
struct Element {
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
GrowableArrayCHeap<Element, mtTest> array;
|
||||||
|
array.push({1});
|
||||||
|
array.push({2});
|
||||||
|
array.push({3});
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_from_end_if([&](const Element& elem) {
|
||||||
|
return elem.value == 1;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_from_end_if([&](const Element& elem) {
|
||||||
|
return elem.value > 1;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int index = array.find_from_end_if([&](const Element& elem) {
|
||||||
|
return elem.value == 4;
|
||||||
|
});
|
||||||
|
ASSERT_EQ(index, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user