Mercurial > hg > truffle
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 |