< prev index next >
src/share/vm/opto/library_call.cpp
Print this page
@@ -2554,10 +2554,11 @@
return NULL;
}
bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile, bool unaligned) {
if (callee()->is_static()) return false; // caller must have the capability!
+ assert(type != T_OBJECT || !unaligned, "unaligned access not supported with object type");
#ifndef PRODUCT
{
ResourceMark rm;
// Check the signatures.
@@ -2629,18 +2630,39 @@
val = is_store ? argument(3) : NULL;
}
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
- // First guess at the value type.
- const Type *value_type = Type::get_const_basic_type(type);
-
// Try to categorize the address. If it comes up as TypeJavaPtr::BOTTOM,
// there was not enough information to nail it down.
Compile::AliasType* alias_type = C->alias_type(adr_type);
assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
+ assert(alias_type->adr_type() == TypeRawPtr::BOTTOM || alias_type->adr_type() == TypeOopPtr::BOTTOM ||
+ alias_type->basic_type() != T_ILLEGAL, "field, array element or unknown");
+ bool mismatched = false;
+ BasicType bt = alias_type->basic_type();
+ if (bt != T_ILLEGAL) {
+ if (bt == T_BYTE && adr_type->isa_aryptr()) {
+ // Alias type doesn't differentiate between byte[] and boolean[]).
+ // Use address type to get the element type.
+ bt = adr_type->is_aryptr()->elem()->array_element_basic_type();
+ }
+ if (bt == T_ARRAY || bt == T_NARROWOOP) {
+ // accessing an array field with getObject is not a mismatch
+ bt = T_OBJECT;
+ }
+ if ((bt == T_OBJECT) != (type == T_OBJECT)) {
+ // Don't intrinsify mismatched object accesses
+ return false;
+ }
+ mismatched = (bt != type);
+ }
+
+ // First guess at the value type.
+ const Type *value_type = Type::get_const_basic_type(type);
+
// We will need memory barriers unless we can determine a unique
// alias category for this reference. (Note: If for some reason
// the barriers get omitted and the unsafe reference begins to "pollute"
// the alias analysis of the rest of the graph, either Compile::can_alias
// or Compile::must_alias will throw a diagnostic assert.)
@@ -2695,27 +2717,10 @@
// so there's no problems making a strong assert about mixing users
// of safe & unsafe memory. Otherwise fails in a CTW of rt.jar
// around 5701, class sun/reflect/UnsafeBooleanFieldAccessorImpl.
if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
- assert(alias_type->adr_type() == TypeRawPtr::BOTTOM || alias_type->adr_type() == TypeOopPtr::BOTTOM ||
- alias_type->field() != NULL || alias_type->element() != NULL, "field, array element or unknown");
- bool mismatched = false;
- if (alias_type->element() != NULL || alias_type->field() != NULL) {
- BasicType bt;
- if (alias_type->element() != NULL) {
- const Type* element = alias_type->element();
- bt = element->isa_narrowoop() ? T_OBJECT : element->array_element_basic_type();
- } else {
- bt = alias_type->field()->type()->basic_type();
- }
- if (bt != type) {
- mismatched = true;
- }
- }
- assert(type != T_OBJECT || !unaligned, "unaligned access not supported with object type");
-
if (!is_store) {
MemNode::MemOrd mo = is_volatile ? MemNode::acquire : MemNode::unordered;
// To be valid, unsafe loads may depend on other conditions than
// the one that guards them: pin the Load node
Node* p = make_load(control(), adr, value_type, type, adr_type, mo, LoadNode::Pinned, is_volatile, unaligned, mismatched);
@@ -2970,15 +2975,24 @@
// 32-bit machines ignore the high half of long offsets
offset = ConvL2X(offset);
Node* adr = make_unsafe_address(base, offset);
const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
+ Compile::AliasType* alias_type = C->alias_type(adr_type);
+ assert(alias_type->adr_type() == TypeRawPtr::BOTTOM || alias_type->adr_type() == TypeOopPtr::BOTTOM ||
+ alias_type->basic_type() != T_ILLEGAL, "field, array element or unknown");
+ BasicType bt = alias_type->basic_type();
+ if (bt != T_ILLEGAL &&
+ ((bt == T_OBJECT || bt == T_ARRAY) != (type == T_OBJECT))) {
+ // Don't intrinsify mismatched object accesses.
+ return false;
+ }
+
// For CAS, unlike inline_unsafe_access, there seems no point in
// trying to refine types. Just use the coarse types here.
- const Type *value_type = Type::get_const_basic_type(type);
- Compile::AliasType* alias_type = C->alias_type(adr_type);
assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
+ const Type *value_type = Type::get_const_basic_type(type);
if (kind == LS_xchg && type == T_OBJECT) {
const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
if (tjp != NULL) {
value_type = tjp;
< prev index next >