aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm
diff options
context:
space:
mode:
authorjiangli <none@none>2013-04-15 21:25:23 -0400
committerjiangli <none@none>2013-04-15 21:25:23 -0400
commite7b455fc9a6496a801216d22a5259b0187c02ab7 (patch)
tree06c95f51c880b6f9f7d841c5ecd7a13fc21710bc /src/share/vm
parent94587a094ebc1cdb2883fafaa994bde1a6f3d557 (diff)
parentfb81890b3987580c4cb3fe8fd0aa0821e787d9da (diff)
Merge
Diffstat (limited to 'src/share/vm')
-rw-r--r--src/share/vm/c1/c1_LIRGenerator.cpp19
-rw-r--r--src/share/vm/ci/ciMethod.cpp21
-rw-r--r--src/share/vm/ci/ciMethod.hpp3
-rw-r--r--src/share/vm/ci/ciReplay.cpp9
-rw-r--r--src/share/vm/interpreter/interpreterRuntime.cpp13
-rw-r--r--src/share/vm/interpreter/interpreterRuntime.hpp3
-rw-r--r--src/share/vm/interpreter/invocationCounter.cpp12
-rw-r--r--src/share/vm/oops/method.cpp60
-rw-r--r--src/share/vm/oops/method.hpp132
-rw-r--r--src/share/vm/oops/methodCounters.cpp37
-rw-r--r--src/share/vm/oops/methodCounters.hpp124
-rw-r--r--src/share/vm/oops/methodData.cpp19
-rw-r--r--src/share/vm/opto/parseHelper.cpp18
-rw-r--r--src/share/vm/prims/whitebox.cpp17
-rw-r--r--src/share/vm/runtime/advancedThresholdPolicy.cpp13
-rw-r--r--src/share/vm/runtime/compilationPolicy.cpp65
-rw-r--r--src/share/vm/runtime/fprofiler.cpp5
-rw-r--r--src/share/vm/runtime/simpleThresholdPolicy.cpp8
-rw-r--r--src/share/vm/runtime/vmStructs.cpp17
19 files changed, 449 insertions, 146 deletions
diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp
index ffb2965fd..60c2bb849 100644
--- a/src/share/vm/c1/c1_LIRGenerator.cpp
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -3044,21 +3044,20 @@ void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
assert(level > CompLevel_simple, "Shouldn't be here");
int offset = -1;
- LIR_Opr counter_holder = new_register(T_METADATA);
- LIR_Opr meth;
+ LIR_Opr counter_holder;
if (level == CompLevel_limited_profile) {
- offset = in_bytes(backedge ? Method::backedge_counter_offset() :
- Method::invocation_counter_offset());
- __ metadata2reg(method->constant_encoding(), counter_holder);
- meth = counter_holder;
+ address counters_adr = method->ensure_method_counters();
+ counter_holder = new_pointer_register();
+ __ move(LIR_OprFact::intptrConst(counters_adr), counter_holder);
+ offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() :
+ MethodCounters::invocation_counter_offset());
} else if (level == CompLevel_full_profile) {
+ counter_holder = new_register(T_METADATA);
offset = in_bytes(backedge ? MethodData::backedge_counter_offset() :
MethodData::invocation_counter_offset());
ciMethodData* md = method->method_data_or_null();
assert(md != NULL, "Sanity");
__ metadata2reg(md->constant_encoding(), counter_holder);
- meth = new_register(T_METADATA);
- __ metadata2reg(method->constant_encoding(), meth);
} else {
ShouldNotReachHere();
}
@@ -3069,6 +3068,8 @@ void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
__ store(result, counter);
if (notify) {
LIR_Opr mask = load_immediate(frequency << InvocationCounter::count_shift, T_INT);
+ LIR_Opr meth = new_register(T_METADATA);
+ __ metadata2reg(method->constant_encoding(), meth);
__ logical_and(result, mask, result);
__ cmp(lir_cond_equal, result, LIR_OprFact::intConst(0));
// The bci for info can point to cmp for if's we want the if bci
diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp
index 646de740f..780f4ad86 100644
--- a/src/share/vm/ci/ciMethod.cpp
+++ b/src/share/vm/ci/ciMethod.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -905,6 +905,20 @@ ciMethodData* ciMethod::method_data_or_null() {
}
// ------------------------------------------------------------------
+// ciMethod::ensure_method_counters
+//
+address ciMethod::ensure_method_counters() {
+ check_is_loaded();
+ VM_ENTRY_MARK;
+ methodHandle mh(THREAD, get_Method());
+ MethodCounters *counter = mh->method_counters();
+ if (counter == NULL) {
+ counter = Method::build_method_counters(mh(), CHECK_AND_CLEAR_NULL);
+ }
+ return (address)counter;
+}
+
+// ------------------------------------------------------------------
// ciMethod::should_exclude
//
// Should this method be excluded from compilation?
@@ -1191,13 +1205,14 @@ void ciMethod::dump_replay_data(outputStream* st) {
ASSERT_IN_VM;
ResourceMark rm;
Method* method = get_Method();
+ MethodCounters* mcs = method->method_counters();
Klass* holder = method->method_holder();
st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
holder->name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
- method->invocation_counter()->raw_counter(),
- method->backedge_counter()->raw_counter(),
+ mcs == NULL ? 0 : mcs->invocation_counter()->raw_counter(),
+ mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(),
interpreter_invocation_count(),
interpreter_throwout_count(),
_instructions_size);
diff --git a/src/share/vm/ci/ciMethod.hpp b/src/share/vm/ci/ciMethod.hpp
index cbef39b3c..f206f1991 100644
--- a/src/share/vm/ci/ciMethod.hpp
+++ b/src/share/vm/ci/ciMethod.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -262,6 +262,7 @@ class ciMethod : public ciMetadata {
bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
bool check_call(int refinfo_index, bool is_static) const;
bool ensure_method_data(); // make sure it exists in the VM also
+ address ensure_method_counters();
int instructions_size();
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
diff --git a/src/share/vm/ci/ciReplay.cpp b/src/share/vm/ci/ciReplay.cpp
index 030d93db7..0d68b8cc8 100644
--- a/src/share/vm/ci/ciReplay.cpp
+++ b/src/share/vm/ci/ciReplay.cpp
@@ -920,12 +920,17 @@ void ciReplay::initialize(ciMethod* m) {
method->print_name(tty);
tty->cr();
} else {
+ EXCEPTION_CONTEXT;
+ MethodCounters* mcs = method->method_counters();
// m->_instructions_size = rec->instructions_size;
m->_instructions_size = -1;
m->_interpreter_invocation_count = rec->interpreter_invocation_count;
m->_interpreter_throwout_count = rec->interpreter_throwout_count;
- method->invocation_counter()->_counter = rec->invocation_counter;
- method->backedge_counter()->_counter = rec->backedge_counter;
+ if (mcs == NULL) {
+ mcs = Method::build_method_counters(method, CHECK_AND_CLEAR);
+ }
+ mcs->invocation_counter()->_counter = rec->invocation_counter;
+ mcs->backedge_counter()->_counter = rec->backedge_counter;
}
}
diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp
index a14f0ff59..66d7e03ba 100644
--- a/src/share/vm/interpreter/interpreterRuntime.cpp
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -454,7 +454,7 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
continuation = Interpreter::remove_activation_entry();
#endif
// Count this for compilation purposes
- h_method->interpreter_throwout_increment();
+ h_method->interpreter_throwout_increment(THREAD);
} else {
// handler in this method => change bci/bcp to handler bci/bcp and continue there
handler_pc = h_method->code_base() + handler_bci;
@@ -903,6 +903,15 @@ IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int r
fr.interpreter_frame_set_mdp(new_mdp);
IRT_END
+IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
+ MethodCounters* mcs = Method::build_method_counters(m, thread);
+ if (HAS_PENDING_EXCEPTION) {
+ assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
+ CLEAR_PENDING_EXCEPTION;
+ }
+ return mcs;
+IRT_END
+
IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread))
// We used to need an explict preserve_arguments here for invoke bytecodes. However,
diff --git a/src/share/vm/interpreter/interpreterRuntime.hpp b/src/share/vm/interpreter/interpreterRuntime.hpp
index 3aa2c8348..d46c43e94 100644
--- a/src/share/vm/interpreter/interpreterRuntime.hpp
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -169,6 +169,7 @@ class InterpreterRuntime: AllStatic {
#ifdef ASSERT
static void verify_mdp(Method* method, address bcp, address mdp);
#endif // ASSERT
+ static MethodCounters* build_method_counters(JavaThread* thread, Method* m);
};
diff --git a/src/share/vm/interpreter/invocationCounter.cpp b/src/share/vm/interpreter/invocationCounter.cpp
index 747516369..6a113d0ff 100644
--- a/src/share/vm/interpreter/invocationCounter.cpp
+++ b/src/share/vm/interpreter/invocationCounter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -104,15 +104,19 @@ const char* InvocationCounter::state_as_short_string(State state) {
static address do_nothing(methodHandle method, TRAPS) {
// dummy action for inactive invocation counters
- method->invocation_counter()->set_carry();
- method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
+ MethodCounters* mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ mcs->invocation_counter()->set_carry();
+ mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
return NULL;
}
static address do_decay(methodHandle method, TRAPS) {
// decay invocation counters so compilation gets delayed
- method->invocation_counter()->decay();
+ MethodCounters* mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ mcs->invocation_counter()->decay();
return NULL;
}
diff --git a/src/share/vm/oops/method.cpp b/src/share/vm/oops/method.cpp
index 1e74a2148..b06c08178 100644
--- a/src/share/vm/oops/method.cpp
+++ b/src/share/vm/oops/method.cpp
@@ -91,7 +91,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
set_hidden(false);
set_dont_inline(false);
set_method_data(NULL);
- set_interpreter_throwout_count(0);
+ set_method_counters(NULL);
set_vtable_index(Method::garbage_vtable_index);
// Fix and bury in Method*
@@ -105,16 +105,6 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- set_interpreter_invocation_count(0);
- invocation_counter()->init();
- backedge_counter()->init();
- clear_number_of_breakpoints();
-
-#ifdef TIERED
- set_rate(0);
- set_prev_event_count(0);
- set_prev_time(0);
-#endif
}
// Release Method*. The nmethod will be gone when we get here because
@@ -124,6 +114,8 @@ void Method::deallocate_contents(ClassLoaderData* loader_data) {
set_constMethod(NULL);
MetadataFactory::free_metadata(loader_data, method_data());
set_method_data(NULL);
+ MetadataFactory::free_metadata(loader_data, method_counters());
+ set_method_counters(NULL);
// The nmethod will be gone when we get here.
if (code() != NULL) _code = NULL;
}
@@ -323,7 +315,10 @@ bool Method::was_executed_more_than(int n) {
// compiler does not bump invocation counter of compiled methods
return true;
}
- else if (_invocation_counter.carry() || (method_data() != NULL && method_data()->invocation_counter()->carry())) {
+ else if ((method_counters() != NULL &&
+ method_counters()->invocation_counter()->carry()) ||
+ (method_data() != NULL &&
+ method_data()->invocation_counter()->carry())) {
// The carry bit is set when the counter overflows and causes
// a compilation to occur. We don't know how many times
// the counter has been reset, so we simply assume it has
@@ -387,6 +382,18 @@ void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
}
}
+MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
+ methodHandle mh(m);
+ ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
+ MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
+ if (mh->method_counters() == NULL) {
+ mh->set_method_counters(counters);
+ } else {
+ MetadataFactory::free_metadata(loader_data, counters);
+ }
+ return mh->method_counters();
+}
+
void Method::cleanup_inline_caches() {
// The current system doesn't use inline caches in the interpreter
// => nothing to do (keep this method around for future use)
@@ -794,8 +801,6 @@ void Method::unlink_method() {
set_signature_handler(NULL);
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- invocation_counter()->reset();
- backedge_counter()->reset();
_adapter = NULL;
_from_compiled_entry = NULL;
@@ -808,8 +813,7 @@ void Method::unlink_method() {
assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
set_method_data(NULL);
- set_interpreter_throwout_count(0);
- set_interpreter_invocation_count(0);
+ set_method_counters(NULL);
}
// Called when the method_holder is getting linked. Setup entrypoints so the method
@@ -1545,28 +1549,34 @@ void Method::clear_all_breakpoints() {
int Method::invocation_count() {
+ MethodCounters *mcs = method_counters();
if (TieredCompilation) {
MethodData* const mdo = method_data();
- if (invocation_counter()->carry() || ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) {
+ if (((mcs != NULL) ? mcs->invocation_counter()->carry() : false) ||
+ ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) {
return InvocationCounter::count_limit;
} else {
- return invocation_counter()->count() + ((mdo != NULL) ? mdo->invocation_counter()->count() : 0);
+ return ((mcs != NULL) ? mcs->invocation_counter()->count() : 0) +
+ ((mdo != NULL) ? mdo->invocation_counter()->count() : 0);
}
} else {
- return invocation_counter()->count();
+ return (mcs == NULL) ? 0 : mcs->invocation_counter()->count();
}
}
int Method::backedge_count() {
+ MethodCounters *mcs = method_counters();
if (TieredCompilation) {
MethodData* const mdo = method_data();
- if (backedge_counter()->carry() || ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) {
+ if (((mcs != NULL) ? mcs->backedge_counter()->carry() : false) ||
+ ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) {
return InvocationCounter::count_limit;
} else {
- return backedge_counter()->count() + ((mdo != NULL) ? mdo->backedge_counter()->count() : 0);
+ return ((mcs != NULL) ? mcs->backedge_counter()->count() : 0) +
+ ((mdo != NULL) ? mdo->backedge_counter()->count() : 0);
}
} else {
- return backedge_counter()->count();
+ return (mcs == NULL) ? 0 : mcs->backedge_counter()->count();
}
}
@@ -1621,12 +1631,12 @@ void BreakpointInfo::set(Method* method) {
assert(orig_bytecode() == code, "original bytecode must be the same");
}
#endif
+ Thread *thread = Thread::current();
*method->bcp_from(_bci) = Bytecodes::_breakpoint;
- method->incr_number_of_breakpoints();
+ method->incr_number_of_breakpoints(thread);
SystemDictionary::notice_modification();
{
// Deoptimize all dependents on this method
- Thread *thread = Thread::current();
HandleMark hm(thread);
methodHandle mh(thread, method);
Universe::flush_dependents_on_method(mh);
@@ -1636,7 +1646,7 @@ void BreakpointInfo::set(Method* method) {
void BreakpointInfo::clear(Method* method) {
*method->bcp_from(_bci) = orig_bytecode();
assert(method->number_of_breakpoints() > 0, "must not go negative");
- method->decr_number_of_breakpoints();
+ method->decr_number_of_breakpoints(Thread::current());
}
// jmethodID handling
diff --git a/src/share/vm/oops/method.hpp b/src/share/vm/oops/method.hpp
index b9e176f6b..b23a3955e 100644
--- a/src/share/vm/oops/method.hpp
+++ b/src/share/vm/oops/method.hpp
@@ -31,6 +31,7 @@
#include "interpreter/invocationCounter.hpp"
#include "oops/annotations.hpp"
#include "oops/constantPool.hpp"
+#include "oops/methodCounters.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
#include "oops/typeArrayOop.hpp"
@@ -100,6 +101,7 @@ class CheckedExceptionElement;
class LocalVariableTableElement;
class AdapterHandlerEntry;
class MethodData;
+class MethodCounters;
class ConstMethod;
class InlineTableSizes;
class KlassSizeStats;
@@ -109,7 +111,7 @@ class Method : public Metadata {
private:
ConstMethod* _constMethod; // Method read-only data.
MethodData* _method_data;
- int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
+ MethodCounters* _method_counters;
AccessFlags _access_flags; // Access flags
int _vtable_index; // vtable index of this method (see VtableIndexFlag)
// note: can have vtables with >2**16 elements (because of inheritance)
@@ -124,15 +126,6 @@ class Method : public Metadata {
_hidden : 1,
_dont_inline : 1,
: 3;
- u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
- u2 _number_of_breakpoints; // fullspeed debugging support
- InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
- InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
-
-#ifdef TIERED
- float _rate; // Events (invocation and backedge counter increments) per millisecond
- jlong _prev_time; // Previous time the rate was acquired
-#endif
#ifndef PRODUCT
int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging)
@@ -247,11 +240,31 @@ class Method : public Metadata {
void clear_all_breakpoints();
// Tracking number of breakpoints, for fullspeed debugging.
// Only mutated by VM thread.
- u2 number_of_breakpoints() const { return _number_of_breakpoints; }
- void incr_number_of_breakpoints() { ++_number_of_breakpoints; }
- void decr_number_of_breakpoints() { --_number_of_breakpoints; }
+ u2 number_of_breakpoints() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->number_of_breakpoints();
+ }
+ }
+ void incr_number_of_breakpoints(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->incr_number_of_breakpoints();
+ }
+ }
+ void decr_number_of_breakpoints(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->decr_number_of_breakpoints();
+ }
+ }
// Initialization only
- void clear_number_of_breakpoints() { _number_of_breakpoints = 0; }
+ void clear_number_of_breakpoints() {
+ if (method_counters() != NULL) {
+ method_counters()->clear_number_of_breakpoints();
+ }
+ }
// index into InstanceKlass methods() array
// note: also used by jfr
@@ -288,14 +301,20 @@ class Method : public Metadata {
void set_highest_osr_comp_level(int level);
// Count of times method was exited via exception while interpreting
- void interpreter_throwout_increment() {
- if (_interpreter_throwout_count < 65534) {
- _interpreter_throwout_count++;
+ void interpreter_throwout_increment(TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->interpreter_throwout_increment();
}
}
- int interpreter_throwout_count() const { return _interpreter_throwout_count; }
- void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; }
+ int interpreter_throwout_count() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->interpreter_throwout_count();
+ }
+ }
// size of parameters
int size_of_parameters() const { return constMethod()->size_of_parameters(); }
@@ -339,23 +358,54 @@ class Method : public Metadata {
MethodData* method_data() const {
return _method_data;
}
+
void set_method_data(MethodData* data) {
_method_data = data;
}
- // invocation counter
- InvocationCounter* invocation_counter() { return &_invocation_counter; }
- InvocationCounter* backedge_counter() { return &_backedge_counter; }
+ MethodCounters* method_counters() const {
+ return _method_counters;
+ }
+
+
+ void set_method_counters(MethodCounters* counters) {
+ _method_counters = counters;
+ }
#ifdef TIERED
// We are reusing interpreter_invocation_count as a holder for the previous event count!
// We can do that since interpreter_invocation_count is not used in tiered.
- int prev_event_count() const { return _interpreter_invocation_count; }
- void set_prev_event_count(int count) { _interpreter_invocation_count = count; }
- jlong prev_time() const { return _prev_time; }
- void set_prev_time(jlong time) { _prev_time = time; }
- float rate() const { return _rate; }
- void set_rate(float rate) { _rate = rate; }
+ int prev_event_count() const {
+ if (method_counters() == NULL) {
+ return 0;
+ } else {
+ return method_counters()->interpreter_invocation_count();
+ }
+ }
+ void set_prev_event_count(int count, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_interpreter_invocation_count(count);
+ }
+ }
+ jlong prev_time() const {
+ return method_counters() == NULL ? 0 : method_counters()->prev_time();
+ }
+ void set_prev_time(jlong time, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_prev_time(time);
+ }
+ }
+ float rate() const {
+ return method_counters() == NULL ? 0 : method_counters()->rate();
+ }
+ void set_rate(float rate, TRAPS) {
+ MethodCounters* mcs = get_method_counters(CHECK);
+ if (mcs != NULL) {
+ mcs->set_rate(rate);
+ }
+ }
#endif
int invocation_count();
@@ -366,14 +416,17 @@ class Method : public Metadata {
static void build_interpreter_method_data(methodHandle method, TRAPS);
+ static MethodCounters* build_method_counters(Method* m, TRAPS);
+
int interpreter_invocation_count() {
if (TieredCompilation) return invocation_count();
- else return _interpreter_invocation_count;
+ else return (method_counters() == NULL) ? 0 :
+ method_counters()->interpreter_invocation_count();
}
- void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; }
- int increment_interpreter_invocation_count() {
+ int increment_interpreter_invocation_count(TRAPS) {
if (TieredCompilation) ShouldNotReachHere();
- return ++_interpreter_invocation_count;
+ MethodCounters* mcs = get_method_counters(CHECK_0);
+ return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count();
}
#ifndef PRODUCT
@@ -582,12 +635,12 @@ class Method : public Metadata {
#endif /* CC_INTERP */
static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); }
static ByteSize code_offset() { return byte_offset_of(Method, _code); }
- static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); }
- static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); }
static ByteSize method_data_offset() {
return byte_offset_of(Method, _method_data);
}
- static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); }
+ static ByteSize method_counters_offset() {
+ return byte_offset_of(Method, _method_counters);
+ }
#ifndef PRODUCT
static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); }
#endif // not PRODUCT
@@ -598,8 +651,6 @@ class Method : public Metadata {
// for code generation
static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); }
- static int interpreter_invocation_counter_offset_in_bytes()
- { return offset_of(Method, _interpreter_invocation_count); }
static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); }
static int intrinsic_id_size_in_bytes() { return sizeof(u1); }
@@ -757,6 +808,13 @@ class Method : public Metadata {
private:
void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason);
+ MethodCounters* get_method_counters(TRAPS) {
+ if (_method_counters == NULL) {
+ build_method_counters(this, CHECK_AND_CLEAR_NULL);
+ }
+ return _method_counters;
+ }
+
public:
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
diff --git a/src/share/vm/oops/methodCounters.cpp b/src/share/vm/oops/methodCounters.cpp
new file mode 100644
index 000000000..53d3e682b
--- /dev/null
+++ b/src/share/vm/oops/methodCounters.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include "precompiled.hpp"
+#include "oops/methodCounters.hpp"
+#include "runtime/thread.inline.hpp"
+
+MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
+ return new(loader_data, size(), false, THREAD) MethodCounters();
+}
+
+void MethodCounters::clear_counters() {
+ invocation_counter()->reset();
+ backedge_counter()->reset();
+ set_interpreter_throwout_count(0);
+ set_interpreter_invocation_count(0);
+}
diff --git a/src/share/vm/oops/methodCounters.hpp b/src/share/vm/oops/methodCounters.hpp
new file mode 100644
index 000000000..0a6c895b3
--- /dev/null
+++ b/src/share/vm/oops/methodCounters.hpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_METHODCOUNTERS_HPP
+#define SHARE_VM_OOPS_METHODCOUNTERS_HPP
+
+#include "oops/metadata.hpp"
+#include "interpreter/invocationCounter.hpp"
+
+class MethodCounters: public MetaspaceObj {
+ friend class VMStructs;
+ private:
+ int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
+ u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
+ u2 _number_of_breakpoints; // fullspeed debugging support
+ InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
+ InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations
+
+#ifdef TIERED
+ float _rate; // Events (invocation and backedge counter increments) per millisecond
+ jlong _prev_time; // Previous time the rate was acquired
+#endif
+
+ MethodCounters() : _interpreter_invocation_count(0),
+ _interpreter_throwout_count(0),
+ _number_of_breakpoints(0)
+#ifdef TIERED
+ , _rate(0),
+ _prev_time(0)
+#endif
+ {
+ invocation_counter()->init();
+ backedge_counter()->init();
+ }
+
+ public:
+ static MethodCounters* allocate(ClassLoaderData* loader_data, TRAPS);
+
+ void deallocate_contents(ClassLoaderData* loader_data) {}
+ DEBUG_ONLY(bool on_stack() { return false; }) // for template
+
+ static int size() { return sizeof(MethodCounters) / wordSize; }
+
+ bool is_klass() const { return false; }
+
+ void clear_counters();
+
+ int interpreter_invocation_count() {
+ return _interpreter_invocation_count;
+ }
+ void set_interpreter_invocation_count(int count) {
+ _interpreter_invocation_count = count;
+ }
+ int increment_interpreter_invocation_count() {
+ return ++_interpreter_invocation_count;
+ }
+
+ void interpreter_throwout_increment() {
+ if (_interpreter_throwout_count < 65534) {
+ _interpreter_throwout_count++;
+ }
+ }
+ int interpreter_throwout_count() const {
+ return _interpreter_throwout_count;
+ }
+ void set_interpreter_throwout_count(int count) {
+ _interpreter_throwout_count = count;
+ }
+
+ u2 number_of_breakpoints() const { return _number_of_breakpoints; }
+ void incr_number_of_breakpoints() { ++_number_of_breakpoints; }
+ void decr_number_of_breakpoints() { --_number_of_breakpoints; }
+ void clear_number_of_breakpoints() { _number_of_breakpoints = 0; }
+
+#ifdef TIERED
+ jlong prev_time() const { return _prev_time; }
+ void set_prev_time(jlong time) { _prev_time = time; }
+ float rate() const { return _rate; }
+ void set_rate(float rate) { _rate = rate; }
+#endif
+
+ // invocation counter
+ InvocationCounter* invocation_counter() { return &_invocation_counter; }
+ InvocationCounter* backedge_counter() { return &_backedge_counter; }
+
+ static ByteSize interpreter_invocation_counter_offset() {
+ return byte_offset_of(MethodCounters, _interpreter_invocation_count);
+ }
+
+ static ByteSize invocation_counter_offset() {
+ return byte_offset_of(MethodCounters, _invocation_counter);
+ }
+
+ static ByteSize backedge_counter_offset() {
+ return byte_offset_of(MethodCounters, _backedge_counter);
+ }
+
+ static int interpreter_invocation_counter_offset_in_bytes() {
+ return offset_of(MethodCounters, _interpreter_invocation_count);
+ }
+
+};
+#endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP
diff --git a/src/share/vm/oops/methodData.cpp b/src/share/vm/oops/methodData.cpp
index d01775cc8..73f70bac9 100644
--- a/src/share/vm/oops/methodData.cpp
+++ b/src/share/vm/oops/methodData.cpp
@@ -732,14 +732,17 @@ int MethodData::mileage_of(Method* method) {
} else {
int iic = method->interpreter_invocation_count();
if (mileage < iic) mileage = iic;
- InvocationCounter* ic = method->invocation_counter();
- InvocationCounter* bc = method->backedge_counter();
- int icval = ic->count();
- if (ic->carry()) icval += CompileThreshold;
- if (mileage < icval) mileage = icval;
- int bcval = bc->count();
- if (bc->carry()) bcval += CompileThreshold;
- if (mileage < bcval) mileage = bcval;
+ MethodCounters* mcs = method->method_counters();
+ if (mcs != NULL) {
+ InvocationCounter* ic = mcs->invocation_counter();
+ InvocationCounter* bc = mcs->backedge_counter();
+ int icval = ic->count();
+ if (ic->carry()) icval += CompileThreshold;
+ if (mileage < icval) mileage = icval;
+ int bcval = bc->count();
+ if (bc->carry()) bcval += CompileThreshold;
+ if (mileage < bcval) mileage = bcval;
+ }
}
return mileage;
}
diff --git a/src/share/vm/opto/parseHelper.cpp b/src/share/vm/opto/parseHelper.cpp
index f2a1bd2be..e9486088d 100644
--- a/src/share/vm/opto/parseHelper.cpp
+++ b/src/share/vm/opto/parseHelper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -337,19 +337,21 @@ void Parse::increment_and_test_invocation_counter(int limit) {
if (!count_invocations()) return;
// Get the Method* node.
- const TypePtr* adr_type = TypeMetadataPtr::make(method());
- Node *method_node = makecon(adr_type);
+ ciMethod* m = method();
+ address counters_adr = m->ensure_method_counters();
- // Load the interpreter_invocation_counter from the Method*.
- int offset = Method::interpreter_invocation_counter_offset_in_bytes();
- Node* adr_node = basic_plus_adr(method_node, method_node, offset);
- Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
+ Node* ctrl = control();
+ const TypePtr* adr_type = TypeRawPtr::make(counters_adr);
+ Node *counters_node = makecon(adr_type);
+ Node* adr_iic_node = basic_plus_adr(counters_node, counters_node,
+ MethodCounters::interpreter_invocation_counter_offset_in_bytes());
+ Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type);
test_counter_against_threshold(cnt, limit);
// Add one to the counter and store
Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
- store_to_memory( NULL, adr_node, incr, T_INT, adr_type );
+ store_to_memory( ctrl, adr_iic_node, incr, T_INT, adr_type );
}
//----------------------------method_data_addressing---------------------------
diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp
index 1dfcd3d39..153113fd4 100644
--- a/src/share/vm/prims/whitebox.cpp
+++ b/src/share/vm/prims/whitebox.cpp
@@ -278,6 +278,7 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
MutexLockerEx mu(Compile_lock);
MethodData* mdo = mh->method_data();
+ MethodCounters* mcs = mh->method_counters();
if (mdo != NULL) {
mdo->init();
@@ -288,20 +289,22 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
}
}
- mh->backedge_counter()->init();
- mh->invocation_counter()->init();
- mh->set_interpreter_invocation_count(0);
- mh->set_interpreter_throwout_count(0);
mh->clear_not_c1_compilable();
mh->clear_not_c2_compilable();
mh->clear_not_c2_osr_compilable();
NOT_PRODUCT(mh->set_compiled_invocation_count(0));
+ if (mcs != NULL) {
+ mcs->backedge_counter()->init();
+ mcs->invocation_counter()->init();
+ mcs->set_interpreter_invocation_count(0);
+ mcs->set_interpreter_throwout_count(0);
#ifdef TIERED
- mh->set_rate(0.0F);
- mh->set_prev_event_count(0);
- mh->set_prev_time(0);
+ mcs->set_rate(0.0F);
+ mh->set_prev_event_count(0, THREAD);
+ mh->set_prev_time(0, THREAD);
#endif
+ }
WB_END
WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
diff --git a/src/share/vm/runtime/advancedThresholdPolicy.cpp b/src/share/vm/runtime/advancedThresholdPolicy.cpp
index ce5804a60..81c2b7473 100644
--- a/src/share/vm/runtime/advancedThresholdPolicy.cpp
+++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -74,10 +74,11 @@ void AdvancedThresholdPolicy::initialize() {
// update_rate() is called from select_task() while holding a compile queue lock.
void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) {
+ JavaThread* THREAD = JavaThread::current();
if (is_old(m)) {
// We don't remove old methods from the queue,
// so we can just zero the rate.
- m->set_rate(0);
+ m->set_rate(0, THREAD);
return;
}
@@ -93,13 +94,13 @@ void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) {
if (delta_s >= TieredRateUpdateMinTime) {
// And we must've taken the previous point at least 1ms before.
if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
- m->set_prev_time(t);
- m->set_prev_event_count(event_count);
- m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
+ m->set_prev_time(t, THREAD);
+ m->set_prev_event_count(event_count, THREAD);
+ m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond
} else
if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
// If nothing happened for 25ms, zero the rate. Don't modify prev values.
- m->set_rate(0);
+ m->set_rate(0, THREAD);
}
}
}
diff --git a/src/share/vm/runtime/compilationPolicy.cpp b/src/share/vm/runtime/compilationPolicy.cpp
index 71fa794cd..11607385a 100644
--- a/src/share/vm/runtime/compilationPolicy.cpp
+++ b/src/share/vm/runtime/compilationPolicy.cpp
@@ -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
@@ -198,8 +198,10 @@ void NonTieredCompPolicy::reset_counter_for_invocation_event(methodHandle m) {
// 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");
}
@@ -207,8 +209,10 @@ void NonTieredCompPolicy::reset_counter_for_invocation_event(methodHandle m) {
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
@@ -227,7 +231,10 @@ void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
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();
@@ -265,30 +272,44 @@ void NonTieredCompPolicy::do_safepoint_work() {
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();
+ if (mcs != 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) {
@@ -371,8 +392,10 @@ nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, i
#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
diff --git a/src/share/vm/runtime/fprofiler.cpp b/src/share/vm/runtime/fprofiler.cpp
index ce910b45f..111c4db5a 100644
--- a/src/share/vm/runtime/fprofiler.cpp
+++ b/src/share/vm/runtime/fprofiler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -421,7 +421,8 @@ class interpretedNode : public ProfilerNode {
void print_method_on(outputStream* st) {
ProfilerNode::print_method_on(st);
- if (Verbose) method()->invocation_counter()->print_short();
+ MethodCounters* mcs = method()->method_counters();
+ if (Verbose && mcs != NULL) mcs->invocation_counter()->print_short();
}
};
diff --git a/src/share/vm/runtime/simpleThresholdPolicy.cpp b/src/share/vm/runtime/simpleThresholdPolicy.cpp
index fbb0f89c3..0752fac9d 100644
--- a/src/share/vm/runtime/simpleThresholdPolicy.cpp
+++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -153,8 +153,10 @@ void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
// Set carry flags on the counters if necessary
void SimpleThresholdPolicy::handle_counter_overflow(Method* method) {
- set_carry_if_necessary(method->invocation_counter());
- set_carry_if_necessary(method->backedge_counter());
+ MethodCounters *mcs = method->method_counters();
+ assert(mcs != NULL, "");
+ set_carry_if_necessary(mcs->invocation_counter());
+ set_carry_if_necessary(mcs->backedge_counter());
MethodData* mdo = method->method_data();
if (mdo != NULL) {
set_carry_if_necessary(mdo->invocation_counter());
diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp
index b00f6825d..5b5cdfbd1 100644
--- a/src/share/vm/runtime/vmStructs.cpp
+++ b/src/share/vm/runtime/vmStructs.cpp
@@ -77,6 +77,7 @@
#include "oops/klass.hpp"
#include "oops/markOop.hpp"
#include "oops/methodData.hpp"
+#include "oops/methodCounters.hpp"
#include "oops/method.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
@@ -348,16 +349,17 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(MethodData, _arg_local, intx) \
nonstatic_field(MethodData, _arg_stack, intx) \
nonstatic_field(MethodData, _arg_returned, intx) \
- nonstatic_field(Method, _constMethod, ConstMethod*) \
- nonstatic_field(Method, _method_data, MethodData*) \
- nonstatic_field(Method, _interpreter_invocation_count, int) \
+ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \
+ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \
+ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \
+ nonstatic_field(MethodCounters, _invocation_counter, InvocationCounter) \
+ nonstatic_field(MethodCounters, _backedge_counter, InvocationCounter) \
+ nonstatic_field(Method, _constMethod, ConstMethod*) \
+ nonstatic_field(Method, _method_data, MethodData*) \
+ nonstatic_field(Method, _method_counters, MethodCounters*) \
nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _method_size, u2) \
- nonstatic_field(Method, _interpreter_throwout_count, u2) \
- nonstatic_field(Method, _number_of_breakpoints, u2) \
- nonstatic_field(Method, _invocation_counter, InvocationCounter) \
- nonstatic_field(Method, _backedge_counter, InvocationCounter) \
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, nmethod*) \
nonstatic_field(Method, _i2i_entry, address) \
@@ -1382,6 +1384,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_type(ConstantPoolCache, MetaspaceObj) \
declare_type(MethodData, Metadata) \
declare_type(Method, Metadata) \
+ declare_type(MethodCounters, MetaspaceObj) \
declare_type(ConstMethod, MetaspaceObj) \
\
declare_toplevel_type(Symbol) \