28 #include "oops/arrayOop.hpp" 29 30 // An objArrayOop is an array containing oops. 31 // Evaluating "String arg[10]" will create an objArrayOop. 32 33 class objArrayOopDesc : public arrayOopDesc { 34 friend class objArrayKlass; 35 friend class Runtime1; 36 friend class psPromotionManager; 37 friend class CSetMarkOopClosure; 38 friend class G1ParScanPartialArrayClosure; 39 40 template <class T> T* obj_at_addr(int index) const { 41 assert(is_within_bounds(index), "index out of bounds"); 42 return &((T*)base())[index]; 43 } 44 45 private: 46 // Give size of objArrayOop in HeapWords minus the header 47 static int array_size(int length) { 48 const int OopsPerHeapWord = HeapWordSize/heapOopSize; 49 assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0), 50 "Else the following (new) computation would be in error"); 51 #ifdef ASSERT 52 // The old code is left in for sanity-checking; it'll 53 // go away pretty soon. XXX 54 // Without UseCompressedOops, this is simply: 55 // oop->length() * HeapWordsPerOop; 56 // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer. 57 // The oop elements are aligned up to wordSize 58 const int HeapWordsPerOop = heapOopSize/HeapWordSize; 59 int old_res; 60 if (HeapWordsPerOop > 0) { 61 old_res = length * HeapWordsPerOop; 62 } else { 63 old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord; 64 } 65 #endif // ASSERT 66 int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord; 67 assert(res == old_res, "Inconsistency between old and new."); 68 return res; 69 } 70 71 public: 72 // Returns the offset of the first element. 73 static int base_offset_in_bytes() { 74 return arrayOopDesc::base_offset_in_bytes(T_OBJECT); 75 } 76 77 // base is the address following the header. 78 HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); } 79 80 // Accessing 81 oop obj_at(int index) const { 82 // With UseCompressedOops decode the narrow oop in the objArray to an 83 // uncompressed oop. Otherwise this is simply a "*" operator. 84 if (UseCompressedOops) { 85 return load_decode_heap_oop(obj_at_addr<narrowOop>(index)); 86 } else { 87 return load_decode_heap_oop(obj_at_addr<oop>(index)); | 28 #include "oops/arrayOop.hpp" 29 30 // An objArrayOop is an array containing oops. 31 // Evaluating "String arg[10]" will create an objArrayOop. 32 33 class objArrayOopDesc : public arrayOopDesc { 34 friend class objArrayKlass; 35 friend class Runtime1; 36 friend class psPromotionManager; 37 friend class CSetMarkOopClosure; 38 friend class G1ParScanPartialArrayClosure; 39 40 template <class T> T* obj_at_addr(int index) const { 41 assert(is_within_bounds(index), "index out of bounds"); 42 return &((T*)base())[index]; 43 } 44 45 private: 46 // Give size of objArrayOop in HeapWords minus the header 47 static int array_size(int length) { 48 const uint OopsPerHeapWord = HeapWordSize/heapOopSize; 49 assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0), 50 "Else the following (new) computation would be in error"); 51 uint res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord; 52 #ifdef ASSERT 53 // The old code is left in for sanity-checking; it'll 54 // go away pretty soon. XXX 55 // Without UseCompressedOops, this is simply: 56 // oop->length() * HeapWordsPerOop; 57 // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer. 58 // The oop elements are aligned up to wordSize 59 const uint HeapWordsPerOop = heapOopSize/HeapWordSize; 60 uint old_res; 61 if (HeapWordsPerOop > 0) { 62 old_res = length * HeapWordsPerOop; 63 } else { 64 old_res = align_size_up((uint)length, OopsPerHeapWord)/OopsPerHeapWord; 65 } 66 assert(res == old_res, "Inconsistency between old and new."); 67 #endif // ASSERT 68 return res; 69 } 70 71 public: 72 // Returns the offset of the first element. 73 static int base_offset_in_bytes() { 74 return arrayOopDesc::base_offset_in_bytes(T_OBJECT); 75 } 76 77 // base is the address following the header. 78 HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); } 79 80 // Accessing 81 oop obj_at(int index) const { 82 // With UseCompressedOops decode the narrow oop in the objArray to an 83 // uncompressed oop. Otherwise this is simply a "*" operator. 84 if (UseCompressedOops) { 85 return load_decode_heap_oop(obj_at_addr<narrowOop>(index)); 86 } else { 87 return load_decode_heap_oop(obj_at_addr<oop>(index)); |