Merge

Mon, 19 Mar 2018 13:23:53 -0700

author
asaha
date
Mon, 19 Mar 2018 13:23:53 -0700
changeset 9382
12204b54d3dc
parent 9119
14a3e78ec5cf
parent 9381
700ad8745f3f
child 9383
c8ac3eba6d80
child 9385
0cfb7a4780b9

Merge

.hgtags file | annotate | diff | comparison | revisions
src/share/vm/oops/klass.cpp file | annotate | diff | comparison | revisions
test/runtime/RedefineFinalizer/RedefineFinalizer.java file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Mon Mar 19 12:12:48 2018 -0700
     1.2 +++ b/.hgtags	Mon Mar 19 13:23:53 2018 -0700
     1.3 @@ -1131,6 +1131,11 @@
     1.4  39e2895b795aded8b584626fb019d35f12e9d1e7 jdk8u162-b11
     1.5  69aec2ca5d905dde1d0f29a89076d02a531808a3 jdk8u162-b12
     1.6  caac74fe3cfa9a8c859c28c97d1046a58252af27 jdk8u162-b31
     1.7 +c9b7abadf150328d2187de05b9e8a9cba2486e47 jdk8u162-b32
     1.8 +e8041f2ec96eb6a41307732e6cf6ed90901438ae jdk8u162-b33
     1.9 +bf2e8b1e8e8e6bc1f9b9475de54ba0329a6b24b1 jdk8u162-b34
    1.10 +9b3f207379cf6ecfb8603640269e31ff4e064294 jdk8u162-b35
    1.11 +d2ebd6530396b0afc700cd1a8eaf1f7a7f9fce8d jdk8u162-b36
    1.12  a17bab9405474602b18cd62e060a09b17d6413ac jdk8u171-b00
    1.13  ebfd57cc21e6b7f0c22b17c666b6b28c9340e207 jdk8u171-b01
    1.14  1acd7c1b80241def8fac90f70b0df16356adad47 jdk8u171-b02
     2.1 --- a/agent/src/os/linux/Makefile	Mon Mar 19 12:12:48 2018 -0700
     2.2 +++ b/agent/src/os/linux/Makefile	Mon Mar 19 13:23:53 2018 -0700
     2.3 @@ -1,5 +1,5 @@
     2.4  #
     2.5 -# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
     2.6 +# Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
     2.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8  #
     2.9  # This code is free software; you can redistribute it and/or modify it
    2.10 @@ -76,6 +76,9 @@
    2.11  endif
    2.12  LFLAGS_LIBSA += $(LDFLAGS_HASH_STYLE)
    2.13  
    2.14 +LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
    2.15 +LFLAGS_LIBSA += $(LDFLAGS_NO_EXEC_STACK)
    2.16 +
    2.17  $(LIBSA): $(ARCH) $(OBJS) mapfile
    2.18          $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
    2.19  
     3.1 --- a/make/linux/makefiles/gcc.make	Mon Mar 19 12:12:48 2018 -0700
     3.2 +++ b/make/linux/makefiles/gcc.make	Mon Mar 19 13:23:53 2018 -0700
     3.3 @@ -1,5 +1,5 @@
     3.4  #
     3.5 -# Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     3.6 +# Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
     3.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8  #
     3.9  # This code is free software; you can redistribute it and/or modify it
    3.10 @@ -303,6 +303,8 @@
    3.11  
    3.12  LFLAGS += $(LDFLAGS_HASH_STYLE)
    3.13  
    3.14 +LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
    3.15 +
    3.16  # Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
    3.17  MAPFLAG = -Xlinker --version-script=FILENAME
    3.18  
     4.1 --- a/make/linux/makefiles/jsig.make	Mon Mar 19 12:12:48 2018 -0700
     4.2 +++ b/make/linux/makefiles/jsig.make	Mon Mar 19 13:23:53 2018 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4  #
     4.5 -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 +# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
     4.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8  #
     4.9  # This code is free software; you can redistribute it and/or modify it
    4.10 @@ -44,7 +44,7 @@
    4.11  # cause problems with interposing. See CR: 6466665
    4.12  # LFLAGS_JSIG += $(MAPFLAG:FILENAME=$(LIBJSIG_MAPFILE))
    4.13  
    4.14 -LFLAGS_JSIG += -D_GNU_SOURCE -D_REENTRANT $(LDFLAGS_HASH_STYLE)
    4.15 +LFLAGS_JSIG += -D_GNU_SOURCE -D_REENTRANT $(LDFLAGS_HASH_STYLE) $(LDFLAGS_NO_EXEC_STACK)
    4.16  
    4.17  # DEBUG_BINARIES overrides everything, use full -g debug information
    4.18  ifeq ($(DEBUG_BINARIES), true)
     5.1 --- a/src/share/vm/classfile/metadataOnStackMark.cpp	Mon Mar 19 12:12:48 2018 -0700
     5.2 +++ b/src/share/vm/classfile/metadataOnStackMark.cpp	Mon Mar 19 13:23:53 2018 -0700
     5.3 @@ -41,13 +41,13 @@
     5.4  // Walk metadata on the stack and mark it so that redefinition doesn't delete
     5.5  // it.  Class unloading also walks the previous versions and might try to
     5.6  // delete it, so this class is used by class unloading also.
     5.7 -MetadataOnStackMark::MetadataOnStackMark(bool visit_code_cache) {
     5.8 +MetadataOnStackMark::MetadataOnStackMark(bool has_redefined_a_class) {
     5.9    assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
    5.10    assert(_used_buffers == NULL, "sanity check");
    5.11    NOT_PRODUCT(_is_active = true;)
    5.12  
    5.13    Threads::metadata_do(Metadata::mark_on_stack);
    5.14 -  if (visit_code_cache) {
    5.15 +  if (has_redefined_a_class) {
    5.16      CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
    5.17    }
    5.18    CompileBroker::mark_on_stack();
     6.1 --- a/src/share/vm/classfile/metadataOnStackMark.hpp	Mon Mar 19 12:12:48 2018 -0700
     6.2 +++ b/src/share/vm/classfile/metadataOnStackMark.hpp	Mon Mar 19 13:23:53 2018 -0700
     6.3 @@ -47,7 +47,7 @@
     6.4    static void retire_buffer(MetadataOnStackBuffer* buffer);
     6.5  
     6.6   public:
     6.7 -  MetadataOnStackMark(bool visit_code_cache);
     6.8 +  MetadataOnStackMark(bool has_redefined_a_class);
     6.9     ~MetadataOnStackMark();
    6.10  
    6.11    static void record(Metadata* m, Thread* thread);
     7.1 --- a/src/share/vm/code/nmethod.cpp	Mon Mar 19 12:12:48 2018 -0700
     7.2 +++ b/src/share/vm/code/nmethod.cpp	Mon Mar 19 13:23:53 2018 -0700
     7.3 @@ -2172,7 +2172,7 @@
     7.4                 "metadata must be found in exactly one place");
     7.5          if (r->metadata_is_immediate() && r->metadata_value() != NULL) {
     7.6            Metadata* md = r->metadata_value();
     7.7 -          f(md);
     7.8 +          if (md != _method) f(md);
     7.9          }
    7.10        } else if (iter.type() == relocInfo::virtual_call_type) {
    7.11          // Check compiledIC holders associated with this nmethod
    7.12 @@ -2198,7 +2198,7 @@
    7.13      f(md);
    7.14    }
    7.15  
    7.16 -  // Visit metadata not embedded in the other places.
    7.17 +  // Call function Method*, not embedded in these other places.
    7.18    if (_method != NULL) f(_method);
    7.19  }
    7.20  
     8.1 --- a/src/share/vm/oops/instanceKlass.cpp	Mon Mar 19 12:12:48 2018 -0700
     8.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Mon Mar 19 13:23:53 2018 -0700
     8.3 @@ -2582,16 +2582,6 @@
     8.4      assert(breakpoints() == 0x0, "should have cleared breakpoints");
     8.5    }
     8.6  
     8.7 -  // deallocate information about previous versions
     8.8 -  if (_previous_versions != NULL) {
     8.9 -    for (int i = _previous_versions->length() - 1; i >= 0; i--) {
    8.10 -      PreviousVersionNode * pv_node = _previous_versions->at(i);
    8.11 -      delete pv_node;
    8.12 -    }
    8.13 -    delete _previous_versions;
    8.14 -    _previous_versions = NULL;
    8.15 -  }
    8.16 -
    8.17    // deallocate the cached class file
    8.18    if (_cached_class_file != NULL) {
    8.19      os::free(_cached_class_file, mtClass);
    8.20 @@ -3187,16 +3177,17 @@
    8.21    st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
    8.22    {
    8.23      bool have_pv = false;
    8.24 -    PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
    8.25 -    for (PreviousVersionNode * pv_node = pvw.next_previous_version();
    8.26 -         pv_node != NULL; pv_node = pvw.next_previous_version()) {
    8.27 +    // previous versions are linked together through the InstanceKlass
    8.28 +    for (InstanceKlass* pv_node = _previous_versions;
    8.29 +         pv_node != NULL;
    8.30 +         pv_node = pv_node->previous_versions()) {
    8.31        if (!have_pv)
    8.32          st->print(BULLET"previous version:  ");
    8.33        have_pv = true;
    8.34 -      pv_node->prev_constant_pool()->print_value_on(st);
    8.35 +      pv_node->constants()->print_value_on(st);
    8.36      }
    8.37      if (have_pv) st->cr();
    8.38 -  } // pvw is cleaned up
    8.39 +  }
    8.40  
    8.41    if (generic_signature() != NULL) {
    8.42      st->print(BULLET"generic signature: ");
    8.43 @@ -3610,205 +3601,126 @@
    8.44  // RedefineClasses() support for previous versions:
    8.45  
    8.46  // Purge previous versions
    8.47 -static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_count) {
    8.48 +void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
    8.49    if (ik->previous_versions() != NULL) {
    8.50      // This klass has previous versions so see what we can cleanup
    8.51      // while it is safe to do so.
    8.52  
    8.53      int deleted_count = 0;    // leave debugging breadcrumbs
    8.54      int live_count = 0;
    8.55 -    ClassLoaderData* loader_data = ik->class_loader_data() == NULL ?
    8.56 -                       ClassLoaderData::the_null_class_loader_data() :
    8.57 -                       ik->class_loader_data();
    8.58 +    ClassLoaderData* loader_data = ik->class_loader_data();
    8.59 +    assert(loader_data != NULL, "should never be null");
    8.60  
    8.61      // RC_TRACE macro has an embedded ResourceMark
    8.62 -    RC_TRACE(0x00000200, ("purge: %s: previous version length=%d",
    8.63 -      ik->external_name(), ik->previous_versions()->length()));
    8.64 -
    8.65 -    for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
    8.66 -      // check the previous versions array
    8.67 -      PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
    8.68 -      ConstantPool* cp_ref = pv_node->prev_constant_pool();
    8.69 -      assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
    8.70 -
    8.71 -      ConstantPool* pvcp = cp_ref;
    8.72 +    RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));
    8.73 +
    8.74 +    // previous versions are linked together through the InstanceKlass
    8.75 +    InstanceKlass* pv_node = ik->previous_versions();
    8.76 +    InstanceKlass* last = ik;
    8.77 +    int version = 0;
    8.78 +
    8.79 +    // check the previous versions list
    8.80 +    for (; pv_node != NULL; ) {
    8.81 +
    8.82 +      ConstantPool* pvcp = pv_node->constants();
    8.83 +      assert(pvcp != NULL, "cp ref was unexpectedly cleared");
    8.84 +
    8.85 +
    8.86        if (!pvcp->on_stack()) {
    8.87          // If the constant pool isn't on stack, none of the methods
    8.88 -        // are executing.  Delete all the methods, the constant pool and
    8.89 -        // and this previous version node.
    8.90 -        GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
    8.91 -        if (method_refs != NULL) {
    8.92 -          for (int j = method_refs->length() - 1; j >= 0; j--) {
    8.93 -            Method* method = method_refs->at(j);
    8.94 -            assert(method != NULL, "method ref was unexpectedly cleared");
    8.95 -            method_refs->remove_at(j);
    8.96 -            // method will be freed with associated class.
    8.97 -          }
    8.98 -        }
    8.99 -        // Remove the constant pool
   8.100 -        delete pv_node;
   8.101 -        // Since we are traversing the array backwards, we don't have to
   8.102 -        // do anything special with the index.
   8.103 -        ik->previous_versions()->remove_at(i);
   8.104 +        // are executing.  Unlink this previous_version.
   8.105 +        // The previous version InstanceKlass is on the ClassLoaderData deallocate list
   8.106 +        // so will be deallocated during the next phase of class unloading.
   8.107 +        pv_node = pv_node->previous_versions();
   8.108 +        last->link_previous_versions(pv_node);
   8.109          deleted_count++;
   8.110 +        version++;
   8.111          continue;
   8.112        } else {
   8.113 -        RC_TRACE(0x00000200, ("purge: previous version @%d is alive", i));
   8.114 +        RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive",
   8.115 +                              pv_node));
   8.116          assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
   8.117          guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
   8.118          live_count++;
   8.119        }
   8.120  
   8.121 -      // At least one method is live in this previous version, clean out
   8.122 -      // the others or mark them as obsolete.
   8.123 -      GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
   8.124 +      // At least one method is live in this previous version so clean its MethodData.
   8.125 +      // Reset dead EMCP methods not to get breakpoints.
   8.126 +      // All methods are deallocated when all of the methods for this class are no
   8.127 +      // longer running.
   8.128 +      Array<Method*>* method_refs = pv_node->methods();
   8.129        if (method_refs != NULL) {
   8.130          RC_TRACE(0x00000200, ("purge: previous methods length=%d",
   8.131            method_refs->length()));
   8.132 -        for (int j = method_refs->length() - 1; j >= 0; j--) {
   8.133 +        for (int j = 0; j < method_refs->length(); j++) {
   8.134            Method* method = method_refs->at(j);
   8.135 -          assert(method != NULL, "method ref was unexpectedly cleared");
   8.136 -
   8.137 -          // Remove the emcp method if it's not executing
   8.138 -          // If it's been made obsolete by a redefinition of a non-emcp
   8.139 -          // method, mark it as obsolete but leave it to clean up later.
   8.140 +
   8.141            if (!method->on_stack()) {
   8.142 -            method_refs->remove_at(j);
   8.143 -          } else if (emcp_method_count == 0) {
   8.144 -            method->set_is_obsolete();
   8.145 +            // no breakpoints for non-running methods
   8.146 +            if (method->is_running_emcp()) {
   8.147 +              method->set_running_emcp(false);
   8.148 +            }
   8.149            } else {
   8.150 +            assert (method->is_obsolete() || method->is_running_emcp(),
   8.151 +                    "emcp method cannot run after emcp bit is cleared");
   8.152              // RC_TRACE macro has an embedded ResourceMark
   8.153              RC_TRACE(0x00000200,
   8.154                ("purge: %s(%s): prev method @%d in version @%d is alive",
   8.155                method->name()->as_C_string(),
   8.156 -              method->signature()->as_C_string(), j, i));
   8.157 +              method->signature()->as_C_string(), j, version));
   8.158 +            if (method->method_data() != NULL) {
   8.159 +              // Clean out any weak method links for running methods
   8.160 +              // (also should include not EMCP methods)
   8.161 +              method->method_data()->clean_weak_method_links();
   8.162 +            }
   8.163            }
   8.164          }
   8.165        }
   8.166 +      // next previous version
   8.167 +      last = pv_node;
   8.168 +      pv_node = pv_node->previous_versions();
   8.169 +      version++;
   8.170      }
   8.171 -    assert(ik->previous_versions()->length() == live_count, "sanity check");
   8.172      RC_TRACE(0x00000200,
   8.173        ("purge: previous version stats: live=%d, deleted=%d", live_count,
   8.174        deleted_count));
   8.175    }
   8.176 +
   8.177 +  // Clean MethodData of this class's methods so they don't refer to
   8.178 +  // old methods that are no longer running.
   8.179 +  Array<Method*>* methods = ik->methods();
   8.180 +  int num_methods = methods->length();
   8.181 +  for (int index2 = 0; index2 < num_methods; ++index2) {
   8.182 +    if (methods->at(index2)->method_data() != NULL) {
   8.183 +      methods->at(index2)->method_data()->clean_weak_method_links();
   8.184 +    }
   8.185 +  }
   8.186  }
   8.187  
   8.188 -// External interface for use during class unloading.
   8.189 -void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
   8.190 -  // Call with >0 emcp methods since they are not currently being redefined.
   8.191 -  purge_previous_versions_internal(ik, 1);
   8.192 -}
   8.193 -
   8.194 -
   8.195 -// Potentially add an information node that contains pointers to the
   8.196 -// interesting parts of the previous version of the_class.
   8.197 -// This is also where we clean out any unused references.
   8.198 -// Note that while we delete nodes from the _previous_versions
   8.199 -// array, we never delete the array itself until the klass is
   8.200 -// unloaded. The has_been_redefined() query depends on that fact.
   8.201 -//
   8.202 -void InstanceKlass::add_previous_version(instanceKlassHandle ikh,
   8.203 -       BitMap* emcp_methods, int emcp_method_count) {
   8.204 -  assert(Thread::current()->is_VM_thread(),
   8.205 -         "only VMThread can add previous versions");
   8.206 -
   8.207 -  if (_previous_versions == NULL) {
   8.208 -    // This is the first previous version so make some space.
   8.209 -    // Start with 2 elements under the assumption that the class
   8.210 -    // won't be redefined much.
   8.211 -    _previous_versions =  new (ResourceObj::C_HEAP, mtClass)
   8.212 -                            GrowableArray<PreviousVersionNode *>(2, true);
   8.213 -  }
   8.214 -
   8.215 -  ConstantPool* cp_ref = ikh->constants();
   8.216 -
   8.217 -  // RC_TRACE macro has an embedded ResourceMark
   8.218 -  RC_TRACE(0x00000400, ("adding previous version ref for %s @%d, EMCP_cnt=%d "
   8.219 -                        "on_stack=%d",
   8.220 -    ikh->external_name(), _previous_versions->length(), emcp_method_count,
   8.221 -    cp_ref->on_stack()));
   8.222 -
   8.223 -  // If the constant pool for this previous version of the class
   8.224 -  // is not marked as being on the stack, then none of the methods
   8.225 -  // in this previous version of the class are on the stack so
   8.226 -  // we don't need to create a new PreviousVersionNode. However,
   8.227 -  // we still need to examine older previous versions below.
   8.228 -  Array<Method*>* old_methods = ikh->methods();
   8.229 -
   8.230 -  if (cp_ref->on_stack()) {
   8.231 -    PreviousVersionNode * pv_node = NULL;
   8.232 -    if (emcp_method_count == 0) {
   8.233 -      // non-shared ConstantPool gets a reference
   8.234 -      pv_node = new PreviousVersionNode(cp_ref, NULL);
   8.235 -      RC_TRACE(0x00000400,
   8.236 -          ("add: all methods are obsolete; flushing any EMCP refs"));
   8.237 -    } else {
   8.238 -      int local_count = 0;
   8.239 -      GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
   8.240 -          GrowableArray<Method*>(emcp_method_count, true);
   8.241 -      for (int i = 0; i < old_methods->length(); i++) {
   8.242 -        if (emcp_methods->at(i)) {
   8.243 -            // this old method is EMCP. Save it only if it's on the stack
   8.244 -            Method* old_method = old_methods->at(i);
   8.245 -            if (old_method->on_stack()) {
   8.246 -              method_refs->append(old_method);
   8.247 -            }
   8.248 -          if (++local_count >= emcp_method_count) {
   8.249 -            // no more EMCP methods so bail out now
   8.250 -            break;
   8.251 -          }
   8.252 -        }
   8.253 -      }
   8.254 -      // non-shared ConstantPool gets a reference
   8.255 -      pv_node = new PreviousVersionNode(cp_ref, method_refs);
   8.256 -    }
   8.257 -    // append new previous version.
   8.258 -    _previous_versions->append(pv_node);
   8.259 -  }
   8.260 -
   8.261 -  // Since the caller is the VMThread and we are at a safepoint, this
   8.262 -  // is a good time to clear out unused references.
   8.263 -
   8.264 -  RC_TRACE(0x00000400, ("add: previous version length=%d",
   8.265 -    _previous_versions->length()));
   8.266 -
   8.267 -  // Purge previous versions not executing on the stack
   8.268 -  purge_previous_versions_internal(this, emcp_method_count);
   8.269 -
   8.270 +void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods,
   8.271 +                                                int emcp_method_count) {
   8.272    int obsolete_method_count = old_methods->length() - emcp_method_count;
   8.273  
   8.274    if (emcp_method_count != 0 && obsolete_method_count != 0 &&
   8.275 -      _previous_versions->length() > 0) {
   8.276 +      _previous_versions != NULL) {
   8.277      // We have a mix of obsolete and EMCP methods so we have to
   8.278      // clear out any matching EMCP method entries the hard way.
   8.279      int local_count = 0;
   8.280      for (int i = 0; i < old_methods->length(); i++) {
   8.281 -      if (!emcp_methods->at(i)) {
   8.282 +      Method* old_method = old_methods->at(i);
   8.283 +      if (old_method->is_obsolete()) {
   8.284          // only obsolete methods are interesting
   8.285 -        Method* old_method = old_methods->at(i);
   8.286          Symbol* m_name = old_method->name();
   8.287          Symbol* m_signature = old_method->signature();
   8.288  
   8.289 -        // we might not have added the last entry
   8.290 -        for (int j = _previous_versions->length() - 1; j >= 0; j--) {
   8.291 -          // check the previous versions array for non executing obsolete methods
   8.292 -          PreviousVersionNode * pv_node = _previous_versions->at(j);
   8.293 -
   8.294 -          GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
   8.295 -          if (method_refs == NULL) {
   8.296 -            // We have run into a PreviousVersion generation where
   8.297 -            // all methods were made obsolete during that generation's
   8.298 -            // RedefineClasses() operation. At the time of that
   8.299 -            // operation, all EMCP methods were flushed so we don't
   8.300 -            // have to go back any further.
   8.301 -            //
   8.302 -            // A NULL method_refs is different than an empty method_refs.
   8.303 -            // We cannot infer any optimizations about older generations
   8.304 -            // from an empty method_refs for the current generation.
   8.305 -            break;
   8.306 -          }
   8.307 -
   8.308 -          for (int k = method_refs->length() - 1; k >= 0; k--) {
   8.309 +        // previous versions are linked together through the InstanceKlass
   8.310 +        int j = 0;
   8.311 +        for (InstanceKlass* prev_version = _previous_versions;
   8.312 +             prev_version != NULL;
   8.313 +             prev_version = prev_version->previous_versions(), j++) {
   8.314 +
   8.315 +          Array<Method*>* method_refs = prev_version->methods();
   8.316 +          for (int k = 0; k < method_refs->length(); k++) {
   8.317              Method* method = method_refs->at(k);
   8.318  
   8.319              if (!method->is_obsolete() &&
   8.320 @@ -3816,14 +3728,11 @@
   8.321                  method->signature() == m_signature) {
   8.322                // The current RedefineClasses() call has made all EMCP
   8.323                // versions of this method obsolete so mark it as obsolete
   8.324 -              // and remove the reference.
   8.325                RC_TRACE(0x00000400,
   8.326                  ("add: %s(%s): flush obsolete method @%d in version @%d",
   8.327                  m_name->as_C_string(), m_signature->as_C_string(), k, j));
   8.328  
   8.329                method->set_is_obsolete();
   8.330 -              // Leave obsolete methods on the previous version list to
   8.331 -              // clean up later.
   8.332                break;
   8.333              }
   8.334            }
   8.335 @@ -3831,9 +3740,9 @@
   8.336            // The previous loop may not find a matching EMCP method, but
   8.337            // that doesn't mean that we can optimize and not go any
   8.338            // further back in the PreviousVersion generations. The EMCP
   8.339 -          // method for this generation could have already been deleted,
   8.340 +          // method for this generation could have already been made obsolete,
   8.341            // but there still may be an older EMCP method that has not
   8.342 -          // been deleted.
   8.343 +          // been made obsolete.
   8.344          }
   8.345  
   8.346          if (++local_count >= obsolete_method_count) {
   8.347 @@ -3843,30 +3752,67 @@
   8.348        }
   8.349      }
   8.350    }
   8.351 -} // end add_previous_version()
   8.352 -
   8.353 -
   8.354 -// Determine if InstanceKlass has a previous version.
   8.355 -bool InstanceKlass::has_previous_version() const {
   8.356 -  return (_previous_versions != NULL && _previous_versions->length() > 0);
   8.357 -} // end has_previous_version()
   8.358 -
   8.359 -
   8.360 -InstanceKlass* InstanceKlass::get_klass_version(int version) {
   8.361 -  if (constants()->version() == version) {
   8.362 -    return this;
   8.363 +}
   8.364 +
   8.365 +// Save the scratch_class as the previous version if any of the methods are running.
   8.366 +// The previous_versions are used to set breakpoints in EMCP methods and they are
   8.367 +// also used to clean MethodData links to redefined methods that are no longer running.
   8.368 +void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class,
   8.369 +                                         int emcp_method_count) {
   8.370 +  assert(Thread::current()->is_VM_thread(),
   8.371 +         "only VMThread can add previous versions");
   8.372 +
   8.373 +  // RC_TRACE macro has an embedded ResourceMark
   8.374 +  RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d",
   8.375 +    scratch_class->external_name(), emcp_method_count));
   8.376 +
   8.377 +  // Clean out old previous versions
   8.378 +  purge_previous_versions(this);
   8.379 +
   8.380 +  // Mark newly obsolete methods in remaining previous versions.  An EMCP method from
   8.381 +  // a previous redefinition may be made obsolete by this redefinition.
   8.382 +  Array<Method*>* old_methods = scratch_class->methods();
   8.383 +  mark_newly_obsolete_methods(old_methods, emcp_method_count);
   8.384 +
   8.385 +  // If the constant pool for this previous version of the class
   8.386 +  // is not marked as being on the stack, then none of the methods
   8.387 +  // in this previous version of the class are on the stack so
   8.388 +  // we don't need to add this as a previous version.
   8.389 +  ConstantPool* cp_ref = scratch_class->constants();
   8.390 +  if (!cp_ref->on_stack()) {
   8.391 +    RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running"));
   8.392 +    return;
   8.393    }
   8.394 -  PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
   8.395 -  for (PreviousVersionNode * pv_node = pvw.next_previous_version();
   8.396 -       pv_node != NULL; pv_node = pvw.next_previous_version()) {
   8.397 -    ConstantPool* prev_cp = pv_node->prev_constant_pool();
   8.398 -    if (prev_cp->version() == version) {
   8.399 -      return prev_cp->pool_holder();
   8.400 +
   8.401 +  if (emcp_method_count != 0) {
   8.402 +    // At least one method is still running, check for EMCP methods
   8.403 +    for (int i = 0; i < old_methods->length(); i++) {
   8.404 +      Method* old_method = old_methods->at(i);
   8.405 +      if (!old_method->is_obsolete() && old_method->on_stack()) {
   8.406 +        // if EMCP method (not obsolete) is on the stack, mark as EMCP so that
   8.407 +        // we can add breakpoints for it.
   8.408 +
   8.409 +        // We set the method->on_stack bit during safepoints for class redefinition and
   8.410 +        // class unloading and use this bit to set the is_running_emcp bit.
   8.411 +        // After the safepoint, the on_stack bit is cleared and the running emcp
   8.412 +        // method may exit.   If so, we would set a breakpoint in a method that
   8.413 +        // is never reached, but this won't be noticeable to the programmer.
   8.414 +        old_method->set_running_emcp(true);
   8.415 +        RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT,
   8.416 +                              old_method->name_and_sig_as_C_string(), old_method));
   8.417 +      } else if (!old_method->is_obsolete()) {
   8.418 +        RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT,
   8.419 +                              old_method->name_and_sig_as_C_string(), old_method));
   8.420 +      }
   8.421      }
   8.422    }
   8.423 -  return NULL; // None found
   8.424 -}
   8.425 -
   8.426 +
   8.427 +  // Add previous version if any methods are still running.
   8.428 +  RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack"));
   8.429 +  assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
   8.430 +  scratch_class->link_previous_versions(previous_versions());
   8.431 +  link_previous_versions(scratch_class());
   8.432 +} // end add_previous_version()
   8.433  
   8.434  Method* InstanceKlass::method_with_idnum(int idnum) {
   8.435    Method* m = NULL;
   8.436 @@ -3924,61 +3870,3 @@
   8.437  unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   8.438    return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
   8.439  }
   8.440 -
   8.441 -
   8.442 -// Construct a PreviousVersionNode entry for the array hung off
   8.443 -// the InstanceKlass.
   8.444 -PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
   8.445 -  GrowableArray<Method*>* prev_EMCP_methods) {
   8.446 -
   8.447 -  _prev_constant_pool = prev_constant_pool;
   8.448 -  _prev_EMCP_methods = prev_EMCP_methods;
   8.449 -}
   8.450 -
   8.451 -
   8.452 -// Destroy a PreviousVersionNode
   8.453 -PreviousVersionNode::~PreviousVersionNode() {
   8.454 -  if (_prev_constant_pool != NULL) {
   8.455 -    _prev_constant_pool = NULL;
   8.456 -  }
   8.457 -
   8.458 -  if (_prev_EMCP_methods != NULL) {
   8.459 -    delete _prev_EMCP_methods;
   8.460 -  }
   8.461 -}
   8.462 -
   8.463 -// Construct a helper for walking the previous versions array
   8.464 -PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) {
   8.465 -  _thread = thread;
   8.466 -  _previous_versions = ik->previous_versions();
   8.467 -  _current_index = 0;
   8.468 -  _current_p = NULL;
   8.469 -  _current_constant_pool_handle = constantPoolHandle(thread, ik->constants());
   8.470 -}
   8.471 -
   8.472 -
   8.473 -// Return the interesting information for the next previous version
   8.474 -// of the klass. Returns NULL if there are no more previous versions.
   8.475 -PreviousVersionNode* PreviousVersionWalker::next_previous_version() {
   8.476 -  if (_previous_versions == NULL) {
   8.477 -    // no previous versions so nothing to return
   8.478 -    return NULL;
   8.479 -  }
   8.480 -
   8.481 -  _current_p = NULL;  // reset to NULL
   8.482 -  _current_constant_pool_handle = NULL;
   8.483 -
   8.484 -  int length = _previous_versions->length();
   8.485 -
   8.486 -  while (_current_index < length) {
   8.487 -    PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
   8.488 -
   8.489 -    // Save a handle to the constant pool for this previous version,
   8.490 -    // which keeps all the methods from being deallocated.
   8.491 -    _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool());
   8.492 -    _current_p = pv_node;
   8.493 -    return pv_node;
   8.494 -  }
   8.495 -
   8.496 -  return NULL;
   8.497 -} // end next_previous_version()
     9.1 --- a/src/share/vm/oops/instanceKlass.hpp	Mon Mar 19 12:12:48 2018 -0700
     9.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Mon Mar 19 13:23:53 2018 -0700
     9.3 @@ -88,7 +88,6 @@
     9.4  class fieldDescriptor;
     9.5  class DepChange;
     9.6  class nmethodBucket;
     9.7 -class PreviousVersionNode;
     9.8  class JvmtiCachedClassFieldMap;
     9.9  class MemberNameTable;
    9.10  
    9.11 @@ -235,7 +234,8 @@
    9.12      _misc_is_anonymous             = 1 << 3, // has embedded _host_klass field
    9.13      _misc_is_contended             = 1 << 4, // marked with contended annotation
    9.14      _misc_has_default_methods      = 1 << 5, // class/superclass/implemented interfaces has default methods
    9.15 -    _misc_declares_default_methods = 1 << 6  // directly declares default methods (any access)
    9.16 +    _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access)
    9.17 +    _misc_has_been_redefined       = 1 << 7  // class has been redefined
    9.18    };
    9.19    u2              _misc_flags;
    9.20    u2              _minor_version;        // minor version number of class file
    9.21 @@ -250,9 +250,8 @@
    9.22    nmethodBucket*  _dependencies;         // list of dependent nmethods
    9.23    nmethod*        _osr_nmethods_head;    // Head of list of on-stack replacement nmethods for this class
    9.24    BreakpointInfo* _breakpoints;          // bpt lists, managed by Method*
    9.25 -  // Array of interesting part(s) of the previous version(s) of this
    9.26 -  // InstanceKlass. See PreviousVersionWalker below.
    9.27 -  GrowableArray<PreviousVersionNode *>* _previous_versions;
    9.28 +  // Linked instanceKlasses of previous versions
    9.29 +  InstanceKlass* _previous_versions;
    9.30    // JVMTI fields can be moved to their own structure - see 6315920
    9.31    // JVMTI: cached class file, before retransformable agent modified it in CFLH
    9.32    JvmtiCachedClassFileData* _cached_class_file;
    9.33 @@ -669,21 +668,31 @@
    9.34    }
    9.35  
    9.36    // RedefineClasses() support for previous versions:
    9.37 -  void add_previous_version(instanceKlassHandle ikh, BitMap *emcp_methods,
    9.38 -         int emcp_method_count);
    9.39 -  // If the _previous_versions array is non-NULL, then this klass
    9.40 -  // has been redefined at least once even if we aren't currently
    9.41 -  // tracking a previous version.
    9.42 -  bool has_been_redefined() const { return _previous_versions != NULL; }
    9.43 -  bool has_previous_version() const;
    9.44 +  void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
    9.45 +
    9.46 +  InstanceKlass* previous_versions() const { return _previous_versions; }
    9.47 +
    9.48 +  bool has_been_redefined() const {
    9.49 +    return (_misc_flags & _misc_has_been_redefined) != 0;
    9.50 +  }
    9.51 +  void set_has_been_redefined() {
    9.52 +    _misc_flags |= _misc_has_been_redefined;
    9.53 +  }
    9.54 +
    9.55    void init_previous_versions() {
    9.56      _previous_versions = NULL;
    9.57    }
    9.58 -  GrowableArray<PreviousVersionNode *>* previous_versions() const {
    9.59 -    return _previous_versions;
    9.60 +
    9.61 +
    9.62 +  InstanceKlass* get_klass_version(int version) {
    9.63 +    for (InstanceKlass* ik = this; ik != NULL; ik = ik->previous_versions()) {
    9.64 +      if (ik->constants()->version() == version) {
    9.65 +        return ik;
    9.66 +      }
    9.67 +    }
    9.68 +    return NULL;
    9.69    }
    9.70  
    9.71 -  InstanceKlass* get_klass_version(int version);
    9.72    static void purge_previous_versions(InstanceKlass* ik);
    9.73  
    9.74    // JVMTI: Support for caching a class file before it is modified by an agent that can do retransformation
    9.75 @@ -1124,6 +1133,10 @@
    9.76  
    9.77    // Free CHeap allocated fields.
    9.78    void release_C_heap_structures();
    9.79 +
    9.80 +  // RedefineClasses support
    9.81 +  void link_previous_versions(InstanceKlass* pv) { _previous_versions = pv; }
    9.82 +  void mark_newly_obsolete_methods(Array<Method*>* old_methods, int emcp_method_count);
    9.83  public:
    9.84    // CDS support - remove and restore oops from metadata. Oops are not shared.
    9.85    virtual void remove_unshareable_info();
    9.86 @@ -1222,62 +1235,6 @@
    9.87  };
    9.88  
    9.89  
    9.90 -// If breakpoints are more numerous than just JVMTI breakpoints,
    9.91 -// consider compressing this data structure.
    9.92 -// It is currently a simple linked list defined in method.hpp.
    9.93 -
    9.94 -class BreakpointInfo;
    9.95 -
    9.96 -
    9.97 -// A collection point for interesting information about the previous
    9.98 -// version(s) of an InstanceKlass.  A GrowableArray of PreviousVersionNodes
    9.99 -// is attached to the InstanceKlass as needed. See PreviousVersionWalker below.
   9.100 -class PreviousVersionNode : public CHeapObj<mtClass> {
   9.101 - private:
   9.102 -  ConstantPool*    _prev_constant_pool;
   9.103 -
   9.104 -  // If the previous version of the InstanceKlass doesn't have any
   9.105 -  // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
   9.106 -  // EMCP methods have been collected, then _prev_EMCP_methods can
   9.107 -  // have a length of zero.
   9.108 -  GrowableArray<Method*>* _prev_EMCP_methods;
   9.109 -
   9.110 -public:
   9.111 -  PreviousVersionNode(ConstantPool* prev_constant_pool,
   9.112 -                      GrowableArray<Method*>* prev_EMCP_methods);
   9.113 -  ~PreviousVersionNode();
   9.114 -  ConstantPool* prev_constant_pool() const {
   9.115 -    return _prev_constant_pool;
   9.116 -  }
   9.117 -  GrowableArray<Method*>* prev_EMCP_methods() const {
   9.118 -    return _prev_EMCP_methods;
   9.119 -  }
   9.120 -};
   9.121 -
   9.122 -
   9.123 -// Helper object for walking previous versions.
   9.124 -class PreviousVersionWalker : public StackObj {
   9.125 - private:
   9.126 -  Thread*                               _thread;
   9.127 -  GrowableArray<PreviousVersionNode *>* _previous_versions;
   9.128 -  int                                   _current_index;
   9.129 -
   9.130 -  // A pointer to the current node object so we can handle the deletes.
   9.131 -  PreviousVersionNode*                  _current_p;
   9.132 -
   9.133 -  // The constant pool handle keeps all the methods in this class from being
   9.134 -  // deallocated from the metaspace during class unloading.
   9.135 -  constantPoolHandle                    _current_constant_pool_handle;
   9.136 -
   9.137 - public:
   9.138 -  PreviousVersionWalker(Thread* thread, InstanceKlass *ik);
   9.139 -
   9.140 -  // Return the interesting information for the next previous version
   9.141 -  // of the klass. Returns NULL if there are no more previous versions.
   9.142 -  PreviousVersionNode* next_previous_version();
   9.143 -};
   9.144 -
   9.145 -
   9.146  //
   9.147  // nmethodBucket is used to record dependent nmethods for
   9.148  // deoptimization.  nmethod dependencies are actually <klass, method>
    10.1 --- a/src/share/vm/oops/klass.cpp	Mon Mar 19 12:12:48 2018 -0700
    10.2 +++ b/src/share/vm/oops/klass.cpp	Mon Mar 19 13:23:53 2018 -0700
    10.3 @@ -468,6 +468,12 @@
    10.4      if (clean_alive_klasses && current->oop_is_instance()) {
    10.5        InstanceKlass* ik = InstanceKlass::cast(current);
    10.6        ik->clean_weak_instanceklass_links(is_alive);
    10.7 +
    10.8 +      // JVMTI RedefineClasses creates previous versions that are not in
    10.9 +      // the class hierarchy, so process them here.
   10.10 +      while ((ik = ik->previous_versions()) != NULL) {
   10.11 +        ik->clean_weak_instanceklass_links(is_alive);
   10.12 +      }
   10.13      }
   10.14    }
   10.15  }
    11.1 --- a/src/share/vm/oops/method.cpp	Mon Mar 19 12:12:48 2018 -0700
    11.2 +++ b/src/share/vm/oops/method.cpp	Mon Mar 19 13:23:53 2018 -0700
    11.3 @@ -91,6 +91,7 @@
    11.4    set_hidden(false);
    11.5    set_dont_inline(false);
    11.6    set_has_injected_profile(false);
    11.7 +  set_running_emcp(false);
    11.8    set_method_data(NULL);
    11.9    clear_method_counters();
   11.10    set_vtable_index(Method::garbage_vtable_index);
    12.1 --- a/src/share/vm/oops/method.hpp	Mon Mar 19 12:12:48 2018 -0700
    12.2 +++ b/src/share/vm/oops/method.hpp	Mon Mar 19 13:23:53 2018 -0700
    12.3 @@ -111,6 +111,7 @@
    12.4                      _caller_sensitive     : 1,
    12.5                      _force_inline         : 1,
    12.6                      _hidden               : 1,
    12.7 +                    _running_emcp         : 1,
    12.8                      _dont_inline          : 1,
    12.9                      _has_injected_profile : 1,
   12.10                                            : 2;
   12.11 @@ -712,6 +713,21 @@
   12.12    void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
   12.13    bool is_deleted() const                           { return access_flags().is_deleted(); }
   12.14    void set_is_deleted()                             { _access_flags.set_is_deleted(); }
   12.15 +
   12.16 +  bool is_running_emcp() const {
   12.17 +    // EMCP methods are old but not obsolete or deleted. Equivalent
   12.18 +    // Modulo Constant Pool means the method is equivalent except
   12.19 +    // the constant pool and instructions that access the constant
   12.20 +    // pool might be different.
   12.21 +    // If a breakpoint is set in a redefined method, its EMCP methods that are
   12.22 +    // still running must have a breakpoint also.
   12.23 +    return _running_emcp;
   12.24 +  }
   12.25 +
   12.26 +  void set_running_emcp(bool x) {
   12.27 +    _running_emcp = x;
   12.28 +  }
   12.29 +
   12.30    bool on_stack() const                             { return access_flags().on_stack(); }
   12.31    void set_on_stack(const bool value);
   12.32  
    13.1 --- a/src/share/vm/oops/methodData.cpp	Mon Mar 19 12:12:48 2018 -0700
    13.2 +++ b/src/share/vm/oops/methodData.cpp	Mon Mar 19 13:23:53 2018 -0700
    13.3 @@ -1559,9 +1559,35 @@
    13.4    }
    13.5  }
    13.6  
    13.7 -// Remove SpeculativeTrapData entries that reference an unloaded
    13.8 -// method
    13.9 -void MethodData::clean_extra_data(BoolObjectClosure* is_alive) {
   13.10 +class CleanExtraDataClosure : public StackObj {
   13.11 +public:
   13.12 +  virtual bool is_live(Method* m) = 0;
   13.13 +};
   13.14 +
   13.15 +// Check for entries that reference an unloaded method
   13.16 +class CleanExtraDataKlassClosure : public CleanExtraDataClosure {
   13.17 +private:
   13.18 +  BoolObjectClosure* _is_alive;
   13.19 +public:
   13.20 +  CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {}
   13.21 +  bool is_live(Method* m) {
   13.22 +    return m->method_holder()->is_loader_alive(_is_alive);
   13.23 +  }
   13.24 +};
   13.25 +
   13.26 +// Check for entries that reference a redefined method
   13.27 +class CleanExtraDataMethodClosure : public CleanExtraDataClosure {
   13.28 +public:
   13.29 +  CleanExtraDataMethodClosure() {}
   13.30 +  bool is_live(Method* m) {
   13.31 +    return m->on_stack();
   13.32 +  }
   13.33 +};
   13.34 +
   13.35 +
   13.36 +// Remove SpeculativeTrapData entries that reference an unloaded or
   13.37 +// redefined method
   13.38 +void MethodData::clean_extra_data(CleanExtraDataClosure* cl) {
   13.39    DataLayout* dp  = extra_data_base();
   13.40    DataLayout* end = extra_data_limit();
   13.41  
   13.42 @@ -1572,7 +1598,7 @@
   13.43        SpeculativeTrapData* data = new SpeculativeTrapData(dp);
   13.44        Method* m = data->method();
   13.45        assert(m != NULL, "should have a method");
   13.46 -      if (!m->method_holder()->is_loader_alive(is_alive)) {
   13.47 +      if (!cl->is_live(m)) {
   13.48          // "shift" accumulates the number of cells for dead
   13.49          // SpeculativeTrapData entries that have been seen so
   13.50          // far. Following entries must be shifted left by that many
   13.51 @@ -1603,9 +1629,9 @@
   13.52    }
   13.53  }
   13.54  
   13.55 -// Verify there's no unloaded method referenced by a
   13.56 +// Verify there's no unloaded or redefined method referenced by a
   13.57  // SpeculativeTrapData entry
   13.58 -void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) {
   13.59 +void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) {
   13.60  #ifdef ASSERT
   13.61    DataLayout* dp  = extra_data_base();
   13.62    DataLayout* end = extra_data_limit();
   13.63 @@ -1615,7 +1641,7 @@
   13.64      case DataLayout::speculative_trap_data_tag: {
   13.65        SpeculativeTrapData* data = new SpeculativeTrapData(dp);
   13.66        Method* m = data->method();
   13.67 -      assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist");
   13.68 +      assert(m != NULL && cl->is_live(m), "Method should exist");
   13.69        break;
   13.70      }
   13.71      case DataLayout::bit_data_tag:
   13.72 @@ -1641,6 +1667,19 @@
   13.73      parameters->clean_weak_klass_links(is_alive);
   13.74    }
   13.75  
   13.76 -  clean_extra_data(is_alive);
   13.77 -  verify_extra_data_clean(is_alive);
   13.78 +  CleanExtraDataKlassClosure cl(is_alive);
   13.79 +  clean_extra_data(&cl);
   13.80 +  verify_extra_data_clean(&cl);
   13.81  }
   13.82 +
   13.83 +void MethodData::clean_weak_method_links() {
   13.84 +  for (ProfileData* data = first_data();
   13.85 +       is_valid(data);
   13.86 +       data = next_data(data)) {
   13.87 +    data->clean_weak_method_links();
   13.88 +  }
   13.89 +
   13.90 +  CleanExtraDataMethodClosure cl;
   13.91 +  clean_extra_data(&cl);
   13.92 +  verify_extra_data_clean(&cl);
   13.93 +}
    14.1 --- a/src/share/vm/oops/methodData.hpp	Mon Mar 19 12:12:48 2018 -0700
    14.2 +++ b/src/share/vm/oops/methodData.hpp	Mon Mar 19 13:23:53 2018 -0700
    14.3 @@ -251,6 +251,9 @@
    14.4  
    14.5    // GC support
    14.6    void clean_weak_klass_links(BoolObjectClosure* cl);
    14.7 +
    14.8 +  // Redefinition support
    14.9 +  void clean_weak_method_links();
   14.10  };
   14.11  
   14.12  
   14.13 @@ -508,6 +511,9 @@
   14.14    // GC support
   14.15    virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {}
   14.16  
   14.17 +  // Redefinition support
   14.18 +  virtual void clean_weak_method_links() {}
   14.19 +
   14.20    // CI translation: ProfileData can represent both MethodDataOop data
   14.21    // as well as CIMethodData data. This function is provided for translating
   14.22    // an oop in a ProfileData to the ci equivalent. Generally speaking,
   14.23 @@ -2030,6 +2036,7 @@
   14.24  //
   14.25  
   14.26  CC_INTERP_ONLY(class BytecodeInterpreter;)
   14.27 +class CleanExtraDataClosure;
   14.28  
   14.29  class MethodData : public Metadata {
   14.30    friend class VMStructs;
   14.31 @@ -2183,9 +2190,9 @@
   14.32    static bool profile_parameters_jsr292_only();
   14.33    static bool profile_all_parameters();
   14.34  
   14.35 -  void clean_extra_data(BoolObjectClosure* is_alive);
   14.36 +  void clean_extra_data(CleanExtraDataClosure* cl);
   14.37    void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false);
   14.38 -  void verify_extra_data_clean(BoolObjectClosure* is_alive);
   14.39 +  void verify_extra_data_clean(CleanExtraDataClosure* cl);
   14.40  
   14.41  public:
   14.42    static int header_size() {
   14.43 @@ -2477,6 +2484,8 @@
   14.44    static bool profile_return_jsr292_only();
   14.45  
   14.46    void clean_method_data(BoolObjectClosure* is_alive);
   14.47 +
   14.48 +  void clean_weak_method_links();
   14.49  };
   14.50  
   14.51  #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP
    15.1 --- a/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	Mon Mar 19 12:12:48 2018 -0700
    15.2 +++ b/src/share/vm/prims/jvmtiGetLoadedClasses.cpp	Mon Mar 19 13:23:53 2018 -0700
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
    15.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.8   *
    15.9   * This code is free software; you can redistribute it and/or modify it
   15.10 @@ -27,6 +27,9 @@
   15.11  #include "memory/universe.inline.hpp"
   15.12  #include "prims/jvmtiGetLoadedClasses.hpp"
   15.13  #include "runtime/thread.hpp"
   15.14 +#if INCLUDE_ALL_GCS
   15.15 +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
   15.16 +#endif
   15.17  
   15.18  
   15.19  // The closure for GetLoadedClasses
   15.20 @@ -35,6 +38,20 @@
   15.21    Stack<jclass, mtInternal> _classStack;
   15.22    JvmtiEnv* _env;
   15.23  
   15.24 +// Tell the GC to keep this klass alive
   15.25 +static void ensure_klass_alive(oop o) {
   15.26 +  // A klass that was previously considered dead can be looked up in the
   15.27 +  // CLD/SD, and its _java_mirror or _class_loader can be stored in a root
   15.28 +  // or a reachable object making it alive again. The SATB part of G1 needs
   15.29 +  // to get notified about this potential resurrection, otherwise the marking
   15.30 +  // might not find the object.
   15.31 +#if INCLUDE_ALL_GCS
   15.32 +  if (UseG1GC && o != NULL) {
   15.33 +    G1SATBCardTableModRefBS::enqueue(o);
   15.34 +  }
   15.35 +#endif
   15.36 +}
   15.37 +
   15.38  public:
   15.39    LoadedClassesClosure(JvmtiEnv* env) {
   15.40      _env = env;
   15.41 @@ -43,6 +60,7 @@
   15.42    void do_klass(Klass* k) {
   15.43      // Collect all jclasses
   15.44      _classStack.push((jclass) _env->jni_reference(k->java_mirror()));
   15.45 +    ensure_klass_alive(k->java_mirror());
   15.46    }
   15.47  
   15.48    int extract(jclass* result_list) {
    16.1 --- a/src/share/vm/prims/jvmtiImpl.cpp	Mon Mar 19 12:12:48 2018 -0700
    16.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp	Mon Mar 19 13:23:53 2018 -0700
    16.3 @@ -282,39 +282,22 @@
    16.4  void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
    16.5    ((Method*)_method->*meth_act)(_bci);
    16.6  
    16.7 -  // add/remove breakpoint to/from versions of the method that
    16.8 -  // are EMCP. Directly or transitively obsolete methods are
    16.9 -  // not saved in the PreviousVersionNodes.
   16.10 +  // add/remove breakpoint to/from versions of the method that are EMCP.
   16.11    Thread *thread = Thread::current();
   16.12    instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
   16.13    Symbol* m_name = _method->name();
   16.14    Symbol* m_signature = _method->signature();
   16.15  
   16.16    // search previous versions if they exist
   16.17 -  PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh());
   16.18 -  for (PreviousVersionNode * pv_node = pvw.next_previous_version();
   16.19 -       pv_node != NULL; pv_node = pvw.next_previous_version()) {
   16.20 -    GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods();
   16.21 -
   16.22 -    if (methods == NULL) {
   16.23 -      // We have run into a PreviousVersion generation where
   16.24 -      // all methods were made obsolete during that generation's
   16.25 -      // RedefineClasses() operation. At the time of that
   16.26 -      // operation, all EMCP methods were flushed so we don't
   16.27 -      // have to go back any further.
   16.28 -      //
   16.29 -      // A NULL methods array is different than an empty methods
   16.30 -      // array. We cannot infer any optimizations about older
   16.31 -      // generations from an empty methods array for the current
   16.32 -      // generation.
   16.33 -      break;
   16.34 -    }
   16.35 +  for (InstanceKlass* pv_node = ikh->previous_versions();
   16.36 +       pv_node != NULL;
   16.37 +       pv_node = pv_node->previous_versions()) {
   16.38 +    Array<Method*>* methods = pv_node->methods();
   16.39  
   16.40      for (int i = methods->length() - 1; i >= 0; i--) {
   16.41        Method* method = methods->at(i);
   16.42 -      // obsolete methods that are running are not deleted from
   16.43 -      // previous version array, but they are skipped here.
   16.44 -      if (!method->is_obsolete() &&
   16.45 +      // Only set breakpoints in running EMCP methods.
   16.46 +      if (method->is_running_emcp() &&
   16.47            method->name() == m_name &&
   16.48            method->signature() == m_signature) {
   16.49          RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
    17.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Mon Mar 19 12:12:48 2018 -0700
    17.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Mon Mar 19 13:23:53 2018 -0700
    17.3 @@ -3435,13 +3435,12 @@
    17.4      }
    17.5  
    17.6      // the previous versions' constant pool caches may need adjustment
    17.7 -    PreviousVersionWalker pvw(_thread, ik);
    17.8 -    for (PreviousVersionNode * pv_node = pvw.next_previous_version();
    17.9 -         pv_node != NULL; pv_node = pvw.next_previous_version()) {
   17.10 -      other_cp = pv_node->prev_constant_pool();
   17.11 -      cp_cache = other_cp->cache();
   17.12 +    for (InstanceKlass* pv_node = ik->previous_versions();
   17.13 +         pv_node != NULL;
   17.14 +         pv_node = pv_node->previous_versions()) {
   17.15 +      cp_cache = pv_node->constants()->cache();
   17.16        if (cp_cache != NULL) {
   17.17 -        cp_cache->adjust_method_entries(other_cp->pool_holder(), &trace_name_printed);
   17.18 +        cp_cache->adjust_method_entries(pv_node, &trace_name_printed);
   17.19        }
   17.20      }
   17.21    }
   17.22 @@ -3461,9 +3460,8 @@
   17.23    }
   17.24  }
   17.25  
   17.26 -void VM_RedefineClasses::check_methods_and_mark_as_obsolete(
   17.27 -       BitMap *emcp_methods, int * emcp_method_count_p) {
   17.28 -  *emcp_method_count_p = 0;
   17.29 +int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
   17.30 +  int emcp_method_count = 0;
   17.31    int obsolete_count = 0;
   17.32    int old_index = 0;
   17.33    for (int j = 0; j < _matching_methods_length; ++j, ++old_index) {
   17.34 @@ -3537,9 +3535,9 @@
   17.35        // that we get from effectively overwriting the old methods
   17.36        // when the new methods are attached to the_class.
   17.37  
   17.38 -      // track which methods are EMCP for add_previous_version() call
   17.39 -      emcp_methods->set_bit(old_index);
   17.40 -      (*emcp_method_count_p)++;
   17.41 +      // Count number of methods that are EMCP.  The method will be marked
   17.42 +      // old but not obsolete if it is EMCP.
   17.43 +      emcp_method_count++;
   17.44  
   17.45        // An EMCP method is _not_ obsolete. An obsolete method has a
   17.46        // different jmethodID than the current method. An EMCP method
   17.47 @@ -3589,10 +3587,11 @@
   17.48                            old_method->name()->as_C_string(),
   17.49                            old_method->signature()->as_C_string()));
   17.50    }
   17.51 -  assert((*emcp_method_count_p + obsolete_count) == _old_methods->length(),
   17.52 +  assert((emcp_method_count + obsolete_count) == _old_methods->length(),
   17.53      "sanity check");
   17.54 -  RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", *emcp_method_count_p,
   17.55 +  RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count,
   17.56      obsolete_count));
   17.57 +  return emcp_method_count;
   17.58  }
   17.59  
   17.60  // This internal class transfers the native function registration from old methods
   17.61 @@ -3973,11 +3972,8 @@
   17.62    old_constants->set_pool_holder(scratch_class());
   17.63  #endif
   17.64  
   17.65 -  // track which methods are EMCP for add_previous_version() call below
   17.66 -  BitMap emcp_methods(_old_methods->length());
   17.67 -  int emcp_method_count = 0;
   17.68 -  emcp_methods.clear();  // clears 0..(length() - 1)
   17.69 -  check_methods_and_mark_as_obsolete(&emcp_methods, &emcp_method_count);
   17.70 +  // track number of methods that are EMCP for add_previous_version() call below
   17.71 +  int emcp_method_count = check_methods_and_mark_as_obsolete();
   17.72    transfer_old_native_function_registrations(the_class);
   17.73  
   17.74    // The class file bytes from before any retransformable agents mucked
   17.75 @@ -4064,9 +4060,10 @@
   17.76      scratch_class->enclosing_method_method_index());
   17.77    scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx);
   17.78  
   17.79 +  the_class->set_has_been_redefined();
   17.80 +
   17.81    // keep track of previous versions of this class
   17.82 -  the_class->add_previous_version(scratch_class, &emcp_methods,
   17.83 -    emcp_method_count);
   17.84 +  the_class->add_previous_version(scratch_class, emcp_method_count);
   17.85  
   17.86    RC_TIMER_STOP(_timer_rsc_phase1);
   17.87    RC_TIMER_START(_timer_rsc_phase2);
    18.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp	Mon Mar 19 12:12:48 2018 -0700
    18.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp	Mon Mar 19 13:23:53 2018 -0700
    18.3 @@ -403,14 +403,9 @@
    18.4    // Change jmethodIDs to point to the new methods
    18.5    void update_jmethod_ids();
    18.6  
    18.7 -  // In addition to marking methods as obsolete, this routine
    18.8 -  // records which methods are EMCP (Equivalent Module Constant
    18.9 -  // Pool) in the emcp_methods BitMap and returns the number of
   18.10 -  // EMCP methods via emcp_method_count_p. This information is
   18.11 -  // used when information about the previous version of the_class
   18.12 -  // is squirreled away.
   18.13 -  void check_methods_and_mark_as_obsolete(BitMap *emcp_methods,
   18.14 -         int * emcp_method_count_p);
   18.15 +  // In addition to marking methods as old and/or obsolete, this routine
   18.16 +  // counts the number of methods that are EMCP (Equivalent Module Constant Pool).
   18.17 +  int check_methods_and_mark_as_obsolete();
   18.18    void transfer_old_native_function_registrations(instanceKlassHandle the_class);
   18.19  
   18.20    // Install the redefinition of a class
    19.1 --- a/src/share/vm/prims/whitebox.cpp	Mon Mar 19 12:12:48 2018 -0700
    19.2 +++ b/src/share/vm/prims/whitebox.cpp	Mon Mar 19 13:23:53 2018 -0700
    19.3 @@ -1,5 +1,5 @@
    19.4  /*
    19.5 - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
    19.6 + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
    19.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.8   *
    19.9   * This code is free software; you can redistribute it and/or modify it
   19.10 @@ -158,6 +158,9 @@
   19.11  }
   19.12  WB_END
   19.13  
   19.14 +#ifdef LINUX
   19.15 +#include "utilities/elfFile.hpp"
   19.16 +#endif
   19.17  
   19.18  WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
   19.19    return (jlong)Arguments::max_heap_for_compressed_oops();
   19.20 @@ -1010,6 +1013,21 @@
   19.21    }
   19.22  }
   19.23  
   19.24 +// Checks that the library libfile has the noexecstack bit set.
   19.25 +WB_ENTRY(jboolean, WB_CheckLibSpecifiesNoexecstack(JNIEnv* env, jobject o, jstring libfile))
   19.26 +  jboolean ret = false;
   19.27 +#ifdef LINUX
   19.28 +  // Can't be in VM when we call JNI.
   19.29 +  ThreadToNativeFromVM ttnfv(thread);
   19.30 +  const char* lf = env->GetStringUTFChars(libfile, NULL);
   19.31 +  CHECK_JNI_EXCEPTION_(env, 0);
   19.32 +  ElfFile ef(lf);
   19.33 +  ret = (jboolean) ef.specifies_noexecstack();
   19.34 +  env->ReleaseStringUTFChars(libfile, lf);
   19.35 +#endif
   19.36 +  return ret;
   19.37 +WB_END
   19.38 +
   19.39  #define CC (char*)
   19.40  
   19.41  static JNINativeMethod methods[] = {
   19.42 @@ -1121,6 +1139,8 @@
   19.43                                                        (void*)&WB_GetNMethod         },
   19.44    {CC"isMonitorInflated",  CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
   19.45    {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
   19.46 +  {CC"checkLibSpecifiesNoexecstack", CC"(Ljava/lang/String;)Z",
   19.47 +                                                      (void*)&WB_CheckLibSpecifiesNoexecstack},
   19.48  };
   19.49  
   19.50  #undef CC
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/compiler/profiling/spectrapredefineclass/Agent.java	Mon Mar 19 13:23:53 2018 -0700
    20.3 @@ -0,0 +1,142 @@
    20.4 +/*
    20.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.
   20.11 + *
   20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.15 + * version 2 for more details (a copy is included in the LICENSE file that
   20.16 + * accompanied this code).
   20.17 + *
   20.18 + * You should have received a copy of the GNU General Public License version
   20.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.21 + *
   20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.23 + * or visit www.oracle.com if you need additional information or have any
   20.24 + * questions.
   20.25 + */
   20.26 +
   20.27 +import java.security.*;
   20.28 +import java.lang.instrument.*;
   20.29 +import java.lang.reflect.*;
   20.30 +import java.lang.management.ManagementFactory;
   20.31 +import com.sun.tools.attach.VirtualMachine;
   20.32 +
   20.33 +class A {
   20.34 +    void m() {
   20.35 +    }
   20.36 +}
   20.37 +
   20.38 +class B extends A {
   20.39 +    void m() {
   20.40 +    }
   20.41 +}
   20.42 +
   20.43 +class C extends A {
   20.44 +    void m() {
   20.45 +    }
   20.46 +}
   20.47 +
   20.48 +class Test {
   20.49 +
   20.50 +    static public void m() throws Exception {
   20.51 +        for (int i = 0; i < 20000; i++) {
   20.52 +            m1(a);
   20.53 +        }
   20.54 +        for (int i = 0; i < 4; i++) {
   20.55 +            m1(b);
   20.56 +        }
   20.57 +    }
   20.58 +
   20.59 +    static boolean m1(A a) {
   20.60 +        boolean res =  Agent.m2(a);
   20.61 +        return res;
   20.62 +    }
   20.63 +
   20.64 +    static public A a = new A();
   20.65 +    static public B b = new B();
   20.66 +    static public C c = new C();
   20.67 +}
   20.68 +
   20.69 +public class Agent implements ClassFileTransformer {
   20.70 +
   20.71 +
   20.72 +    static class MemoryChunk {
   20.73 +        MemoryChunk other;
   20.74 +        long[] array;
   20.75 +        MemoryChunk(MemoryChunk other) {
   20.76 +            other = other;
   20.77 +            array = new long[1024 * 1024 * 1024];
   20.78 +        }
   20.79 +    }
   20.80 +
   20.81 +    static public boolean m2(A a) {
   20.82 +        boolean res = false;
   20.83 +        if (a.getClass() == B.class) {
   20.84 +            a.m();
   20.85 +        } else {
   20.86 +            res = true;
   20.87 +        }
   20.88 +        return res;
   20.89 +    }
   20.90 +
   20.91 +    static public void main(String[] args) throws Exception {
   20.92 +        // Create speculative trap entries
   20.93 +        Test.m();
   20.94 +
   20.95 +        String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
   20.96 +        int p = nameOfRunningVM.indexOf('@');
   20.97 +        String pid = nameOfRunningVM.substring(0, p);
   20.98 +
   20.99 +        // Make the nmethod go away
  20.100 +        for (int i = 0; i < 10; i++) {
  20.101 +            System.gc();
  20.102 +        }
  20.103 +
  20.104 +        // Redefine class
  20.105 +        try {
  20.106 +            VirtualMachine vm = VirtualMachine.attach(pid);
  20.107 +            vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
  20.108 +            vm.detach();
  20.109 +        } catch (Exception e) {
  20.110 +            throw new RuntimeException(e);
  20.111 +        }
  20.112 +
  20.113 +        Test.m();
  20.114 +        // GC will hit dead method pointer
  20.115 +        for (int i = 0; i < 10; i++) {
  20.116 +            System.gc();
  20.117 +        }
  20.118 +    }
  20.119 +
  20.120 +    public synchronized byte[] transform(final ClassLoader classLoader,
  20.121 +                                         final String className,
  20.122 +                                         Class<?> classBeingRedefined,
  20.123 +                                         ProtectionDomain protectionDomain,
  20.124 +                                         byte[] classfileBuffer) {
  20.125 +        System.out.println("Transforming class " + className);
  20.126 +        return classfileBuffer;
  20.127 +    }
  20.128 +
  20.129 +    public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) {
  20.130 +
  20.131 +        try {
  20.132 +            instrumentation.retransformClasses(to_redefine);
  20.133 +        } catch (Exception e) {
  20.134 +            e.printStackTrace();
  20.135 +        }
  20.136 +
  20.137 +    }
  20.138 +
  20.139 +    public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Exception {
  20.140 +        Agent transformer = new Agent();
  20.141 +        instrumentation.addTransformer(transformer, true);
  20.142 +
  20.143 +        redefine(agentArgs, instrumentation, Test.class);
  20.144 +    }
  20.145 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/compiler/profiling/spectrapredefineclass/Launcher.java	Mon Mar 19 13:23:53 2018 -0700
    21.3 @@ -0,0 +1,47 @@
    21.4 +/*
    21.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.
   21.11 + *
   21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.15 + * version 2 for more details (a copy is included in the LICENSE file that
   21.16 + * accompanied this code).
   21.17 + *
   21.18 + * You should have received a copy of the GNU General Public License version
   21.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.21 + *
   21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.23 + * or visit www.oracle.com if you need additional information or have any
   21.24 + * questions.
   21.25 + */
   21.26 +import java.io.PrintWriter;
   21.27 +import com.oracle.java.testlibrary.*;
   21.28 +
   21.29 +/*
   21.30 + * @test
   21.31 + * @bug 8038636
   21.32 + * @library /testlibrary
   21.33 + * @build Agent
   21.34 + * @run main ClassFileInstaller Agent
   21.35 + * @run main Launcher
   21.36 + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -Xmx1M -XX:ReservedCodeCacheSize=3M Agent
   21.37 + */
   21.38 +public class Launcher {
   21.39 +    public static void main(String[] args) throws Exception  {
   21.40 +
   21.41 +      PrintWriter pw = new PrintWriter("MANIFEST.MF");
   21.42 +      pw.println("Agent-Class: Agent");
   21.43 +      pw.println("Can-Retransform-Classes: true");
   21.44 +      pw.close();
   21.45 +
   21.46 +      ProcessBuilder pb = new ProcessBuilder();
   21.47 +      pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", System.getProperty("test.classes",".") + "/agent.jar", "Agent.class"});
   21.48 +      pb.start().waitFor();
   21.49 +    }
   21.50 +}
    22.1 --- a/test/runtime/RedefineFinalizer/RedefineFinalizer.java	Mon Mar 19 12:12:48 2018 -0700
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,64 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 - *
    22.8 - * This code is free software; you can redistribute it and/or modify it
    22.9 - * under the terms of the GNU General Public License version 2 only, as
   22.10 - * published by the Free Software Foundation.
   22.11 - *
   22.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   22.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.15 - * version 2 for more details (a copy is included in the LICENSE file that
   22.16 - * accompanied this code).
   22.17 - *
   22.18 - * You should have received a copy of the GNU General Public License version
   22.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   22.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.21 - *
   22.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.23 - * or visit www.oracle.com if you need additional information or have any
   22.24 - * questions.
   22.25 - */
   22.26 -
   22.27 -/*
   22.28 - * @test
   22.29 - * @bug 6904403
   22.30 - * @summary Don't assert if we redefine finalize method
   22.31 - * @library /testlibrary
   22.32 - * @build RedefineClassHelper
   22.33 - * @run main RedefineClassHelper
   22.34 - * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer
   22.35 - */
   22.36 -
   22.37 -/*
   22.38 - * Regression test for hitting:
   22.39 - *
   22.40 - * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer
   22.41 - *
   22.42 - * when redefining finalizer method
   22.43 - */
   22.44 -public class RedefineFinalizer {
   22.45 -
   22.46 -    public static String newB =
   22.47 -                "class RedefineFinalizer$B {" +
   22.48 -                "   protected void finalize() { " +
   22.49 -                "       System.out.println(\"Finalizer called\");" +
   22.50 -                "   }" +
   22.51 -                "}";
   22.52 -
   22.53 -    public static void main(String[] args) throws Exception {
   22.54 -        RedefineClassHelper.redefineClass(B.class, newB);
   22.55 -
   22.56 -        A a = new A();
   22.57 -    }
   22.58 -
   22.59 -    static class A extends B {
   22.60 -    }
   22.61 -
   22.62 -    static class B {
   22.63 -        protected void finalize() {
   22.64 -            // should be empty
   22.65 -        }
   22.66 -    }
   22.67 -}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/test/runtime/RedefineTests/RedefineFinalizer.java	Mon Mar 19 13:23:53 2018 -0700
    23.3 @@ -0,0 +1,64 @@
    23.4 +/*
    23.5 + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
    23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.7 + *
    23.8 + * This code is free software; you can redistribute it and/or modify it
    23.9 + * under the terms of the GNU General Public License version 2 only, as
   23.10 + * published by the Free Software Foundation.
   23.11 + *
   23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.15 + * version 2 for more details (a copy is included in the LICENSE file that
   23.16 + * accompanied this code).
   23.17 + *
   23.18 + * You should have received a copy of the GNU General Public License version
   23.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.21 + *
   23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   23.23 + * or visit www.oracle.com if you need additional information or have any
   23.24 + * questions.
   23.25 + */
   23.26 +
   23.27 +/*
   23.28 + * @test
   23.29 + * @bug 6904403
   23.30 + * @summary Don't assert if we redefine finalize method
   23.31 + * @library /testlibrary
   23.32 + * @build RedefineClassHelper
   23.33 + * @run main RedefineClassHelper
   23.34 + * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer
   23.35 + */
   23.36 +
   23.37 +/*
   23.38 + * Regression test for hitting:
   23.39 + *
   23.40 + * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer
   23.41 + *
   23.42 + * when redefining finalizer method
   23.43 + */
   23.44 +public class RedefineFinalizer {
   23.45 +
   23.46 +    public static String newB =
   23.47 +                "class RedefineFinalizer$B {" +
   23.48 +                "   protected void finalize() { " +
   23.49 +                "       System.out.println(\"Finalizer called\");" +
   23.50 +                "   }" +
   23.51 +                "}";
   23.52 +
   23.53 +    public static void main(String[] args) throws Exception {
   23.54 +        RedefineClassHelper.redefineClass(B.class, newB);
   23.55 +
   23.56 +        A a = new A();
   23.57 +    }
   23.58 +
   23.59 +    static class A extends B {
   23.60 +    }
   23.61 +
   23.62 +    static class B {
   23.63 +        protected void finalize() {
   23.64 +            // should be empty
   23.65 +        }
   23.66 +    }
   23.67 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/test/runtime/RedefineTests/RedefineRunningMethods.java	Mon Mar 19 13:23:53 2018 -0700
    24.3 @@ -0,0 +1,143 @@
    24.4 +/*
    24.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 + *
    24.8 + * This code is free software; you can redistribute it and/or modify it
    24.9 + * under the terms of the GNU General Public License version 2 only, as
   24.10 + * published by the Free Software Foundation.
   24.11 + *
   24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.15 + * version 2 for more details (a copy is included in the LICENSE file that
   24.16 + * accompanied this code).
   24.17 + *
   24.18 + * You should have received a copy of the GNU General Public License version
   24.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.21 + *
   24.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.23 + * or visit www.oracle.com if you need additional information or have any
   24.24 + * questions.
   24.25 + */
   24.26 +
   24.27 +/*
   24.28 + * @test
   24.29 + * @bug 8055008
   24.30 + * @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop
   24.31 + * @library /testlibrary
   24.32 + * @build RedefineClassHelper
   24.33 + * @run main RedefineClassHelper
   24.34 + * @run main/othervm -javaagent:redefineagent.jar RedefineRunningMethods
   24.35 + */
   24.36 +public class RedefineRunningMethods {
   24.37 +
   24.38 +    public static String newB =
   24.39 +                "class RedefineRunningMethods$B {" +
   24.40 +                "   static int count1 = 0;" +
   24.41 +                "   static int count2 = 0;" +
   24.42 +                "   public static volatile boolean stop = false;" +
   24.43 +                "  static void localSleep() { " +
   24.44 +                "    try{ " +
   24.45 +                "      Thread.currentThread().sleep(10);" +
   24.46 +                "    } catch(InterruptedException ie) { " +
   24.47 +                "    } " +
   24.48 +                " } " +
   24.49 +                "   public static void infinite() { " +
   24.50 +                "       System.out.println(\"infinite called\");" +
   24.51 +                "   }" +
   24.52 +                "   public static void infinite_emcp() { " +
   24.53 +                "       while (!stop) { count2++; localSleep(); }" +
   24.54 +                "   }" +
   24.55 +                "}";
   24.56 +
   24.57 +    public static String evenNewerB =
   24.58 +                "class RedefineRunningMethods$B {" +
   24.59 +                "   static int count1 = 0;" +
   24.60 +                "   static int count2 = 0;" +
   24.61 +                "   public static volatile boolean stop = false;" +
   24.62 +                "  static void localSleep() { " +
   24.63 +                "    try{ " +
   24.64 +                "      Thread.currentThread().sleep(1);" +
   24.65 +                "    } catch(InterruptedException ie) { " +
   24.66 +                "    } " +
   24.67 +                " } " +
   24.68 +                "   public static void infinite() { }" +
   24.69 +                "   public static void infinite_emcp() { " +
   24.70 +                "       System.out.println(\"infinite_emcp now obsolete called\");" +
   24.71 +                "   }" +
   24.72 +                "}";
   24.73 +
   24.74 +    static class B {
   24.75 +        static int count1 = 0;
   24.76 +        static int count2 = 0;
   24.77 +        public static volatile boolean stop = false;
   24.78 +        static void localSleep() {
   24.79 +          try{
   24.80 +            Thread.currentThread().sleep(10);//sleep for 10 ms
   24.81 +          } catch(InterruptedException ie) {
   24.82 +          }
   24.83 +        }
   24.84 +
   24.85 +        public static void infinite() {
   24.86 +            while (!stop) { count1++; localSleep(); }
   24.87 +        }
   24.88 +        public static void infinite_emcp() {
   24.89 +            while (!stop) { count2++; localSleep(); }
   24.90 +        }
   24.91 +    }
   24.92 +
   24.93 +
   24.94 +    public static void main(String[] args) throws Exception {
   24.95 +
   24.96 +        new Thread() {
   24.97 +            public void run() {
   24.98 +                B.infinite();
   24.99 +            }
  24.100 +        }.start();
  24.101 +
  24.102 +        new Thread() {
  24.103 +            public void run() {
  24.104 +                B.infinite_emcp();
  24.105 +            }
  24.106 +        }.start();
  24.107 +
  24.108 +        RedefineClassHelper.redefineClass(B.class, newB);
  24.109 +
  24.110 +        System.gc();
  24.111 +
  24.112 +        B.infinite();
  24.113 +
  24.114 +        // Start a thread with the second version of infinite_emcp running
  24.115 +        new Thread() {
  24.116 +            public void run() {
  24.117 +                B.infinite_emcp();
  24.118 +            }
  24.119 +        }.start();
  24.120 +
  24.121 +        for (int i = 0; i < 20 ; i++) {
  24.122 +            String s = new String("some garbage");
  24.123 +            System.gc();
  24.124 +        }
  24.125 +
  24.126 +        RedefineClassHelper.redefineClass(B.class, evenNewerB);
  24.127 +        System.gc();
  24.128 +
  24.129 +        for (int i = 0; i < 20 ; i++) {
  24.130 +            B.infinite();
  24.131 +            String s = new String("some garbage");
  24.132 +            System.gc();
  24.133 +        }
  24.134 +
  24.135 +        B.infinite_emcp();
  24.136 +
  24.137 +        // purge should clean everything up.
  24.138 +        B.stop = true;
  24.139 +
  24.140 +        for (int i = 0; i < 20 ; i++) {
  24.141 +            B.infinite();
  24.142 +            String s = new String("some garbage");
  24.143 +            System.gc();
  24.144 +        }
  24.145 +    }
  24.146 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/test/runtime/execstack/TestCheckJDK.java	Mon Mar 19 13:23:53 2018 -0700
    25.3 @@ -0,0 +1,67 @@
    25.4 +/*
    25.5 + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.
   25.11 + *
   25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.15 + * version 2 for more details (a copy is included in the LICENSE file that
   25.16 + * accompanied this code).
   25.17 + *
   25.18 + * You should have received a copy of the GNU General Public License version
   25.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.21 + *
   25.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.23 + * or visit www.oracle.com if you need additional information or have any
   25.24 + * questions.
   25.25 + */
   25.26 +
   25.27 +/**
   25.28 + * @test Testexecstack.java
   25.29 + * @summary Searches for all libraries in test VM and checks that they
   25.30 + *          have the noexecstack bit set.
   25.31 + * @requires (os.family == "linux")
   25.32 + * @library /testlibrary /testlibrary/whitebox
   25.33 + * @build sun.hotspot.WhiteBox
   25.34 + * @run driver ClassFileInstaller sun.hotspot.WhiteBox
   25.35 + *                                sun.hotspot.WhiteBox$WhiteBoxPermission
   25.36 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
   25.37 + *                   TestCheckJDK
   25.38 + */
   25.39 +
   25.40 +import com.oracle.java.testlibrary.Asserts;
   25.41 +import sun.hotspot.WhiteBox;
   25.42 +
   25.43 +import java.nio.file.Files;
   25.44 +import java.nio.file.Path;
   25.45 +import java.nio.file.Paths;
   25.46 +
   25.47 +public class TestCheckJDK {
   25.48 +    static boolean testPassed = true;
   25.49 +    private static final WhiteBox WB = WhiteBox.getWhiteBox();
   25.50 +
   25.51 +    static void checkExecStack(Path file) {
   25.52 +        String filename = file.toString();
   25.53 +        if (filename.endsWith(".so")) {
   25.54 +            if (!WB.checkLibSpecifiesNoexecstack(filename)) {
   25.55 +                System.out.println("Library does not have the noexecstack bit set: " + filename);
   25.56 +                testPassed = false;
   25.57 +            }
   25.58 +        }
   25.59 +    }
   25.60 +
   25.61 +    public static void main(String[] args) throws Throwable {
   25.62 +        String vmInstallDir = System.getProperty("java.home");
   25.63 +
   25.64 +        Files.walk(Paths.get(vmInstallDir)).filter(Files::isRegularFile).forEach(TestCheckJDK::checkExecStack);
   25.65 +
   25.66 +        Asserts.assertTrue(testPassed,
   25.67 +            "The tested VM contains libs that don't have the noexecstack " +
   25.68 +            "bit set. They must be linked with -z,noexecstack.");
   25.69 +    }
   25.70 +}
    26.1 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Mon Mar 19 12:12:48 2018 -0700
    26.2 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Mon Mar 19 13:23:53 2018 -0700
    26.3 @@ -1,5 +1,5 @@
    26.4  /*
    26.5 - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
    26.6 + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
    26.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.8   *
    26.9   * This code is free software; you can redistribute it and/or modify it
   26.10 @@ -235,4 +235,7 @@
   26.11  
   26.12    // Class Data Sharing
   26.13    public native boolean isSharedClass(Class<?> c);
   26.14 +
   26.15 +  // Returns true on linux if library has the noexecstack flag set.
   26.16 +  public native boolean checkLibSpecifiesNoexecstack(String libfilename);
   26.17  }

mercurial