/* Sun-$Revision: 23.3 $ */
/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
See the LICENSE file for license information. */
# pragma interface
const fint enumeration_list_capacity = 16;
// I hold enumerated oops in the resource area space-efficiently
class enumeration_list: public ResourceObj {
protected:
oop contents[enumeration_list_capacity];
fint count;
enumeration_list* next;
void add_more(oop obj, enumeration_list*& head, fint& totalCount);
public:
enumeration_list() {count = 0; next = NULL;}
void add(oop obj, enumeration_list*& head, fint& totalCount) {
if (obj->is_marked()) {
}
else if (count < enumeration_list_capacity) {
contents[count++] = obj; obj->set_mark();
++totalCount;
} else add_more(obj, head, totalCount);
}
void oops_do(oopsDoFn f);
};
class enumeration: public ResourceObj {
friend void package_enumeration_result(oop* p);
friend void package_enumeration_maps(oop* p);
protected:
oop* targetp;
smi num_targets;
smi num_live_vframes;
bool has_assignments;
unsigned long limit;
enumeration_list* objs;
int32 obj_count;
enumeration_list* maps;
int32 map_count;
oop* maps_array;
oop* maps_p;
oop* resultp;
enumeration(unsigned long lmt) {
limit = lmt;
error_code = 0;
objs = new enumeration_list;
obj_count = 0;
maps = new enumeration_list;
map_count = 0;
}
void pack_result();
void pack_maps();
public:
markOop error_code;
objVectorOop resultVector;
void set_error(markOop m);
bool is_ok() {return !error_code;}
bool stop() {return !is_ok() || obj_count >= limit;}
virtual void add_obj(oop obj) {
assert(slotsOop(obj) != Memory->errorObj,
"shouldn't ever expose errorObj");
if (!stop()) objs->add(obj, objs, obj_count);}
void add_map(Map* m) {
if (!stop()) maps->add(as_mapOop(m), maps, map_count);}
void add_families(oop* bottom, oop* top);
oop* get_targets() { return targetp; }
smi get_num_targets() { return num_targets; }
int get_num_live_vframes() { return num_live_vframes; }
bool targets_has_assignments() { return has_assignments; }
bool is_target(oop t);
oop* get_maps() { return maps_array; }
smi get_num_maps() { return map_count; }
virtual void enumerate() = 0;
virtual void filter_match(oopsOop obj, oop* matching_cell, smi targetNo) = 0;
virtual void filter_map(mapOop obj) = 0;
};
class referencesEnumeration: public enumeration {
friend oop enumerate_vector_references(objVectorOop vector, oop limit);
referencesEnumeration(oop* targetp_arg,
smi num_targets_arg,
smi num_live_vframes_arg,
bool has_assignments_arg,
smi limit_arg)
: enumeration(limit_arg) {
targetp = targetp_arg;
num_targets = num_live_vframes_arg + num_targets_arg;
num_live_vframes = num_live_vframes_arg;
has_assignments = has_assignments_arg;
}
void enumerate();
void filter_match(oopsOop obj, oop* matching_cell, smi targetNo);
void filter_map(mapOop obj);
protected:
void consider_vframe(oopsOop obj, oop* matching_cell, smi targetNo);
void consider_obj( oopsOop obj, oop* matching_cell, smi targetNo);
};
class implementorsEnumeration: public enumeration {
friend oop enumerate_vector_implementors(objVectorOop vector, oop limit);
smi poss_assignments_index;
implementorsEnumeration(oop* targetp_arg, smi num_targets_arg,
smi num_poss_ass, smi limit_arg)
: enumeration(limit_arg) {
targetp= targetp_arg;
num_targets= num_targets_arg;
poss_assignments_index= num_poss_ass;
}
void enumerate();
void filter_match(oopsOop obj, oop* matching_cell, smi targetNo);
void filter_map(mapOop obj) { Unused(obj); ShouldNotCallThis(); }
};
class allObjEnumeration: public enumeration {
friend oop enumerate_all_objs(oop limit);
allObjEnumeration(smi lim)
: enumeration(lim) {
}
void enumerate();
void filter_match(oopsOop obj, oop* matching_cell, smi targetNo) {
Unused(obj); Unused(matching_cell); Unused(targetNo);
ShouldNotCallThis(); }
void filter_map(mapOop obj) { Unused(obj); ShouldNotCallThis(); }
};