src/share/vm/oops/oop.inline.hpp

Print this page
rev 3688 : 7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by:


 168 inline address*  oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); }
 169 
 170 
 171 // Functions for getting and setting oops within instance objects.
 172 // If the oops are compressed, the type passed to these overloaded functions
 173 // is narrowOop.  All functions are overloaded so they can be called by
 174 // template functions without conditionals (the compiler instantiates via
 175 // the right type and inlines the appopriate code).
 176 
 177 inline bool oopDesc::is_null(oop obj)       { return obj == NULL; }
 178 inline bool oopDesc::is_null(Klass* obj)  { return obj == NULL; }
 179 inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
 180 
 181 // Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit
 182 // offset from the heap base.  Saving the check for null can save instructions
 183 // in inner GC loops so these are separated.
 184 
 185 inline bool check_obj_alignment(oop obj) {
 186   return (intptr_t)obj % MinObjAlignmentInBytes == 0;
 187 }
 188 inline bool check_obj_alignment(Klass* obj) {
 189   return (intptr_t)obj % MinObjAlignmentInBytes == 0;
 190 }
 191 
 192 inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
 193   assert(!is_null(v), "oop value can never be zero");
 194   assert(check_obj_alignment(v), "Address not aligned");
 195   assert(Universe::heap()->is_in_reserved(v), "Address not in heap");
 196   address base = Universe::narrow_oop_base();
 197   int    shift = Universe::narrow_oop_shift();
 198   uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
 199   assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
 200   uint64_t result = pd >> shift;
 201   assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow");
 202   assert(decode_heap_oop(result) == v, "reversibility");
 203   return (narrowOop)result;
 204 }
 205 
 206 inline narrowOop oopDesc::encode_heap_oop(oop v) {
 207   return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
 208 }
 209 


 211   assert(!is_null(v), "narrow oop value can never be zero");
 212   address base = Universe::narrow_oop_base();
 213   int    shift = Universe::narrow_oop_shift();
 214   oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
 215   assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
 216   return result;
 217 }
 218 
 219 inline oop oopDesc::decode_heap_oop(narrowOop v) {
 220   return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v);
 221 }
 222 
 223 inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; }
 224 inline oop oopDesc::decode_heap_oop(oop v)  { return v; }
 225 
 226 // Encoding and decoding for klass field.  It is copied code, but someday
 227 // might not be the same as oop.
 228 
 229 inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
 230   assert(!is_null(v), "oop value can never be zero");
 231   assert(check_obj_alignment(v), "Address not aligned");
 232   address base = Universe::narrow_oop_base();
 233   int    shift = Universe::narrow_oop_shift();
 234   uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
 235   assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
 236   uint64_t result = pd >> shift;
 237   assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
 238   assert(decode_klass(result) == v, "reversibility");
 239   return (narrowOop)result;
 240 }
 241 
 242 inline narrowOop oopDesc::encode_klass(Klass* v) {
 243   return (is_null(v)) ? (narrowOop)0 : encode_klass_not_null(v);
 244 }
 245 
 246 inline Klass* oopDesc::decode_klass_not_null(narrowOop v) {
 247   assert(!is_null(v), "narrow oop value can never be zero");
 248   address base = Universe::narrow_oop_base();
 249   int    shift = Universe::narrow_oop_shift();
 250   Klass* result = (Klass*)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
 251   assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
 252   return result;
 253 }
 254 
 255 inline Klass* oopDesc::decode_klass(narrowOop v) {
 256   return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
 257 }
 258 
 259 // Load an oop out of the Java heap as is without decoding.
 260 // Called by GC to check for null before decoding.
 261 inline oop       oopDesc::load_heap_oop(oop* p)          { return *p; }
 262 inline narrowOop oopDesc::load_heap_oop(narrowOop* p)    { return *p; }
 263 
 264 // Load and decode an oop out of the Java heap into a wide oop.
 265 inline oop oopDesc::load_decode_heap_oop_not_null(oop* p)       { return *p; }
 266 inline oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) {
 267   return decode_heap_oop_not_null(*p);
 268 }
 269 
 270 // Load and decode an oop out of the heap accepting null
 271 inline oop oopDesc::load_decode_heap_oop(oop* p) { return *p; }




 168 inline address*  oopDesc::address_field_addr(int offset) const { return (address*) field_base(offset); }
 169 
 170 
 171 // Functions for getting and setting oops within instance objects.
 172 // If the oops are compressed, the type passed to these overloaded functions
 173 // is narrowOop.  All functions are overloaded so they can be called by
 174 // template functions without conditionals (the compiler instantiates via
 175 // the right type and inlines the appopriate code).
 176 
 177 inline bool oopDesc::is_null(oop obj)       { return obj == NULL; }
 178 inline bool oopDesc::is_null(Klass* obj)  { return obj == NULL; }
 179 inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
 180 
 181 // Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit
 182 // offset from the heap base.  Saving the check for null can save instructions
 183 // in inner GC loops so these are separated.
 184 
 185 inline bool check_obj_alignment(oop obj) {
 186   return (intptr_t)obj % MinObjAlignmentInBytes == 0;
 187 }
 188 inline bool check_klass_alignment(Klass* obj) {
 189   return (intptr_t)obj % KlassAlignmentInBytes == 0;
 190 }
 191 
 192 inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
 193   assert(!is_null(v), "oop value can never be zero");
 194   assert(check_obj_alignment(v), "Address not aligned");
 195   assert(Universe::heap()->is_in_reserved(v), "Address not in heap");
 196   address base = Universe::narrow_oop_base();
 197   int    shift = Universe::narrow_oop_shift();
 198   uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
 199   assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
 200   uint64_t result = pd >> shift;
 201   assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow");
 202   assert(decode_heap_oop(result) == v, "reversibility");
 203   return (narrowOop)result;
 204 }
 205 
 206 inline narrowOop oopDesc::encode_heap_oop(oop v) {
 207   return (is_null(v)) ? (narrowOop)0 : encode_heap_oop_not_null(v);
 208 }
 209 


 211   assert(!is_null(v), "narrow oop value can never be zero");
 212   address base = Universe::narrow_oop_base();
 213   int    shift = Universe::narrow_oop_shift();
 214   oop result = (oop)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
 215   assert(check_obj_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
 216   return result;
 217 }
 218 
 219 inline oop oopDesc::decode_heap_oop(narrowOop v) {
 220   return is_null(v) ? (oop)NULL : decode_heap_oop_not_null(v);
 221 }
 222 
 223 inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; }
 224 inline oop oopDesc::decode_heap_oop(oop v)  { return v; }
 225 
 226 // Encoding and decoding for klass field.  It is copied code, but someday
 227 // might not be the same as oop.
 228 
 229 inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
 230   assert(!is_null(v), "oop value can never be zero");
 231   assert(check_klass_alignment(v), "Address not aligned");
 232   address base = Universe::narrow_klass_base();
 233   int    shift = Universe::narrow_klass_shift();
 234   uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
 235   assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
 236   uint64_t result = pd >> shift;
 237   assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
 238   assert(decode_klass(result) == v, "reversibility");
 239   return (narrowOop)result;
 240 }
 241 
 242 inline narrowOop oopDesc::encode_klass(Klass* v) {
 243   return (is_null(v)) ? (narrowOop)0 : encode_klass_not_null(v);
 244 }
 245 
 246 inline Klass* oopDesc::decode_klass_not_null(narrowOop v) {
 247   assert(!is_null(v), "narrow oop value can never be zero");
 248   address base = Universe::narrow_klass_base();
 249   int    shift = Universe::narrow_klass_shift();
 250   Klass* result = (Klass*)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
 251   assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
 252   return result;
 253 }
 254 
 255 inline Klass* oopDesc::decode_klass(narrowOop v) {
 256   return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
 257 }
 258 
 259 // Load an oop out of the Java heap as is without decoding.
 260 // Called by GC to check for null before decoding.
 261 inline oop       oopDesc::load_heap_oop(oop* p)          { return *p; }
 262 inline narrowOop oopDesc::load_heap_oop(narrowOop* p)    { return *p; }
 263 
 264 // Load and decode an oop out of the Java heap into a wide oop.
 265 inline oop oopDesc::load_decode_heap_oop_not_null(oop* p)       { return *p; }
 266 inline oop oopDesc::load_decode_heap_oop_not_null(narrowOop* p) {
 267   return decode_heap_oop_not_null(*p);
 268 }
 269 
 270 // Load and decode an oop out of the heap accepting null
 271 inline oop oopDesc::load_decode_heap_oop(oop* p) { return *p; }