74 size_t offset = pointer_delta(high, low); 75 check_offset(offset, "offset too large"); 76 set_offset_array(index, (u_char)offset); 77 } 78 79 void G1BlockOffsetSharedArray::set_offset_array(size_t left, size_t right, u_char offset) { 80 check_index(right, "right index out of range"); 81 assert(left <= right, "indexes out of order"); 82 size_t num_cards = right - left + 1; 83 if (UseMemSetInBOT) { 84 memset(&_offset_array[left], offset, num_cards); 85 } else { 86 size_t i = left; 87 const size_t end = i + num_cards; 88 for (; i < end; i++) { 89 _offset_array[i] = offset; 90 } 91 } 92 } 93 94 void G1BlockOffsetSharedArray::check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { 95 check_index(index, "index out of range"); 96 assert(high >= low, "addresses out of order"); 97 check_offset(pointer_delta(high, low), "offset too large"); 98 assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset"); 99 } 100 101 // Variant of index_for that does not check the index for validity. 102 inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const { 103 return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN; 104 } 105 106 inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { 107 char* pc = (char*)p; 108 assert(pc >= (char*)_reserved.start() && 109 pc < (char*)_reserved.end(), 110 err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")", 111 p2i(p), p2i(_reserved.start()), p2i(_reserved.end()))); 112 size_t result = index_for_raw(p); 113 check_index(result, "bad index from address"); 114 return result; 115 } 116 117 inline HeapWord* 118 G1BlockOffsetSharedArray::address_for_index(size_t index) const { 119 check_index(index, "index out of range"); 120 HeapWord* result = address_for_index_raw(index); 174 } 175 assert(q <= n, "wrong order for q and addr"); 176 assert(addr < n, "wrong order for addr and n"); 177 return q; 178 } 179 180 inline HeapWord* 181 G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, 182 const void* addr) { 183 if (oop(q)->klass_or_null() == NULL) return q; 184 HeapWord* n = q + block_size(q); 185 // In the normal case, where the query "addr" is a card boundary, and the 186 // offset table chunks are the same size as cards, the block starting at 187 // "q" will contain addr, so the test below will fail, and we'll fall 188 // through quickly. 189 if (n <= addr) { 190 q = forward_to_block_containing_addr_slow(q, n, addr); 191 } 192 assert(q <= addr, "wrong order for current and arg"); 193 return q; 194 } 195 196 ////////////////////////////////////////////////////////////////////////// 197 // BlockOffsetArrayNonContigSpace inlines 198 ////////////////////////////////////////////////////////////////////////// 199 inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) { 200 // Verify that the BOT shows [blk_start, blk_end) to be one block. 201 verify_single_block(blk_start, blk_end); 202 // adjust _unallocated_block upward or downward 203 // as appropriate 204 if (BlockOffsetArrayUseUnallocatedBlock) { 205 assert(_unallocated_block <= _end, 206 "Inconsistent value for _unallocated_block"); 207 if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) { 208 // CMS-specific note: a block abutting _unallocated_block to 209 // its left is being freed, a new block is being added or 210 // we are resetting following a compaction 211 _unallocated_block = blk_start; 212 } 213 } 214 } 215 216 inline void G1BlockOffsetArray::freed(HeapWord* blk, size_t size) { 217 freed(blk, blk + size); 218 } 219 220 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP | 74 size_t offset = pointer_delta(high, low); 75 check_offset(offset, "offset too large"); 76 set_offset_array(index, (u_char)offset); 77 } 78 79 void G1BlockOffsetSharedArray::set_offset_array(size_t left, size_t right, u_char offset) { 80 check_index(right, "right index out of range"); 81 assert(left <= right, "indexes out of order"); 82 size_t num_cards = right - left + 1; 83 if (UseMemSetInBOT) { 84 memset(&_offset_array[left], offset, num_cards); 85 } else { 86 size_t i = left; 87 const size_t end = i + num_cards; 88 for (; i < end; i++) { 89 _offset_array[i] = offset; 90 } 91 } 92 } 93 94 // Variant of index_for that does not check the index for validity. 95 inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const { 96 return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN; 97 } 98 99 inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { 100 char* pc = (char*)p; 101 assert(pc >= (char*)_reserved.start() && 102 pc < (char*)_reserved.end(), 103 err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")", 104 p2i(p), p2i(_reserved.start()), p2i(_reserved.end()))); 105 size_t result = index_for_raw(p); 106 check_index(result, "bad index from address"); 107 return result; 108 } 109 110 inline HeapWord* 111 G1BlockOffsetSharedArray::address_for_index(size_t index) const { 112 check_index(index, "index out of range"); 113 HeapWord* result = address_for_index_raw(index); 167 } 168 assert(q <= n, "wrong order for q and addr"); 169 assert(addr < n, "wrong order for addr and n"); 170 return q; 171 } 172 173 inline HeapWord* 174 G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, 175 const void* addr) { 176 if (oop(q)->klass_or_null() == NULL) return q; 177 HeapWord* n = q + block_size(q); 178 // In the normal case, where the query "addr" is a card boundary, and the 179 // offset table chunks are the same size as cards, the block starting at 180 // "q" will contain addr, so the test below will fail, and we'll fall 181 // through quickly. 182 if (n <= addr) { 183 q = forward_to_block_containing_addr_slow(q, n, addr); 184 } 185 assert(q <= addr, "wrong order for current and arg"); 186 return q; 187 } 188 189 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP |