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