Mercurial > hg > graal-jvmci-8
diff src/share/vm/c1/c1_LIRGenerator.cpp @ 6275:957c266d8bc5
Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 21 Aug 2012 10:39:19 +0200 |
parents | 33df1aeaebbf 1d7922586cf6 |
children | c38f13903fdf |
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LIRGenerator.cpp Mon Aug 20 15:21:31 2012 +0200 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Tue Aug 21 10:39:19 2012 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1242,6 +1242,36 @@ NULL /* info */); } +// Example: clazz.isInstance(object) +void LIRGenerator::do_isInstance(Intrinsic* x) { + assert(x->number_of_arguments() == 2, "wrong type"); + + // TODO could try to substitute this node with an equivalent InstanceOf + // if clazz is known to be a constant Class. This will pick up newly found + // constants after HIR construction. I'll leave this to a future change. + + // as a first cut, make a simple leaf call to runtime to stay platform independent. + // could follow the aastore example in a future change. + + LIRItem clazz(x->argument_at(0), this); + LIRItem object(x->argument_at(1), this); + clazz.load_item(); + object.load_item(); + LIR_Opr result = rlock_result(x); + + // need to perform null check on clazz + if (x->needs_null_check()) { + CodeEmitInfo* info = state_for(x); + __ null_check(clazz.result(), info); + } + + LIR_Opr call_result = call_runtime(clazz.value(), object.value(), + CAST_FROM_FN_PTR(address, Runtime1::is_instance_of), + x->type(), + NULL); // NULL CodeEmitInfo results in a leaf call + __ move(call_result, result); +} + // Example: object.getClass () void LIRGenerator::do_getClass(Intrinsic* x) { assert(x->number_of_arguments() == 1, "wrong type"); @@ -1910,6 +1940,14 @@ } +void LIRGenerator::do_TypeCast(TypeCast* x) { + LIRItem value(x->obj(), this); + value.load_item(); + // the result is the same as from the node we are casting + set_result(x, value.result()); +} + + void LIRGenerator::do_Throw(Throw* x) { LIRItem exception(x->exception(), this); exception.load_item(); @@ -2737,7 +2775,10 @@ // JSR 292 // Preserve the SP over MethodHandle call sites. ciMethod* target = x->target(); - if (target->is_method_handle_invoke()) { + bool is_method_handle_invoke = (// %%% FIXME: Are both of these relevant? + target->is_method_handle_intrinsic() || + target->is_compiled_lambda_form()); + if (is_method_handle_invoke) { info->set_is_method_handle_invoke(true); __ move(FrameMap::stack_pointer(), FrameMap::method_handle_invoke_SP_save_opr()); } @@ -2777,31 +2818,29 @@ int index = bcs.get_method_index(); size_t call_site_offset = cpcache->get_f1_offset(index); + // Load CallSite object from constant pool cache. + LIR_Opr call_site = new_register(objectType); + __ oop2reg(cpcache->constant_encoding(), call_site); + __ move_wide(new LIR_Address(call_site, call_site_offset, T_OBJECT), call_site); + // If this invokedynamic call site hasn't been executed yet in // the interpreter, the CallSite object in the constant pool // cache is still null and we need to deoptimize. if (cpcache->is_f1_null_at(index)) { - // Cannot re-use same xhandlers for multiple CodeEmitInfos, so - // clone all handlers. This is handled transparently in other - // places by the CodeEmitInfo cloning logic but is handled - // specially here because a stub isn't being used. - x->set_exception_handlers(new XHandlers(x->exception_handlers())); - + // Only deoptimize if the CallSite object is still null; we don't + // recompile methods in C1 after deoptimization so this call site + // might be resolved the next time we execute it after OSR. DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info); - __ jump(deopt_stub); + __ cmp(lir_cond_equal, call_site, LIR_OprFact::oopConst(NULL)); + __ branch(lir_cond_equal, T_OBJECT, deopt_stub); } // Use the receiver register for the synthetic MethodHandle // argument. receiver = LIR_Assembler::receiverOpr(); - LIR_Opr tmp = new_register(objectType); - - // Load CallSite object from constant pool cache. - __ oop2reg(cpcache->constant_encoding(), tmp); - __ move_wide(new LIR_Address(tmp, (int)call_site_offset, T_OBJECT), tmp); // Load target MethodHandle from CallSite object. - __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver); + __ load(new LIR_Address(call_site, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver); __ call_dynamic(target, receiver, result_register, SharedRuntime::get_resolve_opt_virtual_call_stub(), @@ -2809,13 +2848,13 @@ break; } default: - ShouldNotReachHere(); + fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(x->code()))); break; } // JSR 292 // Restore the SP after MethodHandle call sites. - if (target->is_method_handle_invoke()) { + if (is_method_handle_invoke) { __ move(FrameMap::method_handle_invoke_SP_save_opr(), FrameMap::stack_pointer()); } @@ -2879,6 +2918,50 @@ __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type())); } +void LIRGenerator::do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x) { + assert(x->number_of_arguments() == expected_arguments, "wrong type"); + LIR_Opr reg = result_register_for(x->type()); + __ call_runtime_leaf(routine, getThreadTemp(), + reg, new LIR_OprList()); + LIR_Opr result = rlock_result(x); + __ move(reg, result); +} + +#ifdef TRACE_HAVE_INTRINSICS +void LIRGenerator::do_ThreadIDIntrinsic(Intrinsic* x) { + LIR_Opr thread = getThreadPointer(); + LIR_Opr osthread = new_pointer_register(); + __ move(new LIR_Address(thread, in_bytes(JavaThread::osthread_offset()), osthread->type()), osthread); + size_t thread_id_size = OSThread::thread_id_size(); + if (thread_id_size == (size_t) BytesPerLong) { + LIR_Opr id = new_register(T_LONG); + __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_LONG), id); + __ convert(Bytecodes::_l2i, id, rlock_result(x)); + } else if (thread_id_size == (size_t) BytesPerInt) { + __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_INT), rlock_result(x)); + } else { + ShouldNotReachHere(); + } +} + +void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) { + CodeEmitInfo* info = state_for(x); + CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check + assert(info != NULL, "must have info"); + LIRItem arg(x->argument_at(1), this); + arg.load_item(); + LIR_Opr klass = new_register(T_OBJECT); + __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), T_OBJECT), klass, info); + LIR_Opr id = new_register(T_LONG); + ByteSize offset = TRACE_ID_OFFSET; + LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG); + __ move(trace_id_addr, id); + __ logical_or(id, LIR_OprFact::longConst(0x01l), id); + __ store(id, trace_id_addr); + __ logical_and(id, LIR_OprFact::longConst(~0x3l), id); + __ move(id, rlock_result(x)); +} +#endif void LIRGenerator::do_Intrinsic(Intrinsic* x) { switch (x->id()) { @@ -2890,27 +2973,24 @@ break; } - case vmIntrinsics::_currentTimeMillis: { - assert(x->number_of_arguments() == 0, "wrong type"); - LIR_Opr reg = result_register_for(x->type()); - __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeMillis), getThreadTemp(), - reg, new LIR_OprList()); - LIR_Opr result = rlock_result(x); - __ move(reg, result); +#ifdef TRACE_HAVE_INTRINSICS + case vmIntrinsics::_threadID: do_ThreadIDIntrinsic(x); break; + case vmIntrinsics::_classID: do_ClassIDIntrinsic(x); break; + case vmIntrinsics::_counterTime: + do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), 0, x); break; - } - - case vmIntrinsics::_nanoTime: { - assert(x->number_of_arguments() == 0, "wrong type"); - LIR_Opr reg = result_register_for(x->type()); - __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeNanos), getThreadTemp(), - reg, new LIR_OprList()); - LIR_Opr result = rlock_result(x); - __ move(reg, result); +#endif + + case vmIntrinsics::_currentTimeMillis: + do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeMillis), 0, x); break; - } + + case vmIntrinsics::_nanoTime: + do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeNanos), 0, x); + break; case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break; + case vmIntrinsics::_isInstance: do_isInstance(x); break; case vmIntrinsics::_getClass: do_getClass(x); break; case vmIntrinsics::_currentThread: do_currentThread(x); break; @@ -2920,7 +3000,9 @@ case vmIntrinsics::_dsqrt: // fall through case vmIntrinsics::_dtan: // fall through case vmIntrinsics::_dsin : // fall through - case vmIntrinsics::_dcos : do_MathIntrinsic(x); break; + case vmIntrinsics::_dcos : // fall through + case vmIntrinsics::_dexp : // fall through + case vmIntrinsics::_dpow : do_MathIntrinsic(x); break; case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break; // java.nio.Buffer.checkIndex @@ -2936,11 +3018,6 @@ do_CompareAndSwap(x, longType); break; - // sun.misc.AtomicLongCSImpl.attemptUpdate - case vmIntrinsics::_attemptUpdate: - do_AttemptUpdate(x); - break; - case vmIntrinsics::_Reference_get: do_Reference_get(x); break; @@ -2961,7 +3038,7 @@ recv = new_register(T_OBJECT); __ move(value.result(), recv); } - __ profile_call(x->method(), x->bci_of_invoke(), mdo, recv, tmp, x->known_holder()); + __ profile_call(x->method(), x->bci_of_invoke(), x->callee(), mdo, recv, tmp, x->known_holder()); } void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) { @@ -3181,4 +3258,3 @@ } } } -