mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
Initial load
This commit is contained in:
parent
686d76f772
commit
8153779ad3
2894 changed files with 911801 additions and 0 deletions
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright 2001-2005 Sun Microsystems, Inc. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// This class can be used to locate the beginning of an object in the
|
||||
// covered region.
|
||||
//
|
||||
|
||||
class ObjectStartArray : public CHeapObj {
|
||||
friend class VerifyObjectStartArrayClosure;
|
||||
|
||||
private:
|
||||
PSVirtualSpace _virtual_space;
|
||||
MemRegion _reserved_region;
|
||||
MemRegion _covered_region;
|
||||
MemRegion _blocks_region;
|
||||
jbyte* _raw_base;
|
||||
jbyte* _offset_base;
|
||||
|
||||
public:
|
||||
|
||||
enum BlockValueConstants {
|
||||
clean_block = -1
|
||||
};
|
||||
|
||||
enum BlockSizeConstants {
|
||||
block_shift = 9,
|
||||
block_size = 1 << block_shift,
|
||||
block_size_in_words = block_size / sizeof(HeapWord)
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
// Mapping from address to object start array entry
|
||||
jbyte* block_for_addr(void* p) const {
|
||||
assert(_covered_region.contains(p),
|
||||
"out of bounds access to object start array");
|
||||
jbyte* result = &_offset_base[uintptr_t(p) >> block_shift];
|
||||
assert(_blocks_region.contains(result),
|
||||
"out of bounds result in byte_for");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Mapping from object start array entry to address of first word
|
||||
HeapWord* addr_for_block(jbyte* p) {
|
||||
assert(_blocks_region.contains(p),
|
||||
"out of bounds access to object start array");
|
||||
size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte));
|
||||
HeapWord* result = (HeapWord*) (delta << block_shift);
|
||||
assert(_covered_region.contains(result),
|
||||
"out of bounds accessor from card marking array");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Mapping that includes the derived offset.
|
||||
// If the block is clean, returns the last address in the covered region.
|
||||
// If the block is < index 0, returns the start of the covered region.
|
||||
HeapWord* offset_addr_for_block (jbyte* p) const {
|
||||
// We have to do this before the assert
|
||||
if (p < _raw_base) {
|
||||
return _covered_region.start();
|
||||
}
|
||||
|
||||
assert(_blocks_region.contains(p),
|
||||
"out of bounds access to object start array");
|
||||
|
||||
if (*p == clean_block) {
|
||||
return _covered_region.end();
|
||||
}
|
||||
|
||||
size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte));
|
||||
HeapWord* result = (HeapWord*) (delta << block_shift);
|
||||
result += *p;
|
||||
|
||||
assert(_covered_region.contains(result),
|
||||
"out of bounds accessor from card marking array");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// This method is in lieu of a constructor, so that this class can be
|
||||
// embedded inline in other classes.
|
||||
void initialize(MemRegion reserved_region);
|
||||
|
||||
void set_covered_region(MemRegion mr);
|
||||
|
||||
void reset();
|
||||
|
||||
MemRegion covered_region() { return _covered_region; }
|
||||
|
||||
void allocate_block(HeapWord* p) {
|
||||
assert(_covered_region.contains(p), "Must be in covered region");
|
||||
jbyte* block = block_for_addr(p);
|
||||
HeapWord* block_base = addr_for_block(block);
|
||||
size_t offset = pointer_delta(p, block_base, sizeof(HeapWord*));
|
||||
assert(offset < 128, "Sanity");
|
||||
// When doing MT offsets, we can't assert this.
|
||||
//assert(offset > *block, "Found backwards allocation");
|
||||
*block = (jbyte)offset;
|
||||
|
||||
// tty->print_cr("[%p]", p);
|
||||
}
|
||||
|
||||
// Optimized for finding the first object that crosses into
|
||||
// a given block. The blocks contain the offset of the last
|
||||
// object in that block. Scroll backwards by one, and the first
|
||||
// object hit should be at the begining of the block
|
||||
HeapWord* object_start(HeapWord* addr) const {
|
||||
assert(_covered_region.contains(addr), "Must be in covered region");
|
||||
jbyte* block = block_for_addr(addr);
|
||||
HeapWord* scroll_forward = offset_addr_for_block(block--);
|
||||
while (scroll_forward > addr) {
|
||||
scroll_forward = offset_addr_for_block(block--);
|
||||
}
|
||||
|
||||
HeapWord* next = scroll_forward;
|
||||
while (next <= addr) {
|
||||
scroll_forward = next;
|
||||
next += oop(next)->size();
|
||||
}
|
||||
assert(scroll_forward <= addr, "wrong order for current and arg");
|
||||
assert(addr <= next, "wrong order for arg and next");
|
||||
return scroll_forward;
|
||||
}
|
||||
|
||||
bool is_block_allocated(HeapWord* addr) {
|
||||
assert(_covered_region.contains(addr), "Must be in covered region");
|
||||
jbyte* block = block_for_addr(addr);
|
||||
if (*block == clean_block)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if an object starts in the range of heap addresses.
|
||||
// If an object starts at an address corresponding to
|
||||
// "start", the method will return true.
|
||||
bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue