address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  const char *name;
  switch (type) {
    case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    case T_BYTE:    name = "jni_fast_GetByteField";    break;
    case T_CHAR:    name = "jni_fast_GetCharField";    break;
    case T_SHORT:   name = "jni_fast_GetShortField";   break;
    case T_INT:     name = "jni_fast_GetIntField";     break;
    default:        ShouldNotReachHere();
  }
  ResourceMark rm;
  BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
  address fast_entry = b->instructions_begin();
  CodeBuffer cbuf(fast_entry, b->instructions_size());
  MacroAssembler* masm = new MacroAssembler(&cbuf);

  Label slow;

  // stack layout:    offset from rsp (in words):
  //  return pc        0
  //  jni env          1
  //  obj              2
  //  jfieldID         3

  ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
  __ mov32 (rcx, counter);
  __ testb (rcx, 1);
  __ jcc (Assembler::notZero, slow);
  if (os::is_MP()) {
    __ mov(rax, rcx);
    __ andptr(rax, 1);                         // rax, must end up 0
    __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize));
                                              // obj, notice rax, is 0.
                                              // rdx is data dependent on rcx.
  } else {
    __ movptr (rdx, Address(rsp, 2*wordSize));  // obj
  }
  __ movptr(rax, Address(rsp, 3*wordSize));  // jfieldID
  __ movptr(rdx, Address(rdx, 0));           // *obj
  __ shrptr (rax, 2);                         // offset

  assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  speculative_load_pclist[count] = __ pc();
  switch (type) {
    case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break;
    case T_BYTE:    __ movsbl (rax, Address(rdx, rax, Address::times_1)); break;
    case T_CHAR:    __ movzwl (rax, Address(rdx, rax, Address::times_1)); break;
    case T_SHORT:   __ movswl (rax, Address(rdx, rax, Address::times_1)); break;
    case T_INT:     __ movl   (rax, Address(rdx, rax, Address::times_1)); break;
    default:        ShouldNotReachHere();
  }

  Address ca1;
  if (os::is_MP()) {
    __ lea(rdx, counter);
    __ xorptr(rdx, rax);
    __ xorptr(rdx, rax);
    __ cmp32(rcx, Address(rdx, 0));
    // ca1 is the same as ca because
    // rax, ^ counter_addr ^ rax, = address
    // ca1 is data dependent on rax,.
  } else {
    __ cmp32(rcx, counter);
  }
  __ jcc (Assembler::notEqual, slow);

#ifndef _WINDOWS
  __ ret (0);
#else
  // __stdcall calling convention
  __ ret (3*wordSize);
#endif

  slowcase_entry_pclist[count++] = __ pc();
  __ bind (slow);
  address slow_case_addr;
  switch (type) {
    case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
    case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
    case T_INT:     slow_case_addr = jni_GetIntField_addr();
  }
  // tail call
  __ jump (ExternalAddress(slow_case_addr));

  __ flush ();

#ifndef _WINDOWS
  return fast_entry;
#else
  switch (type) {
    case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t)fast_entry; break;
    case T_BYTE:    jni_fast_GetByteField_fp = (GetByteField_t)fast_entry; break;
    case T_CHAR:    jni_fast_GetCharField_fp = (GetCharField_t)fast_entry; break;
    case T_SHORT:   jni_fast_GetShortField_fp = (GetShortField_t)fast_entry; break;
    case T_INT:     jni_fast_GetIntField_fp = (GetIntField_t)fast_entry;
  }
  return os::win32::fast_jni_accessor_wrapper(type);
