--- a/hotspot/src/share/vm/memory/blockOffsetTable.hpp Sat Aug 14 00:47:52 2010 -0700
+++ b/hotspot/src/share/vm/memory/blockOffsetTable.hpp Mon Aug 16 15:58:42 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,6 +107,8 @@
N_words = 1 << LogN_words
};
+ bool _init_to_zero;
+
// The reserved region covered by the shared array.
MemRegion _reserved;
@@ -125,17 +127,28 @@
assert(index < _vs.committed_size(), "index out of range");
return _offset_array[index];
}
- void set_offset_array(size_t index, u_char offset) {
+ // An assertion-checking helper method for the set_offset_array() methods below.
+ void check_reducing_assertion(bool reducing);
+
+ void set_offset_array(size_t index, u_char offset, bool reducing = false) {
+ check_reducing_assertion(reducing);
assert(index < _vs.committed_size(), "index out of range");
+ assert(!reducing || _offset_array[index] >= offset, "Not reducing");
_offset_array[index] = offset;
}
- void set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
+
+ void set_offset_array(size_t index, HeapWord* high, HeapWord* low, bool reducing = false) {
+ check_reducing_assertion(reducing);
assert(index < _vs.committed_size(), "index out of range");
assert(high >= low, "addresses out of order");
assert(pointer_delta(high, low) <= N_words, "offset too large");
+ assert(!reducing || _offset_array[index] >= (u_char)pointer_delta(high, low),
+ "Not reducing");
_offset_array[index] = (u_char)pointer_delta(high, low);
}
- void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
+
+ void set_offset_array(HeapWord* left, HeapWord* right, u_char offset, bool reducing = false) {
+ check_reducing_assertion(reducing);
assert(index_for(right - 1) < _vs.committed_size(),
"right address out of range");
assert(left < right, "Heap addresses out of order");
@@ -150,12 +163,14 @@
size_t i = index_for(left);
const size_t end = i + num_cards;
for (; i < end; i++) {
+ assert(!reducing || _offset_array[i] >= offset, "Not reducing");
_offset_array[i] = offset;
}
}
}
- void set_offset_array(size_t left, size_t right, u_char offset) {
+ void set_offset_array(size_t left, size_t right, u_char offset, bool reducing = false) {
+ check_reducing_assertion(reducing);
assert(right < _vs.committed_size(), "right address out of range");
assert(left <= right, "indexes out of order");
size_t num_cards = right - left + 1;
@@ -169,6 +184,7 @@
size_t i = left;
const size_t end = i + num_cards;
for (; i < end; i++) {
+ assert(!reducing || _offset_array[i] >= offset, "Not reducing");
_offset_array[i] = offset;
}
}
@@ -212,6 +228,11 @@
void set_bottom(HeapWord* new_bottom);
+ // Whether entries should be initialized to zero. Used currently only for
+ // error checking.
+ void set_init_to_zero(bool val) { _init_to_zero = val; }
+ bool init_to_zero() { return _init_to_zero; }
+
// Updates all the BlockOffsetArray's sharing this shared array to
// reflect the current "top"'s of their spaces.
void update_offset_arrays(); // Not yet implemented!
@@ -285,17 +306,23 @@
// initialized to point backwards to the beginning of the covered region.
bool _init_to_zero;
+ // An assertion-checking helper method for the set_remainder*() methods below.
+ void check_reducing_assertion(bool reducing) { _array->check_reducing_assertion(reducing); }
+
// Sets the entries
// corresponding to the cards starting at "start" and ending at "end"
// to point back to the card before "start": the interval [start, end)
- // is right-open.
- void set_remainder_to_point_to_start(HeapWord* start, HeapWord* end);
+ // is right-open. The last parameter, reducing, indicates whether the
+ // updates to individual entries always reduce the entry from a higher
+ // to a lower value. (For example this would hold true during a temporal
+ // regime during which only block splits were updating the BOT.
+ void set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing = false);
// Same as above, except that the args here are a card _index_ interval
// that is closed: [start_index, end_index]
- void set_remainder_to_point_to_start_incl(size_t start, size_t end);
+ void set_remainder_to_point_to_start_incl(size_t start, size_t end, bool reducing = false);
// A helper function for BOT adjustment/verification work
- void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action);
+ void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action, bool reducing = false);
public:
// The space may not have its bottom and top set yet, which is why the
@@ -303,7 +330,7 @@
// elements of the array are initialized to zero. Otherwise, they are
// initialized to point backwards to the beginning.
BlockOffsetArray(BlockOffsetSharedArray* array, MemRegion mr,
- bool init_to_zero);
+ bool init_to_zero_);
// Note: this ought to be part of the constructor, but that would require
// "this" to be passed as a parameter to a member constructor for
@@ -358,6 +385,12 @@
// If true, initialize array slots with no allocated blocks to zero.
// Otherwise, make them point back to the front.
bool init_to_zero() { return _init_to_zero; }
+ // Corresponding setter
+ void set_init_to_zero(bool val) {
+ _init_to_zero = val;
+ assert(_array != NULL, "_array should be non-NULL");
+ _array->set_init_to_zero(val);
+ }
// Debugging
// Return the index of the last entry in the "active" region.
@@ -424,16 +457,16 @@
// of BOT is touched. It is assumed (and verified in the
// non-product VM) that the remaining cards of the block
// are correct.
- void mark_block(HeapWord* blk_start, HeapWord* blk_end);
- void mark_block(HeapWord* blk, size_t size) {
- mark_block(blk, blk + size);
+ void mark_block(HeapWord* blk_start, HeapWord* blk_end, bool reducing = false);
+ void mark_block(HeapWord* blk, size_t size, bool reducing = false) {
+ mark_block(blk, blk + size, reducing);
}
// Adjust _unallocated_block to indicate that a particular
// block has been newly allocated or freed. It is assumed (and
// verified in the non-product VM) that the BOT is correct for
// the given block.
- void allocated(HeapWord* blk_start, HeapWord* blk_end) {
+ void allocated(HeapWord* blk_start, HeapWord* blk_end, bool reducing = false) {
// Verify that the BOT shows [blk, blk + blk_size) to be one block.
verify_single_block(blk_start, blk_end);
if (BlockOffsetArrayUseUnallocatedBlock) {
@@ -441,14 +474,12 @@
}
}
- void allocated(HeapWord* blk, size_t size) {
- allocated(blk, blk + size);
+ void allocated(HeapWord* blk, size_t size, bool reducing = false) {
+ allocated(blk, blk + size, reducing);
}
void freed(HeapWord* blk_start, HeapWord* blk_end);
- void freed(HeapWord* blk, size_t size) {
- freed(blk, blk + size);
- }
+ void freed(HeapWord* blk, size_t size);
HeapWord* block_start_unsafe(const void* addr) const;
@@ -456,7 +487,6 @@
// start of the block that contains the given address.
HeapWord* block_start_careful(const void* addr) const;
-
// Verification & debugging: ensure that the offset table reflects
// the fact that the block [blk_start, blk_end) or [blk, blk + size)
// is a single block of storage. NOTE: can't const this because of