Esempio n. 1
0
void C1_MacroAssembler::allocate_object(
    Register obj,                        // result: pointer to object after successful allocation
    Register t1,                         // temp register
    Register t2,                         // temp register, must be a global register for try_allocate
    Register t3,                         // temp register
    int      hdr_size,                   // object header size in words
    int      obj_size,                   // object size in words
    Register klass,                      // object klass
    Label&   slow_case                   // continuation point if fast allocation fails
) {
    assert_different_registers(obj, t1, t2, t3, klass);
    assert(klass == G5, "must be G5");

    // allocate space & initialize header
    if (!is_simm13(obj_size * wordSize)) {
        // would need to use extra register to load
        // object size => go the slow case for now
        ba(slow_case);
        delayed()->nop();
        return;
    }
    try_allocate(obj, noreg, obj_size * wordSize, t2, t3, slow_case);

    initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2);
}
Esempio n. 2
0
void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
    assert(obj == rax, "obj must be in rax, for cmpxchg");
    assert_different_registers(obj, t1, t2); // XXX really?
    assert(header_size >= 0 && object_size >= header_size, "illegal sizes");

    try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);

    initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
}
Esempio n. 3
0
void C1_MacroAssembler::allocate_array(
  Register obj,                        // result: Pointer to array after successful allocation.
  Register len,                        // array length
  Register t1,                         // temp register
  Register t2,                         // temp register
  int      hdr_size,                   // object header size in words
  int      elt_size,                   // element size in bytes
  Register klass,                      // object klass
  Label&   slow_case                   // Continuation point if fast allocation fails.
) {
  assert_different_registers(obj, len, t1, t2, klass);

  // Determine alignment mask.
  assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work");

  // Check for negative or excessive length.
  compareU64_and_branch(len, (int32_t)max_array_allocation_length, bcondHigh, slow_case);

  // Compute array size.
  // Note: If 0 <= len <= max_length, len*elt_size + header + alignment is
  // smaller or equal to the largest integer. Also, since top is always
  // aligned, we can do the alignment here instead of at the end address
  // computation.
  const Register arr_size = t2;
  switch (elt_size) {
    case  1: lgr_if_needed(arr_size, len); break;
    case  2: z_sllg(arr_size, len, 1); break;
    case  4: z_sllg(arr_size, len, 2); break;
    case  8: z_sllg(arr_size, len, 3); break;
    default: ShouldNotReachHere();
  }
  add2reg(arr_size, hdr_size * wordSize + MinObjAlignmentInBytesMask); // Add space for header & alignment.
  z_nill(arr_size, (~MinObjAlignmentInBytesMask) & 0xffff);            // Align array size.

  try_allocate(obj, arr_size, 0, t1, slow_case);

  initialize_header(obj, klass, len, noreg, t1);

  // Clear rest of allocated space.
  Label done;
  Register object_fields = t1;
  Register Rzero = Z_R1_scratch;
  z_aghi(arr_size, -(hdr_size * BytesPerWord));
  z_bre(done); // Jump if size of fields is zero.
  z_la(object_fields, hdr_size * BytesPerWord, obj);
  z_xgr(Rzero, Rzero);
  initialize_body(object_fields, arr_size, Rzero);
  bind(done);

  // Dtrace support is unimplemented.
  // if (CURRENT_ENV->dtrace_alloc_probes()) {
  //   assert(obj == rax, "must be");
  //   call(RuntimeAddress(Runtime1::entry_for (Runtime1::dtrace_object_alloc_id)));
  // }

  verify_oop(obj);
}
Esempio n. 4
0
 _Ty* acquire(const ArgT0& arg0, const ArgT1& arg1, const ArgT2& arg2)
 {
     try_allocate();
     _Ty* obj = get_free();
     try
     {
         new (obj) _Ty(arg0, arg1, arg2);
     }
     catch (...)
     {
         free(obj); throw;
     }
 
     return obj;
 }
Esempio n. 5
0
    _Ty* acquire()
    {
        try_allocate();
        _Ty* obj = get_free();
        try
        {
            new (obj) _Ty();
        }
        catch (...)
        {
            free(obj); throw;
        }

        return obj;
    }
