comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 2133:2250ee17e258

7007068: G1: refine the BOT during evac failure handling Summary: During evacuation failure handling we refine the BOT to reflect the location of all the objects in the regions we scan. The changeset includes some minor cleanup: a) non-product print_on() method on the G1 BOT class, b) added more complete BOT verification during heap / region verification, c) slight modification to the BOT set up for humongous regions to be more consistent with the BOT set up during evac failure handling, and d) removed a couple of unused methods. Reviewed-by: johnc, ysr
author tonyp
date Wed, 12 Jan 2011 13:06:00 -0500
parents 7c5250dbd584
children b158bed62ef5
comparison
equal deleted inserted replaced
2132:4947ee68d19c 2133:2250ee17e258
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
3854 HeapRegion* _hr; 3854 HeapRegion* _hr;
3855 size_t _prev_marked_bytes; 3855 size_t _prev_marked_bytes;
3856 size_t _next_marked_bytes; 3856 size_t _next_marked_bytes;
3857 OopsInHeapRegionClosure *_cl; 3857 OopsInHeapRegionClosure *_cl;
3858 public: 3858 public:
3859 RemoveSelfPointerClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* cl) : 3859 RemoveSelfPointerClosure(G1CollectedHeap* g1, HeapRegion* hr,
3860 _g1(g1), _cm(_g1->concurrent_mark()), _prev_marked_bytes(0), 3860 OopsInHeapRegionClosure* cl) :
3861 _g1(g1), _hr(hr), _cm(_g1->concurrent_mark()), _prev_marked_bytes(0),
3861 _next_marked_bytes(0), _cl(cl) {} 3862 _next_marked_bytes(0), _cl(cl) {}
3862 3863
3863 size_t prev_marked_bytes() { return _prev_marked_bytes; } 3864 size_t prev_marked_bytes() { return _prev_marked_bytes; }
3864 size_t next_marked_bytes() { return _next_marked_bytes; } 3865 size_t next_marked_bytes() { return _next_marked_bytes; }
3865 3866
3867 // <original comment>
3866 // The original idea here was to coalesce evacuated and dead objects. 3868 // The original idea here was to coalesce evacuated and dead objects.
3867 // However that caused complications with the block offset table (BOT). 3869 // However that caused complications with the block offset table (BOT).
3868 // In particular if there were two TLABs, one of them partially refined. 3870 // In particular if there were two TLABs, one of them partially refined.
3869 // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~| 3871 // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~|
3870 // The BOT entries of the unrefined part of TLAB_2 point to the start 3872 // The BOT entries of the unrefined part of TLAB_2 point to the start
3871 // of TLAB_2. If the last object of the TLAB_1 and the first object 3873 // of TLAB_2. If the last object of the TLAB_1 and the first object
3872 // of TLAB_2 are coalesced, then the cards of the unrefined part 3874 // of TLAB_2 are coalesced, then the cards of the unrefined part
3873 // would point into middle of the filler object. 3875 // would point into middle of the filler object.
3876 // The current approach is to not coalesce and leave the BOT contents intact.
3877 // </original comment>
3874 // 3878 //
3875 // The current approach is to not coalesce and leave the BOT contents intact. 3879 // We now reset the BOT when we start the object iteration over the
3880 // region and refine its entries for every object we come across. So
3881 // the above comment is not really relevant and we should be able
3882 // to coalesce dead objects if we want to.
3876 void do_object(oop obj) { 3883 void do_object(oop obj) {
3884 HeapWord* obj_addr = (HeapWord*) obj;
3885 assert(_hr->is_in(obj_addr), "sanity");
3886 size_t obj_size = obj->size();
3887 _hr->update_bot_for_object(obj_addr, obj_size);
3877 if (obj->is_forwarded() && obj->forwardee() == obj) { 3888 if (obj->is_forwarded() && obj->forwardee() == obj) {
3878 // The object failed to move. 3889 // The object failed to move.
3879 assert(!_g1->is_obj_dead(obj), "We should not be preserving dead objs."); 3890 assert(!_g1->is_obj_dead(obj), "We should not be preserving dead objs.");
3880 _cm->markPrev(obj); 3891 _cm->markPrev(obj);
3881 assert(_cm->isPrevMarked(obj), "Should be marked!"); 3892 assert(_cm->isPrevMarked(obj), "Should be marked!");
3882 _prev_marked_bytes += (obj->size() * HeapWordSize); 3893 _prev_marked_bytes += (obj_size * HeapWordSize);
3883 if (_g1->mark_in_progress() && !_g1->is_obj_ill(obj)) { 3894 if (_g1->mark_in_progress() && !_g1->is_obj_ill(obj)) {
3884 _cm->markAndGrayObjectIfNecessary(obj); 3895 _cm->markAndGrayObjectIfNecessary(obj);
3885 } 3896 }
3886 obj->set_mark(markOopDesc::prototype()); 3897 obj->set_mark(markOopDesc::prototype());
3887 // While we were processing RSet buffers during the 3898 // While we were processing RSet buffers during the
3899 obj->oop_iterate(_cl); 3910 obj->oop_iterate(_cl);
3900 assert(_cm->isPrevMarked(obj), "Should be marked!"); 3911 assert(_cm->isPrevMarked(obj), "Should be marked!");
3901 } else { 3912 } else {
3902 // The object has been either evacuated or is dead. Fill it with a 3913 // The object has been either evacuated or is dead. Fill it with a
3903 // dummy object. 3914 // dummy object.
3904 MemRegion mr((HeapWord*)obj, obj->size()); 3915 MemRegion mr((HeapWord*)obj, obj_size);
3905 CollectedHeap::fill_with_object(mr); 3916 CollectedHeap::fill_with_object(mr);
3906 _cm->clearRangeBothMaps(mr); 3917 _cm->clearRangeBothMaps(mr);
3907 } 3918 }
3908 } 3919 }
3909 }; 3920 };
3919 cl = &immediate_update; 3930 cl = &immediate_update;
3920 } 3931 }
3921 HeapRegion* cur = g1_policy()->collection_set(); 3932 HeapRegion* cur = g1_policy()->collection_set();
3922 while (cur != NULL) { 3933 while (cur != NULL) {
3923 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); 3934 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
3924 3935 assert(!cur->isHumongous(), "sanity");
3925 RemoveSelfPointerClosure rspc(_g1h, cl); 3936
3926 if (cur->evacuation_failed()) { 3937 if (cur->evacuation_failed()) {
3927 assert(cur->in_collection_set(), "bad CS"); 3938 assert(cur->in_collection_set(), "bad CS");
3939 RemoveSelfPointerClosure rspc(_g1h, cur, cl);
3940
3941 cur->reset_bot();
3928 cl->set_region(cur); 3942 cl->set_region(cur);
3929 cur->object_iterate(&rspc); 3943 cur->object_iterate(&rspc);
3930 3944
3931 // A number of manipulations to make the TAMS be the current top, 3945 // A number of manipulations to make the TAMS be the current top,
3932 // and the marked bytes be the ones observed in the iteration. 3946 // and the marked bytes be the ones observed in the iteration.
3985 while (_evac_failure_scan_stack->length() > 0) { 3999 while (_evac_failure_scan_stack->length() > 0) {
3986 oop obj = _evac_failure_scan_stack->pop(); 4000 oop obj = _evac_failure_scan_stack->pop();
3987 _evac_failure_closure->set_region(heap_region_containing(obj)); 4001 _evac_failure_closure->set_region(heap_region_containing(obj));
3988 obj->oop_iterate_backwards(_evac_failure_closure); 4002 obj->oop_iterate_backwards(_evac_failure_closure);
3989 } 4003 }
3990 }
3991
3992 void G1CollectedHeap::handle_evacuation_failure(oop old) {
3993 markOop m = old->mark();
3994 // forward to self
3995 assert(!old->is_forwarded(), "precondition");
3996
3997 old->forward_to(old);
3998 handle_evacuation_failure_common(old, m);
3999 } 4004 }
4000 4005
4001 oop 4006 oop
4002 G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, 4007 G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
4003 oop old) { 4008 oop old) {