Mercurial > hg > truffle
comparison src/share/vm/ci/ciMethod.cpp @ 1783:d5d065957597
6953144: Tiered compilation
Summary: Infrastructure for tiered compilation support (interpreter + c1 + c2) for 32 and 64 bit. Simple tiered policy implementation.
Reviewed-by: kvn, never, phh, twisti
author | iveresov |
---|---|
date | Fri, 03 Sep 2010 17:51:07 -0700 |
parents | 3e8fbc61cee8 |
children | c93c652551b5 |
comparison
equal
deleted
inserted
replaced
1782:f353275af40e | 1783:d5d065957597 |
---|---|
47 _code_size = h_m()->code_size(); | 47 _code_size = h_m()->code_size(); |
48 _intrinsic_id = h_m()->intrinsic_id(); | 48 _intrinsic_id = h_m()->intrinsic_id(); |
49 _handler_count = h_m()->exception_table()->length() / 4; | 49 _handler_count = h_m()->exception_table()->length() / 4; |
50 _uses_monitors = h_m()->access_flags().has_monitor_bytecodes(); | 50 _uses_monitors = h_m()->access_flags().has_monitor_bytecodes(); |
51 _balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching(); | 51 _balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching(); |
52 _is_compilable = !h_m()->is_not_compilable(); | 52 _is_c1_compilable = !h_m()->is_not_c1_compilable(); |
53 _is_c2_compilable = !h_m()->is_not_c2_compilable(); | |
53 // Lazy fields, filled in on demand. Require allocation. | 54 // Lazy fields, filled in on demand. Require allocation. |
54 _code = NULL; | 55 _code = NULL; |
55 _exception_handlers = NULL; | 56 _exception_handlers = NULL; |
56 _liveness = NULL; | 57 _liveness = NULL; |
57 _method_blocks = NULL; | 58 _method_blocks = NULL; |
59 _flow = NULL; | 60 _flow = NULL; |
60 _bcea = NULL; | 61 _bcea = NULL; |
61 #endif // COMPILER2 || SHARK | 62 #endif // COMPILER2 || SHARK |
62 | 63 |
63 ciEnv *env = CURRENT_ENV; | 64 ciEnv *env = CURRENT_ENV; |
64 if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) { | 65 if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) { |
65 // 6328518 check hotswap conditions under the right lock. | 66 // 6328518 check hotswap conditions under the right lock. |
66 MutexLocker locker(Compile_lock); | 67 MutexLocker locker(Compile_lock); |
67 if (Dependencies::check_evol_method(h_m()) != NULL) { | 68 if (Dependencies::check_evol_method(h_m()) != NULL) { |
68 _is_compilable = false; | 69 _is_c1_compilable = false; |
70 _is_c2_compilable = false; | |
69 } | 71 } |
70 } else { | 72 } else { |
71 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | 73 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
72 } | 74 } |
73 | 75 |
91 _holder = env->get_object(h_m()->method_holder())->as_instance_klass(); | 93 _holder = env->get_object(h_m()->method_holder())->as_instance_klass(); |
92 ciSymbol* sig_symbol = env->get_object(h_m()->signature())->as_symbol(); | 94 ciSymbol* sig_symbol = env->get_object(h_m()->signature())->as_symbol(); |
93 _signature = new (env->arena()) ciSignature(_holder, sig_symbol); | 95 _signature = new (env->arena()) ciSignature(_holder, sig_symbol); |
94 _method_data = NULL; | 96 _method_data = NULL; |
95 // Take a snapshot of these values, so they will be commensurate with the MDO. | 97 // Take a snapshot of these values, so they will be commensurate with the MDO. |
96 if (ProfileInterpreter) { | 98 if (ProfileInterpreter || TieredCompilation) { |
97 int invcnt = h_m()->interpreter_invocation_count(); | 99 int invcnt = h_m()->interpreter_invocation_count(); |
98 // if the value overflowed report it as max int | 100 // if the value overflowed report it as max int |
99 _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ; | 101 _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ; |
100 _interpreter_throwout_count = h_m()->interpreter_throwout_count(); | 102 _interpreter_throwout_count = h_m()->interpreter_throwout_count(); |
101 } else { | 103 } else { |
435 } else { // ReceiverTypeData is a subclass of CounterData | 437 } else { // ReceiverTypeData is a subclass of CounterData |
436 ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData(); | 438 ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData(); |
437 // In addition, virtual call sites have receiver type information | 439 // In addition, virtual call sites have receiver type information |
438 int receivers_count_total = 0; | 440 int receivers_count_total = 0; |
439 int morphism = 0; | 441 int morphism = 0; |
442 // Precompute morphism for the possible fixup | |
440 for (uint i = 0; i < call->row_limit(); i++) { | 443 for (uint i = 0; i < call->row_limit(); i++) { |
441 ciKlass* receiver = call->receiver(i); | 444 ciKlass* receiver = call->receiver(i); |
442 if (receiver == NULL) continue; | 445 if (receiver == NULL) continue; |
443 morphism += 1; | 446 morphism++; |
444 int rcount = call->receiver_count(i); | 447 } |
448 int epsilon = 0; | |
449 if (TieredCompilation && ProfileInterpreter) { | |
450 // Interpreter and C1 treat final and special invokes differently. | |
451 // C1 will record a type, whereas the interpreter will just | |
452 // increment the count. Detect this case. | |
453 if (morphism == 1 && count > 0) { | |
454 epsilon = count; | |
455 count = 0; | |
456 } | |
457 } | |
458 for (uint i = 0; i < call->row_limit(); i++) { | |
459 ciKlass* receiver = call->receiver(i); | |
460 if (receiver == NULL) continue; | |
461 int rcount = call->receiver_count(i) + epsilon; | |
445 if (rcount == 0) rcount = 1; // Should be valid value | 462 if (rcount == 0) rcount = 1; // Should be valid value |
446 receivers_count_total += rcount; | 463 receivers_count_total += rcount; |
447 // Add the receiver to result data. | 464 // Add the receiver to result data. |
448 result.add_receiver(receiver, rcount); | 465 result.add_receiver(receiver, rcount); |
449 // If we extend profiling to record methods, | 466 // If we extend profiling to record methods, |
685 // counts in the MDO should be scaled by 4X, so that | 702 // counts in the MDO should be scaled by 4X, so that |
686 // they can be usefully and stably compared against the | 703 // they can be usefully and stably compared against the |
687 // invocation counts in methods. | 704 // invocation counts in methods. |
688 int ciMethod::scale_count(int count, float prof_factor) { | 705 int ciMethod::scale_count(int count, float prof_factor) { |
689 if (count > 0 && method_data() != NULL) { | 706 if (count > 0 && method_data() != NULL) { |
690 int current_mileage = method_data()->current_mileage(); | 707 int counter_life; |
691 int creation_mileage = method_data()->creation_mileage(); | |
692 int counter_life = current_mileage - creation_mileage; | |
693 int method_life = interpreter_invocation_count(); | 708 int method_life = interpreter_invocation_count(); |
709 if (TieredCompilation) { | |
710 // In tiered the MDO's life is measured directly, so just use the snapshotted counters | |
711 counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count()); | |
712 } else { | |
713 int current_mileage = method_data()->current_mileage(); | |
714 int creation_mileage = method_data()->creation_mileage(); | |
715 counter_life = current_mileage - creation_mileage; | |
716 } | |
717 | |
694 // counter_life due to backedge_counter could be > method_life | 718 // counter_life due to backedge_counter could be > method_life |
695 if (counter_life > method_life) | 719 if (counter_life > method_life) |
696 counter_life = method_life; | 720 counter_life = method_life; |
697 if (0 < counter_life && counter_life <= method_life) { | 721 if (0 < counter_life && counter_life <= method_life) { |
698 count = (int)((double)count * prof_factor * method_life / counter_life + 0.5); | 722 count = (int)((double)count * prof_factor * method_life / counter_life + 0.5); |
776 VM_ENTRY_MARK; | 800 VM_ENTRY_MARK; |
777 ciEnv* env = CURRENT_ENV; | 801 ciEnv* env = CURRENT_ENV; |
778 Thread* my_thread = JavaThread::current(); | 802 Thread* my_thread = JavaThread::current(); |
779 methodHandle h_m(my_thread, get_methodOop()); | 803 methodHandle h_m(my_thread, get_methodOop()); |
780 | 804 |
781 if (Tier1UpdateMethodData && is_tier1_compile(env->comp_level())) { | 805 // Create an MDO for the inlinee |
806 if (TieredCompilation && is_c1_compile(env->comp_level())) { | |
782 build_method_data(h_m); | 807 build_method_data(h_m); |
783 } | 808 } |
784 | 809 |
785 if (h_m()->method_data() != NULL) { | 810 if (h_m()->method_data() != NULL) { |
786 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); | 811 _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data(); |
883 // ciMethod::can_be_compiled | 908 // ciMethod::can_be_compiled |
884 // | 909 // |
885 // Have previous compilations of this method succeeded? | 910 // Have previous compilations of this method succeeded? |
886 bool ciMethod::can_be_compiled() { | 911 bool ciMethod::can_be_compiled() { |
887 check_is_loaded(); | 912 check_is_loaded(); |
888 return _is_compilable; | 913 ciEnv* env = CURRENT_ENV; |
914 if (is_c1_compile(env->comp_level())) { | |
915 return _is_c1_compilable; | |
916 } | |
917 return _is_c2_compilable; | |
889 } | 918 } |
890 | 919 |
891 // ------------------------------------------------------------------ | 920 // ------------------------------------------------------------------ |
892 // ciMethod::set_not_compilable | 921 // ciMethod::set_not_compilable |
893 // | 922 // |
894 // Tell the VM that this method cannot be compiled at all. | 923 // Tell the VM that this method cannot be compiled at all. |
895 void ciMethod::set_not_compilable() { | 924 void ciMethod::set_not_compilable() { |
896 check_is_loaded(); | 925 check_is_loaded(); |
897 VM_ENTRY_MARK; | 926 VM_ENTRY_MARK; |
898 _is_compilable = false; | 927 ciEnv* env = CURRENT_ENV; |
899 get_methodOop()->set_not_compilable(); | 928 if (is_c1_compile(env->comp_level())) { |
929 _is_c1_compilable = false; | |
930 } else { | |
931 _is_c2_compilable = false; | |
932 } | |
933 get_methodOop()->set_not_compilable(env->comp_level()); | |
900 } | 934 } |
901 | 935 |
902 // ------------------------------------------------------------------ | 936 // ------------------------------------------------------------------ |
903 // ciMethod::can_be_osr_compiled | 937 // ciMethod::can_be_osr_compiled |
904 // | 938 // |
908 // of failed OSR compilations per bci. The entry_bci parameter | 942 // of failed OSR compilations per bci. The entry_bci parameter |
909 // is currently unused. | 943 // is currently unused. |
910 bool ciMethod::can_be_osr_compiled(int entry_bci) { | 944 bool ciMethod::can_be_osr_compiled(int entry_bci) { |
911 check_is_loaded(); | 945 check_is_loaded(); |
912 VM_ENTRY_MARK; | 946 VM_ENTRY_MARK; |
913 return !get_methodOop()->access_flags().is_not_osr_compilable(); | 947 ciEnv* env = CURRENT_ENV; |
948 return !get_methodOop()->is_not_osr_compilable(env->comp_level()); | |
914 } | 949 } |
915 | 950 |
916 // ------------------------------------------------------------------ | 951 // ------------------------------------------------------------------ |
917 // ciMethod::has_compiled_code | 952 // ciMethod::has_compiled_code |
918 bool ciMethod::has_compiled_code() { | 953 bool ciMethod::has_compiled_code() { |
919 VM_ENTRY_MARK; | 954 VM_ENTRY_MARK; |
920 return get_methodOop()->code() != NULL; | 955 return get_methodOop()->code() != NULL; |
956 } | |
957 | |
958 int ciMethod::comp_level() { | |
959 check_is_loaded(); | |
960 VM_ENTRY_MARK; | |
961 nmethod* nm = get_methodOop()->code(); | |
962 if (nm != NULL) return nm->comp_level(); | |
963 return 0; | |
921 } | 964 } |
922 | 965 |
923 // ------------------------------------------------------------------ | 966 // ------------------------------------------------------------------ |
924 // ciMethod::instructions_size | 967 // ciMethod::instructions_size |
925 // | 968 // |
926 // This is a rough metric for "fat" methods, compared before inlining | 969 // This is a rough metric for "fat" methods, compared before inlining |
927 // with InlineSmallCode. The CodeBlob::code_size accessor includes | 970 // with InlineSmallCode. The CodeBlob::code_size accessor includes |
928 // junk like exception handler, stubs, and constant table, which are | 971 // junk like exception handler, stubs, and constant table, which are |
929 // not highly relevant to an inlined method. So we use the more | 972 // not highly relevant to an inlined method. So we use the more |
930 // specific accessor nmethod::insts_size. | 973 // specific accessor nmethod::insts_size. |
931 int ciMethod::instructions_size() { | 974 int ciMethod::instructions_size(int comp_level) { |
932 GUARDED_VM_ENTRY( | 975 GUARDED_VM_ENTRY( |
933 nmethod* code = get_methodOop()->code(); | 976 nmethod* code = get_methodOop()->code(); |
934 // if there's no compiled code or the code was produced by the | 977 if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) { |
935 // tier1 profiler return 0 for the code size. This should | 978 return code->code_end() - code->verified_entry_point(); |
936 // probably be based on the compilation level of the nmethod but | 979 } |
937 // that currently isn't properly recorded. | 980 return 0; |
938 if (code == NULL || | |
939 (TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) { | |
940 return 0; | |
941 } | |
942 return code->insts_end() - code->verified_entry_point(); | |
943 ) | 981 ) |
944 } | 982 } |
945 | 983 |
946 // ------------------------------------------------------------------ | 984 // ------------------------------------------------------------------ |
947 // ciMethod::log_nmethod_identity | 985 // ciMethod::log_nmethod_identity |