/* * Copyright (c) 2016, 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. * */ #include "ci/ciField.hpp" #include "ci/ciValueKlass.hpp" #include "oops/valueKlass.hpp" // Number of value type factory parameters int ciValueKlass::param_count() const { valueKlassHandle vklass_h(ValueKlass::cast(get_Klass())); methodHandle factory_h(vklass_h->factory_method()); return factory_h->constMethod()->valuefactory_parameter_mapping_length(); } // Size of value type factory parameters in words int ciValueKlass::param_size() { int size = 0; for (int i = 0; i < param_count(); ++i) { size += get_field_type_by_index(i)->size(); } return size; } // Returns the value factory parameter index of the field with the given offset. // If the field at 'offset' belongs to a flattened value type field, return the // index of the ValueType parameter corresponding to this flattened value type. int ciValueKlass::get_field_index_by_offset(int offset) { assert(contains_field_offset(offset), "invalid field offset"); int best_offset = 0; int best_index = -1; // Search the field with the given offset for (int i = 0; i < param_count(); ++i) { int field_offset = get_field_offset_by_index(i); if (field_offset == offset) { // Exact match return i; } else if (field_offset < offset && field_offset > best_offset) { // No exact match. Save the index of the field with the closest offset that // is smaller than the given field offset. This index corresponds to the // flattened value type field that holds the field we are looking for. best_offset = field_offset; best_index = i; } } assert(best_index >= 0, "field not found"); assert(best_offset == offset || get_field_type_by_index(best_index)->is_valuetype(), "offset should match for non-VTs"); return best_index; } // Returns the field offset of the value factory parameter with the given index int ciValueKlass::get_field_offset_by_index(int index) const { // Compute the field index from the factory parameter index valueKlassHandle vklass_h(ValueKlass::cast(get_Klass())); methodHandle factory_h(vklass_h->factory_method()); int field_index = factory_h->constMethod()->valuefactory_parameter_mapping_start()[index].data.field_index; // Get the field offset return vklass_h->field_offset(field_index); } // Returns the field type of the value factory parameter with the given index ciType* ciValueKlass::get_field_type_by_index(int index) { int offset = get_field_offset_by_index(index); VM_ENTRY_MARK; return get_field_type_by_offset(offset); } // Offset of the first field in the value type int ciValueKlass::get_first_field_offset() const { valueKlassHandle vklass_h(ValueKlass::cast(get_Klass())); return vklass_h()->first_field_offset(); }