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); }
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); }
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); }
_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; }
_Ty* acquire() { try_allocate(); _Ty* obj = get_free(); try { new (obj) _Ty(); } catch (...) { free(obj); throw; } return obj; }
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); }
/* 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); }