markOop.hpp revision 187:790e66e5fbac
190075Sobrien/* 290075Sobrien * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. 390075Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 490075Sobrien * 590075Sobrien * This code is free software; you can redistribute it and/or modify it 690075Sobrien * under the terms of the GNU General Public License version 2 only, as 790075Sobrien * published by the Free Software Foundation. 890075Sobrien * 990075Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 1090075Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1190075Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1290075Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1390075Sobrien * accompanied this code). 1490075Sobrien * 1590075Sobrien * You should have received a copy of the GNU General Public License version 1690075Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 1790075Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1890075Sobrien * 1990075Sobrien * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 2090075Sobrien * CA 95054 USA or visit www.sun.com if you need additional information or 2190075Sobrien * have any questions. 2290075Sobrien * 2390075Sobrien */ 2490075Sobrien 2590075Sobrien// The markOop describes the header of an object. 2690075Sobrien// 2790075Sobrien// Note that the mark is not a real oop but just a word. 2890075Sobrien// It is placed in the oop hierarchy for historical reasons. 2990075Sobrien// 3090075Sobrien// Bit-format of an object header (most significant first): 3190075Sobrien// 3290075Sobrien// 32 bits: unused:0 hash:25 age:4 biased_lock:1 lock:2 3390075Sobrien// 64 bits: unused:24 hash:31 cms:2 age:4 biased_lock:1 lock:2 3490075Sobrien// unused:20 size:35 cms:2 age:4 biased_lock:1 lock:2 (if cms 3590075Sobrien// free chunk) 3690075Sobrien// 3790075Sobrien// - hash contains the identity hash value: largest value is 3890075Sobrien// 31 bits, see os::random(). Also, 64-bit vm's require 3990075Sobrien// a hash value no bigger than 32 bits because they will not 4090075Sobrien// properly generate a mask larger than that: see library_call.cpp 4190075Sobrien// and c1_CodePatterns_sparc.cpp. 4290075Sobrien// 4390075Sobrien// - the biased lock pattern is used to bias a lock toward a given 4490075Sobrien// thread. When this pattern is set in the low three bits, the lock 4590075Sobrien// is either biased toward a given thread or "anonymously" biased, 4690075Sobrien// indicating that it is possible for it to be biased. When the 4790075Sobrien// lock is biased toward a given thread, locking and unlocking can 4890075Sobrien// be performed by that thread without using atomic operations. 4990075Sobrien// When a lock's bias is revoked, it reverts back to the normal 5090075Sobrien// locking scheme described below. 5190075Sobrien// 5290075Sobrien// Note that we are overloading the meaning of the "unlocked" state 5390075Sobrien// of the header. Because we steal a bit from the age we can 5490075Sobrien// guarantee that the bias pattern will never be seen for a truly 5590075Sobrien// unlocked object. 5690075Sobrien// 5790075Sobrien// Note also that the biased state contains the age bits normally 5890075Sobrien// contained in the object header. Large increases in scavenge 5990075Sobrien// times were seen when these bits were absent and an arbitrary age 6090075Sobrien// assigned to all biased objects, because they tended to consume a 6190075Sobrien// significant fraction of the eden semispaces and were not 6290075Sobrien// promoted promptly, causing an increase in the amount of copying 6390075Sobrien// performed. The runtime system aligns all JavaThread* pointers to 6490075Sobrien// a very large value (currently 128 bytes) to make room for the 6590075Sobrien// age bits when biased locking is enabled. 6690075Sobrien// 6790075Sobrien// [JavaThread* | epoch | age | 1 | 01] lock is biased toward given thread 6890075Sobrien// [0 | epoch | age | 1 | 01] lock is anonymously biased 6990075Sobrien// 7090075Sobrien// - the two lock bits are used to describe three states: locked/unlocked and monitor. 7190075Sobrien// 7290075Sobrien// [ptr | 00] locked ptr points to real header on stack 7390075Sobrien// [header | 0 | 01] unlocked regular object header 7490075Sobrien// [ptr | 10] monitor inflated lock (header is wapped out) 7590075Sobrien// [ptr | 11] marked used by markSweep to mark an object 7690075Sobrien// not valid at any other time 7790075Sobrien// 7890075Sobrien// We assume that stack/thread pointers have the lowest two bits cleared. 7990075Sobrien 8090075Sobrienclass BasicLock; 8190075Sobrienclass ObjectMonitor; 8290075Sobrienclass JavaThread; 8390075Sobrien 8490075Sobrienclass markOopDesc: public oopDesc { 8590075Sobrien private: 8690075Sobrien // Conversion 8790075Sobrien uintptr_t value() const { return (uintptr_t) this; } 8890075Sobrien 8990075Sobrien public: 9090075Sobrien // Constants 9190075Sobrien enum { age_bits = 4, 9290075Sobrien lock_bits = 2, 9390075Sobrien biased_lock_bits = 1, 9490075Sobrien max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits, 9590075Sobrien hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits, 9690075Sobrien cms_bits = LP64_ONLY(1) NOT_LP64(0), 9790075Sobrien epoch_bits = 2 9890075Sobrien }; 9990075Sobrien 10090075Sobrien // The biased locking code currently requires that the age bits be 10190075Sobrien // contiguous to the lock bits. Class data sharing would prefer the 10290075Sobrien // hash bits to be lower down to provide more random hash codes for 10390075Sobrien // shared read-only symbolOop objects, because these objects' mark 10490075Sobrien // words are set to their own address with marked_value in the lock 10590075Sobrien // bit, and using lower bits would make their identity hash values 10690075Sobrien // more random. However, the performance decision was made in favor 10790075Sobrien // of the biased locking code. 10890075Sobrien 10990075Sobrien enum { lock_shift = 0, 11090075Sobrien biased_lock_shift = lock_bits, 11190075Sobrien age_shift = lock_bits + biased_lock_bits, 11290075Sobrien cms_shift = age_shift + age_bits, 11390075Sobrien hash_shift = cms_shift + cms_bits, 11490075Sobrien epoch_shift = hash_shift 11590075Sobrien }; 11690075Sobrien 11790075Sobrien enum { lock_mask = right_n_bits(lock_bits), 11890075Sobrien lock_mask_in_place = lock_mask << lock_shift, 11990075Sobrien biased_lock_mask = right_n_bits(lock_bits + biased_lock_bits), 12090075Sobrien biased_lock_mask_in_place= biased_lock_mask << lock_shift, 12190075Sobrien biased_lock_bit_in_place = 1 << biased_lock_shift, 12290075Sobrien age_mask = right_n_bits(age_bits), 12390075Sobrien age_mask_in_place = age_mask << age_shift, 12490075Sobrien epoch_mask = right_n_bits(epoch_bits), 12590075Sobrien epoch_mask_in_place = epoch_mask << epoch_shift, 12690075Sobrien cms_mask = right_n_bits(cms_bits), 12790075Sobrien cms_mask_in_place = cms_mask << cms_shift 12890075Sobrien#ifndef _WIN64 12990075Sobrien ,hash_mask = right_n_bits(hash_bits), 13090075Sobrien hash_mask_in_place = (address_word)hash_mask << hash_shift 13190075Sobrien#endif 13290075Sobrien }; 13390075Sobrien 13490075Sobrien // Alignment of JavaThread pointers encoded in object header required by biased locking 13590075Sobrien enum { biased_lock_alignment = 2 << (epoch_shift + epoch_bits) 13690075Sobrien }; 13790075Sobrien 13890075Sobrien#ifdef _WIN64 13990075Sobrien // These values are too big for Win64 14090075Sobrien const static uintptr_t hash_mask = right_n_bits(hash_bits); 14190075Sobrien const static uintptr_t hash_mask_in_place = 14290075Sobrien (address_word)hash_mask << hash_shift; 14390075Sobrien#endif 14490075Sobrien 14590075Sobrien enum { locked_value = 0, 14690075Sobrien unlocked_value = 1, 14790075Sobrien monitor_value = 2, 14890075Sobrien marked_value = 3, 14990075Sobrien biased_lock_pattern = 5 15090075Sobrien }; 15190075Sobrien 15290075Sobrien enum { no_hash = 0 }; // no hash value assigned 15390075Sobrien 15490075Sobrien enum { no_hash_in_place = (address_word)no_hash << hash_shift, 15590075Sobrien no_lock_in_place = unlocked_value 15690075Sobrien }; 15790075Sobrien 15890075Sobrien enum { max_age = age_mask }; 15990075Sobrien 16090075Sobrien enum { max_bias_epoch = epoch_mask }; 16190075Sobrien 16290075Sobrien // Biased Locking accessors. 16390075Sobrien // These must be checked by all code which calls into the 16490075Sobrien // ObjectSynchronizer and other code. The biasing is not understood 16590075Sobrien // by the lower-level CAS-based locking code, although the runtime 16690075Sobrien // fixes up biased locks to be compatible with it when a bias is 16790075Sobrien // revoked. 16890075Sobrien bool has_bias_pattern() const { 16990075Sobrien return (mask_bits(value(), biased_lock_mask_in_place) == biased_lock_pattern); 17090075Sobrien } 17190075Sobrien JavaThread* biased_locker() const { 17290075Sobrien assert(has_bias_pattern(), "should not call this otherwise"); 17390075Sobrien return (JavaThread*) ((intptr_t) (mask_bits(value(), ~(biased_lock_mask_in_place | age_mask_in_place | epoch_mask_in_place)))); 17490075Sobrien } 17590075Sobrien // Indicates that the mark has the bias bit set but that it has not 17690075Sobrien // yet been biased toward a particular thread 17790075Sobrien bool is_biased_anonymously() const { 17890075Sobrien return (has_bias_pattern() && (biased_locker() == NULL)); 17990075Sobrien } 18090075Sobrien // Indicates epoch in which this bias was acquired. If the epoch 18190075Sobrien // changes due to too many bias revocations occurring, the biases 18290075Sobrien // from the previous epochs are all considered invalid. 18390075Sobrien int bias_epoch() const { 18490075Sobrien assert(has_bias_pattern(), "should not call this otherwise"); 18590075Sobrien return (mask_bits(value(), epoch_mask_in_place) >> epoch_shift); 18690075Sobrien } 18790075Sobrien markOop set_bias_epoch(int epoch) { 18890075Sobrien assert(has_bias_pattern(), "should not call this otherwise"); 18990075Sobrien assert((epoch & (~epoch_mask)) == 0, "epoch overflow"); 19090075Sobrien return markOop(mask_bits(value(), ~epoch_mask_in_place) | (epoch << epoch_shift)); 19190075Sobrien } 19290075Sobrien markOop incr_bias_epoch() { 19390075Sobrien return set_bias_epoch((1 + bias_epoch()) & epoch_mask); 19490075Sobrien } 19590075Sobrien // Prototype mark for initialization 19690075Sobrien static markOop biased_locking_prototype() { 19790075Sobrien return markOop( biased_lock_pattern ); 19890075Sobrien } 19990075Sobrien 20090075Sobrien // lock accessors (note that these assume lock_shift == 0) 20190075Sobrien bool is_locked() const { 20290075Sobrien return (mask_bits(value(), lock_mask_in_place) != unlocked_value); 20390075Sobrien } 20490075Sobrien bool is_unlocked() const { 20590075Sobrien return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); 20690075Sobrien } 20790075Sobrien bool is_marked() const { 20890075Sobrien return (mask_bits(value(), lock_mask_in_place) == marked_value); 20990075Sobrien } 21090075Sobrien bool is_neutral() const { return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); } 21190075Sobrien 21290075Sobrien // Special temporary state of the markOop while being inflated. 21390075Sobrien // Code that looks at mark outside a lock need to take this into account. 21490075Sobrien bool is_being_inflated() const { return (value() == 0); } 21590075Sobrien 21690075Sobrien // Distinguished markword value - used when inflating over 21790075Sobrien // an existing stacklock. 0 indicates the markword is "BUSY". 21890075Sobrien // Lockword mutators that use a LD...CAS idiom should always 21990075Sobrien // check for and avoid overwriting a 0 value installed by some 22090075Sobrien // other thread. (They should spin or block instead. The 0 value 22190075Sobrien // is transient and *should* be short-lived). 22290075Sobrien static markOop INFLATING() { return (markOop) 0; } // inflate-in-progress 22390075Sobrien 22490075Sobrien // Should this header be preserved during GC? 22590075Sobrien bool must_be_preserved(oop obj_containing_mark) const { 22690075Sobrien if (!UseBiasedLocking) 22790075Sobrien return (!is_unlocked() || !has_no_hash()); 22890075Sobrien return must_be_preserved_with_bias(obj_containing_mark); 22990075Sobrien } 23090075Sobrien inline bool must_be_preserved_with_bias(oop obj_containing_mark) const; 23190075Sobrien 23290075Sobrien // Should this header (including its age bits) be preserved in the 23390075Sobrien // case of a promotion failure during scavenge? 23490075Sobrien // Note that we special case this situation. We want to avoid 23590075Sobrien // calling BiasedLocking::preserve_marks()/restore_marks() (which 23690075Sobrien // decrease the number of mark words that need to be preserved 23790075Sobrien // during GC) during each scavenge. During scavenges in which there 23890075Sobrien // is no promotion failure, we actually don't need to call the above 23990075Sobrien // routines at all, since we don't mutate and re-initialize the 24090075Sobrien // marks of promoted objects using init_mark(). However, during 24190075Sobrien // scavenges which result in promotion failure, we do re-initialize 24290075Sobrien // the mark words of objects, meaning that we should have called 24390075Sobrien // these mark word preservation routines. Currently there's no good 24490075Sobrien // place in which to call them in any of the scavengers (although 24590075Sobrien // guarded by appropriate locks we could make one), but the 24690075Sobrien // observation is that promotion failures are quite rare and 24790075Sobrien // reducing the number of mark words preserved during them isn't a 24890075Sobrien // high priority. 24990075Sobrien bool must_be_preserved_for_promotion_failure(oop obj_containing_mark) const { 25090075Sobrien if (!UseBiasedLocking) 25190075Sobrien return (this != prototype()); 25290075Sobrien return must_be_preserved_with_bias_for_promotion_failure(obj_containing_mark); 25390075Sobrien } 25490075Sobrien inline bool must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const; 25590075Sobrien 25690075Sobrien // Should this header be preserved during a scavenge where CMS is 25790075Sobrien // the old generation? 25890075Sobrien // (This is basically the same body as must_be_preserved_for_promotion_failure(), 25990075Sobrien // but takes the klassOop as argument instead) 26090075Sobrien bool must_be_preserved_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const { 26190075Sobrien if (!UseBiasedLocking) 26290075Sobrien return (this != prototype()); 26390075Sobrien return must_be_preserved_with_bias_for_cms_scavenge(klass_of_obj_containing_mark); 26490075Sobrien } 26590075Sobrien inline bool must_be_preserved_with_bias_for_cms_scavenge(klassOop klass_of_obj_containing_mark) const; 26690075Sobrien 26790075Sobrien // WARNING: The following routines are used EXCLUSIVELY by 26890075Sobrien // synchronization functions. They are not really gc safe. 26990075Sobrien // They must get updated if markOop layout get changed. 27090075Sobrien markOop set_unlocked() const { 27190075Sobrien return markOop(value() | unlocked_value); 27290075Sobrien } 27390075Sobrien bool has_locker() const { 27490075Sobrien return ((value() & lock_mask_in_place) == locked_value); 27590075Sobrien } 27690075Sobrien BasicLock* locker() const { 27790075Sobrien assert(has_locker(), "check"); 27890075Sobrien return (BasicLock*) value(); 27990075Sobrien } 28090075Sobrien bool has_monitor() const { 28190075Sobrien return ((value() & monitor_value) != 0); 28290075Sobrien } 28390075Sobrien ObjectMonitor* monitor() const { 28490075Sobrien assert(has_monitor(), "check"); 28590075Sobrien // Use xor instead of &~ to provide one extra tag-bit check. 28690075Sobrien return (ObjectMonitor*) (value() ^ monitor_value); 28790075Sobrien } 28890075Sobrien bool has_displaced_mark_helper() const { 28990075Sobrien return ((value() & unlocked_value) == 0); 29090075Sobrien } 29190075Sobrien markOop displaced_mark_helper() const { 29290075Sobrien assert(has_displaced_mark_helper(), "check"); 29390075Sobrien intptr_t ptr = (value() & ~monitor_value); 29490075Sobrien return *(markOop*)ptr; 29590075Sobrien } 29690075Sobrien void set_displaced_mark_helper(markOop m) const { 29790075Sobrien assert(has_displaced_mark_helper(), "check"); 29890075Sobrien intptr_t ptr = (value() & ~monitor_value); 29990075Sobrien *(markOop*)ptr = m; 30090075Sobrien } 30190075Sobrien markOop copy_set_hash(intptr_t hash) const { 30290075Sobrien intptr_t tmp = value() & (~hash_mask_in_place); 30390075Sobrien tmp |= ((hash & hash_mask) << hash_shift); 30490075Sobrien return (markOop)tmp; 30590075Sobrien } 30690075Sobrien // it is only used to be stored into BasicLock as the 30790075Sobrien // indicator that the lock is using heavyweight monitor 30890075Sobrien static markOop unused_mark() { 30990075Sobrien return (markOop) marked_value; 31090075Sobrien } 31190075Sobrien // the following two functions create the markOop to be 31290075Sobrien // stored into object header, it encodes monitor info 31390075Sobrien static markOop encode(BasicLock* lock) { 31490075Sobrien return (markOop) lock; 31590075Sobrien } 31690075Sobrien static markOop encode(ObjectMonitor* monitor) { 31790075Sobrien intptr_t tmp = (intptr_t) monitor; 31890075Sobrien return (markOop) (tmp | monitor_value); 31990075Sobrien } 32090075Sobrien static markOop encode(JavaThread* thread, int age, int bias_epoch) { 32190075Sobrien intptr_t tmp = (intptr_t) thread; 32290075Sobrien assert(UseBiasedLocking && ((tmp & (epoch_mask_in_place | age_mask_in_place | biased_lock_mask_in_place)) == 0), "misaligned JavaThread pointer"); 32390075Sobrien assert(age <= max_age, "age too large"); 32490075Sobrien assert(bias_epoch <= max_bias_epoch, "bias epoch too large"); 32590075Sobrien return (markOop) (tmp | (bias_epoch << epoch_shift) | (age << age_shift) | biased_lock_pattern); 32690075Sobrien } 32790075Sobrien 32890075Sobrien // used to encode pointers during GC 32990075Sobrien markOop clear_lock_bits() { return markOop(value() & ~lock_mask_in_place); } 33090075Sobrien 33190075Sobrien // age operations 33290075Sobrien markOop set_marked() { return markOop((value() & ~lock_mask_in_place) | marked_value); } 33390075Sobrien 33490075Sobrien int age() const { return mask_bits(value() >> age_shift, age_mask); } 33590075Sobrien markOop set_age(int v) const { 33690075Sobrien assert((v & ~age_mask) == 0, "shouldn't overflow age field"); 33790075Sobrien return markOop((value() & ~age_mask_in_place) | (((intptr_t)v & age_mask) << age_shift)); 33890075Sobrien } 33990075Sobrien markOop incr_age() const { return age() == max_age ? markOop(this) : set_age(age() + 1); } 34090075Sobrien 34190075Sobrien // hash operations 34290075Sobrien intptr_t hash() const { 34390075Sobrien return mask_bits(value() >> hash_shift, hash_mask); 34490075Sobrien } 34590075Sobrien 34690075Sobrien bool has_no_hash() const { 34790075Sobrien return hash() == no_hash; 34890075Sobrien } 34990075Sobrien 35090075Sobrien // Prototype mark for initialization 35190075Sobrien static markOop prototype() { 35290075Sobrien return markOop( no_hash_in_place | no_lock_in_place ); 35390075Sobrien } 35490075Sobrien 35590075Sobrien // Helper function for restoration of unmarked mark oops during GC 35690075Sobrien static inline markOop prototype_for_object(oop obj); 35790075Sobrien 35890075Sobrien // Debugging 35990075Sobrien void print_on(outputStream* st) const; 36090075Sobrien 36190075Sobrien // Prepare address of oop for placement into mark 36290075Sobrien inline static markOop encode_pointer_as_mark(void* p) { return markOop(p)->set_marked(); } 36390075Sobrien 36490075Sobrien // Recover address of oop from encoded form used in mark 36590075Sobrien inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); } 36690075Sobrien 36790075Sobrien // see the definition in markOop.cpp for the gory details 36890075Sobrien bool should_not_be_cached() const; 36990075Sobrien 37090075Sobrien // These markOops indicate cms free chunk blocks and not objects. 37190075Sobrien // In 64 bit, the markOop is set to distinguish them from oops. 37290075Sobrien // These are defined in 32 bit mode for vmStructs. 37390075Sobrien const static uintptr_t cms_free_chunk_pattern = 0x1; 37490075Sobrien 37590075Sobrien // Constants for the size field. 37690075Sobrien enum { size_shift = cms_shift + cms_bits, 37790075Sobrien size_bits = 35 // need for compressed oops 32G 37890075Sobrien }; 37990075Sobrien // These values are too big for Win64 38090075Sobrien const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits)) 38190075Sobrien NOT_LP64(0); 38290075Sobrien const static uintptr_t size_mask_in_place = 38390075Sobrien (address_word)size_mask << size_shift; 38490075Sobrien 38590075Sobrien#ifdef _LP64 38690075Sobrien static markOop cms_free_prototype() { 38790075Sobrien return markOop(((intptr_t)prototype() & ~cms_mask_in_place) | 38890075Sobrien ((cms_free_chunk_pattern & cms_mask) << cms_shift)); 38990075Sobrien } 39090075Sobrien uintptr_t cms_encoding() const { 39190075Sobrien return mask_bits(value() >> cms_shift, cms_mask); 39290075Sobrien } 39390075Sobrien bool is_cms_free_chunk() const { 39490075Sobrien return is_neutral() && 39590075Sobrien (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern; 39690075Sobrien } 39790075Sobrien 39890075Sobrien size_t get_size() const { return (size_t)(value() >> size_shift); } 39990075Sobrien static markOop set_size_and_free(size_t size) { 40090075Sobrien assert((size & ~size_mask) == 0, "shouldn't overflow size field"); 40190075Sobrien return markOop(((intptr_t)cms_free_prototype() & ~size_mask_in_place) | 40290075Sobrien (((intptr_t)size & size_mask) << size_shift)); 40390075Sobrien } 40490075Sobrien#endif // _LP64 40590075Sobrien}; 40690075Sobrien