--- old/src/hotspot/share/opto/runtime.cpp 2019-03-11 14:26:56.762354455 +0100 +++ new/src/hotspot/share/opto/runtime.cpp 2019-03-11 14:26:56.550354458 +0100 @@ -49,6 +49,8 @@ #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.inline.hpp" +#include "oops/valueArrayKlass.hpp" +#include "oops/valueArrayOop.inline.hpp" #include "opto/ad.hpp" #include "opto/addnode.hpp" #include "opto/callnode.hpp" @@ -240,7 +242,12 @@ // Scavenge and allocate an instance. oop result; - if (array_type->is_typeArray_klass()) { + if (array_type->is_valueArray_klass()) { + // TODO refactor all these checks, is_typeArray_klass should not be true for a value type array + // TODO use oopFactory::new_array + Klass* elem_type = ValueArrayKlass::cast(array_type)->element_klass(); + result = oopFactory::new_valueArray(elem_type, len, THREAD); + } else if (array_type->is_typeArray_klass()) { // The oopFactory likes to work with the element type. // (We could bypass the oopFactory, since it doesn't add much value.) BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type(); @@ -251,7 +258,7 @@ // that latter value in hand for the fast path. Handle holder(THREAD, array_type->klass_holder()); // keep the array klass alive Klass* elem_type = ObjArrayKlass::cast(array_type)->element_klass(); - result = oopFactory::new_objArray(elem_type, len, THREAD); + result = oopFactory::new_array(elem_type, len, THREAD); } // Pass oops back through thread local storage. Our apparent type to Java @@ -565,7 +572,7 @@ const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); - return TypeFunc::make(domain,range); + return TypeFunc::make(domain, range); } @@ -1173,7 +1180,7 @@ fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = NULL; // void const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); - return TypeFunc::make(domain,range); + return TypeFunc::make(domain, range); } JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) @@ -1492,7 +1499,7 @@ const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); - return TypeFunc::make(domain,range); + return TypeFunc::make(domain, range); } @@ -1510,7 +1517,7 @@ const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); - return TypeFunc::make(domain,range); + return TypeFunc::make(domain, range); } const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { @@ -1526,7 +1533,7 @@ const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); - return TypeFunc::make(domain,range); + return TypeFunc::make(domain, range); } @@ -1658,3 +1665,124 @@ st->print_raw_cr(tempst.as_string()); } + +const TypeFunc *OptoRuntime::store_value_type_fields_Type() { + // create input type (domain) + uint total = SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2; + const Type **fields = TypeTuple::fields(total); + // We don't know the number of returned values and their + // types. Assume all registers available to the return convention + // are used. + fields[TypeFunc::Parms] = TypePtr::BOTTOM; + uint i = 1; + for (; i < SharedRuntime::java_return_convention_max_int; i++) { + fields[TypeFunc::Parms+i] = TypeInt::INT; + } + for (; i < total; i+=2) { + fields[TypeFunc::Parms+i] = Type::DOUBLE; + fields[TypeFunc::Parms+i+1] = Type::HALF; + } + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields); + + // create result type (range) + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; + + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields); + + return TypeFunc::make(domain, range); +} + +const TypeFunc *OptoRuntime::pack_value_type_Type() { + // create input type (domain) + uint total = 1 + SharedRuntime::java_return_convention_max_int + SharedRuntime::java_return_convention_max_float*2; + const Type **fields = TypeTuple::fields(total); + // We don't know the number of returned values and their + // types. Assume all registers available to the return convention + // are used. + fields[TypeFunc::Parms] = TypeRawPtr::BOTTOM; + fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; + uint i = 2; + for (; i < SharedRuntime::java_return_convention_max_int+1; i++) { + fields[TypeFunc::Parms+i] = TypeInt::INT; + } + for (; i < total; i+=2) { + fields[TypeFunc::Parms+i] = Type::DOUBLE; + fields[TypeFunc::Parms+i+1] = Type::HALF; + } + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms + total, fields); + + // create result type (range) + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; + + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1,fields); + + return TypeFunc::make(domain, range); +} + +JRT_LEAF(void, OptoRuntime::load_unknown_value(valueArrayOopDesc* array, int index, instanceOopDesc* buffer)) +{ + Klass* klass = array->klass(); + assert(klass->is_valueArray_klass(), "expected value array oop"); + + ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); + ValueKlass* vklass = vaklass->element_klass(); + void* src = array->value_at_addr(index, vaklass->layout_helper()); + vklass->value_store(src, vklass->data_for_oop(buffer), + vaklass->element_byte_size(), true, false); +} +JRT_END + +const TypeFunc *OptoRuntime::load_unknown_value_Type() { + // create input type (domain) + const Type **fields = TypeTuple::fields(3); + // We don't know the number of returned values and their + // types. Assume all registers available to the return convention + // are used. + fields[TypeFunc::Parms] = TypeOopPtr::NOTNULL; + fields[TypeFunc::Parms+1] = TypeInt::POS; + fields[TypeFunc::Parms+2] = TypeInstPtr::NOTNULL; + + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields); + + // create result type (range) + fields = TypeTuple::fields(0); + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); + + return TypeFunc::make(domain, range); +} + +JRT_LEAF(void, OptoRuntime::store_unknown_value(instanceOopDesc* buffer, valueArrayOopDesc* array, int index)) +{ + assert(buffer != NULL, "can't store null into flat array"); + Klass* klass = array->klass(); + assert(klass->is_valueArray_klass(), "expected value array"); + assert(ArrayKlass::cast(klass)->element_klass() == buffer->klass(), "Store type incorrect"); + + ValueArrayKlass* vaklass = ValueArrayKlass::cast(klass); + ValueKlass* vklass = vaklass->element_klass(); + const int lh = vaklass->layout_helper(); + vklass->value_store(vklass->data_for_oop(buffer), array->value_at_addr(index, lh), + vaklass->element_byte_size(), true, false); +} +JRT_END + +const TypeFunc *OptoRuntime::store_unknown_value_Type() { + // create input type (domain) + const Type **fields = TypeTuple::fields(3); + // We don't know the number of returned values and their + // types. Assume all registers available to the return convention + // are used. + fields[TypeFunc::Parms] = TypeInstPtr::NOTNULL; + fields[TypeFunc::Parms+1] = TypeOopPtr::NOTNULL; + fields[TypeFunc::Parms+2] = TypeInt::POS; + + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+3, fields); + + // create result type (range) + fields = TypeTuple::fields(0); + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); + + return TypeFunc::make(domain, range); +}