2230
2231 __ bind(resolved);
2232
2233 // Class initialization barrier for static methods
2234 if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
2235 const Register method = temp;
2236 const Register klass = temp;
2237
2238 __ movptr(method, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
2239 __ load_method_holder(klass, method);
2240 __ clinit_barrier(klass, nullptr /*L_fast_path*/, &L_clinit_barrier_slow);
2241 }
2242 }
2243
2244 void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
2245 Register cache,
2246 Register index) {
2247 const Register temp = rbx;
2248 assert_different_registers(cache, index, temp);
2249
2250 Label resolved;
2251
2252 Bytecodes::Code code = bytecode();
2253 switch (code) {
2254 case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2255 case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2256 default: break;
2257 }
2258
2259 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2260 __ load_field_entry(cache, index);
2261 if (byte_no == f1_byte) {
2262 __ load_unsigned_byte(temp, Address(cache, in_bytes(ResolvedFieldEntry::get_code_offset())));
2263 } else {
2264 __ load_unsigned_byte(temp, Address(cache, in_bytes(ResolvedFieldEntry::put_code_offset())));
2265 }
2266 __ cmpl(temp, code); // have we resolved this bytecode?
2267 __ jcc(Assembler::equal, resolved);
2268
2269 // resolve first time through
2270 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2271 __ movl(temp, code);
2272 __ call_VM(noreg, entry, temp);
2273 // Update registers with resolved info
2274 __ load_field_entry(cache, index);
2275
2276 __ bind(resolved);
2277 }
2278
2279 void TemplateTable::load_resolved_field_entry(Register obj,
2280 Register cache,
2281 Register tos_state,
2282 Register offset,
2283 Register flags,
2284 bool is_static = false) {
2285 assert_different_registers(cache, tos_state, flags, offset);
2286
2287 // Field offset
2288 __ load_sized_value(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
2289
2290 // Flags
2291 __ load_unsigned_byte(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())));
2292
2293 // TOS state
2294 __ load_unsigned_byte(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())));
2295
2296 // Klass overwrite register
|
2230
2231 __ bind(resolved);
2232
2233 // Class initialization barrier for static methods
2234 if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
2235 const Register method = temp;
2236 const Register klass = temp;
2237
2238 __ movptr(method, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
2239 __ load_method_holder(klass, method);
2240 __ clinit_barrier(klass, nullptr /*L_fast_path*/, &L_clinit_barrier_slow);
2241 }
2242 }
2243
2244 void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
2245 Register cache,
2246 Register index) {
2247 const Register temp = rbx;
2248 assert_different_registers(cache, index, temp);
2249
2250 Label L_clinit_barrier_slow;
2251 Label resolved;
2252
2253 Bytecodes::Code code = bytecode();
2254 switch (code) {
2255 case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2256 case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2257 default: break;
2258 }
2259
2260 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2261 __ load_field_entry(cache, index);
2262 if (byte_no == f1_byte) {
2263 __ load_unsigned_byte(temp, Address(cache, in_bytes(ResolvedFieldEntry::get_code_offset())));
2264 } else {
2265 __ load_unsigned_byte(temp, Address(cache, in_bytes(ResolvedFieldEntry::put_code_offset())));
2266 }
2267 __ cmpl(temp, code); // have we resolved this bytecode?
2268 __ jcc(Assembler::equal, resolved);
2269
2270 // resolve first time through
2271 __ bind(L_clinit_barrier_slow);
2272 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2273 __ movl(temp, code);
2274 __ call_VM(noreg, entry, temp);
2275 // Update registers with resolved info
2276 __ load_field_entry(cache, index);
2277
2278 __ bind(resolved);
2279
2280 // Class initialization barrier for static fields
2281 if (VM_Version::supports_fast_class_init_checks() &&
2282 (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
2283 const Register field_holder = temp;
2284 const Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg);
2285 assert(thread != noreg, "x86_32 not supported");
2286
2287 __ movptr(field_holder, Address(cache, in_bytes(ResolvedFieldEntry::field_holder_offset())));
2288 __ clinit_barrier(field_holder, nullptr /*L_fast_path*/, &L_clinit_barrier_slow);
2289 }
2290 }
2291
2292 void TemplateTable::load_resolved_field_entry(Register obj,
2293 Register cache,
2294 Register tos_state,
2295 Register offset,
2296 Register flags,
2297 bool is_static = false) {
2298 assert_different_registers(cache, tos_state, flags, offset);
2299
2300 // Field offset
2301 __ load_sized_value(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
2302
2303 // Flags
2304 __ load_unsigned_byte(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())));
2305
2306 // TOS state
2307 __ load_unsigned_byte(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())));
2308
2309 // Klass overwrite register
|