< prev index next >

src/hotspot/share/prims/vectorSupport.cpp

Print this page

        

@@ -36,10 +36,177 @@
 
 #ifdef COMPILER2
 #include "opto/matcher.hpp" // Matcher::max_vector_size(BasicType)
 #endif // COMPILER2
 
+bool VectorSupport::is_vector(Klass* klass) {
+  return klass->is_subclass_of(SystemDictionary::vector_VectorPayload_klass());
+}
+
+bool VectorSupport::is_vector_mask(Klass* klass) {
+  return klass->is_subclass_of(SystemDictionary::vector_VectorMask_klass());
+}
+
+bool VectorSupport::is_vector_shuffle(Klass* klass) {
+  return klass->is_subclass_of(SystemDictionary::vector_VectorShuffle_klass());
+}
+
+BasicType VectorSupport::klass2bt(InstanceKlass* ik) {
+  assert(ik->is_subclass_of(SystemDictionary::vector_VectorPayload_klass()), "%s not a VectorPayload", ik->name()->as_C_string());
+  fieldDescriptor fd; // find_field initializes fd if found
+  // static final Class<?> ETYPE;
+  Klass* holder = ik->find_field(vmSymbols::ETYPE_name(), vmSymbols::class_signature(), &fd);
+
+  assert(holder != NULL, "sanity");
+  assert(fd.is_static(), "");
+  assert(fd.offset() > 0, "");
+
+  if (is_vector_shuffle(ik)) {
+    return T_BYTE;
+  } else { // vector and mask
+    oop value = ik->java_mirror()->obj_field(fd.offset());
+    BasicType elem_bt = java_lang_Class::as_BasicType(value);
+    return elem_bt;
+  }
+}
+
+jint VectorSupport::klass2length(InstanceKlass* ik) {
+  fieldDescriptor fd; // find_field initializes fd if found
+  // static final int VLENGTH;
+  Klass* holder = ik->find_field(vmSymbols::VLENGTH_name(), vmSymbols::int_signature(), &fd);
+
+  assert(holder != NULL, "sanity");
+  assert(fd.is_static(), "");
+  assert(fd.offset() > 0, "");
+
+  jint vlen = ik->java_mirror()->int_field(fd.offset());
+  assert(vlen > 0, "");
+  return vlen;
+}
+
+void VectorSupport::init_vector_array(typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr) {
+  int elem_size = type2aelembytes(elem_bt);
+  for (int i = 0; i < num_elem; i++) {
+    switch (elem_bt) {
+      case T_BYTE: {
+        jbyte elem_value = *(jbyte*) (value_addr + i * elem_size);
+        arr->byte_at_put(i, elem_value);
+        break;
+      }
+      case T_SHORT: {
+        jshort elem_value = *(jshort*) (value_addr + i * elem_size);
+        arr->short_at_put(i, elem_value);
+        break;
+      }
+      case T_INT: {
+        jint elem_value = *(jint*) (value_addr + i * elem_size);
+        arr->int_at_put(i, elem_value);
+        break;
+      }
+      case T_LONG: {
+        jlong elem_value = *(jlong*) (value_addr + i * elem_size);
+        arr->long_at_put(i, elem_value);
+        break;
+      }
+      case T_FLOAT: {
+        jfloat elem_value = *(jfloat*) (value_addr + i * elem_size);
+        arr->float_at_put(i, elem_value);
+        break;
+      }
+      case T_DOUBLE: {
+        jdouble elem_value = *(jdouble*) (value_addr + i * elem_size);
+        arr->double_at_put(i, elem_value);
+        break;
+      }
+      default:
+        fatal("unsupported: %s", type2name(elem_bt));
+    }
+  }
+}
+
+void VectorSupport::init_mask_array(typeArrayOop arr, BasicType elem_bt, int num_elem, address value_addr) {
+  int elem_size = type2aelembytes(elem_bt);
+
+  for (int i = 0; i < num_elem; i++) {
+    switch (elem_bt) {
+      case T_BYTE: {
+        jbyte elem_value = *(jbyte*) (value_addr + i * elem_size);
+        arr->bool_at_put(i, elem_value != 0);
+        break;
+      }
+      case T_SHORT: {
+        jshort elem_value = *(jshort*) (value_addr + i * elem_size);
+        arr->bool_at_put(i, elem_value != 0);
+        break;
+      }
+      case T_INT:   // fall-through
+      case T_FLOAT: {
+        jint elem_value = *(jint*) (value_addr + i * elem_size);
+        arr->bool_at_put(i, elem_value != 0);
+        break;
+      }
+      case T_LONG: // fall-through
+      case T_DOUBLE: {
+        jlong elem_value = *(jlong*) (value_addr + i * elem_size);
+        arr->bool_at_put(i, elem_value != 0);
+        break;
+      }
+      default:
+        fatal("unsupported: %s", type2name(elem_bt));
+    }
+  }
+}
+
+oop VectorSupport::allocate_vector_payload_helper(InstanceKlass* ik, BasicType elem_bt, int num_elem, address value_addr, TRAPS) {
+
+  bool is_mask = is_vector_mask(ik);
+
+  // On-heap vector values are represented as primitive arrays.
+  TypeArrayKlass* tak = TypeArrayKlass::cast(Universe::typeArrayKlassObj(is_mask ? T_BOOLEAN : elem_bt));
+
+  typeArrayOop arr = tak->allocate(num_elem, CHECK_NULL); // safepoint
+
+  if (is_mask) {
+    init_mask_array(arr, elem_bt, num_elem, value_addr);
+  } else {
+    init_vector_array(arr, elem_bt, num_elem, value_addr);
+  }
+  return arr;
+}
+
+oop VectorSupport::allocate_vector(InstanceKlass* ik, frame* fr, RegisterMap* reg_map, ObjectValue* ov, TRAPS) {
+  assert(is_vector(ik), "%s not a vector", ik->name()->as_C_string());
+  assert(ov->field_size() == 1, "%s not a vector", ik->name()->as_C_string());
+
+  // Vector value in an aligned adjacent tuple (1, 2, 4, 8, or 16 slots).
+  LocationValue* loc_value = ov->field_at(0)->as_LocationValue();
+
+  BasicType elem_bt = klass2bt(ik);
+  int num_elem = klass2length(ik);
+
+  Handle vbox = ik->allocate_instance_handle(CHECK_NULL);
+
+  Location loc = loc_value->location();
+
+  oop payload = NULL;
+  if (loc.type() == Location::vector) {
+    address value_addr = loc.is_register()
+        // Value was in a callee-save register
+        ? reg_map->location(VMRegImpl::as_VMReg(loc.register_number()))
+        // Else value was directly saved on the stack. The frame's original stack pointer,
+        // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used.
+        : ((address)fr->unextended_sp()) + loc.stack_offset();
+    payload = allocate_vector_payload_helper(ik, elem_bt, num_elem, value_addr, CHECK_NULL); // safepoint
+  } else {
+    // assert(false, "interesting");
+    StackValue* value = StackValue::create_stack_value(fr, reg_map, loc_value);
+    payload = value->get_obj()();
+  }
+  vector_VectorPayload::set_payload(vbox(), payload);
+  return vbox();
+}
+
 #ifdef COMPILER2
 int VectorSupport::vop2ideal(jint id, BasicType bt) {
   VectorOperation vop = (VectorOperation)id;
   switch (vop) {
     case VECTOR_OP_ADD: {
< prev index next >