< prev index next >

src/share/vm/ci/ciValueKlass.cpp

Print this page

        

@@ -24,37 +24,69 @@
 
 #include "ci/ciField.hpp"
 #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()));
   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);
 }
 
-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();
 }
< prev index next >