int scheme_inline_alloc(mz_jit_state *jitter, int amt, Scheme_Type ty, int flags,
			int keep_r0_r1, int keep_fpr1, int inline_retry,
                        int keep_extfpr1)
/* Puts allocated result at JIT_V1; first word is GC tag.
   Uses JIT_R2 as temporary. The allocated memory is "dirty" (i.e., not 0ed).
   Save FP0 when FP ops are enabled. */
{
  GC_CAN_IGNORE jit_insn *ref, *reffail;
#ifdef MZ_GC_STRESS_TESTING
  GC_CAN_IGNORE jit_insn *refstress;
#endif
  intptr_t a_word, sz, algn;

  sz = GC_compute_alloc_size(amt);
  algn = GC_alloc_alignment();

  __START_TINY_JUMPS__(1);
#ifdef MZ_GC_STRESS_TESTING
  refstress = jit_jmpi(jit_forward());
#endif
  reffail = jit_get_ip();
  mz_tl_ldi_p(JIT_V1, tl_GC_gen0_alloc_page_ptr);
  jit_subi_l(JIT_R2, JIT_V1, 1);
  jit_andi_l(JIT_R2, JIT_R2, (algn - 1));
  ref = jit_blti_l(jit_forward(), JIT_R2, (algn - sz));
#ifdef MZ_GC_STRESS_TESTING
  mz_patch_ucbranch(refstress);
#endif
  CHECK_LIMIT();
  __END_TINY_JUMPS__(1);

  /* Failure handling */
  if (inline_retry) {
    int mode;
    if (keep_r0_r1)
      mode = 1;
    else if (keep_fpr1)
      mode = 2;
    else if (keep_extfpr1)
      mode = 3;
    else
      mode = 0;
    scheme_generate_alloc_retry(jitter, mode);
    CHECK_LIMIT();
  } else {
    if (keep_r0_r1) {
      (void)jit_calli(sjc.retry_alloc_code_keep_r0_r1);
    } else if (keep_fpr1) {
      (void)jit_calli(sjc.retry_alloc_code_keep_fpr1);
#ifdef MZ_LONG_DOUBLE
    } else if (keep_extfpr1) {
      (void)jit_calli(sjc.retry_alloc_code_keep_extfpr1);
#endif
    } else {
      (void)jit_calli(sjc.retry_alloc_code);
    }
  }
  __START_TINY_JUMPS__(1);
  (void)jit_jmpi(reffail);
  __END_SHORT_JUMPS__(1);
  
  __START_TINY_JUMPS__(1);
  mz_patch_branch(ref);
  jit_addi_ul(JIT_R2, JIT_V1, sz);
  (void)mz_tl_sti_l(tl_GC_gen0_alloc_page_ptr, JIT_R2, JIT_R0);

  /* GC header: */
  if (ty >= 0) {
    if ((ty == scheme_pair_type)
        || (ty == scheme_mutable_pair_type)
        || (ty == scheme_raw_pair_type))
      a_word = GC_pair_initial_word(amt);
    else
      a_word = GC_initial_word(amt);
    jit_stir_l(JIT_V1, a_word);
    
    /* Scheme_Object header: */
    a_word = initial_tag_word(ty, flags);
    jit_stixi_l(sizeof(intptr_t), JIT_V1, a_word);
  } else {
    /* an array of pointers */
    a_word = GC_array_initial_word(amt);
    jit_stir_l(JIT_V1, a_word);
  }

  CHECK_LIMIT();
  __END_TINY_JUMPS__(1);

  return 1;
}
Esempio n. 2
0
int scheme_inline_alloc(mz_jit_state *jitter, int amt, Scheme_Type ty, int immut,
			int keep_r0_r1, int keep_fpr1, int inline_retry)
/* Puts allocated result at JIT_V1; first word is GC tag.
   Uses JIT_R2 as temporary. The allocated memory is "dirty" (i.e., not 0ed).
   Save FP0 when FP ops are enabled. */
{
  GC_CAN_IGNORE jit_insn *ref, *reffail;
  intptr_t a_word, sz, algn;

  sz = GC_compute_alloc_size(amt);
  algn = GC_alloc_alignment();

  __START_TINY_JUMPS__(1);
  reffail = _jit.x.pc;
  mz_tl_ldi_p(JIT_V1, tl_GC_gen0_alloc_page_ptr);
  jit_subi_l(JIT_R2, JIT_V1, 1);
  jit_andi_l(JIT_R2, JIT_R2, (algn - 1));
  ref = jit_blti_l(jit_forward(), JIT_R2, (algn - sz));
  CHECK_LIMIT();
  __END_TINY_JUMPS__(1);

  /* Failure handling */
  if (keep_r0_r1) {
    if (inline_retry) {
      scheme_generate_alloc_retry(jitter, 1);
      CHECK_LIMIT();
    } else {
      (void)jit_calli(sjc.retry_alloc_code_keep_r0_r1);
    }
  } else if (keep_fpr1) {
    (void)jit_calli(sjc.retry_alloc_code_keep_fpr1);
  } else {
    (void)jit_calli(sjc.retry_alloc_code);
  }
  __START_TINY_JUMPS__(1);
  (void)jit_jmpi(reffail);
  __END_SHORT_JUMPS__(1);
  
  __START_TINY_JUMPS__(1);
  mz_patch_branch(ref);
  jit_addi_ul(JIT_R2, JIT_V1, sz);
  (void)mz_tl_sti_l(tl_GC_gen0_alloc_page_ptr, JIT_R2, JIT_R0);

  /* GC header: */
  if (ty >= 0) {
    a_word = GC_initial_word(amt);
    jit_movi_l(JIT_R2, a_word);
    jit_str_l(JIT_V1, JIT_R2);
    
    /* Scheme_Object header: */
    a_word = initial_tag_word(ty, immut);
    jit_movi_l(JIT_R2, a_word);
    jit_stxi_l(sizeof(intptr_t), JIT_V1, JIT_R2);
  } else {
    /* an array of pointers */
    a_word = GC_array_initial_word(amt);
    jit_movi_l(JIT_R2, a_word);
    jit_str_l(JIT_V1, JIT_R2);
  }

  CHECK_LIMIT();
  __END_TINY_JUMPS__(1);

  return 1;
}