< prev index next >

src/hotspot/share/prims/vectorSupport.cpp

Print this page

        

*** 36,45 **** --- 36,212 ---- #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 >