< prev index next >

src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp

Print this page
rev 54670 : Port of valuetypes to aarch64


  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "gc/shared/barrierSetAssembler.hpp"
  29 #include "interpreter/bytecodeHistogram.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/interpreterRuntime.hpp"
  32 #include "interpreter/interp_masm.hpp"
  33 #include "interpreter/templateInterpreterGenerator.hpp"
  34 #include "interpreter/templateTable.hpp"
  35 #include "interpreter/bytecodeTracer.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/arrayOop.hpp"
  38 #include "oops/methodData.hpp"
  39 #include "oops/method.hpp"
  40 #include "oops/oop.inline.hpp"

  41 #include "prims/jvmtiExport.hpp"
  42 #include "prims/jvmtiThreadState.hpp"
  43 #include "runtime/arguments.hpp"
  44 #include "runtime/deoptimization.hpp"
  45 #include "runtime/frame.inline.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/stubRoutines.hpp"
  48 #include "runtime/synchronizer.hpp"
  49 #include "runtime/timer.hpp"
  50 #include "runtime/vframeArray.hpp"
  51 #include "utilities/debug.hpp"
  52 #include <sys/types.h>
  53 
  54 #ifndef PRODUCT
  55 #include "oops/method.hpp"
  56 #endif // !PRODUCT
  57 
  58 #ifdef BUILTIN_SIM
  59 #include "../../../../../../simulator/simulator.hpp"
  60 #endif


 423       __ lea(c_rarg2, Address((address)message));
 424     } else {
 425       __ mov(c_rarg2, NULL_WORD);
 426     }
 427     __ call_VM(r0,
 428                CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
 429                c_rarg1, c_rarg2);
 430   }
 431   // throw exception
 432   __ b(address(Interpreter::throw_exception_entry()));
 433   return entry;
 434 }
 435 
 436 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
 437   address entry = __ pc();
 438 
 439   // Restore stack bottom in case i2c adjusted stack
 440   __ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
 441   // and NULL it as marker that esp is now tos until next java call
 442   __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));































































 443   __ restore_bcp();
 444   __ restore_locals();
 445   __ restore_constant_pool_cache();
 446   __ get_method(rmethod);
 447 
 448   if (state == atos) {
 449     Register obj = r0;
 450     Register mdp = r1;
 451     Register tmp = r2;
 452     __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
 453     __ profile_return_type(mdp, obj, tmp);
 454   }
 455 
 456   // Pop N words from the stack
 457   __ get_cache_and_index_at_bcp(r1, r2, 1, index_size);
 458   __ ldr(r1, Address(r1, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
 459   __ andr(r1, r1, ConstantPoolCacheEntry::parameter_size_mask);
 460 
 461   __ add(esp, esp, r1, Assembler::LSL, 3);
 462 


 549     __ dispatch_next(state, step);
 550   } else {
 551     __ jump_to_entry(continuation);
 552   }
 553   return entry;
 554 }
 555 
 556 address TemplateInterpreterGenerator::generate_result_handler_for(
 557         BasicType type) {
 558     address entry = __ pc();
 559   switch (type) {
 560   case T_BOOLEAN: __ c2bool(r0);         break;
 561   case T_CHAR   : __ uxth(r0, r0);       break;
 562   case T_BYTE   : __ sxtb(r0, r0);        break;
 563   case T_SHORT  : __ sxth(r0, r0);        break;
 564   case T_INT    : __ uxtw(r0, r0);        break;  // FIXME: We almost certainly don't need this
 565   case T_LONG   : /* nothing to do */        break;
 566   case T_VOID   : /* nothing to do */        break;
 567   case T_FLOAT  : /* nothing to do */        break;
 568   case T_DOUBLE : /* nothing to do */        break;

 569   case T_OBJECT :
 570     // retrieve result from frame
 571     __ ldr(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
 572     // and verify it
 573     __ verify_oop(r0);
 574     break;
 575   default       : ShouldNotReachHere();
 576   }
 577   __ ret(lr);                                  // return from result handler
 578   return entry;
 579 }
 580 
 581 address TemplateInterpreterGenerator::generate_safept_entry_for(
 582         TosState state,
 583         address runtime_entry) {
 584   address entry = __ pc();
 585   __ push(state);
 586   __ call_VM(noreg, runtime_entry);
 587   __ membar(Assembler::AnyAny);
 588   __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos));




  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.inline.hpp"
  28 #include "gc/shared/barrierSetAssembler.hpp"
  29 #include "interpreter/bytecodeHistogram.hpp"
  30 #include "interpreter/interpreter.hpp"
  31 #include "interpreter/interpreterRuntime.hpp"
  32 #include "interpreter/interp_masm.hpp"
  33 #include "interpreter/templateInterpreterGenerator.hpp"
  34 #include "interpreter/templateTable.hpp"
  35 #include "interpreter/bytecodeTracer.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/arrayOop.hpp"
  38 #include "oops/methodData.hpp"
  39 #include "oops/method.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "oops/valueKlass.hpp"
  42 #include "prims/jvmtiExport.hpp"
  43 #include "prims/jvmtiThreadState.hpp"
  44 #include "runtime/arguments.hpp"
  45 #include "runtime/deoptimization.hpp"
  46 #include "runtime/frame.inline.hpp"
  47 #include "runtime/sharedRuntime.hpp"
  48 #include "runtime/stubRoutines.hpp"
  49 #include "runtime/synchronizer.hpp"
  50 #include "runtime/timer.hpp"
  51 #include "runtime/vframeArray.hpp"
  52 #include "utilities/debug.hpp"
  53 #include <sys/types.h>
  54 
  55 #ifndef PRODUCT
  56 #include "oops/method.hpp"
  57 #endif // !PRODUCT
  58 
  59 #ifdef BUILTIN_SIM
  60 #include "../../../../../../simulator/simulator.hpp"
  61 #endif


 424       __ lea(c_rarg2, Address((address)message));
 425     } else {
 426       __ mov(c_rarg2, NULL_WORD);
 427     }
 428     __ call_VM(r0,
 429                CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
 430                c_rarg1, c_rarg2);
 431   }
 432   // throw exception
 433   __ b(address(Interpreter::throw_exception_entry()));
 434   return entry;
 435 }
 436 
 437 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
 438   address entry = __ pc();
 439 
 440   // Restore stack bottom in case i2c adjusted stack
 441   __ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
 442   // and NULL it as marker that esp is now tos until next java call
 443   __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
 444 
 445  if (state == atos && ValueTypeReturnedAsFields) {
 446     // A value type might be returned. If fields are in registers we
 447     // need to allocate a value type instance and initialize it with
 448     // the value of the fields.
 449     Label skip, slow_case;
 450 
 451     // We only need a new buffered value if a new one is not returned
 452 
 453     __ tbz(r0, 0, skip);
 454 
 455     // Try to allocate a new buffered value (from the heap)
 456     if (UseTLAB) {
 457 
 458       // klass is in r0
 459       __ andr(rscratch1, r0, -2);
 460       
 461       // get obj size
 462       __ ldrw(rscratch1, Address(rscratch1 /*klass*/, Klass::layout_helper_offset()));
 463       __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
 464 
 465      // check whether we have space in TLAB, 
 466      // rscratch1 contains pointer to just allocated obj
 467       __ lea(rscratch1, Address(rscratch1, rscratch2)); 
 468       __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
 469 
 470       __ cmp(rscratch1, rscratch2);
 471       __ br(Assembler::GT, slow_case);
 472 
 473       // OK we have room in TLAB, 
 474       // Set new TLAB top
 475       __ str(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_top_offset()))); 
 476 
 477       // Set new class always locked
 478       __ mov(rscratch2, (uint64_t) markOopDesc::always_locked_prototype());
 479       __ str(rscratch2, Address(rscratch1, oopDesc::mark_offset_in_bytes()));
 480 
 481       __ store_klass_gap(rscratch1, zr);  // zero klass gap for compressed oops
 482       __ andr(rscratch2, r0, -2);
 483       __ store_klass(rscratch1, rscratch2);  // klass
 484 
 485       // We have our new buffered value, initialize its fields with a
 486       // value class specific handler
 487       __ ldr(rscratch2, Address(rscratch1, InstanceKlass::adr_valueklass_fixed_block_offset()));
 488       __ ldr(rscratch2, Address(rscratch2, ValueKlass::pack_handler_offset()));
 489 
 490 
 491       // Mov new class to r0 and call pack_handler
 492       __ mov(r0, rscratch1);
 493       __ blrt(rscratch2, 1, 0, 0);
 494       __ b(skip);
 495     }
 496 
 497     __ bind(slow_case);
 498 
 499     // We failed to allocate a new value, fall back to a runtime
 500     // call. Some oop field may be live in some registers but we can't
 501     // tell. That runtime call will take care of preserving them
 502     // across a GC if there's one.
 503     __ super_call_VM_leaf(StubRoutines::store_value_type_fields_to_buf());
 504     __ bind(skip);
 505   }
 506 
 507   __ restore_bcp();
 508   __ restore_locals();
 509   __ restore_constant_pool_cache();
 510   __ get_method(rmethod);
 511 
 512   if (state == atos) {
 513     Register obj = r0;
 514     Register mdp = r1;
 515     Register tmp = r2;
 516     __ ldr(mdp, Address(rmethod, Method::method_data_offset()));
 517     __ profile_return_type(mdp, obj, tmp);
 518   }
 519 
 520   // Pop N words from the stack
 521   __ get_cache_and_index_at_bcp(r1, r2, 1, index_size);
 522   __ ldr(r1, Address(r1, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
 523   __ andr(r1, r1, ConstantPoolCacheEntry::parameter_size_mask);
 524 
 525   __ add(esp, esp, r1, Assembler::LSL, 3);
 526 


 613     __ dispatch_next(state, step);
 614   } else {
 615     __ jump_to_entry(continuation);
 616   }
 617   return entry;
 618 }
 619 
 620 address TemplateInterpreterGenerator::generate_result_handler_for(
 621         BasicType type) {
 622     address entry = __ pc();
 623   switch (type) {
 624   case T_BOOLEAN: __ c2bool(r0);         break;
 625   case T_CHAR   : __ uxth(r0, r0);       break;
 626   case T_BYTE   : __ sxtb(r0, r0);        break;
 627   case T_SHORT  : __ sxth(r0, r0);        break;
 628   case T_INT    : __ uxtw(r0, r0);        break;  // FIXME: We almost certainly don't need this
 629   case T_LONG   : /* nothing to do */        break;
 630   case T_VOID   : /* nothing to do */        break;
 631   case T_FLOAT  : /* nothing to do */        break;
 632   case T_DOUBLE : /* nothing to do */        break;
 633   case T_VALUETYPE: // fall through (value types are handled with oops)
 634   case T_OBJECT :
 635     // retrieve result from frame
 636     __ ldr(r0, Address(rfp, frame::interpreter_frame_oop_temp_offset*wordSize));
 637     // and verify it
 638     __ verify_oop(r0);
 639     break;
 640   default       : ShouldNotReachHere();
 641   }
 642   __ ret(lr);                                  // return from result handler
 643   return entry;
 644 }
 645 
 646 address TemplateInterpreterGenerator::generate_safept_entry_for(
 647         TosState state,
 648         address runtime_entry) {
 649   address entry = __ pc();
 650   __ push(state);
 651   __ call_VM(noreg, runtime_entry);
 652   __ membar(Assembler::AnyAny);
 653   __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos));


< prev index next >