hotspot/src/share/vm/oops/arrayOop.hpp
changeset 360 21d113ecbf6a
parent 202 dc13bf0e5d5d
child 591 04d2e26e6d69
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    21  * have any questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 // arrayOopDesc is the abstract baseclass for all arrays.
    25 // arrayOopDesc is the abstract baseclass for all arrays.  It doesn't
       
    26 // declare pure virtual to enforce this because that would allocate a vtbl
       
    27 // in each instance, which we don't want.
       
    28 
       
    29 // The layout of array Oops is:
       
    30 //
       
    31 //  markOop
       
    32 //  klassOop  // 32 bits if compressed but declared 64 in LP64.
       
    33 //  length    // shares klass memory or allocated after declared fields.
       
    34 
    26 
    35 
    27 class arrayOopDesc : public oopDesc {
    36 class arrayOopDesc : public oopDesc {
    28   friend class VMStructs;
    37   friend class VMStructs;
    29  private:
    38 
    30   int _length; // number of elements in the array
    39   // Interpreter/Compiler offsets
       
    40 
       
    41   // Header size computation.
       
    42   // The header is considered the oop part of this type plus the length.
       
    43   // Returns the aligned header_size_in_bytes.  This is not equivalent to
       
    44   // sizeof(arrayOopDesc) which should not appear in the code, except here.
       
    45   static int header_size_in_bytes() {
       
    46     size_t hs = UseCompressedOops ?
       
    47             sizeof(arrayOopDesc) :
       
    48             align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize);
       
    49 #ifdef ASSERT
       
    50     // make sure it isn't called before UseCompressedOops is initialized.
       
    51     static size_t arrayoopdesc_hs = 0;
       
    52     if (arrayoopdesc_hs == 0) arrayoopdesc_hs = hs;
       
    53     assert(arrayoopdesc_hs == hs, "header size can't change");
       
    54 #endif // ASSERT
       
    55     return (int)hs;
       
    56   }
    31 
    57 
    32  public:
    58  public:
    33   // Interpreter/Compiler offsets
    59   // The _length field is not declared in C++.  It is allocated after the
    34   static int length_offset_in_bytes()             { return offset_of(arrayOopDesc, _length); }
    60   // declared nonstatic fields in arrayOopDesc if not compressed, otherwise
    35   static int base_offset_in_bytes(BasicType type) { return header_size(type) * HeapWordSize; }
    61   // it occupies the second half of the _klass field in oopDesc.
       
    62   static int length_offset_in_bytes() {
       
    63     return UseCompressedOops ? klass_gap_offset_in_bytes() :
       
    64                                sizeof(arrayOopDesc);
       
    65   }
       
    66 
       
    67   // Returns the offset of the first element.
       
    68   static int base_offset_in_bytes(BasicType type) {
       
    69     return header_size(type) * HeapWordSize;
       
    70   }
    36 
    71 
    37   // Returns the address of the first element.
    72   // Returns the address of the first element.
    38   void* base(BasicType type) const              { return (void*) (((intptr_t) this) + base_offset_in_bytes(type)); }
    73   void* base(BasicType type) const {
       
    74     return (void*) (((intptr_t) this) + base_offset_in_bytes(type));
       
    75   }
    39 
    76 
    40   // Tells whether index is within bounds.
    77   // Tells whether index is within bounds.
    41   bool is_within_bounds(int index) const        { return 0 <= index && index < length(); }
    78   bool is_within_bounds(int index) const        { return 0 <= index && index < length(); }
    42 
    79 
    43   // Accessores for instance variable
    80   // Accessors for instance variable which is not a C++ declared nonstatic
    44   int length() const                            { return _length;   }
    81   // field.
    45   void set_length(int length)                   { _length = length; }
    82   int length() const {
       
    83     return *(int*)(((intptr_t)this) + length_offset_in_bytes());
       
    84   }
       
    85   void set_length(int length) {
       
    86     *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
       
    87   }
    46 
    88 
    47   // Header size computation.
    89   // Should only be called with constants as argument
    48   // Should only be called with constants as argument (will not constant fold otherwise)
    90   // (will not constant fold otherwise)
       
    91   // Returns the header size in words aligned to the requirements of the
       
    92   // array object type.
    49   static int header_size(BasicType type) {
    93   static int header_size(BasicType type) {
    50     return Universe::element_type_should_be_aligned(type)
    94     size_t typesize_in_bytes = header_size_in_bytes();
    51       ? align_object_size(sizeof(arrayOopDesc)/HeapWordSize)
    95     return (int)(Universe::element_type_should_be_aligned(type)
    52       : sizeof(arrayOopDesc)/HeapWordSize;
    96       ? align_object_size(typesize_in_bytes/HeapWordSize)
       
    97       : typesize_in_bytes/HeapWordSize);
    53   }
    98   }
    54 
    99 
    55   // This method returns the  maximum length that can passed into
   100   // This method returns the  maximum length that can passed into
    56   // typeArrayOop::object_size(scale, length, header_size) without causing an
   101   // typeArrayOop::object_size(scale, length, header_size) without causing an
    57   // overflow. We substract an extra 2*wordSize to guard against double word
   102   // overflow. We substract an extra 2*wordSize to guard against double word
    60     assert(type >= 0 && type < T_CONFLICT, "wrong type");
   105     assert(type >= 0 && type < T_CONFLICT, "wrong type");
    61     assert(type2aelembytes(type) != 0, "wrong type");
   106     assert(type2aelembytes(type) != 0, "wrong type");
    62     // We use max_jint, since object_size is internally represented by an 'int'
   107     // We use max_jint, since object_size is internally represented by an 'int'
    63     // This gives us an upper bound of max_jint words for the size of the oop.
   108     // This gives us an upper bound of max_jint words for the size of the oop.
    64     int32_t max_words = (max_jint - header_size(type) - 2);
   109     int32_t max_words = (max_jint - header_size(type) - 2);
    65     int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type);
   110     int elembytes = type2aelembytes(type);
    66     jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
   111     jlong len = ((jlong)max_words * HeapWordSize) / elembytes;
    67     return (len > max_jint) ? max_jint : (int32_t)len;
   112     return (len > max_jint) ? max_jint : (int32_t)len;
    68   }
   113   }
    69 
   114 
    70 };
   115 };