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; }
|