aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/prims
diff options
context:
space:
mode:
authorjrose <none@none>2010-06-02 22:45:42 -0700
committerjrose <none@none>2010-06-02 22:45:42 -0700
commitf5c11173784f3afbc5a741bfa24860f68e2326b0 (patch)
tree8e32b99f1f669fe44fc4f518799c45b1b067e57c /src/share/vm/prims
parentdb3885202d9095c5a296d45d3758e40bad411679 (diff)
parent90aebc75b907b0ddfeb3ef2d0576a47f3afc7656 (diff)
Merge
Diffstat (limited to 'src/share/vm/prims')
-rw-r--r--src/share/vm/prims/jvmtiClassFileReconstituter.cpp4
-rw-r--r--src/share/vm/prims/jvmtiExport.cpp75
-rw-r--r--src/share/vm/prims/jvmtiExport.hpp7
-rw-r--r--src/share/vm/prims/methodComparator.cpp53
-rw-r--r--src/share/vm/prims/methodHandleWalk.cpp10
5 files changed, 85 insertions, 64 deletions
diff --git a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
index b2d69373d..e8ac72d4a 100644
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -638,7 +638,7 @@ void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
// length of bytecode (mnemonic + operands)
address bcp = bs.bcp();
- int len = bs.next_bcp() - bcp;
+ int len = bs.instruction_size();
assert(len > 0, "length must be > 0");
// copy the bytecodes
diff --git a/src/share/vm/prims/jvmtiExport.cpp b/src/share/vm/prims/jvmtiExport.cpp
index 07d4bf01a..a4c2828da 100644
--- a/src/share/vm/prims/jvmtiExport.cpp
+++ b/src/share/vm/prims/jvmtiExport.cpp
@@ -726,6 +726,32 @@ GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_id
GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;
JavaThread* JvmtiExport::_current_poster;
+void JvmtiExport::post_compiled_method_unload_internal(JavaThread* self, jmethodID method, const void *code_begin) {
+ EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+ ("JVMTI [%s] method compile unload event triggered",
+ JvmtiTrace::safe_get_thread_name(self)));
+
+ // post the event for each environment that has this event enabled.
+ JvmtiEnvIterator it;
+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+ if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
+
+ EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+ ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
+ JvmtiTrace::safe_get_thread_name(self), method));
+
+ ResourceMark rm(self);
+
+ JvmtiEventMark jem(self);
+ JvmtiJavaThreadEventTransition jet(self);
+ jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
+ if (callback != NULL) {
+ (*callback)(env->jvmti_external(), method, code_begin);
+ }
+ }
+ }
+}
+
// post any pending CompiledMethodUnload events
void JvmtiExport::post_pending_compiled_method_unload_events() {
@@ -788,26 +814,7 @@ void JvmtiExport::post_pending_compiled_method_unload_events() {
// flag, cleanup _current_poster to indicate that no thread is now servicing the
// pending events list, and finally notify any thread that might be waiting.
for (;;) {
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] method compile unload event triggered",
- JvmtiTrace::safe_get_thread_name(self)));
-
- // post the event for each environment that has this event enabled.
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
- JvmtiTrace::safe_get_thread_name(self), method));
-
- JvmtiEventMark jem(self);
- JvmtiJavaThreadEventTransition jet(self);
- jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), method, code_begin);
- }
- }
- }
+ post_compiled_method_unload_internal(self, method, code_begin);
// event posted, now re-grab monitor and get the next event
// If there's no next event then we are done. If this is the first
@@ -1864,17 +1871,25 @@ void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID metho
}
// used at a safepoint to post a CompiledMethodUnload event
-void JvmtiExport::post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
-
- // create list lazily
- if (_pending_compiled_method_unload_method_ids == NULL) {
- _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
- _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
+void JvmtiExport::post_compiled_method_unload(jmethodID mid, const void *code_begin) {
+ if (SafepointSynchronize::is_at_safepoint()) {
+ // Class unloading can cause nmethod unloading which is reported
+ // by the VMThread. These must be batched to be processed later.
+ if (_pending_compiled_method_unload_method_ids == NULL) {
+ // create list lazily
+ _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
+ _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
+ }
+ _pending_compiled_method_unload_method_ids->append(mid);
+ _pending_compiled_method_unload_code_begins->append(code_begin);
+ _have_pending_compiled_method_unload_events = true;
+ } else {
+ // Unloading caused by the sweeper can be reported synchronously.
+ if (have_pending_compiled_method_unload_events()) {
+ post_pending_compiled_method_unload_events();
+ }
+ post_compiled_method_unload_internal(JavaThread::current(), mid, code_begin);
}
- _pending_compiled_method_unload_method_ids->append(mid);
- _pending_compiled_method_unload_code_begins->append(code_begin);
- _have_pending_compiled_method_unload_events = true;
}
void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
diff --git a/src/share/vm/prims/jvmtiExport.hpp b/src/share/vm/prims/jvmtiExport.hpp
index 31c5571ee..57d1fb530 100644
--- a/src/share/vm/prims/jvmtiExport.hpp
+++ b/src/share/vm/prims/jvmtiExport.hpp
@@ -144,6 +144,9 @@ class JvmtiExport : public AllStatic {
// posts any pending CompiledMethodUnload events.
static void post_pending_compiled_method_unload_events();
+ // Perform the actual notification to interested JvmtiEnvs.
+ static void post_compiled_method_unload_internal(JavaThread* self, jmethodID mid, const void* code_begin);
+
// posts a DynamicCodeGenerated event (internal/private implementation).
// The public post_dynamic_code_generated* functions make use of the
// internal implementation.
@@ -299,8 +302,8 @@ class JvmtiExport : public AllStatic {
static void post_compiled_method_load(nmethod *nm) KERNEL_RETURN;
static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN;
- // used at a safepoint to post a CompiledMethodUnload event
- static void post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) KERNEL_RETURN;
+ // used to post a CompiledMethodUnload event
+ static void post_compiled_method_unload(jmethodID mid, const void *code_begin) KERNEL_RETURN;
// similiar to post_dynamic_code_generated except that it can be used to
// post a DynamicCodeGenerated event while holding locks in the VM. Any event
diff --git a/src/share/vm/prims/methodComparator.cpp b/src/share/vm/prims/methodComparator.cpp
index 4b198f95b..9190d5a83 100644
--- a/src/share/vm/prims/methodComparator.cpp
+++ b/src/share/vm/prims/methodComparator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -130,8 +130,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
case Bytecodes::_multianewarray : // fall through
case Bytecodes::_checkcast : // fall through
case Bytecodes::_instanceof : {
- u2 cpi_old = _s_old->get_index_big();
- u2 cpi_new = _s_new->get_index_big();
+ u2 cpi_old = _s_old->get_index_u2();
+ u2 cpi_new = _s_new->get_index_u2();
if ((_old_cp->klass_at_noresolve(cpi_old) != _new_cp->klass_at_noresolve(cpi_new)))
return false;
if (c_old == Bytecodes::_multianewarray &&
@@ -147,9 +147,10 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
case Bytecodes::_invokevirtual : // fall through
case Bytecodes::_invokespecial : // fall through
case Bytecodes::_invokestatic : // fall through
+ case Bytecodes::_invokedynamic : // fall through
case Bytecodes::_invokeinterface : {
- u2 cpci_old = _s_old->get_index_int();
- u2 cpci_new = _s_new->get_index_int();
+ int cpci_old = _s_old->has_index_u4() ? _s_old->get_index_u4() : _s_old->get_index_u2_cpcache();
+ int cpci_new = _s_new->has_index_u4() ? _s_new->get_index_u4() : _s_new->get_index_u2_cpcache();
// Check if the names of classes, field/method names and signatures at these indexes
// are the same. Indices which are really into constantpool cache (rather than constant
// pool itself) are accepted by the constantpool query routines below.
@@ -162,14 +163,10 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
case Bytecodes::_ldc : // fall through
case Bytecodes::_ldc_w : {
- u2 cpi_old, cpi_new;
- if (c_old == Bytecodes::_ldc) {
- cpi_old = _s_old->bcp()[1];
- cpi_new = _s_new->bcp()[1];
- } else {
- cpi_old = _s_old->get_index_big();
- cpi_new = _s_new->get_index_big();
- }
+ Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method()(), _s_old->bcp());
+ Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method()(), _s_new->bcp());
+ int cpi_old = ldc_old->index();
+ int cpi_new = ldc_new->index();
constantTag tag_old = _old_cp->tag_at(cpi_old);
constantTag tag_new = _new_cp->tag_at(cpi_new);
if (tag_old.is_int() || tag_old.is_float()) {
@@ -179,7 +176,9 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
if (_old_cp->int_at(cpi_old) != _new_cp->int_at(cpi_new))
return false;
} else {
- if (_old_cp->float_at(cpi_old) != _new_cp->float_at(cpi_new))
+ // Use jint_cast to compare the bits rather than numerical values.
+ // This makes a difference for NaN constants.
+ if (jint_cast(_old_cp->float_at(cpi_old)) != jint_cast(_new_cp->float_at(cpi_new)))
return false;
}
} else if (tag_old.is_string() || tag_old.is_unresolved_string()) {
@@ -199,8 +198,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
}
case Bytecodes::_ldc2_w : {
- u2 cpi_old = _s_old->get_index_big();
- u2 cpi_new = _s_new->get_index_big();
+ u2 cpi_old = _s_old->get_index_u2();
+ u2 cpi_new = _s_new->get_index_u2();
constantTag tag_old = _old_cp->tag_at(cpi_old);
constantTag tag_new = _new_cp->tag_at(cpi_new);
if (tag_old.value() != tag_new.value())
@@ -209,7 +208,9 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
if (_old_cp->long_at(cpi_old) != _new_cp->long_at(cpi_new))
return false;
} else {
- if (_old_cp->double_at(cpi_old) != _new_cp->double_at(cpi_new))
+ // Use jlong_cast to compare the bits rather than numerical values.
+ // This makes a difference for NaN constants.
+ if (jlong_cast(_old_cp->double_at(cpi_old)) != jlong_cast(_new_cp->double_at(cpi_new)))
return false;
}
break;
@@ -221,7 +222,7 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
break;
case Bytecodes::_sipush :
- if (_s_old->get_index_big() != _s_new->get_index_big())
+ if (_s_old->get_index_u2() != _s_new->get_index_u2())
return false;
break;
@@ -260,8 +261,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
case Bytecodes::_ifnonnull : // fall through
case Bytecodes::_ifnull : // fall through
case Bytecodes::_jsr : {
- short old_ofs = (short) _s_old->get_index_big();
- short new_ofs = (short) _s_new->get_index_big();
+ int old_ofs = _s_old->bytecode()->get_offset_s2(c_old);
+ int new_ofs = _s_new->bytecode()->get_offset_s2(c_new);
if (_switchable_test) {
int old_dest = _s_old->bci() + old_ofs;
int new_dest = _s_new->bci() + new_ofs;
@@ -285,9 +286,11 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
if (_s_old->is_wide() != _s_new->is_wide())
return false;
if (! _s_old->is_wide()) {
- if (_s_old->get_index_big() != _s_new->get_index_big())
+ // We could use get_index_u1 and get_constant_u1, but it's simpler to grab both bytes at once:
+ if (Bytes::get_Java_u2(_s_old->bcp() + 1) != Bytes::get_Java_u2(_s_new->bcp() + 1))
return false;
} else {
+ // We could use get_index_u2 and get_constant_u2, but it's simpler to grab all four bytes at once:
if (Bytes::get_Java_u4(_s_old->bcp() + 1) != Bytes::get_Java_u4(_s_new->bcp() + 1))
return false;
}
@@ -295,8 +298,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
case Bytecodes::_goto_w : // fall through
case Bytecodes::_jsr_w : {
- int old_ofs = (int) Bytes::get_Java_u4(_s_old->bcp() + 1);
- int new_ofs = (int) Bytes::get_Java_u4(_s_new->bcp() + 1);
+ int old_ofs = _s_old->bytecode()->get_offset_s4(c_old);
+ int new_ofs = _s_new->bytecode()->get_offset_s4(c_new);
if (_switchable_test) {
int old_dest = _s_old->bci() + old_ofs;
int new_dest = _s_new->bci() + new_ofs;
@@ -357,8 +360,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
}
}
} else { // !_switchable_test, can use fast rough compare
- int len_old = _s_old->next_bcp() - _s_old->bcp();
- int len_new = _s_new->next_bcp() - _s_new->bcp();
+ int len_old = _s_old->instruction_size();
+ int len_new = _s_new->instruction_size();
if (len_old != len_new)
return false;
if (memcmp(_s_old->bcp(), _s_new->bcp(), len_old) != 0)
diff --git a/src/share/vm/prims/methodHandleWalk.cpp b/src/share/vm/prims/methodHandleWalk.cpp
index d4f9ab3b0..f41f63a16 100644
--- a/src/share/vm/prims/methodHandleWalk.cpp
+++ b/src/share/vm/prims/methodHandleWalk.cpp
@@ -732,7 +732,7 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case Bytecodes::_dreturn:
case Bytecodes::_areturn:
case Bytecodes::_return:
- assert(strcmp(Bytecodes::format(op), "b") == 0, "wrong bytecode format");
+ assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_b, "wrong bytecode format");
_bytecode.push(op);
break;
@@ -748,7 +748,7 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
case Bytecodes::_fstore:
case Bytecodes::_dstore:
case Bytecodes::_astore:
- assert(strcmp(Bytecodes::format(op), "bi") == 0, "wrong bytecode format");
+ assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bi, "wrong bytecode format");
assert((char) index == index, "index does not fit in 8-bit");
_bytecode.push(op);
_bytecode.push(index);
@@ -757,18 +757,18 @@ void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index) {
// bii
case Bytecodes::_ldc2_w:
case Bytecodes::_checkcast:
- assert(strcmp(Bytecodes::format(op), "bii") == 0, "wrong bytecode format");
+ assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bkk, "wrong bytecode format");
assert((short) index == index, "index does not fit in 16-bit");
_bytecode.push(op);
_bytecode.push(index >> 8);
_bytecode.push(index);
break;
- // bjj
+ // bJJ
case Bytecodes::_invokestatic:
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
- assert(strcmp(Bytecodes::format(op), "bjj") == 0, "wrong bytecode format");
+ assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format");
assert((short) index == index, "index does not fit in 16-bit");
_bytecode.push(op);
_bytecode.push(index >> 8);