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