< 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,266 ----
assert(check_compiled_frame(thread), "incorrect caller");
// Scavenge and allocate an instance.
oop result;
! 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();
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_array(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
*** 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() {
--- 570,580 ----
// 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();
--- 1178,1188 ----
// 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
--- 1497,1507 ----
// 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);
--- 1515,1525 ----
// 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");
--- 1531,1541 ----
// 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 ****
--- 1663,1788 ----
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 >