24 |
24 |
25 // An objArrayOop is an array containing oops. |
25 // An objArrayOop is an array containing oops. |
26 // Evaluating "String arg[10]" will create an objArrayOop. |
26 // Evaluating "String arg[10]" will create an objArrayOop. |
27 |
27 |
28 class objArrayOopDesc : public arrayOopDesc { |
28 class objArrayOopDesc : public arrayOopDesc { |
|
29 friend class objArrayKlass; |
|
30 friend class Runtime1; |
|
31 friend class psPromotionManager; |
|
32 |
|
33 template <class T> T* obj_at_addr(int index) const { |
|
34 assert(is_within_bounds(index), "index out of bounds"); |
|
35 return &((T*)base())[index]; |
|
36 } |
|
37 |
29 public: |
38 public: |
|
39 // base is the address following the header. |
|
40 HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); } |
|
41 |
30 // Accessing |
42 // Accessing |
31 oop obj_at(int index) const { return *obj_at_addr(index); } |
43 oop obj_at(int index) const { |
32 void obj_at_put(int index, oop value) { oop_store(obj_at_addr(index), value); } |
44 // With UseCompressedOops decode the narrow oop in the objArray to an |
33 oop* base() const { return (oop*) arrayOopDesc::base(T_OBJECT); } |
45 // uncompressed oop. Otherwise this is simply a "*" operator. |
|
46 if (UseCompressedOops) { |
|
47 return load_decode_heap_oop(obj_at_addr<narrowOop>(index)); |
|
48 } else { |
|
49 return load_decode_heap_oop(obj_at_addr<oop>(index)); |
|
50 } |
|
51 } |
34 |
52 |
|
53 void obj_at_put(int index, oop value) { |
|
54 if (UseCompressedOops) { |
|
55 oop_store(obj_at_addr<narrowOop>(index), value); |
|
56 } else { |
|
57 oop_store(obj_at_addr<oop>(index), value); |
|
58 } |
|
59 } |
35 // Sizing |
60 // Sizing |
36 static int header_size() { return arrayOopDesc::header_size(T_OBJECT); } |
61 static int header_size() { return arrayOopDesc::header_size(T_OBJECT); } |
37 static int object_size(int length) { return align_object_size(header_size() + length); } |
62 int object_size() { return object_size(length()); } |
38 int object_size() { return object_size(length()); } |
63 int array_size() { return array_size(length()); } |
39 |
64 |
40 // Returns the address of the index'th element |
65 static int object_size(int length) { |
41 oop* obj_at_addr(int index) const { |
66 // This returns the object size in HeapWords. |
42 assert(is_within_bounds(index), "index out of bounds"); |
67 return align_object_size(header_size() + array_size(length)); |
43 return &base()[index]; |
|
44 } |
68 } |
|
69 |
|
70 // Give size of objArrayOop in HeapWords minus the header |
|
71 static int array_size(int length) { |
|
72 // Without UseCompressedOops, this is simply: |
|
73 // oop->length() * HeapWordsPerOop; |
|
74 // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer. |
|
75 // The oop elements are aligned up to wordSize |
|
76 const int HeapWordsPerOop = heapOopSize/HeapWordSize; |
|
77 if (HeapWordsPerOop > 0) { |
|
78 return length * HeapWordsPerOop; |
|
79 } else { |
|
80 const int OopsPerHeapWord = HeapWordSize/heapOopSize; |
|
81 int word_len = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord; |
|
82 return word_len; |
|
83 } |
|
84 } |
|
85 |
|
86 // special iterators for index ranges, returns size of object |
|
87 #define ObjArrayOop_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \ |
|
88 int oop_iterate_range(OopClosureType* blk, int start, int end); |
|
89 |
|
90 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayOop_OOP_ITERATE_DECL) |
|
91 ALL_OOP_OOP_ITERATE_CLOSURES_3(ObjArrayOop_OOP_ITERATE_DECL) |
45 }; |
92 }; |