예제 #1
0
파일: FASTCALL.C 프로젝트: moyuanming/Train
void main(void)
 {
   unsigned long int i, result;

   clock_t start_time, stop_time;

   printf("Processing...\n");
   start_time = clock();

   for (i = 0; i < 2000000L; i++)
     result = add_fast(i, -i);

   stop_time = clock();
   printf("Processing time for fast call %d ticks\n",
     stop_time - start_time);

   start_time = clock();

   for (i = 0; i < 2000000L; i++)
     result = add_slow(i, -i);

   stop_time = clock();
   printf("Processing time for normal call %d ticks\n",
     stop_time - start_time);
 }
예제 #2
0
VtableStub* VtableStubs::create_itable_stub(int itable_index) {
  const int code_length = VtableStub::pd_code_size_limit(false);
  VtableStub* s = new(code_length) VtableStub(false, itable_index);
  // Can be NULL if there is no free space in the code cache.
  if (s == NULL) {
    return NULL;
  }

  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

  assert(VtableStub::receiver_location() == R0->as_VMReg(), "receiver expected in R0");

  // R0-R3 / R0-R7 registers hold the arguments and cannot be spoiled
  const Register Rclass  = AARCH64_ONLY(R9)  NOT_AARCH64(R4);
  const Register Rlength = AARCH64_ONLY(R10)  NOT_AARCH64(R5);
  const Register Rscan   = AARCH64_ONLY(R11) NOT_AARCH64(R6);
  const Register tmp     = Rtemp;

  assert_different_registers(Ricklass, Rclass, Rlength, Rscan, tmp);

  // Calculate the start of itable (itable goes after vtable)
  const int scale = exact_log2(vtableEntry::size_in_bytes());
  address npe_addr = __ pc();
  __ load_klass(Rclass, R0);
  __ ldr_s32(Rlength, Address(Rclass, Klass::vtable_length_offset()));

  __ add(Rscan, Rclass, in_bytes(Klass::vtable_start_offset()));
  __ add(Rscan, Rscan, AsmOperand(Rlength, lsl, scale));

  // Search through the itable for an interface equal to incoming Ricklass
  // itable looks like [intface][offset][intface][offset][intface][offset]
  const int entry_size = itableOffsetEntry::size() * HeapWordSize;
  assert(itableOffsetEntry::interface_offset_in_bytes() == 0, "not added for convenience");

  Label loop;
  __ bind(loop);
  __ ldr(tmp, Address(Rscan, entry_size, post_indexed));
#ifdef AARCH64
  Label found;
  __ cmp(tmp, Ricklass);
  __ b(found, eq);
  __ cbnz(tmp, loop);
#else
  __ cmp(tmp, Ricklass);  // set ZF and CF if interface is found
  __ cmn(tmp, 0, ne);     // check if tmp == 0 and clear CF if it is
  __ b(loop, ne);
#endif // AARCH64

  assert(StubRoutines::throw_IncompatibleClassChangeError_entry() != NULL, "Check initialization order");
#ifdef AARCH64
  __ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, tmp);
  __ bind(found);
#else
  // CF == 0 means we reached the end of itable without finding icklass
  __ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, noreg, cc);
#endif // !AARCH64

  // Interface found at previous position of Rscan, now load the method oop
  __ ldr_s32(tmp, Address(Rscan, itableOffsetEntry::offset_offset_in_bytes() - entry_size));
  {
    const int method_offset = itableMethodEntry::size() * HeapWordSize * itable_index +
      itableMethodEntry::method_offset_in_bytes();
    __ add_slow(Rmethod, Rclass, method_offset);
  }
  __ ldr(Rmethod, Address(Rmethod, tmp));

  address ame_addr = __ pc();

#ifdef AARCH64
  __ ldr(tmp, Address(Rmethod, Method::from_compiled_offset()));
  __ br(tmp);
#else
  __ ldr(PC, Address(Rmethod, Method::from_compiled_offset()));
#endif // AARCH64

  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                  itable_index, p2i(s->entry_point()),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // FIXME ARM: need correct 'slop' - below is x86 code
  // shut the door on sizing bugs
  //int slop = 8;  // 32-bit offset is this much larger than a 13-bit one
  //assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}