Esempio n. 6
0
void C1_MacroAssembler::allocate_object(
  Register obj,                        // Result: pointer to object after successful allocation.
  Register t1,                         // temp register
  Register t2,                         // temp register: Must be a global register for try_allocate.
  int      hdr_size,                   // object header size in words
  int      obj_size,                   // object size in words
  Register klass,                      // object klass
  Label&   slow_case                   // Continuation point if fast allocation fails.
) {
  assert_different_registers(obj, t1, t2, klass);

  // Allocate space and initialize header.
  try_allocate(obj, noreg, obj_size * wordSize, t1, slow_case);

  initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2);
}
Esempio n. 7
0
/* imc_reg_alloc is the main loop of the allocation algorithm. It operates
 * on a single compilation unit at a time.
 */
void
imc_reg_alloc(struct Parrot_Interp *interpreter, IMC_Unit * unit)
{
    int to_spill;
    int todo, first;

    if (!unit)
        return;
    if (!optimizer_level && pasm_file)
        return;

    init_tables(interpreter);
    allocated = 0;

#if IMC_TRACE
    fprintf(stderr, "reg_alloc.c: imc_reg_alloc\n");
    if (unit->instructions->r[1] && unit->instructions->r[1]->pcc_sub) {
        fprintf(stderr, "img_reg_alloc: pcc_sub (nargs = %d)\n",
            unit->instructions->r[1]->pcc_sub->nargs);
    }
#endif

    debug(interpreter, DEBUG_IMC, "\n------------------------\n");
    debug(interpreter, DEBUG_IMC, "processing sub %s\n", function);
    debug(interpreter, DEBUG_IMC, "------------------------\n\n");
    if (IMCC_INFO(interpreter)->verbose ||
            (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
        imc_stat_init(unit);

    /* consecutive labels, if_branch, unused_labels ... */
    pre_optimize(interpreter, unit);
    if (optimizer_level == OPT_PRE && pasm_file)
        return;

    nodeStack = imcstack_new();
    unit->n_spilled = 0;

    todo = first = 1;
    while (todo) {
        find_basic_blocks(interpreter, unit, first);
        build_cfg(interpreter, unit);

        if (first && (IMCC_INFO(interpreter)->debug & DEBUG_CFG))
            dump_cfg(unit);
        first = 0;
        todo = cfg_optimize(interpreter, unit);
    }

    todo = first = 1;
    while (todo) {
        if (!first) {
            find_basic_blocks(interpreter, unit, 0);
            build_cfg(interpreter, unit);
        }
        first = 0;

        compute_dominators(interpreter, unit);
        find_loops(interpreter, unit);

        build_reglist(interpreter, unit);
        life_analysis(interpreter, unit);
        /* optimize, as long as there is something to do */
        if (dont_optimize)
            todo = 0;
        else {
            todo = optimize(interpreter, unit);
            if (todo)
                pre_optimize(interpreter, unit);
        }
    }
    todo = 1;
#if !DOIT_AGAIN_SAM
    build_interference_graph(interpreter, unit);
#endif
    while (todo) {
#if DOIT_AGAIN_SAM
        build_interference_graph(interpreter, unit);
#endif
        if (optimizer_level & OPT_SUB)
            allocate_wanted_regs(unit);
        compute_spilling_costs(interpreter, unit);
#ifdef DO_SIMPLIFY
        /* simplify until no changes can be made */
        while (simplify(unit)) {}
#endif
        order_spilling(unit);          /* put the remaining items on stack */

        to_spill = try_allocate(interpreter, unit);
        allocated = 1;

        if ( to_spill >= 0 ) {
            allocated = 0;
            spill(interpreter, unit, to_spill);
            /*
             * build the new cfg/reglist on the fly in spill() and
             * do life analysis there for only the involved regs
             */
#if DOIT_AGAIN_SAM
            find_basic_blocks(interpreter, unit, 0);
            build_cfg(interpreter, unit);
            build_reglist(interpreter, unit);
            life_analysis(interpreter);
#endif
        }
        else {
            /* the process is finished */
            todo = 0;
        }
    }
    if (optimizer_level & OPT_SUB)
        sub_optimize(interpreter, unit);
    if (IMCC_INFO(interpreter)->debug & DEBUG_IMC)
        dump_instructions(unit);
    if (IMCC_INFO(interpreter)->verbose  ||
            (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
        print_stat(interpreter, unit);
    imcstack_free(nodeStack);
}