/* Sun-$Revision: 23.4 $ */
/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
See the LICENSE file for license information. */
# pragma interface
// format:
// marked<1> age<7> hash<22> tag<2>
//
const fint marked_bits = 1;
const fint age_bits = 7;
const fint hash_bits = BitsPerWord - marked_bits - age_bits - Tag_Size;
const fint hash_shift = Tag_Size;
const fint age_shift = hash_bits + hash_shift;
const fint marked_shift = age_bits + age_shift;
# define DEFINE_MASKS(name) \
const int32 CONC(name,_mask) = nthMask(CONC(name,_bits)); \
const int32 CONC(name,_mask_in_place) = CONC(name,_mask) << CONC(name,_shift);
DEFINE_MASKS(hash)
DEFINE_MASKS(age)
DEFINE_MASKS(marked)
enum { no_hash = 0, first_hash = 1, second_hash = 2 };
const int32 no_hash_in_place = no_hash << hash_shift;
const int32 first_hash_in_place = first_hash << hash_shift;
const int32 second_hash_in_place = second_hash << hash_shift;
# define initial_markOop markOop(no_hash_in_place | Mark_Tag)
# define badOop markOop(first_hash_in_place | Mark_Tag)
// although this is a markOop, defining it as more general oop
// prevents compiler complaints about anOop == failedAllocationOop -- dmu
# define failedAllocationOop oop(second_hash_in_place | Mark_Tag)
const int32 overflow_hash_in_place = first_hash_in_place;
const int32 overflow_age_in_place = age_mask_in_place;
struct markOopClass: oopClass {
Map* map() { return Memory->mark_map; }
// accessors
# define BOOL_ACCESSOR(name) \
\
bool CONC3(is_,name,ed)() { \
return maskBits(int32(this), CONC(name,ed_mask_in_place)) != 0; } \
\
markOop name() { \
return markOop(int32(this) | CONC(name,ed_mask_in_place)); } \
\
markOop CONC(un,name)() { \
return markOop(int32(this) & ~CONC(name,ed_mask_in_place)); }
BOOL_ACCESSOR(mark)
# define VALUE_ACCESSOR(name, setAction, setAssert) \
\
int32 name() { \
return maskBits(int32(this), CONC(name,_mask_in_place)) \
>> CONC(name,_shift); } \
\
markOop CONC(set_,name)(int32 v) { \
setAction; \
markOop val = markOop((int32(this) & ~CONC(name,_mask_in_place)) | \
((v & CONC(name,_mask)) << CONC(name,_shift))); \
setAssert; \
return val; } \
\
int32 CONC(name,_in_place)() { \
return maskBits(int32(this), CONC(name,_mask_in_place)); } \
\
markOop CONC3(set_,name,_in_place)(int32 v) { \
assert((v & ~CONC(name,_mask_in_place)) == 0, \
"shouldn't overflow field"); \
return markOop((int32(this) & ~CONC(name,_mask_in_place)) | v); } \
\
markOop CONC(incr_,name)() { \
int32 n = CONC(name,_in_place)(); \
if (n == CONC(name,_mask_in_place)) { \
n = CONC3(overflow_,name,_in_place); \
} else { \
n += (1 << CONC(name,_shift)); \
} \
return CONC3(set_,name,_in_place)(n); } \
\
friend int32 CONC(max_,name)() { return CONC(name,_mask); }
VALUE_ACCESSOR(hash,
if ((v & hash_mask) == 0) v += first_hash;/* avoid no_hash */,
assert(val->hash() != no_hash, "should have hash now"));
VALUE_ACCESSOR(age, , );
friend int32 assign_hash(markOop& m);
friend int32 hash_markOop(markOop& m) {
int32 h = m->hash();
return h == no_hash ? assign_hash(m) : h; }
smi identity_hash() { return hash(); }
void print_oop() { lprintf("Mark#0x%lx", (void*)(long) this); }
void print();
};