Mercurial > hg > graal-jvmci-8
comparison src/share/vm/c1/c1_LIRGenerator.cpp @ 12875:d13d7aba8c12
8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Wed, 09 Oct 2013 16:32:21 +0200 |
parents | c775af091fe9 |
children | ce0cc25bc5e2 |
comparison
equal
deleted
inserted
replaced
12874:46ef27bcacb3 | 12875:d13d7aba8c12 |
---|---|
2569 | 2569 |
2570 __ jump(x->default_sux()); | 2570 __ jump(x->default_sux()); |
2571 } | 2571 } |
2572 | 2572 |
2573 | 2573 |
2574 ciKlass* LIRGenerator::profile_arg_type(ciMethodData* md, int md_base_offset, int md_offset, intptr_t profiled_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_k) { | |
2575 ciKlass* result = NULL; | |
2576 bool do_null = !not_null && !TypeEntries::was_null_seen(profiled_k); | |
2577 bool do_update = !TypeEntries::is_type_unknown(profiled_k); | |
2578 // known not to be null or null bit already set and already set to | |
2579 // unknown: nothing we can do to improve profiling | |
2580 if (!do_null && !do_update) { | |
2581 return result; | |
2582 } | |
2583 | |
2584 ciKlass* exact_klass = NULL; | |
2585 Compilation* comp = Compilation::current(); | |
2586 if (do_update) { | |
2587 // try to find exact type, using CHA if possible, so that loading | |
2588 // the klass from the object can be avoided | |
2589 ciType* type = arg->exact_type(); | |
2590 if (type == NULL) { | |
2591 type = arg->declared_type(); | |
2592 type = comp->cha_exact_type(type); | |
2593 } | |
2594 assert(type == NULL || type->is_klass(), "type should be class"); | |
2595 exact_klass = (type != NULL && type->is_loaded()) ? (ciKlass*)type : NULL; | |
2596 | |
2597 do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass; | |
2598 } | |
2599 | |
2600 if (!do_null && !do_update) { | |
2601 return result; | |
2602 } | |
2603 | |
2604 ciKlass* exact_signature_k = NULL; | |
2605 if (do_update) { | |
2606 // Is the type from the signature exact (the only one possible)? | |
2607 exact_signature_k = signature_k->exact_klass(); | |
2608 if (exact_signature_k == NULL) { | |
2609 exact_signature_k = comp->cha_exact_type(signature_k); | |
2610 } else { | |
2611 result = exact_signature_k; | |
2612 do_update = false; | |
2613 // Known statically. No need to emit any code: prevent | |
2614 // LIR_Assembler::emit_profile_type() from emitting useless code | |
2615 profiled_k = ciTypeEntries::with_status(result, profiled_k); | |
2616 } | |
2617 if (exact_signature_k != NULL && exact_klass != exact_signature_k) { | |
2618 assert(exact_klass == NULL, "arg and signature disagree?"); | |
2619 // sometimes the type of the signature is better than the best type | |
2620 // the compiler has | |
2621 exact_klass = exact_signature_k; | |
2622 do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass; | |
2623 } | |
2624 } | |
2625 | |
2626 if (!do_null && !do_update) { | |
2627 return result; | |
2628 } | |
2629 | |
2630 if (mdp == LIR_OprFact::illegalOpr) { | |
2631 mdp = new_register(T_METADATA); | |
2632 __ metadata2reg(md->constant_encoding(), mdp); | |
2633 if (md_base_offset != 0) { | |
2634 LIR_Address* base_type_address = new LIR_Address(mdp, md_base_offset, T_ADDRESS); | |
2635 mdp = new_pointer_register(); | |
2636 __ leal(LIR_OprFact::address(base_type_address), mdp); | |
2637 } | |
2638 } | |
2639 LIRItem value(arg, this); | |
2640 value.load_item(); | |
2641 __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA), | |
2642 value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL); | |
2643 return result; | |
2644 } | |
2645 | |
2574 void LIRGenerator::do_Base(Base* x) { | 2646 void LIRGenerator::do_Base(Base* x) { |
2575 __ std_entry(LIR_OprFact::illegalOpr); | 2647 __ std_entry(LIR_OprFact::illegalOpr); |
2576 // Emit moves from physical registers / stack slots to virtual registers | 2648 // Emit moves from physical registers / stack slots to virtual registers |
2577 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); | 2649 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); |
2578 IRScope* irScope = compilation()->hir()->top_scope(); | 2650 IRScope* irScope = compilation()->hir()->top_scope(); |
3002 | 3074 |
3003 default: ShouldNotReachHere(); break; | 3075 default: ShouldNotReachHere(); break; |
3004 } | 3076 } |
3005 } | 3077 } |
3006 | 3078 |
3079 void LIRGenerator::profile_arguments(ProfileCall* x) { | |
3080 if (MethodData::profile_arguments()) { | |
3081 int bci = x->bci_of_invoke(); | |
3082 ciMethodData* md = x->method()->method_data_or_null(); | |
3083 ciProfileData* data = md->bci_to_data(bci); | |
3084 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | |
3085 ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset(); | |
3086 int base_offset = md->byte_offset_of_slot(data, extra); | |
3087 LIR_Opr mdp = LIR_OprFact::illegalOpr; | |
3088 ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args(); | |
3089 | |
3090 Bytecodes::Code bc = x->method()->java_code_at_bci(bci); | |
3091 int start = 0; | |
3092 int stop = args->number_of_arguments(); | |
3093 if (x->nb_profiled_args() < stop) { | |
3094 // if called through method handle invoke, some arguments may have been popped | |
3095 stop = x->nb_profiled_args(); | |
3096 } | |
3097 ciSignature* sig = x->callee()->signature(); | |
3098 // method handle call to virtual method | |
3099 bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc); | |
3100 ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL); | |
3101 for (int i = 0; i < stop; i++) { | |
3102 int off = in_bytes(TypeStackSlotEntries::type_offset(i)) - in_bytes(TypeStackSlotEntries::args_data_offset()); | |
3103 ciKlass* exact = profile_arg_type(md, base_offset, off, | |
3104 args->type(i), x->profiled_arg_at(i+start), mdp, | |
3105 !x->arg_needs_null_check(i+start), sig_stream.next_klass()); | |
3106 if (exact != NULL) { | |
3107 md->set_argument_type(bci, i, exact); | |
3108 } | |
3109 } | |
3110 } | |
3111 } | |
3112 } | |
3113 | |
3007 void LIRGenerator::do_ProfileCall(ProfileCall* x) { | 3114 void LIRGenerator::do_ProfileCall(ProfileCall* x) { |
3008 // Need recv in a temporary register so it interferes with the other temporaries | 3115 // Need recv in a temporary register so it interferes with the other temporaries |
3009 LIR_Opr recv = LIR_OprFact::illegalOpr; | 3116 LIR_Opr recv = LIR_OprFact::illegalOpr; |
3010 LIR_Opr mdo = new_register(T_OBJECT); | 3117 LIR_Opr mdo = new_register(T_OBJECT); |
3011 // tmp is used to hold the counters on SPARC | 3118 // tmp is used to hold the counters on SPARC |
3012 LIR_Opr tmp = new_pointer_register(); | 3119 LIR_Opr tmp = new_pointer_register(); |
3120 | |
3121 if (x->nb_profiled_args() > 0) { | |
3122 profile_arguments(x); | |
3123 } | |
3124 | |
3013 if (x->recv() != NULL) { | 3125 if (x->recv() != NULL) { |
3014 LIRItem value(x->recv(), this); | 3126 LIRItem value(x->recv(), this); |
3015 value.load_item(); | 3127 value.load_item(); |
3016 recv = new_register(T_OBJECT); | 3128 recv = new_register(T_OBJECT); |
3017 __ move(value.result(), recv); | 3129 __ move(value.result(), recv); |