blob: 57c305d56d38fbe20aeb6de53c9ba8469305db35 [file] [log] [blame]
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_OOPS_TYPEARRAYOOP_HPP
#define SHARE_VM_OOPS_TYPEARRAYOOP_HPP
#include "oops/arrayOop.hpp"
#include "oops/typeArrayKlass.hpp"
#include "runtime/orderAccess.inline.hpp"
// A typeArrayOop is an array containing basic types (non oop elements).
// It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
#include <limits.h>
class typeArrayOopDesc : public arrayOopDesc {
protected:
jchar* char_base() const { return (jchar*) base(T_CHAR); }
jboolean* bool_base() const { return (jboolean*)base(T_BOOLEAN); }
jbyte* byte_base() const { return (jbyte*) base(T_BYTE); }
jint* int_base() const { return (jint*) base(T_INT); }
jlong* long_base() const { return (jlong*) base(T_LONG); }
jshort* short_base() const { return (jshort*) base(T_SHORT); }
jfloat* float_base() const { return (jfloat*) base(T_FLOAT); }
jdouble* double_base() const { return (jdouble*) base(T_DOUBLE); }
friend class TypeArrayKlass;
public:
jbyte* byte_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &byte_base()[which];
}
jboolean* bool_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &bool_base()[which];
}
jchar* char_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &char_base()[which];
}
jint* int_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &int_base()[which];
}
jshort* short_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &short_base()[which];
}
jushort* ushort_at_addr(int which) const { // for field descriptor arrays
assert(is_within_bounds(which), "index out of bounds");
return (jushort*) &short_base()[which];
}
jlong* long_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &long_base()[which];
}
jfloat* float_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &float_base()[which];
}
jdouble* double_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return &double_base()[which];
}
jbyte byte_at(int which) const { return *byte_at_addr(which); }
void byte_at_put(int which, jbyte contents) { *byte_at_addr(which) = contents; }
jboolean bool_at(int which) const { return *bool_at_addr(which); }
void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = (((jint)contents) & 1); }
jchar char_at(int which) const { return *char_at_addr(which); }
void char_at_put(int which, jchar contents) { *char_at_addr(which) = contents; }
jint int_at(int which) const { return *int_at_addr(which); }
void int_at_put(int which, jint contents) { *int_at_addr(which) = contents; }
jshort short_at(int which) const { return *short_at_addr(which); }
void short_at_put(int which, jshort contents) { *short_at_addr(which) = contents; }
jushort ushort_at(int which) const { return *ushort_at_addr(which); }
void ushort_at_put(int which, jushort contents) { *ushort_at_addr(which) = contents; }
jlong long_at(int which) const { return *long_at_addr(which); }
void long_at_put(int which, jlong contents) { *long_at_addr(which) = contents; }
jfloat float_at(int which) const { return *float_at_addr(which); }
void float_at_put(int which, jfloat contents) { *float_at_addr(which) = contents; }
jdouble double_at(int which) const { return *double_at_addr(which); }
void double_at_put(int which, jdouble contents) { *double_at_addr(which) = contents; }
jbyte byte_at_acquire(int which) const { return OrderAccess::load_acquire(byte_at_addr(which)); }
void release_byte_at_put(int which, jbyte contents) { OrderAccess::release_store(byte_at_addr(which), contents); }
// Java thinks metadata arrays are just arrays of either long or int, since
// there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate
// casting
#ifdef _LP64
Metadata* metadata_at(int which) const {
return (Metadata*)*long_at_addr(which); }
void metadata_at_put(int which, Metadata* contents) {
*long_at_addr(which) = (long)contents;
}
#else
Metadata* metadata_at(int which) const {
return (Metadata*)*int_at_addr(which); }
void metadata_at_put(int which, Metadata* contents) {
*int_at_addr(which) = (int)contents;
}
#endif // _LP64
// Sizing
// Returns the number of words necessary to hold an array of "len"
// elements each of the given "byte_size".
private:
static int object_size(int lh, int length) {
int instance_header_size = Klass::layout_helper_header_size(lh);
int element_shift = Klass::layout_helper_log2_element_size(lh);
DEBUG_ONLY(BasicType etype = Klass::layout_helper_element_type(lh));
assert(length <= arrayOopDesc::max_array_length(etype), "no overflow");
julong size_in_bytes = (juint)length;
size_in_bytes <<= element_shift;
size_in_bytes += instance_header_size;
julong size_in_words = ((size_in_bytes + (HeapWordSize-1)) >> LogHeapWordSize);
assert(size_in_words <= (julong)max_jint, "no overflow");
return align_object_size((intptr_t)size_in_words);
}
public:
int object_size() {
TypeArrayKlass* tk = TypeArrayKlass::cast(klass());
return object_size(tk->layout_helper(), length());
}
};
#endif // SHARE_VM_OOPS_TYPEARRAYOOP_HPP