Пример #1
0
/*
 * 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);
    }
  }
}
Пример #2
0
/*
 * 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);
}
Пример #3
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
  }
}
Пример #4
0
ALWAYS_INLINE void nip::parse::Parser::generic_block() {
	block_start();
	while (!is(RIGHT_BRACKET, DEDENT)) {
		element();
	}
	block_end();
}
Пример #5
0
// 블럭 초기 설정
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();
}
Пример #6
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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");
  }
}
Пример #10
0
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;
}
Пример #11
0
void nip::parse::Parser::about_section() {
	if (expect(IDENTIFIER, "expected identifier")) {
		block_start();
		while (is(DEDENT, RIGHT_BRACKET)) {
			metadata_field();
		}
		block_end();
	}
}
Пример #12
0
/*
 * 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);
}
Пример #13
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;
}
Пример #14
0
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;
		}
	}
}
Пример #15
0
void nip::parse::Parser::type_definition() {
	if (accept(IDENTIFIER)) {
		block_start();
		while (accept(KEY_CASE)) {
			type_name();
			newlines();
		}
	}
	else {
		error("expected identifier");
	}
}
Пример #16
0
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
  }
}
Пример #17
0
/******************************************************************************
**  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);
}
Пример #18
0
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;
}
Пример #19
0
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;
  }
}
Пример #20
0
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;
    }
  };
}
Пример #21
0
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");
}
Пример #22
0
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;
}
Пример #23
0
bool Space::is_in(const void* p) const {
  HeapWord* b = block_start(p);
  return b != NULL && block_is_obj(b);
}
Пример #24
0
bool ParallelScavengeHeap::block_is_obj(const HeapWord* addr) const {
  return block_start(addr) == addr;
}
Пример #25
0
/**
 * 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;
}
Пример #26
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;
}
Пример #27
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 "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;
}