Ejemplo n.º 1
0
// Allocates memory (parameter(), literal(), emit_epilog, emit_with_literal)
void quotation_jit::iterate_quotation() {
  bool stack_frame = stack_frame_p();

  set_position(0);

  if (stack_frame) {
    emit(parent->special_objects[JIT_SAFEPOINT]);
    emit(parent->special_objects[JIT_PROLOG]);
  }

  cell length = array_capacity(elements.untagged());
  bool tail_call = false;

  for (cell i = 0; i < length; i++) {
    set_position(i);
    data_root<object> obj(nth(i), parent);

    switch (obj.type()) {
      case WORD_TYPE:
        // Sub-primitives
        if (to_boolean(obj.as<word>()->subprimitive)) {
          tail_call = emit_subprimitive(obj.value(),     // word
                                        i == length - 1, // tail_call_p
                                        stack_frame);    // stack_frame_p
        }                                                // Everything else
        else if (i == length - 1) {
          emit_epilog(stack_frame);
          tail_call = true;
          word_jump(obj.value());
        } else
          word_call(obj.value());
        break;
      case WRAPPER_TYPE:
        push(obj.as<wrapper>()->object);
        break;
      case BYTE_ARRAY_TYPE:
        // Primitive calls
        if (primitive_call_p(i, length)) {
// On x86-64 and PowerPC, the VM pointer is stored in a register;
// on other platforms, the RT_VM relocation is used and it needs
// an offset parameter
#ifdef FACTOR_X86
          parameter(tag_fixnum(0));
#endif
          parameter(obj.value());
          parameter(false_object);
#ifdef FACTOR_PPC_TOC
          parameter(obj.value());
          parameter(false_object);
#endif
          emit(parent->special_objects[JIT_PRIMITIVE]);

          i++;
        } else
          push(obj.value());
        break;
      case QUOTATION_TYPE:
        // 'if' preceded by two literal quotations (this is why if and ? are
        // mutually recursive in the library, but both still work)
        if (fast_if_p(i, length)) {
          emit_epilog(stack_frame);
          tail_call = true;
          emit_quotation(nth(i));
          emit_quotation(nth(i + 1));
          emit(parent->special_objects[JIT_IF]);
          i += 2;
        } // dip
        else if (fast_dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_DIP]);
          i++;
        } // 2dip
        else if (fast_2dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_2DIP]);
          i++;
        } // 3dip
        else if (fast_3dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_3DIP]);
          i++;
        } else
          push(obj.value());
        break;
      case ARRAY_TYPE:
        // Method dispatch
        if (mega_lookup_p(i, length)) {
          tail_call = true;
          emit_mega_cache_lookup(nth(i), untag_fixnum(nth(i + 1)), nth(i + 2));
          i += 3;
        } // Non-optimizing compiler ignores declarations
        else if (declare_p(i, length))
          i++;
        else
          push(obj.value());
        break;
      default:
        push(obj.value());
        break;
    }
  }

  if (!tail_call) {
    set_position(length);
    emit_epilog(stack_frame);
    emit(parent->special_objects[JIT_RETURN]);
  }
}
Ejemplo n.º 2
0
/* Allocates memory (parameter(), literal(), emit_epilog, emit_with_literal)*/
void quotation_jit::iterate_quotation() {
  bool no_non_safepoint_words = no_non_safepoint_words_p();

  set_position(0);

  if (no_non_safepoint_words) {
    emit(parent->special_objects[JIT_SAFEPOINT]);
    emit(parent->special_objects[JIT_PROLOG]);
  }

  cell length = array_capacity(elements.untagged());
  bool tail_call = false;

  for (cell i = 0; i < length; i++) {
    set_position(i);

    data_root<object> obj(array_nth(elements.untagged(), i), parent);

    switch (obj.type()) {
      case WORD_TYPE:
        /* Sub-primitives */
        if (to_boolean(obj.as<word>()->subprimitive)) {
          tail_call = emit_subprimitive(obj.value(),     /* word */
                                        i == length - 1, /* tail_call_p */
                                        no_non_safepoint_words);    /* stack_frame_p */
        }                                                /* Everything else */
        else if (i == length - 1) {
          emit_epilog(no_non_safepoint_words);
          tail_call = true;
          word_jump(obj.value());
        } else
          word_call(obj.value());
        break;
      case WRAPPER_TYPE:
        push(obj.as<wrapper>()->object);
        break;
      case BYTE_ARRAY_TYPE:
        /* Primitive calls */
        if (primitive_call_p(i, length)) {
/* On x86-64 and PowerPC, the VM pointer is stored in
   a register; on other platforms, the RT_VM relocation
   is used and it needs an offset parameter */
#ifdef FACTOR_X86
          parameter(tag_fixnum(0));
#endif
          parameter(obj.value());
          parameter(false_object);
#ifdef FACTOR_PPC_TOC
          parameter(obj.value());
          parameter(false_object);
#endif
          emit(parent->special_objects[JIT_PRIMITIVE]);

          i++;
        } else
          push(obj.value());
        break;
      case QUOTATION_TYPE:
        /* 'if' preceded by two literal quotations (this is why if and ? are
           mutually recursive in the library, but both still work) */
        if (fast_if_p(i, length)) {
          emit_epilog(no_non_safepoint_words);
          tail_call = true;

          emit_quotation(array_nth(elements.untagged(), i));
          emit_quotation(array_nth(elements.untagged(), i + 1));
          emit(parent->special_objects[JIT_IF]);

          i += 2;
        } /* dip */
        else if (fast_dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_DIP]);
          i++;
        } /* 2dip */
        else if (fast_2dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_2DIP]);
          i++;
        } /* 3dip */
        else if (fast_3dip_p(i, length)) {
          emit_quotation(obj.value());
          emit(parent->special_objects[JIT_3DIP]);
          i++;
        } else
          push(obj.value());
        break;
      case ARRAY_TYPE:
        /* Method dispatch */
        if (mega_lookup_p(i, length)) {
          fixnum index = untag_fixnum(array_nth(elements.untagged(), i + 1));
          /* Load the object from the datastack, then remove our stack frame. */
          emit_with_literal(parent->special_objects[PIC_LOAD],
                            tag_fixnum(-index * sizeof(cell)));
          emit_epilog(no_non_safepoint_words);
          tail_call = true;

          emit_mega_cache_lookup(array_nth(elements.untagged(), i), index,
                                 array_nth(elements.untagged(), i + 2));
          i += 3;
        } /* Non-optimizing compiler ignores declarations */
        else if (declare_p(i, length))
          i++;
        else
          push(obj.value());
        break;
      default:
        push(obj.value());
        break;
    }
  }

  if (!tail_call) {
    set_position(length);
    emit_epilog(no_non_safepoint_words);
    emit(parent->special_objects[JIT_RETURN]);
  }
}