/* * Apply f(aux, i) to all i that have positive count in block k */ static void iterate_in_block(uint32_t *a, uint32_t k, void *aux, sparse_array_iterator_t f) { uint32_t n, i; n = block_start(k) + BSIZE; for (i = block_start(k); i<n; i++) { if (a[i] > 0) { f(aux, i); } } }
/* * Copy block i of a into b */ static void copy_block(uint32_t *b, uint32_t *a, uint32_t i) { uint32_t n; n = BSIZE; a += block_start(i); b += block_start(i); do { * b++ = *a ++; n --; } while (n > 0); }
void Space::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl) { assert(!mr.is_empty(), "Should be non-empty"); // We use MemRegion(bottom(), end()) rather than used_region() below // because the two are not necessarily equal for some kinds of // spaces, in particular, certain kinds of free list spaces. // We could use the more complicated but more precise: // MemRegion(used_region().start(), round_to(used_region().end(), CardSize)) // but the slight imprecision seems acceptable in the assertion check. assert(MemRegion(bottom(), end()).contains(mr), "Should be within used space"); HeapWord* prev = cl->previous(); // max address from last time if (prev >= mr.end()) { // nothing to do return; } // This assert will not work when we go from cms space to perm // space, and use same closure. Easy fix deferred for later. XXX YSR // assert(prev == NULL || contains(prev), "Should be within space"); bool last_was_obj_array = false; HeapWord *blk_start_addr, *region_start_addr; if (prev > mr.start()) { region_start_addr = prev; blk_start_addr = prev; // The previous invocation may have pushed "prev" beyond the // last allocated block yet there may be still be blocks // in this region due to a particular coalescing policy. // Relax the assertion so that the case where the unallocated // block is maintained and "prev" is beyond the unallocated // block does not cause the assertion to fire. assert((BlockOffsetArrayUseUnallocatedBlock && (!is_in(prev))) || (blk_start_addr == block_start(region_start_addr)), "invariant"); } else { region_start_addr = mr.start(); blk_start_addr = block_start(region_start_addr); } HeapWord* region_end_addr = mr.end(); MemRegion derived_mr(region_start_addr, region_end_addr); while (blk_start_addr < region_end_addr) { const size_t size = block_size(blk_start_addr); if (block_is_obj(blk_start_addr)) { last_was_obj_array = cl->do_object_bm(oop(blk_start_addr), derived_mr); } else { last_was_obj_array = false; } blk_start_addr += size; } if (!last_was_obj_array) { assert((bottom() <= blk_start_addr) && (blk_start_addr <= end()), "Should be within (closed) used space"); assert(blk_start_addr > prev, "Invariant"); cl->set_previous(blk_start_addr); // min address for next time } }
ALWAYS_INLINE void nip::parse::Parser::generic_block() { block_start(); while (!is(RIGHT_BRACKET, DEDENT)) { element(); } block_end(); }
// 블럭 초기 설정 void Block::Init() { int i, j; // 랜덤 seed 값 넣기 srand( (unsigned)time( NULL ) ); // 화면 배열 초기화 for( i = 0; i < MAX_SIZE_Y - 1; ++i ) { for( j = 0; j < MAX_SIZE_X; ++j ) { if( (j == 0) || (j == MAX_SIZE_X - 1) ) { m_total_block[i][j] = 1; } else { m_total_block[i][j] = 0; } } } // 화면 맨 밑줄을 1로 채운다. for( j = 0; j < MAX_SIZE_X; ++j ) m_total_block[MAX_SIZE_Y - 1][j] = 1; m_shape = MakeBlock(); block_start( &m_angle, &m_x, &m_y ); m_block_state = 0; m_oldTime = clock(); m_moveTime = 1000; screen = Screen::Instance(); }
void nip::parse::Parser::import_element() { block_start(); while (!is(DEDENT, RIGHT_BRACKET)) { import_name(); } block_end(); }
void ContinuousMosaicRV::change_value(ChangeValue& move, Variable::Signal sgl) { int pos = block_start(move.position); if(sgl==Variable::_SET || sgl==Variable::_PROPOSE) { _last_move = CHANGE_VALUE; _last_change_value = move; _value[pos] = move.to; int i; for(i=pos;i<=block_end(pos);i++) { _has_changed[i] = true; } } else if(sgl==Variable::_ACCEPT) { if(_last_move!=CHANGE_VALUE) error("ContinuousMosaicRV::change_value(): inconsistency in move"); _last_move = NO_CHANGE; _has_changed = vector<bool>(_n,false); } else if(sgl==Variable::_REVERT) { if(_last_move!=CHANGE_VALUE) error("ContinuousMosaicRV::change_value(): inconsistency in move"); _last_move = NO_CHANGE; _value[pos] = move.from; _has_changed = vector<bool>(_n,false); } else { error("ContinuousMosaicRV::change_value(): unexpected Variable signal"); } act_on_signal(sgl); send_signal_to_children(sgl); }
HeapWord* HeapRegion::object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(mr.start()); mr = mr.intersection(used_region()); if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). assert(cur <= mr.start() && (oop(cur)->klass_or_null() == NULL || cur + oop(cur)->size() > mr.start()), "postcondition of block_start"); oop obj; while (cur < mr.end()) { obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; } else if (!g1h->is_obj_dead(obj)) { cl->do_object(obj); } if (cl->abort()) return cur; // The check above must occur before the operation below, since an // abort might invalidate the "size" operation. cur += obj->size(); } return NULL; }
void ContiguousSpace::verify(bool allow_dirty) const { HeapWord* p = bottom(); HeapWord* t = top(); HeapWord* prev_p = NULL; while (p < t) { oop(p)->verify(); oop(p)->oop_iterate(&VerifyOopClosure::verify_oop); prev_p = p; p += oop(p)->size(); } guarantee(p == top(), "end of last object must match end of space"); if (top() != end()) { guarantee(top() == block_start(end()-1) && top() == block_start(top()), "top should be start of unallocated block, if it exists"); } }
void Block::NextBlockInit() { m_shape = next_block_shape; next_block_shape = MakeBlock(); block_start( &m_angle, &m_x, &m_y ); //angle,x,y는 포인터임 m_block_state = 0; }
void nip::parse::Parser::about_section() { if (expect(IDENTIFIER, "expected identifier")) { block_start(); while (is(DEDENT, RIGHT_BRACKET)) { metadata_field(); } block_end(); } }
/* * Initialize block i in array a */ static void clean_block(uint32_t *a, uint32_t i) { uint32_t n; n = BSIZE; a += block_start(i); do { *a ++ = 0; n --; } while (n > 0); }
void ContinuousMosaicRV::implement_merge_blocks(const int right_block_start, const double to) { if(block_start(right_block_start)!=right_block_start) error("ContinuousMosaicRV::implement_merge_blocks(): right block does not start at right_block_start"); if(right_block_start==0) error("ContinuousMosaicRV::implement_merge_blocks(): cannot left-merge the leftmost block"); const int left_block_start = block_start(right_block_start-1); // Update _value _value[left_block_start] = to; // Update _block_start and _block_end int i; const int merged_block_end = block_end(right_block_start); for(i=left_block_start;i<right_block_start;i++) { _block_end[i] = merged_block_end; _has_changed[i] = true; } for(;i<=merged_block_end;i++) { _block_start[i] = left_block_start; _has_changed[i] = true; } --_nblocks; }
void ContinuousMosaicRV::implement_extend_block(const int old_block_start, const int new_block_start) { if(block_start(old_block_start)!=old_block_start) error("ContinuousMosaicRV::implement_extend_block(): block does not start at old_block_start"); if(old_block_start==0) error("ContinuousMosaicRV::implement_extend_block(): cannot left-extend the leftmost block"); const int leftmost = block_start(old_block_start-1)+1; const int rightmost = block_end(old_block_start); if(new_block_start<leftmost || new_block_start>rightmost) error("ContinuousMosaicRV::implement_extend_block(): extension out of range"); int i; // Update _value _value[new_block_start] = _value[old_block_start]; // Update _block_start and _block_end if(old_block_start<new_block_start) { // Rightwards move for(i=leftmost-1;i<new_block_start;i++) { _block_end[i] = new_block_start-1; } for(i=old_block_start;i<new_block_start;i++) { _block_start[i] = leftmost-1; _has_changed[i] = true; } // On a right move, define as having changed the first value occurring at the start // of the right block (even though it hasn't) _has_changed[new_block_start] = true; for(i=new_block_start;i<=rightmost;i++) { _block_start[i] = new_block_start; } } else if(old_block_start>new_block_start) { // Leftwards move for(i=leftmost-1;i<new_block_start;i++) { _block_end[i] = new_block_start-1; } // Changed 9:42 15/09/2009 //for(i=new_block_start;i<=old_block_start;i++) { for(i=new_block_start;i<old_block_start;i++) { _block_end[i] = rightmost; _has_changed[i] = true; } for(i=new_block_start;i<=rightmost;i++) { _block_start[i] = new_block_start; } } }
void nip::parse::Parser::type_definition() { if (accept(IDENTIFIER)) { block_start(); while (accept(KEY_CASE)) { type_name(); newlines(); } } else { error("expected identifier"); } }
void ContiguousSpace::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl) { assert(!mr.is_empty(), "Should be non-empty"); assert(used_region().contains(mr), "Should be within used space"); HeapWord* prev = cl->previous(); // max address from last time if (prev >= mr.end()) { // nothing to do return; } // See comment above (in more general method above) in case you // happen to use this method. assert(prev == NULL || is_in_reserved(prev), "Should be within space"); bool last_was_obj_array = false; HeapWord *obj_start_addr, *region_start_addr; if (prev > mr.start()) { region_start_addr = prev; obj_start_addr = prev; assert(obj_start_addr == block_start(region_start_addr), "invariant"); } else { region_start_addr = mr.start(); obj_start_addr = block_start(region_start_addr); } HeapWord* region_end_addr = mr.end(); MemRegion derived_mr(region_start_addr, region_end_addr); while (obj_start_addr < region_end_addr) { oop obj = oop(obj_start_addr); const size_t size = obj->size(); last_was_obj_array = cl->do_object_bm(obj, derived_mr); obj_start_addr += size; } if (!last_was_obj_array) { assert((bottom() <= obj_start_addr) && (obj_start_addr <= end()), "Should be within (closed) used space"); assert(obj_start_addr > prev, "Invariant"); cl->set_previous(obj_start_addr); // min address for next time } }
/****************************************************************************** ** huffman_encode ** -------------------------------------------------------------------------- ** Quantize and Encode a 8x8 DCT block by JPEG Huffman lossless coding. ** This function writes encoded bit-stream into bit-buffer. ** ** ARGUMENTS: ** ctx - pointer to encoder context; ** data - pointer to 8x8 DCT block; ** ** RETURN: - ******************************************************************************/ void huffman_encode(huffman_t *const ctx, const short data[], unsigned block_num) { unsigned magn, bits; unsigned zerorun, i; short diff; short dc = quantize(data[0], ctx->qtable[0]); // WARNING: in order to everything to work correctly // the get_DC_value must be called before the block_start // otherwise it returns a wrong DC value in case of megablocks // (the block_start reset the force_marker variable, which is // used by get_DC_value diff = get_DC_value(dc, block_num); block_start(block_num); bits = huffman_bits(diff); magn = huffman_magnitude(diff); add_to_block(ctx->hdcbit[magn], ctx->hdclen[magn]); add_to_block(bits, magn); for (zerorun = 0, i = 1; i < 64; i++) { const short ac = quantize(data[zig[i]], ctx->qtable[zig[i]]); if (ac) { while (zerorun >= 16) { zerorun -= 16; // ZRL add_to_block(ctx->hacbit[15][0], ctx->haclen[15][0]); } bits = huffman_bits(ac); magn = huffman_magnitude(ac); add_to_block(ctx->hacbit[zerorun][magn], ctx->haclen[zerorun][magn]); add_to_block(bits, magn); zerorun = 0; } else zerorun++; } if (zerorun) { // EOB - End Of Block add_to_block(ctx->hacbit[0][0], ctx->haclen[0][0]); } block_end(&bitbuf); }
void ContinuousMosaicRV::implement_split_block(const int right_block_start, const double to[2]) { const int left_block_start = block_start(right_block_start); if(left_block_start==right_block_start) error("ContinuousMosaicRV::implement_split_block(): left block starts at right_block_start"); // Update _value _value[left_block_start] = to[0]; _value[right_block_start] = to[1]; // Update _block_start and _block_end int i; const int right_block_end = block_end(right_block_start); for(i=left_block_start;i<right_block_start;i++) { _block_end[i] = right_block_start-1; _has_changed[i] = true; } for(;i<=right_block_end;i++) { _block_start[i] = right_block_start; _has_changed[i] = true; } ++_nblocks; }
void BlockOffsetArray::verify() const { // For each entry in the block offset table, verify that // the entry correctly finds the start of an object at the // first address covered by the block or to the left of that // first address. size_t next_index = 1; size_t last_index = last_active_index(); // Use for debugging. Initialize to NULL to distinguish the // first iteration through the while loop. HeapWord* last_p = NULL; HeapWord* last_start = NULL; oop last_o = NULL; while (next_index <= last_index) { // Use an address past the start of the address for // the entry. HeapWord* p = _array->address_for_index(next_index) + 1; if (p >= _end) { // That's all of the allocated block table. return; } // block_start() asserts that start <= p. HeapWord* start = block_start(p); // First check if the start is an allocated block and only // then if it is a valid object. oop o = oop(start); assert(!Universe::is_fully_initialized() || _sp->is_free_block(start) || o->is_oop_or_null(), "Bad object was found"); next_index++; last_p = p; last_start = start; last_o = o; } }
void ContiguousSpace::oop_iterate(MemRegion mr, OopClosure* blk) { if (is_empty()) { return; } MemRegion cur = MemRegion(bottom(), top()); mr = mr.intersection(cur); if (mr.is_empty()) { return; } if (mr.equals(cur)) { oop_iterate(blk); return; } assert(mr.end() <= top(), "just took an intersection above"); HeapWord* obj_addr = block_start(mr.start()); HeapWord* t = mr.end(); // Handle first object specially. oop obj = oop(obj_addr); SpaceMemRegionOopsIterClosure smr_blk(blk, mr); obj_addr += obj->oop_iterate(&smr_blk); while (obj_addr < t) { oop obj = oop(obj_addr); assert(obj->is_oop(), "expected an oop"); obj_addr += obj->size(); // If "obj_addr" is not greater than top, then the // entire object "obj" is within the region. if (obj_addr <= t) { obj->oop_iterate(blk); } else { // "obj" extends beyond end of region obj->oop_iterate(&smr_blk); break; } }; }
void OffsetTableContigSpace::verify(bool allow_dirty) const { HeapWord* p = bottom(); HeapWord* prev_p = NULL; VerifyOldOopClosure blk; // Does this do anything? blk.allow_dirty = allow_dirty; int objs = 0; int blocks = 0; if (VerifyObjectStartArray) { _offsets.verify(); } while (p < top()) { size_t size = oop(p)->size(); // For a sampling of objects in the space, find it using the // block offset table. if (blocks == BLOCK_SAMPLE_INTERVAL) { guarantee(p == block_start(p + (size/2)), "check offset computation"); blocks = 0; } else { blocks++; } if (objs == OBJ_SAMPLE_INTERVAL) { oop(p)->verify(); blk.the_obj = oop(p); oop(p)->oop_iterate(&blk); objs = 0; } else { objs++; } prev_p = p; p += size; } guarantee(p == top(), "end of last object must match end of space"); }
HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, FilterOutOfRegionClosure* cl, bool filter_young) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a // GC alloc region that extends onto a GC LAB, which may not be // parseable. Stop such at the "saved_mark" of the region. if (G1CollectedHeap::heap()->is_gc_active()) { mr = mr.intersection(used_region_at_save_marks()); } else { mr = mr.intersection(used_region()); } if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). // The intersection of the incoming mr (for the card) and the // allocated part of the region is non-empty. This implies that // we have actually allocated into this region. The code in // G1CollectedHeap.cpp that allocates a new region sets the // is_young tag on the region before allocating. Thus we // safely know if this region is young. if (is_young() && filter_young) { return NULL; } assert(!is_young(), "check value of filter_young"); // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(mr.start()); assert(cur <= mr.start(), "Postcondition"); while (cur <= mr.start()) { if (oop(cur)->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; } // Otherwise... int sz = oop(cur)->size(); if (cur + sz > mr.start()) break; // Otherwise, go on. cur = cur + sz; } oop obj; obj = oop(cur); // If we finish this loop... assert(cur <= mr.start() && obj->klass_or_null() != NULL && cur + obj->size() > mr.start(), "Loop postcondition"); if (!g1h->is_obj_dead(obj)) { obj->oop_iterate(cl, mr); } HeapWord* next; while (cur < mr.end()) { obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; }; // Otherwise: next = (cur + obj->size()); if (!g1h->is_obj_dead(obj)) { if (next < mr.end()) { obj->oop_iterate(cl); } else { // this obj spans the boundary. If it's an array, stop at the // boundary. if (obj->is_objArray()) { obj->oop_iterate(cl, mr); } else { obj->oop_iterate(cl); } } } cur = next; } return NULL; }
bool Space::is_in(const void* p) const { HeapWord* b = block_start(p); return b != NULL && block_is_obj(b); }
bool ParallelScavengeHeap::block_is_obj(const HeapWord* addr) const { return block_start(addr) == addr; }
/** * Parses the file and populates the structures used by this FUSE driver. * * \param filename The filename to parse * \param r The result structure to populate (or NULL if not needed) * \returns 0 if successful, -1 if not. */ static int process_file(const char *filename, result_t new_result) { img_info = tsk_img_open_sing(filename, TSK_IMG_TYPE_DETECT, 0); if (img_info == NULL) { info_log("Failed to open image: %s", filename); return -1; } fs_info = tsk_fs_open_img(img_info, 0, TSK_FS_TYPE_DETECT); if (fs_info == NULL) { info_log("Failed to open filesystem: %s", filename); return -1; } const char *fsname = tsk_fs_type_toname(fs_info->ftype); result_set_brief_data_description(new_result, fsname); mountpoint = g_strdup_printf("%s:mnt-%s", filename, fsname); char *description = g_strdup_printf("%" PRIdDADDR " bytes (%" PRIdDADDR " %ss of %u size)", fs_info->block_count * fs_info->block_size, fs_info->block_count, fs_info->duname, fs_info->block_size); result_set_data_description(new_result, description); g_free(description); result_set_confidence(new_result, 100); block_start(absolute_offset); TSK_FS_DIR_WALK_FLAG_ENUM name_flags = (TSK_FS_DIR_WALK_FLAG_ENUM) (TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE); if (tsk_fs_dir_walk(fs_info, fs_info->root_inum, name_flags, examine_dirent, new_result) != 0) { // Why does this occur? Is it because it's an invalid filesystem structure, or the // structure is damaged? I'm going to assume the structure is damaged, but partially available. warning_log("Warning, unable to fully walk fs! Probably truncated or not a real FS header."); } unsigned int size; block_range_t *ranges = block_end(&size); if (ranges != NULL) { result_set_block_ranges(new_result, ranges, size); for (int i = 0; i < size; i++) { block_range_close(ranges[i]); } g_free(ranges); } if (inode_lookup != NULL) { g_tree_destroy(inode_lookup); inode_lookup = NULL; } unsigned int num_contracts; result_get_new_contracts(new_result, &num_contracts); if (num_contracts > 0) { // Ready to mount! int ret = do_mount(mountpoint); if (ret != 0) { error_log("Failed to mount filesystem!"); } } remove_all_files(); return 0; }
HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, FilterOutOfRegionClosure* cl, bool filter_young, jbyte* card_ptr) { // Currently, we should only have to clean the card if filter_young // is true and vice versa. if (filter_young) { assert(card_ptr != NULL, "pre-condition"); } else { assert(card_ptr == NULL, "pre-condition"); } G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a // GC alloc region that extends onto a GC LAB, which may not be // parseable. Stop such at the "scan_top" of the region. if (g1h->is_gc_active()) { mr = mr.intersection(MemRegion(bottom(), scan_top())); } else { mr = mr.intersection(used_region()); } if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). // The intersection of the incoming mr (for the card) and the // allocated part of the region is non-empty. This implies that // we have actually allocated into this region. The code in // G1CollectedHeap.cpp that allocates a new region sets the // is_young tag on the region before allocating. Thus we // safely know if this region is young. if (is_young() && filter_young) { return NULL; } assert(!is_young(), "check value of filter_young"); // We can only clean the card here, after we make the decision that // the card is not young. And we only clean the card if we have been // asked to (i.e., card_ptr != NULL). if (card_ptr != NULL) { *card_ptr = CardTableModRefBS::clean_card_val(); // We must complete this write before we do any of the reads below. OrderAccess::storeload(); } // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); HeapWord* const end = mr.end(); // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(start); assert(cur <= start, "Postcondition"); oop obj; HeapWord* next = cur; do { cur = next; obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; } // Otherwise... next = cur + block_size(cur); } while (next <= start); // If we finish the above loop...We have a parseable object that // begins on or before the start of the memory region, and ends // inside or spans the entire region. assert(cur <= start, "Loop postcondition"); assert(obj->klass_or_null() != NULL, "Loop postcondition"); do { obj = oop(cur); assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant"); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; } // Advance the current pointer. "obj" still points to the object to iterate. cur = cur + block_size(cur); if (!g1h->is_obj_dead(obj)) { // Non-objArrays are sometimes marked imprecise at the object start. We // always need to iterate over them in full. // We only iterate over object arrays in full if they are completely contained // in the memory region. if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) { obj->oop_iterate(cl); } else { obj->oop_iterate(cl, mr); } } } while (cur < end); return NULL; }
HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, FilterOutOfRegionClosure* cl, bool filter_young, jbyte* card_ptr) { // Currently, we should only have to clean the card if filter_young // is true and vice versa. if (filter_young) { assert(card_ptr != NULL, "pre-condition"); } else { assert(card_ptr == NULL, "pre-condition"); } G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a // GC alloc region that extends onto a GC LAB, which may not be // parseable. Stop such at the "saved_mark" of the region. if (g1h->is_gc_active()) { mr = mr.intersection(used_region_at_save_marks()); } else { mr = mr.intersection(used_region()); } if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). // The intersection of the incoming mr (for the card) and the // allocated part of the region is non-empty. This implies that // we have actually allocated into this region. The code in // G1CollectedHeap.cpp that allocates a new region sets the // is_young tag on the region before allocating. Thus we // safely know if this region is young. if (is_young() && filter_young) { return NULL; } assert(!is_young(), "check value of filter_young"); // We can only clean the card here, after we make the decision that // the card is not young. And we only clean the card if we have been // asked to (i.e., card_ptr != NULL). if (card_ptr != NULL) { *card_ptr = CardTableModRefBS::clean_card_val(); // We must complete this write before we do any of the reads below. OrderAccess::storeload(); } // Cache the boundaries of the memory region in some const locals HeapWord* const start = mr.start(); HeapWord* const end = mr.end(); // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(start); assert(cur <= start, "Postcondition"); oop obj; HeapWord* next = cur; while (next <= start) { cur = next; obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; } // Otherwise... next = (cur + obj->size()); } // If we finish the above loop...We have a parseable object that // begins on or before the start of the memory region, and ends // inside or spans the entire region. assert(obj == oop(cur), "sanity"); assert(cur <= start && obj->klass_or_null() != NULL && (cur + obj->size()) > start, "Loop postcondition"); if (!g1h->is_obj_dead(obj)) { obj->oop_iterate(cl, mr); } while (cur < end) { obj = oop(cur); if (obj->klass_or_null() == NULL) { // Ran into an unparseable point. return cur; }; // Otherwise: next = (cur + obj->size()); if (!g1h->is_obj_dead(obj)) { if (next < end || !obj->is_objArray()) { // This object either does not span the MemRegion // boundary, or if it does it's not an array. // Apply closure to whole object. obj->oop_iterate(cl); } else { // This obj is an array that spans the boundary. // Stop at the boundary. obj->oop_iterate(cl, mr); } } cur = next; } return NULL; }