--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri May 08 23:00:08 2009 -0700
@@ -378,7 +378,7 @@
compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
- if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
+ if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
__ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
__ delayed()->nop();
}
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri May 08 23:00:08 2009 -0700
@@ -286,7 +286,7 @@
initialize_body(base, index);
}
- if (DTraceAllocProbes) {
+ if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == O0, "must be");
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
relocInfo::runtime_call_type);
@@ -355,7 +355,7 @@
sub(arr_size, hdr_size * wordSize, index); // compute index = number of words to clear
initialize_body(base, index);
- if (DTraceAllocProbes) {
+ if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == O0, "must be");
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
relocInfo::runtime_call_type);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri May 08 23:00:08 2009 -0700
@@ -439,7 +439,7 @@
// if the method does not have an exception handler, then there is
// no reason to search for one
- if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
+ if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
// the exception oop and pc are in rax, and rdx
// no other registers need to be preserved, so invalidate them
__ invalidate_registers(false, true, true, false, true, true);
--- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri May 08 23:00:08 2009 -0700
@@ -258,7 +258,7 @@
}
}
- if (DTraceAllocProbes) {
+ if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == rax, "must be");
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}
@@ -291,7 +291,7 @@
const Register len_zero = len;
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
- if (DTraceAllocProbes) {
+ if (CURRENT_ENV->dtrace_alloc_probes()) {
assert(obj == rax, "must be");
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
}
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Fri May 08 23:00:08 2009 -0700
@@ -319,7 +319,7 @@
return;
}
- if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
+ if (_env->jvmti_can_hotswap_or_post_breakpoint()) {
// We can assert evol_method because method->can_be_compiled is true.
dependency_recorder()->assert_evol_method(method());
}
@@ -435,7 +435,7 @@
assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time");
_arena = Thread::current()->resource_area();
_compilation = this;
- _needs_debug_information = JvmtiExport::can_examine_or_deopt_anywhere() ||
+ _needs_debug_information = _env->jvmti_can_examine_or_deopt_anywhere() ||
JavaMonitorsInStackTrace || AlwaysEmitDebugInfo || DeoptimizeALot;
_exception_info_list = new ExceptionInfoList();
_implicit_exception_table.set_size(0);
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 08 23:00:08 2009 -0700
@@ -1662,7 +1662,7 @@
// Register dependence if JVMTI has either breakpoint
// setting or hotswapping of methods capabilities since they may
// cause deoptimization.
- if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
+ if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
dependency_recorder()->assert_evol_method(inline_target);
}
return;
@@ -2863,7 +2863,7 @@
start_block->merge(_initial_state);
BlockBegin* sync_handler = NULL;
- if (method()->is_synchronized() || DTraceMethodProbes) {
+ if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) {
// setup an exception handler to do the unlocking and/or notification
sync_handler = new BlockBegin(-1);
sync_handler->set(BlockBegin::exception_entry_flag);
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri May 08 23:00:08 2009 -0700
@@ -1064,7 +1064,7 @@
void LIRGenerator::do_Return(Return* x) {
- if (DTraceMethodProbes) {
+ if (compilation()->env()->dtrace_method_probes()) {
BasicTypeList signature;
signature.append(T_INT); // thread
signature.append(T_OBJECT); // methodOop
@@ -1769,7 +1769,7 @@
__ null_check(exception_opr, new CodeEmitInfo(info, true));
}
- if (JvmtiExport::can_post_exceptions() &&
+ if (compilation()->env()->jvmti_can_post_exceptions() &&
!block()->is_set(BlockBegin::default_exception_handler_flag)) {
// we need to go through the exception lookup path to get JVMTI
// notification done
@@ -1779,7 +1779,7 @@
assert(!block()->is_set(BlockBegin::default_exception_handler_flag) || unwind,
"should be no more handlers to dispatch to");
- if (DTraceMethodProbes &&
+ if (compilation()->env()->dtrace_method_probes() &&
block()->is_set(BlockBegin::default_exception_handler_flag)) {
// notify that this frame is unwinding
BasicTypeList signature;
@@ -2204,7 +2204,7 @@
java_index += type2size[t];
}
- if (DTraceMethodProbes) {
+ if (compilation()->env()->dtrace_method_probes()) {
BasicTypeList signature;
signature.append(T_INT); // thread
signature.append(T_OBJECT); // methodOop
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri May 08 23:00:08 2009 -0700
@@ -171,6 +171,34 @@
}
// ------------------------------------------------------------------
+// Cache Jvmti state
+void ciEnv::cache_jvmti_state() {
+ VM_ENTRY_MARK;
+ // Get Jvmti capabilities under lock to get consistant values.
+ MutexLocker mu(JvmtiThreadState_lock);
+ _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
+ _jvmti_can_examine_or_deopt_anywhere = JvmtiExport::can_examine_or_deopt_anywhere();
+ _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
+ _jvmti_can_post_exceptions = JvmtiExport::can_post_exceptions();
+}
+
+// ------------------------------------------------------------------
+// Cache DTrace flags
+void ciEnv::cache_dtrace_flags() {
+ // Need lock?
+ _dtrace_extended_probes = ExtendedDTraceProbes;
+ if (_dtrace_extended_probes) {
+ _dtrace_monitor_probes = true;
+ _dtrace_method_probes = true;
+ _dtrace_alloc_probes = true;
+ } else {
+ _dtrace_monitor_probes = DTraceMonitorProbes;
+ _dtrace_method_probes = DTraceMethodProbes;
+ _dtrace_alloc_probes = DTraceAllocProbes;
+ }
+}
+
+// ------------------------------------------------------------------
// helper for lazy exception creation
ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) {
VM_ENTRY_MARK;
@@ -810,16 +838,39 @@
// and invalidating our dependencies until we install this method.
MutexLocker ml(Compile_lock);
- if (log() != NULL) {
- // Log the dependencies which this compilation declares.
- dependencies()->log_all_dependencies();
+ // Change in Jvmti state may invalidate compilation.
+ if (!failing() &&
+ ( (!jvmti_can_hotswap_or_post_breakpoint() &&
+ JvmtiExport::can_hotswap_or_post_breakpoint()) ||
+ (!jvmti_can_examine_or_deopt_anywhere() &&
+ JvmtiExport::can_examine_or_deopt_anywhere()) ||
+ (!jvmti_can_access_local_variables() &&
+ JvmtiExport::can_access_local_variables()) ||
+ (!jvmti_can_post_exceptions() &&
+ JvmtiExport::can_post_exceptions()) )) {
+ record_failure("Jvmti state change invalidated dependencies");
}
- // Encode the dependencies now, so we can check them right away.
- dependencies()->encode_content_bytes();
+ // Change in DTrace flags may invalidate compilation.
+ if (!failing() &&
+ ( (!dtrace_extended_probes() && ExtendedDTraceProbes) ||
+ (!dtrace_method_probes() && DTraceMethodProbes) ||
+ (!dtrace_alloc_probes() && DTraceAllocProbes) )) {
+ record_failure("DTrace flags change invalidated dependencies");
+ }
- // Check for {class loads, evolution, breakpoints} during compilation
- check_for_system_dictionary_modification(target);
+ if (!failing()) {
+ if (log() != NULL) {
+ // Log the dependencies which this compilation declares.
+ dependencies()->log_all_dependencies();
+ }
+
+ // Encode the dependencies now, so we can check them right away.
+ dependencies()->encode_content_bytes();
+
+ // Check for {class loads, evolution, breakpoints} during compilation
+ check_for_system_dictionary_modification(target);
+ }
methodHandle method(THREAD, target->get_methodOop());
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Fri May 08 23:00:08 2009 -0700
@@ -53,6 +53,18 @@
char* _name_buffer;
int _name_buffer_len;
+ // Cache Jvmti state
+ bool _jvmti_can_hotswap_or_post_breakpoint;
+ bool _jvmti_can_examine_or_deopt_anywhere;
+ bool _jvmti_can_access_local_variables;
+ bool _jvmti_can_post_exceptions;
+
+ // Cache DTrace flags
+ bool _dtrace_extended_probes;
+ bool _dtrace_monitor_probes;
+ bool _dtrace_method_probes;
+ bool _dtrace_alloc_probes;
+
// Distinguished instances of certain ciObjects..
static ciObject* _null_object_instance;
static ciMethodKlass* _method_klass_instance;
@@ -236,6 +248,20 @@
bool break_at_compile() { return _break_at_compile; }
void set_break_at_compile(bool z) { _break_at_compile = z; }
+ // Cache Jvmti state
+ void cache_jvmti_state();
+ bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; }
+ bool jvmti_can_examine_or_deopt_anywhere() const { return _jvmti_can_examine_or_deopt_anywhere; }
+ bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; }
+ bool jvmti_can_post_exceptions() const { return _jvmti_can_post_exceptions; }
+
+ // Cache DTrace flags
+ void cache_dtrace_flags();
+ bool dtrace_extended_probes() const { return _dtrace_extended_probes; }
+ bool dtrace_monitor_probes() const { return _dtrace_monitor_probes; }
+ bool dtrace_method_probes() const { return _dtrace_method_probes; }
+ bool dtrace_alloc_probes() const { return _dtrace_alloc_probes; }
+
// The compiler task which has created this env.
// May be useful to find out compile_id, comp_level, etc.
CompileTask* task() { return _task; }
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri May 08 23:00:08 2009 -0700
@@ -60,7 +60,8 @@
_flow = NULL;
#endif // COMPILER2
- if (JvmtiExport::can_hotswap_or_post_breakpoint() && _is_compilable) {
+ ciEnv *env = CURRENT_ENV;
+ if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
// 6328518 check hotswap conditions under the right lock.
MutexLocker locker(Compile_lock);
if (Dependencies::check_evol_method(h_m()) != NULL) {
@@ -84,7 +85,6 @@
if (_can_be_statically_bound && h_m()->is_abstract())
_can_be_statically_bound = false;
- ciEnv *env = CURRENT_ENV;
// generating _signature may allow GC and therefore move m.
// These fields are always filled in.
_name = env->get_object(h_m()->name())->as_symbol();
@@ -337,7 +337,7 @@
_liveness->compute_liveness();
}
MethodLivenessResult result = _liveness->get_liveness_at(bci);
- if (JvmtiExport::can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
+ if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
// Keep all locals live for the user's edification and amusement.
result.at_put_range(0, result.size(), true);
}
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri May 08 23:00:08 2009 -0700
@@ -1530,6 +1530,12 @@
assert(thread->env() == &ci_env, "set by ci_env");
// The thread-env() field is cleared in ~CompileTaskWrapper.
+ // Cache Jvmti state
+ ci_env.cache_jvmti_state();
+
+ // Cache DTrace flags
+ ci_env.cache_dtrace_flags();
+
ciMethod* target = ci_env.get_method_from_handle(target_handle);
TraceTime t1("compilation", &time);
--- a/hotspot/src/share/vm/opto/doCall.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp Fri May 08 23:00:08 2009 -0700
@@ -47,7 +47,7 @@
CallGenerator* cg;
// Dtrace currently doesn't work unless all calls are vanilla
- if (DTraceMethodProbes) {
+ if (env()->dtrace_method_probes()) {
allow_inline = false;
}
--- a/hotspot/src/share/vm/opto/graphKit.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Fri May 08 23:00:08 2009 -0700
@@ -459,7 +459,7 @@
void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) {
bool must_throw = true;
- if (JvmtiExport::can_post_exceptions()) {
+ if (env()->jvmti_can_post_exceptions()) {
// Do not try anything fancy if we're notifying the VM on every throw.
// Cf. case Bytecodes::_athrow in parse2.cpp.
uncommon_trap(reason, Deoptimization::Action_none,
@@ -769,7 +769,7 @@
}
}
- if (JvmtiExport::can_examine_or_deopt_anywhere()) {
+ if (env()->jvmti_can_examine_or_deopt_anywhere()) {
// At any safepoint, this method can get breakpointed, which would
// then require an immediate deoptimization.
full_info = true;
--- a/hotspot/src/share/vm/opto/macro.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Fri May 08 23:00:08 2009 -0700
@@ -988,7 +988,7 @@
initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn);
}
- if (DTraceAllocProbes ||
+ if (C->env()->dtrace_alloc_probes() ||
!UseTLAB && (!Universe::heap()->supports_inline_contig_alloc() ||
(UseConcMarkSweepGC && CMSIncrementalMode))) {
// Force slow-path allocation
@@ -1150,7 +1150,7 @@
fast_oop_ctrl, fast_oop_rawmem, fast_oop,
klass_node, length, size_in_bytes);
- if (ExtendedDTraceProbes) {
+ if (C->env()->dtrace_extended_probes()) {
// Slow-path call
int size = TypeFunc::Parms + 2;
CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(),
--- a/hotspot/src/share/vm/opto/parse1.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/opto/parse1.cpp Fri May 08 23:00:08 2009 -0700
@@ -439,7 +439,7 @@
// Always register dependence if JVMTI is enabled, because
// either breakpoint setting or hotswapping of methods may
// cause deoptimization.
- if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
+ if (C->env()->jvmti_can_hotswap_or_post_breakpoint()) {
C->dependencies()->assert_evol_method(method());
}
@@ -953,7 +953,7 @@
bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode;
// record exit from a method if compiled while Dtrace is turned on.
- if (do_synch || DTraceMethodProbes) {
+ if (do_synch || C->env()->dtrace_method_probes()) {
// First move the exception list out of _exits:
GraphKit kit(_exits.transfer_exceptions_into_jvms());
SafePointNode* normal_map = kit.map(); // keep this guy safe
@@ -975,7 +975,7 @@
// Unlock!
kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
}
- if (DTraceMethodProbes) {
+ if (C->env()->dtrace_method_probes()) {
kit.make_dtrace_method_exit(method());
}
// Done with exception-path processing.
@@ -1074,7 +1074,7 @@
NOT_PRODUCT( count_compiled_calls(true/*at_method_entry*/, false/*is_inline*/); )
- if (DTraceMethodProbes) {
+ if (C->env()->dtrace_method_probes()) {
make_dtrace_method_entry(method());
}
@@ -1960,7 +1960,7 @@
if (method()->is_synchronized() && GenerateSynchronizationCode) {
shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
}
- if (DTraceMethodProbes) {
+ if (C->env()->dtrace_method_probes()) {
make_dtrace_method_exit(method());
}
SafePointNode* exit_return = _exits.map();
--- a/hotspot/src/share/vm/opto/parse2.cpp Fri May 08 15:16:38 2009 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp Fri May 08 23:00:08 2009 -0700
@@ -2052,7 +2052,7 @@
// null exception oop throws NULL pointer exception
do_null_check(peek(), T_OBJECT);
if (stopped()) return;
- if (JvmtiExport::can_post_exceptions()) {
+ if (env()->jvmti_can_post_exceptions()) {
// "Full-speed throwing" is not necessary here,
// since we're notifying the VM on every throw.
uncommon_trap(Deoptimization::Reason_unhandled,