21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciCallSite.hpp"
27 #include "ci/ciMethodHandle.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "interpreter/linkResolver.hpp"
32 #include "opto/addnode.hpp"
33 #include "opto/callGenerator.hpp"
34 #include "opto/castnode.hpp"
35 #include "opto/cfgnode.hpp"
36 #include "opto/mulnode.hpp"
37 #include "opto/parse.hpp"
38 #include "opto/rootnode.hpp"
39 #include "opto/runtime.hpp"
40 #include "opto/subnode.hpp"
41 #include "prims/nativeLookup.hpp"
42 #include "runtime/sharedRuntime.hpp"
43
44 void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
45 if (TraceTypeProfile || C->print_inlining()) {
46 outputStream* out = tty;
47 if (!C->print_inlining()) {
48 if (!PrintOpto && !PrintCompilation) {
49 method->print_short_name();
50 tty->cr();
51 }
52 CompileTask::print_inlining_tty(prof_method, depth, bci);
53 } else {
54 out = C->print_inlining_stream();
55 }
56 CompileTask::print_inline_indent(depth, out);
57 out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
58 stringStream ss;
59 prof_klass->name()->print_symbol_on(&ss);
60 out->print("%s", ss.as_string());
639 BasicType rt = rtype->basic_type();
640 BasicType ct = ctype->basic_type();
641 if (ct == T_VOID) {
642 // It's OK for a method to return a value that is discarded.
643 // The discarding does not require any special action from the caller.
644 // The Java code knows this, at VerifyType.isNullConversion.
645 pop_node(rt); // whatever it was, pop it
646 } else if (rt == T_INT || is_subword_type(rt)) {
647 // Nothing. These cases are handled in lambda form bytecode.
648 assert(ct == T_INT || is_subword_type(ct), "must match: rt=%s, ct=%s", type2name(rt), type2name(ct));
649 } else if (rt == T_OBJECT || rt == T_ARRAY) {
650 assert(ct == T_OBJECT || ct == T_ARRAY, "rt=%s, ct=%s", type2name(rt), type2name(ct));
651 if (ctype->is_loaded()) {
652 const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
653 const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
654 if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
655 Node* retnode = pop();
656 Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type));
657 push(cast_obj);
658 }
659 }
660 } else {
661 assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct));
662 // push a zero; it's better than getting an oop/int mismatch
663 pop_node(rt);
664 Node* retnode = zerocon(ct);
665 push_node(ct, retnode);
666 }
667 // Now that the value is well-behaved, continue with the call-site type.
668 rtype = ctype;
669 }
670 } else {
671 // Symbolic resolution enforces the types to be the same.
672 // NOTE: We must relax the assert for unloaded types because two
673 // different ciType instances of the same unloaded class type
674 // can appear to be "loaded" by different loaders (depending on
675 // the accessing class).
676 assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
677 "mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name());
678 }
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciCallSite.hpp"
27 #include "ci/ciMethodHandle.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "compiler/compileBroker.hpp"
30 #include "compiler/compileLog.hpp"
31 #include "interpreter/linkResolver.hpp"
32 #include "opto/addnode.hpp"
33 #include "opto/callGenerator.hpp"
34 #include "opto/castnode.hpp"
35 #include "opto/cfgnode.hpp"
36 #include "opto/mulnode.hpp"
37 #include "opto/parse.hpp"
38 #include "opto/rootnode.hpp"
39 #include "opto/runtime.hpp"
40 #include "opto/subnode.hpp"
41 #include "opto/valuetypenode.hpp"
42 #include "prims/nativeLookup.hpp"
43 #include "runtime/sharedRuntime.hpp"
44
45 void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
46 if (TraceTypeProfile || C->print_inlining()) {
47 outputStream* out = tty;
48 if (!C->print_inlining()) {
49 if (!PrintOpto && !PrintCompilation) {
50 method->print_short_name();
51 tty->cr();
52 }
53 CompileTask::print_inlining_tty(prof_method, depth, bci);
54 } else {
55 out = C->print_inlining_stream();
56 }
57 CompileTask::print_inline_indent(depth, out);
58 out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
59 stringStream ss;
60 prof_klass->name()->print_symbol_on(&ss);
61 out->print("%s", ss.as_string());
640 BasicType rt = rtype->basic_type();
641 BasicType ct = ctype->basic_type();
642 if (ct == T_VOID) {
643 // It's OK for a method to return a value that is discarded.
644 // The discarding does not require any special action from the caller.
645 // The Java code knows this, at VerifyType.isNullConversion.
646 pop_node(rt); // whatever it was, pop it
647 } else if (rt == T_INT || is_subword_type(rt)) {
648 // Nothing. These cases are handled in lambda form bytecode.
649 assert(ct == T_INT || is_subword_type(ct), "must match: rt=%s, ct=%s", type2name(rt), type2name(ct));
650 } else if (rt == T_OBJECT || rt == T_ARRAY) {
651 assert(ct == T_OBJECT || ct == T_ARRAY, "rt=%s, ct=%s", type2name(rt), type2name(ct));
652 if (ctype->is_loaded()) {
653 const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
654 const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
655 if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
656 Node* retnode = pop();
657 Node* cast_obj = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type));
658 push(cast_obj);
659 }
660 }
661 } else if (rt == T_VALUETYPE) {
662 assert(ct == T_VALUETYPE, "value type expected but got rt=%s, ct=%s", type2name(rt), type2name(ct));
663 if (rtype == C->env()->___Value_klass()) {
664 const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
665 Node* retnode = pop();
666 Node* cast = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type));
667 Node* vt = ValueTypeNode::make(_gvn, merged_memory(), cast);
668 push(vt);
669 } else {
670 assert(ctype == C->env()->___Value_klass(), "unexpected value type klass");
671 Node* retnode = pop();
672 assert(retnode->is_ValueType(), "inconsistent");
673 retnode = retnode->as_ValueType()->store_to_memory(this);
674 push(retnode);
675 }
676 } else {
677 assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct));
678 // push a zero; it's better than getting an oop/int mismatch
679 pop_node(rt);
680 Node* retnode = zerocon(ct);
681 push_node(ct, retnode);
682 }
683 // Now that the value is well-behaved, continue with the call-site type.
684 rtype = ctype;
685 }
686 } else {
687 // Symbolic resolution enforces the types to be the same.
688 // NOTE: We must relax the assert for unloaded types because two
689 // different ciType instances of the same unloaded class type
690 // can appear to be "loaded" by different loaders (depending on
691 // the accessing class).
692 assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
693 "mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name());
694 }
|