duke@435: /* stefank@2314: * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_OOPS_OBJARRAYOOP_HPP stefank@2314: #define SHARE_VM_OOPS_OBJARRAYOOP_HPP stefank@2314: stefank@2314: #include "oops/arrayOop.hpp" stefank@2314: duke@435: // An objArrayOop is an array containing oops. duke@435: // Evaluating "String arg[10]" will create an objArrayOop. duke@435: duke@435: class objArrayOopDesc : public arrayOopDesc { coleenp@548: friend class objArrayKlass; coleenp@548: friend class Runtime1; coleenp@548: friend class psPromotionManager; ysr@777: friend class CSMarkOopClosure; ysr@777: friend class G1ParScanPartialArrayClosure; coleenp@548: coleenp@548: template T* obj_at_addr(int index) const { coleenp@548: assert(is_within_bounds(index), "index out of bounds"); coleenp@548: return &((T*)base())[index]; coleenp@548: } coleenp@548: ysr@1526: private: ysr@1526: // Give size of objArrayOop in HeapWords minus the header ysr@1526: static int array_size(int length) { ysr@1526: const int OopsPerHeapWord = HeapWordSize/heapOopSize; ysr@1526: assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0), ysr@1526: "Else the following (new) computation would be in error"); ysr@1526: #ifdef ASSERT ysr@1526: // The old code is left in for sanity-checking; it'll ysr@1526: // go away pretty soon. XXX ysr@1526: // Without UseCompressedOops, this is simply: ysr@1526: // oop->length() * HeapWordsPerOop; ysr@1526: // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer. ysr@1526: // The oop elements are aligned up to wordSize ysr@1526: const int HeapWordsPerOop = heapOopSize/HeapWordSize; ysr@1526: int old_res; ysr@1526: if (HeapWordsPerOop > 0) { ysr@1526: old_res = length * HeapWordsPerOop; ysr@1526: } else { ysr@1526: old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord; ysr@1526: } ysr@1526: #endif // ASSERT ysr@1530: int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord; ysr@1526: assert(res == old_res, "Inconsistency between old and new."); ysr@1526: return res; ysr@1526: } ysr@1526: duke@435: public: twisti@1330: // Returns the offset of the first element. twisti@1330: static int base_offset_in_bytes() { twisti@1330: return arrayOopDesc::base_offset_in_bytes(T_OBJECT); twisti@1330: } twisti@1330: coleenp@548: // base is the address following the header. coleenp@548: HeapWord* base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); } coleenp@548: duke@435: // Accessing coleenp@548: oop obj_at(int index) const { coleenp@548: // With UseCompressedOops decode the narrow oop in the objArray to an coleenp@548: // uncompressed oop. Otherwise this is simply a "*" operator. coleenp@548: if (UseCompressedOops) { coleenp@548: return load_decode_heap_oop(obj_at_addr(index)); coleenp@548: } else { coleenp@548: return load_decode_heap_oop(obj_at_addr(index)); coleenp@548: } coleenp@548: } duke@435: coleenp@548: void obj_at_put(int index, oop value) { coleenp@548: if (UseCompressedOops) { coleenp@548: oop_store(obj_at_addr(index), value); coleenp@548: } else { coleenp@548: oop_store(obj_at_addr(index), value); coleenp@548: } coleenp@548: } duke@435: // Sizing coleenp@548: static int header_size() { return arrayOopDesc::header_size(T_OBJECT); } coleenp@548: int object_size() { return object_size(length()); } duke@435: coleenp@548: static int object_size(int length) { coleenp@548: // This returns the object size in HeapWords. ysr@1530: uint asz = array_size(length); ysr@1530: uint osz = align_object_size(header_size() + asz); ysr@1530: assert(osz >= asz, "no overflow"); ysr@1530: assert((int)osz > 0, "no overflow"); ysr@1530: return (int)osz; duke@435: } coleenp@548: coleenp@548: // special iterators for index ranges, returns size of object coleenp@548: #define ObjArrayOop_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \ coleenp@548: int oop_iterate_range(OopClosureType* blk, int start, int end); coleenp@548: coleenp@548: ALL_OOP_OOP_ITERATE_CLOSURES_1(ObjArrayOop_OOP_ITERATE_DECL) ysr@777: ALL_OOP_OOP_ITERATE_CLOSURES_2(ObjArrayOop_OOP_ITERATE_DECL) duke@435: }; stefank@2314: stefank@2314: #endif // SHARE_VM_OOPS_OBJARRAYOOP_HPP