object_type ClassifyObjectClosure::classify_object(oop obj, bool count) { object_type type = unknown_type; Klass* k = obj->blueprint(); if (k->as_klassOop() == SystemDictionary::Object_klass()) { tty->print_cr("Found the class!"); } if (count) { k->set_alloc_count(k->alloc_count() + 1); } if (obj->is_instance()) { if (k->oop_is_instanceRef()) { type = instanceRef_type; } else { type = instance_type; } } else if (obj->is_typeArray()) { type = typeArray_type; } else if (obj->is_objArray()) { type = objArray_type; } else if (obj->is_symbol()) { type = symbol_type; } else if (obj->is_klass()) { Klass* k = ((klassOop)obj)->klass_part(); if (k->oop_is_instance()) { type = instanceKlass_type; } else { type = klass_type; } } else if (obj->is_method()) { type = method_type; } else if (obj->is_constMethod()) { type = constMethod_type; } else if (obj->is_methodData()) { ShouldNotReachHere(); } else if (obj->is_constantPool()) { type = constantPool_type; } else if (obj->is_constantPoolCache()) { type = constantPoolCache_type; } else if (obj->is_compiledICHolder()) { type = compiledICHolder_type; } else { ShouldNotReachHere(); } assert(type != unknown_type, "found object of unknown type."); return type; }
// Return true if oop represents an object that is "visible" // to the java world. static inline bool visible_oop(oop o) { // the sentinel for deleted handles isn't visible if (o == JNIHandles::deleted_handle()) { return false; } // instance if (o->is_instance()) { // instance objects are visible if (o->klass() != SystemDictionary::Class_klass()) { return true; } if (java_lang_Class::is_primitive(o)) { return true; } // java.lang.Classes are visible Klass* k = java_lang_Class::as_Klass(o); if (k->is_klass()) { // if it's a class for an object, an object array, or // primitive (type) array then it's visible. if (k->is_instance_klass()) { return true; } if (k->is_objArray_klass()) { return true; } if (k->is_typeArray_klass()) { return true; } } return false; } // object arrays are visible if they aren't system object arrays if (o->is_objArray()) { return true; } // type arrays are visible if (o->is_typeArray()) { return true; } // everything else (Method*s, ...) aren't visible return false; }; // end of visible_oop()
template <class T> void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), "Precondition"); T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); bool failed = false; if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _use_prev_marking)) { if (!_failures) { gclog_or_tty->print_cr(""); gclog_or_tty->print_cr("----------"); } if (!_g1h->is_in_closed_subset(obj)) { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); gclog_or_tty->print_cr("Field "PTR_FORMAT " of live obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", p, (void*) _containing_obj, from->bottom(), from->end()); print_object(gclog_or_tty, _containing_obj); gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", (void*) obj); } else { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); gclog_or_tty->print_cr("Field "PTR_FORMAT " of live obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", p, (void*) _containing_obj, from->bottom(), from->end()); print_object(gclog_or_tty, _containing_obj); gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", (void*) obj, to->bottom(), to->end()); print_object(gclog_or_tty, obj); } gclog_or_tty->print_cr("----------"); _failures = true; failed = true; _n_failures++; } if (!_g1h->full_collection()) { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* to = _g1h->heap_region_containing(obj); if (from != NULL && to != NULL && from != to && !to->isHumongous()) { jbyte cv_obj = *_bs->byte_for_const(_containing_obj); jbyte cv_field = *_bs->byte_for_const(p); const jbyte dirty = CardTableModRefBS::dirty_card_val(); bool is_bad = !(from->is_young() || to->rem_set()->contains_reference(p) || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed (_containing_obj->is_objArray() ? cv_field == dirty : cv_obj == dirty || cv_field == dirty)); if (is_bad) { if (!_failures) { gclog_or_tty->print_cr(""); gclog_or_tty->print_cr("----------"); } gclog_or_tty->print_cr("Missing rem set entry:"); gclog_or_tty->print_cr("Field "PTR_FORMAT " of obj "PTR_FORMAT ", in region %d ["PTR_FORMAT ", "PTR_FORMAT"),", p, (void*) _containing_obj, from->hrs_index(), from->bottom(), from->end()); _containing_obj->print_on(gclog_or_tty); gclog_or_tty->print_cr("points to obj "PTR_FORMAT " in region %d ["PTR_FORMAT ", "PTR_FORMAT").", (void*) obj, to->hrs_index(), to->bottom(), to->end()); obj->print_on(gclog_or_tty); gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field); gclog_or_tty->print_cr("----------"); _failures = true; if (!failed) _n_failures++; } } } } }
oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, oop const old, markOop const old_mark) { const size_t word_sz = old->size(); HeapRegion* const from_region = _g1h->heap_region_containing_raw(old); // +1 to make the -1 indexes valid... const int young_index = from_region->young_index_in_cset()+1; assert( (from_region->is_young() && young_index > 0) || (!from_region->is_young() && young_index == 0), "invariant" ); const AllocationContext_t context = from_region->allocation_context(); uint age = 0; InCSetState dest_state = next_state(state, old_mark, age); HeapWord* obj_ptr = _plab_allocator->plab_allocate(dest_state, word_sz, context); // PLAB allocations should succeed most of the time, so we'll // normally check against NULL once and that's it. if (obj_ptr == NULL) { obj_ptr = _plab_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context); if (obj_ptr == NULL) { obj_ptr = allocate_in_next_plab(state, &dest_state, word_sz, context); if (obj_ptr == NULL) { // This will either forward-to-self, or detect that someone else has // installed a forwarding pointer. return handle_evacuation_failure_par(old, old_mark); } } } assert(obj_ptr != NULL, "when we get here, allocation should have succeeded"); assert(_g1h->is_in_reserved(obj_ptr), "Allocated memory should be in the heap"); #ifndef PRODUCT // Should this evacuation fail? if (_g1h->evacuation_should_fail()) { // Doing this after all the allocation attempts also tests the // undo_allocation() method too. _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); return handle_evacuation_failure_par(old, old_mark); } #endif // !PRODUCT // We're going to allocate linearly, so might as well prefetch ahead. Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); const oop obj = oop(obj_ptr); const oop forward_ptr = old->forward_to_atomic(obj); if (forward_ptr == NULL) { Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); if (dest_state.is_young()) { if (age < markOopDesc::max_age) { age++; } if (old_mark->has_displaced_mark_helper()) { // In this case, we have to install the mark word first, // otherwise obj looks to be forwarded (the old mark word, // which contains the forward pointer, was copied) obj->set_mark(old_mark); markOop new_mark = old_mark->displaced_mark_helper()->set_age(age); old_mark->set_displaced_mark_helper(new_mark); } else { obj->set_mark(old_mark->set_age(age)); } age_table()->add(age, word_sz); } else { obj->set_mark(old_mark); } if (G1StringDedup::is_enabled()) { const bool is_from_young = state.is_young(); const bool is_to_young = dest_state.is_young(); assert(is_from_young == _g1h->heap_region_containing_raw(old)->is_young(), "sanity"); assert(is_to_young == _g1h->heap_region_containing_raw(obj)->is_young(), "sanity"); G1StringDedup::enqueue_from_evacuation(is_from_young, is_to_young, _worker_id, obj); } size_t* const surv_young_words = surviving_young_words(); surv_young_words[young_index] += word_sz; if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { // We keep track of the next start index in the length field of // the to-space object. The actual length can be found in the // length field of the from-space object. arrayOop(obj)->set_length(0); oop* old_p = set_partial_array_mask(old); push_on_queue(old_p); } else { HeapRegion* const to_region = _g1h->heap_region_containing_raw(obj_ptr); _scanner.set_region(to_region); obj->oop_iterate_backwards(&_scanner); } return obj; } else { _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); return forward_ptr; } }
inline bool G1CMObjArrayProcessor::should_be_sliced(oop obj) { return obj->is_objArray() && ((size_t)((objArrayOop)obj)->size()) >= 2 * ObjArrayMarkingStride; }
size_t G1CMObjArrayProcessor::process_obj(oop obj) { assert(should_be_sliced(obj), "Must be an array object %d and large " SIZE_FORMAT, obj->is_objArray(), (size_t)obj->size()); return process_array_slice(objArrayOop(obj), (HeapWord*)obj, (size_t)objArrayOop(obj)->size()); }