627 |
627 |
628 // Put top into the hash table ASAP. |
628 // Put top into the hash table ASAP. |
629 initial_gvn()->transform_no_reclaim(top()); |
629 initial_gvn()->transform_no_reclaim(top()); |
630 |
630 |
631 // Set up tf(), start(), and find a CallGenerator. |
631 // Set up tf(), start(), and find a CallGenerator. |
632 CallGenerator* cg; |
632 CallGenerator* cg = NULL; |
633 if (is_osr_compilation()) { |
633 if (is_osr_compilation()) { |
634 const TypeTuple *domain = StartOSRNode::osr_domain(); |
634 const TypeTuple *domain = StartOSRNode::osr_domain(); |
635 const TypeTuple *range = TypeTuple::make_range(method()->signature()); |
635 const TypeTuple *range = TypeTuple::make_range(method()->signature()); |
636 init_tf(TypeFunc::make(domain, range)); |
636 init_tf(TypeFunc::make(domain, range)); |
637 StartNode* s = new (this, 2) StartOSRNode(root(), domain); |
637 StartNode* s = new (this, 2) StartOSRNode(root(), domain); |
642 // Normal case. |
642 // Normal case. |
643 init_tf(TypeFunc::make(method())); |
643 init_tf(TypeFunc::make(method())); |
644 StartNode* s = new (this, 2) StartNode(root(), tf()->domain()); |
644 StartNode* s = new (this, 2) StartNode(root(), tf()->domain()); |
645 initial_gvn()->set_type_bottom(s); |
645 initial_gvn()->set_type_bottom(s); |
646 init_start(s); |
646 init_start(s); |
647 float past_uses = method()->interpreter_invocation_count(); |
647 if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) { |
648 float expected_uses = past_uses; |
648 // With java.lang.ref.reference.get() we must go through the |
649 cg = CallGenerator::for_inline(method(), expected_uses); |
649 // intrinsic when G1 is enabled - even when get() is the root |
|
650 // method of the compile - so that, if necessary, the value in |
|
651 // the referent field of the reference object gets recorded by |
|
652 // the pre-barrier code. |
|
653 // Specifically, if G1 is enabled, the value in the referent |
|
654 // field is recorded by the G1 SATB pre barrier. This will |
|
655 // result in the referent being marked live and the reference |
|
656 // object removed from the list of discovered references during |
|
657 // reference processing. |
|
658 cg = find_intrinsic(method(), false); |
|
659 } |
|
660 if (cg == NULL) { |
|
661 float past_uses = method()->interpreter_invocation_count(); |
|
662 float expected_uses = past_uses; |
|
663 cg = CallGenerator::for_inline(method(), expected_uses); |
|
664 } |
650 } |
665 } |
651 if (failing()) return; |
666 if (failing()) return; |
652 if (cg == NULL) { |
667 if (cg == NULL) { |
653 record_method_not_compilable_all_tiers("cannot parse method"); |
668 record_method_not_compilable_all_tiers("cannot parse method"); |
654 return; |
669 return; |
2046 static bool oop_offset_is_sane(const TypeInstPtr* tp) { |
2061 static bool oop_offset_is_sane(const TypeInstPtr* tp) { |
2047 ciInstanceKlass *k = tp->klass()->as_instance_klass(); |
2062 ciInstanceKlass *k = tp->klass()->as_instance_klass(); |
2048 // Make sure the offset goes inside the instance layout. |
2063 // Make sure the offset goes inside the instance layout. |
2049 return k->contains_field_offset(tp->offset()); |
2064 return k->contains_field_offset(tp->offset()); |
2050 // Note that OffsetBot and OffsetTop are very negative. |
2065 // Note that OffsetBot and OffsetTop are very negative. |
|
2066 } |
|
2067 |
|
2068 // Eliminate trivially redundant StoreCMs and accumulate their |
|
2069 // precedence edges. |
|
2070 static void eliminate_redundant_card_marks(Node* n) { |
|
2071 assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); |
|
2072 if (n->in(MemNode::Address)->outcnt() > 1) { |
|
2073 // There are multiple users of the same address so it might be |
|
2074 // possible to eliminate some of the StoreCMs |
|
2075 Node* mem = n->in(MemNode::Memory); |
|
2076 Node* adr = n->in(MemNode::Address); |
|
2077 Node* val = n->in(MemNode::ValueIn); |
|
2078 Node* prev = n; |
|
2079 bool done = false; |
|
2080 // Walk the chain of StoreCMs eliminating ones that match. As |
|
2081 // long as it's a chain of single users then the optimization is |
|
2082 // safe. Eliminating partially redundant StoreCMs would require |
|
2083 // cloning copies down the other paths. |
|
2084 while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) { |
|
2085 if (adr == mem->in(MemNode::Address) && |
|
2086 val == mem->in(MemNode::ValueIn)) { |
|
2087 // redundant StoreCM |
|
2088 if (mem->req() > MemNode::OopStore) { |
|
2089 // Hasn't been processed by this code yet. |
|
2090 n->add_prec(mem->in(MemNode::OopStore)); |
|
2091 } else { |
|
2092 // Already converted to precedence edge |
|
2093 for (uint i = mem->req(); i < mem->len(); i++) { |
|
2094 // Accumulate any precedence edges |
|
2095 if (mem->in(i) != NULL) { |
|
2096 n->add_prec(mem->in(i)); |
|
2097 } |
|
2098 } |
|
2099 // Everything above this point has been processed. |
|
2100 done = true; |
|
2101 } |
|
2102 // Eliminate the previous StoreCM |
|
2103 prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); |
|
2104 assert(mem->outcnt() == 0, "should be dead"); |
|
2105 mem->disconnect_inputs(NULL); |
|
2106 } else { |
|
2107 prev = mem; |
|
2108 } |
|
2109 mem = prev->in(MemNode::Memory); |
|
2110 } |
|
2111 } |
2051 } |
2112 } |
2052 |
2113 |
2053 //------------------------------final_graph_reshaping_impl---------------------- |
2114 //------------------------------final_graph_reshaping_impl---------------------- |
2054 // Implement items 1-5 from final_graph_reshaping below. |
2115 // Implement items 1-5 from final_graph_reshaping below. |
2055 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { |
2116 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { |
2174 case Op_StoreF: |
2235 case Op_StoreF: |
2175 case Op_LoadF: |
2236 case Op_LoadF: |
2176 frc.inc_float_count(); |
2237 frc.inc_float_count(); |
2177 goto handle_mem; |
2238 goto handle_mem; |
2178 |
2239 |
|
2240 case Op_StoreCM: |
|
2241 { |
|
2242 // Convert OopStore dependence into precedence edge |
|
2243 Node* prec = n->in(MemNode::OopStore); |
|
2244 n->del_req(MemNode::OopStore); |
|
2245 n->add_prec(prec); |
|
2246 eliminate_redundant_card_marks(n); |
|
2247 } |
|
2248 |
|
2249 // fall through |
|
2250 |
2179 case Op_StoreB: |
2251 case Op_StoreB: |
2180 case Op_StoreC: |
2252 case Op_StoreC: |
2181 case Op_StoreCM: |
|
2182 case Op_StorePConditional: |
2253 case Op_StorePConditional: |
2183 case Op_StoreI: |
2254 case Op_StoreI: |
2184 case Op_StoreL: |
2255 case Op_StoreL: |
2185 case Op_StoreIConditional: |
2256 case Op_StoreIConditional: |
2186 case Op_StoreLConditional: |
2257 case Op_StoreLConditional: |