Skip to content
Permalink
Browse files

8239142: C2's UseUniqueSubclasses optimization is broken for array ac…

…cesses

Avoid resetting the elemtype for array accesses.

Reviewed-by: vlivanov, eosterlund
  • Loading branch information
Tobias Hartmann
Tobias Hartmann committed Feb 18, 2020
1 parent 4e430ff commit cb2eeb7d9aa84be816186f76a554fd78b9484a61
Showing with 6 additions and 15 deletions.
  1. +1 −1 src/hotspot/share/opto/parse.hpp
  2. +5 −14 src/hotspot/share/opto/parse2.cpp
@@ -480,7 +480,7 @@ class Parse : public GraphKit {
// Helper function to generate array store
void array_store(BasicType etype);
// Helper function to compute array addressing
Node* array_addressing(BasicType type, int vals, const Type* *result2=NULL);
Node* array_addressing(BasicType type, int vals, const Type*& elemtype);

void clinit_deopt();

@@ -54,18 +54,15 @@ extern int explicit_null_checks_inserted,
void Parse::array_load(BasicType bt) {
const Type* elemtype = Type::TOP;
bool big_val = bt == T_DOUBLE || bt == T_LONG;
Node* adr = array_addressing(bt, 0, &elemtype);
Node* adr = array_addressing(bt, 0, elemtype);
if (stopped()) return; // guaranteed null or range check

pop(); // index (already used)
Node* array = pop(); // the array itself

if (elemtype == TypeInt::BOOL) {
bt = T_BOOLEAN;
} else if (bt == T_OBJECT) {
elemtype = _gvn.type(array)->is_aryptr()->elem()->make_oopptr();
}

const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);

Node* ld = access_load_at(array, adr, adr_type, elemtype, bt,
@@ -82,7 +79,7 @@ void Parse::array_load(BasicType bt) {
void Parse::array_store(BasicType bt) {
const Type* elemtype = Type::TOP;
bool big_val = bt == T_DOUBLE || bt == T_LONG;
Node* adr = array_addressing(bt, big_val ? 2 : 1, &elemtype);
Node* adr = array_addressing(bt, big_val ? 2 : 1, elemtype);
if (stopped()) return; // guaranteed null or range check
if (bt == T_OBJECT) {
array_store_check();
@@ -98,10 +95,7 @@ void Parse::array_store(BasicType bt) {

if (elemtype == TypeInt::BOOL) {
bt = T_BOOLEAN;
} else if (bt == T_OBJECT) {
elemtype = _gvn.type(array)->is_aryptr()->elem()->make_oopptr();
}

const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);

access_store_at(array, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
@@ -110,7 +104,7 @@ void Parse::array_store(BasicType bt) {

//------------------------------array_addressing-------------------------------
// Pull array and index from the stack. Compute pointer-to-element.
Node* Parse::array_addressing(BasicType type, int vals, const Type* *result2) {
Node* Parse::array_addressing(BasicType type, int vals, const Type*& elemtype) {
Node *idx = peek(0+vals); // Get from stack without popping
Node *ary = peek(1+vals); // in case of exception

@@ -121,9 +115,9 @@ Node* Parse::array_addressing(BasicType type, int vals, const Type* *result2) {

const TypeAryPtr* arytype = _gvn.type(ary)->is_aryptr();
const TypeInt* sizetype = arytype->size();
const Type* elemtype = arytype->elem();
elemtype = arytype->elem();

if (UseUniqueSubclasses && result2 != NULL) {
if (UseUniqueSubclasses) {
const Type* el = elemtype->make_ptr();
if (el && el->isa_instptr()) {
const TypeInstPtr* toop = el->is_instptr();
@@ -207,9 +201,6 @@ Node* Parse::array_addressing(BasicType type, int vals, const Type* *result2) {
// Make array address computation control dependent to prevent it
// from floating above the range check during loop optimizations.
Node* ptr = array_element_address(ary, idx, type, sizetype, control());

if (result2 != NULL) *result2 = elemtype;

assert(ptr != top(), "top should go hand-in-hand with stopped");

return ptr;

0 comments on commit cb2eeb7

Please sign in to comment.