hotspot/src/share/vm/opto/parse1.cpp
changeset 24442 4d4ae31dea26
parent 24424 2658d7834c6e
child 24923 9631f7d691dc
--- a/hotspot/src/share/vm/opto/parse1.cpp	Tue May 13 11:25:17 2014 +0200
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Tue May 13 11:32:10 2014 -0700
@@ -568,6 +568,9 @@
   } else {
     set_map(entry_map);
     do_method_entry();
+    if (depth() == 1 && C->age_code()) {
+      decrement_age();
+    }
   }
   if (depth() == 1) {
     // Add check to deoptimize the nmethod if RTM state was changed
@@ -2048,6 +2051,31 @@
 #endif
 }
 
+void Parse::decrement_age() {
+  MethodCounters* mc = method()->ensure_method_counters();
+  if (mc == NULL) {
+    C->record_failure("Must have MCs");
+    return;
+  }
+  assert(!is_osr_parse(), "Not doing this for OSRs");
+
+  // Set starting bci for uncommon trap.
+  set_parse_bci(0);
+
+  const TypePtr* adr_type = TypeRawPtr::make((address)mc);
+  Node* mc_adr = makecon(adr_type);
+  Node* cnt_adr = basic_plus_adr(mc_adr, mc_adr, in_bytes(MethodCounters::nmethod_age_offset()));
+  Node* cnt = make_load(control(), cnt_adr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
+  Node* decr = _gvn.transform(new (C) SubINode(cnt, makecon(TypeInt::ONE)));
+  store_to_memory(control(), cnt_adr, decr, T_INT, adr_type, MemNode::unordered);
+  Node *chk   = _gvn.transform(new (C) CmpINode(decr, makecon(TypeInt::ZERO)));
+  Node* tst   = _gvn.transform(new (C) BoolNode(chk, BoolTest::gt));
+  { BuildCutout unless(this, tst, PROB_ALWAYS);
+    uncommon_trap(Deoptimization::Reason_tenured,
+                  Deoptimization::Action_make_not_entrant);
+  }
+}
+
 //------------------------------return_current---------------------------------
 // Append current _map to _exit_return
 void Parse::return_current(Node* value) {