00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 class markOopDesc: public oopDesc {
00040 private:
00041 unsigned int value() const { return (unsigned int) this; }
00042 friend int assign_hash(markOop& m);
00043
00044 enum { no_hash = 0,
00045 first_hash = 1};
00046
00047 enum { sentinel_bits = 1,
00048 near_death_bits = 1,
00049 tagged_contents_bits = 1,
00050 age_bits = 7,
00051 hash_bits = BitsPerWord - sentinel_bits - near_death_bits - tagged_contents_bits - age_bits - Tag_Size };
00052
00053 enum { hash_shift = Tag_Size,
00054 age_shift = hash_bits + hash_shift,
00055 tagged_contents_shift = age_bits + age_shift,
00056 near_death_shift = tagged_contents_bits + tagged_contents_shift,
00057 sentinel_shift = near_death_bits + near_death_shift };
00058
00059 enum { hash_mask = nthMask(hash_bits),
00060 hash_mask_in_place = hash_mask << hash_shift,
00061 age_mask = nthMask(age_bits),
00062 age_mask_in_place = age_mask << age_shift,
00063 tagged_contents_mask = nthMask(tagged_contents_bits),
00064 tagged_contents_mask_in_place = tagged_contents_mask << tagged_contents_shift,
00065 near_death_mask = nthMask(near_death_bits),
00066 near_death_mask_in_place = near_death_mask << near_death_shift,
00067 sentinel_mask = nthMask(sentinel_bits),
00068 sentinel_mask_in_place = sentinel_mask << sentinel_shift };
00069
00070
00071 enum { no_hash_in_place = no_hash << hash_shift,
00072 first_hash_in_place = first_hash << hash_shift,
00073 untagged_contents_in_place = 1 << tagged_contents_shift };
00074
00075 enum { sentinel_is_place = 1 << sentinel_shift } ;
00076 public:
00077 enum { max_age = age_mask };
00078
00079 bool has_sentinel() const { return maskBits(value(), sentinel_mask_in_place) != 0; }
00080 markOop set_sentinel() const { return markOop( sentinel_is_place | value()); }
00081 markOop clear_sentinel() const { return markOop(~sentinel_is_place & value()); }
00082
00083 bool has_tagged_contents() const { return maskBits(value(), tagged_contents_mask_in_place) != 0; }
00084
00085 bool is_near_death() const { return maskBits(value(), near_death_mask_in_place) != 0; }
00086 markOop set_near_death() const { return markOop( near_death_mask_in_place | value()); }
00087 markOop clear_near_death() const { return markOop(~near_death_mask_in_place & value()); }
00088
00089
00090 bool is_klass_invalid() const { return !has_sentinel(); }
00091 markOop set_klass_invalid() const { return clear_sentinel(); }
00092 markOop clear_klass_invalid() const { return set_sentinel(); }
00093
00094
00095 static int context_forward_bit_mask() { return near_death_mask_in_place; }
00096 bool has_context_forward() const { return is_near_death(); }
00097 markOop set_context_forward() const { return set_near_death(); }
00098
00099
00100 bool is_queued() const { return !has_sentinel(); }
00101 markOop set_queued() const { return clear_sentinel(); }
00102 markOop clear_queued() const { return set_sentinel(); }
00103
00104
00105 int age() const { return maskBits(value(), age_mask_in_place) >> age_shift; }
00106 markOop set_age(int v) const {
00107 assert((v & ~age_mask) == 0, "shouldn't overflow field");
00108 return markOop((value() & ~age_mask_in_place) | ((v & age_mask) << age_shift));
00109 }
00110 markOop incr_age() const { return age() == max_age ? markOop(this) : set_age(age() + 1); }
00111
00112
00113 int hash() const { return maskBits(value(), hash_mask_in_place) >> hash_shift; }
00114 markOop set_hash(int v) const {
00115 if ((v & hash_mask) == 0) v = first_hash;
00116 markOop val = markOop((value() & ~hash_mask_in_place) | ((v & hash_mask) << hash_shift));
00117 assert(val->hash() != no_hash, "should have hash now");
00118 return val;
00119 }
00120 bool has_valid_hash() const { return hash() != no_hash; }
00121
00122
00123 static markOop tagged_prototype() {
00124 return markOop(sentinel_is_place | no_hash_in_place | Mark_Tag);
00125 }
00126 static markOop untagged_prototype() {
00127 return markOop(sentinel_is_place | untagged_contents_in_place | no_hash_in_place | Mark_Tag);
00128 }
00129
00130
00131 static markOop bad() {
00132 return markOop(sentinel_is_place | first_hash_in_place | Mark_Tag);
00133 }
00134
00135 friend int hash_markOop(markOop& m) {
00136 int v = m->hash();
00137 return v == no_hash ? assign_hash(m) : v;
00138 }
00139
00140
00141 void print_on(outputStream* st);
00142
00143 static int masked_hash(int v) { return v & hash_mask; }
00144 };
00145
00146 # define badOop markOopDesc::bad()
00147
00148
00149
00150 inline bool is_oop_root(oop* p) { return !markOop(p)->has_sentinel(); }