1853 }
1854
1855 HeapRegion*
1856 G1ConcurrentMark::claim_region(uint worker_id) {
1857 // "checkpoint" the finger
1858 HeapWord* finger = _finger;
1859
1860 // _heap_end will not change underneath our feet; it only changes at
1861 // yield points.
1862 while (finger < _heap_end) {
1863 assert(_g1h->is_in_g1_reserved(finger), "invariant");
1864
1865 HeapRegion* curr_region = _g1h->heap_region_containing(finger);
1866 // Make sure that the reads below do not float before loading curr_region.
1867 OrderAccess::loadload();
1868 // Above heap_region_containing may return NULL as we always scan claim
1869 // until the end of the heap. In this case, just jump to the next region.
1870 HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
1871
1872 // Is the gap between reading the finger and doing the CAS too long?
1873 HeapWord* res = (HeapWord*) Atomic::cmpxchg_ptr(end, &_finger, finger);
1874 if (res == finger && curr_region != NULL) {
1875 // we succeeded
1876 HeapWord* bottom = curr_region->bottom();
1877 HeapWord* limit = curr_region->next_top_at_mark_start();
1878
1879 // notice that _finger == end cannot be guaranteed here since,
1880 // someone else might have moved the finger even further
1881 assert(_finger >= end, "the finger should have moved forward");
1882
1883 if (limit > bottom) {
1884 return curr_region;
1885 } else {
1886 assert(limit == bottom,
1887 "the region limit should be at bottom");
1888 // we return NULL and the caller should try calling
1889 // claim_region() again.
1890 return NULL;
1891 }
1892 } else {
1893 assert(_finger > finger, "the finger should have moved forward");
|
1853 }
1854
1855 HeapRegion*
1856 G1ConcurrentMark::claim_region(uint worker_id) {
1857 // "checkpoint" the finger
1858 HeapWord* finger = _finger;
1859
1860 // _heap_end will not change underneath our feet; it only changes at
1861 // yield points.
1862 while (finger < _heap_end) {
1863 assert(_g1h->is_in_g1_reserved(finger), "invariant");
1864
1865 HeapRegion* curr_region = _g1h->heap_region_containing(finger);
1866 // Make sure that the reads below do not float before loading curr_region.
1867 OrderAccess::loadload();
1868 // Above heap_region_containing may return NULL as we always scan claim
1869 // until the end of the heap. In this case, just jump to the next region.
1870 HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
1871
1872 // Is the gap between reading the finger and doing the CAS too long?
1873 HeapWord* res = Atomic::cmpxchg(end, &_finger, finger);
1874 if (res == finger && curr_region != NULL) {
1875 // we succeeded
1876 HeapWord* bottom = curr_region->bottom();
1877 HeapWord* limit = curr_region->next_top_at_mark_start();
1878
1879 // notice that _finger == end cannot be guaranteed here since,
1880 // someone else might have moved the finger even further
1881 assert(_finger >= end, "the finger should have moved forward");
1882
1883 if (limit > bottom) {
1884 return curr_region;
1885 } else {
1886 assert(limit == bottom,
1887 "the region limit should be at bottom");
1888 // we return NULL and the caller should try calling
1889 // claim_region() again.
1890 return NULL;
1891 }
1892 } else {
1893 assert(_finger > finger, "the finger should have moved forward");
|