--- old/src/share/vm/ci/ciValueKlass.cpp 2016-11-16 09:06:10.326498529 +0100 +++ new/src/share/vm/ci/ciValueKlass.cpp 2016-11-16 09:06:10.258498528 +0100 @@ -26,20 +26,49 @@ #include "ci/ciValueKlass.hpp" #include "oops/valueKlass.hpp" -int ciValueKlass::get_field_index_by_offset(int offset) { - // TODO do we need handles here? +// 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()); - // Search field with field_offset and return factory parameter index - for (int index = 0; index < field_count(); ++index) { - if (get_field_offset_by_index(index) == offset) { - return index; + 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; } } - ShouldNotReachHere(); - return -1; + 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())); @@ -49,12 +78,15 @@ return vklass_h->field_offset(field_index); } -BasicType ciValueKlass::get_field_type_by_index(int index) const { - // Compute the field index from the factory parameter 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())); - methodHandle factory_h(vklass_h->factory_method()); - int field_index = factory_h->constMethod()->valuefactory_parameter_mapping_start()[index].data.field_index; - // Get the basic type of the field - Symbol* signature = vklass_h->field_signature(field_index); - return vmSymbols::signature_type(signature); + return vklass_h()->first_field_offset(); }