annotate src/share/vm/oops/objArrayOop.hpp @ 1095:7bfd295ec074

6908208: UseCompressedOops: array_size() returns incorrect size for MAX_INT object array following 6906727 Summary: In array_size() cast to an unsigned to avoid overflow of intermediate value. Reviewed-by: kvn, tonyp, jmasa, jcoomes, coleenp
author ysr
date Tue, 08 Dec 2009 15:12:17 -0800
parents 6aa7255741f3
children
rev   line source
duke@0 1 /*
xdono@948 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
duke@0 7 * published by the Free Software Foundation.
duke@0 8 *
duke@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 13 * accompanied this code).
duke@0 14 *
duke@0 15 * You should have received a copy of the GNU General Public License version
duke@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 18 *
duke@0 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@0 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@0 21 * have any questions.
duke@0 22 *
duke@0 23 */
duke@0 24
duke@0 25 // An objArrayOop is an array containing oops.
duke@0 26 // Evaluating "String arg[10]" will create an objArrayOop.
duke@0 27
duke@0 28 class objArrayOopDesc : public arrayOopDesc {
coleenp@113 29 friend class objArrayKlass;
coleenp@113 30 friend class Runtime1;
coleenp@113 31 friend class psPromotionManager;
ysr@342 32 friend class CSMarkOopClosure;
ysr@342 33 friend class G1ParScanPartialArrayClosure;
coleenp@113 34
coleenp@113 35 template <class T> T* obj_at_addr(int index) const {
coleenp@113 36 assert(is_within_bounds(index), "index out of bounds");
coleenp@113 37 return &((T*)base())[index];
coleenp@113 38 }
coleenp@113 39
ysr@1091 40 private:
ysr@1091 41 // Give size of objArrayOop in HeapWords minus the header
ysr@1091 42 static int array_size(int length) {
ysr@1091 43 const int OopsPerHeapWord = HeapWordSize/heapOopSize;
ysr@1091 44 assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
ysr@1091 45 "Else the following (new) computation would be in error");
ysr@1091 46 #ifdef ASSERT
ysr@1091 47 // The old code is left in for sanity-checking; it'll
ysr@1091 48 // go away pretty soon. XXX
ysr@1091 49 // Without UseCompressedOops, this is simply:
ysr@1091 50 // oop->length() * HeapWordsPerOop;
ysr@1091 51 // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
ysr@1091 52 // The oop elements are aligned up to wordSize
ysr@1091 53 const int HeapWordsPerOop = heapOopSize/HeapWordSize;
ysr@1091 54 int old_res;
ysr@1091 55 if (HeapWordsPerOop > 0) {
ysr@1091 56 old_res = length * HeapWordsPerOop;
ysr@1091 57 } else {
ysr@1091 58 old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
ysr@1091 59 }
ysr@1091 60 #endif // ASSERT
ysr@1095 61 int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
ysr@1091 62 assert(res == old_res, "Inconsistency between old and new.");
ysr@1091 63 return res;
ysr@1091 64 }
ysr@1091 65
duke@0 66 public:
twisti@895 67 // Returns the offset of the first element.
twisti@895 68 static int base_offset_in_bytes() {
twisti@895 69 return arrayOopDesc::base_offset_in_bytes(T_OBJECT);
twisti@895 70 }
twisti@895 71
coleenp@113 72 // base is the address following the header.
coleenp@113 73 HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
coleenp@113 74
duke@0 75 // Accessing
coleenp@113 76 oop obj_at(int index) const {
coleenp@113 77 // With UseCompressedOops decode the narrow oop in the objArray to an
coleenp@113 78 // uncompressed oop. Otherwise this is simply a "*" operator.
coleenp@113 79 if (UseCompressedOops) {
coleenp@113 80 return load_decode_heap_oop(obj_at_addr<narrowOop>(index));
coleenp@113 81 } else {
coleenp@113 82 return load_decode_heap_oop(obj_at_addr<oop>(index));
coleenp@113 83 }
coleenp@113 84 }
duke@0 85
coleenp@113 86 void obj_at_put(int index, oop value) {
coleenp@113 87 if (UseCompressedOops) {
coleenp@113 88 oop_store(obj_at_addr<narrowOop>(index), value);
coleenp@113 89 } else {
coleenp@113 90 oop_store(obj_at_addr<oop>(index), value);
coleenp@113 91 }
coleenp@113 92 }
duke@0 93 // Sizing
coleenp@113 94 static int header_size() { return arrayOopDesc::header_size(T_OBJECT); }
coleenp@113 95 int object_size() { return object_size(length()); }
duke@0 96
coleenp@113 97 static int object_size(int length) {
coleenp@113 98 // This returns the object size in HeapWords.
ysr@1095 99 uint asz = array_size(length);
ysr@1095 100 uint osz = align_object_size(header_size() + asz);
ysr@1095 101 assert(osz >= asz, "no overflow");
ysr@1095 102 assert((int)osz > 0, "no overflow");
ysr@1095 103 return (int)osz;
duke@0 104 }
coleenp@113 105
coleenp@113 106 // special iterators for index ranges, returns size of object
coleenp@113 107 #define ObjArrayOop_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \
coleenp@113 108 int oop_iterate_range(OopClosureType* blk, int start, int end);
coleenp@113 109
coleenp@113 110 ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayOop_OOP_ITERATE_DECL)
ysr@342 111 ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayOop_OOP_ITERATE_DECL)
duke@0 112 };