changeset 514:09506d69c8cb

move old files aside
author jrose
date Tue, 13 Aug 2013 00:50:02 -0700
parents 920e65ad4626
children 3e126536de3f
files .hgignore annot.txt anonk.patch anonk.txt asm/asm-jsr292-bsm.patch asm/asm-jsr292-ldc.patch dynopt-6912064.patch indy-bsm-7001379.patch indy-notrans-6981791.patch indy.txt jdk7-b147-to-bsd-port.patch meth-bsme-7049415.patch meth-ci-7009600.patch meth-enable-6817525.patch meth-err-7012087.patch meth-impl-6839872.patch meth-ing-7049410.patch meth-lazy-7023639.jit.patch meth-lazy.txt meth-mhw-7047961.patch meth-rename-7012648.patch meth-ver-6987991.patch meth.txt nonperm.txt old/.hgignore old/annot.txt old/anonk.patch old/anonk.txt old/asm-jsr292-bsm.patch old/asm-jsr292-ldc.patch old/cpindex-6939207.patch old/cpindex-6956164.patch old/cpindex-6957004.patch old/cpindex-6957080.patch old/cpindex-6981788.patch old/cpindex-oopmap.patch old/deopt-mh-6921352.patch old/disassembler-6912062.patch old/dont-fixup-6921799.patch old/dynopt-6912064.patch old/fix-oop-relocs-6940520.patch old/indy-6655646.patch old/indy-6858164.patch old/indy-amd64-6829192.patch old/indy-args-6984311.patch old/indy-args-6996563.patch old/indy-bsm-6964498.patch old/indy-bsm-7001379.patch old/indy-c1-sparc-6930772.patch old/indy-c1-x86-6919934.patch old/indy-c2-sparc-6934104.patch old/indy-cleanup-6893081.patch old/indy-deopt-6969574.patch old/indy-notrans-6981791.patch old/indy-sparc-6829193.patch old/indy.compiler-6829187.patch old/indy.compiler.inline-6893268.patch old/indy.compiler.pkgtest.patch old/indy.txt old/inlines-6912063.patch old/jdk7-b147-to-bsd-port.patch old/meth-6655638.patch old/meth-6815692.patch old/meth-api-6981777.patch old/meth-asm-6812678.patch old/meth-bcon-nary.patch old/meth-bcp-6939196.patch old/meth-bsme-7049415.patch old/meth-ci-7009600.patch old/meth-enable-6817525.patch old/meth-err-7012087.patch old/meth-ilookup-6812831.patch old/meth-impl-6839872.patch old/meth-ing-6939134.patch old/meth-ing-6939224.patch old/meth-ing-6994093.patch old/meth-ing-7049410.patch old/meth-lazy-7023639.jit.patch old/meth-lazy.txt old/meth-ldc-6939203.patch old/meth-ldc-6960865.patch old/meth-mhw-7047961.patch old/meth-minor-6814659.patch old/meth-rename-7012648.patch old/meth-subtype-6813212.patch old/meth-ver-6987991.patch old/meth.fixes.patch old/meth.txt old/meth.walker-6894206.patch old/meth.walker.fixes-6914206.patch old/nonperm.txt old/oops-7028374.patch old/post-6939930-adjust.patch old/reset-thread-mh-flag-6941529.patch old/trustfinal-6912065.patch
diffstat 94 files changed, 46218 insertions(+), 93022 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-syntax: glob
-status
-guards
--- a/annot.txt	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-6711908: JVM needs direct access to some annotations
-Summary: Add annotation extraction code to class file parser.
-Contributed-by: jrose, michael.haupt@oracle.com
-
-http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6711908
-
-Features:
-- skips most annotations, including unknown ones
-- looks for hardwired annotations significant to the VM
-- initial annotation type will be something like sun.misc.CompilerAdvice
-
-The initial version of the patch has the check for annotation type faked.
-
-The interfaces will be VM private, at least to start with.
--- a/anonk.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1188 +0,0 @@
-diff --git a/src/share/vm/ci/ciEnv.cpp b/src/share/vm/ci/ciEnv.cpp
---- a/src/share/vm/ci/ciEnv.cpp
-+++ b/src/share/vm/ci/ciEnv.cpp
-@@ -484,11 +484,16 @@
-   } else if (tag.is_double()) {
-     return ciConstant((jdouble)cpool->double_at(index));
-   } else if (tag.is_string() || tag.is_unresolved_string()) {
--    oop string = cpool->string_at(index, THREAD);
--    if (HAS_PENDING_EXCEPTION) {
--      CLEAR_PENDING_EXCEPTION;
--      record_out_of_memory_failure();
--      return ciConstant();
-+    oop string = NULL;
-+    if (cpool->is_pseudo_string_at(index)) {
-+      string = cpool->pseudo_string_at(index);
-+    } else {
-+      string = cpool->string_at(index, THREAD);
-+      if (HAS_PENDING_EXCEPTION) {
-+        CLEAR_PENDING_EXCEPTION;
-+        record_out_of_memory_failure();
-+        return ciConstant();
-+      }
-     }
-     ciObject* constant = get_object(string);
-     assert (constant->is_instance(), "must be an instance, or not? ");
-diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
---- a/src/share/vm/classfile/classFileParser.cpp
-+++ b/src/share/vm/classfile/classFileParser.cpp
-@@ -168,9 +168,21 @@
-           // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
-           cfs->guarantee_more(utf8_length+1, CHECK);  // utf8 string, tag/access_flags
-           cfs->skip_u1_fast(utf8_length);
-+
-           // Before storing the symbol, make sure it's legal
-           if (_need_verify) {
-             verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
-+          }
-+
-+          if (AnonymousClasses && has_cp_patch_at(index)) {
-+            Handle patch = clear_cp_patch_at(index);
-+            guarantee_property(java_lang_String::is_instance(patch()),
-+                               "Illegal utf8 patch at %d in class file %s",
-+                               index, CHECK);
-+            char* str = java_lang_String::as_utf8_string(patch());
-+            // (could use java_lang_String::as_symbol instead, but might as well batch them)
-+            utf8_buffer = (u1*) str;
-+            utf8_length = (int) strlen(str);
-           }
- 
-           unsigned int hash;
-@@ -245,7 +257,7 @@
-         int klass_ref_index = cp->klass_ref_index_at(index);
-         int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
-         check_property(valid_cp_range(klass_ref_index, length) &&
--                       cp->tag_at(klass_ref_index).is_klass_reference(),
-+                       is_klass_reference(cp, klass_ref_index),
-                        "Invalid constant pool index %u in class file %s",
-                        klass_ref_index,
-                        CHECK_(nullHandle));
-@@ -326,16 +338,46 @@
-     } // end of switch
-   } // end of for
- 
-+  if (_cp_patches != NULL) {
-+    // need to treat this_class specially...
-+    assert(AnonymousClasses, "");
-+    int this_class_index;
-+    {
-+      cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len
-+      u1* mark = cfs->current();
-+      u2 flags         = cfs->get_u2_fast();
-+      this_class_index = cfs->get_u2_fast();
-+      cfs->set_current(mark);  // revert to mark
-+    }
-+
-+    for (index = 1; index < length; index++) {          // Index 0 is unused
-+      if (has_cp_patch_at(index)) {
-+        guarantee_property(index != this_class_index,
-+                           "Illegal constant pool patch to self at %d in class file %s",
-+                           index, CHECK_(nullHandle));
-+        patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
-+      }
-+    }
-+    // Ensure that all the patches have been used.
-+    for (index = 0; index < _cp_patches->length(); index++) {
-+      guarantee_property(!has_cp_patch_at(index),
-+                         "Unused constant pool patch at %d in class file %s",
-+                         index, CHECK_(nullHandle));
-+    }
-+  }
-+
-   if (!_need_verify) {
-     return cp;
-   }
- 
-   // second verification pass - checks the strings are of the right format.
-+  // but not yet to the other entries
-   for (index = 1; index < length; index++) {
-     jbyte tag = cp->tag_at(index).value();
-     switch (tag) {
-       case JVM_CONSTANT_UnresolvedClass: {
-         symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
-+        // check the name, even if _cp_patches will overwrite it
-         verify_legal_class_name(class_name, CHECK_(nullHandle));
-         break;
-       }
-@@ -378,6 +420,73 @@
- }
- 
- 
-+void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
-+  assert(AnonymousClasses, "");
-+  BasicType patch_type = T_VOID;
-+  switch (cp->tag_at(index).value()) {
-+
-+  case JVM_CONSTANT_UnresolvedClass :
-+    // Patching a class means pre-resolving it.
-+    // The name in the constant pool is ignored.
-+    if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance
-+      guarantee_property(!java_lang_Class::is_primitive(patch()),
-+                         "Illegal class patch at %d in class file %s",
-+                         index, CHECK);
-+      cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
-+    } else {
-+      guarantee_property(java_lang_String::is_instance(patch()),
-+                         "Illegal class patch at %d in class file %s",
-+                         index, CHECK);
-+      symbolHandle name = java_lang_String::as_symbol(patch(), CHECK);
-+      cp->unresolved_klass_at_put(index, name());
-+    }
-+    break;
-+
-+  case JVM_CONSTANT_UnresolvedString :
-+    // Patching a string means pre-resolving it.
-+    // The spelling in the constant pool is ignored.
-+    // The constant reference may be any object whatever.
-+    // If it is not a real interned string, the constant is referred
-+    // to as a "pseudo-string", and must be presented to the CP
-+    // explicitly, because it may require scavenging.
-+    cp->pseudo_string_at_put(index, patch());
-+    break;
-+
-+  case JVM_CONSTANT_Integer : patch_type = T_INT;    goto patch_prim;
-+  case JVM_CONSTANT_Float :   patch_type = T_FLOAT;  goto patch_prim;
-+  case JVM_CONSTANT_Long :    patch_type = T_LONG;   goto patch_prim;
-+  case JVM_CONSTANT_Double :  patch_type = T_DOUBLE; goto patch_prim;
-+  patch_prim:
-+    {
-+      jvalue value;
-+      BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
-+      guarantee_property(value_type == patch_type,
-+                         "Illegal primitive patch at %d in class file %s",
-+                         index, CHECK);
-+      switch (value_type) {
-+      case T_INT:    cp->int_at_put(index,   value.i); break;
-+      case T_FLOAT:  cp->float_at_put(index, value.f); break;
-+      case T_LONG:   cp->long_at_put(index,  value.j); break;
-+      case T_DOUBLE: cp->double_at_put(index, value.d); break;
-+      default:       assert(false, "");
-+      }
-+    }
-+    break;
-+
-+  default:
-+    // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
-+    guarantee_property(!has_cp_patch_at(index),
-+                       "Illegal unexpected patch at %d in class file %s",
-+                       index, CHECK);
-+    return;
-+  }
-+
-+  // On fall-through, mark the patch as used.
-+  clear_cp_patch_at(index);
-+}
-+
-+
-+
- class NameSigHash: public ResourceObj {
-  public:
-   symbolOop     _name;       // name
-@@ -448,25 +557,32 @@
-   int index;
-   for (index = 0; index < length; index++) {
-     u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
-+    KlassHandle interf;
-     check_property(
-       valid_cp_range(interface_index, cp->length()) &&
--        cp->tag_at(interface_index).is_unresolved_klass(),
-+      is_klass_reference(cp, interface_index),
-       "Interface name has bad constant pool index %u in class file %s",
-       interface_index, CHECK_(nullHandle));
--    symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
--
--    // Don't need to check legal name because it's checked when parsing constant pool.
--    // But need to make sure it's not an array type.
--    guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
--                       "Bad interface name in class file %s", CHECK_(nullHandle));
--
--    vmtimer->suspend();  // do not count recursive loading twice
--    // Call resolve_super so classcircularity is checked
--    klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
--                  unresolved_klass, class_loader, protection_domain,
--                  false, CHECK_(nullHandle));
--    KlassHandle interf (THREAD, k);
--    vmtimer->resume();
-+    if (cp->tag_at(interface_index).is_klass()) {
-+      interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
-+    } else {
-+      symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
-+
-+      // Don't need to check legal name because it's checked when parsing constant pool.
-+      // But need to make sure it's not an array type.
-+      guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
-+                         "Bad interface name in class file %s", CHECK_(nullHandle));
-+
-+      vmtimer->suspend();  // do not count recursive loading twice
-+      // Call resolve_super so classcircularity is checked
-+      klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
-+                    unresolved_klass, class_loader, protection_domain,
-+                    false, CHECK_(nullHandle));
-+      interf = KlassHandle(THREAD, k);
-+      vmtimer->resume();
-+
-+      cp->klass_at_put(interface_index, interf()); // eagerly resolve
-+    }
- 
-     if (!Klass::cast(interf())->is_interface()) {
-       THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
-@@ -877,8 +993,7 @@
-                          "Illegal exception table handler in class file %s", CHECK_(nullHandle));
-       if (catch_type_index != 0) {
-         guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
--                          (cp->tag_at(catch_type_index).is_klass() ||
--                           cp->tag_at(catch_type_index).is_unresolved_klass()),
-+                           is_klass_reference(cp, catch_type_index),
-                            "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
-       }
-     }
-@@ -1117,7 +1232,7 @@
-     } else if (tag == ITEM_Object) {
-       u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
-       guarantee_property(valid_cp_range(class_index, cp->length()) &&
--                         cp->tag_at(class_index).is_unresolved_klass(),
-+                         is_klass_reference(cp, class_index),
-                          "Bad class index %u in StackMap in class file %s",
-                          class_index, CHECK);
-     } else if (tag == ITEM_Uninitialized) {
-@@ -1183,7 +1298,7 @@
-       checked_exception = cfs->get_u2_fast();
-       check_property(
-         valid_cp_range(checked_exception, cp->length()) &&
--        cp->tag_at(checked_exception).is_klass_reference(),
-+        is_klass_reference(cp, checked_exception),
-         "Exception name has bad type at constant pool %u in class file %s",
-         checked_exception, CHECK_NULL);
-     }
-@@ -1918,7 +2033,7 @@
-     check_property(
-       inner_class_info_index == 0 ||
-         (valid_cp_range(inner_class_info_index, cp_size) &&
--        cp->tag_at(inner_class_info_index).is_klass_reference()),
-+        is_klass_reference(cp, inner_class_info_index)),
-       "inner_class_info_index %u has bad constant type in class file %s",
-       inner_class_info_index, CHECK_0);
-     // Outer class index
-@@ -1926,7 +2041,7 @@
-     check_property(
-       outer_class_info_index == 0 ||
-         (valid_cp_range(outer_class_info_index, cp_size) &&
--        cp->tag_at(outer_class_info_index).is_klass_reference()),
-+        is_klass_reference(cp, outer_class_info_index)),
-       "outer_class_info_index %u has bad constant type in class file %s",
-       outer_class_info_index, CHECK_0);
-     // Inner class name
-@@ -2088,7 +2203,7 @@
-         }
-         // Validate the constant pool indices and types
-         if (!cp->is_within_bounds(class_index) ||
--            !cp->tag_at(class_index).is_klass_reference()) {
-+            !is_klass_reference(cp, class_index)) {
-           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
-         }
-         if (method_index != 0 &&
-@@ -2349,6 +2464,7 @@
- instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
-                                                     Handle class_loader,
-                                                     Handle protection_domain,
-+                                                    GrowableArray<Handle>* cp_patches,
-                                                     symbolHandle& parsed_name,
-                                                     TRAPS) {
-   // So that JVMTI can cache class file in the state before retransformable agents
-@@ -2380,6 +2496,7 @@
-     }
-   }
- 
-+  _cp_patches = cp_patches;
- 
-   instanceKlassHandle nullHandle;
- 
-@@ -2510,14 +2627,22 @@
-                      CHECK_(nullHandle));
-     } else {
-       check_property(valid_cp_range(super_class_index, cp_size) &&
--                     cp->tag_at(super_class_index).is_unresolved_klass(),
-+                     is_klass_reference(cp, super_class_index),
-                      "Invalid superclass index %u in class file %s",
-                      super_class_index,
-                      CHECK_(nullHandle));
-       // The class name should be legal because it is checked when parsing constant pool.
-       // However, make sure it is not an array type.
--      if (_need_verify) {
--        guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
-+      bool is_array = false;
-+      if (cp->tag_at(super_class_index).is_klass()) {
-+        super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
-+        if (_need_verify)
-+          is_array = super_klass->oop_is_array();
-+      } else if (_need_verify) {
-+        is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
-+      }
-+      if (_need_verify) {
-+        guarantee_property(!is_array,
-                           "Bad superclass name in class file %s", CHECK_(nullHandle));
-       }
-     }
-@@ -2557,7 +2682,7 @@
-     objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
- 
-     // We check super class after class file is parsed and format is checked
--    if (super_class_index > 0) {
-+    if (super_class_index > 0 && super_klass.is_null()) {
-       symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
-       if (access_flags.is_interface()) {
-         // Before attempting to resolve the superclass, check for class format
-@@ -2574,6 +2699,9 @@
-                                                            CHECK_(nullHandle));
-       KlassHandle kh (THREAD, k);
-       super_klass = instanceKlassHandle(THREAD, kh());
-+      cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
-+    }
-+    if (super_klass.not_null()) {
-       if (super_klass->is_interface()) {
-         ResourceMark rm(THREAD);
-         Exceptions::fthrow(
-@@ -3000,6 +3128,7 @@
-     this_klass->set_method_ordering(method_ordering());
-     this_klass->set_initial_method_idnum(methods->length());
-     this_klass->set_name(cp->klass_name_at(this_class_index));
-+    cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
-     this_klass->set_protection_domain(protection_domain());
-     this_klass->set_fields_annotations(fields_annotations());
-     this_klass->set_methods_annotations(methods_annotations());
-diff --git a/src/share/vm/classfile/classFileParser.hpp b/src/share/vm/classfile/classFileParser.hpp
---- a/src/share/vm/classfile/classFileParser.hpp
-+++ b/src/share/vm/classfile/classFileParser.hpp
-@@ -33,6 +33,7 @@
-   u2   _major_version;
-   u2   _minor_version;
-   symbolHandle _class_name;
-+  GrowableArray<Handle>* _cp_patches; // overrides for CP entries
- 
-   bool _has_finalizer;
-   bool _has_empty_finalizer;
-@@ -203,6 +204,35 @@
-   char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
-   char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
- 
-+  bool has_cp_patch_at(int index) {
-+    assert(AnonymousClasses, "");
-+    assert(index >= 0, "oob");
-+    return (_cp_patches != NULL
-+            && index < _cp_patches->length()
-+            && _cp_patches->adr_at(index)->not_null());
-+  }
-+  Handle cp_patch_at(int index) {
-+    assert(has_cp_patch_at(index), "oob");
-+    return _cp_patches->at(index);
-+  }
-+  Handle clear_cp_patch_at(int index) {
-+    Handle patch = cp_patch_at(index);
-+    _cp_patches->at_put(index, Handle());
-+    assert(!has_cp_patch_at(index), "");
-+    return patch;
-+  }
-+  void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
-+
-+  // Wrapper for constantTag.is_klass_[or_]reference.
-+  // In older versions of the VM, klassOops cannot sneak into early phases of
-+  // constant pool construction, but in later versions they can.
-+  // %%% Let's phase out the old is_klass_reference.
-+  bool is_klass_reference(constantPoolHandle cp, int index) {
-+    return ((LinkWellKnownClasses || AnonymousClasses)
-+            ? cp->tag_at(index).is_klass_or_reference()
-+            : cp->tag_at(index).is_klass_reference());
-+  }
-+
-  public:
-   // Constructor
-   ClassFileParser(ClassFileStream* st) { set_stream(st); }
-@@ -218,6 +248,14 @@
-                                      Handle class_loader,
-                                      Handle protection_domain,
-                                      symbolHandle& parsed_name,
-+                                     TRAPS) {
-+    return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD);
-+  }
-+  instanceKlassHandle parseClassFile(symbolHandle name,
-+                                     Handle class_loader,
-+                                     Handle protection_domain,
-+                                     GrowableArray<Handle>* cp_patches,
-+                                     symbolHandle& parsed_name,
-                                      TRAPS);
- 
-   // Verifier checks
-diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp
---- a/src/share/vm/classfile/systemDictionary.cpp
-+++ b/src/share/vm/classfile/systemDictionary.cpp
-@@ -937,6 +937,8 @@
-                                         Handle class_loader,
-                                         Handle protection_domain,
-                                         ClassFileStream* st,
-+                                        KlassHandle host_klass,
-+                                        GrowableArray<Handle>* cp_patches,
-                                         TRAPS) {
-   symbolHandle parsed_name;
- 
-@@ -953,9 +955,9 @@
-   instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
-                                                              class_loader,
-                                                              protection_domain,
-+                                                             cp_patches,
-                                                              parsed_name,
-                                                              THREAD);
--
- 
-   // We don't redefine the class, so we just need to clean up whether there
-   // was an error or not (don't want to modify any system dictionary
-@@ -970,6 +972,30 @@
-     MutexLocker mu(SystemDictionary_lock, THREAD);
-     placeholders()->find_and_remove(p_index, p_hash, parsed_name, class_loader, THREAD);
-     SystemDictionary_lock->notify_all();
-+    }
-+  }
-+
-+  if (host_klass.not_null() && k.not_null()) {
-+    assert(AnonymousClasses, "");
-+    // If it's anonymous, initialize it now, since nobody else will.
-+    k->set_host_klass(host_klass());
-+
-+    {
-+      MutexLocker mu_r(Compile_lock, THREAD);
-+
-+      // Add to class hierarchy, initialize vtables, and do possible
-+      // deoptimizations.
-+      add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
-+
-+      // But, do not add to system dictionary.
-+    }
-+
-+    k->eager_initialize(THREAD);
-+
-+    // notify jvmti
-+    if (JvmtiExport::should_post_class_load()) {
-+        assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
-+        JvmtiExport::post_class_load((JavaThread *) THREAD, k());
-     }
-   }
- 
-diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp
---- a/src/share/vm/classfile/systemDictionary.hpp
-+++ b/src/share/vm/classfile/systemDictionary.hpp
-@@ -228,6 +228,16 @@
-                                Handle class_loader,
-                                Handle protection_domain,
-                                ClassFileStream* st,
-+                               TRAPS) {
-+    KlassHandle nullHandle;
-+    return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD);
-+  }
-+  static klassOop parse_stream(symbolHandle class_name,
-+                               Handle class_loader,
-+                               Handle protection_domain,
-+                               ClassFileStream* st,
-+                               KlassHandle host_klass,
-+                               GrowableArray<Handle>* cp_patches,
-                                TRAPS);
- 
-   // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
-diff --git a/src/share/vm/classfile/verifier.cpp b/src/share/vm/classfile/verifier.cpp
---- a/src/share/vm/classfile/verifier.cpp
-+++ b/src/share/vm/classfile/verifier.cpp
-@@ -1600,7 +1600,11 @@
-     types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
-     verify_cp_type(index, cp, types, CHECK_VERIFY(this));
-   }
--  if (tag.is_string() || tag.is_unresolved_string()) {
-+  if (tag.is_string() && cp->is_pseudo_string_at(index)) {
-+    current_frame->push_stack(
-+      VerificationType::reference_type(
-+        vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
-+  } else if (tag.is_string() || tag.is_unresolved_string()) {
-     current_frame->push_stack(
-       VerificationType::reference_type(
-         vmSymbols::java_lang_String()), CHECK_VERIFY(this));
-diff --git a/src/share/vm/includeDB_gc_parallel b/src/share/vm/includeDB_gc_parallel
---- a/src/share/vm/includeDB_gc_parallel
-+++ b/src/share/vm/includeDB_gc_parallel
-@@ -29,6 +29,12 @@
- collectorPolicy.cpp                     cmsGCAdaptivePolicyCounters.hpp
- 
- compiledICHolderKlass.cpp               oop.pcgc.inline.hpp
-+
-+constantPoolKlass.cpp                   cardTableRS.hpp
-+constantPoolKlass.cpp                   oop.pcgc.inline.hpp
-+constantPoolKlass.cpp                   psPromotionManager.inline.hpp
-+constantPoolKlass.cpp                   psScavenge.inline.hpp
-+constantPoolKlass.cpp                   parOopClosures.inline.hpp
- 
- genCollectedHeap.cpp                    concurrentMarkSweepThread.hpp
- genCollectedHeap.cpp                    vmCMSOperations.hpp
-diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
---- a/src/share/vm/oops/constantPoolKlass.cpp
-+++ b/src/share/vm/oops/constantPoolKlass.cpp
-@@ -35,6 +35,7 @@
-   c->set_tags(NULL);
-   c->set_cache(NULL);
-   c->set_pool_holder(NULL);
-+  c->set_flags(0);
-   // only set to non-zero if constant pool is merged by RedefineClasses
-   c->set_orig_length(0);
-   // all fields are initialized; needed for GC
-@@ -261,10 +262,32 @@
- 
- void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
-   assert(obj->is_constantPool(), "should be constant pool");
-+  constantPoolOop cp = (constantPoolOop) obj;
-+  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
-+    oop* base = (oop*)cp->base();
-+    for (int i = 0; i < cp->length(); ++i, ++base) {
-+      if (cp->tag_at(i).is_string()) {
-+        if (PSScavenge::should_scavenge(base)) {
-+          pm->claim_or_forward_breadth(base);
-+        }
-+      }
-+    }
-+  }
- }
- 
- void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-   assert(obj->is_constantPool(), "should be constant pool");
-+  constantPoolOop cp = (constantPoolOop) obj;
-+  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
-+    oop* base = (oop*)cp->base();
-+    for (int i = 0; i < cp->length(); ++i, ++base) {
-+      if (cp->tag_at(i).is_string()) {
-+        if (PSScavenge::should_scavenge(base)) {
-+          pm->claim_or_forward_depth(base);
-+        }
-+      }
-+    }
-+  }
- }
- #endif // SERIALGC
- 
-@@ -278,6 +301,11 @@
-   assert(obj->is_constantPool(), "must be constantPool");
-   Klass::oop_print_on(obj, st);
-   constantPoolOop cp = constantPoolOop(obj);
-+  if (cp->flags() != 0) {
-+    st->print(" - flags : 0x%x", cp->flags());
-+    if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
-+    st->cr();
-+  }
- 
-   // Temp. remove cache so we can do lookups with original indicies.
-   constantPoolCacheHandle cache (THREAD, cp->cache());
-@@ -302,7 +330,11 @@
-         break;
-       case JVM_CONSTANT_UnresolvedString :
-       case JVM_CONSTANT_String :
--        anObj = cp->string_at(index, CATCH);
-+        if (cp->is_pseudo_string_at(index)) {
-+          anObj = cp->pseudo_string_at(index);
-+        } else {
-+          anObj = cp->string_at(index, CATCH);
-+        }
-         anObj->print_value_on(st);
-         st->print(" {0x%lx}", (address)anObj);
-         break;
-@@ -382,8 +414,12 @@
-                   "should be symbol or instance");
-       }
-       if (cp->tag_at(i).is_string()) {
--        guarantee((*base)->is_perm(),     "should be in permspace");
--        guarantee((*base)->is_instance(), "should be instance");
-+        if (!cp->has_pseudo_string()) {
-+          guarantee((*base)->is_perm(),   "should be in permspace");
-+          guarantee((*base)->is_instance(), "should be instance");
-+        } else {
-+          // can be non-perm, can be non-instance (array)
-+        }
-       }
-       base++;
-     }
-diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
---- a/src/share/vm/oops/constantPoolOop.cpp
-+++ b/src/share/vm/oops/constantPoolOop.cpp
-@@ -24,6 +24,18 @@
- 
- # include "incls/_precompiled.incl"
- # include "incls/_constantPoolOop.cpp.incl"
-+
-+void constantPoolOopDesc::set_flag_at(FlagBit fb) {
-+  const int MAX_STATE_CHANGES = 2;
-+  for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
-+    int oflags = _flags;
-+    int nflags = oflags | (1 << (int)fb);
-+    if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
-+      return;
-+  }
-+  assert(false, "failed to cmpxchg flags");
-+  _flags |= (1 << (int)fb);     // better than nothing
-+}
- 
- klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
-   // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
-@@ -333,8 +345,10 @@
-   oop entry = *(obj_at_addr(which));
-   if (entry->is_symbol()) {
-     return ((symbolOop)entry)->as_C_string();
-+  } else if (java_lang_String::is_instance(entry)) {
-+    return java_lang_String::as_utf8_string(entry);
-   } else {
--    return java_lang_String::as_utf8_string(entry);
-+    return (char*)"<pseudo-string>";
-   }
- }
- 
-@@ -382,6 +396,19 @@
-   }
-   assert(java_lang_String::is_instance(entry), "must be string");
-   return entry;
-+}
-+
-+
-+bool constantPoolOopDesc::is_pseudo_string_at(int which) {
-+  oop entry = *(obj_at_addr(which));
-+  if (entry->is_symbol())
-+    // Not yet resolved, but it will resolve to a string.
-+    return false;
-+  else if (java_lang_String::is_instance(entry))
-+    return false; // actually, it might be a non-interned or non-perm string
-+  else
-+    // truly pseudo
-+    return true;
- }
- 
- 
-diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
---- a/src/share/vm/oops/constantPoolOop.hpp
-+++ b/src/share/vm/oops/constantPoolOop.hpp
-@@ -41,6 +41,7 @@
-   typeArrayOop         _tags; // the tag array describing the constant pool's contents
-   constantPoolCacheOop _cache;         // the cache holding interpreter runtime information
-   klassOop             _pool_holder;   // the corresponding class
-+  int                  _flags;         // a few header bits to describe contents for GC
-   int                  _length; // number of elements in the array
-   // only set to non-zero if constant pool is merged by RedefineClasses
-   int                  _orig_length;
-@@ -48,6 +49,16 @@
-   void set_tags(typeArrayOop tags)             { oop_store_without_check((oop*)&_tags, tags); }
-   void tag_at_put(int which, jbyte t)          { tags()->byte_at_put(which, t); }
-   void release_tag_at_put(int which, jbyte t)  { tags()->release_byte_at_put(which, t); }
-+
-+  enum FlagBit {
-+    FB_has_pseudo_string = 2
-+  };
-+
-+  int flags() const                         { return _flags; }
-+  void set_flags(int f)                     { _flags = f; }
-+  bool flag_at(FlagBit fb) const            { return (_flags & (1 << (int)fb)) != 0; }
-+  void set_flag_at(FlagBit fb);
-+  // no clear_flag_at function; they only increase
- 
-  private:
-   intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
-@@ -81,6 +92,9 @@
- 
-  public:
-   typeArrayOop tags() const                 { return _tags; }
-+
-+  bool has_pseudo_string() const            { return flag_at(FB_has_pseudo_string); }
-+  void set_pseudo_string()                  {    set_flag_at(FB_has_pseudo_string); }
- 
-   // Klass holding pool
-   klassOop pool_holder() const              { return _pool_holder; }
-@@ -272,6 +286,27 @@
-     return string_at_impl(h_this, which, CHECK_NULL);
-   }
- 
-+  // A "pseudo-string" is an non-string oop that has found is way into
-+  // a String entry.
-+  // Under AnonymousClasses this can happen if the user patches a live
-+  // object into a CONSTANT_String entry of an anonymous class.
-+  // Method oops internally created for method handles may also
-+  // use pseudo-strings to link themselves to related metaobjects.
-+
-+  bool is_pseudo_string_at(int which);
-+
-+  oop pseudo_string_at(int which) {
-+    assert(tag_at(which).is_string(), "Corrupted constant pool");
-+    return *obj_at_addr(which);
-+  }
-+
-+  void pseudo_string_at_put(int which, oop x) {
-+    assert(AnonymousClasses, "");
-+    set_pseudo_string();        // mark header
-+    assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
-+    string_at_put(which, x);    // this works just fine
-+  }
-+
-   // only called when we are sure a string entry is already resolved (via an
-   // earlier string_at call.
-   oop resolved_string_at(int which) {
-@@ -293,6 +328,7 @@
-   // UTF8 char* representation was chosen to avoid conversion of
-   // java_lang_Strings at resolved entries into symbolOops
-   // or vice versa.
-+  // Caller is responsible for checking for pseudo-strings.
-   char* string_at_noresolve(int which);
- 
-   jint name_and_type_at(int which) {
-diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp
---- a/src/share/vm/oops/instanceKlass.hpp
-+++ b/src/share/vm/oops/instanceKlass.hpp
-@@ -147,6 +147,10 @@
-   oop             _class_loader;
-   // Protection domain.
-   oop             _protection_domain;
-+  // Host class, which grants its access privileges to this class also.
-+  // This is only non-null for an anonymous class (AnonymousClasses enabled).
-+  // The host class is either named, or a previously loaded anonymous class.
-+  klassOop        _host_klass;
-   // Class signers.
-   objArrayOop     _signers;
-   // Name of source file containing this klass, NULL if not specified.
-@@ -374,6 +378,11 @@
-   // protection domain
-   oop protection_domain()                  { return _protection_domain; }
-   void set_protection_domain(oop pd)       { oop_store((oop*) &_protection_domain, pd); }
-+
-+  // host class
-+  oop host_klass() const                   { return _host_klass; }
-+  void set_host_klass(oop host)            { oop_store((oop*) &_host_klass, host); }
-+  bool is_anonymous() const                { return _host_klass != NULL; }
- 
-   // signers
-   objArrayOop signers() const              { return _signers; }
-@@ -709,6 +718,7 @@
-   oop* adr_constants() const         { return (oop*)&this->_constants;}
-   oop* adr_class_loader() const      { return (oop*)&this->_class_loader;}
-   oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
-+  oop* adr_host_klass() const        { return (oop*)&this->_host_klass;}
-   oop* adr_signers() const           { return (oop*)&this->_signers;}
-   oop* adr_source_file_name() const  { return (oop*)&this->_source_file_name;}
-   oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
-diff --git a/src/share/vm/oops/instanceKlassKlass.cpp b/src/share/vm/oops/instanceKlassKlass.cpp
---- a/src/share/vm/oops/instanceKlassKlass.cpp
-+++ b/src/share/vm/oops/instanceKlassKlass.cpp
-@@ -81,6 +81,7 @@
-   MarkSweep::mark_and_push(ik->adr_source_debug_extension());
-   MarkSweep::mark_and_push(ik->adr_inner_classes());
-   MarkSweep::mark_and_push(ik->adr_protection_domain());
-+  MarkSweep::mark_and_push(ik->adr_host_klass());
-   MarkSweep::mark_and_push(ik->adr_signers());
-   MarkSweep::mark_and_push(ik->adr_generic_signature());
-   MarkSweep::mark_and_push(ik->adr_class_annotations());
-@@ -120,6 +121,7 @@
-   PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
-   PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
-   PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
-+  PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
-   PSParallelCompact::mark_and_push(cm, ik->adr_signers());
-   PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
-   PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
-@@ -159,6 +161,7 @@
-   blk->do_oop(ik->adr_constants());
-   blk->do_oop(ik->adr_class_loader());
-   blk->do_oop(ik->adr_protection_domain());
-+  blk->do_oop(ik->adr_host_klass());
-   blk->do_oop(ik->adr_signers());
-   blk->do_oop(ik->adr_source_file_name());
-   blk->do_oop(ik->adr_source_debug_extension());
-@@ -211,6 +214,8 @@
-   if (mr.contains(adr)) blk->do_oop(adr);
-   adr = ik->adr_protection_domain();
-   if (mr.contains(adr)) blk->do_oop(adr);
-+  adr = ik->adr_host_klass();
-+  if (mr.contains(adr)) blk->do_oop(adr);
-   adr = ik->adr_signers();
-   if (mr.contains(adr)) blk->do_oop(adr);
-   adr = ik->adr_source_file_name();
-@@ -260,6 +265,7 @@
-   MarkSweep::adjust_pointer(ik->adr_constants());
-   MarkSweep::adjust_pointer(ik->adr_class_loader());
-   MarkSweep::adjust_pointer(ik->adr_protection_domain());
-+  MarkSweep::adjust_pointer(ik->adr_host_klass());
-   MarkSweep::adjust_pointer(ik->adr_signers());
-   MarkSweep::adjust_pointer(ik->adr_source_file_name());
-   MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
-@@ -295,6 +301,11 @@
-     pm->claim_or_forward_breadth(pd_addr);
-   }
- 
-+  oop* hk_addr = ik->adr_host_klass();
-+  if (PSScavenge::should_scavenge(hk_addr)) {
-+    pm->claim_or_forward_breadth(hk_addr);
-+  }
-+
-   oop* sg_addr = ik->adr_signers();
-   if (PSScavenge::should_scavenge(sg_addr)) {
-     pm->claim_or_forward_breadth(sg_addr);
-@@ -316,6 +327,11 @@
-   oop* pd_addr = ik->adr_protection_domain();
-   if (PSScavenge::should_scavenge(pd_addr)) {
-     pm->claim_or_forward_depth(pd_addr);
-+  }
-+
-+  oop* hk_addr = ik->adr_host_klass();
-+  if (PSScavenge::should_scavenge(hk_addr)) {
-+    pm->claim_or_forward_depth(hk_addr);
-   }
- 
-   oop* sg_addr = ik->adr_signers();
-@@ -421,6 +437,7 @@
-     ik->set_constants(NULL);
-     ik->set_class_loader(NULL);
-     ik->set_protection_domain(NULL);
-+    ik->set_host_klass(NULL);
-     ik->set_signers(NULL);
-     ik->set_source_file_name(NULL);
-     ik->set_source_debug_extension(NULL);
-@@ -526,6 +543,7 @@
-   st->print(" - constants:         "); ik->constants()->print_value_on(st);         st->cr();
-   st->print(" - class loader:      "); ik->class_loader()->print_value_on(st);      st->cr();
-   st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
-+  st->print(" - host class: ");        ik->host_klass()->print_value_on(st);        st->cr();
-   st->print(" - signers:           "); ik->signers()->print_value_on(st);           st->cr();
-   if (ik->source_file_name() != NULL) {
-     st->print(" - source file:       ");
-@@ -626,7 +644,7 @@
-     ik->_verify_count = Universe::verify_count();
- #endif
-     // Verify that klass is present in SystemDictionary
--    if (ik->is_loaded()) {
-+    if (ik->is_loaded() && !ik->is_anonymous()) {
-       symbolHandle h_name (thread, ik->name());
-       Handle h_loader (thread, ik->class_loader());
-       Handle h_obj(thread, obj);
-@@ -764,6 +782,9 @@
-     if (ik->protection_domain() != NULL) {
-       guarantee(ik->protection_domain()->is_oop(),  "should be oop");
-     }
-+    if (ik->host_klass() != NULL) {
-+      guarantee(ik->host_klass()->is_oop(),  "should be oop");
-+    }
-     if (ik->signers() != NULL) {
-       guarantee(ik->signers()->is_objArray(),       "should be obj array");
-     }
-diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
---- a/src/share/vm/oops/klass.cpp
-+++ b/src/share/vm/oops/klass.cpp
-@@ -478,6 +478,24 @@
- 
- 
- const char* Klass::external_name() const {
-+  if (oop_is_instance()) {
-+    instanceKlass* ik = (instanceKlass*) this;
-+    if (ik->is_anonymous()) {
-+      assert(AnonymousClasses, "");
-+      intptr_t hash = ik->java_mirror()->identity_hash();
-+      char     hash_buf[40];
-+      sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
-+      size_t   hash_len = strlen(hash_buf);
-+
-+      size_t result_len = name()->utf8_length();
-+      char*  result     = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-+      name()->as_klass_external_name(result, (int) result_len + 1);
-+      assert(strlen(result) == result_len, "");
-+      strcpy(result + result_len, hash_buf);
-+      assert(strlen(result) == result_len + hash_len, "");
-+      return result;
-+    }
-+  }
-   return name()->as_klass_external_name();
- }
- 
-diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp
---- a/src/share/vm/prims/jvm.cpp
-+++ b/src/share/vm/prims/jvm.cpp
-@@ -744,6 +744,7 @@
- 
- // common code for JVM_DefineClass() and JVM_DefineClassWithSource()
- static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
-+  if (source == NULL)  source = "__JVM_DefineClass__";
- 
-   // Since exceptions can be thrown, class initialization can take place
-   // if name is NULL no check for class name in .class stream has to be made.
-@@ -782,7 +783,7 @@
- JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
-   JVMWrapper2("JVM_DefineClass %s", name);
- 
--  return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD);
-+  return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
- JVM_END
- 
- 
-diff --git a/src/share/vm/prims/jvm.h b/src/share/vm/prims/jvm.h
---- a/src/share/vm/prims/jvm.h
-+++ b/src/share/vm/prims/jvm.h
-@@ -421,6 +421,14 @@
- JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
-                           const jbyte *buf, jsize len, jobject pd,
-                           const char *source);
-+
-+/* Define a class with a source (MLVM) */
-+JNIEXPORT jclass JNICALL
-+JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
-+                      const jbyte *buf, jsize len, jobject pd,
-+                      const char *source,
-+                      // same args as JVM_DefineClassWithSource to this point
-+                      jobjectArray constants);
- 
- /*
-  * Reflection support functions
-diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp
---- a/src/share/vm/prims/unsafe.cpp
-+++ b/src/share/vm/prims/unsafe.cpp
-@@ -837,6 +837,163 @@
-   }
- UNSAFE_END
- 
-+#define DAC_Args CLS"[B["OBJ
-+// define a class but do not make it known to the class loader or system dictionary
-+// - host_class:  supplies context for linkage, access control, protection domain, and class loader
-+// - data:  bytes of a class file, a raw memory address (length gives the number of bytes)
-+// - cp_patches:  where non-null entries exist, they replace corresponding CP entries in data
-+
-+// When you load an anonymous class U, it works as if you changed its name just before loading,
-+// to a name that you will never use again.  Since the name is lost, no other class can directly
-+// link to any member of U.  Just after U is loaded, the only way to use it is reflectively,
-+// through java.lang.Class methods like Class.newInstance.
-+
-+// Access checks for linkage sites within U continue to follow the same rules as for named classes.
-+// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
-+// An anonymous class also has special privileges to access any member of its host class.
-+// This is the main reason why this loading operation is unsafe.  The purpose of this is to
-+// allow language implementations to simulate "open classes"; a host class in effect gets
-+// new code when an anonymous class is loaded alongside it.  A less convenient but more
-+// standard way to do this is with reflection, which can also be set to ignore access
-+// restrictions.
-+
-+// Access into an anonymous class is possible only through reflection.  Therefore, there
-+// are no special access rules for calling into an anonymous class.  The relaxed access
-+// rule for the host class is applied in the opposite direction:  A host class reflectively
-+// access one of its anonymous classes.
-+
-+// If you load the same bytecodes twice, you get two different classes.  You can reload
-+// the same bytecodes with or without varying CP patches.
-+
-+// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
-+// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
-+// The CONSTANT_Class entry for that name can be patched to refer directly to U1.
-+
-+// This allows, for example, U2 to use U1 as a superclass or super-interface, or as
-+// an outer class (so that U2 is an anonymous inner class of anonymous U1).
-+// It is not possible for a named class, or an older anonymous class, to refer by
-+// name (via its CP) to a newer anonymous class.
-+
-+// CP patching may also be used to modify (i.e., hack) the names of methods, classes,
-+// or type descriptors used in the loaded anonymous class.
-+
-+// Finally, CP patching may be used to introduce "live" objects into the constant pool,
-+// instead of "dead" strings.  A compiled statement like println((Object)"hello") can
-+// be changed to println(greeting), where greeting is an arbitrary object created before
-+// the anonymous class is loaded.  This is useful in dynamic languages, in which
-+// various kinds of metaobjects must be introduced as constants into bytecode.
-+// Note the cast (Object), which tells the verifier to expect an arbitrary object,
-+// not just a literal string.  For such ldc instructions, the verifier uses the
-+// type Object instead of String, if the loaded constant is not in fact a String.
-+
-+static oop
-+Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
-+                                 jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
-+                                 HeapWord* *temp_alloc,
-+                                 TRAPS) {
-+
-+  if (UsePerfData) {
-+    ClassLoader::unsafe_defineClassCallCounter()->inc();
-+  }
-+
-+  if (data == NULL) {
-+    THROW_0(vmSymbols::java_lang_NullPointerException());
-+  }
-+
-+  jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
-+  jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
-+  HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
-+  if (body == NULL) {
-+    THROW_0(vmSymbols::java_lang_OutOfMemoryError());
-+  }
-+
-+  // caller responsible to free it:
-+  (*temp_alloc) = body;
-+
-+  {
-+    jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
-+    Copy::conjoint_words((HeapWord*) array_base, body, word_length);
-+  }
-+
-+  u1* class_bytes = (u1*) body;
-+  int class_bytes_length = (int) length;
-+  if (class_bytes_length < 0)  class_bytes_length = 0;
-+  if (class_bytes == NULL
-+      || host_class == NULL
-+      || length != class_bytes_length)
-+    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
-+
-+  objArrayHandle cp_patches_h;
-+  if (cp_patches_jh != NULL) {
-+    oop p = JNIHandles::resolve_non_null(cp_patches_jh);
-+    if (!p->is_objArray())
-+      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
-+    cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
-+  }
-+
-+  KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
-+  const char* host_source = host_klass->external_name();
-+  Handle      host_loader(THREAD, host_klass->class_loader());
-+  Handle      host_domain(THREAD, host_klass->protection_domain());
-+
-+  GrowableArray<Handle>* cp_patches = NULL;
-+  if (cp_patches_h.not_null()) {
-+    int alen = cp_patches_h->length();
-+    for (int i = alen-1; i >= 0; i--) {
-+      oop p = cp_patches_h->obj_at(i);
-+      if (p != NULL) {
-+        Handle patch(THREAD, p);
-+        if (cp_patches == NULL)
-+          cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle());
-+        cp_patches->at_put(i, patch);
-+      }
-+    }
-+  }
-+
-+  ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
-+
-+  instanceKlassHandle anon_klass;
-+  {
-+    symbolHandle no_class_name;
-+    klassOop anonk = SystemDictionary::parse_stream(no_class_name,
-+                                                    host_loader, host_domain,
-+                                                    &st, host_klass, cp_patches,
-+                                                    CHECK_NULL);
-+    if (anonk == NULL)  return NULL;
-+    anon_klass = instanceKlassHandle(THREAD, anonk);
-+  }
-+
-+  // let caller initialize it as needed...
-+
-+  return anon_klass->java_mirror();
-+}
-+
-+UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
-+{
-+  UnsafeWrapper("Unsafe_DefineAnonymousClass");
-+  ResourceMark rm(THREAD);
-+
-+  HeapWord* temp_alloc = NULL;
-+
-+  jobject res_jh = NULL;
-+
-+  { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
-+                                                   host_class, data, cp_patches_jh,
-+                                                   &temp_alloc, THREAD);
-+    if (res_oop != NULL)
-+      res_jh = JNIHandles::make_local(env, res_oop);
-+  }
-+
-+  // try/finally clause:
-+  if (temp_alloc != NULL) {
-+    FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
-+  }
-+
-+  return (jclass) res_jh;
-+}
-+UNSAFE_END
-+
-+
- 
- UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
-   UnsafeWrapper("Unsafe_MonitorEnter");
-@@ -1292,6 +1449,9 @@
-     {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)}
- };
- 
-+JNINativeMethod anonk_methods[] = {
-+    {CC"defineAnonymousClass", CC"("DAC_Args")"CLS,      FN_PTR(Unsafe_DefineAnonymousClass)},
-+};
- 
- #undef CC
- #undef FN_PTR
-@@ -1354,6 +1514,15 @@
-         }
-       }
-     }
-+    if (AnonymousClasses) {
-+      env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
-+      if (env->ExceptionOccurred()) {
-+        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-+          tty->print_cr("Warning:  SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
-+        }
-+        env->ExceptionClear();
-+      }
-+    }
-     int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
-     if (env->ExceptionOccurred()) {
-       if (PrintMiscellaneous && (Verbose || WizardMode)) {
-diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
---- a/src/share/vm/runtime/globals.hpp
-+++ b/src/share/vm/runtime/globals.hpp
-@@ -3230,6 +3230,9 @@
-           "Skip assert() and verify() which page-in unwanted shared "       \
-           "objects. ")                                                      \
-                                                                             \
-+  product(bool, AnonymousClasses, false,                                    \
-+          "support sun.misc.Unsafe.defineAnonymousClass")                   \
-+                                                                            \
-   product(bool, TaggedStackInterpreter, false,                              \
-           "Insert tags in interpreter execution stack for oopmap generaion")\
-                                                                             \
-diff --git a/src/share/vm/runtime/reflection.cpp b/src/share/vm/runtime/reflection.cpp
---- a/src/share/vm/runtime/reflection.cpp
-+++ b/src/share/vm/runtime/reflection.cpp
-@@ -456,10 +456,32 @@
-   return can_relax_access_check_for(current_class, new_class, classloader_only);
- }
- 
-+static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
-+  DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
-+  for (;;) {
-+    klassOop hc = (klassOop) ik->host_klass();
-+    if (hc == NULL)        return false;
-+    if (hc == host_klass)  return true;
-+    ik = instanceKlass::cast(hc);
-+
-+    // There's no way to make a host class loop short of patching memory.
-+    // Therefore there cannot be a loop here unles there's another bug.
-+    // Still, let's check for it.
-+    assert(--inf_loop_check > 0, "no host_klass loop");
-+  }
-+}
-+
- bool Reflection::can_relax_access_check_for(
-     klassOop accessor, klassOop accessee, bool classloader_only) {
-   instanceKlass* accessor_ik = instanceKlass::cast(accessor);
-   instanceKlass* accessee_ik  = instanceKlass::cast(accessee);
-+
-+  // If either is on the other's host_klass chain, access is OK,
-+  // because one is inside the other.
-+  if (under_host_klass(accessor_ik, accessee) ||
-+      under_host_klass(accessee_ik, accessor))
-+    return true;
-+
-   if (RelaxAccessControlCheck ||
-       (accessor_ik->major_version() < JAVA_1_5_VERSION &&
-        accessee_ik->major_version() < JAVA_1_5_VERSION)) {
-diff --git a/src/share/vm/utilities/constantTag.hpp b/src/share/vm/utilities/constantTag.hpp
---- a/src/share/vm/utilities/constantTag.hpp
-+++ b/src/share/vm/utilities/constantTag.hpp
-@@ -71,6 +71,7 @@
-   bool is_string_index() const      { return _tag == JVM_CONSTANT_StringIndex; }
- 
-   bool is_klass_reference() const   { return is_klass_index() || is_unresolved_klass(); }
-+  bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
-   bool is_field_or_method() const   { return is_field() || is_method() || is_interface_method(); }
-   bool is_symbol() const            { return is_utf8(); }
- 
--- a/anonk.txt	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-6653858: dynamic languages need to be able to load anonymous classes 
-Summary: low-level privileged sun.misc.Unsafe.defineAnonymousClass
-
-http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6653858
-
-Features:
-- loads an arbitrary class from bytecodes
-- puts class in class hierarchy but *not* in any class loader
-- piggybacks on a "host class" as if it were an inner class
-- elements of the anonymous constant pool can be patched easily
-- string constants can be replaced by arbitrary objects in CP
-
-Tests:
-- jdk/test/java/dyn/AnonymousClassLoader/TestAnonK.java
-
-Why the patching stuff?  Mainly, it makes some use cases much easier.
-Second, the constant pool needed some internal patching anyway,
-to anonymize the loaded class itself.  Finally, if you are going
-to use this seriously, you'll want to build anonymous classes
-on top of pre-existing anonymous classes, and that requires patching.
-
-Incremental testing:
-This does not require a full JDK build.
-
-$ rm -rf build/bootcp
-$ mkdir -p build/bootcp
-
-$ files='
-sources/jdk/test/java/dyn/AnonymousClassLoader/*.java
-sources/jdk/src/share/classes/java/dyn/AnonymousClassLoader.java
-sources/jdk/src/share/classes/java/dyn/ConstantPool*.java
-sources/jdk/src/share/classes/java/dyn/InvalidConstantPoolFormatException.java
-sources/jdk/src/share/classes/sun/misc/Unsafe.java
-sources/jdk/src/share/classes/sun/reflect/Reflection.java
-'
-$ $JAVA_HOME/bin/javac -d build/bootcp $files
-$ $JAVA_HOME/bin/javac -XXaltjvm=?? -XX:+AnonymousClasses -Xbootclasspath/p:build/bootcp TestAnonK
--- a/asm/asm-jsr292-bsm.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-Make asm compatible with the output of this MLVM patch:
-  http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/indy-bsm-6964498.patch
-  http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/083fde3b838e
-
-Change comment:
-  6964498: JSR 292 invokedynamic sites need local bootstrap methods
-  Summary: Add JVM_CONSTANT_InvokeDynamic records to constant pool to determine per-instruction BSMs.
-
-Apply this patch after asm-jsr292-ldc.patch.
-
-diff --git a/src/org/objectweb/asm/ClassReader.java b/src/org/objectweb/asm/ClassReader.java
---- a/src/org/objectweb/asm/ClassReader.java
-+++ b/src/org/objectweb/asm/ClassReader.java
-@@ -126,8 +126,10 @@
-      * strategy could be extended to all constant pool items, but its benefit
-      * would not be so great for these items (because they are much less
-      * expensive to parse than CONSTANT_Utf8 items).
-+     * <p>
-+     * We also use this array to cache members.
-      */
--    private final String[] strings;
-+    private final Object[] strings;
- 
-     /**
-      * Maximum length of the strings contained in the constant pool of the
-@@ -166,7 +168,7 @@
-         // parses the constant pool
-         items = new int[readUnsignedShort(off + 8)];
-         int n = items.length;
--        strings = new String[n];
-+        strings = new Object[n];
-         int max = 0;
-         int index = off + 10;
-         for (int i = 1; i < n; ++i) {
-@@ -176,6 +178,7 @@
-                 case ClassWriter.FIELD:
-                 case ClassWriter.METH:
-                 case ClassWriter.IMETH:
-+                case ClassWriter.INDY:
-                 case ClassWriter.INT:
-                 case ClassWriter.FLOAT:
-                 case ClassWriter.NAME_TYPE:
-@@ -301,6 +304,13 @@
-                             readUTF8(nameType, buf),
-                             readUTF8(nameType + 2, buf));
-                     break;
-+                case ClassWriter.INDY:
-+                    nameType = items[readUnsignedShort(index + 2)];
-+                    item.set(tag,
-+                            readMethodHandle(index, buf).encoding(),
-+                            readUTF8(nameType, buf),
-+                            readUTF8(nameType + 2, buf));
-+                    break;
-                 case ClassWriter.INT:
-                     item.set(readInt(index));
-                     break;
-@@ -327,10 +337,10 @@
-                     break;
- 
-                 case ClassWriter.UTF8: {
--                    String s = strings[i];
-+                    String s = (String) strings[i];
-                     if (s == null) {
-                         index = items[i];
--                        s = strings[i] = readUTF(index + 2,
-+                        strings[i] = s = readUTF(index + 2,
-                                 readUnsignedShort(index),
-                                 buf);
-                     }
-@@ -1406,7 +1416,12 @@
-                             String iowner;
-                             // INVOKEDYNAMIC is receiverless
-                             if (opcode == Opcodes.INVOKEDYNAMIC) {
--                                iowner = Opcodes.INVOKEDYNAMIC_OWNER;
-+                                if (readByte(cpIndex - 1) != ClassWriter.INDY) {
-+                                    iowner = Opcodes.INVOKEDYNAMIC_OWNER;
-+                                } else {
-+                                    iowner = readMethodHandle(readUnsignedShort(cpIndex + 0), c).encoding();
-+                                    cpIndex = items[readUnsignedShort(cpIndex + 2)];
-+                                }
-                             } else {
-                                 iowner = readClass(cpIndex, c);
-                                 cpIndex = items[readUnsignedShort(cpIndex + 2)];
-@@ -1996,16 +2011,16 @@
-      */
-     public String readUTF8(int index, final char[] buf) {
-         int item = readUnsignedShort(index);
--        return getUTF8(item, buf);
--    }
--
--    private String getUTF8(int item, final char[] buf) {
--        String s = strings[item];
-+        String s = (String) strings[item];
-         if (s != null) {
-             return s;
-         }
--        int index = items[item];
--        return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
-+        strings[item] = s = getUTF8(items[item], buf);
-+        return s;
-+    }
-+
-+    private String getUTF8(int index, final char[] buf) {
-+        return readUTF(index + 2, readUnsignedShort(index), buf);
-     }
- 
-     /**
-@@ -2087,6 +2102,8 @@
-     public Object readConst(final int item, final char[] buf) {
-         int index = items[item];
-         if (index == 0)  return null;
-+        Object obj = strings[item];
-+        if (obj != null)  return obj;
-         int tag = b[index - 1];
-         switch (tag) {
-             case ClassWriter.INT:
-@@ -2104,7 +2121,7 @@
-             case ClassWriter.STR:
-                 return readUTF8(index, buf);
-             case ClassWriter.UTF8:
--                return getUTF8(item, buf);
-+                return strings[item] = getUTF8(index, buf);
-             case ClassWriter.FIELD:
-             case ClassWriter.METH:
-                 return getMemberConst(tag, index, buf);
-@@ -2116,17 +2133,36 @@
-                                   readUTF8(index + 2, buf));
-             case ClassWriter.MHANDLE:
-                 return getMethodHandle(index, buf);
-+            case ClassWriter.INDY:
-+                return getInvokeDynamic(index, buf);
-             default:
-                 return "<Unknown Item>";
-         }
-     }
- 
-+    private Member readMethodHandle(int item, char[] buf) {
-+        Object mh = strings[item];
-+        if (mh == null) {
-+            strings[item] = mh = getMethodHandle(items[item], buf);
-+        }
-+        return (Member) mh;
-+    }
-+
-     private Object getMethodHandle(int index, char[] buf) {
-         return getMemberConst(Member.methodHandleTag(readByte(index)),
-                               items[readUnsignedShort(index + 1)],
-                               buf);
-     }
- 
-+    private Object getInvokeDynamic(int index, char[] buf) {
-+        int bsmItem = readUnsignedShort(index + 0);
-+        int nameTypeIndex = items[readUnsignedShort(index + 2)];
-+        return new Member(readMethodHandle(bsmItem, buf),
-+                          readUTF8(nameTypeIndex + 0, buf),
-+                          readUTF8(nameTypeIndex + 2, buf),
-+                          ClassWriter.INDY);
-+    }
-+
-     private Object getMemberConst(int tag, int index, char[] buf) {
-         String owner = readClass(index + 0, buf);
-         int nameTypeIndex = items[readUnsignedShort(index + 2)];
-@@ -2134,6 +2170,5 @@
-                           readUTF8(nameTypeIndex + 0, buf),
-                           readUTF8(nameTypeIndex + 2, buf),
-                           tag);
--
-     }
- }
-diff --git a/src/org/objectweb/asm/ClassWriter.java b/src/org/objectweb/asm/ClassWriter.java
---- a/src/org/objectweb/asm/ClassWriter.java
-+++ b/src/org/objectweb/asm/ClassWriter.java
-@@ -227,6 +227,11 @@
-     static final int MTYPE = Opcodes.CONSTANT_MethodType;
-  
-     /**
-+     * The type of CONSTANT_InvokeDynamic constant pool items.
-+     */
-+    static final int INDY = Opcodes.CONSTANT_InvokeDynamic;
-+ 
-+    /**
-      * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
-      * instead of the constant pool, in order to avoid clashes with normal
-      * constant pool items in the ClassWriter constant pool's hash table.
-diff --git a/src/org/objectweb/asm/Item.java b/src/org/objectweb/asm/Item.java
---- a/src/org/objectweb/asm/Item.java
-+++ b/src/org/objectweb/asm/Item.java
-@@ -51,6 +51,7 @@
-      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
-      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
-      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
-+     * {@link ClassWriter#INDY},
-      * {@link ClassWriter#MTYPE}, or a result of {@link ClassWriter#methodHandleTag(int)}
-      * 
-      * Special Item types are used for Items that are stored in the ClassWriter
-diff --git a/src/org/objectweb/asm/Member.java b/src/org/objectweb/asm/Member.java
---- a/src/org/objectweb/asm/Member.java
-+++ b/src/org/objectweb/asm/Member.java
-@@ -45,9 +45,9 @@
-     // ------------------------------------------------------------------------
- 
-     /**
--     * The containing type.
-+     * The containing type or member.
-      */
--    private final Type owner;
-+    private final Object owner;
- 
-     /**
-      * The name of the member.
-@@ -112,6 +112,14 @@
-              tag);
-     }
- 
-+    public Member(Member owner, String name, String type, int tag) {
-+        if (tag == 0)  badArg(tag);
-+        this.owner = owner;
-+        this.name = name;
-+        this.type = Type.getType(type);
-+        this.tag = tag;
-+    }
-+
-     // ------------------------------------------------------------------------
-     // Accessors
-     // ------------------------------------------------------------------------
-@@ -119,7 +127,7 @@
-     /**
-      * Returns the owner of this member, or null if there is none.
-      */
--    public Type getOwner() {
-+    public Object getOwner() {
-         return owner;
-     }
- 
-@@ -226,9 +234,14 @@
-             else
-                 buf.append("<").append(modeName(mode)).append("> ");
-         }
--        if (owner != null) {
--            owner.getInternalName(buf);
-+        if (owner instanceof Type) {
-+            ((Type)owner).getInternalName(buf);
-             buf.append('.');
-+        } else if (owner instanceof Member) {
-+            buf.append('<');
-+            ((Member)owner).encode(buf, pretty);
-+            buf.append('>');
-+            if (pretty)  buf.append(' ');
-         }
-         buf.append(name);
-         if (!pretty) {
-@@ -278,6 +291,7 @@
-             case Opcodes.CONSTANT_NameAndType:   return "NameAndType";
-             case Opcodes.CONSTANT_MethodHandle:  return "MethodHandle";
-             case Opcodes.CONSTANT_MethodType:    return "MethodType";
-+            case Opcodes.CONSTANT_InvokeDynamic: return "InvokeDynamic";
-         }
-         if ((tag & 0xFF) == Opcodes.CONSTANT_MethodHandle) {
-             return "MethodHandle/"+modeName(methodHandleTagKind(tag));
-diff --git a/src/org/objectweb/asm/Opcodes.java b/src/org/objectweb/asm/Opcodes.java
---- a/src/org/objectweb/asm/Opcodes.java
-+++ b/src/org/objectweb/asm/Opcodes.java
-@@ -103,6 +103,7 @@
-     int CONSTANT_NameAndType = 12;
-     int CONSTANT_MethodHandle = 15;  // JSR 292
-     int CONSTANT_MethodType = 16;  // JSR 292
-+    int CONSTANT_InvokeDynamic = 17;  // JSR 292
- 
-     // CONSTANT_MethodHandle constant pool items have a subtype tag
-     int REF_getField = 1;
--- a/asm/asm-jsr292-ldc.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1225 +0,0 @@
-Make asm compatible with the bytecodes defined by this JVM change:
-  http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/136b78722a08
-  http://hg.openjdk.java.net/mlvm/mlvm/hotspot/file/tip/meth-ldc-6939203.patch
-
-Change comment:
-  6939203: JSR 292 needs method handle constants
-  Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode.
-
-Apply this patch before asm-jsr292-bsm.patch.
-
-diff --git a/src/org/objectweb/asm/ClassReader.java b/src/org/objectweb/asm/ClassReader.java
---- a/src/org/objectweb/asm/ClassReader.java
-+++ b/src/org/objectweb/asm/ClassReader.java
-@@ -31,6 +31,7 @@
- 
- import java.io.InputStream;
- import java.io.IOException;
-+import java.util.Arrays;
- 
- /**
-  * A Java class parser to make a {@link ClassVisitor} visit an existing class.
-@@ -191,7 +192,11 @@
-                         max = size;
-                     }
-                     break;
-+                case ClassWriter.MHANDLE:
-+                    size = 4;
-+                    break;
-                 // case ClassWriter.CLASS:
-+                // case ClassWriter.MTYPE:
-                 // case ClassWriter.STR:
-                 default:
-                     size = 3;
-@@ -283,6 +288,10 @@
-             Item item = new Item(i);
-             int nameType;
-             switch (tag) {
-+                case ClassWriter.MHANDLE:
-+                    tag = Member.methodHandleTag(readByte(index));
-+                    index = items[readUnsignedShort(index + 1)];
-+                    // fall through:
-                 case ClassWriter.FIELD:
-                 case ClassWriter.METH:
-                 case ClassWriter.IMETH:
-@@ -292,7 +301,6 @@
-                             readUTF8(nameType, buf),
-                             readUTF8(nameType + 2, buf));
-                     break;
--
-                 case ClassWriter.INT:
-                     item.set(readInt(index));
-                     break;
-@@ -332,6 +340,7 @@
- 
-                 // case ClassWriter.STR:
-                 // case ClassWriter.CLASS:
-+                // case ClassWriter.MTYPE:
-                 default:
-                     item.set(tag, readUTF8(index, buf), null, null);
-                     break;
-@@ -1496,6 +1505,40 @@
-     }
- 
-     /**
-+     * Makes the given visitor visit the Java constant pool of this {@link ClassReader}.
-+     *
-+     * @param poolVisitor the visitor that must visit this class.
-+     */
-+    public void acceptPoolVisitor(final ConstantPoolVisitor poolVisitor) {
-+        acceptPoolVisitor(poolVisitor, -1);
-+    }
-+
-+    /**
-+     * Makes the given visitor visit the Java constant pool of this {@link ClassReader}.
-+     *
-+     * @param poolVisitor the visitor that must visit this class.
-+     * @param tagFilter bit-encoded set of constant types to visit (-1 means all, 0 means none, 2 means UTF8 only, etc.)
-+     */
-+    public void acceptPoolVisitor(final ConstantPoolVisitor poolVisitor, final int tagFilter) {
-+        char[] buf = new char[maxStringLength];
-+        int len = getItemLength();
-+        poolVisitor.visitPool(len);
-+        if (tagFilter != 0) {
-+            for (int i = 0; i < len; i++) {
-+                int pos = getItem(i);
-+                if (pos == 0)  continue;
-+                int tag = b[pos-1];
-+                int bitpos = tag;
-+                if (bitpos > 31)  bitpos = 31;  // sign bit
-+                if (((tagFilter >> bitpos) & 1) == 0)  continue;
-+                Object value = readConst(i, buf);
-+                poolVisitor.visitPoolConstant(i, tag, value);
-+            }
-+        }
-+        poolVisitor.visitPoolEnd();
-+    }
-+
-+    /**
-      * Reads parameter annotations and makes the given visitor visit them.
-      * 
-      * @param v start offset in {@link #b b} of the annotations to be read.
-@@ -1864,6 +1907,16 @@
-         return items[item];
-     }
- 
-+    /** Limit to the parameter of {@link #getItem}. */
-+    public int getItemLength() {
-+        return items.length;
-+    }
-+
-+    /** How long should buffers be? */
-+    public int getBufLength() {
-+        return maxStringLength;
-+    }
-+
-     /**
-      * Reads a byte value in {@link #b b}. <i>This method is intended for
-      * {@link Attribute} sub classes, and is normally not needed by class
-@@ -1943,11 +1996,15 @@
-      */
-     public String readUTF8(int index, final char[] buf) {
-         int item = readUnsignedShort(index);
-+        return getUTF8(item, buf);
-+    }
-+
-+    private String getUTF8(int item, final char[] buf) {
-         String s = strings[item];
-         if (s != null) {
-             return s;
-         }
--        index = items[item];
-+        int index = items[item];
-         return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
-     }
- 
-@@ -2029,7 +2086,9 @@
-      */
-     public Object readConst(final int item, final char[] buf) {
-         int index = items[item];
--        switch (b[index - 1]) {
-+        if (index == 0)  return null;
-+        int tag = b[index - 1];
-+        switch (tag) {
-             case ClassWriter.INT:
-                 return new Integer(readInt(index));
-             case ClassWriter.FLOAT:
-@@ -2040,9 +2099,41 @@
-                 return new Double(Double.longBitsToDouble(readLong(index)));
-             case ClassWriter.CLASS:
-                 return Type.getObjectType(readUTF8(index, buf));
--                // case ClassWriter.STR:
-+            case ClassWriter.MTYPE:
-+                return Type.getType(readUTF8(index, buf));
-+            case ClassWriter.STR:
-+                return readUTF8(index, buf);
-+            case ClassWriter.UTF8:
-+                return getUTF8(item, buf);
-+            case ClassWriter.FIELD:
-+            case ClassWriter.METH:
-+                return getMemberConst(tag, index, buf);
-+            case ClassWriter.IMETH:
-+                return getMemberConst(ClassWriter.METH, index, buf);
-+            case ClassWriter.NAME_TYPE:
-+                return new Member(null,
-+                                  readUTF8(index + 0, buf),
-+                                  readUTF8(index + 2, buf));
-+            case ClassWriter.MHANDLE:
-+                return getMethodHandle(index, buf);
-             default:
--                return readUTF8(index, buf);
-+                return "<Unknown Item>";
-         }
-     }
-+
-+    private Object getMethodHandle(int index, char[] buf) {
-+        return getMemberConst(Member.methodHandleTag(readByte(index)),
-+                              items[readUnsignedShort(index + 1)],
-+                              buf);
-+    }
-+
-+    private Object getMemberConst(int tag, int index, char[] buf) {
-+        String owner = readClass(index + 0, buf);
-+        int nameTypeIndex = items[readUnsignedShort(index + 2)];
-+        return new Member(owner,
-+                          readUTF8(nameTypeIndex + 0, buf),
-+                          readUTF8(nameTypeIndex + 2, buf),
-+                          tag);
-+
-+    }
- }
-diff --git a/src/org/objectweb/asm/ClassWriter.java b/src/org/objectweb/asm/ClassWriter.java
---- a/src/org/objectweb/asm/ClassWriter.java
-+++ b/src/org/objectweb/asm/ClassWriter.java
-@@ -164,64 +164,74 @@
-     /**
-      * The type of CONSTANT_Class constant pool items.
-      */
--    static final int CLASS = 7;
-+    static final int CLASS = Opcodes.CONSTANT_Class;
- 
-     /**
-      * The type of CONSTANT_Fieldref constant pool items.
-      */
--    static final int FIELD = 9;
-+    static final int FIELD = Opcodes.CONSTANT_Fieldref;
- 
-     /**
-      * The type of CONSTANT_Methodref constant pool items.
-      */
--    static final int METH = 10;
-+    static final int METH = Opcodes.CONSTANT_Methodref;
- 
-     /**
-      * The type of CONSTANT_InterfaceMethodref constant pool items.
-      */
--    static final int IMETH = 11;
-+    static final int IMETH = Opcodes.CONSTANT_InterfaceMethodref;
- 
-     /**
-      * The type of CONSTANT_String constant pool items.
-      */
--    static final int STR = 8;
-+    static final int STR = Opcodes.CONSTANT_String;
- 
-     /**
-      * The type of CONSTANT_Integer constant pool items.
-      */
--    static final int INT = 3;
-+    static final int INT = Opcodes.CONSTANT_Integer;
- 
-     /**
-      * The type of CONSTANT_Float constant pool items.
-      */
--    static final int FLOAT = 4;
-+    static final int FLOAT = Opcodes.CONSTANT_Float;
- 
-     /**
-      * The type of CONSTANT_Long constant pool items.
-      */
--    static final int LONG = 5;
-+    static final int LONG = Opcodes.CONSTANT_Long;
- 
-     /**
-      * The type of CONSTANT_Double constant pool items.
-      */
--    static final int DOUBLE = 6;
-+    static final int DOUBLE = Opcodes.CONSTANT_Double;
- 
-     /**
-      * The type of CONSTANT_NameAndType constant pool items.
-      */
--    static final int NAME_TYPE = 12;
-+    static final int NAME_TYPE = Opcodes.CONSTANT_NameAndType;
- 
-     /**
-      * The type of CONSTANT_Utf8 constant pool items.
-      */
--    static final int UTF8 = 1;
-+    static final int UTF8 = Opcodes.CONSTANT_Utf8;
- 
-     /**
-+     * The type of CONSTANT_MethodHandle constant pool items.
-+     */
-+    static final int MHANDLE = Opcodes.CONSTANT_MethodHandle;
-+
-+    /**
-+     * The type of CONSTANT_MethodType constant pool items.
-+     */
-+    static final int MTYPE = Opcodes.CONSTANT_MethodType;
-+ 
-+    /**
-      * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
-      * instead of the constant pool, in order to avoid clashes with normal
-      * constant pool items in the ClassWriter constant pool's hash table.
-      */
--    static final int TYPE_NORMAL = 13;
-+    static final int TYPE_NORMAL = 23;
- 
-     /**
-      * Uninitialized type Item stored in the ClassWriter
-@@ -229,14 +239,14 @@
-      * avoid clashes with normal constant pool items in the ClassWriter constant
-      * pool's hash table.
-      */
--    static final int TYPE_UNINIT = 14;
-+    static final int TYPE_UNINIT = 24;
- 
-     /**
-      * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
-      * instead of the constant pool, in order to avoid clashes with normal
-      * constant pool items in the ClassWriter constant pool's hash table.
-      */
--    static final int TYPE_MERGED = 15;
-+    static final int TYPE_MERGED = 25;
- 
-     /**
-      * The class reader from which this class writer was constructed, if any.
-@@ -284,6 +294,11 @@
-     final Item key3;
- 
-     /**
-+     * A reusable key used to look for items in the {@link #items} hash table.
-+     */
-+    final Item key4;
-+
-+    /**
-      * A type table used to temporarily store internal names that will not
-      * necessarily be stored in the constant pool. This type table is used by
-      * the control flow and data flow analysis algorithm used to compute stack
-@@ -546,6 +561,7 @@
-         key = new Item();
-         key2 = new Item();
-         key3 = new Item();
-+        key4 = new Item();
-         this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
-         this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
-     }
-@@ -903,7 +919,7 @@
-                     ? t.getInternalName()
-                     : t.getDescriptor());
-         } else {
--            throw new IllegalArgumentException("value " + cst);
-+            throw badArg(cst);
-         }
-     }
- 
-@@ -977,6 +993,39 @@
-     }
- 
-     /**
-+     * Adds a method type reference to the constant pool of the class being build.
-+     * Does nothing if the constant pool already contains a similar item.
-+     * <i>This method is intended for {@link Attribute} sub classes, and is
-+     * normally not needed by class generators or adapters.</i>
-+     *
-+     * @param value the internal name of the MethodType.
-+     * @return a new or already existing MethodType reference item.
-+     */
-+    Item newMethodTypeItem(final String value) {
-+        key2.set(MTYPE, value, null, null);
-+        Item result = get(key2);
-+        if (result == null) {
-+            pool.put12(MTYPE, newUTF8(value));
-+            result = new Item(index++, key2);
-+            put(result);
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Adds a method type reference to the constant pool of the class being build.
-+     * Does nothing if the constant pool already contains a similar item.
-+     * <i>This method is intended for {@link Attribute} sub classes, and is
-+     * normally not needed by class generators or adapters.</i>
-+     *
-+     * @param value the internal name of the method type.
-+     * @return the index of a new or already existing method type reference item.
-+     */
-+    public int newMethodType(final String value) {
-+        return newMethodTypeItem(value).index;
-+    }
-+
-+    /**
-      * Adds a field reference to the constant pool of the class being build.
-      * Does nothing if the constant pool already contains a similar item.
-      *
-@@ -1062,6 +1111,60 @@
-     }
- 
-     /**
-+     * Adds a member reference to the constant pool of the class being build.
-+     * Does nothing if the constant pool already contains a similar item.
-+     *
-+     * @param owner the internal name of the member's owner class.
-+     * @param name the member's name.
-+     * @param desc the member's descriptor.
-+     * @param refKind the type of reference
-+     * @return a new or already existing method reference item.
-+     */
-+    Item newMethodHandleItem(
-+        final String owner,
-+        final String name,
-+        final String desc,
-+        final int refKind)
-+    {
-+        int type = Member.methodHandleTag(refKind);
-+        key4.set(type, owner, name, desc);
-+        Item result = get(key4);
-+        if (result == null) {
-+            int ref;
-+            if (refKind <= Opcodes.REF_putStatic) {
-+                ref = newField(owner, name, desc);
-+            } else {
-+                ref = newMethod(owner, name, desc, refKind == Opcodes.REF_invokeInterface);
-+            }
-+            put112(type, ref);
-+            result = new Item(index++, key4);
-+            put(result);
-+        }
-+        return result;
-+    }
-+
-+    /**
-+     * Adds a member reference to the constant pool of the class being build.
-+     * Does nothing if the constant pool already contains a similar item.
-+     * <i>This method is intended for {@link Attribute} sub classes, and is
-+     * normally not needed by class generators or adapters.</i>
-+     *
-+     * @param owner the internal name of the member's owner class.
-+     * @param name the member's name.
-+     * @param desc the member's descriptor.
-+     * @param refKind the type of reference
-+     * @return the index of a new or already existing method handle reference item.
-+     */
-+    public int newMethodHandle(
-+        final String owner,
-+        final String name,
-+        final String desc,
-+        final int refKind)
-+    {
-+        return newMethodHandleItem(owner, name, desc, refKind).index;
-+    }
-+
-+    /**
-      * Adds an integer to the constant pool of the class being build. Does
-      * nothing if the constant pool already contains a similar item.
-      *
-@@ -1356,6 +1459,10 @@
-         items[index] = i;
-     }
- 
-+    static private IllegalArgumentException badArg(Object value) {
-+        return new IllegalArgumentException("value " + value);
-+    }
-+
-     /**
-      * Puts one byte and two shorts into the constant pool.
-      *
-@@ -1364,6 +1471,20 @@
-      * @param s2 another short.
-      */
-     private void put122(final int b, final int s1, final int s2) {
-+        if (b != (b & 0xFF))  throw badArg(Integer.valueOf(b));
-         pool.put12(b, s1).putShort(s2);
-     }
-+
-+    /**
-+     * Puts two bytes and two shorts into the constant pool.
-+     *
-+     * @param b1b2 two bytes, packed into an int as b1 + b2*256.
-+     * @param s1 a short.
-+     * @param s2 another short.
-+     */
-+    private void put112(final int b1b2, final int s1) {
-+        if (b1b2 != (b1b2 & 0xFFFF) || (b1b2 & 0x00FF) == 0 || (b1b2 & 0xFF00) == 0)
-+            throw badArg(Integer.valueOf(b1b2));
-+        pool.putByte(b1b2 & 0xFF).put12(b1b2 >> 8, s1);
-+    }
- }
-diff --git a/src/org/objectweb/asm/ConstantPoolVisitor.java b/src/org/objectweb/asm/ConstantPoolVisitor.java
-new file mode 100644
---- /dev/null
-+++ b/src/org/objectweb/asm/ConstantPoolVisitor.java
-@@ -0,0 +1,63 @@
-+/***
-+ * ASM: a very small and fast Java bytecode manipulation framework
-+ * Copyright (c) 2000-2007 INRIA, France Telecom
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the copyright holders nor the names of its
-+ *    contributors may be used to endorse or promote products derived from
-+ *    this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+package org.objectweb.asm;
-+
-+/**
-+ * A visitor to visit a Java class constant pool.
-+ * The methods of this interface must be called
-+ * in the following order: <tt>visitPool</tt>
-+ * ( <tt>visitPoolConstant</tt> )* <tt>visitPoolEnd</tt>.
-+ * 
-+ * @author John R. Rose
-+ */
-+public interface ConstantPoolVisitor {
-+
-+    /**
-+     * Visits the header of the constant pool.
-+     * 
-+     * @param length the number of items of the constant pool, including holes (at least one)
-+     */
-+    void visitPool(int length);
-+
-+    /**
-+     * Visits a constant item
-+     *
-+     * @param item the number of the item being visited
-+     * @param tag the tag of this constant pool item, e.g., {@link Opcodes#CONSTANT_Class}.
-+     * @param value the constant value, in the form of an Integer, String, Type, Member, etc.
-+     */
-+    void visitPoolConstant(int item, int tag, Object value);
-+
-+    /**
-+     * Visits the end of the constant pool. This method, which is the last one to be
-+     * called, is used to inform the visitor that all the constants have been visited.
-+     */
-+    void visitPoolEnd();
-+}
-diff --git a/src/org/objectweb/asm/Item.java b/src/org/objectweb/asm/Item.java
---- a/src/org/objectweb/asm/Item.java
-+++ b/src/org/objectweb/asm/Item.java
-@@ -50,7 +50,8 @@
-      * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
-      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
-      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
--     * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}.
-+     * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
-+     * {@link ClassWriter#MTYPE}, or a result of {@link ClassWriter#methodHandleTag(int)}
-      * 
-      * Special Item types are used for Items that are stored in the ClassWriter
-      * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
-@@ -199,6 +200,7 @@
-             case ClassWriter.UTF8:
-             case ClassWriter.STR:
-             case ClassWriter.CLASS:
-+            case ClassWriter.MTYPE:
-             case ClassWriter.TYPE_NORMAL:
-                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
-                 return;
-@@ -209,6 +211,7 @@
-                 // ClassWriter.FIELD:
-                 // ClassWriter.METH:
-                 // ClassWriter.IMETH:
-+                // ClassWriter.MHANDLE:
-             default:
-                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
-                         * strVal2.hashCode() * strVal3.hashCode());
-@@ -229,6 +232,7 @@
-             case ClassWriter.UTF8:
-             case ClassWriter.STR:
-             case ClassWriter.CLASS:
-+            case ClassWriter.MTYPE:
-             case ClassWriter.TYPE_NORMAL:
-                 return i.strVal1.equals(strVal1);
-             case ClassWriter.TYPE_MERGED:
-@@ -245,6 +249,7 @@
-             // case ClassWriter.FIELD:
-             // case ClassWriter.METH:
-             // case ClassWriter.IMETH:
-+            // case ClassWriter.MHANDLE:
-             default:    
-                 return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
-                         && i.strVal3.equals(strVal3);
-diff --git a/src/org/objectweb/asm/Member.java b/src/org/objectweb/asm/Member.java
-new file mode 100644
---- /dev/null
-+++ b/src/org/objectweb/asm/Member.java
-@@ -0,0 +1,303 @@
-+/***
-+ * ASM: a very small and fast Java bytecode manipulation framework
-+ * Copyright (c) 2000-2007 INRIA, France Telecom
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the copyright holders nor the names of its
-+ *    contributors may be used to endorse or promote products derived from
-+ *    this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ * THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+package org.objectweb.asm;
-+
-+import java.lang.reflect.Constructor;
-+import java.lang.reflect.Method;
-+
-+/**
-+ * A Java class member. This class can be used to make it easier to manipulate
-+ * fields, methods, and method handles.
-+ * 
-+ * @author John R. Rose
-+ */
-+public class Member {
-+
-+    // ------------------------------------------------------------------------
-+    // Fields
-+    // ------------------------------------------------------------------------
-+
-+    /**
-+     * The containing type.
-+     */
-+    private final Type owner;
-+
-+    /**
-+     * The name of the member.
-+     */
-+    private final String name;
-+
-+    /**
-+     * The type of the member (METHOD, OBJECT, etc.)
-+     */
-+    private final Type type;
-+
-+    /**
-+     * A constant pool tag, one of FIELD, METH (not IMETH), NAME_TYPE, or (MHANDLE + refKind*256).
-+     */
-+    private final int tag;
-+
-+    /**
-+     * Cached unique string encoding for this member.
-+     */
-+    private String encoding;
-+
-+    // ------------------------------------------------------------------------
-+    // Constructors
-+    // ------------------------------------------------------------------------
-+
-+    /**
-+     * Constructs a member description.
-+     * @param owner the type in which this member occurs
-+     * @param name  the name of the member
-+     * @param type  the type of the member (method or field)
-+     */
-+    public Member(Type owner, String name, Type type) {
-+        this(owner, name, type, 0);
-+    }
-+
-+    /**
-+     * Constructs a member description.
-+     * @param owner the type in which this member occurs
-+     * @param name  the name of the member
-+     * @param type  the type of the member (method or field)
-+     * @param tag  the optional constant pool tag
-+     */
-+    public Member(Type owner, String name, Type type, int tag) {
-+        if (tag == 0) {
-+            // default tag depends on type:
-+            tag = (type.getSort() == Type.METHOD ? ClassWriter.METH : ClassWriter.FIELD);
-+        }
-+        this.owner = owner;
-+        this.name = name;
-+        this.type = type;
-+        this.tag = tag;
-+    }
-+
-+    public Member(String owner, String name, String type) {
-+        this(owner, name, type, 0);
-+    }
-+
-+    public Member(String owner, String name, String type, int tag) {
-+        this(owner == null ? null : Type.getObjectType(owner),
-+             name,
-+             type == null ? null : Type.getType(type),
-+             tag);
-+    }
-+
-+    // ------------------------------------------------------------------------
-+    // Accessors
-+    // ------------------------------------------------------------------------
-+
-+    /**
-+     * Returns the owner of this member, or null if there is none.
-+     */
-+    public Type getOwner() {
-+        return owner;
-+    }
-+
-+    /**
-+     * Returns the name of this member, or null if there is none.
-+     */
-+    public String getName() {
-+        return name;
-+    }
-+
-+    /**
-+     * Returns the type of this member, or null if there is none.
-+     */
-+    public Type getType() {
-+        return type;
-+    }
-+
-+    /**
-+     * Returns the tag of this member.
-+     */
-+    public int getTag() {
-+        return tag;
-+    }
-+
-+    // ------------------------------------------------------------------------
-+    // Equals, hashCode and toString
-+    // ------------------------------------------------------------------------
-+
-+    /**
-+     * Tests if the given object is equal to this member.
-+     * 
-+     * @param o the object to be compared to this member.
-+     * @return <tt>true</tt> if the given object is equal to this member.
-+     */
-+    public boolean equals(final Object o) {
-+        if (this == o) {
-+            return true;
-+        }
-+        if (!(o instanceof Member)) {
-+            return false;
-+        }
-+        Member that = (Member) o;
-+        return eq(this.owner, that.owner) &&
-+               eq(this.name, that.name) &&
-+               eq(this.type, that.type) &&
-+               this.tag == that.tag;
-+    }
-+
-+    private static boolean eq(Object x, Object y) {
-+        return (x == y) || (x != null && x.equals(y));
-+    }
-+
-+    /**
-+     * Returns a hash code value for this type.
-+     * 
-+     * @return a hash code value for this type.
-+     */
-+    public int hashCode() {
-+        int hc = tag;
-+        hc = hc*31 + (owner == null ? 0 : owner.hashCode());
-+        hc = hc*31 + (name == null ? 0 : name.hashCode());
-+        hc = hc*31 + (type == null ? 0 : type.hashCode());
-+        return hc;
-+    }
-+
-+    /**
-+     * Returns a string representation of this member.
-+     * The string will be of the form owner.name (descriptor) for a method
-+     * or owner.name : descriptor for a field.
-+     * If it is a method handle reference, the mode will be appended.
-+     * 
-+     * @return a string representation
-+     */
-+    public String toString() {
-+        return encode(new StringBuffer(), true).toString();
-+    }
-+
-+    /* @return a string representation which is unique to this member */
-+    public String encoding() {
-+        String s = encoding;
-+        if (s == null) {
-+            encoding = s = encode(new StringBuffer(), false).toString();
-+        }
-+        return s;
-+    }
-+
-+    /**
-+     * Write a string representation of this member to buf.
-+     * If pretty it will be the toString representation.
-+     * Otherwise, it will be a structured string that is
-+     * unique to this member, of the form "MODE.OWNER.NAME.TYPE".
-+     * The "MODE." prefix is present only for a method handle reference.
-+     * The "OWNER." prefix is not present for a bare NameAndType & type.
-+     * None of the strings contains the dot '.' character.
-+     * Qualified names are qualified with '/' slash.
-+     * The tag is not an explicit part of the encoding,
-+     * but could be deduced if necessary.
-+     */
-+    StringBuffer encode(StringBuffer buf, boolean pretty) {
-+        int mode = (tag >> 8);
-+        if (mode != 0) {
-+            if (!pretty)
-+                buf.append(modeName(mode)).append('.');
-+            else
-+                buf.append("<").append(modeName(mode)).append("> ");
-+        }
-+        if (owner != null) {
-+            owner.getInternalName(buf);
-+            buf.append('.');
-+        }
-+        buf.append(name);
-+        if (!pretty) {
-+            buf.append(".");
-+        } else if (type.getSort() == Type.METHOD) {
-+            buf.append(" ");
-+        } else {
-+            buf.append(" : ");
-+        }
-+        type.getDescriptor(buf);
-+        return buf;
-+    }
-+
-+    /** Create a composite tag for a CONSTANT_MethodHandle item. */
-+    static int methodHandleTag(int refKind) {
-+        if (refKind >= Opcodes.REF_getField
-+            && refKind <= Opcodes.REF_invokeInterface)
-+            return Opcodes.CONSTANT_MethodHandle + (refKind << 8);
-+        throw badArg(refKind);
-+    }
-+    /** Extract a subtype tag from a composite tag for a CONSTANT_MethodHandle item. */
-+    static int methodHandleTagKind(int tag) {
-+        if ((tag & 0xFF) == Opcodes.CONSTANT_MethodHandle
-+                && ((tag-0x100) >>> 8) < Opcodes.REF_invokeInterface)
-+            return (tag >> 8);
-+        throw badArg(tag);
-+    }
-+
-+    static private IllegalArgumentException badArg(int value) {
-+        return new IllegalArgumentException("value " + value);
-+    }
-+
-+    /** String value of a constant pool tag. */
-+    public static String tagName(int tag) {
-+        switch (tag) {
-+            case 0: return "None";
-+            case Opcodes.CONSTANT_Utf8:       return "Utf8";
-+            case Opcodes.CONSTANT_Integer:    return "Integer";
-+            case Opcodes.CONSTANT_Float:      return "Float";
-+            case Opcodes.CONSTANT_Long:       return "Long";
-+            case Opcodes.CONSTANT_Double:     return "Double";
-+            case Opcodes.CONSTANT_Class:      return "Class";
-+            case Opcodes.CONSTANT_String:     return "String";
-+            case Opcodes.CONSTANT_Fieldref:   return "Fieldref";
-+            case Opcodes.CONSTANT_Methodref:  return "Methodref";
-+            case Opcodes.CONSTANT_InterfaceMethodref:  return "InterfaceMethodref";
-+            case Opcodes.CONSTANT_NameAndType:   return "NameAndType";
-+            case Opcodes.CONSTANT_MethodHandle:  return "MethodHandle";
-+            case Opcodes.CONSTANT_MethodType:    return "MethodType";
-+        }
-+        if ((tag & 0xFF) == Opcodes.CONSTANT_MethodHandle) {
-+            return "MethodHandle/"+modeName(methodHandleTagKind(tag));
-+        }
-+        return "BadTag#"+tag;
-+    }
-+    /** String value ofa MethodHandle submode. */
-+    public static String modeName(int mode) {
-+        switch (mode) {
-+            case 0: return "NoMode";
-+            case Opcodes.REF_getField: return "getField";
-+            case Opcodes.REF_getStatic: return "getStatic";
-+            case Opcodes.REF_putField: return "putField";
-+            case Opcodes.REF_putStatic: return "putStatic";
-+            case Opcodes.REF_invokeVirtual: return "invokeVirtual";
-+            case Opcodes.REF_invokeStatic: return "invokeStatic";
-+            case Opcodes.REF_invokeSpecial: return "invokeSpecial";
-+            case Opcodes.REF_newInvokeSpecial: return "newInvokeSpecial";
-+            case Opcodes.REF_invokeInterface: return "invokeInterface";
-+        }
-+        return "BadMode#"+mode;
-+    }
-+}
-diff --git a/src/org/objectweb/asm/Opcodes.java b/src/org/objectweb/asm/Opcodes.java
---- a/src/org/objectweb/asm/Opcodes.java
-+++ b/src/org/objectweb/asm/Opcodes.java
-@@ -89,6 +89,32 @@
-     int T_INT = 10;
-     int T_LONG = 11;
- 
-+    // constant pool tags
-+    int CONSTANT_Utf8 = 1;
-+    int CONSTANT_Integer = 3;
-+    int CONSTANT_Float = 4;
-+    int CONSTANT_Long = 5;
-+    int CONSTANT_Double = 6;
-+    int CONSTANT_Class = 7;
-+    int CONSTANT_String = 8;
-+    int CONSTANT_Fieldref = 9;
-+    int CONSTANT_Methodref = 10;
-+    int CONSTANT_InterfaceMethodref = 11;
-+    int CONSTANT_NameAndType = 12;
-+    int CONSTANT_MethodHandle = 15;  // JSR 292
-+    int CONSTANT_MethodType = 16;  // JSR 292
-+
-+    // CONSTANT_MethodHandle constant pool items have a subtype tag
-+    int REF_getField = 1;
-+    int REF_getStatic = 2;
-+    int REF_putField = 3;
-+    int REF_putStatic = 4;
-+    int REF_invokeVirtual = 5;
-+    int REF_invokeStatic = 6;
-+    int REF_invokeSpecial = 7;
-+    int REF_newInvokeSpecial = 8;
-+    int REF_invokeInterface = 9;
-+
-     // stack map frame types
- 
-     /**
-@@ -138,7 +164,7 @@
-     /** 
-      * Represents a owner of an invokedynamic call.
-      */
--    String INVOKEDYNAMIC_OWNER = "java/lang/dyn/Dynamic";
-+    String INVOKEDYNAMIC_OWNER = "java/dyn/InvokeDynamic";
-     
-     // opcodes // visit method (- = idem)
- 
-diff --git a/src/org/objectweb/asm/Type.java b/src/org/objectweb/asm/Type.java
---- a/src/org/objectweb/asm/Type.java
-+++ b/src/org/objectweb/asm/Type.java
-@@ -97,6 +97,11 @@
-     public static final int OBJECT = 10;
- 
-     /**
-+     * The sort of method reference type. See {@link #getSort getSort}.
-+     */
-+    public static final int METHOD = 11;
-+
-+    /**
-      * The <tt>void</tt> type.
-      */
-     public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
-@@ -394,18 +399,21 @@
-                 return LONG_TYPE;
-             case 'D':
-                 return DOUBLE_TYPE;
-+            case '(':
-+                len = 1;
-+                while (buf[off + len] != ')') {
-+                    len += computeLen(buf, off + len);
-+                }
-+                len += 1;
-+                len += computeLen(buf, off + len);
-+                return new Type(METHOD, buf, off, len);
-             case '[':
-                 len = 1;
-                 while (buf[off + len] == '[') {
-                     ++len;
-                 }
--                if (buf[off + len] == 'L') {
--                    ++len;
--                    while (buf[off + len] != ';') {
--                        ++len;
--                    }
--                }
--                return new Type(ARRAY, buf, off, len + 1);
-+                len += computeLen(buf, off + len);
-+                return new Type(ARRAY, buf, off, len);
-                 // case 'L':
-             default:
-                 len = 1;
-@@ -416,6 +424,17 @@
-         }
-     }
- 
-+    private static int computeLen(char[] buf, int off) {
-+        if (buf[off] != 'L')  return 1;
-+        int len = 1;  // skip 'L'
-+        while (buf[off + len] != ';') {
-+            ++len;
-+        }
-+        ++len;  // skip semi also
-+        return len;
-+    }
-+
-+
-     // ------------------------------------------------------------------------
-     // Accessors
-     // ------------------------------------------------------------------------
-@@ -499,10 +518,12 @@
-      * array type. The internal name of a class is its fully qualified name (as
-      * returned by Class.getName(), where '.' are replaced by '/'. This method
-      * should only be used for an object or array type.
--     * 
-+     *
-      * @return the internal name of the class corresponding to this object type.
-      */
-     public String getInternalName() {
-+        if (buf == null)
-+            return "<" + getDescriptorChar() + ">";
-         return new String(buf, off, len);
-     }
- 
-@@ -516,6 +537,7 @@
-      * @return the descriptor corresponding to this Java type.
-      */
-     public String getDescriptor() {
-+        if (sort == METHOD)  return getInternalName();
-         StringBuffer buf = new StringBuffer();
-         getDescriptor(buf);
-         return buf.toString();
-@@ -545,21 +567,45 @@
-     }
- 
-     /**
-+     * Appends the internal name of this Java type to the given
-+     * string buffer.
-+     * 
-+     * For primitives, it is a single letter in angle brackets, such as '&lt;I&gt;'.
-+     *
-+     * @param buf the string buffer to which the descriptor must be appended.
-+     */
-+    public void getInternalName(final StringBuffer buf) {
-+        if (this.buf == null)
-+            buf.append('<').append(getDescriptorChar()).append('>');
-+        else
-+            buf.append(this.buf, off, len);
-+    }
-+
-+    public char getDescriptorChar() {
-+        if (buf == null)
-+            return (char) ((off & 0xFF000000) >>> 24);
-+        else if (sort == OBJECT)
-+            return 'L';
-+        else
-+            return buf[0];
-+    }
-+
-+    /**
-      * Appends the descriptor corresponding to this Java type to the given
-      * string buffer.
-      * 
-      * @param buf the string buffer to which the descriptor must be appended.
-      */
--    private void getDescriptor(final StringBuffer buf) {
-+    void getDescriptor(final StringBuffer buf) {
-         if (this.buf == null) {
-             // descriptor is in byte 3 of 'off' for primitive types (buf == null)
--            buf.append((char) ((off & 0xFF000000) >>> 24));
--        } else if (sort == ARRAY) {
--            buf.append(this.buf, off, len);
--        } else { // sort == OBJECT
-+            buf.append(getDescriptorChar());
-+        } else if (sort == OBJECT) {
-             buf.append('L');
-             buf.append(this.buf, off, len);
-             buf.append(';');
-+        } else { // sort == ARRAY, METHOD
-+            buf.append(this.buf, off, len);
-         }
-     }
- 
-@@ -582,7 +628,7 @@
- 
-     /**
-      * Returns the descriptor corresponding to the given Java type.
--     * 
-+     *
-      * @param c an object class, a primitive class or an array class.
-      * @return the descriptor corresponding to the given class.
-      */
-@@ -593,6 +639,23 @@
-     }
- 
-     /**
-+     * Returns the descriptor corresponding to the given Java method type.
-+     * 
-+     * @param c an array of types, with the return type first
-+     * @return the descriptor corresponding to the given type.
-+     */
-+    public static String getDescriptor(final Class ret, final Class[] params) {
-+        StringBuffer buf = new StringBuffer();
-+        buf.append('(');
-+        for (int i = 0; i < params.length; i++) {
-+            getDescriptor(buf, params[i]);
-+        }
-+        buf.append(')');
-+        getDescriptor(buf, ret);
-+        return buf.toString();
-+    }
-+
-+    /**
-      * Returns the descriptor corresponding to the given constructor.
-      * 
-      * @param c a {@link Constructor Constructor} object.
-@@ -733,7 +796,7 @@
-         if (sort != t.sort) {
-             return false;
-         }
--        if (sort == OBJECT || sort == ARRAY) {
-+        if (buf != null) {
-             if (len != t.len) {
-                 return false;
-             }
-@@ -753,7 +816,7 @@
-      */
-     public int hashCode() {
-         int hc = 13 * sort;
--        if (sort == OBJECT || sort == ARRAY) {
-+        if (buf != null) {
-             for (int i = off, end = i + len; i < end; i++) {
-                 hc = 17 * (hc + buf[i]);
-             }
-@@ -764,9 +827,9 @@
-     /**
-      * Returns a string representation of this type.
-      * 
--     * @return the descriptor of this type.
-+     * @return the internal name of this type.
-      */
-     public String toString() {
--        return getDescriptor();
-+        return getInternalName();
-     }
- }
-diff --git a/src/org/objectweb/asm/util/TraceClassVisitor.java b/src/org/objectweb/asm/util/TraceClassVisitor.java
---- a/src/org/objectweb/asm/util/TraceClassVisitor.java
-+++ b/src/org/objectweb/asm/util/TraceClassVisitor.java
-@@ -36,9 +36,11 @@
- import org.objectweb.asm.Attribute;
- import org.objectweb.asm.ClassReader;
- import org.objectweb.asm.ClassVisitor;
-+import org.objectweb.asm.ConstantPoolVisitor;
- import org.objectweb.asm.MethodVisitor;
- import org.objectweb.asm.Opcodes;
- import org.objectweb.asm.FieldVisitor;
-+import org.objectweb.asm.Member;
- import org.objectweb.asm.signature.SignatureReader;
- 
- /**
-@@ -92,7 +94,7 @@
-  * @author Eugene Kuleshov
-  */
- public class TraceClassVisitor extends TraceAbstractVisitor implements
--        ClassVisitor
-+        ClassVisitor, ConstantPoolVisitor
- {
- 
-     /**
-@@ -145,7 +147,9 @@
-         } else {
-             cr = new ClassReader(args[i]);
-         }
--        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)),
-+        TraceClassVisitor visitor = new TraceClassVisitor(new PrintWriter(System.out));
-+        cr.acceptPoolVisitor(visitor);
-+        cr.accept(visitor,
-                 getDefaultAttributes(),
-                 flags);
-     }
-@@ -468,6 +472,50 @@
-     }
- 
-     // ------------------------------------------------------------------------
-+    // Implementation of the ConstantPoolVisitor interface
-+    // ------------------------------------------------------------------------
-+
-+    public void visitPool(int length) {
-+        buf.setLength(0);
-+        buf.append("CONSTANTS {  // length=").append(length).append('\n');
-+        text.add(buf.toString());
-+        if (cv instanceof ConstantPoolVisitor)
-+            ((ConstantPoolVisitor)cv).visitPool(length);
-+    }
-+    
-+    public void visitPoolConstant(int item, int tag, Object value) {
-+        buf.setLength(0);
-+        buf.append("  ").append(item).append(" ");
-+        buf.append(Member.tagName(tag)).append(" : ");
-+        boolean done = false;
-+        if (value instanceof String) {
-+            String s = (String) value;
-+            for (int k = s.length() - 1; k >= 0; k--) {
-+                char c = s.charAt(k);
-+                if (!(Character.isJavaIdentifierPart(c)
-+                        || "/".indexOf(c) >= 0)) {
-+                    appendString(buf, (String) value);
-+                    done = true;
-+                    break;
-+                }
-+            }
-+        }
-+        if (!done)
-+            buf.append(value);
-+        buf.append('\n');
-+        text.add(buf.toString());
-+        if (cv instanceof ConstantPoolVisitor)
-+            ((ConstantPoolVisitor)cv).visitPoolConstant(item, tag, value);
-+    }
-+
-+    public void visitPoolEnd() {
-+        text.add("} //CONSTANTS\n");
-+        text.add("\n");
-+        if (cv instanceof ConstantPoolVisitor)
-+            ((ConstantPoolVisitor)cv).visitPoolEnd();
-+    }
-+
-+    // ------------------------------------------------------------------------
-     // Utility methods
-     // ------------------------------------------------------------------------
- 
-diff --git a/src/org/objectweb/asm/util/TraceMethodVisitor.java b/src/org/objectweb/asm/util/TraceMethodVisitor.java
---- a/src/org/objectweb/asm/util/TraceMethodVisitor.java
-+++ b/src/org/objectweb/asm/util/TraceMethodVisitor.java
-@@ -327,7 +327,11 @@
-         if (cst instanceof String) {
-             AbstractVisitor.appendString(buf, (String) cst);
-         } else if (cst instanceof Type) {
--            buf.append(((Type) cst).getDescriptor()).append(".class");
-+            Type t = (Type) cst;
-+            if (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)
-+                buf.append(t.getInternalName()).append(".class");
-+            else
-+                buf.append(t.getDescriptor());
-         } else {
-             buf.append(cst);
-         }
--- a/dynopt-6912064.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-6912064: type profiles need to be exploited more for dynamic language support
-Reviewed-by: kvn
-
-diff --git a/src/share/vm/includeDB_compiler2 b/src/share/vm/includeDB_compiler2
---- a/src/share/vm/includeDB_compiler2
-+++ b/src/share/vm/includeDB_compiler2
-@@ -488,6 +488,7 @@
- graphKit.hpp                            callnode.hpp
- graphKit.hpp                            cfgnode.hpp
- graphKit.hpp                            ciEnv.hpp
-+graphKit.hpp                            ciMethodData.hpp
- graphKit.hpp                            divnode.hpp
- graphKit.hpp                            compile.hpp
- graphKit.hpp                            deoptimization.hpp
-diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
---- a/src/share/vm/opto/graphKit.cpp
-+++ b/src/share/vm/opto/graphKit.cpp
-@@ -2419,11 +2419,79 @@
- }
- 
- 
-+//------------------------------seems_never_null-------------------------------
-+// Use null_seen information if it is available from the profile.
-+// If we see an unexpected null at a type check we record it and force a
-+// recompile; the offending check will be recompiled to handle NULLs.
-+// If we see several offending BCIs, then all checks in the
-+// method will be recompiled.
-+bool GraphKit::seems_never_null(Node* obj, ciProfileData* data) {
-+  if (UncommonNullCast               // Cutout for this technique
-+      && obj != null()               // And not the -Xcomp stupid case?
-+      && !too_many_traps(Deoptimization::Reason_null_check)
-+      ) {
-+    if (data == NULL)
-+      // Edge case:  no mature data.  Be optimistic here.
-+      return true;
-+    // If the profile has not seen a null, assume it won't happen.
-+    assert(java_bc() == Bytecodes::_checkcast ||
-+           java_bc() == Bytecodes::_instanceof ||
-+           java_bc() == Bytecodes::_aastore, "MDO must collect null_seen bit here");
-+    return !data->as_BitData()->null_seen();
-+  }
-+  return false;
-+}
-+
-+//------------------------maybe_cast_profiled_receiver-------------------------
-+// If the profile has seen exactly one type, narrow to exactly that type.
-+// Subsequent type checks will always fold up.
-+Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj,
-+                                             ciProfileData* data,
-+                                             ciKlass* require_klass) {
-+  if (!UseTypeProfile || !TypeProfileCasts) return NULL;
-+  if (data == NULL)  return NULL;
-+
-+  // Make sure we haven't already deoptimized from this tactic.
-+  if (too_many_traps(Deoptimization::Reason_class_check))
-+    return NULL;
-+
-+  // (No, this isn't a call, but it's enough like a virtual call
-+  // to use the same ciMethod accessor to get the profile info...)
-+  ciCallProfile profile = method()->call_profile_at_bci(bci());
-+  if (profile.count() >= 0 &&         // no cast failures here
-+      profile.has_receiver(0) &&
-+      profile.morphism() == 1) {
-+    ciKlass* exact_kls = profile.receiver(0);
-+    if (require_klass == NULL ||
-+        static_subtype_check(require_klass, exact_kls) == SSC_always_true) {
-+      // If we narrow the type to match what the type profile sees,
-+      // we can then remove the rest of the cast.
-+      // This is a win, even if the exact_kls is very specific,
-+      // because downstream operations, such as method calls,
-+      // will often benefit from the sharper type.
-+      Node* exact_obj = not_null_obj; // will get updated in place...
-+      Node* slow_ctl  = type_check_receiver(exact_obj, exact_kls, 1.0,
-+                                            &exact_obj);
-+      { PreserveJVMState pjvms(this);
-+        set_control(slow_ctl);
-+        uncommon_trap(Deoptimization::Reason_class_check,
-+                      Deoptimization::Action_maybe_recompile);
-+      }
-+      replace_in_map(not_null_obj, exact_obj);
-+      return exact_obj;
-+    }
-+    // assert(ssc == SSC_always_true)... except maybe the profile lied to us.
-+  }
-+
-+  return NULL;
-+}
-+
-+
- //-------------------------------gen_instanceof--------------------------------
- // Generate an instance-of idiom.  Used by both the instance-of bytecode
- // and the reflective instance-of call.
--Node* GraphKit::gen_instanceof( Node *subobj, Node* superklass ) {
--  C->set_has_split_ifs(true); // Has chance for split-if optimization
-+Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) {
-+  kill_dead_locals();           // Benefit all the uncommon traps
-   assert( !stopped(), "dead parse path should be checked in callers" );
-   assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()),
-          "must check for not-null not-dead klass in callers");
-@@ -2434,9 +2502,16 @@
-   Node*       phi    = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL);
-   C->set_has_split_ifs(true); // Has chance for split-if optimization
- 
-+  ciProfileData* data = NULL;
-+  if (java_bc() == Bytecodes::_instanceof) {  // Only for the bytecode
-+    data = method()->method_data()->bci_to_data(bci());
-+  }
-+  bool never_see_null = (ProfileDynamicTypes  // aggressive use of profile
-+                         && seems_never_null(obj, data));
-+
-   // Null check; get casted pointer; set region slot 3
-   Node* null_ctl = top();
--  Node* not_null_obj = null_check_oop(subobj, &null_ctl);
-+  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
- 
-   // If not_null_obj is dead, only null-path is taken
-   if (stopped()) {              // Doing instance-of on a NULL?
-@@ -2445,6 +2520,23 @@
-   }
-   region->init_req(_null_path, null_ctl);
-   phi   ->init_req(_null_path, intcon(0)); // Set null path value
-+  if (null_ctl == top()) {
-+    // Do this eagerly, so that pattern matches like is_diamond_phi
-+    // will work even during parsing.
-+    assert(_null_path == PATH_LIMIT-1, "delete last");
-+    region->del_req(_null_path);
-+    phi   ->del_req(_null_path);
-+  }
-+
-+  if (ProfileDynamicTypes && data != NULL) {
-+    Node* cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, NULL);
-+    if (stopped()) {            // Profile disagrees with this path.
-+      set_control(null_ctl);    // Null is the only remaining possibility.
-+      return intcon(0);
-+    }
-+    if (cast_obj != NULL)
-+      not_null_obj = cast_obj;
-+  }
- 
-   // Load the object's klass
-   Node* obj_klass = load_object_klass(not_null_obj);
-@@ -2514,20 +2602,8 @@
-   C->set_has_split_ifs(true); // Has chance for split-if optimization
- 
-   // Use null-cast information if it is available
--  bool never_see_null = false;
--  // If we see an unexpected null at a check-cast we record it and force a
--  // recompile; the offending check-cast will be compiled to handle NULLs.
--  // If we see several offending BCIs, then all checkcasts in the
--  // method will be compiled to handle NULLs.
--  if (UncommonNullCast            // Cutout for this technique
--      && failure_control == NULL  // regular case
--      && obj != null()            // And not the -Xcomp stupid case?
--      && !too_many_traps(Deoptimization::Reason_null_check)) {
--    // Finally, check the "null_seen" bit from the interpreter.
--    if (data == NULL || !data->as_BitData()->null_seen()) {
--      never_see_null = true;
--    }
--  }
-+  bool never_see_null = ((failure_control == NULL)  // regular case only
-+                         && seems_never_null(obj, data));
- 
-   // Null check; get casted pointer; set region slot 3
-   Node* null_ctl = top();
-@@ -2540,47 +2616,26 @@
-   }
-   region->init_req(_null_path, null_ctl);
-   phi   ->init_req(_null_path, null());  // Set null path value
-+  if (null_ctl == top()) {
-+    // Do this eagerly, so that pattern matches like is_diamond_phi
-+    // will work even during parsing.
-+    assert(_null_path == PATH_LIMIT-1, "delete last");
-+    region->del_req(_null_path);
-+    phi   ->del_req(_null_path);
-+  }
- 
--  Node* cast_obj = NULL;        // the casted version of the object
--
--  // If the profile has seen exactly one type, narrow to that type.
--  // (The subsequent subtype check will always fold up.)
--  if (UseTypeProfile && TypeProfileCasts && data != NULL &&
-+  Node* cast_obj = NULL;
-+  if (data != NULL &&
-       // Counter has never been decremented (due to cast failure).
-       // ...This is a reasonable thing to expect.  It is true of
-       // all casts inserted by javac to implement generic types.
--      data->as_CounterData()->count() >= 0 &&
--      !too_many_traps(Deoptimization::Reason_class_check)) {
--    // (No, this isn't a call, but it's enough like a virtual call
--    // to use the same ciMethod accessor to get the profile info...)
--    ciCallProfile profile = method()->call_profile_at_bci(bci());
--    if (profile.count() >= 0 &&         // no cast failures here
--        profile.has_receiver(0) &&
--        profile.morphism() == 1) {
--      ciKlass* exact_kls = profile.receiver(0);
--      int ssc = static_subtype_check(tk->klass(), exact_kls);
--      if (ssc == SSC_always_true) {
--        // If we narrow the type to match what the type profile sees,
--        // we can then remove the rest of the cast.
--        // This is a win, even if the exact_kls is very specific,
--        // because downstream operations, such as method calls,
--        // will often benefit from the sharper type.
--        Node* exact_obj = not_null_obj; // will get updated in place...
--        Node* slow_ctl  = type_check_receiver(exact_obj, exact_kls, 1.0,
--                                              &exact_obj);
--        { PreserveJVMState pjvms(this);
--          set_control(slow_ctl);
--          uncommon_trap(Deoptimization::Reason_class_check,
--                        Deoptimization::Action_maybe_recompile);
--        }
--        if (failure_control != NULL) // failure is now impossible
--          (*failure_control) = top();
--        replace_in_map(not_null_obj, exact_obj);
--        // adjust the type of the phi to the exact klass:
--        phi->raise_bottom_type(_gvn.type(exact_obj)->meet(TypePtr::NULL_PTR));
--        cast_obj = exact_obj;
--      }
--      // assert(cast_obj != NULL)... except maybe the profile lied to us.
-+      data->as_CounterData()->count() >= 0) {
-+    cast_obj = maybe_cast_profiled_receiver(not_null_obj, data, tk->klass());
-+    if (cast_obj != NULL) {
-+      if (failure_control != NULL) // failure is now impossible
-+        (*failure_control) = top();
-+      // adjust the type of the phi to the exact klass:
-+      phi->raise_bottom_type(_gvn.type(cast_obj)->meet(TypePtr::NULL_PTR));
-     }
-   }
- 
-diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp
---- a/src/share/vm/opto/graphKit.hpp
-+++ b/src/share/vm/opto/graphKit.hpp
-@@ -336,6 +336,14 @@
-   Node* null_check_oop(Node* value, Node* *null_control,
-                        bool never_see_null = false);
- 
-+  // Check the null_seen bit.
-+  bool seems_never_null(Node* obj, ciProfileData* data);
-+
-+  // Use the type profile to narrow an object type.
-+  Node* maybe_cast_profiled_receiver(Node* not_null_obj,
-+                                     ciProfileData* data,
-+                                     ciKlass* require_klass);
-+
-   // Cast obj to not-null on this path
-   Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
-   // Replace all occurrences of one node by another.
-diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp
---- a/src/share/vm/opto/library_call.cpp
-+++ b/src/share/vm/opto/library_call.cpp
-@@ -906,7 +906,8 @@
-   const int count_offset = java_lang_String::count_offset_in_bytes();
-   const int offset_offset = java_lang_String::offset_offset_in_bytes();
- 
--  _sp += 2;
-+  int nargs = 2;
-+  _sp += nargs;
-   Node* argument = pop();  // pop non-receiver first:  it was pushed second
-   Node* receiver = pop();
- 
-@@ -914,11 +915,11 @@
-   // null check technically happens in the wrong place, which can lead to
-   // invalid stack traces when string compare is inlined into a method
-   // which handles NullPointerExceptions.
--  _sp += 2;
-+  _sp += nargs;
-   receiver = do_null_check(receiver, T_OBJECT);
-   //should not do null check for argument for String.equals(), because spec
-   //allows to specify NULL as argument.
--  _sp -= 2;
-+  _sp -= nargs;
- 
-   if (stopped()) {
-     return true;
-@@ -943,7 +944,9 @@
-   ciInstanceKlass* klass = env()->String_klass();
- 
-   if (!stopped()) {
-+    _sp += nargs;          // gen_instanceof might do an uncommon trap
-     Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
-+    _sp -= nargs;
-     Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
-     Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
- 
-@@ -2920,7 +2923,9 @@
-   switch (id) {
-   case vmIntrinsics::_isInstance:
-     // nothing is an instance of a primitive type
-+    _sp += nargs;          // gen_instanceof might do an uncommon trap
-     query_value = gen_instanceof(obj, kls);
-+    _sp -= nargs;
-     break;
- 
-   case vmIntrinsics::_getModifiers:
-diff --git a/src/share/vm/opto/parse.hpp b/src/share/vm/opto/parse.hpp
---- a/src/share/vm/opto/parse.hpp
-+++ b/src/share/vm/opto/parse.hpp
-@@ -493,6 +493,7 @@
-   float   dynamic_branch_prediction(float &cnt);
-   float   branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
-   bool    seems_never_taken(float prob);
-+  bool    seems_stable_comparison(BoolTest::mask btest, Node* c);
- 
-   void    do_ifnull(BoolTest::mask btest, Node* c);
-   void    do_if(BoolTest::mask btest, Node* c);
-diff --git a/src/share/vm/opto/parse2.cpp b/src/share/vm/opto/parse2.cpp
---- a/src/share/vm/opto/parse2.cpp
-+++ b/src/share/vm/opto/parse2.cpp
-@@ -892,6 +892,62 @@
-   return prob < PROB_MIN;
- }
- 
-+// True if the comparison seems to be the kind that will not change its
-+// statistics from true to false.  See comments in adjust_map_after_if.
-+// This question is only asked along paths which are already
-+// classifed as untaken (by seems_never_taken), so really,
-+// if a path is never taken, its controlling comparison is
-+// already acting in a stable fashion.  If the comparison
-+// seems stable, we will put an expensive uncommon trap
-+// on the untaken path.  To be conservative, and to allow
-+// partially executed counted loops to be compiled fully,
-+// we will plant uncommon traps only after pointer comparisons.
-+bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) {
-+  for (int depth = 4; depth > 0; depth--) {
-+    // The following switch can find CmpP here over half the time for
-+    // dynamic language code rich with type tests.
-+    // Code using counted loops or array manipulations (typical
-+    // of benchmarks) will have many (>80%) CmpI instructions.
-+    switch (cmp->Opcode()) {
-+    case Op_CmpP:
-+      // A never-taken null check looks like CmpP/BoolTest::eq.
-+      // These certainly should be closed off as uncommon traps.
-+      if (btest == BoolTest::eq)
-+        return true;
-+      // A never-failed type check looks like CmpP/BoolTest::ne.
-+      // Let's put traps on those, too, so that we don't have to compile
-+      // unused paths with indeterminate dynamic type information.
-+      if (ProfileDynamicTypes)
-+        return true;
-+      return false;
-+
-+    case Op_CmpI:
-+      // A small minority (< 10%) of CmpP are masked as CmpI,
-+      // as if by boolean conversion ((p == q? 1: 0) != 0).
-+      // Detect that here, even if it hasn't optimized away yet.
-+      // Specifically, this covers the 'instanceof' operator.
-+      if (btest == BoolTest::ne || btest == BoolTest::eq) {
-+        if (_gvn.type(cmp->in(2))->singleton() &&
-+            cmp->in(1)->is_Phi()) {
-+          PhiNode* phi = cmp->in(1)->as_Phi();
-+          int true_path = phi->is_diamond_phi();
-+          if (true_path > 0 &&
-+              _gvn.type(phi->in(1))->singleton() &&
-+              _gvn.type(phi->in(2))->singleton()) {
-+            // phi->region->if_proj->ifnode->bool->cmp
-+            BoolNode* bol = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
-+            btest = bol->_test._test;
-+            cmp = bol->in(1);
-+            continue;
-+          }
-+        }
-+      }
-+      return false;
-+    }
-+  }
-+  return false;
-+}
-+
- //-------------------------------repush_if_args--------------------------------
- // Push arguments of an "if" bytecode back onto the stack by adjusting _sp.
- inline int Parse::repush_if_args() {
-@@ -1137,19 +1193,22 @@
- 
-   bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
- 
--  int cop = c->Opcode();
--  if (seems_never_taken(prob) && cop == Op_CmpP && btest == BoolTest::eq) {
--    // (An earlier version of do_if omitted '&& btest == BoolTest::eq'.)
--    //
-+  if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) {
-     // If this might possibly turn into an implicit null check,
-     // and the null has never yet been seen, we need to generate
-     // an uncommon trap, so as to recompile instead of suffering
-     // with very slow branches.  (We'll get the slow branches if
-     // the program ever changes phase and starts seeing nulls here.)
-     //
--    // The tests we worry about are of the form (p == null).
--    // We do not simply inspect for a null constant, since a node may
-+    // We do not inspect for a null constant, since a node may
-     // optimize to 'null' later on.
-+    //
-+    // Null checks, and other tests which expect inequality,
-+    // show btest == BoolTest::eq along the non-taken branch.
-+    // On the other hand, type tests, must-be-null tests,
-+    // and other tests which expect pointer equality,
-+    // show btest == BoolTest::ne along the non-taken branch.
-+    // We prune both types of branches if they look unused.
-     repush_if_args();
-     // We need to mark this branch as taken so that if we recompile we will
-     // see that it is possible. In the tiered system the interpreter doesn't
-diff --git a/src/share/vm/opto/parseHelper.cpp b/src/share/vm/opto/parseHelper.cpp
---- a/src/share/vm/opto/parseHelper.cpp
-+++ b/src/share/vm/opto/parseHelper.cpp
-@@ -119,7 +119,11 @@
-   }
- 
-   // Push the bool result back on stack
--  push( gen_instanceof( pop(), makecon(TypeKlassPtr::make(klass)) ) );
-+  Node* res = gen_instanceof(peek(), makecon(TypeKlassPtr::make(klass)));
-+
-+  // Pop from stack AFTER gen_instanceof because it can uncommon trap.
-+  pop();
-+  push(res);
- }
- 
- //------------------------------array_store_check------------------------------
-diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
---- a/src/share/vm/runtime/globals.hpp
-+++ b/src/share/vm/runtime/globals.hpp
-@@ -2433,6 +2433,9 @@
-   develop(bool, MonomorphicArrayCheck, true,                                \
-           "Uncommon-trap array store checks that require full type check")  \
-                                                                             \
-+  diagnostic(bool, ProfileDynamicTypes, true,                               \
-+          "do extra type profiling and use it more aggressively")           \
-+                                                                            \
-   develop(bool, DelayCompilationDuringStartup, true,                        \
-           "Delay invoking the compiler until main application class is "    \
-           "loaded")                                                         \
--- a/indy-bsm-7001379.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1266 +0,0 @@
-7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
-Reviewed-by: twisti
-
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
---- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
-@@ -60,10 +60,7 @@
-     headerSize  = type.getSize();
-     elementSize = 0;
-     // fetch constants:
--    MULTI_OPERAND_COUNT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_count_offset").intValue();
--    MULTI_OPERAND_BASE_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_multi_operand_base_offset").intValue();
-     INDY_BSM_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_bsm_offset").intValue();
--    INDY_NT_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_nt_offset").intValue();
-     INDY_ARGC_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argc_offset").intValue();
-     INDY_ARGV_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argv_offset").intValue();
-   }
-@@ -83,10 +80,7 @@
-   private static long headerSize;
-   private static long elementSize;
- 
--  private static int MULTI_OPERAND_COUNT_OFFSET;
--  private static int MULTI_OPERAND_BASE_OFFSET;
-   private static int INDY_BSM_OFFSET;
--  private static int INDY_NT_OFFSET;
-   private static int INDY_ARGC_OFFSET;
-   private static int INDY_ARGV_OFFSET;
- 
-@@ -296,20 +290,23 @@
-   }
- 
-   /** Lookup for multi-operand (InvokeDynamic) entries. */
--  public int[] getMultiOperandsAt(int i) {
-+  public short[] getBootstrapSpecifierAt(int i) {
-     if (Assert.ASSERTS_ENABLED) {
-       Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool");
-     }
--    int pos = this.getIntAt(i);
--    int countPos = pos + MULTI_OPERAND_COUNT_OFFSET;  // == pos-1
--    int basePos  = pos + MULTI_OPERAND_BASE_OFFSET;   // == pos
--    if (countPos < 0)  return null;  // safety first
-+    if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans)
-+        return null;
-+    int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
-     TypeArray operands = getOperands();
-     if (operands == null)  return null;  // safety first
--    int length = operands.getIntAt(countPos);
--    int[] values = new int[length];
--    for (int j = 0; j < length; j++) {
--        values[j] = operands.getIntAt(basePos+j);
-+    int basePos = VM.getVM().buildIntFromShorts(operands.getShortAt(bsmSpec * 2 + 0),
-+                                                operands.getShortAt(bsmSpec * 2 + 1));
-+    int argv = basePos + INDY_ARGV_OFFSET;
-+    int argc = operands.getShortAt(basePos + INDY_ARGC_OFFSET);
-+    int endPos = argv + argc;
-+    short[] values = new short[endPos - basePos];
-+    for (int j = 0; j < values.length; j++) {
-+        values[j] = operands.getShortAt(basePos+j);
-     }
-     return values;
-   }
-@@ -334,6 +331,7 @@
-     case JVM_CONSTANT_MethodHandle:       return "JVM_CONSTANT_MethodHandle";
-     case JVM_CONSTANT_MethodType:         return "JVM_CONSTANT_MethodType";
-     case JVM_CONSTANT_InvokeDynamic:      return "JVM_CONSTANT_InvokeDynamic";
-+    case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional";
-     case JVM_CONSTANT_Invalid:            return "JVM_CONSTANT_Invalid";
-     case JVM_CONSTANT_UnresolvedClass:    return "JVM_CONSTANT_UnresolvedClass";
-     case JVM_CONSTANT_UnresolvedClassInError:    return "JVM_CONSTANT_UnresolvedClassInError";
-@@ -393,6 +391,7 @@
-         case JVM_CONSTANT_MethodHandle:
-         case JVM_CONSTANT_MethodType:
-         case JVM_CONSTANT_InvokeDynamic:
-+        case JVM_CONSTANT_InvokeDynamicTrans:
-           visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
-           break;
-         }
-@@ -556,19 +555,16 @@
-                   break;
-               }
- 
-+              case JVM_CONSTANT_InvokeDynamicTrans:
-               case JVM_CONSTANT_InvokeDynamic: {
-                   dos.writeByte(cpConstType);
--                  int[] values = getMultiOperandsAt(ci);
--                  for (int vn = 0; vn < values.length; vn++) {
--                      dos.writeShort(values[vn]);
--                  }
--                  int bootstrapMethodIndex = values[INDY_BSM_OFFSET];
--                  int nameAndTypeIndex = values[INDY_NT_OFFSET];
--                  int argumentCount = values[INDY_ARGC_OFFSET];
--                  assert(INDY_ARGV_OFFSET + argumentCount == values.length);
--                  if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bootstrapMethodIndex
--                                          + ", N&T = " + nameAndTypeIndex
--                                          + ", argc = " + argumentCount);
-+                  int value = getIntAt(ci);
-+                  short bsmIndex = (short) extractLowShortFromInt(value);
-+                  short nameAndTypeIndex = (short) extractHighShortFromInt(value);
-+                  dos.writeShort(bsmIndex);
-+                  dos.writeShort(nameAndTypeIndex);
-+                  if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bsmIndex
-+                                          + ", N&T = " + nameAndTypeIndex);
-                   break;
-               }
- 
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
---- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
-@@ -321,13 +321,16 @@
-                      break;
-                 }
- 
-+                case JVM_CONSTANT_InvokeDynamicTrans:
-                 case JVM_CONSTANT_InvokeDynamic: {
-                      dos.writeByte(cpConstType);
--                     int[] values = cpool.getMultiOperandsAt(ci);
--                     for (int vn = 0; vn < values.length; vn++) {
--                         dos.writeShort(values[vn]);
--                     }
--                     if (DEBUG) debugMessage("CP[" + ci + "] = INDY indexes = " + Arrays.toString(values));
-+                     int value = cpool.getIntAt(ci);
-+                     short bsmIndex = (short) extractLowShortFromInt(value);
-+                     short nameAndTypeIndex = (short) extractHighShortFromInt(value);
-+                     dos.writeShort(bsmIndex);
-+                     dos.writeShort(nameAndTypeIndex);
-+                     if (DEBUG) debugMessage("CP[" + ci + "] = INDY bsm = " +
-+                           bsmIndex + ", N&T = " + nameAndTypeIndex);
-                      break;
-                 }
- 
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
---- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
-@@ -460,7 +460,8 @@
-       return buf.toString();
-    }
- 
--   private String genListOfShort(int[] values) {
-+   private String genListOfShort(short[] values) {
-+      if (values == null || values.length == 0)  return "";
-       Formatter buf = new Formatter(genHTML);
-       buf.append('[');
-       for (int i = 0; i < values.length; i++) {
-@@ -594,9 +595,11 @@
-                buf.cell(Integer.toString(cpool.getIntAt(index)));
-                break;
- 
-+            case JVM_CONSTANT_InvokeDynamicTrans:
-             case JVM_CONSTANT_InvokeDynamic:
-                buf.cell("JVM_CONSTANT_InvokeDynamic");
--               buf.cell(genListOfShort(cpool.getMultiOperandsAt(index)));
-+               buf.cell(genLowHighShort(cpool.getIntAt(index)) +
-+                        genListOfShort(cpool.getBootstrapSpecifierAt(index)));
-                break;
- 
-             default:
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
---- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
-@@ -40,7 +40,7 @@
-   private static int JVM_CONSTANT_NameAndType             = 12;
-   private static int JVM_CONSTANT_MethodHandle            = 15;  // JSR 292
-   private static int JVM_CONSTANT_MethodType              = 16;  // JSR 292
--  //      static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
-+  private static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
-   private static int JVM_CONSTANT_InvokeDynamic           = 18;  // JSR 292
-   private static int JVM_CONSTANT_Invalid                 = 0;   // For bad value initialization
-   private static int JVM_CONSTANT_UnresolvedClass         = 100; // Temporary tag until actual use
-@@ -67,6 +67,8 @@
-     this.tag = tag;
-   }
- 
-+  public int value() { return tag; }
-+
-   public boolean isKlass()            { return tag == JVM_CONSTANT_Class; }
-   public boolean isField ()           { return tag == JVM_CONSTANT_Fieldref; }
-   public boolean isMethod()           { return tag == JVM_CONSTANT_Methodref; }
-@@ -81,6 +83,7 @@
-   public boolean isMethodHandle()     { return tag == JVM_CONSTANT_MethodHandle; }
-   public boolean isMethodType()       { return tag == JVM_CONSTANT_MethodType; }
-   public boolean isInvokeDynamic()    { return tag == JVM_CONSTANT_InvokeDynamic; }
-+  public boolean isInvokeDynamicTrans() { return tag == JVM_CONSTANT_InvokeDynamicTrans; }
- 
-   public boolean isInvalid()          { return tag == JVM_CONSTANT_Invalid; }
- 
-diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
---- a/src/share/vm/classfile/classFileParser.cpp
-+++ b/src/share/vm/classfile/classFileParser.cpp
-@@ -73,12 +73,6 @@
-   unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
-   int names_count = 0;
- 
--  // Side buffer for operands of variable-sized (InvokeDynamic) entries.
--  GrowableArray<int>* operands = NULL;
--#ifdef ASSERT
--  GrowableArray<int>* indy_instructions = new GrowableArray<int>(THREAD, 10);
--#endif
--
-   // parsing  Index 0 is unused
-   for (int index = 1; index < length; index++) {
-     // Each of the following case guarantees one more byte in the stream
-@@ -158,36 +152,20 @@
-                "Class file version does not support constant tag %u in class file %s"),
-               tag, CHECK);
-           }
--          if (!AllowTransitionalJSR292 && tag == JVM_CONSTANT_InvokeDynamicTrans) {
--            classfile_parse_error(
-+          cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
-+          u2 bootstrap_specifier_index = cfs->get_u2_fast();
-+          u2 name_and_type_index = cfs->get_u2_fast();
-+          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
-+            if (!AllowTransitionalJSR292)
-+              classfile_parse_error(
-                 "This JVM does not support transitional InvokeDynamic tag %u in class file %s",
-                 tag, CHECK);
--          }
--          bool trans_no_argc = AllowTransitionalJSR292 && (tag == JVM_CONSTANT_InvokeDynamicTrans);
--          cfs->guarantee_more(7, CHECK);  // bsm_index, nt, argc, ..., tag/access_flags
--          u2 bootstrap_method_index = cfs->get_u2_fast();
--          u2 name_and_type_index = cfs->get_u2_fast();
--          int argument_count = trans_no_argc ? 0 : cfs->get_u2_fast();
--          cfs->guarantee_more(2*argument_count + 1, CHECK);  // argv[argc]..., tag/access_flags
--          int argv_offset = constantPoolOopDesc::_indy_argv_offset;
--          int op_count = argv_offset + argument_count;  // bsm, nt, argc, argv[]...
--          int op_base = start_operand_group(operands, op_count, CHECK);
--          assert(argv_offset == 3, "else adjust next 3 assignments");
--          operands->at_put(op_base + constantPoolOopDesc::_indy_bsm_offset, bootstrap_method_index);
--          operands->at_put(op_base + constantPoolOopDesc::_indy_nt_offset, name_and_type_index);
--          operands->at_put(op_base + constantPoolOopDesc::_indy_argc_offset, argument_count);
--          for (int arg_i = 0; arg_i < argument_count; arg_i++) {
--            int arg = cfs->get_u2_fast();
--            operands->at_put(op_base + constantPoolOopDesc::_indy_argv_offset + arg_i, arg);
--          }
--          cp->invoke_dynamic_at_put(index, op_base, op_count);
--#ifdef ASSERT
--          // Record the steps just taken for later checking.
--          indy_instructions->append(index);
--          indy_instructions->append(bootstrap_method_index);
--          indy_instructions->append(name_and_type_index);
--          indy_instructions->append(argument_count);
--#endif //ASSERT
-+            cp->invoke_dynamic_trans_at_put(index, bootstrap_specifier_index, name_and_type_index);
-+            break;
-+          }
-+          if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index)
-+            _max_bootstrap_specifier_index = (int) bootstrap_specifier_index;  // collect for later
-+          cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);
-         }
-         break;
-       case JVM_CONSTANT_Integer :
-@@ -290,23 +268,6 @@
-     oopFactory::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
-   }
- 
--  if (operands != NULL && operands->length() > 0) {
--    store_operand_array(operands, cp, CHECK);
--  }
--#ifdef ASSERT
--  // Re-assert the indy structures, now that assertion checking can work.
--  for (int indy_i = 0; indy_i < indy_instructions->length(); ) {
--    int index                  = indy_instructions->at(indy_i++);
--    int bootstrap_method_index = indy_instructions->at(indy_i++);
--    int name_and_type_index    = indy_instructions->at(indy_i++);
--    int argument_count         = indy_instructions->at(indy_i++);
--    assert(cp->check_invoke_dynamic_at(index,
--                                       bootstrap_method_index, name_and_type_index,
--                                       argument_count),
--           "indy structure is OK");
--  }
--#endif //ASSERT
--
-   // Copy _current pointer of local copy back to stream().
- #ifdef ASSERT
-   assert(cfs0->current() == old_current, "non-exclusive use of stream()");
-@@ -314,41 +275,6 @@
-   cfs0->set_current(cfs1.current());
- }
- 
--int ClassFileParser::start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS) {
--  if (operands == NULL) {
--    operands = new GrowableArray<int>(THREAD, 100);
--    int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
--    while (operands->length() <= fillp_offset)
--      operands->append(0);  // force op_base > 0, for an error check
--    DEBUG_ONLY(operands->at_put(fillp_offset, (int)badHeapWordVal));
--  }
--  int cnt_pos = operands->append(op_count);
--  int arg_pos = operands->length();
--  operands->at_grow(arg_pos + op_count - 1);  // grow to include the operands
--  assert(operands->length() == arg_pos + op_count, "");
--  int op_base = cnt_pos - constantPoolOopDesc::_multi_operand_count_offset;
--  return op_base;
--}
--
--void ClassFileParser::store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS) {
--  // Collect the buffer of operands from variable-sized entries into a permanent array.
--  int arraylen = operands->length();
--  int fillp_offset = constantPoolOopDesc::_multi_operand_buffer_fill_pointer_offset;
--  assert(operands->at(fillp_offset) == (int)badHeapWordVal, "value unused so far");
--  operands->at_put(fillp_offset, arraylen);
--  cp->multi_operand_buffer_grow(arraylen, CHECK);
--  typeArrayOop operands_oop = cp->operands();
--  assert(operands_oop->length() == arraylen, "");
--  for (int i = 0; i < arraylen; i++) {
--    operands_oop->int_at_put(i, operands->at(i));
--  }
--  cp->set_operands(operands_oop);
--  // The fill_pointer is used only by constantPoolOop::copy_entry_to and friends,
--  // when constant pools need to be merged.  Make sure it is sane now.
--  assert(cp->multi_operand_buffer_fill_pointer() == arraylen, "");
--}
--
--
- bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
- 
- constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
-@@ -375,7 +301,8 @@
- 
-   // first verification pass - validate cross references and fixup class and string constants
-   for (index = 1; index < length; index++) {          // Index 0 is unused
--    switch (cp->tag_at(index).value()) {
-+    jbyte tag = cp->tag_at(index).value();
-+    switch (tag) {
-       case JVM_CONSTANT_Class :
-         ShouldNotReachHere();     // Only JVM_CONSTANT_ClassIndex should be present
-         break;
-@@ -517,35 +444,23 @@
-         }
-         break;
-       case JVM_CONSTANT_InvokeDynamicTrans :
--        ShouldNotReachHere();  // this tag does not appear in the heap
-       case JVM_CONSTANT_InvokeDynamic :
-         {
--          int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
-           int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
--          check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292)
--                         ||
--                         (valid_cp_range(bootstrap_method_ref_index, length) &&
--                          (cp->tag_at(bootstrap_method_ref_index).is_method_handle())),
--                         "Invalid constant pool index %u in class file %s",
--                         bootstrap_method_ref_index,
--                         CHECK_(nullHandle));
-           check_property(valid_cp_range(name_and_type_ref_index, length) &&
-                          cp->tag_at(name_and_type_ref_index).is_name_and_type(),
-                          "Invalid constant pool index %u in class file %s",
-                          name_and_type_ref_index,
-                          CHECK_(nullHandle));
--          int argc = cp->invoke_dynamic_argument_count_at(index);
--          for (int arg_i = 0; arg_i < argc; arg_i++) {
--            int arg = cp->invoke_dynamic_argument_index_at(index, arg_i);
--            check_property(valid_cp_range(arg, length) &&
--                           cp->tag_at(arg).is_loadable_constant() ||
--                           // temporary early forms of string and class:
--                           cp->tag_at(arg).is_klass_index() ||
--                           cp->tag_at(arg).is_string_index(),
-+          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
-+            int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
-+            check_property(valid_cp_range(bootstrap_method_ref_index, length) &&
-+                           cp->tag_at(bootstrap_method_ref_index).is_method_handle(),
-                            "Invalid constant pool index %u in class file %s",
--                           arg,
-+                           bootstrap_method_ref_index,
-                            CHECK_(nullHandle));
-           }
-+          // bootstrap specifier index must be checked later, when BootstrapMethods attr is available
-           break;
-         }
-       default:
-@@ -2403,6 +2318,78 @@
-   k->set_generic_signature(cp->symbol_at(signature_index));
- }
- 
-+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
-+                                                                  u4 attribute_byte_length, TRAPS) {
-+  ClassFileStream* cfs = stream();
-+  u1* current_start = cfs->current();
-+
-+  cfs->guarantee_more(2, CHECK);  // length
-+  int attribute_array_length = cfs->get_u2_fast();
-+
-+  guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
-+                     "Short length on BootstrapMethods in class file %s",
-+                     CHECK);
-+
-+  // The attribute contains a counted array of counted tuples of shorts,
-+  // represending bootstrap specifiers:
-+  //    length*{bootstrap_method_index, argument_count*{argument_index}}
-+  int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2);
-+  // operand_count = number of shorts in attr, except for leading length
-+
-+  // The attribute is copied into a short[] array.
-+  // The array begins with a series of short[2] pairs, one for each tuple.
-+  int index_size = (attribute_array_length * 2);
-+
-+  typeArrayOop operands_oop = oopFactory::new_permanent_intArray(index_size + operand_count, CHECK);
-+  typeArrayHandle operands(THREAD, operands_oop);
-+  operands_oop = NULL; // tidy
-+
-+  int operand_fill_index = index_size;
-+  int cp_size = cp->length();
-+
-+  for (int n = 0; n < attribute_array_length; n++) {
-+    // Store a 32-bit offset into the header of the operand array.
-+    assert(constantPoolOopDesc::operand_offset_at(operands(), n) == 0, "");
-+    constantPoolOopDesc::operand_offset_at_put(operands(), n, operand_fill_index);
-+
-+    // Read a bootstrap specifier.
-+    cfs->guarantee_more(sizeof(u2) * 2, CHECK);  // bsm, argc
-+    u2 bootstrap_method_index = cfs->get_u2_fast();
-+    u2 argument_count = cfs->get_u2_fast();
-+    check_property(
-+      valid_cp_range(bootstrap_method_index, cp_size) &&
-+      cp->tag_at(bootstrap_method_index).is_method_handle(),
-+      "bootstrap_method_index %u has bad constant type in class file %s",
-+      bootstrap_method_index,
-+      CHECK);
-+    operands->short_at_put(operand_fill_index++, bootstrap_method_index);
-+    operands->short_at_put(operand_fill_index++, argument_count);
-+
-+    cfs->guarantee_more(sizeof(u2) * argument_count, CHECK);  // argv[argc]
-+    for (int j = 0; j < argument_count; j++) {
-+      u2 argument_index = cfs->get_u2_fast();
-+      check_property(
-+        valid_cp_range(argument_index, cp_size) &&
-+        cp->tag_at(argument_index).is_loadable_constant(),
-+        "argument_index %u has bad constant type in class file %s",
-+        argument_index,
-+        CHECK);
-+      operands->short_at_put(operand_fill_index++, argument_index);
-+    }
-+  }
-+
-+  assert(operand_fill_index == operands()->length(), "exact fill");
-+  assert(constantPoolOopDesc::operand_array_length(operands()) == attribute_array_length, "correct decode");
-+
-+  u1* current_end = cfs->current();
-+  guarantee_property(current_end == current_start + attribute_byte_length,
-+                     "Bad length on BootstrapMethods in class file %s",
-+                     CHECK);
-+
-+  cp->set_operands(operands());
-+}
-+
-+
- void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
-   ClassFileStream* cfs = stream();
-   // Set inner classes attribute to default sentinel
-@@ -2412,6 +2397,7 @@
-   bool parsed_sourcefile_attribute = false;
-   bool parsed_innerclasses_attribute = false;
-   bool parsed_enclosingmethod_attribute = false;
-+  bool parsed_bootstrap_methods_attribute = false;
-   u1* runtime_visible_annotations = NULL;
-   int runtime_visible_annotations_length = 0;
-   u1* runtime_invisible_annotations = NULL;
-@@ -2510,6 +2496,12 @@
-           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
-         }
-         k->set_enclosing_method_indices(class_index, method_index);
-+      } else if (tag == vmSymbols::tag_bootstrap_methods() &&
-+                 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
-+        if (parsed_bootstrap_methods_attribute)
-+          classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
-+        parsed_bootstrap_methods_attribute = true;
-+        parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
-       } else {
-         // Unknown attribute
-         cfs->skip_u1(attribute_length, CHECK);
-@@ -2525,6 +2517,11 @@
-                                                      runtime_invisible_annotations_length,
-                                                      CHECK);
-   k->set_class_annotations(annotations());
-+
-+  if (_max_bootstrap_specifier_index >= 0) {
-+    guarantee_property(parsed_bootstrap_methods_attribute,
-+                       "Missing BootstrapMethods attribute in class file %s", CHECK);
-+  }
- }
- 
- 
-@@ -2850,6 +2847,7 @@
-                             PerfClassTraceTime::PARSE_CLASS);
- 
-   _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
-+  _max_bootstrap_specifier_index = -1;
- 
-   if (JvmtiExport::should_post_class_file_load_hook()) {
-     unsigned char* ptr = cfs->buffer();
-diff --git a/src/share/vm/classfile/classFileParser.hpp b/src/share/vm/classfile/classFileParser.hpp
---- a/src/share/vm/classfile/classFileParser.hpp
-+++ b/src/share/vm/classfile/classFileParser.hpp
-@@ -40,6 +40,8 @@
-   bool _has_empty_finalizer;
-   bool _has_vanilla_constructor;
- 
-+  int _max_bootstrap_specifier_index;
-+
-   enum { fixed_buffer_size = 128 };
-   u_char linenumbertable_buffer[fixed_buffer_size];
- 
-@@ -56,9 +58,6 @@
- 
-   constantPoolHandle parse_constant_pool(TRAPS);
- 
--  static int start_operand_group(GrowableArray<int>* &operands, int op_count, TRAPS);
--  static void store_operand_array(GrowableArray<int>* operands, constantPoolHandle cp, TRAPS);
--
-   // Interface parsing
-   objArrayHandle parse_interfaces(constantPoolHandle cp,
-                                   int length,
-@@ -120,6 +119,7 @@
-   void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-   void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-   void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-+  void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS);
- 
-   // Annotations handling
-   typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
-diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp
---- a/src/share/vm/classfile/vmSymbols.hpp
-+++ b/src/share/vm/classfile/vmSymbols.hpp
-@@ -127,6 +127,7 @@
-   template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations")    \
-   template(tag_annotation_default,                    "AnnotationDefault")                        \
-   template(tag_enclosing_method,                      "EnclosingMethod")                          \
-+  template(tag_bootstrap_methods,                     "BootstrapMethods")                         \
-                                                                                                   \
-   /* exception klasses: at least all exceptions thrown by the VM have entries here */             \
-   template(java_lang_ArithmeticException,             "java/lang/ArithmeticException")            \
-diff --git a/src/share/vm/interpreter/bytecodeTracer.cpp b/src/share/vm/interpreter/bytecodeTracer.cpp
---- a/src/share/vm/interpreter/bytecodeTracer.cpp
-+++ b/src/share/vm/interpreter/bytecodeTracer.cpp
-@@ -337,6 +337,7 @@
-     break;
-   case JVM_CONSTANT_NameAndType:
-   case JVM_CONSTANT_InvokeDynamic:
-+  case JVM_CONSTANT_InvokeDynamicTrans:
-     has_klass = false;
-     break;
-   default:
-diff --git a/src/share/vm/interpreter/rewriter.cpp b/src/share/vm/interpreter/rewriter.cpp
---- a/src/share/vm/interpreter/rewriter.cpp
-+++ b/src/share/vm/interpreter/rewriter.cpp
-@@ -43,6 +43,7 @@
-       case JVM_CONSTANT_MethodHandle      : // fall through
-       case JVM_CONSTANT_MethodType        : // fall through
-       case JVM_CONSTANT_InvokeDynamic     : // fall through
-+      case JVM_CONSTANT_InvokeDynamicTrans: // fall through
-         add_cp_cache_entry(i);
-         break;
-     }
-@@ -52,6 +53,7 @@
-             "all cp cache indexes fit in a u2");
- 
-   _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0);
-+  _have_invoke_dynamic |= ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamicTrans)) != 0);
- }
- 
- 
-@@ -65,7 +67,7 @@
-       oopFactory::new_constantPoolCache(length, methodOopDesc::IsUnsafeConc, CHECK);
-   cache->initialize(_cp_cache_map);
- 
--  // Don't bother to the next pass if there is no JVM_CONSTANT_InvokeDynamic.
-+  // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic.
-   if (_have_invoke_dynamic) {
-     for (int i = 0; i < length; i++) {
-       int pool_index = cp_cache_entry_pool_index(i);
-diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
---- a/src/share/vm/oops/constantPoolKlass.cpp
-+++ b/src/share/vm/oops/constantPoolKlass.cpp
-@@ -372,6 +372,7 @@
-       case JVM_CONSTANT_MethodType :
-         st->print("signature_index=%d", cp->method_type_index_at(index));
-         break;
-+      case JVM_CONSTANT_InvokeDynamicTrans :
-       case JVM_CONSTANT_InvokeDynamic :
-         {
-           st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index));
-diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
---- a/src/share/vm/oops/constantPoolOop.cpp
-+++ b/src/share/vm/oops/constantPoolOop.cpp
-@@ -901,7 +901,8 @@
-   {
-     int k1 = method_type_index_at(index1);
-     int k2 = cp2->method_type_index_at(index2);
--    if (k1 == k2) {
-+    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
-+    if (match) {
-       return true;
-     }
-   } break;
-@@ -913,28 +914,33 @@
-     if (k1 == k2) {
-       int i1 = method_handle_index_at(index1);
-       int i2 = cp2->method_handle_index_at(index2);
--      if (i1 == i2) {
-+      bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
-+      if (match) {
-         return true;
-       }
-     }
-   } break;
- 
-   case JVM_CONSTANT_InvokeDynamic:
-+  case JVM_CONSTANT_InvokeDynamicTrans:
-   {
--    int op_count = multi_operand_count_at(index1);
--    if (op_count == cp2->multi_operand_count_at(index2)) {
--      bool all_equal = true;
--      for (int op_i = 0; op_i < op_count; op_i++) {
--        int k1 = multi_operand_ref_at(index1, op_i);
--        int k2 = cp2->multi_operand_ref_at(index2, op_i);
--        if (k1 != k2) {
--          all_equal = false;
--          break;
--        }
-+    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
-+    int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
-+    bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
-+    if (!match)  return false;
-+    k1 = invoke_dynamic_name_and_type_ref_index_at(index1);
-+    k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
-+    match = compare_entry_to(k1, cp2, k2, CHECK_false);
-+    if (!match)  return false;
-+    int argc = invoke_dynamic_argument_count_at(index1);
-+    if (argc == cp2->invoke_dynamic_argument_count_at(index2)) {
-+      for (int j = 0; j < argc; j++) {
-+        k1 = invoke_dynamic_argument_index_at(index1, j);
-+        k2 = cp2->invoke_dynamic_argument_index_at(index2, j);
-+        match = compare_entry_to(k1, cp2, k2, CHECK_false);
-+        if (!match)  return false;
-       }
--      if (all_equal) {
--        return true;           // got through loop; all elements equal
--      }
-+      return true;           // got through loop; all elements equal
-     }
-   } break;
- 
-@@ -970,44 +976,18 @@
- } // end compare_entry_to()
- 
- 
--// Grow this->operands() to the indicated length, unless it is already at least that long.
--void constantPoolOopDesc::multi_operand_buffer_grow(int min_length, TRAPS) {
--  int old_length = multi_operand_buffer_fill_pointer();
--  if (old_length >= min_length)  return;
--  int new_length = min_length;
--  assert(new_length > _multi_operand_buffer_fill_pointer_offset, "");
--  typeArrayHandle new_operands = oopFactory::new_permanent_intArray(new_length, CHECK);
--  if (operands() == NULL) {
--    new_operands->int_at_put(_multi_operand_buffer_fill_pointer_offset, old_length);
--  } else {
--    // copy fill pointer and everything else
--    for (int i = 0; i < old_length; i++) {
--      new_operands->int_at_put(i, operands()->int_at(i));
--    }
--  }
--  set_operands(new_operands());
--}
--
--
- // Copy this constant pool's entries at start_i to end_i (inclusive)
- // to the constant pool to_cp's entries starting at to_i. A total of
- // (end_i - start_i) + 1 entries are copied.
--void constantPoolOopDesc::copy_cp_to(int start_i, int end_i,
-+void constantPoolOopDesc::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
-        constantPoolHandle to_cp, int to_i, TRAPS) {
- 
-   int dest_i = to_i;  // leave original alone for debug purposes
- 
--  if (operands() != NULL) {
--    // pre-grow the target CP's operand buffer
--    int nops = this->multi_operand_buffer_fill_pointer();
--    nops   += to_cp->multi_operand_buffer_fill_pointer();
--    to_cp->multi_operand_buffer_grow(nops, CHECK);
--  }
-+  for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
-+    copy_entry_to(from_cp, src_i, to_cp, dest_i, CHECK);
- 
--  for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) {
--    copy_entry_to(src_i, to_cp, dest_i, CHECK);
--
--    switch (tag_at(src_i).value()) {
-+    switch (from_cp->tag_at(src_i).value()) {
-     case JVM_CONSTANT_Double:
-     case JVM_CONSTANT_Long:
-       // double and long take two constant pool entries
-@@ -1022,30 +1002,81 @@
-       break;
-     }
-   }
-+
-+  int from_oplen = operand_array_length(from_cp->operands());
-+  int old_oplen  = operand_array_length(to_cp->operands());
-+  if (from_oplen != 0) {
-+    // append my operands to the target's operands array
-+    if (old_oplen == 0) {
-+      to_cp->set_operands(from_cp->operands());  // reuse; do not merge
-+    } else {
-+      int old_len  = to_cp->operands()->length();
-+      int from_len = from_cp->operands()->length();
-+      int old_off  = old_oplen * sizeof(u2);
-+      int from_off = from_oplen * sizeof(u2);
-+      typeArrayHandle new_operands = oopFactory::new_permanent_shortArray(old_len + from_len, CHECK);
-+      int fillp = 0, len = 0;
-+      // first part of dest
-+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
-+                                   new_operands->short_at_addr(fillp),
-+                                   (len = old_off) * sizeof(u2));
-+      fillp += len;
-+      // first part of src
-+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(0),
-+                                   new_operands->short_at_addr(fillp),
-+                                   (len = from_off) * sizeof(u2));
-+      fillp += len;
-+      // second part of dest
-+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(old_off),
-+                                   new_operands->short_at_addr(fillp),
-+                                   (len = old_len - old_off) * sizeof(u2));
-+      fillp += len;
-+      // second part of src
-+      Copy::conjoint_memory_atomic(to_cp->operands()->short_at_addr(from_off),
-+                                   new_operands->short_at_addr(fillp),
-+                                   (len = from_len - from_off) * sizeof(u2));
-+      fillp += len;
-+      assert(fillp == new_operands->length(), "");
-+
-+      // Adjust indexes in the first part of the copied operands array.
-+      for (int j = 0; j < from_oplen; j++) {
-+        int offset = operand_offset_at(new_operands(), old_oplen + j);
-+        assert(offset == operand_offset_at(from_cp->operands(), j), "correct copy");
-+        offset += old_len;  // every new tuple is preceded by old_len extra u2's
-+        operand_offset_at_put(new_operands(), old_oplen + j, offset);
-+      }
-+
-+      // replace target operands array with combined array
-+      to_cp->set_operands(new_operands());
-+    }
-+  }
-+
- } // end copy_cp_to()
- 
- 
- // Copy this constant pool's entry at from_i to the constant pool
- // to_cp's entry at to_i.
--void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp,
--       int to_i, TRAPS) {
-+void constantPoolOopDesc::copy_entry_to(constantPoolHandle from_cp, int from_i,
-+                                        constantPoolHandle to_cp, int to_i,
-+                                        TRAPS) {
- 
--  switch (tag_at(from_i).value()) {
-+  int tag = from_cp->tag_at(from_i).value();
-+  switch (tag) {
-   case JVM_CONSTANT_Class:
-   {
--    klassOop k = klass_at(from_i, CHECK);
-+    klassOop k = from_cp->klass_at(from_i, CHECK);
-     to_cp->klass_at_put(to_i, k);
-   } break;
- 
-   case JVM_CONSTANT_ClassIndex:
-   {
--    jint ki = klass_index_at(from_i);
-+    jint ki = from_cp->klass_index_at(from_i);
-     to_cp->klass_index_at_put(to_i, ki);
-   } break;
- 
-   case JVM_CONSTANT_Double:
-   {
--    jdouble d = double_at(from_i);
-+    jdouble d = from_cp->double_at(from_i);
-     to_cp->double_at_put(to_i, d);
-     // double takes two constant pool entries so init second entry's tag
-     to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
-@@ -1053,33 +1084,33 @@
- 
-   case JVM_CONSTANT_Fieldref:
-   {
--    int class_index = uncached_klass_ref_index_at(from_i);
--    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
-+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
-+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
-     to_cp->field_at_put(to_i, class_index, name_and_type_index);
-   } break;
- 
-   case JVM_CONSTANT_Float:
-   {
--    jfloat f = float_at(from_i);
-+    jfloat f = from_cp->float_at(from_i);
-     to_cp->float_at_put(to_i, f);
-   } break;
- 
-   case JVM_CONSTANT_Integer:
-   {
--    jint i = int_at(from_i);
-+    jint i = from_cp->int_at(from_i);
-     to_cp->int_at_put(to_i, i);
-   } break;
- 
-   case JVM_CONSTANT_InterfaceMethodref:
-   {
--    int class_index = uncached_klass_ref_index_at(from_i);
--    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
-+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
-+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
-     to_cp->interface_method_at_put(to_i, class_index, name_and_type_index);
-   } break;
- 
-   case JVM_CONSTANT_Long:
-   {
--    jlong l = long_at(from_i);
-+    jlong l = from_cp->long_at(from_i);
-     to_cp->long_at_put(to_i, l);
-     // long takes two constant pool entries so init second entry's tag
-     to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid);
-@@ -1087,39 +1118,39 @@
- 
-   case JVM_CONSTANT_Methodref:
-   {
--    int class_index = uncached_klass_ref_index_at(from_i);
--    int name_and_type_index = uncached_name_and_type_ref_index_at(from_i);
-+    int class_index = from_cp->uncached_klass_ref_index_at(from_i);
-+    int name_and_type_index = from_cp->uncached_name_and_type_ref_index_at(from_i);
-     to_cp->method_at_put(to_i, class_index, name_and_type_index);
-   } break;
- 
-   case JVM_CONSTANT_NameAndType:
-   {
--    int name_ref_index = name_ref_index_at(from_i);
--    int signature_ref_index = signature_ref_index_at(from_i);
-+    int name_ref_index = from_cp->name_ref_index_at(from_i);
-+    int signature_ref_index = from_cp->signature_ref_index_at(from_i);
-     to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index);
-   } break;
- 
-   case JVM_CONSTANT_String:
-   {
--    oop s = string_at(from_i, CHECK);
-+    oop s = from_cp->string_at(from_i, CHECK);
-     to_cp->string_at_put(to_i, s);
-   } break;
- 
-   case JVM_CONSTANT_StringIndex:
-   {
--    jint si = string_index_at(from_i);
-+    jint si = from_cp->string_index_at(from_i);
-     to_cp->string_index_at_put(to_i, si);
-   } break;
- 
-   case JVM_CONSTANT_UnresolvedClass:
-   {
--    symbolOop k = unresolved_klass_at(from_i);
-+    symbolOop k = from_cp->unresolved_klass_at(from_i);
-     to_cp->unresolved_klass_at_put(to_i, k);
-   } break;
- 
-   case JVM_CONSTANT_UnresolvedClassInError:
-   {
--    symbolOop k = unresolved_klass_at(from_i);
-+    symbolOop k = from_cp->unresolved_klass_at(from_i);
-     to_cp->unresolved_klass_at_put(to_i, k);
-     to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError);
-   } break;
-@@ -1127,51 +1158,42 @@
- 
-   case JVM_CONSTANT_UnresolvedString:
-   {
--    symbolOop s = unresolved_string_at(from_i);
-+    symbolOop s = from_cp->unresolved_string_at(from_i);
-     to_cp->unresolved_string_at_put(to_i, s);
-   } break;
- 
-   case JVM_CONSTANT_Utf8:
-   {
--    symbolOop s = symbol_at(from_i);
-+    symbolOop s = from_cp->symbol_at(from_i);
-     to_cp->symbol_at_put(to_i, s);
-   } break;
- 
-   case JVM_CONSTANT_MethodType:
-   {
--    jint k = method_type_index_at(from_i);
-+    jint k = from_cp->method_type_index_at(from_i);
-     to_cp->method_type_index_at_put(to_i, k);
-   } break;
- 
-   case JVM_CONSTANT_MethodHandle:
-   {
--    int k1 = method_handle_ref_kind_at(from_i);
--    int k2 = method_handle_index_at(from_i);
-+    int k1 = from_cp->method_handle_ref_kind_at(from_i);
-+    int k2 = from_cp->method_handle_index_at(from_i);
-     to_cp->method_handle_index_at_put(to_i, k1, k2);
-   } break;
- 
-+  case JVM_CONSTANT_InvokeDynamicTrans:
-+  {
-+    int k1 = from_cp->invoke_dynamic_bootstrap_method_ref_index_at(from_i);
-+    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
-+    to_cp->invoke_dynamic_trans_at_put(to_i, k1, k2);
-+  } break;
-+
-   case JVM_CONSTANT_InvokeDynamic:
-   {
--    int op_count = multi_operand_count_at(from_i);
--    int fillp = to_cp->multi_operand_buffer_fill_pointer();
--    int to_op_base = fillp - _multi_operand_count_offset;  // fillp is count offset; get to base
--    to_cp->multi_operand_buffer_grow(to_op_base + op_count, CHECK);
--    to_cp->operands()->int_at_put(fillp++, op_count);
--    assert(fillp == to_op_base + _multi_operand_base_offset, "just wrote count, will now write args");
--    for (int op_i = 0; op_i < op_count; op_i++) {
--      int op = multi_operand_ref_at(from_i, op_i);
--      to_cp->operands()->int_at_put(fillp++, op);
--    }
--    assert(fillp <= to_cp->operands()->length(), "oob");
--    to_cp->set_multi_operand_buffer_fill_pointer(fillp);
--    to_cp->invoke_dynamic_at_put(to_i, to_op_base, op_count);
--#ifdef ASSERT
--    int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i);
--    int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i);
--    int k3 = invoke_dynamic_argument_count_at(from_i);
--    assert(to_cp->check_invoke_dynamic_at(to_i, k1, k2, k3),
--           "indy structure is OK");
--#endif //ASSERT
-+    int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i);
-+    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
-+    k1 += operand_array_length(to_cp->operands());  // to_cp might already have operands
-+    to_cp->invoke_dynamic_at_put(to_i, k1, k2);
-   } break;
- 
-   // Invalid is used as the tag for the second constant pool entry
-@@ -1181,7 +1203,6 @@
- 
-   default:
-   {
--    jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb
-     ShouldNotReachHere();
-   } break;
-   }
-@@ -1392,8 +1413,9 @@
-       return 5;
- 
-     case JVM_CONSTANT_InvokeDynamic:
--      // u1 tag, u2 bsm, u2 nt, u2 argc, u2 argv[argc]
--      return 7 + 2 * invoke_dynamic_argument_count_at(idx);
-+    case JVM_CONSTANT_InvokeDynamicTrans:
-+      // u1 tag, u2 bsm, u2 nt
-+      return 5;
- 
-     case JVM_CONSTANT_Long:
-     case JVM_CONSTANT_Double:
-@@ -1606,19 +1628,15 @@
-         DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
-         break;
-       }
-+      case JVM_CONSTANT_InvokeDynamicTrans:
-       case JVM_CONSTANT_InvokeDynamic: {
--        *bytes = JVM_CONSTANT_InvokeDynamic;
--        idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx);
--        idx2 = invoke_dynamic_name_and_type_ref_index_at(idx);
--        int argc = invoke_dynamic_argument_count_at(idx);
-+        *bytes = tag;
-+        idx1 = extract_low_short_from_int(*int_at_addr(idx));
-+        idx2 = extract_high_short_from_int(*int_at_addr(idx));
-+        assert(idx2 == invoke_dynamic_name_and_type_ref_index_at(idx), "correct half of u4");
-         Bytes::put_Java_u2((address) (bytes+1), idx1);
-         Bytes::put_Java_u2((address) (bytes+3), idx2);
--        Bytes::put_Java_u2((address) (bytes+5), argc);
--        for (int arg_i = 0; arg_i < argc; arg_i++) {
--          int arg = invoke_dynamic_argument_index_at(idx, arg_i);
--          Bytes::put_Java_u2((address) (bytes+7+2*arg_i), arg);
--        }
--        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd [%d]", idx1, idx2, argc));
-+        DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2));
-         break;
-       }
-     }
-diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
---- a/src/share/vm/oops/constantPoolOop.hpp
-+++ b/src/share/vm/oops/constantPoolOop.hpp
-@@ -162,28 +162,16 @@
-     *int_at_addr(which) = ref_index;
-   }
- 
--  void invoke_dynamic_at_put(int which, int operand_base, int operand_count) {
-+  void invoke_dynamic_at_put(int which, int bootstrap_specifier_index, int name_and_type_index) {
-     tag_at_put(which, JVM_CONSTANT_InvokeDynamic);
--    *int_at_addr(which) = operand_base;  // this is the real information
-+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
-   }
--#ifdef ASSERT
--  bool check_invoke_dynamic_at(int which,
--                               int bootstrap_method_index,
--                               int name_and_type_index,
--                               int argument_count) {
--    assert(invoke_dynamic_bootstrap_method_ref_index_at(which) == bootstrap_method_index,
--           "already stored by caller");
--    assert(invoke_dynamic_name_and_type_ref_index_at(which) == name_and_type_index,
--           "already stored by caller");
--    assert(invoke_dynamic_argument_count_at(which) == argument_count,
--           "consistent argument count");
--    if (argument_count != 0) {
--      invoke_dynamic_argument_index_at(which, 0);
--      invoke_dynamic_argument_index_at(which, argument_count - 1);
--    }
--    return true;
-+
-+  void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) {
-+    tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans);
-+    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index;
-+    assert(AllowTransitionalJSR292, "");
-   }
--#endif //ASSERT
- 
-   // Temporary until actual use
-   void unresolved_string_at_put(int which, symbolOop s) {
-@@ -426,75 +414,90 @@
-     return symbol_at(sym);
-   }
- 
-- private:
--  // some nodes (InvokeDynamic) have a variable number of operands, each a u2 value
--  enum { _multi_operand_count_offset = -1,
--         _multi_operand_base_offset  = 0,
--         _multi_operand_buffer_fill_pointer_offset = 0  // shared at front of operands array
--  };
--  int multi_operand_buffer_length() {
--    return operands() == NULL ? 0 : operands()->length();
-+  int invoke_dynamic_name_and_type_ref_index_at(int which) {
-+    assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
-+    return extract_high_short_from_int(*int_at_addr(which));
-   }
--  int multi_operand_buffer_fill_pointer() {
--    return operands() == NULL
--      ? _multi_operand_buffer_fill_pointer_offset + 1
--      : operands()->int_at(_multi_operand_buffer_fill_pointer_offset);
-+  int invoke_dynamic_bootstrap_specifier_index(int which) {
-+    assert(tag_at(which).value() == JVM_CONSTANT_InvokeDynamic, "Corrupted constant pool");
-+    return extract_low_short_from_int(*int_at_addr(which));
-   }
--  void multi_operand_buffer_grow(int min_length, TRAPS);
--  void set_multi_operand_buffer_fill_pointer(int fillp) {
--    assert(operands() != NULL, "");
--    operands()->int_at_put(_multi_operand_buffer_fill_pointer_offset, fillp);
-+  int invoke_dynamic_operand_base(int which) {
-+    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
-+    return operand_offset_at(operands(), bootstrap_specifier_index);
-   }
--  int multi_operand_base_at(int which) {
--    assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    int op_base = *int_at_addr(which);
--    assert(op_base > _multi_operand_buffer_fill_pointer_offset, "Corrupted operand base");
--    return op_base;
-+  // The first part of the operands array consists of an index into the second part.
-+  // Extract a 32-bit index value from the first part.
-+  static int operand_offset_at(typeArrayOop operands, int bootstrap_specifier_index) {
-+    int n = (bootstrap_specifier_index * 2);
-+    assert(n >= 0 && n+2 <= operands->length(), "oob");
-+    // The first 32-bit index points to the beginning of the second part
-+    // of the operands array.  Make sure this index is in the first part.
-+    DEBUG_ONLY(int second_part = build_int_from_shorts(operands->short_at(0),
-+                                                       operands->short_at(1)));
-+    assert(second_part == 0 || n+2 <= second_part, "oob (2)");
-+    int offset = build_int_from_shorts(operands->short_at(n+0),
-+                                       operands->short_at(n+1));
-+    // The offset itself must point into the second part of the array.
-+    assert(offset == 0 || offset >= second_part && offset <= operands->length(), "oob (3)");
-+    return offset;
-   }
--  int multi_operand_count_at(int which) {
--    int op_base = multi_operand_base_at(which);
--    assert((uint)(op_base + _multi_operand_count_offset) < (uint)operands()->length(), "oob");
--    int count = operands()->int_at(op_base + _multi_operand_count_offset);
--    return count;
-+  static void operand_offset_at_put(typeArrayOop operands, int bootstrap_specifier_index, int offset) {
-+    int n = bootstrap_specifier_index * 2;
-+    assert(n >= 0 && n+2 <= operands->length(), "oob");
-+    operands->short_at_put(n+0, extract_low_short_from_int(offset));
-+    operands->short_at_put(n+1, extract_high_short_from_int(offset));
-   }
--  int multi_operand_ref_at(int which, int i) {
--    int op_base = multi_operand_base_at(which);
--    assert((uint)i < (uint)multi_operand_count_at(which), "oob");
--    assert((uint)(op_base + _multi_operand_base_offset + i) < (uint)operands()->length(), "oob");
--    return operands()->int_at(op_base + _multi_operand_base_offset + i);
--  }
--  void set_multi_operand_ref_at(int which, int i, int ref) {
--    DEBUG_ONLY(multi_operand_ref_at(which, i));  // trigger asserts
--    int op_base = multi_operand_base_at(which);
--    operands()->int_at_put(op_base + _multi_operand_base_offset + i, ref);
-+  static int operand_array_length(typeArrayOop operands) {
-+    if (operands == NULL || operands->length() == 0)  return 0;
-+    int second_part = operand_offset_at(operands, 0);
-+    return (second_part / 2);
-   }
- 
-- public:
--  // layout of InvokeDynamic:
-+#ifdef ASSERT
-+  // operand tuples fit together exactly, end to end
-+  static int operand_limit_at(typeArrayOop operands, int bootstrap_specifier_index) {
-+    int nextidx = bootstrap_specifier_index + 1;
-+    if (nextidx == operand_array_length(operands))
-+      return operands->length();
-+    else
-+      return operand_offset_at(operands, nextidx);
-+  }
-+  int invoke_dynamic_operand_limit(int which) {
-+    int bootstrap_specifier_index = invoke_dynamic_bootstrap_specifier_index(which);
-+    return operand_limit_at(operands(), bootstrap_specifier_index);
-+  }
-+#endif //ASSERT
-+
-+  // layout of InvokeDynamic bootstrap method specifier (in second part of operands array):
-   enum {
-          _indy_bsm_offset  = 0,  // CONSTANT_MethodHandle bsm
--         _indy_nt_offset   = 1,  // CONSTANT_NameAndType descr
--         _indy_argc_offset = 2,  // u2 argc
--         _indy_argv_offset = 3   // u2 argv[argc]
-+         _indy_argc_offset = 1,  // u2 argc
-+         _indy_argv_offset = 2   // u2 argv[argc]
-   };
-   int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
-     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    return multi_operand_ref_at(which, _indy_bsm_offset);
--  }
--  int invoke_dynamic_name_and_type_ref_index_at(int which) {
--    assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    return multi_operand_ref_at(which, _indy_nt_offset);
-+    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
-+      return extract_low_short_from_int(*int_at_addr(which));
-+    int op_base = invoke_dynamic_operand_base(which);
-+    return operands()->short_at(op_base + _indy_bsm_offset);
-   }
-   int invoke_dynamic_argument_count_at(int which) {
-     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    int argc = multi_operand_ref_at(which, _indy_argc_offset);
--    DEBUG_ONLY(int op_count = multi_operand_count_at(which));
--    assert(_indy_argv_offset + argc == op_count, "consistent inner and outer counts");
-+    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
-+      return 0;
-+    int op_base = invoke_dynamic_operand_base(which);
-+    int argc = operands()->short_at(op_base + _indy_argc_offset);
-+    DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc;
-+               int next_offset = invoke_dynamic_operand_limit(which));
-+    assert(end_offset == next_offset, "matched ending");
-     return argc;
-   }
-   int invoke_dynamic_argument_index_at(int which, int j) {
--    assert((uint)j < (uint)invoke_dynamic_argument_count_at(which), "oob");
--    return multi_operand_ref_at(which, _indy_argv_offset + j);
-+    int op_base = invoke_dynamic_operand_base(which);
-+    DEBUG_ONLY(int argc = operands()->short_at(op_base + _indy_argc_offset));
-+    assert((uint)j < (uint)argc, "oob");
-+    return operands()->short_at(op_base + _indy_argv_offset + j);
-   }
- 
-   // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve,
-@@ -642,9 +645,12 @@
-  public:
-   // Merging constantPoolOop support:
-   bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
--  void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i,
--    TRAPS);
--  void copy_entry_to(int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
-+  void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS) {
-+    constantPoolHandle h_this(THREAD, this);
-+    copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD);
-+  }
-+  static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
-+  static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
-   int  find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
-   int  orig_length() const                { return _orig_length; }
-   void set_orig_length(int orig_length)   { _orig_length = orig_length; }
-diff --git a/src/share/vm/prims/jvm.h b/src/share/vm/prims/jvm.h
---- a/src/share/vm/prims/jvm.h
-+++ b/src/share/vm/prims/jvm.h
-@@ -1048,7 +1048,8 @@
-     JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
-     JVM_CONSTANT_MethodType             = 16,  // JSR 292
-     JVM_CONSTANT_InvokeDynamicTrans     = 17,  // JSR 292, only occurs in old class files
--    JVM_CONSTANT_InvokeDynamic          = 18   // JSR 292
-+    JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
-+    JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
- };
- 
- /* JVM_CONSTANT_MethodHandle subtypes */
-diff --git a/src/share/vm/prims/jvmtiRedefineClasses.cpp b/src/share/vm/prims/jvmtiRedefineClasses.cpp
---- a/src/share/vm/prims/jvmtiRedefineClasses.cpp
-+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp
-@@ -201,7 +201,7 @@
-     case JVM_CONSTANT_Double:  // fall through
-     case JVM_CONSTANT_Long:
-     {
--      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
-+      constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p,
-         THREAD);
- 
-       if (scratch_i != *merge_cp_length_p) {
-@@ -226,7 +226,7 @@
-     case JVM_CONSTANT_UnresolvedClass:  // fall through
-     case JVM_CONSTANT_UnresolvedString:
-     {
--      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
-+      constantPoolOopDesc::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p,
-         THREAD);
- 
-       if (scratch_i != *merge_cp_length_p) {
-@@ -1080,13 +1080,13 @@
-       case JVM_CONSTANT_Long:
-         // just copy the entry to *merge_cp_p, but double and long take
-         // two constant pool entries
--        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
-+        constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0);
-         old_i++;
-         break;
- 
-       default:
-         // just copy the entry to *merge_cp_p
--        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
-+        constantPoolOopDesc::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0);
-         break;
-       }
-     } // end for each old_cp entry
-diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp
---- a/src/share/vm/runtime/vmStructs.cpp
-+++ b/src/share/vm/runtime/vmStructs.cpp
-@@ -1532,10 +1532,7 @@
-   /* constantPoolOop layout enum for InvokeDynamic */                     \
-   /*************************************************/                     \
-                                                                           \
--  declare_constant(constantPoolOopDesc::_multi_operand_count_offset)      \
--  declare_constant(constantPoolOopDesc::_multi_operand_base_offset)       \
-   declare_constant(constantPoolOopDesc::_indy_bsm_offset)                 \
--  declare_constant(constantPoolOopDesc::_indy_nt_offset)                  \
-   declare_constant(constantPoolOopDesc::_indy_argc_offset)                \
-   declare_constant(constantPoolOopDesc::_indy_argv_offset)                \
-                                                                           \
-diff --git a/src/share/vm/utilities/constantTag.cpp b/src/share/vm/utilities/constantTag.cpp
---- a/src/share/vm/utilities/constantTag.cpp
-+++ b/src/share/vm/utilities/constantTag.cpp
-@@ -93,6 +93,8 @@
-       return "MethodType";
-     case JVM_CONSTANT_InvokeDynamic :
-       return "InvokeDynamic";
-+    case JVM_CONSTANT_InvokeDynamicTrans :
-+      return "InvokeDynamic/transitional";
-     case JVM_CONSTANT_Object :
-       return "Object";
-     case JVM_CONSTANT_Utf8 :
-diff --git a/src/share/vm/utilities/constantTag.hpp b/src/share/vm/utilities/constantTag.hpp
---- a/src/share/vm/utilities/constantTag.hpp
-+++ b/src/share/vm/utilities/constantTag.hpp
-@@ -80,7 +80,8 @@
- 
-   bool is_method_type() const              { return _tag == JVM_CONSTANT_MethodType; }
-   bool is_method_handle() const            { return _tag == JVM_CONSTANT_MethodHandle; }
--  bool is_invoke_dynamic() const           { return _tag == JVM_CONSTANT_InvokeDynamic; }
-+  bool is_invoke_dynamic() const           { return (_tag == JVM_CONSTANT_InvokeDynamic ||
-+                                                     _tag == JVM_CONSTANT_InvokeDynamicTrans); }
- 
-   bool is_loadable_constant() const {
-     return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
--- a/indy-notrans-6981791.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1250 +0,0 @@
-6981791: remove experimental code for JSR 292
-Reviewed-by: twisti
-
-grep -n AllowTransitionalJSR292 $(hg loc -I src) \
-  && echo "*** ERROR: There is still code for transitional modes! "
-
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
---- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
-@@ -331,8 +331,6 @@
-     if (Assert.ASSERTS_ENABLED) {
-       Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool");
-     }
--    if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans)
--        return null;
-     int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
-     TypeArray operands = getOperands();
-     if (operands == null)  return null;  // safety first
-@@ -368,7 +366,6 @@
-     case JVM_CONSTANT_MethodHandle:       return "JVM_CONSTANT_MethodHandle";
-     case JVM_CONSTANT_MethodType:         return "JVM_CONSTANT_MethodType";
-     case JVM_CONSTANT_InvokeDynamic:      return "JVM_CONSTANT_InvokeDynamic";
--    case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional";
-     case JVM_CONSTANT_Invalid:            return "JVM_CONSTANT_Invalid";
-     case JVM_CONSTANT_UnresolvedClass:    return "JVM_CONSTANT_UnresolvedClass";
-     case JVM_CONSTANT_UnresolvedClassInError:    return "JVM_CONSTANT_UnresolvedClassInError";
-@@ -428,7 +425,6 @@
-         case JVM_CONSTANT_MethodHandle:
-         case JVM_CONSTANT_MethodType:
-         case JVM_CONSTANT_InvokeDynamic:
--        case JVM_CONSTANT_InvokeDynamicTrans:
-           visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
-           break;
-         }
-@@ -592,7 +588,6 @@
-                   break;
-               }
- 
--              case JVM_CONSTANT_InvokeDynamicTrans:
-               case JVM_CONSTANT_InvokeDynamic: {
-                   dos.writeByte(cpConstType);
-                   int value = getIntAt(ci);
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
---- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
-@@ -42,7 +42,7 @@
-     public static final int JVM_CONSTANT_NameAndType        = 12;
-     public static final int JVM_CONSTANT_MethodHandle       = 15;
-     public static final int JVM_CONSTANT_MethodType         = 16;
--    public static final int JVM_CONSTANT_InvokeDynamicTrans = 17;  // only occurs in old class files
-+    //     static final int JVM_CONSTANT_(unused)           = 17;
-     public static final int JVM_CONSTANT_InvokeDynamic      = 18;
- 
-     // JVM_CONSTANT_MethodHandle subtypes
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
---- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
-@@ -321,7 +321,6 @@
-                      break;
-                 }
- 
--                case JVM_CONSTANT_InvokeDynamicTrans:
-                 case JVM_CONSTANT_InvokeDynamic: {
-                      dos.writeByte(cpConstType);
-                      int value = cpool.getIntAt(ci);
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
---- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
-@@ -598,7 +598,6 @@
-                buf.cell(Integer.toString(cpool.getIntAt(index)));
-                break;
- 
--            case JVM_CONSTANT_InvokeDynamicTrans:
-             case JVM_CONSTANT_InvokeDynamic:
-                buf.cell("JVM_CONSTANT_InvokeDynamic");
-                buf.cell(genLowHighShort(cpool.getIntAt(index)) +
-diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
---- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
-+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
-@@ -40,7 +40,7 @@
-   private static int JVM_CONSTANT_NameAndType             = 12;
-   private static int JVM_CONSTANT_MethodHandle            = 15;  // JSR 292
-   private static int JVM_CONSTANT_MethodType              = 16;  // JSR 292
--  private static int JVM_CONSTANT_InvokeDynamicTrans      = 17;  // JSR 292, only occurs in old class files
-+  //      static int JVM_CONSTANT_(unused)                = 17;  // JSR 292 early drafts only
-   private static int JVM_CONSTANT_InvokeDynamic           = 18;  // JSR 292
-   private static int JVM_CONSTANT_Invalid                 = 0;   // For bad value initialization
-   private static int JVM_CONSTANT_UnresolvedClass         = 100; // Temporary tag until actual use
-@@ -83,7 +83,6 @@
-   public boolean isMethodHandle()     { return tag == JVM_CONSTANT_MethodHandle; }
-   public boolean isMethodType()       { return tag == JVM_CONSTANT_MethodType; }
-   public boolean isInvokeDynamic()    { return tag == JVM_CONSTANT_InvokeDynamic; }
--  public boolean isInvokeDynamicTrans() { return tag == JVM_CONSTANT_InvokeDynamicTrans; }
- 
-   public boolean isInvalid()          { return tag == JVM_CONSTANT_Invalid; }
- 
-diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
---- a/src/share/vm/classfile/classFileParser.cpp
-+++ b/src/share/vm/classfile/classFileParser.cpp
-@@ -169,7 +169,6 @@
-           ShouldNotReachHere();
-         }
-         break;
--      case JVM_CONSTANT_InvokeDynamicTrans :  // this tag appears only in old classfiles
-       case JVM_CONSTANT_InvokeDynamic :
-         {
-           if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
-@@ -185,14 +184,6 @@
-           cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
-           u2 bootstrap_specifier_index = cfs->get_u2_fast();
-           u2 name_and_type_index = cfs->get_u2_fast();
--          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
--            if (!AllowTransitionalJSR292)
--              classfile_parse_error(
--                "This JVM does not support transitional InvokeDynamic tag %u in class file %s",
--                tag, CHECK);
--            cp->invoke_dynamic_trans_at_put(index, bootstrap_specifier_index, name_and_type_index);
--            break;
--          }
-           if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index)
-             _max_bootstrap_specifier_index = (int) bootstrap_specifier_index;  // collect for later
-           cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);
-@@ -491,7 +482,6 @@
-               ref_index, CHECK_(nullHandle));
-         }
-         break;
--      case JVM_CONSTANT_InvokeDynamicTrans :
-       case JVM_CONSTANT_InvokeDynamic :
-         {
-           int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
-@@ -500,14 +490,6 @@
-                          "Invalid constant pool index %u in class file %s",
-                          name_and_type_ref_index,
-                          CHECK_(nullHandle));
--          if (tag == JVM_CONSTANT_InvokeDynamicTrans) {
--            int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
--            check_property(valid_cp_range(bootstrap_method_ref_index, length) &&
--                           cp->tag_at(bootstrap_method_ref_index).is_method_handle(),
--                           "Invalid constant pool index %u in class file %s",
--                           bootstrap_method_ref_index,
--                           CHECK_(nullHandle));
--          }
-           // bootstrap specifier index must be checked later, when BootstrapMethods attr is available
-           break;
-         }
-@@ -2822,7 +2804,6 @@
-     }
-   }
- 
--  if (AllowTransitionalJSR292 && word_sig_index == 0)  return;
-   if (word_sig_index == 0)
-     THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
-               "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle");
-@@ -2862,7 +2843,6 @@
-     }
-   }
- 
--  if (AllowTransitionalJSR292 && !found_vmentry)  return;
-   if (!found_vmentry)
-     THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
-               "missing vmentry byte field in java.lang.invoke.MethodHandle");
-@@ -3234,15 +3214,6 @@
-     if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
-       java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
-     }
--    if (AllowTransitionalJSR292 &&
--        EnableInvokeDynamic && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
--      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
--    }
--    if (AllowTransitionalJSR292 &&
--        EnableInvokeDynamic && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
--      // allow vmentry field in MethodHandleImpl also
--      java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
--    }
- 
-     // Add a fake "discovered" field if it is not present
-     // for compatibility with earlier jdk's.
-diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp
---- a/src/share/vm/classfile/javaClasses.cpp
-+++ b/src/share/vm/classfile/javaClasses.cpp
-@@ -69,28 +69,6 @@
-     return ik->find_local_field(name_symbol, signature_symbol, fd);
- }
- 
--static bool find_hacked_field(instanceKlass* ik,
--                              Symbol* name_symbol, Symbol* signature_symbol,
--                              fieldDescriptor* fd,
--                              bool allow_super = false) {
--  bool found = find_field(ik, name_symbol, signature_symbol, fd, allow_super);
--  if (!found && AllowTransitionalJSR292) {
--    Symbol* backup_sig = SystemDictionary::find_backup_signature(signature_symbol);
--    if (backup_sig != NULL) {
--      found = find_field(ik, name_symbol, backup_sig, fd, allow_super);
--      if (TraceMethodHandles) {
--        ResourceMark rm;
--        tty->print_cr("MethodHandles: %s.%s: backup for %s => %s%s",
--                      ik->name()->as_C_string(), name_symbol->as_C_string(),
--                      signature_symbol->as_C_string(), backup_sig->as_C_string(),
--                      (found ? "" : " (NOT FOUND)"));
--      }
--    }
--  }
--  return found;
--}
--#define find_field find_hacked_field  /* remove after AllowTransitionalJSR292 */
--
- // Helpful routine for computing field offsets at run time rather than hardcoding them
- static void
- compute_offset(int &dest_offset,
-@@ -2226,7 +2204,6 @@
-   klassOop k = SystemDictionary::MethodHandle_klass();
-   if (k != NULL && EnableInvokeDynamic) {
-     bool allow_super = false;
--    if (AllowTransitionalJSR292)  allow_super = true;  // temporary, to access java.dyn.MethodHandleImpl
-     compute_offset(_type_offset,      k, vmSymbols::type_name(),      vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
-     compute_offset(_vmtarget_offset,  k, vmSymbols::vmtarget_name(),  vmSymbols::object_signature(),                      allow_super);
-     compute_offset(_vmentry_offset,   k, vmSymbols::vmentry_name(),   vmSymbols::machine_word_signature(),                allow_super);
-diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp
---- a/src/share/vm/classfile/systemDictionary.cpp
-+++ b/src/share/vm/classfile/systemDictionary.cpp
-@@ -1887,99 +1887,27 @@
-   0
- };
- 
--Symbol* SystemDictionary::find_backup_symbol(Symbol* symbol,
--                                             const char* from_prefix,
--                                             const char* to_prefix) {
--  assert(AllowTransitionalJSR292, "");  // delete this subroutine
--  Symbol* backup_symbol = NULL;
--  size_t from_len = strlen(from_prefix);
--  if (strncmp((const char*) symbol->base(), from_prefix, from_len) != 0)
--    return NULL;
--  char buf[100];
--  size_t to_len = strlen(to_prefix);
--  size_t tail_len = symbol->utf8_length() - from_len;
--  size_t new_len = to_len + tail_len;
--  guarantee(new_len < sizeof(buf), "buf too small");
--  memcpy(buf, to_prefix, to_len);
--  memcpy(buf + to_len, symbol->base() + from_len, tail_len);
--  buf[new_len] = '\0';
--  vmSymbols::SID backup_sid = vmSymbols::find_sid(buf);
--  if (backup_sid != vmSymbols::NO_SID) {
--    backup_symbol = vmSymbols::symbol_at(backup_sid);
--  }
--  return backup_symbol;
--}
--
--Symbol* SystemDictionary::find_backup_class_name(Symbol* symbol) {
--  assert(AllowTransitionalJSR292, "");  // delete this subroutine
--  if (symbol == NULL)  return NULL;
--  Symbol* backup_symbol = find_backup_symbol(symbol, "java/lang/invoke/", "java/dyn/");  // AllowTransitionalJSR292 ONLY
--  if (backup_symbol == NULL)
--    backup_symbol = find_backup_symbol(symbol, "java/dyn/", "sun/dyn/");  // AllowTransitionalJSR292 ONLY
--  return backup_symbol;
--}
--
--Symbol* SystemDictionary::find_backup_signature(Symbol* symbol) {
--  assert(AllowTransitionalJSR292, "");  // delete this subroutine
--  if (symbol == NULL)  return NULL;
--  return find_backup_symbol(symbol, "Ljava/lang/invoke/", "Ljava/dyn/");
--}
--
- bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
-   assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
-   int  info = wk_init_info[id - FIRST_WKID];
-   int  sid  = (info >> CEIL_LG_OPTION_LIMIT);
-   Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
-   klassOop*    klassp = &_well_known_klasses[id];
--  bool pre_load = (init_opt < SystemDictionary::Opt);
--  bool try_load = true;
-+  bool must_load = (init_opt < SystemDictionary::Opt);
-+  bool try_load  = true;
-   if (init_opt == SystemDictionary::Opt_Kernel) {
- #ifndef KERNEL
-     try_load = false;
- #endif //KERNEL
-   }
--  Symbol* backup_symbol = NULL;  // symbol to try if the current symbol fails
--  if (init_opt == SystemDictionary::Pre_JSR292) {
--    if (!EnableInvokeDynamic)  try_load = false;  // do not bother to load such classes
--    if (AllowTransitionalJSR292) {
--      backup_symbol = find_backup_class_name(symbol);
--      if (try_load && PreferTransitionalJSR292) {
--        while (backup_symbol != NULL) {
--          (*klassp) = resolve_or_null(backup_symbol, CHECK_0); // try backup early
--          if (TraceMethodHandles) {
--            ResourceMark rm;
--            tty->print_cr("MethodHandles: try backup first for %s => %s (%s)",
--                          symbol->as_C_string(), backup_symbol->as_C_string(),
--                          ((*klassp) == NULL) ? "no such class" : "backup load succeeded");
--          }
--          if ((*klassp) != NULL)  return true;
--          backup_symbol = find_backup_class_name(backup_symbol);  // find next backup
--        }
--      }
--    }
--  }
--  if ((*klassp) != NULL)  return true;
--  if (!try_load)          return false;
--  while (symbol != NULL) {
--    bool must_load = (pre_load && (backup_symbol == NULL));
-+  if ((*klassp) == NULL && try_load) {
-     if (must_load) {
-       (*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
-     } else {
-       (*klassp) = resolve_or_null(symbol,       CHECK_0); // load optional klass
-     }
--    if ((*klassp) != NULL)  return true;
--    // Go around again.  Example of long backup sequence:
--    // java.lang.invoke.MemberName, java.dyn.MemberName, sun.dyn.MemberName, ONLY if AllowTransitionalJSR292
--    if (TraceMethodHandles && (backup_symbol != NULL)) {
--      ResourceMark rm;
--      tty->print_cr("MethodHandles: backup for %s => %s",
--                    symbol->as_C_string(), backup_symbol->as_C_string());
--    }
--    symbol = backup_symbol;
--    if (AllowTransitionalJSR292)
--      backup_symbol = find_backup_class_name(symbol);
-   }
--  return false;
-+  return ((*klassp) != NULL);
- }
- 
- void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) {
-@@ -2409,9 +2337,7 @@
-     // Must create lots of stuff here, but outside of the SystemDictionary lock.
-     if (THREAD->is_Compiler_thread())
-       return NULL;              // do not attempt from within compiler
--    bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name));
--    if (AllowInvokeForInvokeGeneric && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
--      for_invokeGeneric = true;
-+    bool for_invokeGeneric = (name_id != vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name));
-     bool found_on_bcp = false;
-     Handle mt = find_method_handle_type(signature, accessing_klass,
-                                         for_invokeGeneric,
-@@ -2498,14 +2424,10 @@
-   JavaCallArguments args(Handle(THREAD, rt()));
-   args.push_oop(pts());
-   JavaValue result(T_OBJECT);
--  Symbol* findMethodHandleType_signature = vmSymbols::findMethodHandleType_signature();
--  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
--    findMethodHandleType_signature = vmSymbols::findMethodHandleType_TRANS_signature();
--  }
-   JavaCalls::call_static(&result,
-                          SystemDictionary::MethodHandleNatives_klass(),
-                          vmSymbols::findMethodHandleType_name(),
--                         findMethodHandleType_signature,
-+                         vmSymbols::findMethodHandleType_signature(),
-                          &args, CHECK_(empty));
-   Handle method_type(THREAD, (oop) result.get_jobject());
- 
-@@ -2513,14 +2435,10 @@
-     // call java.lang.invoke.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
-     JavaCallArguments args(Handle(THREAD, method_type()));
-     JavaValue no_result(T_VOID);
--    Symbol* notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_signature();
--    if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodType_klass()->name() == vmSymbols::java_dyn_MethodType()) {
--      notifyGenericMethodType_signature = vmSymbols::notifyGenericMethodType_TRANS_signature();
--    }
-     JavaCalls::call_static(&no_result,
-                            SystemDictionary::MethodHandleNatives_klass(),
-                            vmSymbols::notifyGenericMethodType_name(),
--                           notifyGenericMethodType_signature,
-+                           vmSymbols::notifyGenericMethodType_signature(),
-                            &args, THREAD);
-     if (HAS_PENDING_EXCEPTION) {
-       // If the notification fails, just kill it.
-@@ -2569,14 +2487,10 @@
-   args.push_oop(name());
-   args.push_oop(type());
-   JavaValue result(T_OBJECT);
--  Symbol* linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_signature();
--  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandle_klass()->name() == vmSymbols::java_dyn_MethodHandle()) {
--    linkMethodHandleConstant_signature = vmSymbols::linkMethodHandleConstant_TRANS_signature();
--  }
-   JavaCalls::call_static(&result,
-                          SystemDictionary::MethodHandleNatives_klass(),
-                          vmSymbols::linkMethodHandleConstant_name(),
--                         linkMethodHandleConstant_signature,
-+                         vmSymbols::linkMethodHandleConstant_signature(),
-                          &args, CHECK_(empty));
-   return Handle(THREAD, (oop) result.get_jobject());
- }
-@@ -2607,17 +2521,10 @@
-   args.push_oop(caller_mname());
-   args.push_int(caller_bci);
-   JavaValue result(T_OBJECT);
--  Symbol* makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_signature();
--  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::sun_dyn_MethodHandleNatives()) {
--    makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS_signature();
--  }
--  if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::java_dyn_MethodHandleNatives()) {
--    makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS2_signature();
--  }
-   JavaCalls::call_static(&result,
-                          SystemDictionary::MethodHandleNatives_klass(),
-                          vmSymbols::makeDynamicCallSite_name(),
--                         makeDynamicCallSite_signature,
-+                         vmSymbols::makeDynamicCallSite_signature(),
-                          &args, CHECK_(empty));
-   oop call_site_oop = (oop) result.get_jobject();
-   assert(call_site_oop->is_oop()
-@@ -2698,28 +2605,10 @@
-       argument_info_result = argument_info;  // return argument_info to caller
-       return bsm;
-     }
--    // else null BSM; fall through
--  } else if (tag.is_name_and_type()) {
--    // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic
--    // a bare name&type defaults its BSM to null, so fall through...
-   } else {
-     ShouldNotReachHere();  // verifier does not allow this
-   }
- 
--  // Fall through to pick up the per-class bootstrap method.
--  // This mechanism may go away in the PFD.
--  assert(AllowTransitionalJSR292, "else the verifier should have stopped us already");
--  argument_info_result = empty;  // return no argument_info to caller
--  oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method();
--  if (bsm_oop != NULL) {
--    if (TraceMethodHandles) {
--      tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":",
--                    (intptr_t) caller_method(), (intptr_t) bsm_oop);
--    }
--    assert(bsm_oop->is_oop(), "must be sane");
--    return Handle(THREAD, bsm_oop);
--  }
--
-   return empty;
- }
- 
-diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp
---- a/src/share/vm/classfile/systemDictionary.hpp
-+++ b/src/share/vm/classfile/systemDictionary.hpp
-@@ -146,7 +146,6 @@
-   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
-   template(MethodHandle_klass,           java_lang_invoke_MethodHandle,     Pre_JSR292) \
-   template(MemberName_klass,             java_lang_invoke_MemberName,       Pre_JSR292) \
--  template(MethodHandleImpl_klass,       sun_dyn_MethodHandleImpl,          Opt) /* AllowTransitionalJSR292 ONLY */ \
-   template(MethodHandleNatives_klass,    java_lang_invoke_MethodHandleNatives, Pre_JSR292) \
-   template(AdapterMethodHandle_klass,    java_lang_invoke_AdapterMethodHandle, Pre_JSR292) \
-   template(BoundMethodHandle_klass,      java_lang_invoke_BoundMethodHandle, Pre_JSR292) \
-@@ -154,7 +153,6 @@
-   template(MethodType_klass,             java_lang_invoke_MethodType,       Pre_JSR292) \
-   template(MethodTypeForm_klass,         java_lang_invoke_MethodTypeForm,   Pre_JSR292) \
-   template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
--  template(Linkage_klass,                java_lang_invoke_Linkage,          Opt) /* AllowTransitionalJSR292 ONLY */ \
-   template(CallSite_klass,               java_lang_invoke_CallSite,         Pre_JSR292) \
-   /* Note: MethodHandle must be first, and CallSite last in group */          \
-                                                                               \
-@@ -422,8 +420,6 @@
-     initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
-   }
- 
--  static Symbol* find_backup_symbol(Symbol* symbol, const char* from_prefix, const char* to_prefix);
--
- public:
-   #define WK_KLASS_DECLARE(name, ignore_symbol, option) \
-     static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
-@@ -445,9 +441,6 @@
- 
-   static void load_abstract_ownable_synchronizer_klass(TRAPS);
- 
--  static Symbol* find_backup_class_name(Symbol* class_name_symbol);
--  static Symbol* find_backup_signature(Symbol* signature_symbol);
--
- private:
-   // Tells whether ClassLoader.loadClassInternal is present
-   static bool has_loadClassInternal()       { return _has_loadClassInternal; }
-diff --git a/src/share/vm/classfile/verifier.cpp b/src/share/vm/classfile/verifier.cpp
---- a/src/share/vm/classfile/verifier.cpp
-+++ b/src/share/vm/classfile/verifier.cpp
-@@ -1671,19 +1671,13 @@
-       VerificationType::long_type(),
-       VerificationType::long2_type(), CHECK_VERIFY(this));
-   } else if (tag.is_method_handle()) {
--    Symbol* methodHandle_name = vmSymbols::java_lang_invoke_MethodHandle();
--    if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
--      methodHandle_name = SystemDictionaryHandles::MethodHandle_klass()->name();
-     current_frame->push_stack(
-       VerificationType::reference_type(
--        methodHandle_name), CHECK_VERIFY(this));
-+        vmSymbols::java_lang_invoke_MethodHandle()), CHECK_VERIFY(this));
-   } else if (tag.is_method_type()) {
--    Symbol* methodType_name = vmSymbols::java_lang_invoke_MethodType();
--    if (AllowTransitionalJSR292 && !Universe::is_bootstrapping())
--      methodType_name = SystemDictionaryHandles::MethodType_klass()->name();
-     current_frame->push_stack(
-       VerificationType::reference_type(
--        methodType_name), CHECK_VERIFY(this));
-+        vmSymbols::java_lang_invoke_MethodType()), CHECK_VERIFY(this));
-   } else {
-     verify_error(bci, "Invalid index in ldc");
-     return;
-@@ -1950,8 +1944,7 @@
-   unsigned int types = (opcode == Bytecodes::_invokeinterface
-                                 ? 1 << JVM_CONSTANT_InterfaceMethodref
-                       : opcode == Bytecodes::_invokedynamic
--                                ? ((AllowTransitionalJSR292 ? 1 << JVM_CONSTANT_NameAndType : 0)
--                                  |1 << JVM_CONSTANT_InvokeDynamic)
-+                                ? 1 << JVM_CONSTANT_InvokeDynamic
-                                 : 1 << JVM_CONSTANT_Methodref);
-   verify_cp_type(index, cp, types, CHECK_VERIFY(this));
- 
-diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp
---- a/src/share/vm/classfile/vmSymbols.hpp
-+++ b/src/share/vm/classfile/vmSymbols.hpp
-@@ -245,44 +245,15 @@
-   template(java_lang_invoke_AdapterMethodHandle,      "java/lang/invoke/AdapterMethodHandle")     \
-   template(java_lang_invoke_BoundMethodHandle,        "java/lang/invoke/BoundMethodHandle")       \
-   template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
--  /* temporary transitional public names from 6839872: */                                         \
--  template(java_dyn_InvokeDynamic,                    "java/dyn/InvokeDynamic")         /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_Linkage,                          "java/dyn/Linkage")               /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_CallSite,                         "java/dyn/CallSite")              /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodHandle,                     "java/dyn/MethodHandle")          /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodType,                       "java/dyn/MethodType")            /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_WrongMethodTypeException,         "java/dyn/WrongMethodTypeException") /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodType_signature,             "Ljava/dyn/MethodType;")          /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodHandle_signature,           "Ljava/dyn/MethodHandle;")        /* AllowTransitionalJSR292 ONLY */ \
--  /* temporary transitional internal names from 6839872: */                                       \
--  template(java_dyn_MethodTypeForm,                   "java/dyn/MethodTypeForm")        /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodTypeForm_signature,         "Ljava/dyn/MethodTypeForm;")      /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MemberName,                       "java/dyn/MemberName")            /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_MethodHandleNatives,              "java/dyn/MethodHandleNatives")   /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_AdapterMethodHandle,              "java/dyn/AdapterMethodHandle")   /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_BoundMethodHandle,                "java/dyn/BoundMethodHandle")     /* AllowTransitionalJSR292 ONLY */ \
--  template(java_dyn_DirectMethodHandle,               "java/dyn/DirectMethodHandle")    /* AllowTransitionalJSR292 ONLY */ \
--  /* temporary transitional internal names from EDR: */                                           \
--  template(sun_dyn_MemberName,                        "sun/dyn/MemberName")             /* AllowTransitionalJSR292 ONLY */ \
--  template(sun_dyn_MethodHandleImpl,                  "sun/dyn/MethodHandleImpl")       /* AllowTransitionalJSR292 ONLY */ \
--  template(sun_dyn_MethodHandleNatives,               "sun/dyn/MethodHandleNatives")    /* AllowTransitionalJSR292 ONLY */ \
--  template(sun_dyn_AdapterMethodHandle,               "sun/dyn/AdapterMethodHandle")    /* AllowTransitionalJSR292 ONLY */ \
--  template(sun_dyn_BoundMethodHandle,                 "sun/dyn/BoundMethodHandle")      /* AllowTransitionalJSR292 ONLY */ \
--  template(sun_dyn_DirectMethodHandle,                "sun/dyn/DirectMethodHandle")     /* AllowTransitionalJSR292 ONLY */ \
-   /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */         \
-   template(findMethodHandleType_name,                 "findMethodHandleType")                     \
-   template(findMethodHandleType_signature,       "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
--  template(findMethodHandleType_TRANS_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") /* AllowTransitionalJSR292 ONLY */ \
-   template(notifyGenericMethodType_name,              "notifyGenericMethodType")                  \
-   template(notifyGenericMethodType_signature,         "(Ljava/lang/invoke/MethodType;)V")         \
--  template(notifyGenericMethodType_TRANS_signature,   "(Ljava/dyn/MethodType;)V")       /* AllowTransitionalJSR292 ONLY */ \
-   template(linkMethodHandleConstant_name,             "linkMethodHandleConstant")                 \
-   template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
--  template(linkMethodHandleConstant_TRANS_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") /* AllowTransitionalJSR292 ONLY */ \
-   template(makeDynamicCallSite_name,                  "makeDynamicCallSite")                      \
-   template(makeDynamicCallSite_signature, "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/invoke/MemberName;I)Ljava/lang/invoke/CallSite;") \
--  template(makeDynamicCallSite_TRANS_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
--  template(makeDynamicCallSite_TRANS2_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Ljava/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
-   NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
-   LP64_ONLY( do_alias(machine_word_signature,         long_signature) )                           \
-                                                                                                   \
-@@ -910,8 +881,6 @@
-   do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
-   /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
-   do_intrinsic(_checkSpreadArgument,      java_lang_invoke_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
--  do_intrinsic(_checkSpreadArgument_TRANS,sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
--  do_intrinsic(_checkSpreadArgument_TRANS2,java_dyn_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
-    do_name(    checkSpreadArgument_name,       "checkSpreadArgument")                                                   \
-    do_name(    checkSpreadArgument_signature,  "(Ljava/lang/Object;I)V")                                                \
-   do_intrinsic(_invokeExact,              java_lang_invoke_MethodHandle, invokeExact_name,   object_array_object_signature, F_RN) \
-diff --git a/src/share/vm/interpreter/bytecodeTracer.cpp b/src/share/vm/interpreter/bytecodeTracer.cpp
---- a/src/share/vm/interpreter/bytecodeTracer.cpp
-+++ b/src/share/vm/interpreter/bytecodeTracer.cpp
-@@ -345,7 +345,6 @@
-     break;
-   case JVM_CONSTANT_NameAndType:
-   case JVM_CONSTANT_InvokeDynamic:
--  case JVM_CONSTANT_InvokeDynamicTrans:
-     has_klass = false;
-     break;
-   default:
-diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp
---- a/src/share/vm/interpreter/interpreterRuntime.cpp
-+++ b/src/share/vm/interpreter/interpreterRuntime.cpp
-@@ -369,10 +369,7 @@
-   }
- 
-   // create exception
--  Symbol* java_lang_invoke_WrongMethodTypeException = vmSymbols::java_lang_invoke_WrongMethodTypeException();
--  if (AllowTransitionalJSR292)
--    java_lang_invoke_WrongMethodTypeException = SystemDictionaryHandles::WrongMethodTypeException_klass()->name();
--  THROW_MSG(java_lang_invoke_WrongMethodTypeException, message);
-+  THROW_MSG(vmSymbols::java_lang_invoke_WrongMethodTypeException(), message);
- }
- IRT_END
- 
-diff --git a/src/share/vm/interpreter/linkResolver.cpp b/src/share/vm/interpreter/linkResolver.cpp
---- a/src/share/vm/interpreter/linkResolver.cpp
-+++ b/src/share/vm/interpreter/linkResolver.cpp
-@@ -224,9 +224,7 @@
-       // Make sure the Java part of the runtime has been booted up.
-       klassOop natives = SystemDictionary::MethodHandleNatives_klass();
-       if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
--        Symbol* natives_name = vmSymbols::java_lang_invoke_MethodHandleNatives();
--        if (natives != NULL && AllowTransitionalJSR292)  natives_name = Klass::cast(natives)->name();
--        SystemDictionary::resolve_or_fail(natives_name,
-+        SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
-                                           Handle(),
-                                           Handle(),
-                                           true,
-diff --git a/src/share/vm/interpreter/rewriter.cpp b/src/share/vm/interpreter/rewriter.cpp
---- a/src/share/vm/interpreter/rewriter.cpp
-+++ b/src/share/vm/interpreter/rewriter.cpp
-@@ -52,7 +52,6 @@
-       case JVM_CONSTANT_MethodHandle      : // fall through
-       case JVM_CONSTANT_MethodType        : // fall through
-       case JVM_CONSTANT_InvokeDynamic     : // fall through
--      case JVM_CONSTANT_InvokeDynamicTrans: // fall through
-         add_cp_cache_entry(i);
-         break;
-     }
-@@ -62,7 +61,6 @@
-             "all cp cache indexes fit in a u2");
- 
-   _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0);
--  _have_invoke_dynamic |= ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamicTrans)) != 0);
- }
- 
- 
-@@ -81,16 +79,10 @@
-       if (pool_index >= 0 &&
-           _pool->tag_at(pool_index).is_invoke_dynamic()) {
-         int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index);
--        if (bsm_index != 0) {
--          assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
--          // There is a CP cache entry holding the BSM for these calls.
--          int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
--          cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
--        } else {
--          // There is no CP cache entry holding the BSM for these calls.
--          // We will need to look for a class-global BSM, later.
--          guarantee(AllowTransitionalJSR292, "");
--        }
-+        assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
-+        // There is a CP cache entry holding the BSM for these calls.
-+        int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
-+        cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
-       }
-     }
-   }
-diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
---- a/src/share/vm/oops/constantPoolKlass.cpp
-+++ b/src/share/vm/oops/constantPoolKlass.cpp
-@@ -383,7 +383,6 @@
-       case JVM_CONSTANT_MethodType :
-         st->print("signature_index=%d", cp->method_type_index_at(index));
-         break;
--      case JVM_CONSTANT_InvokeDynamicTrans :
-       case JVM_CONSTANT_InvokeDynamic :
-         {
-           st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index));
-diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
---- a/src/share/vm/oops/constantPoolOop.cpp
-+++ b/src/share/vm/oops/constantPoolOop.cpp
-@@ -284,17 +284,13 @@
-     if (constantPoolCacheOopDesc::is_secondary_index(which)) {
-       // Invokedynamic index.
-       int pool_index = cache()->main_entry_at(which)->constant_pool_index();
--      if (!AllowTransitionalJSR292 || tag_at(pool_index).is_invoke_dynamic())
--        pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
-+      pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
-       assert(tag_at(pool_index).is_name_and_type(), "");
-       return pool_index;
-     }
-     // change byte-ordering and go via cache
-     i = remap_instruction_operand_from_cache(which);
-   } else {
--    if (AllowTransitionalJSR292 && tag_at(which).is_name_and_type())
--      // invokedynamic index is a simple name-and-type
--      return which;
-     if (tag_at(which).is_invoke_dynamic()) {
-       int pool_index = invoke_dynamic_name_and_type_ref_index_at(which);
-       assert(tag_at(pool_index).is_name_and_type(), "");
-@@ -953,7 +949,6 @@
-   } break;
- 
-   case JVM_CONSTANT_InvokeDynamic:
--  case JVM_CONSTANT_InvokeDynamicTrans:
-   {
-     int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1);
-     int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2);
-@@ -1214,13 +1209,6 @@
-     to_cp->method_handle_index_at_put(to_i, k1, k2);
-   } break;
- 
--  case JVM_CONSTANT_InvokeDynamicTrans:
--  {
--    int k1 = from_cp->invoke_dynamic_bootstrap_method_ref_index_at(from_i);
--    int k2 = from_cp->invoke_dynamic_name_and_type_ref_index_at(from_i);
--    to_cp->invoke_dynamic_trans_at_put(to_i, k1, k2);
--  } break;
--
-   case JVM_CONSTANT_InvokeDynamic:
-   {
-     int k1 = from_cp->invoke_dynamic_bootstrap_specifier_index(from_i);
-@@ -1446,7 +1434,6 @@
-       return 5;
- 
-     case JVM_CONSTANT_InvokeDynamic:
--    case JVM_CONSTANT_InvokeDynamicTrans:
-       // u1 tag, u2 bsm, u2 nt
-       return 5;
- 
-@@ -1661,7 +1648,6 @@
-         DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
-         break;
-       }
--      case JVM_CONSTANT_InvokeDynamicTrans:
-       case JVM_CONSTANT_InvokeDynamic: {
-         *bytes = tag;
-         idx1 = extract_low_short_from_int(*int_at_addr(idx));
-diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
---- a/src/share/vm/oops/constantPoolOop.hpp
-+++ b/src/share/vm/oops/constantPoolOop.hpp
-@@ -244,12 +244,6 @@
-     *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_specifier_index;
-   }
- 
--  void invoke_dynamic_trans_at_put(int which, int bootstrap_method_index, int name_and_type_index) {
--    tag_at_put(which, JVM_CONSTANT_InvokeDynamicTrans);
--    *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index;
--    assert(AllowTransitionalJSR292, "");
--  }
--
-   // Temporary until actual use
-   void unresolved_string_at_put(int which, Symbol* s) {
-     release_tag_at_put(which, JVM_CONSTANT_UnresolvedString);
-@@ -570,15 +564,11 @@
-   };
-   int invoke_dynamic_bootstrap_method_ref_index_at(int which) {
-     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
--      return extract_low_short_from_int(*int_at_addr(which));
-     int op_base = invoke_dynamic_operand_base(which);
-     return operands()->short_at(op_base + _indy_bsm_offset);
-   }
-   int invoke_dynamic_argument_count_at(int which) {
-     assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
--    if (tag_at(which).value() == JVM_CONSTANT_InvokeDynamicTrans)
--      return 0;
-     int op_base = invoke_dynamic_operand_base(which);
-     int argc = operands()->short_at(op_base + _indy_argc_offset);
-     DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc;
-diff --git a/src/share/vm/oops/cpCacheOop.cpp b/src/share/vm/oops/cpCacheOop.cpp
---- a/src/share/vm/oops/cpCacheOop.cpp
-+++ b/src/share/vm/oops/cpCacheOop.cpp
-@@ -185,7 +185,7 @@
-         this->print(tty, 0);
-       }
-       assert(method->can_be_statically_bound(), "must be a MH invoker method");
--      assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
-+      assert(_f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
-       // SystemDictionary::find_method_handle_invoke only caches
-       // methods which signature classes are on the boot classpath,
-       // otherwise the newly created method is returned.  To avoid
-diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp
---- a/src/share/vm/oops/instanceKlass.hpp
-+++ b/src/share/vm/oops/instanceKlass.hpp
-@@ -193,8 +193,6 @@
-   typeArrayOop    _inner_classes;
-   // Implementors of this interface (not valid if it overflows)
-   klassOop        _implementors[implementors_limit];
--  // invokedynamic bootstrap method (a java.lang.invoke.MethodHandle)
--  oop             _bootstrap_method;  // AllowTransitionalJSR292 ONLY
-   // Annotations for this class, or null if none.
-   typeArrayOop    _class_annotations;
-   // Annotation objects (byte arrays) for fields, or null if no annotations.
-@@ -528,10 +526,6 @@
-                                     u2 method_index)  { _enclosing_method_class_index  = class_index;
-                                                         _enclosing_method_method_index = method_index; }
- 
--  // JSR 292 support
--  oop bootstrap_method() const                        { return _bootstrap_method; }  // AllowTransitionalJSR292 ONLY
--  void set_bootstrap_method(oop mh)                   { oop_store(&_bootstrap_method, mh); }
--
-   // jmethodID support
-   static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
-                      methodHandle method_h);
-@@ -817,7 +811,6 @@
-   oop* adr_signers() const           { return (oop*)&this->_signers;}
-   oop* adr_inner_classes() const     { return (oop*)&this->_inner_classes;}
-   oop* adr_implementors() const      { return (oop*)&this->_implementors[0];}
--  oop* adr_bootstrap_method() const  { return (oop*)&this->_bootstrap_method;}  // AllowTransitionalJSR292 ONLY
-   oop* adr_methods_jmethod_ids() const             { return (oop*)&this->_methods_jmethod_ids;}
-   oop* adr_methods_cached_itable_indices() const   { return (oop*)&this->_methods_cached_itable_indices;}
-   oop* adr_class_annotations() const   { return (oop*)&this->_class_annotations;}
-diff --git a/src/share/vm/oops/instanceKlassKlass.cpp b/src/share/vm/oops/instanceKlassKlass.cpp
---- a/src/share/vm/oops/instanceKlassKlass.cpp
-+++ b/src/share/vm/oops/instanceKlassKlass.cpp
-@@ -105,7 +105,6 @@
-   MarkSweep::mark_and_push(ik->adr_protection_domain());
-   MarkSweep::mark_and_push(ik->adr_host_klass());
-   MarkSweep::mark_and_push(ik->adr_signers());
--  MarkSweep::mark_and_push(ik->adr_bootstrap_method());
-   MarkSweep::mark_and_push(ik->adr_class_annotations());
-   MarkSweep::mark_and_push(ik->adr_fields_annotations());
-   MarkSweep::mark_and_push(ik->adr_methods_annotations());
-@@ -143,7 +142,6 @@
-   PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
-   PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
-   PSParallelCompact::mark_and_push(cm, ik->adr_signers());
--  PSParallelCompact::mark_and_push(cm, ik->adr_bootstrap_method());
-   PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
-   PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations());
-   PSParallelCompact::mark_and_push(cm, ik->adr_methods_annotations());
-@@ -187,7 +185,6 @@
-   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-     blk->do_oop(&ik->adr_implementors()[i]);
-   }
--  blk->do_oop(ik->adr_bootstrap_method());
-   blk->do_oop(ik->adr_class_annotations());
-   blk->do_oop(ik->adr_fields_annotations());
-   blk->do_oop(ik->adr_methods_annotations());
-@@ -242,8 +239,6 @@
-   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-     if (mr.contains(&adr[i])) blk->do_oop(&adr[i]);
-   }
--  adr = ik->adr_bootstrap_method();
--  if (mr.contains(adr)) blk->do_oop(adr);
-   adr = ik->adr_class_annotations();
-   if (mr.contains(adr)) blk->do_oop(adr);
-   adr = ik->adr_fields_annotations();
-@@ -285,7 +280,6 @@
-   for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-     MarkSweep::adjust_pointer(&ik->adr_implementors()[i]);
-   }
--  MarkSweep::adjust_pointer(ik->adr_bootstrap_method());
-   MarkSweep::adjust_pointer(ik->adr_class_annotations());
-   MarkSweep::adjust_pointer(ik->adr_fields_annotations());
-   MarkSweep::adjust_pointer(ik->adr_methods_annotations());
-@@ -322,11 +316,6 @@
-     pm->claim_or_forward_depth(sg_addr);
-   }
- 
--  oop* bsm_addr = ik->adr_bootstrap_method();
--  if (PSScavenge::should_scavenge(bsm_addr)) {
--    pm->claim_or_forward_depth(bsm_addr);
--  }
--
-   klassKlass::oop_push_contents(pm, obj);
- }
- 
-@@ -420,7 +409,6 @@
-     ik->set_breakpoints(NULL);
-     ik->init_previous_versions();
-     ik->set_generic_signature(NULL);
--    ik->set_bootstrap_method(NULL);
-     ik->release_set_methods_jmethod_ids(NULL);
-     ik->release_set_methods_cached_itable_indices(NULL);
-     ik->set_class_annotations(NULL);
-@@ -545,11 +533,6 @@
-     } // pvw is cleaned up
-   } // rm is cleaned up
- 
--  if (ik->bootstrap_method() != NULL) {
--    st->print(BULLET"bootstrap method:  ");
--    ik->bootstrap_method()->print_value_on(st);
--    st->cr();
--  }
-   if (ik->generic_signature() != NULL) {
-     st->print(BULLET"generic signature: ");
-     ik->generic_signature()->print_value_on(st);
-diff --git a/src/share/vm/oops/methodOop.cpp b/src/share/vm/oops/methodOop.cpp
---- a/src/share/vm/oops/methodOop.cpp
-+++ b/src/share/vm/oops/methodOop.cpp
-@@ -839,11 +839,11 @@
- bool methodOopDesc::is_method_handle_invoke_name(vmSymbols::SID name_sid) {
-   switch (name_sid) {
-   case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
--  case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
-+  case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
-     return true;
-   }
--  if ((AllowTransitionalJSR292 || AllowInvokeForInvokeGeneric)
--      && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
-+  if (AllowInvokeGeneric
-+      && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name))
-     return true;
-   return false;
- }
-@@ -1079,7 +1079,6 @@
-   if (name_id == vmSymbols::NO_SID)  return;
-   vmSymbols::SID   sig_id = vmSymbols::find_sid(signature());
-   if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
--      && !(klass_id == vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle) && AllowTransitionalJSR292)
-       && sig_id == vmSymbols::NO_SID)  return;
-   jshort flags = access_flags().as_short();
- 
-@@ -1105,20 +1104,17 @@
-     break;
- 
-   // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*.
--  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_dyn_MethodHandle):  // AllowTransitionalJSR292 ONLY
-   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
-     if (is_static() || !is_native())  break;
-     switch (name_id) {
-     case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
-+      if (!AllowInvokeGeneric)  break;
-+    case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
-       id = vmIntrinsics::_invokeGeneric;
-       break;
-     case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
-       id = vmIntrinsics::_invokeExact;
-       break;
--    case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
--      if (AllowInvokeForInvokeGeneric)   id = vmIntrinsics::_invokeGeneric;
--      else if (AllowTransitionalJSR292)  id = vmIntrinsics::_invokeExact;
--      break;
-     }
-     break;
-   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InvokeDynamic):
-diff --git a/src/share/vm/prims/jvm.h b/src/share/vm/prims/jvm.h
---- a/src/share/vm/prims/jvm.h
-+++ b/src/share/vm/prims/jvm.h
-@@ -1065,7 +1065,7 @@
-     JVM_CONSTANT_NameAndType,
-     JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
-     JVM_CONSTANT_MethodType             = 16,  // JSR 292
--    JVM_CONSTANT_InvokeDynamicTrans     = 17,  // JSR 292, only occurs in old class files
-+    //JVM_CONSTANT_(unused)             = 17,  // JSR 292 early drafts only
-     JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
-     JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
- };
-diff --git a/src/share/vm/prims/methodHandleWalk.cpp b/src/share/vm/prims/methodHandleWalk.cpp
---- a/src/share/vm/prims/methodHandleWalk.cpp
-+++ b/src/share/vm/prims/methodHandleWalk.cpp
-@@ -959,12 +959,6 @@
-   if (m == NULL) {
-     // Get the intrinsic methodOop.
-     m = vmIntrinsics::method_for(iid);
--    if (m == NULL && iid == vmIntrinsics::_checkSpreadArgument && AllowTransitionalJSR292) {
--      m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS);
--      if (m == NULL)
--        // sun.dyn.MethodHandleImpl not found, look for java.dyn.MethodHandleNatives:
--        m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS2);
--    }
-     if (m == NULL) {
-       ArgToken zero;
-       lose(vmIntrinsics::name_at(iid), CHECK_(zero));
-diff --git a/src/share/vm/prims/methodHandles.cpp b/src/share/vm/prims/methodHandles.cpp
---- a/src/share/vm/prims/methodHandles.cpp
-+++ b/src/share/vm/prims/methodHandles.cpp
-@@ -2488,74 +2488,21 @@
- }
- JVM_END
- 
--JVM_ENTRY(void, MHN_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
--  instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
--  if (!AllowTransitionalJSR292) {
--    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
--              "registerBootstrapMethod is only supported in JSR 292 EDR");
--  }
--  ik->link_class(CHECK);
--  if (!java_lang_invoke_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
--    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
--  }
--  const char* err = NULL;
--  if (ik->is_initialized() || ik->is_in_error_state()) {
--    err = "too late: class is already initialized";
--  } else {
--    ObjectLocker ol(ik, THREAD);  // note:  this should be a recursive lock
--    if (ik->is_not_initialized() ||
--        (ik->is_being_initialized() && ik->is_reentrant_initialization(THREAD))) {
--      if (ik->bootstrap_method() != NULL) {
--        err = "class is already equipped with a bootstrap method";
--      } else {
--        ik->set_bootstrap_method(JNIHandles::resolve_non_null(bsm_jh));
--        err = NULL;
--      }
--    } else {
--      err = "class is already initialized";
--      if (ik->is_being_initialized())
--        err = "class is already being initialized in a different thread";
--    }
--  }
--  if (err != NULL) {
--    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err);
--  }
--}
--JVM_END
--
--JVM_ENTRY(jobject, MHN_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
--  if (!AllowTransitionalJSR292)
--    THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
--  instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
--  return JNIHandles::make_local(THREAD, ik->bootstrap_method());
--}
--JVM_END
--
--JVM_ENTRY(void, MHN_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
--  if (!AllowTransitionalJSR292)
--    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
--}
--JVM_END
--
- 
- /// JVM_RegisterMethodHandleMethods
- 
- #define LANG "Ljava/lang/"
--#define JLINV "Ljava/lang/invoke/" /* standard package */
--#define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
--#define IDYN "Lsun/dyn/"  /* alternative package to JDYN if AllowTransitionalJSR292 */
--// FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
-+#define JLINV "Ljava/lang/invoke/"
- 
- #define OBJ   LANG"Object;"
- #define CLS   LANG"Class;"
- #define STRG  LANG"String;"
--#define CST   JDYN"CallSite;"
--#define MT    JDYN"MethodType;"
--#define MH    JDYN"MethodHandle;"
--#define MEM   IDYN"MemberName;"
--#define AMH   IDYN"AdapterMethodHandle;"
--#define BMH   IDYN"BoundMethodHandle;"
--#define DMH   IDYN"DirectMethodHandle;"
-+#define MT    JLINV"MethodType;"
-+#define MH    JLINV"MethodHandle;"
-+#define MEM   JLINV"MemberName;"
-+#define AMH   JLINV"AdapterMethodHandle;"
-+#define BMH   JLINV"BoundMethodHandle;"
-+#define DMH   JLINV"DirectMethodHandle;"
- 
- #define CC (char*)  /*cast a literal from (const char*)*/
- #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
-@@ -2579,39 +2526,6 @@
-   {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHN_getMembers)}
- };
- 
--// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
--static JNINativeMethod methods2[] = {
--  {CC"registerBootstrap",       CC"("CLS MH")V",                FN_PTR(MHN_registerBootstrap)},
--  {CC"getBootstrap",            CC"("CLS")"MH,                  FN_PTR(MHN_getBootstrap)},
--  {CC"setCallSiteTarget",       CC"("CST MH")V",                FN_PTR(MHN_setCallSiteTarget)}
--};
--
--static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
--  for (int i = 0; i < num_methods; i++) {
--    const char* sig = methods[i].signature;
--    if (!strstr(sig, from_sig))  continue;
--    size_t buflen = strlen(sig) + 100;
--    char* buf = NEW_C_HEAP_ARRAY(char, buflen);
--    char* bufp = buf;
--    const char* sigp = sig;
--    size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
--    while (*sigp != '\0') {
--      assert(bufp < buf + buflen - to_len - 1, "oob");
--      if (strncmp(sigp, from_sig, from_len) != 0) {
--        *bufp++ = *sigp++;
--      } else {
--        strcpy(bufp, to_sig);
--        bufp += to_len;
--        sigp += from_len;
--      }
--    }
--    *bufp = '\0';
--    methods[i].signature = buf;  // replace with new signature
--    if (TraceMethodHandles)
--      tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
--  }
--}
--
- // This one function is exported, used by NativeLookup.
- 
- JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
-@@ -2622,92 +2536,41 @@
-     return;  // bind nothing
-   }
- 
--  if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
--      SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
--    warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
--    THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
--  }
--
-   bool enable_MH = true;
- 
--  // Loop control.  FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
--  bool registered_natives = false;
--  bool try_plain = true, try_JDYN = true, try_IDYN = true;
--  for (;;) {
-+  {
-     ThreadToNativeFromVM ttnfv(thread);
- 
--    if      (try_plain) { try_plain = false; }
--    else if (try_JDYN)  { try_JDYN  = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
--    else if (try_IDYN)  { try_IDYN  = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
--    else                { break; }
-     int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
-     if (env->ExceptionOccurred()) {
-+      MethodHandles::set_enabled(false);
-+      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-+      enable_MH = false;
-       env->ExceptionClear();
--      // and try again...
--    } else {
--      registered_natives = true;
--      break;
-     }
-   }
--  if (!registered_natives) {
--    MethodHandles::set_enabled(false);
--    warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
--    enable_MH = false;
--  }
- 
-   if (enable_MH) {
--    bool found_raise_exception = false;
-     KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
--    KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
--    // Loop control.  FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
--    bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
--    for (;;) {
--      KlassHandle try_klass;
--      if      (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
--      else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
--      else              { break; }
--      if (try_klass.is_null())  continue;
-+    if (MHN_klass.not_null()) {
-       TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
-       TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
--      methodOop raiseException_method  = instanceKlass::cast(try_klass->as_klassOop())
-+      methodOop raiseException_method  = instanceKlass::cast(MHN_klass->as_klassOop())
-                     ->find_method(raiseException_name, raiseException_sig);
-       if (raiseException_method != NULL && raiseException_method->is_static()) {
-         MethodHandles::set_raise_exception_method(raiseException_method);
--        found_raise_exception = true;
--        break;
-+      } else {
-+        warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-+        enable_MH = false;
-       }
--    }
--    if (!found_raise_exception) {
--      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-+    } else {
-       enable_MH = false;
-     }
-   }
- 
-   if (enable_MH) {
--    if (AllowTransitionalJSR292) {
--      // We need to link the MethodHandleImpl klass before we generate
--      // the method handle adapters as the _raise_exception adapter uses
--      // one of its methods (and its c2i-adapter).
--      klassOop k = SystemDictionary::MethodHandleImpl_klass();
--      if (k != NULL) {
--        instanceKlass* ik = instanceKlass::cast(k);
--        ik->link_class(CHECK);
--      }
--    }
--
-     MethodHandles::generate_adapters();
-     MethodHandles::set_enabled(true);
-   }
--
--  if (AllowTransitionalJSR292) {
--    ThreadToNativeFromVM ttnfv(thread);
--
--    int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
--    if (env->ExceptionOccurred()) {
--      // Don't do this, since it's too late:
--      //   MethodHandles::set_enabled(false)
--      env->ExceptionClear();
--    }
--  }
- }
- JVM_END
-diff --git a/src/share/vm/prims/nativeLookup.cpp b/src/share/vm/prims/nativeLookup.cpp
---- a/src/share/vm/prims/nativeLookup.cpp
-+++ b/src/share/vm/prims/nativeLookup.cpp
-@@ -120,8 +120,6 @@
- 
-   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
-   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
--  { CC"Java_sun_dyn_MethodHandleNatives_registerNatives",          NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },  // AllowTransitionalJSR292
--  { CC"Java_java_dyn_MethodHandleNatives_registerNatives",         NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },  // AllowTransitionalJSR292
-   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         }
- };
- 
-diff --git a/src/share/vm/runtime/globals.cpp b/src/share/vm/runtime/globals.cpp
---- a/src/share/vm/runtime/globals.cpp
-+++ b/src/share/vm/runtime/globals.cpp
-@@ -63,6 +63,12 @@
- 
- bool Flag::is_unlocked() const {
-   if (strcmp(kind, "{diagnostic}") == 0) {
-+    if (strcmp(name, "EnableInvokeDynamic") == 0 && UnlockExperimentalVMOptions && !UnlockDiagnosticVMOptions) {
-+      // transitional logic to allow tests to run until they are changed
-+      static int warned;
-+      if (++warned == 1)  warning("Use -XX:+UnlockDiagnosticVMOptions before EnableInvokeDynamic flag");
-+      return true;
-+    }
-     return UnlockDiagnosticVMOptions;
-   } else if (strcmp(kind, "{experimental}") == 0 ||
-              strcmp(kind, "{C2 experimental}") == 0) {
-diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
---- a/src/share/vm/runtime/globals.hpp
-+++ b/src/share/vm/runtime/globals.hpp
-@@ -3735,13 +3735,7 @@
-   experimental(bool, TrustFinalNonStaticFields, false,                      \
-           "trust final non-static declarations for constant folding")       \
-                                                                             \
--  experimental(bool, AllowTransitionalJSR292, true,                         \
--          "recognize pre-PFD formats of invokedynamic")                     \
--                                                                            \
--  experimental(bool, PreferTransitionalJSR292, false,                       \
--          "prefer pre-PFD APIs on boot class path, if they exist")          \
--                                                                            \
--  experimental(bool, AllowInvokeForInvokeGeneric, false,                    \
-+  experimental(bool, AllowInvokeGeneric, true,                              \
-           "accept MethodHandle.invoke and MethodHandle.invokeGeneric "      \
-           "as equivalent methods")                                          \
-                                                                             \
-diff --git a/src/share/vm/utilities/constantTag.cpp b/src/share/vm/utilities/constantTag.cpp
---- a/src/share/vm/utilities/constantTag.cpp
-+++ b/src/share/vm/utilities/constantTag.cpp
-@@ -93,8 +93,6 @@
-       return "MethodType";
-     case JVM_CONSTANT_InvokeDynamic :
-       return "InvokeDynamic";
--    case JVM_CONSTANT_InvokeDynamicTrans :
--      return "InvokeDynamic/transitional";
-     case JVM_CONSTANT_Object :
-       return "Object";
-     case JVM_CONSTANT_Utf8 :
-diff --git a/src/share/vm/utilities/constantTag.hpp b/src/share/vm/utilities/constantTag.hpp
---- a/src/share/vm/utilities/constantTag.hpp
-+++ b/src/share/vm/utilities/constantTag.hpp
-@@ -86,8 +86,7 @@
- 
-   bool is_method_type() const              { return _tag == JVM_CONSTANT_MethodType; }
-   bool is_method_handle() const            { return _tag == JVM_CONSTANT_MethodHandle; }
--  bool is_invoke_dynamic() const           { return (_tag == JVM_CONSTANT_InvokeDynamic ||
--                                                     _tag == JVM_CONSTANT_InvokeDynamicTrans); }
-+  bool is_invoke_dynamic() const           { return _tag == JVM_CONSTANT_InvokeDynamic; }
- 
-   bool is_loadable_constant() const {
-     return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) ||
-diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp
---- a/src/share/vm/runtime/arguments.cpp
-+++ b/src/share/vm/runtime/arguments.cpp
-@@ -245,6 +245,7 @@
-   { "MaxLiveObjectEvacuationRatio",
-                            JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
-   { "ForceSharedSpaces",   JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) },
-+  { "AllowTransitionalJSR292",       JDK_Version::jdk(7), JDK_Version::jdk(8) },
-   { NULL, JDK_Version(0), JDK_Version(0) }
- };
- 
--- a/indy.txt	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-6655646: dynamic languages need dynamically linked call sites
-Summary: invokedynamic instruction (JSR 292 RI)
-
-http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6655646
-
-Features:
-- enabled via -XX:+EnableInvokeDynamic
-
-Notes:
-
-If you get an error like this:
-  Exception in thread "main" java.lang.VerifyError: (class: Foo, method: ...) Illegal instruction found at offset 39
-then you need a JDK with a patch to the old verifier plugin, see ../jdk/indy.verify.patch
-As a workaround, use this JVM flag to turn off the (unpatched) verifier:
-  -Xverify:none
-or else put your classes on the BCP: -Xbootclasspath/a:my/classes:my.jar
--- a/jdk7-b147-to-bsd-port.patch	Thu Sep 05 18:02:53 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29517 +0,0 @@
-Diff between these two repositories:
-  hg clone -r jdk7-b147 http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot
-  hg clone -r a32de5085326 http://hg.openjdk.java.net/bsd-port/bsd-port/hotspot #9/01/2011
-
-Plus further changes under review here:
-  http://cr.openjdk.java.net/~never/7089790_full
-
-This patch will be rebased as needed to hotspot-comp.
-
-diff --git a/agent/make/Makefile b/agent/make/Makefile
---- a/agent/make/Makefile
-+++ b/agent/make/Makefile
-@@ -53,6 +53,9 @@
- sun.jvm.hotspot.compiler \
- sun.jvm.hotspot.debugger \
- sun.jvm.hotspot.debugger.amd64 \
-+sun.jvm.hotspot.debugger.bsd \
-+sun.jvm.hotspot.debugger.bsd.amd64 \
-+sun.jvm.hotspot.debugger.bsd.x86 \
- sun.jvm.hotspot.debugger.cdbg \
- sun.jvm.hotspot.debugger.cdbg.basic \
- sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
-@@ -93,6 +96,9 @@
- sun.jvm.hotspot.prims \
- sun.jvm.hotspot.runtime \
- sun.jvm.hotspot.runtime.amd64 \
-+sun.jvm.hotspot.runtime.bsd \
-+sun.jvm.hotspot.runtime.bsd_amd64 \
-+sun.jvm.hotspot.runtime.bsd_x86 \
- sun.jvm.hotspot.runtime.ia64 \
- sun.jvm.hotspot.runtime.linux \
- sun.jvm.hotspot.runtime.linux_amd64 \
-@@ -143,6 +149,9 @@
- sun/jvm/hotspot/compiler/*.java \
- sun/jvm/hotspot/debugger/*.java \
- sun/jvm/hotspot/debugger/amd64/*.java \
-+sun/jvm/hotspot/debugger/bsd/*.java \
-+sun/jvm/hotspot/debugger/bsd/amd64/*.java \
-+sun/jvm/hotspot/debugger/bsd/x86/*.java \
- sun/jvm/hotspot/debugger/cdbg/*.java \
- sun/jvm/hotspot/debugger/cdbg/basic/*.java \
- sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
-@@ -176,6 +185,9 @@
- sun/jvm/hotspot/prims/*.java \
- sun/jvm/hotspot/runtime/*.java \
- sun/jvm/hotspot/runtime/amd64/*.java \
-+sun/jvm/hotspot/runtime/bsd/*.java \
-+sun/jvm/hotspot/runtime/bsd_amd64/*.java \
-+sun/jvm/hotspot/runtime/bsd_x86/*.java \
- sun/jvm/hotspot/runtime/ia64/*.java \
- sun/jvm/hotspot/runtime/linux/*.java \
- sun/jvm/hotspot/runtime/linux_amd64/*.java \
-diff --git a/agent/src/os/bsd/BsdDebuggerLocal.c b/agent/src/os/bsd/BsdDebuggerLocal.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/BsdDebuggerLocal.c
-@@ -0,0 +1,413 @@
-+/*
-+ * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#include <stdlib.h>
-+#include <jni.h>
-+#include "libproc.h"
-+
-+#if defined(x86_64) && !defined(amd64)
-+#define amd64 1
-+#endif
-+
-+#ifdef i386
-+#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
-+#endif
-+
-+#ifdef amd64
-+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
-+#endif
-+
-+#if defined(sparc) || defined(sparcv9)
-+#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
-+#endif
-+
-+static jfieldID p_ps_prochandle_ID = 0;
-+static jfieldID threadList_ID = 0;
-+static jfieldID loadObjectList_ID = 0;
-+
-+static jmethodID createClosestSymbol_ID = 0;
-+static jmethodID createLoadObject_ID = 0;
-+static jmethodID getThreadForThreadId_ID = 0;
-+static jmethodID listAdd_ID = 0;
-+
-+#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
-+#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
-+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
-+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
-+
-+static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
-+  (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
-+}
-+
-+static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
-+  jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
-+  return (struct ps_prochandle*)(intptr_t)ptr;
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    init0
-+ * Signature: ()V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
-+  (JNIEnv *env, jclass cls) {
-+  jclass listClass;
-+
-+  if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
-+     THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
-+  }
-+
-+  // fields we use
-+  p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
-+  CHECK_EXCEPTION;
-+  threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
-+  CHECK_EXCEPTION;
-+  loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
-+  CHECK_EXCEPTION;
-+
-+  // methods we use
-+  createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
-+                    "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
-+  CHECK_EXCEPTION;
-+  createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
-+                    "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
-+  CHECK_EXCEPTION;
-+  getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
-+                                                     "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
-+  CHECK_EXCEPTION;
-+  // java.util.List method we call
-+  listClass = (*env)->FindClass(env, "java/util/List");
-+  CHECK_EXCEPTION;
-+  listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
-+  CHECK_EXCEPTION;
-+}
-+
-+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
-+  (JNIEnv *env, jclass cls)
-+{
-+#ifdef _LP64
-+ return 8;
-+#else
-+ return 4;
-+#endif
-+
-+}
-+
-+
-+static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
-+  int n = 0, i = 0;
-+
-+  // add threads
-+  n = get_num_threads(ph);
-+  for (i = 0; i < n; i++) {
-+    jobject thread;
-+    jobject threadList;
-+    lwpid_t lwpid;
-+
-+    lwpid = get_lwp_id(ph, i);
-+    thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
-+                                      (jlong)lwpid);
-+    CHECK_EXCEPTION;
-+    threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
-+    CHECK_EXCEPTION;
-+    (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
-+    CHECK_EXCEPTION;
-+  }
-+
-+  // add load objects
-+  n = get_num_libs(ph);
-+  for (i = 0; i < n; i++) {
-+     uintptr_t base;
-+     const char* name;
-+     jobject loadObject;
-+     jobject loadObjectList;
-+
-+     base = get_lib_base(ph, i);
-+     name = get_lib_name(ph, i);
-+     loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
-+                                   (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
-+     CHECK_EXCEPTION;
-+     loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
-+     CHECK_EXCEPTION;
-+     (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
-+     CHECK_EXCEPTION;
-+  }
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    attach0
-+ * Signature: (I)V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I
-+  (JNIEnv *env, jobject this_obj, jint jpid) {
-+
-+  struct ps_prochandle* ph;
-+  if ( (ph = Pgrab(jpid)) == NULL) {
-+    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
-+  }
-+  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
-+  fillThreadsAndLoadObjects(env, this_obj, ph);
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    attach0
-+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
-+  (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
-+  const char *execName_cstr;
-+  const char *coreName_cstr;
-+  jboolean isCopy;
-+  struct ps_prochandle* ph;
-+
-+  execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
-+  CHECK_EXCEPTION;
-+  coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
-+  CHECK_EXCEPTION;
-+
-+  if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
-+    (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
-+    (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
-+    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
-+  }
-+  (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
-+  (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
-+  (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
-+  fillThreadsAndLoadObjects(env, this_obj, ph);
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    detach0
-+ * Signature: ()V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0
-+  (JNIEnv *env, jobject this_obj) {
-+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
-+  if (ph != NULL) {
-+     Prelease(ph);
-+  }
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    lookupByName0
-+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
-+ */
-+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0
-+  (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
-+  const char *objectName_cstr, *symbolName_cstr;
-+  jlong addr;
-+  jboolean isCopy;
-+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
-+
-+  objectName_cstr = NULL;
-+  if (objectName != NULL) {
-+    objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
-+    CHECK_EXCEPTION_(0);
-+  }
-+  symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
-+  CHECK_EXCEPTION_(0);
-+
-+  addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
-+
-+  if (objectName_cstr != NULL) {
-+    (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
-+  }
-+  (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
-+  return addr;
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    lookupByAddress0
-+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
-+ */
-+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
-+  (JNIEnv *env, jobject this_obj, jlong addr) {
-+  uintptr_t offset;
-+  const char* sym = NULL;
-+
-+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
-+  sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
-+  if (sym == NULL) return 0;
-+  return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
-+                          (*env)->NewStringUTF(env, sym), (jlong)offset);
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    readBytesFromProcess0
-+ * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
-+ */
-+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0
-+  (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
-+
-+  jboolean isCopy;
-+  jbyteArray array;
-+  jbyte *bufPtr;
-+  ps_err_e err;
-+
-+  array = (*env)->NewByteArray(env, numBytes);
-+  CHECK_EXCEPTION_(0);
-+  bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
-+  CHECK_EXCEPTION_(0);
-+
-+  err = ps_pread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
-+  (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
-+  return (err == PS_OK)? array : 0;
-+}
-+
-+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
-+  (JNIEnv *env, jobject this_obj, jint lwp_id) {
-+
-+  struct reg gregs;
-+  jboolean isCopy;
-+  jlongArray array;
-+  jlong *regs;
-+
-+  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
-+  if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
-+     THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
-+  }
-+
-+#undef NPRGREG
-+#ifdef i386
-+#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
-+#endif
-+#ifdef ia64
-+#define NPRGREG IA64_REG_COUNT
-+#endif
-+#ifdef amd64
-+#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
-+#endif
-+#if defined(sparc) || defined(sparcv9)
-+#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
-+#endif
-+
-+  array = (*env)->NewLongArray(env, NPRGREG);
-+  CHECK_EXCEPTION_(0);
-+  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
-+
-+#undef REG_INDEX
-+
-+#ifdef i386
-+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
-+
-+  regs[REG_INDEX(GS)]  = (uintptr_t) gregs.r_gs;
-+  regs[REG_INDEX(FS)]  = (uintptr_t) gregs.r_fs;
-+  regs[REG_INDEX(ES)]  = (uintptr_t) gregs.r_es;
-+  regs[REG_INDEX(DS)]  = (uintptr_t) gregs.r_ds;
-+  regs[REG_INDEX(EDI)] = (uintptr_t) gregs.r_edi;
-+  regs[REG_INDEX(ESI)] = (uintptr_t) gregs.r_esi;
-+  regs[REG_INDEX(FP)] = (uintptr_t) gregs.r_ebp;
-+  regs[REG_INDEX(SP)] = (uintptr_t) gregs.r_isp;
-+  regs[REG_INDEX(EBX)] = (uintptr_t) gregs.r_ebx;
-+  regs[REG_INDEX(EDX)] = (uintptr_t) gregs.r_edx;
-+  regs[REG_INDEX(ECX)] = (uintptr_t) gregs.r_ecx;
-+  regs[REG_INDEX(EAX)] = (uintptr_t) gregs.r_eax;
-+  regs[REG_INDEX(PC)] = (uintptr_t) gregs.r_eip;
-+  regs[REG_INDEX(CS)]  = (uintptr_t) gregs.r_cs;
-+  regs[REG_INDEX(SS)]  = (uintptr_t) gregs.r_ss;
-+
-+#endif /* i386 */
-+
-+#if ia64
-+  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
-+  int i;
-+  for (i = 0; i < NPRGREG; i++ ) {
-+    regs[i] = 0xDEADDEAD;
-+  }
-+#endif /* ia64 */
-+
-+#ifdef amd64
-+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
-+
-+  regs[REG_INDEX(R15)] = gregs.r_r15;
-+  regs[REG_INDEX(R14)] = gregs.r_r14;
-+  regs[REG_INDEX(R13)] = gregs.r_r13;
-+  regs[REG_INDEX(R12)] = gregs.r_r12;
-+  regs[REG_INDEX(RBP)] = gregs.r_rbp;
-+  regs[REG_INDEX(RBX)] = gregs.r_rbx;
-+  regs[REG_INDEX(R11)] = gregs.r_r11;
-+  regs[REG_INDEX(R10)] = gregs.r_r10;
-+  regs[REG_INDEX(R9)] = gregs.r_r9;
-+  regs[REG_INDEX(R8)] = gregs.r_r8;
-+  regs[REG_INDEX(RAX)] = gregs.r_rax;
-+  regs[REG_INDEX(RCX)] = gregs.r_rcx;
-+  regs[REG_INDEX(RDX)] = gregs.r_rdx;
-+  regs[REG_INDEX(RSI)] = gregs.r_rsi;
-+  regs[REG_INDEX(RDI)] = gregs.r_rdi;
-+  regs[REG_INDEX(RIP)] = gregs.r_rip;
-+  regs[REG_INDEX(CS)] = gregs.r_cs;
-+  regs[REG_INDEX(RSP)] = gregs.r_rsp;
-+  regs[REG_INDEX(SS)] = gregs.r_ss;
-+//  regs[REG_INDEX(FSBASE)] = gregs.fs_base;
-+//  regs[REG_INDEX(GSBASE)] = gregs.gs_base;
-+//  regs[REG_INDEX(DS)] = gregs.ds;
-+//  regs[REG_INDEX(ES)] = gregs.es;
-+//  regs[REG_INDEX(FS)] = gregs.fs;
-+//  regs[REG_INDEX(GS)] = gregs.gs;
-+
-+#endif /* amd64 */
-+
-+#if defined(sparc) || defined(sparcv9)
-+
-+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
-+
-+#ifdef _LP64
-+  regs[REG_INDEX(R_PSR)] = gregs.tstate;
-+  regs[REG_INDEX(R_PC)]  = gregs.tpc;
-+  regs[REG_INDEX(R_nPC)] = gregs.tnpc;
-+  regs[REG_INDEX(R_Y)]   = gregs.y;
-+#else
-+  regs[REG_INDEX(R_PSR)] = gregs.psr;
-+  regs[REG_INDEX(R_PC)]  = gregs.pc;
-+  regs[REG_INDEX(R_nPC)] = gregs.npc;
-+  regs[REG_INDEX(R_Y)]   = gregs.y;
-+#endif
-+  regs[REG_INDEX(R_G0)]  =            0 ;
-+  regs[REG_INDEX(R_G1)]  = gregs.u_regs[0];
-+  regs[REG_INDEX(R_G2)]  = gregs.u_regs[1];
-+  regs[REG_INDEX(R_G3)]  = gregs.u_regs[2];
-+  regs[REG_INDEX(R_G4)]  = gregs.u_regs[3];
-+  regs[REG_INDEX(R_G5)]  = gregs.u_regs[4];
-+  regs[REG_INDEX(R_G6)]  = gregs.u_regs[5];
-+  regs[REG_INDEX(R_G7)]  = gregs.u_regs[6];
-+  regs[REG_INDEX(R_O0)]  = gregs.u_regs[7];
-+  regs[REG_INDEX(R_O1)]  = gregs.u_regs[8];
-+  regs[REG_INDEX(R_O2)]  = gregs.u_regs[ 9];
-+  regs[REG_INDEX(R_O3)]  = gregs.u_regs[10];
-+  regs[REG_INDEX(R_O4)]  = gregs.u_regs[11];
-+  regs[REG_INDEX(R_O5)]  = gregs.u_regs[12];
-+  regs[REG_INDEX(R_O6)]  = gregs.u_regs[13];
-+  regs[REG_INDEX(R_O7)]  = gregs.u_regs[14];
-+#endif /* sparc */
-+
-+
-+  (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
-+  return array;
-+}
-diff --git a/agent/src/os/bsd/Makefile b/agent/src/os/bsd/Makefile
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/Makefile
-@@ -0,0 +1,78 @@
-+#
-+# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
-+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+#
-+# This code is free software; you can redistribute it and/or modify it
-+# under the terms of the GNU General Public License version 2 only, as
-+# published by the Free Software Foundation.
-+#
-+# This code is distributed in the hope that it will be useful, but WITHOUT
-+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+# version 2 for more details (a copy is included in the LICENSE file that
-+# accompanied this code).
-+#
-+# You should have received a copy of the GNU General Public License version
-+# 2 along with this work; if not, write to the Free Software Foundation,
-+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+#
-+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+# or visit www.oracle.com if you need additional information or have any
-+# questions.
-+#  
-+#
-+
-+ARCH := $(shell if ([ `uname -m` = "ia64" ])  ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
-+GCC      = gcc
-+
-+JAVAH    = ${JAVA_HOME}/bin/javah
-+
-+SOURCES  = salibelf.c   \
-+        symtab.c        \
-+	libproc_impl.c  \
-+	ps_proc.c       \
-+	ps_core.c       \
-+	hsearch_r.c     \
-+	BsdDebuggerLocal.c
-+
-+INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
-+
-+OBJS     = $(SOURCES:.c=.o)
-+
-+LIBS     = -lutil -lthread_db
-+
-+CFLAGS   = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
-+
-+LIBSA = $(ARCH)/libsaproc.so
-+
-+all: $(LIBSA)
-+
-+BsdDebuggerLocal.o: BsdDebuggerLocal.c
-+	$(JAVAH) -jni -classpath ../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses  \
-+		sun.jvm.hotspot.debugger.x86.X86ThreadContext \
-+		sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
-+	$(GCC) $(CFLAGS) $<
-+
-+.c.obj:
-+	$(GCC) $(CFLAGS)
-+
-+ifndef LDNOMAP
-+  LFLAGS_LIBSA = -Xlinker --version-script=mapfile
-+endif
-+
-+$(LIBSA): $(OBJS) mapfile
-+	if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
-+	$(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
-+
-+test.o: $(LIBSA) test.c
-+	$(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
-+
-+test: test.o
-+	$(GCC) -o test test.o -L$(ARCH) -lsaproc $(LIBS)
-+
-+clean:
-+	rm -f $(LIBSA)
-+	rm -f $(OBJS)
-+	rm -f test.o
-+	-rmdir $(ARCH)
-+
-diff --git a/agent/src/os/bsd/StubDebuggerLocal.c b/agent/src/os/bsd/StubDebuggerLocal.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/StubDebuggerLocal.c
-@@ -0,0 +1,120 @@
-+/*
-+ * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-+ * CA 95054 USA or visit www.sun.com if you need additional information or
-+ * have any questions.
-+ *
-+ */
-+
-+#include <stdlib.h>
-+#include <jni.h>
-+
-+#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
-+#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
-+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
-+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
-+
-+static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
-+  (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    init0
-+ * Signature: ()V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0
-+  (JNIEnv *env, jclass cls) {
-+}
-+
-+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize
-+  (JNIEnv *env, jclass cls)
-+{
-+#ifdef _LP64
-+ return 8;
-+#else
-+ return 4;
-+#endif
-+
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    attach0
-+ * Signature: (I)V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I
-+  (JNIEnv *env, jobject this_obj, jint jpid) {
-+
-+  THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    attach0
-+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
-+  (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
-+  THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    detach0
-+ * Signature: ()V
-+ */
-+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0
-+  (JNIEnv *env, jobject this_obj) {
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    lookupByName0
-+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
-+ */
-+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0
-+  (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
-+  return 0;
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    lookupByAddress0
-+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
-+ */
-+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0
-+  (JNIEnv *env, jobject this_obj, jlong addr) {
-+  return 0;
-+}
-+
-+/*
-+ * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
-+ * Method:    readBytesFromProcess0
-+ * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
-+ */
-+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0
-+  (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
-+  return 0;
-+}
-+
-+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0
-+  (JNIEnv *env, jobject this_obj, jint lwp_id) {
-+  return 0;
-+}
-diff --git a/agent/src/os/bsd/elfmacros.h b/agent/src/os/bsd/elfmacros.h
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/elfmacros.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#ifndef _ELFMACROS_H_
-+#define _ELFMACROS_H_
-+
-+#define ELF_NHDR        Elf_Note
-+
-+#if defined(_LP64)
-+#define ELF_EHDR        Elf64_Ehdr
-+#define ELF_SHDR        Elf64_Shdr
-+#define ELF_PHDR        Elf64_Phdr
-+#define ELF_SYM         Elf64_Sym
-+#define ELF_DYN         Elf64_Dyn
-+#define ELF_ADDR        Elf64_Addr
-+
-+#ifndef ELF_ST_TYPE
-+#define ELF_ST_TYPE     ELF64_ST_TYPE
-+#endif
-+
-+#else
-+
-+#define ELF_EHDR        Elf32_Ehdr
-+#define ELF_SHDR        Elf32_Shdr
-+#define ELF_PHDR        Elf32_Phdr
-+#define ELF_SYM         Elf32_Sym
-+#define ELF_DYN         Elf32_Dyn
-+#define ELF_ADDR        Elf32_Addr
-+
-+#ifndef ELF_ST_TYPE
-+#define ELF_ST_TYPE     ELF32_ST_TYPE
-+#endif
-+
-+#endif
-+
-+
-+#endif /* _ELFMACROS_H_ */
-diff --git a/agent/src/os/bsd/hsearch_r.c b/agent/src/os/bsd/hsearch_r.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/hsearch_r.c
-@@ -0,0 +1,217 @@
-+/* Copyright (C) 1993,1995-1997,2002,2005,2007,2008
-+   Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1993.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, write to the Free
-+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+   02111-1307 USA.  */
-+
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include <search.h>
-+
-+#include "hsearch_r.h"
-+
-+#define __set_errno(ERRNO) errno = ERRNO
-+
-+/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
-+   [Knuth]            The Art of Computer Programming, part 3 (6.4)  */
-+
-+
-+/* The reentrant version has no static variables to maintain the state.
-+   Instead the interface of all functions is extended to take an argument
-+   which describes the current status.  */
-+typedef struct _ENTRY
-+{
-+  unsigned int used;
-+  ENTRY entry;
-+}
-+_ENTRY;
-+
-+
-+/* For the used double hash method the table size has to be a prime. To
-+   correct the user given table size we need a prime test.  This trivial
-+   algorithm is adequate because
-+   a)  the code is (most probably) called a few times per program run and
-+   b)  the number is small because the table must fit in the core  */
-+static int
-+isprime (unsigned int number)
-+{
-+  /* no even number will be passed */
-+  unsigned int div = 3;
-+
-+  while (div * div < number && number % div != 0)
-+    div += 2;
-+
-+  return number % div != 0;
-+}
-+
-+
-+/* Before using the hash table we must allocate memory for it.
-+   Test for an existing table are done. We allocate one element
-+   more as the found prime number says. This is done for more effective
-+   indexing as explained in the comment for the hsearch function.
-+   The contents of the table is zeroed, especially the field used
-+   becomes zero.  */
-+int
-+hcreate_r (size_t nel, struct hsearch_data *htab)
-+{
-+  /* Test for correct arguments.  */
-+  if (htab == NULL)
-+    {
-+      __set_errno (EINVAL);
-+      return 0;
-+    }
-+
-+  /* There is still another table active. Return with error. */
-+  if (htab->table != NULL)
-+    return 0;
-+
-+  /* Change nel to the first prime number not smaller as nel. */
-+  nel |= 1;      /* make odd */
-+  while (!isprime (nel))
-+    nel += 2;
-+
-+  htab->size = nel;
-+  htab->filled = 0;
-+
-+  /* allocate memory and zero out */
-+  htab->table = (_ENTRY *) calloc (htab->size + 1, sizeof (_ENTRY));
-+  if (htab->table == NULL)
-+    return 0;
-+
-+  /* everything went alright */
-+  return 1;
-+}
-+
-+
-+/* After using the hash table it has to be destroyed. The used memory can
-+   be freed and the local static variable can be marked as not used.  */
-+void
-+hdestroy_r (struct hsearch_data *htab)
-+{
-+  /* Test for correct arguments.  */
-+  if (htab == NULL)
-+    {
-+      __set_errno (EINVAL);
-+      return;
-+    }
-+
-+  /* Free used memory.  */
-+  free (htab->table);
-+
-+  /* the sign for an existing table is an value != NULL in htable */
-+  htab->table = NULL;
-+}
-+
-+
-+/* This is the search function. It uses double hashing with open addressing.
-+   The argument item.key has to be a pointer to an zero terminated, most
-+   probably strings of chars. The function for generating a number of the
-+   strings is simple but fast. It can be replaced by a more complex function
-+   like ajw (see [Aho,Sethi,Ullman]) if the needs are shown.
-+
-+   We use an trick to speed up the lookup. The table is created by hcreate
-+   with one more element available. This enables us to use the index zero
-+   special. This index will never be used because we store the first hash
-+   index in the field used where zero means not used. Every other value
-+   means used. The used field can be used as a first fast comparison for
-+   equality of the stored and the parameter value. This helps to prevent
-+   unnecessary expensive calls of strcmp.  */
-+int
-+hsearch_r (ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
-+{
-+  unsigned int hval;
-+  unsigned int count;
-+  unsigned int len = strlen (item.key);
-+  unsigned int idx;
-+
-+  /* Compute an value for the given string. Perhaps use a better method. */
-+  hval = len;
-+  count = len;
-+  while (count-- > 0)
-+    {
-+      hval <<= 4;
-+      hval += item.key[count];
-+    }
-+
-+  /* First hash function: simply take the modul but prevent zero. */
-+  idx = hval % htab->size + 1;
-+
-+  if (htab->table[idx].used)
-+    {
-+      /* Further action might be required according to the action value. */
-+      if (htab->table[idx].used == hval
-+          && strcmp (item.key, htab->table[idx].entry.key) == 0)
-+        {
-+          *retval = &htab->table[idx].entry;
-+          return 1;
-+        }
-+
-+      /* Second hash function, as suggested in [Knuth] */
-+      unsigned int hval2 = 1 + hval % (htab->size - 2);
-+      unsigned int first_idx = idx;
-+
-+      do
-+        {
-+          /* Because SIZE is prime this guarantees to step through all
-+             available indeces.  */
-+          if (idx <= hval2)
-+            idx = htab->size + idx - hval2;
-+          else
-+            idx -= hval2;
-+
-+          /* If we visited all entries leave the loop unsuccessfully.  */
-+          if (idx == first_idx)
-+            break;
-+
-+            /* If entry is found use it. */
-+          if (htab->table[idx].used == hval
-+              && strcmp (item.key, htab->table[idx].entry.key) == 0)
-+            {
-+              *retval = &htab->table[idx].entry;
-+              return 1;
-+            }
-+        }
-+      while (htab->table[idx].used);
-+    }
-+
-+  /* An empty bucket has been found. */
-+  if (action == ENTER)
-+    {
-+      /* If table is full and another entry should be entered return
-+         with error.  */
-+      if (htab->filled == htab->size)
-+        {
-+          __set_errno (ENOMEM);
-+          *retval = NULL;
-+          return 0;
-+        }
-+
-+      htab->table[idx].used  = hval;
-+      htab->table[idx].entry = item;
-+
-+      ++htab->filled;
-+
-+      *retval = &htab->table[idx].entry;
-+      return 1;
-+    }
-+
-+  __set_errno (ESRCH);
-+  *retval = NULL;
-+  return 0;
-+}
-diff --git a/agent/src/os/bsd/hsearch_r.h b/agent/src/os/bsd/hsearch_r.h
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/hsearch_r.h
-@@ -0,0 +1,42 @@
-+/* Declarations for System V style searching functions.
-+   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, write to the Free
-+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+   02111-1307 USA.  */
-+
-+#ifndef _HSEARCH_R_H_
-+#define _HSEARCH_R_H_
-+
-+#include <search.h>
-+
-+struct _ENTRY;
-+
-+/* Data type for reentrant functions.  */
-+struct hsearch_data
-+  {
-+    struct _ENTRY *table;
-+    unsigned int size;
-+    unsigned int filled;
-+  };
-+
-+/* Reentrant versions which can handle multiple hashing tables at the
-+   same time.  */
-+extern int hsearch_r (ENTRY __item, ACTION __action, ENTRY **__retval,
-+                      struct hsearch_data *__htab);
-+extern int hcreate_r (size_t __nel, struct hsearch_data *__htab);
-+extern void hdestroy_r (struct hsearch_data *__htab);
-+
-+#endif /* _HSEARCH_R_H_ */
-diff --git a/agent/src/os/bsd/libproc.h b/agent/src/os/bsd/libproc.h
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/libproc.h
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#ifndef _LIBPROC_H_
-+#define _LIBPROC_H_
-+
-+#include <unistd.h>
-+#include <stdint.h>
-+#include <machine/reg.h>
-+#include <proc_service.h>
-+
-+#if defined(sparc) || defined(sparcv9)
-+/*
-+  If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
-+  otherwise it should be from /usr/include/asm-sparc
-+  These two files define pt_regs structure differently
-+*/
-+#ifdef _LP64
-+#include "asm-sparc64/ptrace.h"
-+#else
-+#include "asm-sparc/ptrace.h"
-+#endif
-+
-+#endif //sparc or sparcv9
-+
-+/************************************************************************************
-+
-+0. This is very minimal subset of Solaris libproc just enough for current application.
-+Please note that the bulk of the functionality is from proc_service interface. This
-+adds Pgrab__ and some missing stuff. We hide the difference b/w live process and core
-+file by this interface.
-+
-+1. pthread_id is unique. We store this in OSThread::_pthread_id in JVM code.
-+
-+2. All threads see the same pid when they call getpid().
-+We used to save the result of ::getpid() call in OSThread::_thread_id.
-+Because gettid returns actual pid of thread (lwp id), this is
-+unique again. We therefore use OSThread::_thread_id as unique identifier.
-+
-+3. There is a unique LWP id under both thread libraries. libthread_db  maps pthread_id
-+to its underlying lwp_id under both the thread libraries. thread_info.lwp_id stores
-+lwp_id of the thread. The lwp id is nothing but the actual pid of clone'd processes. But
-+unfortunately libthread_db does not work very well for core dumps. So, we get pthread_id
-+only for processes. For core dumps, we don't use libthread_db at all (like gdb).
-+
-+4. ptrace operates on this LWP id under both the thread libraries. When we say 'pid' for
-+ptrace call, we refer to lwp_id of the thread.
-+
-+5. for core file, we parse ELF files and read data from them. For processes we  use
-+combination of ptrace and /proc calls.
-+
-+*************************************************************************************/
-+
-+// This C bool type must be int for compatibility with BSD calls and
-+// it would be a mistake to equivalence it to C++ bool on many platforms
-+
-+typedef int bool;
-+#define true  1
-+#define false 0
-+
-+struct ps_prochandle;
-+
-+// attach to a process
-+struct ps_prochandle* Pgrab(pid_t pid);
-+
-+// attach to a core dump
-+struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
-+
-+// release a process or core
-+void Prelease(struct ps_prochandle* ph);
-+
-+// functions not directly available in Solaris libproc
-+
-+// initialize libproc (call this only once per app)
-+// pass true to make library verbose
-+bool init_libproc(bool verbose);
-+
-+// get number of threads
-+int get_num_threads(struct ps_prochandle* ph);
-+
-+// get lwp_id of n'th thread
-+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index);
-+
-+// get regs for a given lwp
-+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lid, struct reg* regs);
-+
-+// get number of shared objects
-+int get_num_libs(struct ps_prochandle* ph);
-+
-+// get name of n'th lib
-+const char* get_lib_name(struct ps_prochandle* ph, int index);
-+
-+// get base of lib
-+uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
-+
-+// returns true if given library is found in lib list
-+bool find_lib(struct ps_prochandle* ph, const char *lib_name);
-+
-+// symbol lookup
-+uintptr_t lookup_symbol(struct ps_prochandle* ph,  const char* object_name,
-+                       const char* sym_name);
-+
-+// address->nearest symbol lookup. return NULL for no symbol
-+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
-+
-+#endif //__LIBPROC_H_
-diff --git a/agent/src/os/bsd/libproc_impl.c b/agent/src/os/bsd/libproc_impl.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/libproc_impl.c
-@@ -0,0 +1,452 @@
-+/*
-+ * Copyright (c) 2003, 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
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <thread_db.h>
-+#include "libproc_impl.h"
-+
-+static const char* alt_root = NULL;
-+static int alt_root_len = -1;
-+
-+#define SA_ALTROOT "SA_ALTROOT"
-+
-+static void init_alt_root() {
-+   if (alt_root_len == -1) {
-+      alt_root = getenv(SA_ALTROOT);
-+      if (alt_root) {
-+         alt_root_len = strlen(alt_root);
-+      } else {
-+         alt_root_len = 0;
-+      }
-+   }
-+}
-+
-+int pathmap_open(const char* name) {
-+   int fd;
-+   char alt_path[PATH_MAX + 1];
-+
-+   init_alt_root();
-+   fd = open(name, O_RDONLY);
-+   if (fd >= 0) {
-+      return fd;
-+   }
-+
-+   if (alt_root_len > 0) {
-+      strcpy(alt_path, alt_root);
-+      strcat(alt_path, name);
-+      fd = open(alt_path, O_RDONLY);
-+      if (fd >= 0) {
-+         print_debug("path %s substituted for %s\n", alt_path, name);
-+         return fd;
-+      }
-+
-+      if (strrchr(name, '/')) {
-+         strcpy(alt_path, alt_root);
-+         strcat(alt_path, strrchr(name, '/'));
-+         fd = open(alt_path, O_RDONLY);
-+         if (fd >= 0) {
-+            print_debug("path %s substituted for %s\n", alt_path, name);
-+            return fd;
-+         }
-+      }
-+   }
-+
-+   return -1;
-+}
-+
-+static bool _libsaproc_debug;
-+
-+void print_debug(const char* format,...) {
-+   if (_libsaproc_debug) {
-+     va_list alist;
-+
-+     va_start(alist, format);
-+     fputs("libsaproc DEBUG: ", stderr);
-+     vfprintf(stderr, format, alist);
-+     va_end(alist);
-+   }
-+}
-+
-+bool is_debug() {
-+   return _libsaproc_debug;
-+}
-+
-+// initialize libproc
-+bool init_libproc(bool debug) {
-+   // init debug mode
-+   _libsaproc_debug = debug;
-+
-+   // initialize the thread_db library
-+   if (td_init() != TD_OK) {
-+     print_debug("libthread_db's td_init failed\n");
-+     return false;
-+   }
-+
-+   return true;
-+}
-+
-+static void destroy_lib_info(struct ps_prochandle* ph) {
-+   lib_info* lib = ph->libs;
-+   while (lib) {
-+     lib_info *next = lib->next;
-+     if (lib->symtab) {
-+        destroy_symtab(lib->symtab);
-+     }
-+     free(lib);
-+     lib = next;
-+   }
-+}
-+
-+static void destroy_thread_info(struct ps_prochandle* ph) {
-+   thread_info* thr = ph->threads;
-+   while (thr) {
-+     thread_info *next = thr->next;
-+     free(thr);
-+     thr = next;
-+   }
-+}
-+
-+// ps_prochandle cleanup
-+
-+// ps_prochandle cleanup
-+void Prelease(struct ps_prochandle* ph) {
-+   // do the "derived class" clean-up first
-+   ph->ops->release(ph);
-+   destroy_lib_info(ph);
-+   destroy_thread_info(ph);
-+   free(ph);
-+}
-+
-+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
-+   return add_lib_info_fd(ph, libname, -1, base);
-+}
-+
-+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
-+   lib_info* newlib;
-+
-+   if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
-+      print_debug("can't allocate memory for lib_info\n");
-+      return NULL;
-+   }
-+
-+   strncpy(newlib->name, libname, sizeof(newlib->name));
-+   newlib->base = base;
-+
-+   if (fd == -1) {
-+      if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
-+         print_debug("can't open shared object %s\n", newlib->name);
-+         free(newlib);
-+         return NULL;
-+      }
-+   } else {
-+      newlib->fd = fd;
-+   }
-+
-+   // check whether we have got an ELF file. /proc/<pid>/map
-+   // gives out all file mappings and not just shared objects
-+   if (is_elf_file(newlib->fd) == false) {
-+      close(newlib->fd);
-+      free(newlib);
-+      return NULL;
-+   }
-+
-+   newlib->symtab = build_symtab(newlib->fd);
-+   if (newlib->symtab == NULL) {
-+      print_debug("symbol table build failed for %s\n", newlib->name);
-+   }
-+   else {
-+      print_debug("built symbol table for %s\n", newlib->name);
-+   }
-+
-+   // even if symbol table building fails, we add the lib_info.
-+   // This is because we may need to read from the ELF file for core file
-+   // address read functionality. lookup_symbol checks for NULL symtab.
-+   if (ph->libs) {
-+      ph->lib_tail->next = newlib;
-+      ph->lib_tail = newlib;
-+   }  else {
-+      ph->libs = ph->lib_tail = newlib;
-+   }
-+   ph->num_libs++;
-+
-+   return newlib;
-+}
-+
-+// lookup for a specific symbol
-+uintptr_t lookup_symbol(struct ps_prochandle* ph,  const char* object_name,
-+                       const char* sym_name) {
-+   // ignore object_name. search in all libraries
-+   // FIXME: what should we do with object_name?? The library names are obtained
-+   // by parsing /proc/<pid>/maps, which may not be the same as object_name.
-+   // What we need is a utility to map object_name to real file name, something
-+   // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
-+   // now, we just ignore object_name and do a global search for the symbol.
-+
-+   lib_info* lib = ph->libs;
-+   while (lib) {
-+      if (lib->symtab) {
-+         uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
-+         if (res) return res;
-+      }
-+      lib = lib->next;
-+   }
-+
-+   print_debug("lookup failed for symbol '%s' in obj '%s'\n",
-+                          sym_name, object_name);
-+   return (uintptr_t) NULL;
-+}
-+
-+
-+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) {
-+   const char* res = NULL;
-+   lib_info* lib = ph->libs;
-+   while (lib) {
-+      if (lib->symtab && addr >= lib->base) {
-+         res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
-+         if (res) return res;
-+      }
-+      lib = lib->next;
-+   }
-+   return NULL;
-+}
-+
-+// add a thread to ps_prochandle
-+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
-+   thread_info* newthr;
-+   if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
-+      print_debug("can't allocate memory for thread_info\n");
-+      return NULL;
-+   }
-+
-+   // initialize thread info
-+   newthr->pthread_id = pthread_id;
-+   newthr->lwp_id = lwp_id;
-+
-+   // add new thread to the list
-+   newthr->next = ph->threads;
-+   ph->threads = newthr;
-+   ph->num_threads++;
-+   return newthr;
-+}
-+
-+
-+// struct used for client data from thread_db callback
-+struct thread_db_client_data {
-+   struct ps_prochandle* ph;
-+   thread_info_callback callback;
-+};
-+
-+// callback function for libthread_db
-+static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
-+  struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
-+  td_thrinfo_t ti;
-+  td_err_e err;
-+
-+  memset(&ti, 0, sizeof(ti));
-+  err = td_thr_get_info(th_p, &ti);
-+  if (err != TD_OK) {
-+    print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
-+    return err;
-+  }
-+
-+  print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
-+
-+  if (ptr->callback(ptr->ph, (pthread_t)ti.ti_tid, ti.ti_lid) != true)
-+    return TD_ERR;
-+
-+  return TD_OK;
-+}
-+
-+// read thread_info using libthread_db
-+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
-+  struct thread_db_client_data mydata;
-+  td_thragent_t* thread_agent = NULL;
-+  if (td_ta_new(ph, &thread_agent) != TD_OK) {
-+     print_debug("can't create libthread_db agent\n");
-+     return false;
-+  }
-+
-+  mydata.ph = ph;
-+  mydata.callback = cb;
-+
-+  // we use libthread_db iterator to iterate thru list of threads.
-+  if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
-+                 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
-+                 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
-+     td_ta_delete(thread_agent);
-+     return false;
-+  }
-+
-+  // delete thread agent
-+  td_ta_delete(thread_agent);
-+  return true;
-+}
-+
-+
-+// get number of threads
-+int get_num_threads(struct ps_prochandle* ph) {
-+   return ph->num_threads;
-+}
-+
-+// get lwp_id of n'th thread
-+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
-+   int count = 0;
-+   thread_info* thr = ph->threads;
-+   while (thr) {
-+      if (count == index) {
-+         return thr->lwp_id;
-+      }
-+      count++;
-+      thr = thr->next;
-+   }
-+   return -1;
-+}
-+
-+// get regs for a given lwp
-+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) {
-+  return ph->ops->get_lwp_regs(ph, lwp_id, regs);
-+}
-+
-+// get number of shared objects
-+int get_num_libs(struct ps_prochandle* ph) {
-+   return ph->num_libs;
-+}
-+
-+// get name of n'th solib
-+const char* get_lib_name(struct ps_prochandle* ph, int index) {
-+   int count = 0;
-+   lib_info* lib = ph->libs;
-+   while (lib) {
-+      if (count == index) {
-+         return lib->name;
-+      }
-+      count++;
-+      lib = lib->next;
-+   }
-+   return NULL;
-+}
-+
-+// get base address of a lib
-+uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
-+   int count = 0;
-+   lib_info* lib = ph->libs;
-+   while (lib) {
-+      if (count == index) {
-+         return lib->base;
-+      }
-+      count++;
-+      lib = lib->next;
-+   }
-+   return (uintptr_t)NULL;
-+}
-+
-+bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
-+  lib_info *p = ph->libs;
-+  while (p) {
-+    if (strcmp(p->name, lib_name) == 0) {
-+      return true;
-+    }
-+    p = p->next;
-+  }
-+  return false;
-+}
-+
-+//--------------------------------------------------------------------------
-+// proc service functions
-+
-+// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
-+// of the load object object_name in the target process identified by ph.
-+// It returns the symbol's value as an address in the target process in
-+// *sym_addr.
-+
-+ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
-+                    const char *sym_name, psaddr_t *sym_addr) {
-+  *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
-+  return (*sym_addr ? PS_OK : PS_NOSYM);
-+}
-+
-+// read "size" bytes info "buf" from address "addr"
-+ps_err_e ps_pread(struct ps_prochandle *ph, psaddr_t  addr,
-+                  void *buf, size_t size) {
-+  return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
-+}
-+
-+// write "size" bytes of data to debuggee at address "addr"
-+ps_err_e ps_pwrite(struct ps_prochandle *ph, psaddr_t addr,
-+                   const void *buf, size_t size) {
-+  return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
-+}
-+
-+// fill in ptrace_lwpinfo for lid
-+ps_err_e ps_linfo(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
-+  return ph->ops->get_lwp_info(ph, lwp_id, linfo)? PS_OK: PS_ERR;
-+}
-+
-+// needed for when libthread_db is compiled with TD_DEBUG defined
-+void
-+ps_plog (const char *format, ...)
-+{
-+  va_list alist;
-+
-+  va_start(alist, format);
-+  vfprintf(stderr, format, alist);
-+  va_end(alist);
-+}
-+
-+// ------------------------------------------------------------------------
-+// Functions below this point are not yet implemented. They are here only
-+// to make the linker happy.
-+
-+ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
-+  print_debug("ps_lsetfpregs not implemented\n");
-+  return PS_OK;
-+}
-+
-+ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
-+  print_debug("ps_lsetregs not implemented\n");
-+  return PS_OK;
-+}
-+
-+ps_err_e  ps_lgetfpregs(struct  ps_prochandle  *ph,  lwpid_t lid, prfpregset_t *fpregs) {
-+  print_debug("ps_lgetfpregs not implemented\n");
-+  return PS_OK;
-+}
-+
-+ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
-+  print_debug("ps_lgetfpregs not implemented\n");
-+  return PS_OK;
-+}
-+
-+ps_err_e ps_lstop(struct ps_prochandle *ph, lwpid_t lid) {
-+  print_debug("ps_lstop not implemented\n");
-+  return PS_OK;
-+}
-+
-+ps_err_e ps_pcontinue(struct ps_prochandle *ph) {
-+  print_debug("ps_pcontinue not implemented\n");
-+  return PS_OK;
-+}
-diff --git a/agent/src/os/bsd/libproc_impl.h b/agent/src/os/bsd/libproc_impl.h
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/libproc_impl.h
-@@ -0,0 +1,130 @@
-+/*
-+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#ifndef _LIBPROC_IMPL_H_
-+#define _LIBPROC_IMPL_H_
-+
-+#include <unistd.h>
-+#include <limits.h>
-+#include "libproc.h"
-+#include "symtab.h"
-+
-+// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
-+
-+#define BUF_SIZE     (PATH_MAX + NAME_MAX + 1)
-+
-+// list of shared objects
-+typedef struct lib_info {
-+  char             name[BUF_SIZE];
-+  uintptr_t        base;
-+  struct symtab*   symtab;
-+  int              fd;        // file descriptor for lib
-+  struct lib_info* next;
-+} lib_info;
-+
-+// list of threads
-+typedef struct thread_info {
-+   lwpid_t                  lwp_id;
-+   pthread_t                pthread_id; // not used cores, always -1
-+   struct reg               regs;       // not for process, core uses for caching regset
-+   struct thread_info*      next;
-+} thread_info;
-+
-+// list of virtual memory maps
-+typedef struct map_info {
-+   int              fd;       // file descriptor
-+   off_t            offset;   // file offset of this mapping
-+   uintptr_t        vaddr;    // starting virtual address
-+   size_t           memsz;    // size of the mapping
-+   struct map_info* next;
-+} map_info;
-+
-+// vtable for ps_prochandle
-+typedef struct ps_prochandle_ops {
-+   // "derived class" clean-up
-+   void (*release)(struct ps_prochandle* ph);
-+   // read from debuggee
-+   bool (*p_pread)(struct ps_prochandle *ph,
-+            uintptr_t addr, char *buf, size_t size);
-+   // write into debuggee
-+   bool (*p_pwrite)(struct ps_prochandle *ph,
-+            uintptr_t addr, const char *buf , size_t size);
-+   // get integer regset of a thread
-+   bool (*get_lwp_regs)(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs);
-+   // get info on thread
-+   bool (*get_lwp_info)(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo);
-+} ps_prochandle_ops;
-+
-+// the ps_prochandle
-+
-+struct core_data {
-+   int                core_fd;   // file descriptor of core file
-+   int                exec_fd;   // file descriptor of exec file
-+   int                interp_fd; // file descriptor of interpreter (ld-elf.so.1)
-+   // part of the class sharing workaround
-+   int                classes_jsa_fd; // file descriptor of class share archive
-+   uintptr_t          dynamic_addr;  // address of dynamic section of a.out
-+   uintptr_t          ld_base_addr;  // base address of ld.so
-+   size_t             num_maps;  // number of maps.
-+   map_info*          maps;      // maps in a linked list
-+   // part of the class sharing workaround
-+   map_info*          class_share_maps;// class share maps in a linked list
-+   map_info**         map_array; // sorted (by vaddr) array of map_info pointers
-+};
-+
-+struct ps_prochandle {
-+   ps_prochandle_ops* ops;       // vtable ptr
-+   pid_t              pid;
-+   int                num_libs;
-+   lib_info*          libs;      // head of lib list
-+   lib_info*          lib_tail;  // tail of lib list - to append at the end
-+   int                num_threads;
-+   thread_info*       threads;   // head of thread list
-+   struct core_data*  core;      // data only used for core dumps, NULL for process
-+};
-+
-+int pathmap_open(const char* name);
-+
-+void print_debug(const char* format,...);
-+bool is_debug();
-+
-+typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
-+
-+// reads thread info using libthread_db and calls above callback for each thread
-+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb);
-+
-+// adds a new shared object to lib list, returns NULL on failure
-+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base);
-+
-+// adds a new shared object to lib list, supply open lib file descriptor as well
-+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
-+                          uintptr_t base);
-+
-+// adds a new thread to threads list, returns NULL on failure
-+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
-+
-+// a test for ELF signature without using libelf
-+bool is_elf_file(int fd);
-+
-+#endif //_LIBPROC_IMPL_H_
-diff --git a/agent/src/os/bsd/mapfile b/agent/src/os/bsd/mapfile
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/mapfile
-@@ -0,0 +1,66 @@
-+#
-+
-+#
-+# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
-+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+#
-+# This code is free software; you can redistribute it and/or modify it
-+# under the terms of the GNU General Public License version 2 only, as
-+# published by the Free Software Foundation.
-+#
-+# This code is distributed in the hope that it will be useful, but WITHOUT
-+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+# version 2 for more details (a copy is included in the LICENSE file that
-+# accompanied this code).
-+#
-+# You should have received a copy of the GNU General Public License version
-+# 2 along with this work; if not, write to the Free Software Foundation,
-+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+#
-+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+# or visit www.oracle.com if you need additional information or have any
-+# questions.
-+#  
-+#
-+
-+# Define public interface.
-+
-+SUNWprivate_1.1 {
-+        global:
-+
-+		# native methods of BsdDebuggerLocal class
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0;
-+		Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0;
-+	
-+		# proc_service.h functions - to be used by libthread_db
-+		ps_getpid;
-+		ps_pglobal_lookup;
-+		ps_pread;
-+		ps_pwrite;
-+		ps_lsetfpregs;
-+		ps_lsetregs;
-+		ps_lgetfpregs;
-+		ps_lgetregs;
-+		ps_lcontinue;
-+		ps_lgetxmmregs;
-+		ps_lsetxmmregs;
-+		ps_lstop;
-+		ps_linfo;
-+
-+                # used by attach test program
-+                init_libproc;
-+                Pgrab;
-+                Pgrab_core;
-+                Prelease;
-+	
-+	local:
-+		*;
-+};
-diff --git a/agent/src/os/bsd/ps_core.c b/agent/src/os/bsd/ps_core.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/ps_core.c
-@@ -0,0 +1,1023 @@
-+/*
-+ * Copyright (c) 2003, 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
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#include <jni.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stddef.h>
-+#include <elf.h>
-+#include <link.h>
-+#include "libproc_impl.h"
-+#include "salibelf.h"
-+
-+// This file has the libproc implementation to read core files.
-+// For live processes, refer to ps_proc.c. Portions of this is adapted
-+// /modelled after Solaris libproc.so (in particular Pcore.c)
-+
-+//----------------------------------------------------------------------
-+// ps_prochandle cleanup helper functions
-+
-+// close all file descriptors
-+static void close_elf_files(struct ps_prochandle* ph) {
-+   lib_info* lib = NULL;
-+
-+   // close core file descriptor
-+   if (ph->core->core_fd >= 0)
-+     close(ph->core->core_fd);
-+
-+   // close exec file descriptor
-+   if (ph->core->exec_fd >= 0)
-+     close(ph->core->exec_fd);
-+
-+   // close interp file descriptor
-+   if (ph->core->interp_fd >= 0)
-+     close(ph->core->interp_fd);
-+
-+   // close class share archive file
-+   if (ph->core->classes_jsa_fd >= 0)
-+     close(ph->core->classes_jsa_fd);
-+
-+   // close all library file descriptors
-+   lib = ph->libs;
-+   while (lib) {
-+      int fd = lib->fd;
-+      if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
-+      lib = lib->next;
-+   }
-+}
-+
-+// clean all map_info stuff
-+static void destroy_map_info(struct ps_prochandle* ph) {
-+  map_info* map = ph->core->maps;
-+  while (map) {
-+     map_info* next = map->next;
-+     free(map);
-+     map = next;
-+  }
-+
-+  if (ph->core->map_array) {
-+     free(ph->core->map_array);
-+  }
-+
-+  // Part of the class sharing workaround
-+  map = ph->core->class_share_maps;
-+  while (map) {
-+     map_info* next = map->next;
-+     free(map);
-+     map = next;
-+  }
-+}
-+
-+// ps_prochandle operations
-+static void core_release(struct ps_prochandle* ph) {
-+   if (ph->core) {
-+      close_elf_files(ph);
-+      destroy_map_info(ph);
-+      free(ph->core);
-+   }
-+}
-+
-+static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
-+   map_info* map;
-+   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
-+      print_debug("can't allocate memory for map_info\n");
-+      return NULL;
-+   }
-+
-+   // initialize map
-+   map->fd     = fd;
-+   map->offset = offset;
-+   map->vaddr  = vaddr;
-+   map->memsz  = memsz;
-+   return map;
-+}
-+
-+// add map info with given fd, offset, vaddr and memsz
-+static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
-+                             uintptr_t vaddr, size_t memsz) {
-+   map_info* map;
-+   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
-+      return NULL;
-+   }
-+
-+   // add this to map list
-+   map->next  = ph->core->maps;
-+   ph->core->maps   = map;
-+   ph->core->num_maps++;
-+
-+   return map;
-+}
-+
-+// Part of the class sharing workaround
-+static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
-+                             uintptr_t vaddr, size_t memsz) {
-+   map_info* map;
-+   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
-+                                offset, vaddr, memsz)) == NULL) {
-+      return NULL;
-+   }
-+
-+   map->next = ph->core->class_share_maps;
-+   ph->core->class_share_maps = map;
-+   return map;
-+}
-+
-+// Return the map_info for the given virtual address.  We keep a sorted
-+// array of pointers in ph->map_array, so we can binary search.
-+static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
-+{
-+   int mid, lo = 0, hi = ph->core->num_maps - 1;
-+   map_info *mp;
-+
-+   while (hi - lo > 1) {
-+     mid = (lo + hi) / 2;
-+      if (addr >= ph->core->map_array[mid]->vaddr)
-+         lo = mid;
-+      else
-+         hi = mid;
-+   }
-+
-+   if (addr < ph->core->map_array[hi]->vaddr)
-+      mp = ph->core->map_array[lo];
-+   else
-+      mp = ph->core->map_array[hi];
-+
-+   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
-+      return (mp);
-+
-+
-+   // Part of the class sharing workaround
-+   // Unfortunately, we have no way of detecting -Xshare state.
-+   // Check out the share maps atlast, if we don't find anywhere.
-+   // This is done this way so to avoid reading share pages
-+   // ahead of other normal maps. For eg. with -Xshare:off we don't
-+   // want to prefer class sharing data to data from core.
-+   mp = ph->core->class_share_maps;
-+   if (mp) {
-+      print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
-+             addr);
-+   }
-+   while (mp) {
-+      if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
-+         print_debug("located map_info at 0x%lx from class share maps\n",
-+                  addr);
-+         return (mp);
-+      }
-+      mp = mp->next;
-+   }
-+
-+   print_debug("can't locate map_info at 0x%lx\n", addr);
-+   return (NULL);
-+}
-+
-+//---------------------------------------------------------------
-+// Part of the class sharing workaround:
-+//
-+// With class sharing, pages are mapped from classes[_g].jsa file.
-+// The read-only class sharing pages are mapped as MAP_SHARED,
-+// PROT_READ pages. These pages are not dumped into core dump.
-+// With this workaround, these pages are read from classes[_g].jsa.
-+
-+// FIXME: !HACK ALERT!
-+// The format of sharing achive file header is needed to read shared heap
-+// file mappings. For now, I am hard coding portion of FileMapHeader here.
-+// Refer to filemap.hpp.
-+
-+// FileMapHeader describes the shared space data in the file to be
-+// mapped.  This structure gets written to a file.  It is not a class,
-+// so that the compilers don't add any compiler-private data to it.
-+
-+// Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
-+#define NUM_SHARED_MAPS 4
-+
-+// Refer to FileMapInfo::_current_version in filemap.hpp
-+#define CURRENT_ARCHIVE_VERSION 1
-+
-+struct FileMapHeader {
-+  int   _magic;              // identify file type.
-+  int   _version;            // (from enum, above.)
-+  size_t _alignment;         // how shared archive should be aligned
-+
-+  struct space_info {
-+    int    _file_offset;     // sizeof(this) rounded to vm page size
-+    char*  _base;            // copy-on-write base address
-+    size_t _capacity;        // for validity checking
-+    size_t _used;            // for setting space top on read
-+
-+    // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
-+    // the C type matching the C++ bool type on any given platform. For
-+    // Hotspot on BSD we assume the corresponding C type is char but
-+    // licensees on BSD versions may need to adjust the type of these fields.
-+    char   _read_only;       // read only space?
-+    char   _allow_exec;      // executable code in space?
-+
-+  } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
-+
-+  // Ignore the rest of the FileMapHeader. We don't need those fields here.
-+};
-+
-+static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
-+   jboolean i;
-+   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
-+      *pvalue = i;
-+      return true;
-+   } else {
-+      return false;
-+   }
-+}
-+
-+static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
-+   uintptr_t uip;
-+   if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
-+      *pvalue = uip;
-+      return true;
-+   } else {
-+      return false;
-+   }
-+}
-+
-+// used to read strings from debuggee
-+static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
-+   size_t i = 0;
-+   char  c = ' ';
-+
-+   while (c != '\0') {
-+     if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
-+         return false;
-+      if (i < size - 1)
-+         buf[i] = c;
-+      else // smaller buffer
-+         return false;
-+      i++; addr++;
-+   }
-+
-+   buf[i] = '\0';
-+   return true;
-+}
-+
-+#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
-+// mangled name of Arguments::SharedArchivePath
-+#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
-+
-+static bool init_classsharing_workaround(struct ps_prochandle* ph) {
-+   lib_info* lib = ph->libs;
-+   while (lib != NULL) {
-+      // we are iterating over shared objects from the core dump. look for
-+      // libjvm[_g].so.
-+      const char *jvm_name = 0;
-+      if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
-+          (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
-+         char classes_jsa[PATH_MAX];
-+         struct FileMapHeader header;
-+         size_t n = 0;
-+         int fd = -1, m = 0;
-+         uintptr_t base = 0, useSharedSpacesAddr = 0;
-+         uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
-+         jboolean useSharedSpaces = 0;
-+
-+         memset(classes_jsa, 0, sizeof(classes_jsa));
-+         jvm_name = lib->name;
-+         useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
-+         if (useSharedSpacesAddr == 0) {
-+            print_debug("can't lookup 'UseSharedSpaces' flag\n");
-+            return false;
-+         }
-+
-+         // Hotspot vm types are not exported to build this library. So
-+         // using equivalent type jboolean to read the value of
-+         // UseSharedSpaces which is same as hotspot type "bool".
-+         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
-+            print_debug("can't read the value of 'UseSharedSpaces' flag\n");
-+            return false;
-+         }
-+
-+         if ((int)useSharedSpaces == 0) {
-+            print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
-+            return true;
-+         }
-+
-+         sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
-+         if (sharedArchivePathAddrAddr == 0) {
-+            print_debug("can't lookup shared archive path symbol\n");
-+            return false;
-+         }
-+
-+         if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
-+            print_debug("can't read shared archive path pointer\n");
-+            return false;
-+         }
-+
-+         if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
-+            print_debug("can't read shared archive path value\n");
-+            return false;
-+         }
-+
-+         print_debug("looking for %s\n", classes_jsa);
-+         // open the class sharing archive file
-+         fd = pathmap_open(classes_jsa);
-+         if (fd < 0) {
-+            print_debug("can't open %s!\n", classes_jsa);
-+            ph->core->classes_jsa_fd = -1;
-+            return false;
-+         } else {
-+            print_debug("opened %s\n", classes_jsa);
-+         }
-+
-+         // read FileMapHeader from the file
-+         memset(&header, 0, sizeof(struct FileMapHeader));
-+         if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
-+              != sizeof(struct FileMapHeader)) {
-+            print_debug("can't read shared archive file map header from %s\n", classes_jsa);
-+            close(fd);
-+            return false;
-+         }
-+
-+         // check file magic
-+         if (header._magic != 0xf00baba2) {
-+            print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
-+                        classes_jsa, header._magic);
-+            close(fd);
-+            return false;
-+         }
-+
-+         // check version
-+         if (header._version != CURRENT_ARCHIVE_VERSION) {
-+            print_debug("%s has wrong shared archive file version %d, expecting %d\n",
-+                        classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
-+            close(fd);
-+            return false;
-+         }
-+
-+         ph->core->classes_jsa_fd = fd;
-+         // add read-only maps from classes[_g].jsa to the list of maps
-+         for (m = 0; m < NUM_SHARED_MAPS; m++) {
-+            if (header._space[m]._read_only) {
-+               base = (uintptr_t) header._space[m]._base;
-+               // no need to worry about the fractional pages at-the-end.
-+               // possible fractional pages are handled by core_read_data.
-+               add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
-+                         base, (size_t) header._space[m]._used);
-+               print_debug("added a share archive map at 0x%lx\n", base);
-+            }
-+         }
-+         return true;
-+      }
-+      lib = lib->next;
-+   }
-+   return true;
-+}
-+
-+
-+//---------------------------------------------------------------------------
-+// functions to handle map_info
-+
-+// Order mappings based on virtual address.  We use this function as the
-+// callback for sorting the array of map_info pointers.
-+static int core_cmp_mapping(const void *lhsp, const void *rhsp)
-+{
-+   const map_info *lhs = *((const map_info **)lhsp);
-+   const map_info *rhs = *((const map_info **)rhsp);
-+
-+   if (lhs->vaddr == rhs->vaddr)
-+      return (0);
-+
-+   return (lhs->vaddr < rhs->vaddr ? -1 : 1);
-+}
-+
-+// we sort map_info by starting virtual address so that we can do
-+// binary search to read from an address.
-+static bool sort_map_array(struct ps_prochandle* ph) {
-+   size_t num_maps = ph->core->num_maps;
-+   map_info* map = ph->core->maps;
-+   int i = 0;
-+
-+   // allocate map_array
-+   map_info** array;
-+   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
-+      print_debug("can't allocate memory for map array\n");
-+      return false;
-+   }
-+
-+   // add maps to array
-+   while (map) {
-+      array[i] = map;
-+      i++;
-+      map = map->next;
-+   }
-+
-+   // sort is called twice. If this is second time, clear map array
-+   if (ph->core->map_array) free(ph->core->map_array);
-+   ph->core->map_array = array;
-+   // sort the map_info array by base virtual address.
-+   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
-+            core_cmp_mapping);
-+
-+   // print map
-+   if (is_debug()) {
-+      int j = 0;
-+      print_debug("---- sorted virtual address map ----\n");
-+      for (j = 0; j < ph->core->num_maps; j++) {
-+        print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
-+                                         ph->core->map_array[j]->memsz);
-+      }
-+   }
-+
-+   return true;
-+}
-+
-+#ifndef MIN
-+#define MIN(x, y) (((x) < (y))? (x): (y))
-+#endif
-+
-+static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
-+   ssize_t resid = size;
-+   int page_size=sysconf(_SC_PAGE_SIZE);
-+   while (resid != 0) {
-+      map_info *mp = core_lookup(ph, addr);
-+      uintptr_t mapoff;
-+      ssize_t len, rem;
-+      off_t off;
-+      int fd;
-+
-+      if (mp == NULL)
-+         break;  /* No mapping for this address */
-+
-+      fd = mp->fd;
-+      mapoff = addr - mp->vaddr;
-+      len = MIN(resid, mp->memsz - mapoff);
-+      off = mp->offset + mapoff;
-+
-+      if ((len = pread(fd, buf, len, off)) <= 0)
-+         break;
-+
-+      resid -= len;
-+      addr += len;
-+      buf = (char *)buf + len;
-+
-+      // mappings always start at page boundary. But, may end in fractional
-+      // page. fill zeros for possible fractional page at the end of a mapping.
-+      rem = mp->memsz % page_size;
-+      if (rem > 0) {
-+         rem = page_size - rem;
-+         len = MIN(resid, rem);
-+         resid -= len;
-+         addr += len;
-+         // we are not assuming 'buf' to be zero initialized.
-+         memset(buf, 0, len);
-+         buf += len;
-+      }
-+   }
-+
-+   if (resid) {
-+      print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
-+              size, addr, resid);
-+      return false;
-+   } else {
-+      return true;
-+   }
-+}
-+
-+// null implementation for write
-+static bool core_write_data(struct ps_prochandle* ph,
-+                             uintptr_t addr, const char *buf , size_t size) {
-+   return false;
-+}
-+
-+static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
-+                          struct reg* regs) {
-+   // for core we have cached the lwp regs from NOTE section
-+   thread_info* thr = ph->threads;
-+   while (thr) {
-+     if (thr->lwp_id == lwp_id) {
-+       memcpy(regs, &thr->regs, sizeof(struct reg));
-+       return true;
-+     }
-+     thr = thr->next;
-+   }
-+   return false;
-+}
-+
-+static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
-+   print_debug("core_get_lwp_info not implemented\n");
-+   return false;
-+}
-+
-+static ps_prochandle_ops core_ops = {
-+   .release=  core_release,
-+   .p_pread=  core_read_data,
-+   .p_pwrite= core_write_data,
-+   .get_lwp_regs= core_get_lwp_regs,
-+   .get_lwp_info= core_get_lwp_info
-+};
-+
-+// read regs and create thread from NT_PRSTATUS entries from core file
-+static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
-+   // we have to read prstatus_t from buf
-+   // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
-+   prstatus_t* prstat = (prstatus_t*) buf;
-+   thread_info* newthr;
-+   print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
-+   // we set pthread_t to -1 for core dump
-+   if((newthr = add_thread_info(ph, (pthread_t) -1,  prstat->pr_pid)) == NULL)
-+      return false;
-+
-+   // copy regs
-+   memcpy(&newthr->regs, &prstat->pr_reg, sizeof(struct reg));
-+
-+   if (is_debug()) {
-+      print_debug("integer regset\n");
-+#ifdef i386
-+      // print the regset
-+      print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
-+      print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
-+      print_debug("\tecx = 0x%x\n", newthr->regs.r_ecx);
-+      print_debug("\tedx = 0x%x\n", newthr->regs.r_edx);
-+      print_debug("\tesp = 0x%x\n", newthr->regs.r_esp);
-+      print_debug("\tebp = 0x%x\n", newthr->regs.r_ebp);
-+      print_debug("\tesi = 0x%x\n", newthr->regs.r_esi);
-+      print_debug("\tedi = 0x%x\n", newthr->regs.r_edi);
-+      print_debug("\teip = 0x%x\n", newthr->regs.r_eip);
-+#endif
-+
-+#if defined(amd64) || defined(x86_64)
-+      // print the regset
-+      print_debug("\tr15 = 0x%lx\n", newthr->regs.r_r15);
-+      print_debug("\tr14 = 0x%lx\n", newthr->regs.r_r14);
-+      print_debug("\tr13 = 0x%lx\n", newthr->regs.r_r13);
-+      print_debug("\tr12 = 0x%lx\n", newthr->regs.r_r12);
-+      print_debug("\trbp = 0x%lx\n", newthr->regs.r_rbp);
-+      print_debug("\trbx = 0x%lx\n", newthr->regs.r_rbx);
-+      print_debug("\tr11 = 0x%lx\n", newthr->regs.r_r11);
-+      print_debug("\tr10 = 0x%lx\n", newthr->regs.r_r10);
-+      print_debug("\tr9 = 0x%lx\n", newthr->regs.r_r9);
-+      print_debug("\tr8 = 0x%lx\n", newthr->regs.r_r8);
-+      print_debug("\trax = 0x%lx\n", newthr->regs.r_rax);
-+      print_debug("\trcx = 0x%lx\n", newthr->regs.r_rcx);
-+      print_debug("\trdx = 0x%lx\n", newthr->regs.r_rdx);
-+      print_debug("\trsi = 0x%lx\n", newthr->regs.r_rsi);
-+      print_debug("\trdi = 0x%lx\n", newthr->regs.r_rdi);
-+      //print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
-+      print_debug("\trip = 0x%lx\n", newthr->regs.r_rip);
-+      print_debug("\tcs = 0x%lx\n", newthr->regs.r_cs);
-+      //print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
-+      print_debug("\trsp = 0x%lx\n", newthr->regs.r_rsp);
-+      print_debug("\tss = 0x%lx\n", newthr->regs.r_ss);
-+      //print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
-+      //print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
-+      //print_debug("\tds = 0x%lx\n", newthr->regs.ds);
-+      //print_debug("\tes = 0x%lx\n", newthr->regs.es);
-+      //print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
-+      //print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
-+#endif
-+   }
-+
-+   return true;
-+}
-+
-+#define ROUNDUP(x, y)  ((((x)+((y)-1))/(y))*(y))
-+
-+// read NT_PRSTATUS entries from core NOTE segment
-+static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
-+   char* buf = NULL;
-+   char* p = NULL;
-+   size_t size = note_phdr->p_filesz;
-+
-+   // we are interested in just prstatus entries. we will ignore the rest.
-+   // Advance the seek pointer to the start of the PT_NOTE data
-+   if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
-+      print_debug("failed to lseek to PT_NOTE data\n");
-+      return false;
-+   }
-+
-+   // Now process the PT_NOTE structures.  Each one is preceded by
-+   // an Elf{32/64}_Nhdr structure describing its type and size.
-+   if ( (buf = (char*) malloc(size)) == NULL) {
-+      print_debug("can't allocate memory for reading core notes\n");
-+      goto err;
-+   }
-+
-+   // read notes into buffer
-+   if (read(ph->core->core_fd, buf, size) != size) {
-+      print_debug("failed to read notes, core file must have been truncated\n");
-+      goto err;
-+   }
-+
-+   p = buf;
-+   while (p < buf + size) {
-+      ELF_NHDR* notep = (ELF_NHDR*) p;
-+      char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
-+      print_debug("Note header with n_type = %d and n_descsz = %u\n",
-+                                   notep->n_type, notep->n_descsz);
-+
-+      if (notep->n_type == NT_PRSTATUS) {
-+         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
-+            return false;
-+      }
-+      p = descdata + ROUNDUP(notep->n_descsz, 4);
-+   }
-+
-+   free(buf);
-+   return true;
-+
-+err:
-+   if (buf) free(buf);
-+   return false;
-+}
-+
-+// read all segments from core file
-+static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
-+   int i = 0;
-+   ELF_PHDR* phbuf = NULL;
-+   ELF_PHDR* core_php = NULL;
-+
-+   if ((phbuf =  read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
-+      return false;
-+
-+   /*
-+    * Now iterate through the program headers in the core file.
-+    * We're interested in two types of Phdrs: PT_NOTE (which
-+    * contains a set of saved /proc structures), and PT_LOAD (which
-+    * represents a memory mapping from the process's address space).
-+    *
-+    * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
-+    *
-+    *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
-+    *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
-+    *     PT_NOTE has data in new /proc format.
-+    *
-+    *     In Solaris, there is only one pstatus (process status). pstatus contains
-+    *     integer register set among other stuff. For each LWP, we have one lwpstatus
-+    *     entry that has integer regset for that LWP.
-+    *
-+    *     Linux threads are actually 'clone'd processes. To support core analysis
-+    *     of "multithreaded" process, Linux creates more than one pstatus (called
-+    *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
-+    *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
-+    *     function "elf_core_dump".
-+    */
-+
-+    for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
-+      switch (core_php->p_type) {
-+         case PT_NOTE:
-+            if (core_handle_note(ph, core_php) != true) goto err;
-+            break;
-+
-+         case PT_LOAD: {
-+            if (core_php->p_filesz != 0) {
-+               if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
-+                  core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
-+            }
-+            break;
-+         }
-+      }
-+
-+      core_php++;
-+   }
-+
-+   free(phbuf);
-+   return true;
-+err:
-+   free(phbuf);
-+   return false;
-+}
-+
-+// read segments of a shared object
-+static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
-+   int i = 0;
-+   ELF_PHDR* phbuf;
-+   ELF_PHDR* lib_php = NULL;
-+
-+   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
-+      return false;
-+
-+   // we want to process only PT_LOAD segments that are not writable.
-+   // i.e., text segments. The read/write/exec (data) segments would
-+   // have been already added from core file segments.
-+   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
-+      if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
-+         if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
-+            goto err;
-+      }
-+      lib_php++;
-+   }
-+
-+   free(phbuf);
-+   return true;
-+err:
-+   free(phbuf);
-+   return false;
-+}
-+
-+// process segments from interpreter (ld-elf.so.1)
-+static bool read_interp_segments(struct ps_prochandle* ph) {
-+   ELF_EHDR interp_ehdr;
-+
-+   if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
-+       print_debug("interpreter is not a valid ELF file\n");
-+       return false;
-+   }
-+
-+   if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
-+       print_debug("can't read segments of interpreter\n");
-+       return false;
-+   }
-+
-+   return true;
-+}
-+
-+// process segments of a a.out
-+static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
-+   int i = 0;
-+   ELF_PHDR* phbuf = NULL;
-+   ELF_PHDR* exec_php = NULL;
-+
-+   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
-+      return false;
-+
-+   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
-+      switch (exec_php->p_type) {
-+
-+         // add mappings for PT_LOAD segments
-+         case PT_LOAD: {
-+            // add only non-writable segments of non-zero filesz
-+            if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
-+               if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
-+            }
-+            break;
-+         }
-+
-+         // read the interpreter and it's segments
-+         case PT_INTERP: {
-+            char interp_name[BUF_SIZE];
-+
-+            pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
-+            print_debug("ELF interpreter %s\n", interp_name);
-+            // read interpreter segments as well
-+            if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
-+               print_debug("can't open runtime loader\n");
-+               goto err;
-+            }
-+            break;
-+         }
-+
-+         // from PT_DYNAMIC we want to read address of first link_map addr
-+         case PT_DYNAMIC: {
-+            ph->core->dynamic_addr = exec_php->p_vaddr;
-+            print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
-+            break;
-+         }
-+
-+      } // switch
-+      exec_php++;
-+   } // for
-+
-+   free(phbuf);
-+   return true;
-+err:
-+   free(phbuf);
-+   return false;
-+}
-+
-+
-+#define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
-+#define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
-+#define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
-+#define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
-+#define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
-+
-+// read shared library info from runtime linker's data structures.
-+// This work is done by librtlb_db in Solaris
-+static bool read_shared_lib_info(struct ps_prochandle* ph) {
-+   uintptr_t addr = ph->core->dynamic_addr;
-+   uintptr_t debug_base;
-+   uintptr_t first_link_map_addr;
-+   uintptr_t ld_base_addr;
-+   uintptr_t link_map_addr;
-+   uintptr_t lib_base_diff;
-+   uintptr_t lib_base;
-+   uintptr_t lib_name_addr;
-+   char lib_name[BUF_SIZE];
-+   ELF_DYN dyn;
-+   ELF_EHDR elf_ehdr;
-+   int lib_fd;
-+
-+   // _DYNAMIC has information of the form
-+   //         [tag] [data] [tag] [data] .....
-+   // Both tag and data are pointer sized.
-+   // We look for dynamic info with DT_DEBUG. This has shared object info.
-+   // refer to struct r_debug in link.h
-+
-+   dyn.d_tag = DT_NULL;
-+   while (dyn.d_tag != DT_DEBUG) {
-+      if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
-+         print_debug("can't read debug info from _DYNAMIC\n");
-+         return false;
-+      }
-+      addr += sizeof(ELF_DYN);
-+   }
-+
-+   // we have got Dyn entry with DT_DEBUG
-+   debug_base = dyn.d_un.d_ptr;
-+   // at debug_base we have struct r_debug. This has first link map in r_map field
-+   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
-+                 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
-+      print_debug("can't read first link map address\n");
-+      return false;
-+   }
-+
-+   // read ld_base address from struct r_debug
-+   // XXX: There is no r_ldbase member on BSD
-+/*
-+   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
-+                 sizeof(uintptr_t)) != PS_OK) {
-+      print_debug("can't read ld base address\n");
-+      return false;
-+   }
-+   ph->core->ld_base_addr = ld_base_addr;
-+*/
-+   ph->core->ld_base_addr = 0;
-+
-+   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
-+
-+   // now read segments from interp (i.e ld-elf.so.1)
-+   if (read_interp_segments(ph) != true)
-+      return false;
-+
-+   // after adding interpreter (ld.so) mappings sort again
-+   if (sort_map_array(ph) != true)
-+      return false;
-+
-+   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
-+
-+   link_map_addr = first_link_map_addr;
-+   while (link_map_addr != 0) {
-+      // read library base address of the .so. Note that even though <sys/link.h> calls
-+      // link_map->l_addr as "base address",  this is * not * really base virtual
-+      // address of the shared object. This is actually the difference b/w the virtual
-+      // address mentioned in shared object and the actual virtual base where runtime
-+      // linker loaded it. We use "base diff" in read_lib_segments call below.
-+
-+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
-+                   &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
-+         print_debug("can't read shared object base address diff\n");
-+         return false;
-+      }
-+
-+      // read address of the name
-+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
-+                    &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
-+         print_debug("can't read address of shared object name\n");
-+         return false;
-+      }
-+
-+      // read name of the shared object
-+      if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
-+         print_debug("can't read shared object name\n");
-+         return false;
-+      }
-+
-+      if (lib_name[0] != '\0') {
-+         // ignore empty lib names
-+         lib_fd = pathmap_open(lib_name);
-+
-+         if (lib_fd < 0) {
-+            print_debug("can't open shared object %s\n", lib_name);
-+            // continue with other libraries...
-+         } else {
-+            if (read_elf_header(lib_fd, &elf_ehdr)) {
-+               lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
-+               print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
-+                           lib_name, lib_base, lib_base_diff);
-+               // while adding library mappings we need to use "base difference".
-+               if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
-+                  print_debug("can't read shared object's segments\n");
-+                  close(lib_fd);
-+                  return false;
-+               }
-+               add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
-+               // Map info is added for the library (lib_name) so
-+               // we need to re-sort it before calling the p_pdread.
-+               if (sort_map_array(ph) != true)
-+                  return false;
-+            } else {
-+               print_debug("can't read ELF header for shared object %s\n", lib_name);
-+               close(lib_fd);
-+               // continue with other libraries...
-+            }
-+         }
-+      }
-+
-+      // read next link_map address
-+      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
-+                        &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
-+         print_debug("can't read next link in link_map\n");
-+         return false;
-+      }
-+   }
-+
-+   return true;
-+}
-+
-+// the one and only one exposed stuff from this file
-+struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
-+   ELF_EHDR core_ehdr;
-+   ELF_EHDR exec_ehdr;
-+
-+   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
-+   if (ph == NULL) {
-+      print_debug("can't allocate ps_prochandle\n");
-+      return NULL;
-+   }
-+
-+   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
-+      free(ph);
-+      print_debug("can't allocate ps_prochandle\n");
-+      return NULL;
-+   }
-+
-+   // initialize ph
-+   ph->ops = &core_ops;
-+   ph->core->core_fd   = -1;
-+   ph->core->exec_fd   = -1;
-+   ph->core->interp_fd = -1;
-+
-+   // open the core file
-+   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
-+      print_debug("can't open core file\n");
-+      goto err;
-+   }
-+
-+   // read core file ELF header
-+   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
-+      print_debug("core file is not a valid ELF ET_CORE file\n");
-+      goto err;
-+   }
-+
-+   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
-+      print_debug("can't open executable file\n");
-+      goto err;
-+   }
-+
-+   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
-+      print_debug("executable file is not a valid ELF ET_EXEC file\n");
-+      goto err;
-+   }
-+
-+   // process core file segments
-+   if (read_core_segments(ph, &core_ehdr) != true)
-+      goto err;
-+
-+   // process exec file segments
-+   if (read_exec_segments(ph, &exec_ehdr) != true)
-+      goto err;
-+
-+   // exec file is also treated like a shared object for symbol search
-+   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
-+                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
-+      goto err;
-+
-+   // allocate and sort maps into map_array, we need to do this
-+   // here because read_shared_lib_info needs to read from debuggee
-+   // address space
-+   if (sort_map_array(ph) != true)
-+      goto err;
-+
-+   if (read_shared_lib_info(ph) != true)
-+      goto err;
-+
-+   // sort again because we have added more mappings from shared objects
-+   if (sort_map_array(ph) != true)
-+      goto err;
-+
-+   if (init_classsharing_workaround(ph) != true)
-+      goto err;
-+
-+   return ph;
-+
-+err:
-+   Prelease(ph);
-+   return NULL;
-+}
-diff --git a/agent/src/os/bsd/ps_proc.c b/agent/src/os/bsd/ps_proc.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/ps_proc.c
-@@ -0,0 +1,444 @@
-+/*
-+ * Copyright (c) 2003, 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
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#include <limits.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <sys/ptrace.h>
-+#include <sys/param.h>
-+#include <sys/user.h>
-+#include <elf.h>
-+#include <sys/elf_common.h>
-+#include <sys/link_elf.h>
-+#include <libutil.h>
-+#include "libproc_impl.h"
-+#include "elfmacros.h"
-+
-+// This file has the libproc implementation specific to live process
-+// For core files, refer to ps_core.c
-+
-+static inline uintptr_t align(uintptr_t ptr, size_t size) {
-+  return (ptr & ~(size - 1));
-+}
-+
-+// ---------------------------------------------
-+// ptrace functions
-+// ---------------------------------------------
-+
-+// read "size" bytes of data from "addr" within the target process.
-+// unlike the standard ptrace() function, process_read_data() can handle
-+// unaligned address - alignment check, if required, should be done
-+// before calling process_read_data.
-+
-+static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
-+  int rslt;
-+  size_t i, words;
-+  uintptr_t end_addr = addr + size;
-+  uintptr_t aligned_addr = align(addr, sizeof(int));
-+
-+  if (aligned_addr != addr) {
-+    char *ptr = (char *)&rslt;
-+    errno = 0;
-+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
-+    if (errno) {
-+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
-+      return false;
-+    }
-+    for (; aligned_addr != addr; aligned_addr++, ptr++);
-+    for (; ((intptr_t)aligned_addr % sizeof(int)) && aligned_addr < end_addr;
-+        aligned_addr++)
-+       *(buf++) = *(ptr++);
-+  }
-+
-+  words = (end_addr - aligned_addr) / sizeof(int);
-+
-+  // assert((intptr_t)aligned_addr % sizeof(int) == 0);
-+  for (i = 0; i < words; i++) {
-+    errno = 0;
-+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
-+    if (errno) {
-+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
-+      return false;
-+    }
-+    *(int *)buf = rslt;
-+    buf += sizeof(int);
-+    aligned_addr += sizeof(int);
-+  }
-+
-+  if (aligned_addr != end_addr) {
-+    char *ptr = (char *)&rslt;
-+    errno = 0;
-+    rslt = ptrace(PT_READ_D, ph->pid, (caddr_t) aligned_addr, 0);
-+    if (errno) {
-+      print_debug("ptrace(PT_READ_D, ..) failed for %d bytes @ %lx\n", size, addr);
-+      return false;
-+    }
-+    for (; aligned_addr != end_addr; aligned_addr++)
-+       *(buf++) = *(ptr++);
-+  }
-+  return true;
-+}
-+
-+// null implementation for write
-+static bool process_write_data(struct ps_prochandle* ph,
-+                             uintptr_t addr, const char *buf , size_t size) {
-+  return false;
-+}
-+
-+// "user" should be a pointer to a reg
-+static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct reg *user) {
-+  // we have already attached to all thread 'pid's, just use ptrace call
-+  // to get regset now. Note that we don't cache regset upfront for processes.
-+ if (ptrace(PT_GETREGS, pid, (caddr_t) user, 0) < 0) {
-+   print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
-+   return false;
-+ }
-+ return true;
-+}
-+
-+// fill in ptrace_lwpinfo for lid
-+static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
-+  errno = 0;
-+  ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));
-+
-+  return (errno == 0)? true: false;
-+}
-+
-+// attach to a process/thread specified by "pid"
-+static bool ptrace_attach(pid_t pid) {
-+  if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
-+    print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
-+    return false;
-+  } else {
-+    int ret;
-+    int status;
-+    do {
-+      // Wait for debuggee to stop.
-+      ret = waitpid(pid, &status, 0);
-+      if (ret >= 0) {
-+        if (WIFSTOPPED(status)) {
-+          // Debuggee stopped.
-+          return true;
-+        } else {
-+          print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
-+          return false;
-+        }
-+      } else {
-+        switch (errno) {
-+          case EINTR:
-+            continue;
-+            break;
-+          case ECHILD:
-+            print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
-+            break;
-+          case EINVAL:
-+            print_debug("waitpid() failed. Invalid options argument.\n");
-+            break;
-+          default:
-+            print_debug("waitpid() failed. Unexpected error %d\n",errno);
-+        }
-+        return false;
-+      }
-+    } while(true);
-+  }
-+}
-+
-+// -------------------------------------------------------
-+// functions for obtaining library information
-+// -------------------------------------------------------
-+
-+// callback for read_thread_info
-+static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
-+  return add_thread_info(ph, pthread_id, lwp_id) != NULL;
-+}
-+
-+#if defined(__FreeBSD__) && __FreeBSD_version < 701000
-+/*
-+ * TEXT_START_ADDR from binutils/ld/emulparams/<arch_spec>.sh
-+ * Not the most robust but good enough.
-+ */
-+
-+#if defined(amd64) || defined(x86_64)
-+#define TEXT_START_ADDR 0x400000
-+#elif defined(i386)
-+#define TEXT_START_ADDR 0x8048000
-+#else
-+#error TEXT_START_ADDR not defined
-+#endif
-+
-+#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
-+
-+uintptr_t linkmap_addr(struct ps_prochandle *ph) {
-+  uintptr_t ehdr_addr, phdr_addr, dyn_addr, dmap_addr, lmap_addr;
-+  ELF_EHDR ehdr;
-+  ELF_PHDR *phdrs, *phdr;
-+  ELF_DYN *dyns, *dyn;
-+  struct r_debug dmap;
-+  unsigned long hdrs_size;
-+  unsigned int i;
-+
-+  /* read ELF_EHDR at TEXT_START_ADDR and validate */
-+
-+  ehdr_addr = (uintptr_t)TEXT_START_ADDR;
-+
-+  if (process_read_data(ph, ehdr_addr, (char *)&ehdr, sizeof(ehdr)) != true) {
-+    print_debug("process_read_data failed for ehdr_addr %p\n", ehdr_addr);
-+    return (0);
-+  }
-+
-+  if (!IS_ELF(ehdr) ||
-+        ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS ||
-+        ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
-+        ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
-+        ehdr.e_phentsize != sizeof(ELF_PHDR) ||
-+        ehdr.e_version != ELF_TARG_VER ||
-+        ehdr.e_machine != ELF_TARG_MACH) {
-+    print_debug("not an ELF_EHDR at %p\n", ehdr_addr);
-+    return (0);
-+  }
-+
-+  /* allocate space for all ELF_PHDR's and read */
-+
-+  phdr_addr = ehdr_addr + ehdr.e_phoff;
-+  hdrs_size = ehdr.e_phnum * sizeof(ELF_PHDR);
-+
-+  if ((phdrs = malloc(hdrs_size)) == NULL)
-+    return (0);
-+
-+  if (process_read_data(ph, phdr_addr, (char *)phdrs, hdrs_size) != true) {
-+    print_debug("process_read_data failed for phdr_addr %p\n", phdr_addr);
-+    return (0);
-+  }
-+
-+  /* find PT_DYNAMIC section */
-+
-+  for (i = 0, phdr = phdrs; i < ehdr.e_phnum; i++, phdr++) {
-+    if (phdr->p_type == PT_DYNAMIC)
-+      break;
-+  }
-+
-+  if (i >= ehdr.e_phnum) {
-+    print_debug("PT_DYNAMIC section not found!\n");
-+    free(phdrs);
-+    return (0);
-+  }
-+
-+  /* allocate space and read in ELF_DYN headers */
-+
-+  dyn_addr = phdr->p_vaddr;
-+  hdrs_size = phdr->p_memsz;
-+  free(phdrs);
-+
-+  if ((dyns = malloc(hdrs_size)) == NULL)
-+    return (0);
-+
-+  if (process_read_data(ph, dyn_addr, (char *)dyns, hdrs_size) != true) {
-+    print_debug("process_read_data failed for dyn_addr %p\n", dyn_addr);
-+    free(dyns);
-+    return (0);
-+  }
-+
-+  /* find DT_DEBUG */
-+
-+  dyn = dyns;
-+  while (dyn->d_tag != DT_DEBUG && dyn->d_tag != DT_NULL) {
-+    dyn++;
-+  }
-+
-+  if (dyn->d_tag != DT_DEBUG) {
-+    print_debug("failed to find DT_DEBUG\n");
-+    free(dyns);
-+    return (0);
-+  }
-+
-+  /* read struct r_debug into dmap */
-+
-+  dmap_addr = (uintptr_t)dyn->d_un.d_ptr;
-+  free(dyns);
-+
-+  if (process_read_data(ph, dmap_addr, (char *)&dmap, sizeof(dmap)) != true) {
-+    print_debug("process_read_data failed for dmap_addr %p\n", dmap_addr);
-+    return (0);
-+  }
-+
-+  lmap_addr = (uintptr_t)dmap.r_map;
-+
-+  return (lmap_addr);
-+}
-+#endif // __FreeBSD__ && __FreeBSD_version < 701000
-+
-+static bool read_lib_info(struct ps_prochandle* ph) {
-+#if defined(__FreeBSD__) && __FreeBSD_version >= 701000
-+  struct kinfo_vmentry *freep, *kve;
-+  int i, cnt;
-+
-+  freep = kinfo_getvmmap(ph->pid, &cnt);
-+  if (freep == NULL) {
-+      print_debug("can't get vm map for pid\n", ph->pid);
-+      return false;
-+  }
-+
-+  for (i = 0; i < cnt; i++) {
-+    kve = &freep[i];
-+    if ((kve->kve_flags & KVME_FLAG_COW) &&
-+        kve->kve_path != NULL &&
-+        strlen(kve->kve_path) > 0) {
-+
-+      if (find_lib(ph, kve->kve_path) == false) {
-+        lib_info* lib;
-+        if ((lib = add_lib_info(ph, kve->kve_path,
-+                                (uintptr_t) kve->kve_start)) == NULL)
-+          continue; // ignore, add_lib_info prints error
-+
-+        // we don't need to keep the library open, symtab is already
-+        // built. Only for core dump we need to keep the fd open.
-+        close(lib->fd);
-+        lib->fd = -1;
-+      }
-+    }
-+  }
-+
-+  free(freep);
-+
-+  return true;
-+#else
-+  char *l_name;
-+  struct link_map *lmap;
-+  uintptr_t lmap_addr;
-+
-+  if ((l_name = malloc(BUF_SIZE)) == NULL)
-+    return false;
-+
-+  if ((lmap = malloc(sizeof(*lmap))) == NULL) {
-+    free(l_name);
-+    return false;
-+  }
-+
-+  lmap_addr = linkmap_addr(ph);
-+
-+  if (lmap_addr == 0) {
-+    free(l_name);
-+    free(lmap);
-+    return false;
-+  }
-+
-+  do {
-+    if (process_read_data(ph, lmap_addr, (char *)lmap, sizeof(*lmap)) != true) {
-+      print_debug("process_read_data failed for lmap_addr %p\n", lmap_addr);
-+      free (l_name);
-+      free (lmap);
-+      return false;
-+    }
-+
-+    if (process_read_data(ph, (uintptr_t)lmap->l_name, l_name,
-+        BUF_SIZE) != true) {
-+      print_debug("process_read_data failed for lmap->l_name %p\n",
-+          lmap->l_name);
-+      free (l_name);
-+      free (lmap);
-+      return false;
-+    }
-+
-+    if (find_lib(ph, l_name) == false) {
-+      lib_info* lib;
-+      if ((lib = add_lib_info(ph, l_name,
-+                              (uintptr_t) lmap->l_addr)) == NULL)
-+        continue; // ignore, add_lib_info prints error
-+
-+      // we don't need to keep the library open, symtab is already
-+      // built. Only for core dump we need to keep the fd open.
-+      close(lib->fd);
-+      lib->fd = -1;
-+    }
-+    lmap_addr = (uintptr_t)lmap->l_next;
-+  } while (lmap->l_next != NULL);
-+
-+  free (l_name);
-+  free (lmap);
-+
-+  return true;
-+#endif
-+}
-+
-+// detach a given pid
-+static bool ptrace_detach(pid_t pid) {
-+  if (pid && ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) {
-+    print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
-+    return false;
-+  } else {
-+    return true;
-+  }
-+}
-+
-+static void process_cleanup(struct ps_prochandle* ph) {
-+  ptrace_detach(ph->pid);
-+}
-+
-+static ps_prochandle_ops process_ops = {
-+  .release=  process_cleanup,
-+  .p_pread=  process_read_data,
-+  .p_pwrite= process_write_data,
-+  .get_lwp_regs= process_get_lwp_regs,
-+  .get_lwp_info= process_get_lwp_info
-+};
-+
-+// attach to the process. One and only one exposed stuff
-+struct ps_prochandle* Pgrab(pid_t pid) {
-+  struct ps_prochandle* ph = NULL;
-+  thread_info* thr = NULL;
-+
-+  if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
-+     print_debug("can't allocate memory for ps_prochandle\n");
-+     return NULL;
-+  }
-+
-+  if (ptrace_attach(pid) != true) {
-+     free(ph);
-+     return NULL;
-+  }
-+
-+  // initialize ps_prochandle
-+  ph->pid = pid;
-+
-+  // initialize vtable
-+  ph->ops = &process_ops;
-+
-+  // read library info and symbol tables, must do this before attaching threads,
-+  // as the symbols in the pthread library will be used to figure out
-+  // the list of threads within the same process.
-+  if (read_lib_info(ph) != true) {
-+     ptrace_detach(pid);
-+     free(ph);
-+     return NULL;
-+  }
-+
-+  // read thread info
-+  read_thread_info(ph, add_new_thread);
-+
-+  return ph;
-+}
-diff --git a/agent/src/os/bsd/salibelf.c b/agent/src/os/bsd/salibelf.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/salibelf.c
-@@ -0,0 +1,126 @@
-+/*
-+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#include "salibelf.h"
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+extern void print_debug(const char*,...);
-+
-+// ELF file parsing helpers. Note that we do *not* use libelf here.
-+int read_elf_header(int fd, ELF_EHDR* ehdr) {
-+   if (pread(fd, ehdr, sizeof (ELF_EHDR), 0) != sizeof (ELF_EHDR) ||
-+            memcmp(&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
-+            ehdr->e_version != EV_CURRENT) {
-+        return 0;
-+   }
-+   return 1;
-+}
-+
-+bool is_elf_file(int fd) {
-+   ELF_EHDR ehdr;
-+   return read_elf_header(fd, &ehdr);
-+}
-+
-+// read program header table of an ELF file
-+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr) {
-+   ELF_PHDR* phbuf = 0;
-+   // allocate memory for program header table
-+   size_t nbytes = hdr->e_phnum * hdr->e_phentsize;
-+
-+   if ((phbuf = (ELF_PHDR*) malloc(nbytes)) == NULL) {
-+      print_debug("can't allocate memory for reading program header table\n");
-+      return NULL;
-+   }
-+
-+   if (pread(fd, phbuf, nbytes, hdr->e_phoff) != nbytes) {
-+      print_debug("ELF file is truncated! can't read program header table\n");
-+      free(phbuf);
-+      return NULL;
-+   }
-+
-+   return phbuf;
-+}
-+
-+// read section header table of an ELF file
-+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr) {
-+   ELF_SHDR* shbuf = 0;
-+   // allocate memory for section header table
-+   size_t nbytes = hdr->e_shnum * hdr->e_shentsize;
-+
-+   if ((shbuf = (ELF_SHDR*) malloc(nbytes)) == NULL) {
-+      print_debug("can't allocate memory for reading section header table\n");
-+      return NULL;
-+   }
-+
-+   if (pread(fd, shbuf, nbytes, hdr->e_shoff) != nbytes) {
-+      print_debug("ELF file is truncated! can't read section header table\n");
-+      free(shbuf);
-+      return NULL;
-+   }
-+
-+   return shbuf;
-+}
-+
-+// read a particular section's data
-+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr) {
-+  void *buf = NULL;
-+  if (shdr->sh_type == SHT_NOBITS || shdr->sh_size == 0) {
-+     return buf;
-+  }
-+  if ((buf = calloc(shdr->sh_size, 1)) == NULL) {
-+     print_debug("can't allocate memory for reading section data\n");
-+     return NULL;
-+  }
-+  if (pread(fd, buf, shdr->sh_size, shdr->sh_offset) != shdr->sh_size) {
-+     free(buf);
-+     print_debug("section data read failed\n");
-+     return NULL;
-+  }
-+  return buf;
-+}
-+
-+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr) {
-+  uintptr_t baseaddr = (uintptr_t)-1;
-+  int cnt;
-+  ELF_PHDR *phbuf, *phdr;
-+
-+  // read program header table
-+  if ((phbuf = read_program_header_table(fd, ehdr)) == NULL) {
-+    goto quit;
-+  }
-+
-+  // the base address of a shared object is the lowest vaddr of
-+  // its loadable segments (PT_LOAD)
-+  for (phdr = phbuf, cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
-+    if (phdr->p_type == PT_LOAD && phdr->p_vaddr < baseaddr) {
-+      baseaddr = phdr->p_vaddr;
-+    }
-+  }
-+
-+quit:
-+  if (phbuf) free(phbuf);
-+  return baseaddr;
-+}
-diff --git a/agent/src/os/bsd/salibelf.h b/agent/src/os/bsd/salibelf.h
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/salibelf.h
-@@ -0,0 +1,52 @@
-+/*
-+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#ifndef _SALIBELF_H_
-+#define _SALIBELF_H_
-+
-+#include <elf.h>
-+#include "elfmacros.h"
-+#include "libproc_impl.h"
-+
-+// read ELF file header.
-+int read_elf_header(int fd, ELF_EHDR* ehdr);
-+
-+// is given file descriptor corresponds to an ELF file?
-+bool is_elf_file(int fd);
-+
-+// read program header table of an ELF file. caller has to
-+// free the result pointer after use. NULL on failure.
-+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr);
-+
-+// read section header table of an ELF file. caller has to
-+// free the result pointer after use. NULL on failure.
-+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr);
-+
-+// read a particular section's data. caller has to free the
-+// result pointer after use. NULL on failure.
-+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr);
-+
-+// find the base address at which the library wants to load itself
-+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr);
-+#endif /* _SALIBELF_H_ */
-diff --git a/agent/src/os/bsd/symtab.c b/agent/src/os/bsd/symtab.c
-new file mode 100644
---- /dev/null
-+++ b/agent/src/os/bsd/symtab.c
-@@ -0,0 +1,241 @@
-+/*
-+ * Copyright (c) 2003, 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
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ *
-+ */
-+
-+#include <unistd.h>
-+#include <search.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include "hsearch_r.h"
-+#include "symtab.h"
-+#include "salibelf.h"
-+
-+
-+// ----------------------------------------------------
-+// functions for symbol lookups
-+// ----------------------------------------------------
-+
-+struct elf_section {
-+  ELF_SHDR   *c_shdr;
-+  void       *c_data;
-+};
-+
-+struct elf_symbol {
-+  char *name;
-+  uintptr_t offset;
-+  uintptr_t size;
-+};
-+
-+typedef struct symtab {
-+  char *strs;
-+  size_t num_symbols;
-+  struct elf_symbol *symbols;
-+  struct hsearch_data *hash_table;
-+} symtab_t;
-+
-+// read symbol table from given fd.
-+struct symtab* build_symtab(int fd) {
-+  ELF_EHDR ehdr;
-+  struct symtab* symtab = NULL;
-+
-+  // Reading of elf header
-+  struct elf_section *scn_cache = NULL;
-+  int cnt = 0;
-+  ELF_SHDR* shbuf = NULL;
-+  ELF_SHDR* cursct = NULL;
-+  ELF_PHDR* phbuf = NULL;
-+  int symtab_found = 0;
-+  int dynsym_found = 0;
-+  uint32_t symsection = SHT_SYMTAB;
-+
-+  uintptr_t baseaddr = (uintptr_t)-1;
-+
-+  lseek(fd, (off_t)0L, SEEK_SET);
-+  if (! read_elf_header(fd, &ehdr)) {
-+    // not an elf