< prev index next >

src/hotspot/share/opto/runtime.cpp

Print this page

        

*** 47,56 **** --- 47,58 ---- #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #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" #include "opto/cfgnode.hpp" #include "opto/graphKit.hpp"
*** 238,259 **** assert(check_compiled_frame(thread), "incorrect caller"); // Scavenge and allocate an instance. oop result; ! 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(); result = oopFactory::new_typeArray(elem_type, len, THREAD); } else { - // Although the oopFactory likes to work with the elem_type, - // the compiler prefers the array_type, since it must already have - // 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); } // Pass oops back through thread local storage. Our apparent type to Java // is that we return an oop, but we can block on exit from this routine and // a GC can trash the oop in C's return register. The generated stub will --- 240,260 ---- assert(check_compiled_frame(thread), "incorrect caller"); // Scavenge and allocate an instance. oop result; ! if (array_type->is_valueArray_klass()) { ! 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(); result = oopFactory::new_typeArray(elem_type, len, THREAD); } else { Handle holder(THREAD, array_type->klass_holder()); // keep the array klass alive ! result = ObjArrayKlass::cast(array_type)->allocate(len, THREAD); } // Pass oops back through thread local storage. Our apparent type to Java // is that we return an oop, but we can block on exit from this routine and // a GC can trash the oop in C's return register. The generated stub will
*** 563,573 **** // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain,range); } //----------------------------------------------------------------------------- const TypeFunc *OptoRuntime::complete_monitor_exit_Type() { --- 564,574 ---- // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain, range); } //----------------------------------------------------------------------------- const TypeFunc *OptoRuntime::complete_monitor_exit_Type() {
*** 1171,1181 **** // create result type fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = NULL; // void const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); ! return TypeFunc::make(domain,range); } JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) if (receiver == NULL) return; Klass* receiver_klass = receiver->klass(); --- 1172,1182 ---- // create result type fields = TypeTuple::fields(1); fields[TypeFunc::Parms+0] = NULL; // void const TypeTuple *range = TypeTuple::make(TypeFunc::Parms, fields); ! return TypeFunc::make(domain, range); } JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* receiver)) if (receiver == NULL) return; Klass* receiver_klass = receiver->klass();
*** 1490,1500 **** // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain,range); } //----------------------------------------------------------------------------- // Dtrace support. entry and exit probes have the same signature --- 1491,1501 ---- // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain, range); } //----------------------------------------------------------------------------- // Dtrace support. entry and exit probes have the same signature
*** 1508,1518 **** // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain,range); } const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2); --- 1509,1519 ---- // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain, range); } const TypeFunc *OptoRuntime::dtrace_object_alloc_Type() { // create input type (domain) const Type **fields = TypeTuple::fields(2);
*** 1524,1534 **** // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain,range); } JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread)) assert(oopDesc::is_oop(obj), "must be a valid oop"); --- 1525,1535 ---- // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields); ! return TypeFunc::make(domain, range); } JRT_ENTRY_NO_ASYNC(void, OptoRuntime::register_finalizer(oopDesc* obj, JavaThread* thread)) assert(oopDesc::is_oop(obj), "must be a valid oop");
*** 1656,1660 **** --- 1657,1782 ---- tempst.print(" at " INTPTR_FORMAT, p2i(exception_pc)); tempst.print("]"); 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); + }
< prev index next >