Mercurial > hg > graal-jvmci-8
comparison src/share/vm/oops/markOop.hpp @ 187:790e66e5fbac
6687581: Make CMS work with compressed oops
Summary: Make FreeChunk read markword instead of LSB in _klass pointer to indicate that it's a FreeChunk for compressed oops.
Reviewed-by: ysr, jmasa
author | coleenp |
---|---|
date | Mon, 09 Jun 2008 11:51:19 -0400 |
parents | ba764ed4b6f2 |
children | d1605aabd0a1 6aae2f9d0294 |
comparison
equal
deleted
inserted
replaced
185:8759d37f2524 | 187:790e66e5fbac |
---|---|
27 // Note that the mark is not a real oop but just a word. | 27 // Note that the mark is not a real oop but just a word. |
28 // It is placed in the oop hierarchy for historical reasons. | 28 // It is placed in the oop hierarchy for historical reasons. |
29 // | 29 // |
30 // Bit-format of an object header (most significant first): | 30 // Bit-format of an object header (most significant first): |
31 // | 31 // |
32 // | 32 // 32 bits: unused:0 hash:25 age:4 biased_lock:1 lock:2 |
33 // unused:0/25 hash:25/31 age:4 biased_lock:1 lock:2 = 32/64 bits | 33 // 64 bits: unused:24 hash:31 cms:2 age:4 biased_lock:1 lock:2 |
34 // unused:20 size:35 cms:2 age:4 biased_lock:1 lock:2 (if cms | |
35 // free chunk) | |
34 // | 36 // |
35 // - hash contains the identity hash value: largest value is | 37 // - hash contains the identity hash value: largest value is |
36 // 31 bits, see os::random(). Also, 64-bit vm's require | 38 // 31 bits, see os::random(). Also, 64-bit vm's require |
37 // a hash value no bigger than 32 bits because they will not | 39 // a hash value no bigger than 32 bits because they will not |
38 // properly generate a mask larger than that: see library_call.cpp | 40 // properly generate a mask larger than that: see library_call.cpp |
89 enum { age_bits = 4, | 91 enum { age_bits = 4, |
90 lock_bits = 2, | 92 lock_bits = 2, |
91 biased_lock_bits = 1, | 93 biased_lock_bits = 1, |
92 max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits, | 94 max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits, |
93 hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits, | 95 hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits, |
96 cms_bits = LP64_ONLY(1) NOT_LP64(0), | |
94 epoch_bits = 2 | 97 epoch_bits = 2 |
95 }; | 98 }; |
96 | 99 |
97 // The biased locking code currently requires that the age bits be | 100 // The biased locking code currently requires that the age bits be |
98 // contiguous to the lock bits. Class data sharing would prefer the | 101 // contiguous to the lock bits. Class data sharing would prefer the |
104 // of the biased locking code. | 107 // of the biased locking code. |
105 | 108 |
106 enum { lock_shift = 0, | 109 enum { lock_shift = 0, |
107 biased_lock_shift = lock_bits, | 110 biased_lock_shift = lock_bits, |
108 age_shift = lock_bits + biased_lock_bits, | 111 age_shift = lock_bits + biased_lock_bits, |
109 hash_shift = lock_bits + biased_lock_bits + age_bits, | 112 cms_shift = age_shift + age_bits, |
113 hash_shift = cms_shift + cms_bits, | |
110 epoch_shift = hash_shift | 114 epoch_shift = hash_shift |
111 }; | 115 }; |
112 | 116 |
113 enum { lock_mask = right_n_bits(lock_bits), | 117 enum { lock_mask = right_n_bits(lock_bits), |
114 lock_mask_in_place = lock_mask << lock_shift, | 118 lock_mask_in_place = lock_mask << lock_shift, |
116 biased_lock_mask_in_place= biased_lock_mask << lock_shift, | 120 biased_lock_mask_in_place= biased_lock_mask << lock_shift, |
117 biased_lock_bit_in_place = 1 << biased_lock_shift, | 121 biased_lock_bit_in_place = 1 << biased_lock_shift, |
118 age_mask = right_n_bits(age_bits), | 122 age_mask = right_n_bits(age_bits), |
119 age_mask_in_place = age_mask << age_shift, | 123 age_mask_in_place = age_mask << age_shift, |
120 epoch_mask = right_n_bits(epoch_bits), | 124 epoch_mask = right_n_bits(epoch_bits), |
121 epoch_mask_in_place = epoch_mask << epoch_shift | 125 epoch_mask_in_place = epoch_mask << epoch_shift, |
126 cms_mask = right_n_bits(cms_bits), | |
127 cms_mask_in_place = cms_mask << cms_shift | |
122 #ifndef _WIN64 | 128 #ifndef _WIN64 |
123 ,hash_mask = right_n_bits(hash_bits), | 129 ,hash_mask = right_n_bits(hash_bits), |
124 hash_mask_in_place = (address_word)hash_mask << hash_shift | 130 hash_mask_in_place = (address_word)hash_mask << hash_shift |
125 #endif | 131 #endif |
126 }; | 132 }; |
358 // Recover address of oop from encoded form used in mark | 364 // Recover address of oop from encoded form used in mark |
359 inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); } | 365 inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); } |
360 | 366 |
361 // see the definition in markOop.cpp for the gory details | 367 // see the definition in markOop.cpp for the gory details |
362 bool should_not_be_cached() const; | 368 bool should_not_be_cached() const; |
369 | |
370 // These markOops indicate cms free chunk blocks and not objects. | |
371 // In 64 bit, the markOop is set to distinguish them from oops. | |
372 // These are defined in 32 bit mode for vmStructs. | |
373 const static uintptr_t cms_free_chunk_pattern = 0x1; | |
374 | |
375 // Constants for the size field. | |
376 enum { size_shift = cms_shift + cms_bits, | |
377 size_bits = 35 // need for compressed oops 32G | |
378 }; | |
379 // These values are too big for Win64 | |
380 const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits)) | |
381 NOT_LP64(0); | |
382 const static uintptr_t size_mask_in_place = | |
383 (address_word)size_mask << size_shift; | |
384 | |
385 #ifdef _LP64 | |
386 static markOop cms_free_prototype() { | |
387 return markOop(((intptr_t)prototype() & ~cms_mask_in_place) | | |
388 ((cms_free_chunk_pattern & cms_mask) << cms_shift)); | |
389 } | |
390 uintptr_t cms_encoding() const { | |
391 return mask_bits(value() >> cms_shift, cms_mask); | |
392 } | |
393 bool is_cms_free_chunk() const { | |
394 return is_neutral() && | |
395 (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern; | |
396 } | |
397 | |
398 size_t get_size() const { return (size_t)(value() >> size_shift); } | |
399 static markOop set_size_and_free(size_t size) { | |
400 assert((size & ~size_mask) == 0, "shouldn't overflow size field"); | |
401 return markOop(((intptr_t)cms_free_prototype() & ~size_mask_in_place) | | |
402 (((intptr_t)size & size_mask) << size_shift)); | |
403 } | |
404 #endif // _LP64 | |
363 }; | 405 }; |