335 const int tags_offset = Array<u1>::base_offset_in_bytes();
336
337 // get type
338 __ add(r3, r1, tags_offset);
339 __ lea(r3, Address(r0, r3));
340 __ ldarb(r3, r3);
341
342 // unresolved class - get the resolved class
343 __ cmp(r3, (u1)JVM_CONSTANT_UnresolvedClass);
344 __ br(Assembler::EQ, call_ldc);
345
346 // unresolved class in error state - call into runtime to throw the error
347 // from the first resolution attempt
348 __ cmp(r3, (u1)JVM_CONSTANT_UnresolvedClassInError);
349 __ br(Assembler::EQ, call_ldc);
350
351 // resolved class - need to call vm to get java mirror of the class
352 __ cmp(r3, (u1)JVM_CONSTANT_Class);
353 __ br(Assembler::NE, notClass);
354
355 __ bind(call_ldc);
356 __ mov(c_rarg1, is_ldc_wide(type) ? 1 : 0);
357 call_VM(r0, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), c_rarg1);
358 __ push_ptr(r0);
359 __ verify_oop(r0);
360 __ b(Done);
361
362 __ bind(notClass);
363 __ cmp(r3, (u1)JVM_CONSTANT_Float);
364 __ br(Assembler::NE, notFloat);
365 // ftos
366 __ adds(r1, r2, r1, Assembler::LSL, 3);
367 __ ldrs(v0, Address(r1, base_offset));
368 __ push_f();
369 __ b(Done);
370
371 __ bind(notFloat);
372
373 __ cmp(r3, (u1)JVM_CONSTANT_Integer);
374 __ br(Assembler::NE, notInt);
2292 // Update registers with resolved info
2293 __ load_method_entry(Rcache, index);
2294 // n.b. unlike x86 Rcache is now rcpool plus the indexed offset
2295 // so all clients ofthis method must be modified accordingly
2296 __ bind(resolved);
2297
2298 // Class initialization barrier for static methods
2299 if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
2300 __ ldr(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
2301 __ load_method_holder(temp, temp);
2302 __ clinit_barrier(temp, rscratch1, nullptr, &clinit_barrier_slow);
2303 }
2304 }
2305
2306 void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
2307 Register Rcache,
2308 Register index) {
2309 const Register temp = r19;
2310 assert_different_registers(Rcache, index, temp);
2311
2312 Label resolved;
2313
2314 Bytecodes::Code code = bytecode();
2315 switch (code) {
2316 case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2317 case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2318 default: break;
2319 }
2320
2321 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2322 __ load_field_entry(Rcache, index);
2323 if (byte_no == f1_byte) {
2324 __ lea(temp, Address(Rcache, in_bytes(ResolvedFieldEntry::get_code_offset())));
2325 } else {
2326 __ lea(temp, Address(Rcache, in_bytes(ResolvedFieldEntry::put_code_offset())));
2327 }
2328 // Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
2329 __ ldarb(temp, temp);
2330 __ subs(zr, temp, (int) code); // have we resolved this bytecode?
2331 __ br(Assembler::EQ, resolved);
2332
2333 // resolve first time through
2334 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2335 __ mov(temp, (int) code);
2336 __ call_VM(noreg, entry, temp);
2337
2338 // Update registers with resolved info
2339 __ load_field_entry(Rcache, index);
2340 __ bind(resolved);
2341 }
2342
2343 void TemplateTable::load_resolved_field_entry(Register obj,
2344 Register cache,
2345 Register tos_state,
2346 Register offset,
2347 Register flags,
2348 bool is_static = false) {
2349 assert_different_registers(cache, tos_state, flags, offset);
2350
2351 // Field offset
2352 __ load_sized_value(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
2353
2354 // Flags
2355 __ load_unsigned_byte(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())));
2356
2357 // TOS state
2358 if (tos_state != noreg) {
2359 __ load_unsigned_byte(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())));
2360 }
|
335 const int tags_offset = Array<u1>::base_offset_in_bytes();
336
337 // get type
338 __ add(r3, r1, tags_offset);
339 __ lea(r3, Address(r0, r3));
340 __ ldarb(r3, r3);
341
342 // unresolved class - get the resolved class
343 __ cmp(r3, (u1)JVM_CONSTANT_UnresolvedClass);
344 __ br(Assembler::EQ, call_ldc);
345
346 // unresolved class in error state - call into runtime to throw the error
347 // from the first resolution attempt
348 __ cmp(r3, (u1)JVM_CONSTANT_UnresolvedClassInError);
349 __ br(Assembler::EQ, call_ldc);
350
351 // resolved class - need to call vm to get java mirror of the class
352 __ cmp(r3, (u1)JVM_CONSTANT_Class);
353 __ br(Assembler::NE, notClass);
354
355 __ load_resolved_klass_at_offset(r2, r1, r3, rscratch1); // kills r3=tag
356
357 __ cmp(r3, zr); // resolved_klass ?= null
358 __ br(Assembler::EQ, call_ldc);
359
360 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
361 __ ldr(r3, Address(r3, mirror_offset));
362 __ resolve_oop_handle(r3, rscratch1, rscratch2);
363 __ push_ptr(r3);
364
365 __ b(Done);
366
367 __ bind(call_ldc);
368 __ mov(c_rarg1, is_ldc_wide(type) ? 1 : 0);
369 call_VM(r0, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), c_rarg1);
370 __ push_ptr(r0);
371 __ verify_oop(r0);
372 __ b(Done);
373
374 __ bind(notClass);
375 __ cmp(r3, (u1)JVM_CONSTANT_Float);
376 __ br(Assembler::NE, notFloat);
377 // ftos
378 __ adds(r1, r2, r1, Assembler::LSL, 3);
379 __ ldrs(v0, Address(r1, base_offset));
380 __ push_f();
381 __ b(Done);
382
383 __ bind(notFloat);
384
385 __ cmp(r3, (u1)JVM_CONSTANT_Integer);
386 __ br(Assembler::NE, notInt);
2304 // Update registers with resolved info
2305 __ load_method_entry(Rcache, index);
2306 // n.b. unlike x86 Rcache is now rcpool plus the indexed offset
2307 // so all clients ofthis method must be modified accordingly
2308 __ bind(resolved);
2309
2310 // Class initialization barrier for static methods
2311 if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
2312 __ ldr(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
2313 __ load_method_holder(temp, temp);
2314 __ clinit_barrier(temp, rscratch1, nullptr, &clinit_barrier_slow);
2315 }
2316 }
2317
2318 void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
2319 Register Rcache,
2320 Register index) {
2321 const Register temp = r19;
2322 assert_different_registers(Rcache, index, temp);
2323
2324 Label resolved, clinit_barrier_slow;
2325
2326 Bytecodes::Code code = bytecode();
2327 switch (code) {
2328 case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2329 case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2330 default: break;
2331 }
2332
2333 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2334 __ load_field_entry(Rcache, index);
2335 if (byte_no == f1_byte) {
2336 __ lea(temp, Address(Rcache, in_bytes(ResolvedFieldEntry::get_code_offset())));
2337 } else {
2338 __ lea(temp, Address(Rcache, in_bytes(ResolvedFieldEntry::put_code_offset())));
2339 }
2340 // Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
2341 __ ldarb(temp, temp);
2342 __ subs(zr, temp, (int) code); // have we resolved this bytecode?
2343 __ br(Assembler::EQ, resolved);
2344
2345 // resolve first time through
2346 __ bind(clinit_barrier_slow);
2347 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2348 __ mov(temp, (int) code);
2349 __ call_VM(noreg, entry, temp);
2350
2351 // Update registers with resolved info
2352 __ load_field_entry(Rcache, index);
2353 __ bind(resolved);
2354
2355 // Class initialization barrier for static fields
2356 if (VM_Version::supports_fast_class_init_checks() &&
2357 (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
2358 __ ldr(temp, Address(Rcache, ResolvedFieldEntry::field_holder_offset()));
2359 __ clinit_barrier(temp, rscratch1, nullptr, &clinit_barrier_slow);
2360 }
2361 }
2362
2363 void TemplateTable::load_resolved_field_entry(Register obj,
2364 Register cache,
2365 Register tos_state,
2366 Register offset,
2367 Register flags,
2368 bool is_static = false) {
2369 assert_different_registers(cache, tos_state, flags, offset);
2370
2371 // Field offset
2372 __ load_sized_value(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
2373
2374 // Flags
2375 __ load_unsigned_byte(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())));
2376
2377 // TOS state
2378 if (tos_state != noreg) {
2379 __ load_unsigned_byte(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())));
2380 }
|