United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6370773 previously EMCP methods not marked as obsolete
JDK-6370773 : previously EMCP methods not marked as obsolete

Details
Type:
Bug
Submit Date:
2006-01-10
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2006-01-24
Component:
hotspot
OS:
generic
Sub-Component:
jvmti
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0,6
Fixed Versions:

Related Reports
Backport:
Relates:

Sub Tasks

Description
During the code review process for 6338927, Jim Holmlund
noticed that previously EMCP methods are not marked as
obsolete. During a JVM/TI RedefineClasses() call, all
old methods are considered either obsolete or EMCP. At
that time, obsolete methods are marked as such. A subsequent
RedefineClasses() call can make a method that was previously
EMCP to be obsolete. In that case, we do not mark the EMCP
method as obsolete. I believe this oversight is a day one
bug in the RedefineClasses code.

                                    

Comments
EVALUATION

Need to investigate the existing uses of the "obsolete" attribute
to determine the possible problems that can be caused by an EMCP
method not being marked as obsolete. Also need to investigate the
possible problems introduced by an EMCP method becoming obsolete.

In all likelyhood, we should be able to simply mark the previously
EMCP method as obsolete when its weak reference is removed from
the PreviousVersion info.
                                     
2006-01-10
EVALUATION

Here is an analysis of the different places in which is_obsolete occurs:

src/share/vm/ci/ciEnv.cpp
    ciEnv::is_dependence_violated(klassOop k, methodOop m) returns true
    if method m is obsolete. Looks like the previously EMCP method can
    be compiled.

src/share/vm/compiler/compileBroker.cpp
    CompileBroker::compile_method(methodHandle method, ...) returns
    early if method is obsolete. Looks like the previously EMCP method
    can be compiled.

src/share/vm/interpreter/interpreterRuntime.cpp
    InterpreterRuntime::resolve_invoke() checks to see if
    LinkResolver::resolve_invoke() returns an obsolete method. It it
    does, then the resolve is retried. Looks like the previously EMCP
    method can be resolved.

src/share/vm/oops/cpCacheOop.cpp
    ConstantPoolCacheEntry::set_method() has an assert that an obsolete
    method cannot be store in the cache. Looks like the previously EMCP
    method can be stored in the cache.

src/share/vm/oops/klassVtable.cpp
    The uses of is_obsolete() in this file have been removed by the
    fix for 6338927.

src/share/vm/oops/methodOop.hpp
    This is where is_obsolete() and set_is_obsolete() are defined.

src/share/vm/prims/jniId.cpp
    jniIdCreator::jmid() checks for is_obsolete() and returns a
    different jmid value. Looks like the previously EMCP method
    will return the current jmid instead of the obsolete jmid.

    jniIdCreatorWithNoHandles::jmid_or_null() checks for is_obsolete()
    and returns a different jmid value. Looks like the previously EMCP
    method will return the current jmid instead of the obsolete jmid.

src/share/vm/prims/jvmtiEnv.cpp
    JvmtiEnv::IsMethodObsolete() returns true if is_obsolete() returns
    true. Looks like the previously EMCP method will return false
    instead of true if JVM/TI IsMethodObsolete() is called.

src/share/vm/prims/jvmtiEnvBase.cpp
    JvmtiEnvBase::get_jvmdi_method_and_class() checks for is_obsolete()
    and returns a different jmid value. Looks like the previously EMCP
    method will return the current jmid instead of the obsolete jmid.

src/share/vm/prims/jvmtiImpl.cpp
    JvmtiBreakpoint::each_method_version_do() used to return if a
    method was found to be obsolete. This isn't needed with the fix
    for 6338927 and is now an assert().

src/share/vm/prims/jvmtiRedefineClasses.cpp
    VM_RedefineClasses::check_methods_and_mark_as_obsolete() sets the
    is_obsolete attribute.

src/share/vm/runtime/sharedRuntime.cpp
    SharedRuntime::resolve_helper() checks to see if resolve_sub_helper()
    returns an obsolete method. It it does, then the resolve is
    retried. Looks like the previously EMCP method can be resolved.

    SharedRuntime::resolve_sub_helper() skips patching an obsolete
    method. Looks like the previously EMCP method can be patched.

src/share/vm/utilities/accessFlags.hpp
    The is_obsolete attribute is stored in the accessFlags.


Summary: Looks like it should be safe to mark previously EMCP methods
as obsolete. This is only done at a safepoint so the above checks of
the is_obsolete attribute should see a stable value.
                                     
2006-01-10
SUGGESTED FIX

Please see 6370773-webrev-cr0 for the initial proposed fix.
                                     
2006-01-11



Hardware and Software, Engineered to Work Together