c1_LIRGenerator.cpp revision 3560
2362N/A * or visit www.oracle.com if you need additional information or have any
1968N/A#include "precompiled.hpp"
1968N/A#include "c1/c1_Compilation.hpp"
1968N/A#include "c1/c1_FrameMap.hpp"
1968N/A#include "c1/c1_Instruction.hpp"
1968N/A#include "c1/c1_LIRAssembler.hpp"
1968N/A#include "c1/c1_LIRGenerator.hpp"
1968N/A#include "c1/c1_ValueStack.hpp"
1968N/A#include "ci/ciArrayKlass.hpp"
1968N/A#include "ci/ciCPCache.hpp"
1968N/A#include "ci/ciInstance.hpp"
1968N/A#include "runtime/sharedRuntime.hpp"
1968N/A#include "runtime/stubRoutines.hpp"
1968N/A#include "utilities/bitMap.inline.hpp"
1968N/A#include "gc_implementation/g1/heapRegion.hpp"
return node;
assert(value()->operand()->is_illegal() || value()->operand()->is_constant(), "operand should never change");
load_item();
if (r != reg) {
if (oc) {
return NULL;
#ifndef PRODUCT
if (PrintIRWithLIR) {
if (LIRTraceExecution &&
#ifndef PRODUCT
if (PrintIRWithLIR) {
assert(instr->operand() != LIR_OprFact::illegalOpr || instr->as_Constant() != NULL, "this root has not yet been visited");
for_each_state(s) {
assert(s->stack_size() == 0 && s->locals_size() == 0 && (s->locks_size() == 0 || s->locks_size() == 1), "state must be empty");
int index;
assert(x->as_MonitorEnter() || x->as_ProfileInvoke(), "only other cases are MonitorEnter and ProfileInvoke");
void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp_op, CodeEmitInfo* info) {
switch(code) {
if (is_strictfp) {
bool did_strength_reduce = false;
if (is_power_of_2(c)) {
did_strength_reduce = true;
if (!did_strength_reduce) {
if (is_strictfp) {
default: ShouldNotReachHere();
void LIRGenerator::arithmetic_op_int(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp) {
void LIRGenerator::arithmetic_op_long(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
void LIRGenerator::arithmetic_op_fpu(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp) {
void LIRGenerator::shift_op(Bytecodes::Code code, LIR_Opr result_op, LIR_Opr value, LIR_Opr count, LIR_Opr tmp) {
switch(code) {
default: ShouldNotReachHere();
void LIRGenerator::logic_op (Bytecodes::Code code, LIR_Opr result_op, LIR_Opr left_op, LIR_Opr right_op) {
switch(code) {
default: ShouldNotReachHere();
void LIRGenerator::monitor_enter(LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info) {
if (!GenerateSynchronizationCode) return;
// for handling NullPointerException, use debug info representing just the lock stack before this monitorenter
void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, LIR_Opr scratch, int monitor_no) {
if (!GenerateSynchronizationCode) return;
void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) {
Runtime1::StubID stub_id = klass->is_initialized() ? Runtime1::fast_new_instance_id : Runtime1::fast_new_instance_init_check_id;
return (c->value() == 0);
return (c->value() >= 0);
return NULL;
return NULL;
return NULL;
if (t == NULL) {
return NULL;
return NULL;
is_exact = true;
is_exact = true;
src_objarray = (src_exact_type && src_exact_type->is_obj_array_klass()) || (src_declared_type && src_declared_type->is_obj_array_klass());
dst_objarray = (dst_exact_type && dst_exact_type->is_obj_array_klass()) || (dst_declared_type && dst_declared_type->is_obj_array_klass());
if (!src_objarray)
if (!dst_objarray)
if (!x->arg_needs_null_check(0))
if (is_exact) {
return result;
return opr;
value = r;
return tmp;
int t = taken_count_offset;
int index;
return reg;
switch (type) {
case T_BYTE:
case T_BOOLEAN:
return reg;
if (oc) {
return NULL;
assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block");
exceptionOopOpr());
// Code for a constant is generated lazily unless the constant is frequently used and can't be inlined.
if (!x->is_pinned()) {
call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
set_no_result(x);
if (x->needs_null_check()) {
if (x->needs_null_check()) {
// Example: Thread.currentThread()
__ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
set_no_result(x);
if (c != NULL) {
return x->operand();
return NULL;
return NULL;
case T_INT:
case T_FLOAT:
case T_LONG:
case T_DOUBLE:
case T_OBJECT:
return result;
#ifndef SERIALGC
#ifndef SERIALGC
#ifndef SERIALGC
if (do_load) {
if (patch)
if (TwoOperandLIRForm ) {
#ifdef ARM
__ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp);
LIR_Address *card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE);
if (TwoOperandLIRForm) {
T_BYTE));
// Comment copied form templateTable_i486.cpp
// JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
if (needs_patching) {
} else if (x->needs_null_check()) {
set_no_result(x);
#ifndef PRODUCT
if (x->needs_null_check() &&
(needs_patching ||
if (needs_patching) {
if (is_oop) {
if (is_oop) {
if (needs_patching) {
} else if (x->needs_null_check()) {
#ifndef PRODUCT
if (x->needs_null_check() &&
(needs_patching ||
if (needs_patching) {
//------------------------java.nio.Buffer.checkIndex------------------------
// int java.nio.Buffer.checkIndex(int)
if (GenerateRangeChecks) {
cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info);
if (x->needs_null_check()) {
__ load(new LIR_Address(array.result(), arrayOopDesc::length_offset_in_bytes(), T_INT), reg, info, lir_patch_none);
bool needs_range_check = true;
if (use_length) {
if (needs_range_check) {
if (x->needs_null_check()) {
if (use_length) {
if (x->can_trap()) {
set_no_result(x);
#ifndef PRODUCT
if (PrintC1Statistics) {
bool unwind = false;
unwind = true;
bool type_is_exact = true;
type_is_exact = false;
if (GenerateCompilerNullChecks &&
__ null_check(exception_opr, new CodeEmitInfo(info, x->state()->copy(ValueStack::ExceptionState, x->state()->bci())));
unwind = false;
if (unwind) {
assert(input_opr->is_single_fpu() || input_opr->is_double_fpu(), "input should be floating-point value");
if (x->has_index()) {
int log2_scale = 0;
if (x->has_index()) {
#ifndef _LP64
#ifdef X86
#ifdef _LP64
#ifdef _LP64
int log2_scale = 0;
if (x->has_index()) {
if (x->has_index()) {
set_no_result(x);
#ifndef _LP64
if (log2_scale != 0) {
#ifdef _LP64
#ifdef _LP64
#ifdef _LP64
#ifndef SERIALGC
// We can skip generating/checking the remaining guards and
gen_code_stub = false;
gen_offset_check = false;
gen_code_stub = false;
if (gen_code_stub) {
gen_code_stub = false;
gen_source_check = false;
if (gen_code_stub) {
if (gen_offset_check) {
if (gen_source_check) {
set_no_result(x);
set_no_result(x);
do_UnsafePrefetch(x, false);
do_UnsafePrefetch(x, true);
for (int i = 0; i < lng; i++) {
if (len > 0) {
return res;
if (len > 0) {
return res;
set_no_result(x);
if (x->is_safepoint()) {
if (UseTableRanges) {
for (int i = 0; i < len; i++) {
set_no_result(x);
if (x->is_safepoint()) {
if (UseTableRanges) {
for (int i = 0; i < len; i++) {
set_no_result(x);
if (x->is_safepoint()) {
if (x->should_profile()) {
int offset;
int java_index = 0;
case T_BYTE:
case T_BOOLEAN:
case T_SHORT:
case T_CHAR:
t = T_INT;
#ifndef __SOFTFP__
call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
if (x->has_receiver()) {
if (x->has_receiver()) {
if (x->is_invokedynamic()) {
for (int i = 0; i < x->number_of_arguments(); i++) {
return argument_items;
if (x->has_receiver()) {
switch (x->code()) {
} else if (x->vtable_index() < 0) {
__ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
#ifdef ASSERT
assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others");
switch (x->id()) {
do_FPIntrinsics(x);
// java.nio.Buffer.checkIndex
do_AttemptUpdate(x);
do_Reference_get(x);
default: ShouldNotReachHere(); break;
increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
int freq_log;
// Increment the appropriate invocation/backedge counter and notify the runtime.
increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
if (notify) {
if (x->pass_thread()) {
for (int i = 0; i < x->number_of_arguments(); i++) {
set_no_result(x);
LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
LIR_Opr LIRGenerator::call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info) {
if (info) {
return result;
if (info) {
return result;
switch(code) {
default : ShouldNotReachHere(); break;