Example #1
0
CallingConvention* FrameMap::c_calling_convention(const BasicTypeArray* signature) {
  // compute the size of the arguments first.  The signature array
  // that java_calling_convention takes includes a T_VOID after double
  // work items but our signatures do not.
  int i;
  int sizeargs = 0;
  for (i = 0; i < signature->length(); i++) {
    sizeargs += type2size[signature->at(i)];
  }

  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
  VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
  int sig_index = 0;
  for (i = 0; i < sizeargs; i++, sig_index++) {
    sig_bt[i] = signature->at(sig_index);
    if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
      sig_bt[i + 1] = T_VOID;
      i++;
    }
  }

  intptr_t out_preserve = SharedRuntime::c_calling_convention(sig_bt, regs, NULL, sizeargs);
  LIR_OprList* args = new LIR_OprList(signature->length());
  for (i = 0; i < sizeargs;) {
    BasicType t = sig_bt[i];
    assert(t != T_VOID, "should be skipping these");

    // C calls are always outgoing
    bool outgoing = true;
    LIR_Opr opr = map_to_opr(t, regs + i, outgoing);
    // they might be of different types if for instance floating point
    // values are passed in cpu registers, but the sizes must match.
    assert(type2size[opr->type()] == type2size[t], "type mismatch");
    args->append(opr);
    if (opr->is_address()) {
      LIR_Address* addr = opr->as_address_ptr();
      out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
    }
    i += type2size[t];
  }
  assert(args->length() == signature->length(), "size mismatch");
  out_preserve += SharedRuntime::out_preserve_stack_slots();
  update_reserved_argument_area_size(out_preserve * BytesPerWord);
  return new CallingConvention(args, out_preserve);
}
Example #2
0
CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing) {
  // compute the size of the arguments first.  The signature array
  // that java_calling_convention takes includes a T_VOID after double
  // work items but our signatures do not.
  int i;
  int sizeargs = 0;
  for (i = 0; i < signature->length(); i++) {
    sizeargs += type2size[signature->at(i)];
  }

  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
  VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
  int sig_index = 0;
  for (i = 0; i < sizeargs; i++, sig_index++) {
    sig_bt[i] = signature->at(sig_index);
    if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
      sig_bt[i + 1] = T_VOID;
      i++;
    }
  }

  intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing);
  LIR_OprList* args = new LIR_OprList(signature->length());
  for (i = 0; i < sizeargs;) {
    BasicType t = sig_bt[i];
    assert(t != T_VOID, "should be skipping these");
    LIR_Opr opr = map_to_opr(t, regs + i, outgoing);
    args->append(opr);
    if (opr->is_address()) {
      LIR_Address* addr = opr->as_address_ptr();
      assert(addr->disp() == (int)addr->disp(), "out of range value");
      out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);
    }
    i += type2size[t];
  }
  assert(args->length() == signature->length(), "size mismatch");
  out_preserve += SharedRuntime::out_preserve_stack_slots();

  if (outgoing) {
    // update the space reserved for arguments.
    update_reserved_argument_area_size(out_preserve * BytesPerWord);
  }
  return new CallingConvention(args, out_preserve);
}