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;
    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 = 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;
}