1.1 --- a/src/share/vm/memory/blockOffsetTable.hpp Sat Aug 14 00:47:52 2010 -0700 1.2 +++ b/src/share/vm/memory/blockOffsetTable.hpp Mon Aug 16 15:58:42 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -107,6 +107,8 @@ 1.11 N_words = 1 << LogN_words 1.12 }; 1.13 1.14 + bool _init_to_zero; 1.15 + 1.16 // The reserved region covered by the shared array. 1.17 MemRegion _reserved; 1.18 1.19 @@ -125,17 +127,28 @@ 1.20 assert(index < _vs.committed_size(), "index out of range"); 1.21 return _offset_array[index]; 1.22 } 1.23 - void set_offset_array(size_t index, u_char offset) { 1.24 + // An assertion-checking helper method for the set_offset_array() methods below. 1.25 + void check_reducing_assertion(bool reducing); 1.26 + 1.27 + void set_offset_array(size_t index, u_char offset, bool reducing = false) { 1.28 + check_reducing_assertion(reducing); 1.29 assert(index < _vs.committed_size(), "index out of range"); 1.30 + assert(!reducing || _offset_array[index] >= offset, "Not reducing"); 1.31 _offset_array[index] = offset; 1.32 } 1.33 - void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { 1.34 + 1.35 + void set_offset_array(size_t index, HeapWord* high, HeapWord* low, bool reducing = false) { 1.36 + check_reducing_assertion(reducing); 1.37 assert(index < _vs.committed_size(), "index out of range"); 1.38 assert(high >= low, "addresses out of order"); 1.39 assert(pointer_delta(high, low) <= N_words, "offset too large"); 1.40 + assert(!reducing || _offset_array[index] >= (u_char)pointer_delta(high, low), 1.41 + "Not reducing"); 1.42 _offset_array[index] = (u_char)pointer_delta(high, low); 1.43 } 1.44 - void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { 1.45 + 1.46 + void set_offset_array(HeapWord* left, HeapWord* right, u_char offset, bool reducing = false) { 1.47 + check_reducing_assertion(reducing); 1.48 assert(index_for(right - 1) < _vs.committed_size(), 1.49 "right address out of range"); 1.50 assert(left < right, "Heap addresses out of order"); 1.51 @@ -150,12 +163,14 @@ 1.52 size_t i = index_for(left); 1.53 const size_t end = i + num_cards; 1.54 for (; i < end; i++) { 1.55 + assert(!reducing || _offset_array[i] >= offset, "Not reducing"); 1.56 _offset_array[i] = offset; 1.57 } 1.58 } 1.59 } 1.60 1.61 - void set_offset_array(size_t left, size_t right, u_char offset) { 1.62 + void set_offset_array(size_t left, size_t right, u_char offset, bool reducing = false) { 1.63 + check_reducing_assertion(reducing); 1.64 assert(right < _vs.committed_size(), "right address out of range"); 1.65 assert(left <= right, "indexes out of order"); 1.66 size_t num_cards = right - left + 1; 1.67 @@ -169,6 +184,7 @@ 1.68 size_t i = left; 1.69 const size_t end = i + num_cards; 1.70 for (; i < end; i++) { 1.71 + assert(!reducing || _offset_array[i] >= offset, "Not reducing"); 1.72 _offset_array[i] = offset; 1.73 } 1.74 } 1.75 @@ -212,6 +228,11 @@ 1.76 1.77 void set_bottom(HeapWord* new_bottom); 1.78 1.79 + // Whether entries should be initialized to zero. Used currently only for 1.80 + // error checking. 1.81 + void set_init_to_zero(bool val) { _init_to_zero = val; } 1.82 + bool init_to_zero() { return _init_to_zero; } 1.83 + 1.84 // Updates all the BlockOffsetArray's sharing this shared array to 1.85 // reflect the current "top"'s of their spaces. 1.86 void update_offset_arrays(); // Not yet implemented! 1.87 @@ -285,17 +306,23 @@ 1.88 // initialized to point backwards to the beginning of the covered region. 1.89 bool _init_to_zero; 1.90 1.91 + // An assertion-checking helper method for the set_remainder*() methods below. 1.92 + void check_reducing_assertion(bool reducing) { _array->check_reducing_assertion(reducing); } 1.93 + 1.94 // Sets the entries 1.95 // corresponding to the cards starting at "start" and ending at "end" 1.96 // to point back to the card before "start": the interval [start, end) 1.97 - // is right-open. 1.98 - void set_remainder_to_point_to_start(HeapWord* start, HeapWord* end); 1.99 + // is right-open. The last parameter, reducing, indicates whether the 1.100 + // updates to individual entries always reduce the entry from a higher 1.101 + // to a lower value. (For example this would hold true during a temporal 1.102 + // regime during which only block splits were updating the BOT. 1.103 + void set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing = false); 1.104 // Same as above, except that the args here are a card _index_ interval 1.105 // that is closed: [start_index, end_index] 1.106 - void set_remainder_to_point_to_start_incl(size_t start, size_t end); 1.107 + void set_remainder_to_point_to_start_incl(size_t start, size_t end, bool reducing = false); 1.108 1.109 // A helper function for BOT adjustment/verification work 1.110 - void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action); 1.111 + void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action, bool reducing = false); 1.112 1.113 public: 1.114 // The space may not have its bottom and top set yet, which is why the 1.115 @@ -303,7 +330,7 @@ 1.116 // elements of the array are initialized to zero. Otherwise, they are 1.117 // initialized to point backwards to the beginning. 1.118 BlockOffsetArray(BlockOffsetSharedArray* array, MemRegion mr, 1.119 - bool init_to_zero); 1.120 + bool init_to_zero_); 1.121 1.122 // Note: this ought to be part of the constructor, but that would require 1.123 // "this" to be passed as a parameter to a member constructor for 1.124 @@ -358,6 +385,12 @@ 1.125 // If true, initialize array slots with no allocated blocks to zero. 1.126 // Otherwise, make them point back to the front. 1.127 bool init_to_zero() { return _init_to_zero; } 1.128 + // Corresponding setter 1.129 + void set_init_to_zero(bool val) { 1.130 + _init_to_zero = val; 1.131 + assert(_array != NULL, "_array should be non-NULL"); 1.132 + _array->set_init_to_zero(val); 1.133 + } 1.134 1.135 // Debugging 1.136 // Return the index of the last entry in the "active" region. 1.137 @@ -424,16 +457,16 @@ 1.138 // of BOT is touched. It is assumed (and verified in the 1.139 // non-product VM) that the remaining cards of the block 1.140 // are correct. 1.141 - void mark_block(HeapWord* blk_start, HeapWord* blk_end); 1.142 - void mark_block(HeapWord* blk, size_t size) { 1.143 - mark_block(blk, blk + size); 1.144 + void mark_block(HeapWord* blk_start, HeapWord* blk_end, bool reducing = false); 1.145 + void mark_block(HeapWord* blk, size_t size, bool reducing = false) { 1.146 + mark_block(blk, blk + size, reducing); 1.147 } 1.148 1.149 // Adjust _unallocated_block to indicate that a particular 1.150 // block has been newly allocated or freed. It is assumed (and 1.151 // verified in the non-product VM) that the BOT is correct for 1.152 // the given block. 1.153 - void allocated(HeapWord* blk_start, HeapWord* blk_end) { 1.154 + void allocated(HeapWord* blk_start, HeapWord* blk_end, bool reducing = false) { 1.155 // Verify that the BOT shows [blk, blk + blk_size) to be one block. 1.156 verify_single_block(blk_start, blk_end); 1.157 if (BlockOffsetArrayUseUnallocatedBlock) { 1.158 @@ -441,14 +474,12 @@ 1.159 } 1.160 } 1.161 1.162 - void allocated(HeapWord* blk, size_t size) { 1.163 - allocated(blk, blk + size); 1.164 + void allocated(HeapWord* blk, size_t size, bool reducing = false) { 1.165 + allocated(blk, blk + size, reducing); 1.166 } 1.167 1.168 void freed(HeapWord* blk_start, HeapWord* blk_end); 1.169 - void freed(HeapWord* blk, size_t size) { 1.170 - freed(blk, blk + size); 1.171 - } 1.172 + void freed(HeapWord* blk, size_t size); 1.173 1.174 HeapWord* block_start_unsafe(const void* addr) const; 1.175 1.176 @@ -456,7 +487,6 @@ 1.177 // start of the block that contains the given address. 1.178 HeapWord* block_start_careful(const void* addr) const; 1.179 1.180 - 1.181 // Verification & debugging: ensure that the offset table reflects 1.182 // the fact that the block [blk_start, blk_end) or [blk, blk + size) 1.183 // is a single block of storage. NOTE: can't const this because of