#endif
}
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  const char *name;
  switch (type) {
    case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    case T_BYTE:    name = "jni_fast_GetByteField";    break;
    case T_CHAR:    name = "jni_fast_GetCharField";    break;
    case T_SHORT:   name = "jni_fast_GetShortField";   break;
    case T_INT:     name = "jni_fast_GetIntField";     break;
    default:        ShouldNotReachHere();
  }
  ResourceMark rm;
  BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
  CodeBuffer cbuf(blob);
  MacroAssembler* masm = new MacroAssembler(&cbuf);
  address fast_entry = __ pc();

  Label label1, label2;

  AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
  __ sethi (cnt_addrlit, O3);
  Address cnt_addr(O3, cnt_addrlit.low10());
  __ ld (cnt_addr, G4);
  __ andcc (G4, 1, G0);
  __ br (Assembler::notZero, false, Assembler::pn, label1);
  __ delayed()->srl (O2, 2, O4);
  __ ld_ptr (O1, 0, O5);

  assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  speculative_load_pclist[count] = __ pc();
  switch (type) {
    case T_BOOLEAN: __ ldub (O5, O4, G3);  break;
    case T_BYTE:    __ ldsb (O5, O4, G3);  break;
    case T_CHAR:    __ lduh (O5, O4, G3);  break;
    case T_SHORT:   __ ldsh (O5, O4, G3);  break;
    case T_INT:     __ ld (O5, O4, G3);    break;
    default:        ShouldNotReachHere();
  }

  __ ld (cnt_addr, O5);
  __ cmp (O5, G4);
  __ br (Assembler::notEqual, false, Assembler::pn, label2);
  __ delayed()->mov (O7, G1);
  __ retl ();
  __ delayed()->mov (G3, O0);

  slowcase_entry_pclist[count++] = __ pc();
  __ bind (label1);
  __ mov (O7, G1);

  address slow_case_addr;
  switch (type) {
    case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
    case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
    case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
    default:        ShouldNotReachHere();
  }
  __ bind (label2);
  __ call (slow_case_addr, relocInfo::none);
  __ delayed()->mov (G1, O7);

  __ flush ();

  return fast_entry;
}
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
    const char *name;
    switch (type) {
    case T_BOOLEAN:
        name = "jni_fast_GetBooleanField";
        break;
    case T_BYTE:
        name = "jni_fast_GetByteField";
        break;
    case T_CHAR:
        name = "jni_fast_GetCharField";
        break;
    case T_SHORT:
        name = "jni_fast_GetShortField";
        break;
    case T_INT:
        name = "jni_fast_GetIntField";
        break;
    case T_LONG:
        name = "jni_fast_GetLongField";
        break;
    default:
        ShouldNotReachHere();
    }
    ResourceMark rm;
    BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE);
    address fast_entry = b->instructions_begin();
    CodeBuffer* cbuf = new CodeBuffer(fast_entry, b->instructions_size());
    MacroAssembler* masm = new MacroAssembler(cbuf);

    Label slow;

    address counter_addr = SafepointSynchronize::safepoint_counter_addr();
    Address ca(counter_addr, relocInfo::none);
    __ movl (rcounter, ca);
    __ movq (robj, rarg1);
    __ testb (rcounter, 1);
    __ jcc (Assembler::notZero, slow);
    if (os::is_MP()) {
        __ xorq (robj, rcounter);
        __ xorq (robj, rcounter);                   // obj, since
        // robj ^ rcounter ^ rcounter == robj
        // robj is data dependent on rcounter.
    }
    __ movq (robj, Address(robj));                // *obj
    __ movq (roffset, rarg2);
    __ shrq (roffset, 2);                         // offset

    assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
    speculative_load_pclist[count] = __ pc();
    switch (type) {
    case T_BOOLEAN:
        __ movzbl (rax, Address(robj, roffset, Address::times_1));
        break;
    case T_BYTE:
        __ movsbl (rax, Address(robj, roffset, Address::times_1));
        break;
    case T_CHAR:
        __ movzwl (rax, Address(robj, roffset, Address::times_1));
        break;
    case T_SHORT:
        __ movswl (rax, Address(robj, roffset, Address::times_1));
        break;
    case T_INT:
        __ movl   (rax, Address(robj, roffset, Address::times_1));
        break;
    case T_LONG:
        __ movq   (rax, Address(robj, roffset, Address::times_1));
        break;
    default:
        ShouldNotReachHere();
    }

    __ movq (rcounter_addr, (int64_t)counter_addr);
    ca = Address(rcounter_addr);
    if (os::is_MP()) {
        __ xorq (rcounter_addr, rax);
        __ xorq (rcounter_addr, rax);               // ca is data dependent on rax.
    }
    __ cmpl (rcounter, ca);
    __ jcc (Assembler::notEqual, slow);

    __ ret (0);

    slowcase_entry_pclist[count++] = __ pc();
    __ bind (slow);
    address slow_case_addr;
    switch (type) {
    case T_BOOLEAN:
        slow_case_addr = jni_GetBooleanField_addr();
        break;
    case T_BYTE:
        slow_case_addr = jni_GetByteField_addr();
        break;
    case T_CHAR:
        slow_case_addr = jni_GetCharField_addr();
        break;
    case T_SHORT:
        slow_case_addr = jni_GetShortField_addr();
        break;
    case T_INT:
        slow_case_addr = jni_GetIntField_addr();
        break;
    case T_LONG:
        slow_case_addr = jni_GetLongField_addr();
    }
    // tail call
    __ jmp (slow_case_addr, relocInfo::none);

    __ flush ();

    return fast_entry;
}
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  const char *name;
  switch (type) {
    case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    case T_BYTE:    name = "jni_fast_GetByteField";    break;
    case T_CHAR:    name = "jni_fast_GetCharField";    break;
    case T_SHORT:   name = "jni_fast_GetShortField";   break;
    case T_INT:     name = "jni_fast_GetIntField";     break;
    case T_LONG:    name = "jni_fast_GetLongField";    break;
    case T_FLOAT:   name = "jni_fast_GetFloatField";   break;
    case T_DOUBLE:  name = "jni_fast_GetDoubleField";  break;
    default:        ShouldNotReachHere();
  }
  ResourceMark rm;
  BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
  CodeBuffer cbuf(blob);
  MacroAssembler* masm = new MacroAssembler(&cbuf);
  address fast_entry = __ pc();

  Label slow;

  unsigned long offset;
  __ adrp(rcounter_addr,
	  SafepointSynchronize::safepoint_counter_addr(), offset);
  Address safepoint_counter_addr(rcounter_addr, offset);
  __ ldrw(rcounter, safepoint_counter_addr);
  __ andw(rscratch1, rcounter, 1);
  __ cbnzw(rscratch1, slow);
  __ eor(robj, c_rarg1, rcounter);
  __ eor(robj, robj, rcounter);               // obj, since
                                              // robj ^ rcounter ^ rcounter == robj
                                              // robj is address dependent on rcounter.
  __ ldr(robj, Address(robj, 0));             // *obj
  __ lsr(roffset, c_rarg2, 2);                // offset

  assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  speculative_load_pclist[count] = __ pc();   // Used by the segfault handler
  switch (type) {
    case T_BOOLEAN: __ ldrb    (result, Address(robj, roffset)); break;
    case T_BYTE:    __ ldrsb   (result, Address(robj, roffset)); break;
    case T_CHAR:    __ ldrh    (result, Address(robj, roffset)); break;
    case T_SHORT:   __ ldrsh   (result, Address(robj, roffset)); break;
    case T_FLOAT:   __ ldrw    (result, Address(robj, roffset)); break;
    case T_INT:     __ ldrsw   (result, Address(robj, roffset)); break;
    case T_DOUBLE:
    case T_LONG:    __ ldr     (result, Address(robj, roffset)); break;
    default:        ShouldNotReachHere();
  }

  // counter_addr is address dependent on result.
  __ eor(rcounter_addr, rcounter_addr, result);
  __ eor(rcounter_addr, rcounter_addr, result);
  __ ldrw(rscratch1, safepoint_counter_addr);
  __ cmpw(rcounter, rscratch1);
  __ br (Assembler::NE, slow);

  switch (type) {
    case T_FLOAT:   __ fmovs(v0, result); break;
    case T_DOUBLE:  __ fmovd(v0, result); break;
    default:        __ mov(r0, result);   break;
  }
  __ ret(lr);

  slowcase_entry_pclist[count++] = __ pc();
  __ bind(slow);
  address slow_case_addr;
  switch (type) {
    case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
    case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
    case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
    case T_LONG:    slow_case_addr = jni_GetLongField_addr();    break;
    case T_FLOAT:   slow_case_addr = jni_GetFloatField_addr();   break;
    case T_DOUBLE:  slow_case_addr = jni_GetDoubleField_addr();  break;
    default:        ShouldNotReachHere();
  }

  {
    __ enter();
    __ lea(rscratch1, ExternalAddress(slow_case_addr));
    __ blr(rscratch1);
    __ maybe_isb();
    __ leave();
    __ ret(lr);
  }
  __ flush ();

  return fast_entry;
}
Пример #5
0
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  const char *name = NULL;
  switch (type) {
    case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    case T_BYTE:    name = "jni_fast_GetByteField";    break;
    case T_CHAR:    name = "jni_fast_GetCharField";    break;
    case T_SHORT:   name = "jni_fast_GetShortField";   break;
    case T_INT:     name = "jni_fast_GetIntField";     break;
    case T_LONG:    name = "jni_fast_GetLongField";    break;
    default:        ShouldNotReachHere();
  }
  ResourceMark rm;
  BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
  CodeBuffer cbuf(blob);
  MacroAssembler* masm = new MacroAssembler(&cbuf);
  address fast_entry = __ pc();

  Label slow;

  ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
  __ mov32 (rcounter, counter);
  __ mov   (robj, c_rarg1);
  __ testb (rcounter, 1);
  __ jcc (Assembler::notZero, slow);
  if (os::is_MP()) {
    __ xorptr(robj, rcounter);
    __ xorptr(robj, rcounter);                   // obj, since
                                                // robj ^ rcounter ^ rcounter == robj
                                                // robj is data dependent on rcounter.
  }

  __ clear_jweak_tag(robj);

  __ movptr(robj, Address(robj, 0));             // *obj
  __ mov   (roffset, c_rarg2);
  __ shrptr(roffset, 2);                         // offset

  assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  speculative_load_pclist[count] = __ pc();
  switch (type) {
    case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break;
    case T_BYTE:    __ movsbl (rax, Address(robj, roffset, Address::times_1)); break;
    case T_CHAR:    __ movzwl (rax, Address(robj, roffset, Address::times_1)); break;
    case T_SHORT:   __ movswl (rax, Address(robj, roffset, Address::times_1)); break;
    case T_INT:     __ movl   (rax, Address(robj, roffset, Address::times_1)); break;
    case T_LONG:    __ movq   (rax, Address(robj, roffset, Address::times_1)); break;
    default:        ShouldNotReachHere();
  }

  if (os::is_MP()) {
    __ lea(rcounter_addr, counter);
    // ca is data dependent on rax.
    __ xorptr(rcounter_addr, rax);
    __ xorptr(rcounter_addr, rax);
    __ cmpl (rcounter, Address(rcounter_addr, 0));
  } else {
    __ cmp32 (rcounter, counter);
  }
  __ jcc (Assembler::notEqual, slow);

  __ ret (0);

  slowcase_entry_pclist[count++] = __ pc();
  __ bind (slow);
  address slow_case_addr = NULL;
  switch (type) {
    case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
    case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
    case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
    case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
    case T_LONG:    slow_case_addr = jni_GetLongField_addr();
  }
  // tail call
  __ jump (ExternalAddress(slow_case_addr));

  __ flush ();

  return fast_entry;
}