< prev index next > src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
Print this page
dedup_string(obj, req);
}
InstanceKlass::cast(klass)->oop_oop_iterate<OT>(obj, cl);
break;
}
+ case Klass::InlineKlassKind: {
+ // Inline instance.
+ InlineKlass::cast(klass)->oop_oop_iterate<OT>(obj, cl);
+ break;
+ }
case Klass::InstanceRefKlassKind: {
// (Weak) reference instance.
InstanceRefKlass::cast(klass)->oop_oop_iterate<OT>(obj, cl);
break;
}
// We skip iterating over the klass pointer since we know that
// Universe::TypeArrayKlass never moves.
break;
}
case Klass::ObjArrayKlassKind: {
! // Object array and no chunk is set. Must be the first
// time we visit it, start the chunked processing.
do_chunked_array_start<T, OT>(q, cl, obj, klass, weak);
break;
}
default: {
fatal("Unknown klass kind: %d", klass->kind());
}
}
// Count liveness the last: push the outstanding work to the queues first
// We skip iterating over the klass pointer since we know that
// Universe::TypeArrayKlass never moves.
break;
}
case Klass::ObjArrayKlassKind: {
! fatal("Unexpected unrefined object array klass");
+ }
+ case Klass::RefArrayKlassKind: {
+ // Reference array and no chunk is set. Must be the first
// time we visit it, start the chunked processing.
do_chunked_array_start<T, OT>(q, cl, obj, klass, weak);
break;
}
+ case Klass::FlatArrayKlassKind: {
+ // Flat array, all elements are embedded.
+ FlatArrayKlass::cast(klass)->oop_oop_iterate<OT>(obj, cl);
+ break;
+ }
default: {
fatal("Unknown klass kind: %d", klass->kind());
}
}
// Count liveness the last: push the outstanding work to the queues first
// from final- to strong mark.
if (task->count_liveness()) {
count_liveness<GENERATION>(live_data, obj, klass, worker_id);
}
} else {
! // Object array chunk. Process it.
do_chunked_array<T, OT>(q, cl, obj, klass, task->chunk(), task->pow(), weak);
}
}
inline void ShenandoahMark::dedup_string(oop obj, StringDedup::Requests* const req) {
// from final- to strong mark.
if (task->count_liveness()) {
count_liveness<GENERATION>(live_data, obj, klass, worker_id);
}
} else {
! // Reference array chunk. Process it.
do_chunked_array<T, OT>(q, cl, obj, klass, task->chunk(), task->pow(), weak);
}
}
inline void ShenandoahMark::dedup_string(oop obj, StringDedup::Requests* const req) {
}
}
template <class T, class OT>
void ShenandoahMark::do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop obj, Klass* klass, bool weak) {
! assert(obj->is_objArray(), "expect object array");
! objArrayOop array = objArrayOop(obj);
int len = array->length();
! // Mark objArray klass metadata
if (Devirtualizer::do_metadata(cl)) {
Devirtualizer::do_klass(cl, klass);
}
if (len <= (int) ObjArrayMarkingStride*2) {
// A few slices only, process directly
! ObjArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, 0, len);
} else {
int bits = log2i_graceful(len);
// Compensate for non-power-of-two arrays, cover the array in excess:
if (len != (1 << bits)) bits++;
}
}
template <class T, class OT>
void ShenandoahMark::do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop obj, Klass* klass, bool weak) {
! assert(obj->is_refArray(), "expect ref array");
! refArrayOop array = refArrayOop(obj);
int len = array->length();
! // Mark reference array klass metadata
if (Devirtualizer::do_metadata(cl)) {
Devirtualizer::do_klass(cl, klass);
}
if (len <= (int) ObjArrayMarkingStride*2) {
// A few slices only, process directly
! RefArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, 0, len);
} else {
int bits = log2i_graceful(len);
// Compensate for non-power-of-two arrays, cover the array in excess:
if (len != (1 << bits)) bits++;
}
// Process the irregular tail, if present
int from = last_idx;
if (from < len) {
! ObjArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, from, len);
}
}
}
template <class T, class OT>
void ShenandoahMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop obj, Klass* klass, int chunk, int pow, bool weak) {
! assert(obj->is_objArray(), "expect object array");
! objArrayOop array = objArrayOop(obj);
// Split out tasks, as suggested in ShenandoahMarkTask docs. Avoid pushing tasks that
// are known to start beyond the array.
while ((1 << pow) > (int)ObjArrayMarkingStride && (chunk*2 < ShenandoahMarkTask::chunk_size())) {
pow--;
}
// Process the irregular tail, if present
int from = last_idx;
if (from < len) {
! RefArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, from, len);
}
}
}
template <class T, class OT>
void ShenandoahMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop obj, Klass* klass, int chunk, int pow, bool weak) {
! assert(obj->is_refArray(), "expect ref array");
! refArrayOop array = refArrayOop(obj);
// Split out tasks, as suggested in ShenandoahMarkTask docs. Avoid pushing tasks that
// are known to start beyond the array.
while ((1 << pow) > (int)ObjArrayMarkingStride && (chunk*2 < ShenandoahMarkTask::chunk_size())) {
pow--;
int len = array->length();
assert (0 <= from && from < len, "from is sane: %d/%d", from, len);
assert (0 < to && to <= len, "to is sane: %d/%d", to, len);
#endif
! ObjArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, from, to);
}
template <ShenandoahGenerationType GENERATION>
class ShenandoahSATBBufferClosure : public SATBBufferClosure {
private:
int len = array->length();
assert (0 <= from && from < len, "from is sane: %d/%d", from, len);
assert (0 < to && to <= len, "to is sane: %d/%d", to, len);
#endif
! RefArrayKlass::cast(klass)->oop_oop_iterate_elements_range<OT>(array, cl, from, to);
}
template <ShenandoahGenerationType GENERATION>
class ShenandoahSATBBufferClosure : public SATBBufferClosure {
private:
< prev index next >