diff src/share/vm/runtime/compilationPolicy.cpp @ 10105:aeaca88565e6

8010862: The Method counter fields used for profiling can be allocated lazily. Summary: Allocate the method's profiling related metadata until they are needed. Reviewed-by: coleenp, roland
author jiangli
date Tue, 09 Apr 2013 17:17:41 -0400
parents bd7a7ce2e264
children 42a42da29fd7
line wrap: on
line diff
--- a/src/share/vm/runtime/compilationPolicy.cpp	Thu Apr 04 21:15:43 2013 -0700
+++ b/src/share/vm/runtime/compilationPolicy.cpp	Tue Apr 09 17:17:41 2013 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -197,8 +197,10 @@
 
   // BUT also make sure the method doesn't look like it was never executed.
   // Set carry bit and reduce counter's value to min(count, CompileThreshold/2).
-  m->invocation_counter()->set_carry();
-  m->backedge_counter()->set_carry();
+  MethodCounters* mcs = m->method_counters();
+  assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+  mcs->invocation_counter()->set_carry();
+  mcs->backedge_counter()->set_carry();
 
   assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
 }
@@ -206,8 +208,10 @@
 void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
   // Delay next back-branch event but pump up invocation counter to triger
   // whole method compilation.
-  InvocationCounter* i = m->invocation_counter();
-  InvocationCounter* b = m->backedge_counter();
+  MethodCounters* mcs = m->method_counters();
+  assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+  InvocationCounter* i = mcs->invocation_counter();
+  InvocationCounter* b = mcs->backedge_counter();
 
   // Don't set invocation_counter's value too low otherwise the method will
   // look like immature (ic < ~5300) which prevents the inlining based on
@@ -226,7 +230,10 @@
 class CounterDecay : public AllStatic {
   static jlong _last_timestamp;
   static void do_method(Method* m) {
-    m->invocation_counter()->decay();
+    MethodCounters* mcs = m->method_counters();
+    if (mcs != NULL) {
+      mcs->invocation_counter()->decay();
+    }
   }
 public:
   static void decay();
@@ -264,30 +271,43 @@
 
 void NonTieredCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
   ScopeDesc* sd = trap_scope;
+  MethodCounters* mcs;
+  InvocationCounter* c;
   for (; !sd->is_top(); sd = sd->sender()) {
-    // Reset ICs of inlined methods, since they can trigger compilations also.
-    sd->method()->invocation_counter()->reset();
+    mcs = sd->method()->method_counters();
+    if (mcs != NULL) {
+      // Reset ICs of inlined methods, since they can trigger compilations also.
+      mcs->invocation_counter()->reset();
+    }
   }
-  InvocationCounter* c = sd->method()->invocation_counter();
-  if (is_osr) {
-    // It was an OSR method, so bump the count higher.
-    c->set(c->state(), CompileThreshold);
-  } else {
-    c->reset();
+  mcs = sd->method()->method_counters();
+  if (mcs != NULL) {
+    c = mcs->invocation_counter();
+    if (is_osr) {
+      // It was an OSR method, so bump the count higher.
+      c->set(c->state(), CompileThreshold);
+    } else {
+      c->reset();
+    }
+    mcs->backedge_counter()->reset();
   }
-  sd->method()->backedge_counter()->reset();
 }
 
 // This method can be called by any component of the runtime to notify the policy
 // that it's recommended to delay the complation of this method.
 void NonTieredCompPolicy::delay_compilation(Method* method) {
-  method->invocation_counter()->decay();
-  method->backedge_counter()->decay();
+  MethodCounters* mcs = method->method_counters();
+  assert(mcs != NULL, "MethodCounters cannot be NULL");
+  mcs->invocation_counter()->decay();
+  mcs->backedge_counter()->decay();
 }
 
 void NonTieredCompPolicy::disable_compilation(Method* method) {
-  method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
-  method->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
+  MethodCounters* mcs = method->method_counters();
+  if (mcs != NULL) {
+    mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
+    mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
+  }
 }
 
 CompileTask* NonTieredCompPolicy::select_task(CompileQueue* compile_queue) {
@@ -370,8 +390,10 @@
 #ifndef PRODUCT
 void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) {
   if (TraceInvocationCounterOverflow) {
-    InvocationCounter* ic = m->invocation_counter();
-    InvocationCounter* bc = m->backedge_counter();
+    MethodCounters* mcs = m->method_counters();
+    assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
+    InvocationCounter* ic = mcs->invocation_counter();
+    InvocationCounter* bc = mcs->backedge_counter();
     ResourceMark rm;
     const char* msg =
       bci == InvocationEntryBci