// "lock" stores the address of the monitor stack slot, so this is not an oop.
LIR_Opr lock = new_register(T_INT);
CodeEmitInfo* info_for_exception = NULL; if (x->needs_null_check()) {
info_for_exception = state_for (x);
} // This CodeEmitInfo must not have the xhandlers because here the // object is already locked (xhandlers expect object to be unlocked).
CodeEmitInfo* info = state_for (x, x->state(), true);
monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr,
x->monitor_no(), info_for_exception, info);
}
// for _ladd, _lmul, _lsub, _ldiv, _lrem void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) { // Use shifts if divisor is a power of 2 otherwise use DSGR instruction. // Instruction: DSGR R1, R2 // input : R1+1: dividend (R1, R1+1 designate a register pair, R1 must be even) // R2: divisor // // output: R1+1: quotient // R1: remainder // // Register selection: R1: Z_R10 // R1+1: Z_R11 // R2: to be chosen by register allocator (linear scan)
// R1, and R1+1 will be destroyed.
LIRItem right(x->y(), this);
LIRItem left(x->x() , this); // Visit left second, so that the is_register test is valid.
// Call state_for before load_item_force because state_for may // force the evaluation of other instructions that are needed for // correct debug info. Otherwise the live range of the fix // register might be too long.
CodeEmitInfo* info = state_for (x);
if (!ImplicitDiv0Checks) {
__ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));
__ branch(lir_cond_equal, new DivByZeroStub(info)); // Idiv/irem cannot trap (passing info would generate an assertion).
info = NULL;
}
// for: _iadd, _imul, _isub, _idiv, _irem void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) { // Use shifts if divisor is a power of 2 otherwise use DSGFR instruction. // Instruction: DSGFR R1, R2 // input : R1+1: dividend (R1, R1+1 designate a register pair, R1 must be even) // R2: divisor // // output: R1+1: quotient // R1: remainder // // Register selection: R1: Z_R10 // R1+1: Z_R11 // R2: To be chosen by register allocator (linear scan).
// R1, and R1+1 will be destroyed.
LIRItem right(x->y(), this);
LIRItem left(x->x() , this); // Visit left second, so that the is_register test is valid.
// Call state_for before load_item_force because state_for may // force the evaluation of other instructions that are needed for // correct debug info. Otherwise the live range of the fix // register might be too long.
CodeEmitInfo* info = state_for (x);
if (!ImplicitDiv0Checks) {
__ cmp(lir_cond_equal, right.result(), LIR_OprFact::intConst(0));
__ branch(lir_cond_equal, new DivByZeroStub(info)); // Idiv/irem cannot trap (passing info would generate an assertion).
info = NULL;
}
if (result_reg != result) {
__ move(result_reg, result);
}
} else {
LIRItem left(x->x(), this);
LIRItem right(x->y(), this);
LIRItem* left_arg = &left;
LIRItem* right_arg = &right; if (x->is_commutative() && left.is_stack() && right.is_register()) { // swap them if left is real stack (or cached) and right is real register(not cached)
left_arg = &right;
right_arg = &left;
}
left_arg->load_item();
// Do not need to load right, as we can handle stack and constants. if (x->op() == Bytecodes::_imul) { bool use_tmp = false; if (right_arg->is_constant()) { int iconst = right_arg->get_jint_constant(); if (is_power_of_2(iconst - 1) || is_power_of_2(iconst + 1)) {
use_tmp = true;
}
}
right_arg->dont_load_item();
LIR_Opr tmp = LIR_OprFact::illegalOpr; if (use_tmp) {
tmp = new_register(T_INT);
}
rlock_result(x);
void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) { // If an operand with use count 1 is the left operand, then it is // likely that no move for 2-operand-LIR-form is necessary. if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {
x->swap_operands();
}
ValueTag tag = x->type()->tag();
assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters"); switch (tag) { case floatTag: case doubleTag: do_ArithmeticOp_FPU(x); return; case longTag: do_ArithmeticOp_Long(x); return; case intTag: do_ArithmeticOp_Int(x); return; default:
ShouldNotReachHere();
}
}
// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr void LIRGenerator::do_ShiftOp(ShiftOp* x) { // count must always be in rcx
LIRItem value(x->x(), this);
LIRItem count(x->y(), this);
// _iand, _land, _ior, _lor, _ixor, _lxor void LIRGenerator::do_LogicOp(LogicOp* x) { // IF an operand with use count 1 is the left operand, then it is // likely that no move for 2-operand-LIR-form is necessary. if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {
x->swap_operands();
}
LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) {
Unimplemented(); // Currently not supported on this platform. return LIR_OprFact::illegalOpr;
}
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { switch (x->id()) { case vmIntrinsics::_dabs: case vmIntrinsics::_dsqrt: case vmIntrinsics::_dsqrt_strict: {
assert(x->number_of_arguments() == 1, "wrong type");
LIRItem value(x->argument_at(0), this);
value.load_item();
LIR_Opr dst = rlock_result(x);
switch (x->id()) { case vmIntrinsics::_dsqrt: case vmIntrinsics::_dsqrt_strict: {
__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr); break;
} case vmIntrinsics::_dabs: {
__ abs(value.result(), dst, LIR_OprFact::illegalOpr); break;
} default:
ShouldNotReachHere();
} break;
} case vmIntrinsics::_dsin: // fall through case vmIntrinsics::_dcos: // fall through case vmIntrinsics::_dtan: // fall through case vmIntrinsics::_dlog: // fall through case vmIntrinsics::_dlog10: // fall through case vmIntrinsics::_dexp: {
assert(x->number_of_arguments() == 1, "wrong type");
address runtime_entry = NULL; switch (x->id()) { case vmIntrinsics::_dsin:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin); break; case vmIntrinsics::_dcos:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos); break; case vmIntrinsics::_dtan:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan); break; case vmIntrinsics::_dlog:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog); break; case vmIntrinsics::_dlog10:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break; case vmIntrinsics::_dexp:
runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp); break; default:
ShouldNotReachHere();
}
// Copy stubs possibly call C code, e.g. G1 barriers, so we need to reserve room // for the C ABI (see frame::z_abi_160).
BasicTypeArray sig; // Empty signature is precise enough.
frame_map()->c_calling_convention(&sig);
// Make all state_for calls early since they can emit code.
CodeEmitInfo* info = state_for (x, x->state());
LIR_Opr result = rlock_result(x);
__ move(reg, result);
}
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) { // Evaluate state_for early since it may emit code.
CodeEmitInfo* info = state_for (x, x->state()); // In case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction // and therefore provide the state before the parameters have been consumed.
CodeEmitInfo* patching_info = NULL; if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for (x, x->state_before());
}
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
ciKlass* obj = ciObjArrayKlass::make(x->klass()); if (obj == ciEnv::unloaded_ciobjarrayklass()) {
BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
}
klass2reg_with_patching(klass_reg, obj, patching_info);
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);
LIR_Opr result = rlock_result(x);
__ move(reg, result);
}
void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
Values* dims = x->dims(); int i = dims->length();
LIRItemList* items = new LIRItemList(i, i, NULL); while (i-- > 0) {
LIRItem* size = new LIRItem(dims->at(i), this);
items->at_put(i, size);
}
// Evaluate state_for early since it may emit code.
CodeEmitInfo* patching_info = NULL; if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for (x, x->state_before());
// Cannot re-use same xhandlers for multiple CodeEmitInfos, so // clone all handlers (NOTE: Usually this is handled transparently // by the CodeEmitInfo cloning logic in CodeStub constructors but // is done explicitly here because a stub isn't being used).
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
}
CodeEmitInfo* info = state_for (x, x->state());
i = dims->length(); while (--i >= 0) {
LIRItem* size = items->at(i);
size->load_nonconstant(32); // FrameMap::_reserved_argument_area_size includes the dimensions varargs, because // it's initialized to hir()->max_stack() when the FrameMap is created.
store_stack_parameter(size->result(), in_ByteSize(i*sizeof(jint) + FrameMap::first_available_sp_in_frame));
}
CodeEmitInfo* patching_info = NULL; if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) { // Must do this before locking the destination register as an oop register, // and before the obj is loaded (the latter is for deoptimization).
patching_info = state_for (x, x->state_before());
}
obj.load_item();
// info for exceptions
CodeEmitInfo* info_for_exception =
(x->needs_exception_state() ? state_for(x) :
state_for(x, x->state_before(), true/*ignore_xhandler*/));
if (tag == longTag) { // For longs, only conditions "eql", "neq", "lss", "geq" are valid; // mirror for other conditions. if (cond == If::gtr || cond == If::leq) {
cond = Instruction::mirror(cond);
xin = &yitem;
yin = &xitem;
}
xin->set_destroys_register();
}
xin->load_item(); // TODO: don't load long constants != 0L if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { // inline long zero
yin->dont_load_item();
} elseif (tag == longTag || tag == floatTag || tag == doubleTag) { // Longs cannot handle constants at right side.
yin->load_item();
} else {
yin->dont_load_item();
}
LIR_Opr left = xin->result();
LIR_Opr right = yin->result();
set_no_result(x);
// Add safepoint before generating condition code so it can be recomputed. if (x->is_safepoint()) { // Increment backedge counter if needed.
increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),
x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci()); // Use safepoint_poll_register() instead of LIR_OprFact::illegalOpr.
__ safepoint(safepoint_poll_register(), state_for (x, x->state_before()));
}
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32 stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
len.load_item_force(arg3); // We skip int->long conversion here, because CRC32 stub expects int.
crc.load_item_force(arg1); // We skip int->long conversion here, because CRC32C stub doesn't care about high bits.
__ leal(LIR_OprFact::address(a), arg2);
__ move(len, cc->at(2)); // We skip int->long conversion here, because CRC32C stub expects int.
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
fatal("vectorizedMismatch intrinsic is not implemented on this platform");
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet am 2026-10-01)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.