227 last_entry = entry; // remember for monotonicity test
228 }
229 }
230
231
232 void
233 BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
234 assert(blk_start != NULL && blk_end > blk_start,
235 "phantom block");
236 single_block(blk_start, blk_end);
237 }
238
239 // Action_mark - update the BOT for the block [blk_start, blk_end).
240 // Current typical use is for splitting a block.
241 // Action_single - udpate the BOT for an allocation.
242 // Action_verify - BOT verification.
243 void
244 BlockOffsetArray::do_block_internal(HeapWord* blk_start,
245 HeapWord* blk_end,
246 Action action, bool reducing) {
247 assert(Universe::heap()->is_in_reserved(blk_start),
248 "reference must be into the heap");
249 assert(Universe::heap()->is_in_reserved(blk_end-1),
250 "limit must be within the heap");
251 // This is optimized to make the test fast, assuming we only rarely
252 // cross boundaries.
253 uintptr_t end_ui = (uintptr_t)(blk_end - 1);
254 uintptr_t start_ui = (uintptr_t)blk_start;
255 // Calculate the last card boundary preceding end of blk
256 intptr_t boundary_before_end = (intptr_t)end_ui;
257 clear_bits(boundary_before_end, right_n_bits((int)BOTConstants::LogN));
258 if (start_ui <= (uintptr_t)boundary_before_end) {
259 // blk starts at or crosses a boundary
260 // Calculate index of card on which blk begins
261 size_t start_index = _array->index_for(blk_start);
262 // Index of card on which blk ends
263 size_t end_index = _array->index_for(blk_end - 1);
264 // Start address of card on which blk begins
265 HeapWord* boundary = _array->address_for_index(start_index);
266 assert(boundary <= blk_start, "blk should start at or after boundary");
267 if (blk_start != boundary) {
268 // blk starts strictly after boundary
269 // adjust card boundary and start_index forward to next card
701 // _next_offset_threshold
702 // | _next_offset_index
703 // v v
704 // +-------+-------+-------+-------+-------+
705 // | i-1 | i | i+1 | i+2 | i+3 |
706 // +-------+-------+-------+-------+-------+
707 // ( ^ ]
708 // block-start
709 //
710
711 void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
712 HeapWord* blk_end) {
713 assert(blk_start != NULL && blk_end > blk_start,
714 "phantom block");
715 assert(blk_end > _next_offset_threshold,
716 "should be past threshold");
717 assert(blk_start <= _next_offset_threshold,
718 "blk_start should be at or before threshold");
719 assert(pointer_delta(_next_offset_threshold, blk_start) <= BOTConstants::N_words,
720 "offset should be <= BlockOffsetSharedArray::N");
721 assert(Universe::heap()->is_in_reserved(blk_start),
722 "reference must be into the heap");
723 assert(Universe::heap()->is_in_reserved(blk_end-1),
724 "limit must be within the heap");
725 assert(_next_offset_threshold ==
726 _array->_reserved.start() + _next_offset_index*BOTConstants::N_words,
727 "index must agree with threshold");
728
729 debug_only(size_t orig_next_offset_index = _next_offset_index;)
730
731 // Mark the card that holds the offset into the block. Note
732 // that _next_offset_index and _next_offset_threshold are not
733 // updated until the end of this method.
734 _array->set_offset_array(_next_offset_index,
735 _next_offset_threshold,
736 blk_start);
737
738 // We need to now mark the subsequent cards that this blk spans.
739
740 // Index of card on which blk ends.
741 size_t end_index = _array->index_for(blk_end - 1);
742
743 // Are there more cards left to be updated?
758
759 #ifdef ASSERT
760 // The offset can be 0 if the block starts on a boundary. That
761 // is checked by an assertion above.
762 size_t start_index = _array->index_for(blk_start);
763 HeapWord* boundary = _array->address_for_index(start_index);
764 assert((_array->offset_array(orig_next_offset_index) == 0 &&
765 blk_start == boundary) ||
766 (_array->offset_array(orig_next_offset_index) > 0 &&
767 _array->offset_array(orig_next_offset_index) <= BOTConstants::N_words),
768 "offset array should have been set");
769 for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
770 assert(_array->offset_array(j) > 0 &&
771 _array->offset_array(j) <= (u_char) (BOTConstants::N_words+BOTConstants::N_powers-1),
772 "offset array should have been set");
773 }
774 #endif
775 }
776
777 HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
778 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
779 "just checking");
780 _next_offset_index = _array->index_for(_bottom);
781 _next_offset_index++;
782 _next_offset_threshold =
783 _array->address_for_index(_next_offset_index);
784 return _next_offset_threshold;
785 }
786
787 void BlockOffsetArrayContigSpace::zero_bottom_entry() {
788 assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
789 "just checking");
790 size_t bottom_index = _array->index_for(_bottom);
791 _array->set_offset_array(bottom_index, 0);
792 }
793
794 size_t BlockOffsetArrayContigSpace::last_active_index() const {
795 return _next_offset_index == 0 ? 0 : _next_offset_index - 1;
796 }
|
227 last_entry = entry; // remember for monotonicity test
228 }
229 }
230
231
232 void
233 BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
234 assert(blk_start != NULL && blk_end > blk_start,
235 "phantom block");
236 single_block(blk_start, blk_end);
237 }
238
239 // Action_mark - update the BOT for the block [blk_start, blk_end).
240 // Current typical use is for splitting a block.
241 // Action_single - udpate the BOT for an allocation.
242 // Action_verify - BOT verification.
243 void
244 BlockOffsetArray::do_block_internal(HeapWord* blk_start,
245 HeapWord* blk_end,
246 Action action, bool reducing) {
247 assert(GC::gc()->heap()->is_in_reserved(blk_start),
248 "reference must be into the heap");
249 assert(GC::gc()->heap()->is_in_reserved(blk_end-1),
250 "limit must be within the heap");
251 // This is optimized to make the test fast, assuming we only rarely
252 // cross boundaries.
253 uintptr_t end_ui = (uintptr_t)(blk_end - 1);
254 uintptr_t start_ui = (uintptr_t)blk_start;
255 // Calculate the last card boundary preceding end of blk
256 intptr_t boundary_before_end = (intptr_t)end_ui;
257 clear_bits(boundary_before_end, right_n_bits((int)BOTConstants::LogN));
258 if (start_ui <= (uintptr_t)boundary_before_end) {
259 // blk starts at or crosses a boundary
260 // Calculate index of card on which blk begins
261 size_t start_index = _array->index_for(blk_start);
262 // Index of card on which blk ends
263 size_t end_index = _array->index_for(blk_end - 1);
264 // Start address of card on which blk begins
265 HeapWord* boundary = _array->address_for_index(start_index);
266 assert(boundary <= blk_start, "blk should start at or after boundary");
267 if (blk_start != boundary) {
268 // blk starts strictly after boundary
269 // adjust card boundary and start_index forward to next card
701 // _next_offset_threshold
702 // | _next_offset_index
703 // v v
704 // +-------+-------+-------+-------+-------+
705 // | i-1 | i | i+1 | i+2 | i+3 |
706 // +-------+-------+-------+-------+-------+
707 // ( ^ ]
708 // block-start
709 //
710
711 void BlockOffsetArrayContigSpace::alloc_block_work(HeapWord* blk_start,
712 HeapWord* blk_end) {
713 assert(blk_start != NULL && blk_end > blk_start,
714 "phantom block");
715 assert(blk_end > _next_offset_threshold,
716 "should be past threshold");
717 assert(blk_start <= _next_offset_threshold,
718 "blk_start should be at or before threshold");
719 assert(pointer_delta(_next_offset_threshold, blk_start) <= BOTConstants::N_words,
720 "offset should be <= BlockOffsetSharedArray::N");
721 assert(GC::gc()->heap()->is_in_reserved(blk_start),
722 "reference must be into the heap");
723 assert(GC::gc()->heap()->is_in_reserved(blk_end-1),
724 "limit must be within the heap");
725 assert(_next_offset_threshold ==
726 _array->_reserved.start() + _next_offset_index*BOTConstants::N_words,
727 "index must agree with threshold");
728
729 debug_only(size_t orig_next_offset_index = _next_offset_index;)
730
731 // Mark the card that holds the offset into the block. Note
732 // that _next_offset_index and _next_offset_threshold are not
733 // updated until the end of this method.
734 _array->set_offset_array(_next_offset_index,
735 _next_offset_threshold,
736 blk_start);
737
738 // We need to now mark the subsequent cards that this blk spans.
739
740 // Index of card on which blk ends.
741 size_t end_index = _array->index_for(blk_end - 1);
742
743 // Are there more cards left to be updated?
758
759 #ifdef ASSERT
760 // The offset can be 0 if the block starts on a boundary. That
761 // is checked by an assertion above.
762 size_t start_index = _array->index_for(blk_start);
763 HeapWord* boundary = _array->address_for_index(start_index);
764 assert((_array->offset_array(orig_next_offset_index) == 0 &&
765 blk_start == boundary) ||
766 (_array->offset_array(orig_next_offset_index) > 0 &&
767 _array->offset_array(orig_next_offset_index) <= BOTConstants::N_words),
768 "offset array should have been set");
769 for (size_t j = orig_next_offset_index + 1; j <= end_index; j++) {
770 assert(_array->offset_array(j) > 0 &&
771 _array->offset_array(j) <= (u_char) (BOTConstants::N_words+BOTConstants::N_powers-1),
772 "offset array should have been set");
773 }
774 #endif
775 }
776
777 HeapWord* BlockOffsetArrayContigSpace::initialize_threshold() {
778 assert(!GC::gc()->heap()->is_in_reserved(_array->_offset_array),
779 "just checking");
780 _next_offset_index = _array->index_for(_bottom);
781 _next_offset_index++;
782 _next_offset_threshold =
783 _array->address_for_index(_next_offset_index);
784 return _next_offset_threshold;
785 }
786
787 void BlockOffsetArrayContigSpace::zero_bottom_entry() {
788 assert(!GC::gc()->heap()->is_in_reserved(_array->_offset_array),
789 "just checking");
790 size_t bottom_index = _array->index_for(_bottom);
791 _array->set_offset_array(bottom_index, 0);
792 }
793
794 size_t BlockOffsetArrayContigSpace::last_active_index() const {
795 return _next_offset_index == 0 ? 0 : _next_offset_index - 1;
796 }
|