1 /*
  2  * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_VM_OOPS_FLATARRAYOOP_INLINE_HPP
 26 #define SHARE_VM_OOPS_FLATARRAYOOP_INLINE_HPP
 27 
 28 #include "oops/flatArrayOop.hpp"
 29 
 30 #include "classfile/vmSymbols.hpp"
 31 #include "oops/access.inline.hpp"
 32 #include "oops/flatArrayKlass.hpp"
 33 #include "oops/inlineKlass.inline.hpp"
 34 #include "oops/oop.inline.hpp"
 35 #include "runtime/globals.hpp"
 36 
 37 inline void* flatArrayOopDesc::base() const { return arrayOopDesc::base(T_FLAT_ELEMENT); }
 38 
 39 inline void* flatArrayOopDesc::value_at_addr(int index, jint lh) const {
 40   assert(is_within_bounds(index), "index out of bounds");
 41 
 42   address array_base = (address) base();
 43   ptrdiff_t offset = (ptrdiff_t) index << Klass::layout_helper_log2_element_size(lh);
 44   address addr = array_base + offset;
 45   assert(addr >= array_base, "must be");
 46   return (void*) addr;
 47 }
 48 
 49 inline int flatArrayOopDesc::object_size(int lh) const {
 50   return object_size(lh, length());
 51 }
 52 
 53 inline oop flatArrayOopDesc::obj_at(int index) const {
 54   EXCEPTION_MARK;
 55   return obj_at(index, THREAD);
 56 }
 57 
 58 inline oop flatArrayOopDesc::obj_at(int index, TRAPS) const {
 59   assert(is_within_bounds(index), "index %d out of bounds %d", index, length());
 60   FlatArrayKlass* faklass = FlatArrayKlass::cast(klass());
 61   InlineKlass* vk = InlineKlass::cast(faklass->element_klass());
 62   char* this_oop = (char*) (oopDesc*) this;
 63   char* val = (char*) value_at_addr(index, faklass->layout_helper());
 64   ptrdiff_t offset = val - this_oop;
 65   oop res = vk->read_payload_from_addr((oopDesc*)this, offset, faklass->layout_kind(), CHECK_NULL);
 66   return res;
 67 }
 68 
 69 inline jboolean flatArrayOopDesc::null_marker_of_obj_at(int index) const {
 70   EXCEPTION_MARK;
 71   return null_marker_of_obj_at(index, THREAD);
 72 }
 73 
 74 inline jboolean flatArrayOopDesc::null_marker_of_obj_at(int index, TRAPS) const {
 75   assert(is_within_bounds(index), "index %d out of bounds %d", index, length());
 76   FlatArrayKlass* faklass = FlatArrayKlass::cast(klass());
 77   InlineKlass* vk = InlineKlass::cast(faklass->element_klass());
 78   char* this_oop = (char*) (oopDesc*) this;
 79   char* val = (char*) value_at_addr(index, faklass->layout_helper());
 80   ptrdiff_t offset = val - this_oop + (ptrdiff_t)vk->null_marker_offset_in_payload();
 81   return bool_field(offset);
 82 }
 83 
 84 inline void flatArrayOopDesc::obj_at_put(int index, oop value) {
 85   EXCEPTION_MARK;                                 // What if the caller is not a Java Thread?
 86   obj_at_put(index, value, THREAD);
 87 }
 88 
 89 inline void flatArrayOopDesc::obj_at_put(int index, oop value, TRAPS) {
 90   assert(is_within_bounds(index), "index %d out of bounds %d", index, length());
 91   FlatArrayKlass* faklass = FlatArrayKlass::cast(klass());
 92   InlineKlass* vk = InlineKlass::cast(faklass->element_klass());
 93   if (value != nullptr) {
 94     if (value->klass() != vk) {
 95       THROW(vmSymbols::java_lang_ArrayStoreException());
 96     }
 97   } else if(is_null_free_array()) {
 98     THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Cannot store null in a null-restricted array");
 99   }
100   vk->write_value_to_addr(value, value_at_addr(index, faklass->layout_helper()), faklass->layout_kind(), CHECK);
101 }
102 
103 #endif // SHARE_VM_OOPS_FLATARRAYOOP_INLINE_HPP