comparison src/share/vm/c1/c1_LIRGenerator.cpp @ 20491:a60a1309a03a

8058744: Crash in C1 OSRed method w/ Unsafe usage Summary: Fix UnsafeRawOp optimizations Reviewed-by: kvn, drchase, vlivanov
author iveresov
date Tue, 23 Sep 2014 15:09:07 -0700
parents 2fd0fd493045
children b29261b17343
comparison
equal deleted inserted replaced
20490:97ad90b2712c 20491:a60a1309a03a
2040 __ roundfp(input_opr, LIR_OprFact::illegalOpr, result); 2040 __ roundfp(input_opr, LIR_OprFact::illegalOpr, result);
2041 set_result(x, result); 2041 set_result(x, result);
2042 } 2042 }
2043 } 2043 }
2044 2044
2045 // Here UnsafeGetRaw may have x->base() and x->index() be int or long
2046 // on both 64 and 32 bits. Expecting x->base() to be always long on 64bit.
2045 void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) { 2047 void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
2046 LIRItem base(x->base(), this); 2048 LIRItem base(x->base(), this);
2047 LIRItem idx(this); 2049 LIRItem idx(this);
2048 2050
2049 base.load_item(); 2051 base.load_item();
2054 2056
2055 LIR_Opr reg = rlock_result(x, x->basic_type()); 2057 LIR_Opr reg = rlock_result(x, x->basic_type());
2056 2058
2057 int log2_scale = 0; 2059 int log2_scale = 0;
2058 if (x->has_index()) { 2060 if (x->has_index()) {
2059 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
2060 log2_scale = x->log2_scale(); 2061 log2_scale = x->log2_scale();
2061 } 2062 }
2062 2063
2063 assert(!x->has_index() || idx.value() == x->index(), "should match"); 2064 assert(!x->has_index() || idx.value() == x->index(), "should match");
2064 2065
2065 LIR_Opr base_op = base.result(); 2066 LIR_Opr base_op = base.result();
2067 LIR_Opr index_op = idx.result();
2066 #ifndef _LP64 2068 #ifndef _LP64
2067 if (x->base()->type()->tag() == longTag) { 2069 if (x->base()->type()->tag() == longTag) {
2068 base_op = new_register(T_INT); 2070 base_op = new_register(T_INT);
2069 __ convert(Bytecodes::_l2i, base.result(), base_op); 2071 __ convert(Bytecodes::_l2i, base.result(), base_op);
2070 } else { 2072 }
2071 assert(x->base()->type()->tag() == intTag, "must be"); 2073 if (x->has_index()) {
2072 } 2074 if (x->index()->type()->tag() == longTag) {
2075 LIR_Opr long_index_op = index_op;
2076 if (x->index()->type()->is_constant()) {
2077 long_index_op = new_register(T_LONG);
2078 __ move(index_op, long_index_op);
2079 }
2080 index_op = new_register(T_INT);
2081 __ convert(Bytecodes::_l2i, long_index_op, index_op);
2082 } else {
2083 assert(x->index()->type()->tag() == intTag, "must be");
2084 }
2085 }
2086 // At this point base and index should be all ints.
2087 assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
2088 assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
2089 #else
2090 if (x->has_index()) {
2091 if (x->index()->type()->tag() == intTag) {
2092 if (!x->index()->type()->is_constant()) {
2093 index_op = new_register(T_LONG);
2094 __ convert(Bytecodes::_i2l, idx.result(), index_op);
2095 }
2096 } else {
2097 assert(x->index()->type()->tag() == longTag, "must be");
2098 if (x->index()->type()->is_constant()) {
2099 index_op = new_register(T_LONG);
2100 __ move(idx.result(), index_op);
2101 }
2102 }
2103 }
2104 // At this point base is a long non-constant
2105 // Index is a long register or a int constant.
2106 // We allow the constant to stay an int because that would allow us a more compact encoding by
2107 // embedding an immediate offset in the address expression. If we have a long constant, we have to
2108 // move it into a register first.
2109 assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a long non-constant");
2110 assert(!x->has_index() || (index_op->type() == T_INT && index_op->is_constant()) ||
2111 (index_op->type() == T_LONG && !index_op->is_constant()), "unexpected index type");
2073 #endif 2112 #endif
2074 2113
2075 BasicType dst_type = x->basic_type(); 2114 BasicType dst_type = x->basic_type();
2076 LIR_Opr index_op = idx.result();
2077 2115
2078 LIR_Address* addr; 2116 LIR_Address* addr;
2079 if (index_op->is_constant()) { 2117 if (index_op->is_constant()) {
2080 assert(log2_scale == 0, "must not have a scale"); 2118 assert(log2_scale == 0, "must not have a scale");
2119 assert(index_op->type() == T_INT, "only int constants supported");
2081 addr = new LIR_Address(base_op, index_op->as_jint(), dst_type); 2120 addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
2082 } else { 2121 } else {
2083 #ifdef X86 2122 #ifdef X86
2084 #ifdef _LP64
2085 if (!index_op->is_illegal() && index_op->type() == T_INT) {
2086 LIR_Opr tmp = new_pointer_register();
2087 __ convert(Bytecodes::_i2l, index_op, tmp);
2088 index_op = tmp;
2089 }
2090 #endif
2091 addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type); 2123 addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
2092 #elif defined(ARM) 2124 #elif defined(ARM)
2093 addr = generate_address(base_op, index_op, log2_scale, 0, dst_type); 2125 addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
2094 #else 2126 #else
2095 if (index_op->is_illegal() || log2_scale == 0) { 2127 if (index_op->is_illegal() || log2_scale == 0) {
2096 #ifdef _LP64
2097 if (!index_op->is_illegal() && index_op->type() == T_INT) {
2098 LIR_Opr tmp = new_pointer_register();
2099 __ convert(Bytecodes::_i2l, index_op, tmp);
2100 index_op = tmp;
2101 }
2102 #endif
2103 addr = new LIR_Address(base_op, index_op, dst_type); 2128 addr = new LIR_Address(base_op, index_op, dst_type);
2104 } else { 2129 } else {
2105 LIR_Opr tmp = new_pointer_register(); 2130 LIR_Opr tmp = new_pointer_register();
2106 __ shift_left(index_op, log2_scale, tmp); 2131 __ shift_left(index_op, log2_scale, tmp);
2107 addr = new LIR_Address(base_op, tmp, dst_type); 2132 addr = new LIR_Address(base_op, tmp, dst_type);
2124 void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) { 2149 void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) {
2125 int log2_scale = 0; 2150 int log2_scale = 0;
2126 BasicType type = x->basic_type(); 2151 BasicType type = x->basic_type();
2127 2152
2128 if (x->has_index()) { 2153 if (x->has_index()) {
2129 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
2130 log2_scale = x->log2_scale(); 2154 log2_scale = x->log2_scale();
2131 } 2155 }
2132 2156
2133 LIRItem base(x->base(), this); 2157 LIRItem base(x->base(), this);
2134 LIRItem value(x->value(), this); 2158 LIRItem value(x->value(), this);
2147 } 2171 }
2148 2172
2149 set_no_result(x); 2173 set_no_result(x);
2150 2174
2151 LIR_Opr base_op = base.result(); 2175 LIR_Opr base_op = base.result();
2176 LIR_Opr index_op = idx.result();
2177
2152 #ifndef _LP64 2178 #ifndef _LP64
2153 if (x->base()->type()->tag() == longTag) { 2179 if (x->base()->type()->tag() == longTag) {
2154 base_op = new_register(T_INT); 2180 base_op = new_register(T_INT);
2155 __ convert(Bytecodes::_l2i, base.result(), base_op); 2181 __ convert(Bytecodes::_l2i, base.result(), base_op);
2156 } else { 2182 }
2157 assert(x->base()->type()->tag() == intTag, "must be"); 2183 if (x->has_index()) {
2158 } 2184 if (x->index()->type()->tag() == longTag) {
2185 index_op = new_register(T_INT);
2186 __ convert(Bytecodes::_l2i, idx.result(), index_op);
2187 }
2188 }
2189 // At this point base and index should be all ints and not constants
2190 assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
2191 assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
2192 #else
2193 if (x->has_index()) {
2194 if (x->index()->type()->tag() == intTag) {
2195 index_op = new_register(T_LONG);
2196 __ convert(Bytecodes::_i2l, idx.result(), index_op);
2197 }
2198 }
2199 // At this point base and index are long and non-constant
2200 assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a non-constant long");
2201 assert(!x->has_index() || (index_op->type() == T_LONG && !index_op->is_constant()), "index must be a non-constant long");
2159 #endif 2202 #endif
2160 2203
2161 LIR_Opr index_op = idx.result();
2162 if (log2_scale != 0) { 2204 if (log2_scale != 0) {
2163 // temporary fix (platform dependent code without shift on Intel would be better) 2205 // temporary fix (platform dependent code without shift on Intel would be better)
2164 index_op = new_pointer_register(); 2206 // TODO: ARM also allows embedded shift in the address
2165 #ifdef _LP64
2166 if(idx.result()->type() == T_INT) {
2167 __ convert(Bytecodes::_i2l, idx.result(), index_op);
2168 } else {
2169 #endif
2170 // TODO: ARM also allows embedded shift in the address
2171 __ move(idx.result(), index_op);
2172 #ifdef _LP64
2173 }
2174 #endif
2175 __ shift_left(index_op, log2_scale, index_op); 2207 __ shift_left(index_op, log2_scale, index_op);
2176 } 2208 }
2177 #ifdef _LP64
2178 else if(!index_op->is_illegal() && index_op->type() == T_INT) {
2179 LIR_Opr tmp = new_pointer_register();
2180 __ convert(Bytecodes::_i2l, index_op, tmp);
2181 index_op = tmp;
2182 }
2183 #endif
2184 2209
2185 LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type()); 2210 LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
2186 __ move(value.result(), addr); 2211 __ move(value.result(), addr);
2187 } 2212 }
2188 2213