hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 3820 0a8fbbe180db
child 4571 80b553bddc26
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
2105
347008ce7984 6814575: Update copyright year
xdono
parents: 1894
diff changeset
     2
 * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_jvmtiRedefineClasses.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
objArrayOop VM_RedefineClasses::_old_methods = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
objArrayOop VM_RedefineClasses::_new_methods = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
methodOop*  VM_RedefineClasses::_matching_old_methods = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
methodOop*  VM_RedefineClasses::_matching_new_methods = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
methodOop*  VM_RedefineClasses::_deleted_methods      = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
methodOop*  VM_RedefineClasses::_added_methods        = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
int         VM_RedefineClasses::_matching_methods_length = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
int         VM_RedefineClasses::_deleted_methods_length  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
int         VM_RedefineClasses::_added_methods_length    = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
klassOop    VM_RedefineClasses::_the_class_oop = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
VM_RedefineClasses::VM_RedefineClasses(jint class_count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
                                       const jvmtiClassDefinition *class_defs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
                                       JvmtiClassLoadKind class_load_kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  _class_count = class_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  _class_defs = class_defs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  _class_load_kind = class_load_kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  _res = JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
bool VM_RedefineClasses::doit_prologue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  if (_class_count == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    _res = JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  if (_class_defs == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    _res = JVMTI_ERROR_NULL_POINTER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  for (int i = 0; i < _class_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    if (_class_defs[i].klass == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
      _res = JVMTI_ERROR_INVALID_CLASS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    if (_class_defs[i].class_byte_count == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      _res = JVMTI_ERROR_INVALID_CLASS_FORMAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    if (_class_defs[i].class_bytes == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
      _res = JVMTI_ERROR_NULL_POINTER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  // Start timer after all the sanity checks; not quite accurate, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // better than adding a bunch of stop() calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  RC_TIMER_START(_timer_vm_op_prologue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  // We first load new class versions in the prologue, because somewhere down the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  // call chain it is required that the current thread is a Java thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  _res = load_new_class_versions(Thread::current());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  if (_res != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    // Free os::malloc allocated memory in load_new_class_version.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    os::free(_scratch_classes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    RC_TIMER_STOP(_timer_vm_op_prologue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  RC_TIMER_STOP(_timer_vm_op_prologue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
void VM_RedefineClasses::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  if (UseSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    // Sharing is enabled so we remap the shared readonly space to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    // shared readwrite, private just in case we need to redefine
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    // a shared class. We do the remap during the doit() phase of
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    // the safepoint to be safer.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      RC_TRACE_WITH_THREAD(0x00000001, thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
        ("failed to remap shared readonly space to readwrite, private"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      _res = JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  for (int i = 0; i < _class_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  // Disable any dependent concurrent compilations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  SystemDictionary::notice_modification();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  // Set flag indicating that some invariants are no longer true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  // See jvmtiExport.hpp for detailed explanation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  JvmtiExport::set_has_redefined_a_class();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  SystemDictionary::classes_do(check_class, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
void VM_RedefineClasses::doit_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // Free os::malloc allocated memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  // The memory allocated in redefine will be free'ed in next VM operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  os::free(_scratch_classes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  if (RC_TRACE_ENABLED(0x00000004)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    // Used to have separate timers for "doit" and "all", but the timer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    // overhead skewed the measurements.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
    jlong doit_time = _timer_rsc_phase1.milliseconds() +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
                      _timer_rsc_phase2.milliseconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
    RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
      "  prologue=" UINT64_FORMAT "  doit=" UINT64_FORMAT, all_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      _timer_vm_op_prologue.milliseconds(), doit_time));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    RC_TRACE(0x00000004,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
      ("redefine_single_class: phase1=" UINT64_FORMAT "  phase2=" UINT64_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
       _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // classes for primitives cannot be redefined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  if (java_lang_Class::is_primitive(klass_mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  klassOop the_class_oop = java_lang_Class::as_klassOop(klass_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  // classes for arrays cannot be redefined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  if (the_class_oop == NULL || !Klass::cast(the_class_oop)->oop_is_instance()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
// Append the current entry at scratch_i in scratch_cp to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
// where the end of *merge_cp_p is specified by *merge_cp_length_p. For
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
// direct CP entries, there is just the current entry to append. For
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
// indirect and double-indirect CP entries, there are zero or more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
// referenced CP entries along with the current entry to append.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
// Indirect and double-indirect CP entries are handled by recursive
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
// calls to append_entry() as needed. The referenced CP entries are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
// always appended to *merge_cp_p before the referee CP entry. These
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
// referenced CP entries may already exist in *merge_cp_p in which case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
// there is nothing extra to append and only the current entry is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
// appended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
       int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
       TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  // append is different depending on entry tag type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  switch (scratch_cp->tag_at(scratch_i).value()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    // The old verifier is implemented outside the VM. It loads classes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    // but does not resolve constant pool entries directly so we never
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    // see Class entries here with the old verifier. Similarly the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    // verifier does not like Class entries in the input constant pool.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    // The split-verifier is implemented in the VM so it can optionally
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    // and directly resolve constant pool entries to load classes. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    // split-verifier can accept either Class entries or UnresolvedClass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    // entries in the input constant pool. We revert the appended copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    // back to UnresolvedClass so that either verifier will be happy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    // with the constant pool entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    case JVM_CONSTANT_Class:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      // revert the copy to JVM_CONSTANT_UnresolvedClass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      (*merge_cp_p)->unresolved_klass_at_put(*merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
        scratch_cp->klass_name_at(scratch_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
      if (scratch_i != *merge_cp_length_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
        // The new entry in *merge_cp_p is at a different index than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
        // the new entry in scratch_cp so we need to map the index values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
      (*merge_cp_length_p)++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    // these are direct CP entries so they can be directly appended,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    // but double and long take two constant pool entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    case JVM_CONSTANT_Double:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    case JVM_CONSTANT_Long:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
        THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
      if (scratch_i != *merge_cp_length_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
        // The new entry in *merge_cp_p is at a different index than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
        // the new entry in scratch_cp so we need to map the index values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
      (*merge_cp_length_p) += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    // these are direct CP entries so they can be directly appended
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    case JVM_CONSTANT_Float:   // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    case JVM_CONSTANT_Integer: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    case JVM_CONSTANT_Utf8:    // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
    // This was an indirect CP entry, but it has been changed into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
    // an interned string so this entry can be directly appended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    case JVM_CONSTANT_String:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    // These were indirect CP entries, but they have been changed into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    // symbolOops so these entries can be directly appended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    case JVM_CONSTANT_UnresolvedClass:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    case JVM_CONSTANT_UnresolvedString:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
      scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
        THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      if (scratch_i != *merge_cp_length_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
        // The new entry in *merge_cp_p is at a different index than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
        // the new entry in scratch_cp so we need to map the index values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
      (*merge_cp_length_p)++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    // this is an indirect CP entry so it needs special handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
    case JVM_CONSTANT_NameAndType:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      int new_name_ref_i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      bool match = (name_ref_i < *merge_cp_length_p) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
        scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
          THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      if (!match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
        // forward reference in *merge_cp_p or not a direct match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
        int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
          THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
        if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
          guarantee(found_i != name_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
            "compare_entry_to() and find_matching_entry() do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
          // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
          // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
          new_name_ref_i = found_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
          map_index(scratch_cp, name_ref_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
          // no match found so we have to append this entry to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
          append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
            THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
          // The above call to append_entry() can only append one entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
          // so the post call query of *merge_cp_length_p is only for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
          // the sake of consistency.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
          new_name_ref_i = *merge_cp_length_p - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
      int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
      int new_signature_ref_i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
      match = (signature_ref_i < *merge_cp_length_p) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
        scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
          signature_ref_i, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
      if (!match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
        // forward reference in *merge_cp_p or not a direct match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
        int found_i = scratch_cp->find_matching_entry(signature_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
          *merge_cp_p, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
        if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
          guarantee(found_i != signature_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
            "compare_entry_to() and find_matching_entry() do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
          // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
          // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
          new_signature_ref_i = found_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
          map_index(scratch_cp, signature_ref_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
          // no match found so we have to append this entry to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
          append_entry(scratch_cp, signature_ref_i, merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
            merge_cp_length_p, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
          // The above call to append_entry() can only append one entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
          // so the post call query of *merge_cp_length_p is only for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
          // the sake of consistency.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
          new_signature_ref_i = *merge_cp_length_p - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
      // If the referenced entries already exist in *merge_cp_p, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      // both new_name_ref_i and new_signature_ref_i will both be 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      // In that case, all we are appending is the current entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      if (new_name_ref_i == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
        new_name_ref_i = name_ref_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
        RC_TRACE(0x00080000,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
          ("NameAndType entry@%d name_ref_index change: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
          *merge_cp_length_p, name_ref_i, new_name_ref_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
      if (new_signature_ref_i == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
        new_signature_ref_i = signature_ref_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
        RC_TRACE(0x00080000,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
          ("NameAndType entry@%d signature_ref_index change: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
          *merge_cp_length_p, signature_ref_i, new_signature_ref_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
      (*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
        new_name_ref_i, new_signature_ref_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
      if (scratch_i != *merge_cp_length_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
        // The new entry in *merge_cp_p is at a different index than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
        // the new entry in scratch_cp so we need to map the index values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
      (*merge_cp_length_p)++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    // this is a double-indirect CP entry so it needs special handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    case JVM_CONSTANT_Fieldref:           // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    case JVM_CONSTANT_InterfaceMethodref: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    case JVM_CONSTANT_Methodref:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
      int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
      int new_klass_ref_i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      bool match = (klass_ref_i < *merge_cp_length_p) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
        scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
          THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
      if (!match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
        // forward reference in *merge_cp_p or not a direct match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
        int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
          THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
        if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
          guarantee(found_i != klass_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
            "compare_entry_to() and find_matching_entry() do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
          // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
          // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
          new_klass_ref_i = found_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
          map_index(scratch_cp, klass_ref_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
          // no match found so we have to append this entry to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
          append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
            THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
          // The above call to append_entry() can only append one entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
          // so the post call query of *merge_cp_length_p is only for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
          // the sake of consistency. Without the optimization where we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
          // use JVM_CONSTANT_UnresolvedClass, then up to two entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
          // could be appended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
          new_klass_ref_i = *merge_cp_length_p - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
      int name_and_type_ref_i =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
        scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      int new_name_and_type_ref_i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
      match = (name_and_type_ref_i < *merge_cp_length_p) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
        scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
          name_and_type_ref_i, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
      if (!match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        // forward reference in *merge_cp_p or not a direct match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
        int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
          *merge_cp_p, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
        if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
          guarantee(found_i != name_and_type_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
            "compare_entry_to() and find_matching_entry() do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
          // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
          // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
          new_name_and_type_ref_i = found_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
          map_index(scratch_cp, name_and_type_ref_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
          // no match found so we have to append this entry to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
          append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
            merge_cp_length_p, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
          // The above call to append_entry() can append more than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
          // one entry so the post call query of *merge_cp_length_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
          // is required in order to get the right index for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
          // JVM_CONSTANT_NameAndType entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
          new_name_and_type_ref_i = *merge_cp_length_p - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
      // If the referenced entries already exist in *merge_cp_p, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
      // both new_klass_ref_i and new_name_and_type_ref_i will both be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
      // 0. In that case, all we are appending is the current entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
      if (new_klass_ref_i == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
        new_klass_ref_i = klass_ref_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
      if (new_name_and_type_ref_i == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        new_name_and_type_ref_i = name_and_type_ref_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
      const char *entry_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
      switch (scratch_cp->tag_at(scratch_i).value()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      case JVM_CONSTANT_Fieldref:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
        entry_name = "Fieldref";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
        (*merge_cp_p)->field_at_put(*merge_cp_length_p, new_klass_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
          new_name_and_type_ref_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
      case JVM_CONSTANT_InterfaceMethodref:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
        entry_name = "IFMethodref";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
        (*merge_cp_p)->interface_method_at_put(*merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
          new_klass_ref_i, new_name_and_type_ref_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
      case JVM_CONSTANT_Methodref:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
        entry_name = "Methodref";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
        (*merge_cp_p)->method_at_put(*merge_cp_length_p, new_klass_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
          new_name_and_type_ref_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
        guarantee(false, "bad switch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      if (klass_ref_i != new_klass_ref_i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
        RC_TRACE(0x00080000, ("%s entry@%d class_index changed: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
          entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
      if (name_and_type_ref_i != new_name_and_type_ref_i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        RC_TRACE(0x00080000,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
          ("%s entry@%d name_and_type_index changed: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
          entry_name, *merge_cp_length_p, name_and_type_ref_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
          new_name_and_type_ref_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
      if (scratch_i != *merge_cp_length_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
        // The new entry in *merge_cp_p is at a different index than
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
        // the new entry in scratch_cp so we need to map the index values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
        map_index(scratch_cp, scratch_i, *merge_cp_length_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      (*merge_cp_length_p)++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    // At this stage, Class or UnresolvedClass could be here, but not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    // ClassIndex
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    case JVM_CONSTANT_ClassIndex: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    // Invalid is used as the tag for the second constant pool entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    // not be seen by itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    case JVM_CONSTANT_Invalid: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    // At this stage, String or UnresolvedString could be here, but not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    // StringIndex
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    case JVM_CONSTANT_StringIndex: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    // At this stage JVM_CONSTANT_UnresolvedClassInError should not be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    // here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    case JVM_CONSTANT_UnresolvedClassInError: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
      // leave a breadcrumb
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
      jbyte bad_value = scratch_cp->tag_at(scratch_i).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  } // end switch tag value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
} // end append_entry()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  typeArrayOop save;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  save = scratch_class->get_method_annotations_of(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  scratch_class->set_method_annotations_of(i, scratch_class->get_method_annotations_of(j));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  scratch_class->set_method_annotations_of(j, save);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  save = scratch_class->get_method_parameter_annotations_of(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  scratch_class->set_method_parameter_annotations_of(i, scratch_class->get_method_parameter_annotations_of(j));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  scratch_class->set_method_parameter_annotations_of(j, save);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  save = scratch_class->get_method_default_annotations_of(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  scratch_class->set_method_default_annotations_of(i, scratch_class->get_method_default_annotations_of(j));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  scratch_class->set_method_default_annotations_of(j, save);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
             instanceKlassHandle the_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
             instanceKlassHandle scratch_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  // Check superclasses, or rather their names, since superclasses themselves can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  // requested to replace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  // Check for NULL superclass first since this might be java.lang.Object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  if (the_class->super() != scratch_class->super() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      (the_class->super() == NULL || scratch_class->super() == NULL ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
       Klass::cast(the_class->super())->name() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
       Klass::cast(scratch_class->super())->name())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  // Check if the number, names and order of directly implemented interfaces are the same.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  // I think in principle we should just check if the sets of names of directly implemented
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  // interfaces are the same, i.e. the order of declaration (which, however, if changed in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  // .java file, also changes in .class file) should not matter. However, comparing sets is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  // technically a bit more difficult, and, more importantly, I am not sure at present that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  // order of interfaces does not matter on the implementation level, i.e. that the VM does not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  // rely on it somewhere.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  objArrayOop k_interfaces = the_class->local_interfaces();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  objArrayOop k_new_interfaces = scratch_class->local_interfaces();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  int n_intfs = k_interfaces->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  if (n_intfs != k_new_interfaces->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  for (i = 0; i < n_intfs; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
    if (Klass::cast((klassOop) k_interfaces->obj_at(i))->name() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
        Klass::cast((klassOop) k_new_interfaces->obj_at(i))->name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  // Check whether class is in the error init state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  if (the_class->is_in_error_state()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    // TBD #5057930: special error code is needed in 1.6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
    return JVMTI_ERROR_INVALID_CLASS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  // Check whether class modifiers are the same.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  jushort old_flags = (jushort) the_class->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  jushort new_flags = (jushort) scratch_class->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  if (old_flags != new_flags) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  // Check if the number, names, types and order of fields declared in these classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  // are the same.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  typeArrayOop k_old_fields = the_class->fields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  typeArrayOop k_new_fields = scratch_class->fields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  int n_fields = k_old_fields->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  if (n_fields != k_new_fields->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
    // access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
    old_flags = k_old_fields->ushort_at(i + instanceKlass::access_flags_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
    new_flags = k_new_fields->ushort_at(i + instanceKlass::access_flags_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    // offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
    if (k_old_fields->short_at(i + instanceKlass::low_offset) !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
        k_new_fields->short_at(i + instanceKlass::low_offset) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
        k_old_fields->short_at(i + instanceKlass::high_offset) !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
        k_new_fields->short_at(i + instanceKlass::high_offset)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    // name and signature
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    symbolOop name_sym1 = the_class->constants()->symbol_at(name_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    symbolOop sig_sym1 = the_class->constants()->symbol_at(sig_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
    sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    symbolOop name_sym2 = scratch_class->constants()->symbol_at(name_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    symbolOop sig_sym2 = scratch_class->constants()->symbol_at(sig_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
      return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  // Do a parallel walk through the old and new methods. Detect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  // cases where they match (exist in both), have been added in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // the new methods, or have been deleted (exist only in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  // old methods).  The class file parser places methods in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  // by method name, but does not order overloaded methods by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  // signature.  In order to determine what fate befell the methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // this code places the overloaded new methods that have matching
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  // old methods in the same order as the old methods and places
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  // new overloaded methods at the end of overloaded methods of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  // that name. The code for this order normalization is adapted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  // from the algorithm used in instanceKlass::find_method().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  // Since we are swapping out of order entries as we find them,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  // we only have to search forward through the overloaded methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  // Methods which are added and have the same name as an existing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  // method (but different signature) will be put at the end of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  // the methods with that name, and the name mismatch code will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  // handle them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  objArrayHandle k_old_methods(the_class->methods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  objArrayHandle k_new_methods(scratch_class->methods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  int n_old_methods = k_old_methods->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  int n_new_methods = k_new_methods->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  int ni = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  int oi = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
    methodOop k_old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    methodOop k_new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
    enum { matched, added, deleted, undetermined } method_was = undetermined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    if (oi >= n_old_methods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      if (ni >= n_new_methods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
        break; // we've looked at everything, done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      // New method at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
      k_new_method = (methodOop) k_new_methods->obj_at(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
      method_was = added;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    } else if (ni >= n_new_methods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
      // Old method, at the end, is deleted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
      k_old_method = (methodOop) k_old_methods->obj_at(oi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      method_was = deleted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
      // There are more methods in both the old and new lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
      k_old_method = (methodOop) k_old_methods->obj_at(oi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
      k_new_method = (methodOop) k_new_methods->obj_at(ni);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
      if (k_old_method->name() != k_new_method->name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
        // Methods are sorted by method name, so a mismatch means added
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
        // or deleted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
        if (k_old_method->name()->fast_compare(k_new_method->name()) > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
          method_was = added;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
          method_was = deleted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
      } else if (k_old_method->signature() == k_new_method->signature()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
        // Both the name and signature match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
        method_was = matched;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
        // The name matches, but the signature doesn't, which means we have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
        // search forward through the new overloaded methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
        int nj;  // outside the loop for post-loop check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
        for (nj = ni + 1; nj < n_new_methods; nj++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
          methodOop m = (methodOop)k_new_methods->obj_at(nj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
          if (k_old_method->name() != m->name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
            // reached another method name so no more overloaded methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
            method_was = deleted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
          if (k_old_method->signature() == m->signature()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
            // found a match so swap the methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
            k_new_methods->obj_at_put(ni, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
            k_new_methods->obj_at_put(nj, k_new_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
            k_new_method = m;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
            method_was = matched;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
        if (nj >= n_new_methods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
          // reached the end without a match; so method was deleted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
          method_was = deleted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
    switch (method_was) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
    case matched:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
      // methods match, be sure modifiers do too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
      old_flags = (jushort) k_old_method->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
      new_flags = (jushort) k_new_method->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
      if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
        return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
        u2 new_num = k_new_method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
        u2 old_num = k_old_method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
        if (new_num != old_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
          methodOop idnum_owner = scratch_class->method_with_idnum(old_num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
          if (idnum_owner != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
            // There is already a method assigned this idnum -- switch them
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
            idnum_owner->set_method_idnum(new_num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
          k_new_method->set_method_idnum(old_num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
          swap_all_method_annotations(old_num, new_num, scratch_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
                            k_new_method->name_and_sig_as_C_string(), ni,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
                            k_old_method->name_and_sig_as_C_string(), oi));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
      // advance to next pair of methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
      ++oi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
      ++ni;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
    case added:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
      // method added, see if it is OK
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      new_flags = (jushort) k_new_method->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
      if ((new_flags & JVM_ACC_PRIVATE) == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
           // hack: private should be treated as final, but alas
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
          || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
         ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
        // new methods must be private
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
        return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
        u2 num = the_class->next_method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
        if (num == constMethodOopDesc::UNSET_IDNUM) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
          // cannot add any more methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
          return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
        u2 new_num = k_new_method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
        methodOop idnum_owner = scratch_class->method_with_idnum(num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
        if (idnum_owner != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
          // There is already a method assigned this idnum -- switch them
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
          idnum_owner->set_method_idnum(new_num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
        k_new_method->set_method_idnum(num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
        swap_all_method_annotations(new_num, num, scratch_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
      RC_TRACE(0x00008000, ("Method added: new: %s [%d]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
                            k_new_method->name_and_sig_as_C_string(), ni));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
      ++ni; // advance to next new method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
    case deleted:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
      // method deleted, see if it is OK
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
      old_flags = (jushort) k_old_method->access_flags().get_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
      if ((old_flags & JVM_ACC_PRIVATE) == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
           // hack: private should be treated as final, but alas
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
          || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
         ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
        // deleted methods must be private
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
        return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
      RC_TRACE(0x00008000, ("Method deleted: old: %s [%d]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
                            k_old_method->name_and_sig_as_C_string(), oi));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
      ++oi; // advance to next old method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
// Find new constant pool index value for old constant pool index value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
// by seaching the index map. Returns zero (0) if there is no mapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
// value for the old constant pool index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
int VM_RedefineClasses::find_new_index(int old_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  if (_index_map_count == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    // map is empty so nothing can be found
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  if (old_index < 1 || old_index >= _index_map_p->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
    // The old_index is out of range so it is not mapped. This should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
    // not happen in regular constant pool merging use, but it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    // happen if a corrupt annotation is processed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  int value = _index_map_p->at(old_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  if (value == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    // the old_index is not mapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  return value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
} // end find_new_index()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
// Returns true if the current mismatch is due to a resolved/unresolved
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
// class pair. Otherwise, returns false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
       int index1, constantPoolHandle cp2, int index2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
  jbyte t1 = cp1->tag_at(index1).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  if (t1 != JVM_CONSTANT_Class && t1 != JVM_CONSTANT_UnresolvedClass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    return false;  // wrong entry type; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  jbyte t2 = cp2->tag_at(index2).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  if (t2 != JVM_CONSTANT_Class && t2 != JVM_CONSTANT_UnresolvedClass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    return false;  // wrong entry type; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  if (t1 == t2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    return false;  // not a mismatch; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  char *s1 = cp1->klass_name_at(index1)->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  char *s2 = cp2->klass_name_at(index2)->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
  if (strcmp(s1, s2) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    return false;  // strings don't match; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  return true;  // made it through the gauntlet; this is our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
} // end is_unresolved_class_mismatch()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
// Returns true if the current mismatch is due to a resolved/unresolved
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
// string pair. Otherwise, returns false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
bool VM_RedefineClasses::is_unresolved_string_mismatch(constantPoolHandle cp1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
       int index1, constantPoolHandle cp2, int index2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  jbyte t1 = cp1->tag_at(index1).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  if (t1 != JVM_CONSTANT_String && t1 != JVM_CONSTANT_UnresolvedString) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
    return false;  // wrong entry type; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  jbyte t2 = cp2->tag_at(index2).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  if (t2 != JVM_CONSTANT_String && t2 != JVM_CONSTANT_UnresolvedString) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
    return false;  // wrong entry type; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  if (t1 == t2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
    return false;  // not a mismatch; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  char *s1 = cp1->string_at_noresolve(index1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
  char *s2 = cp2->string_at_noresolve(index2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  if (strcmp(s1, s2) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
    return false;  // strings don't match; not our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  return true;  // made it through the gauntlet; this is our special case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
} // end is_unresolved_string_mismatch()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  // For consistency allocate memory using os::malloc wrapper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  _scratch_classes = (instanceKlassHandle *)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    os::malloc(sizeof(instanceKlassHandle) * _class_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  if (_scratch_classes == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current());
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1
diff changeset
   834
  // state can only be NULL if the current thread is exiting which
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1
diff changeset
   835
  // should not happen since we're trying to do a RedefineClasses
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1
diff changeset
   836
  guarantee(state != NULL, "exiting thread calling load_new_class_versions");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  for (int i = 0; i < _class_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
    oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
    // classes for primitives cannot be redefined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    if (!is_modifiable_class(mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
      return JVMTI_ERROR_UNMODIFIABLE_CLASS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    klassOop the_class_oop = java_lang_Class::as_klassOop(mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
    instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
    symbolHandle the_class_sym = symbolHandle(THREAD, the_class->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
    // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    RC_TRACE_WITH_THREAD(0x00000001, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
      ("loading name=%s (avail_mem=" UINT64_FORMAT "K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
      the_class->external_name(), os::available_memory() >> 10));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    ClassFileStream st((u1*) _class_defs[i].class_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
      _class_defs[i].class_byte_count, (char *)"__VM_RedefineClasses__");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
    // Parse the stream.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
    Handle the_class_loader(THREAD, the_class->class_loader());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    Handle protection_domain(THREAD, the_class->protection_domain());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    // Set redefined class handle in JvmtiThreadState class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
    // This redefined class is sent to agent event handler for class file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
    // load hook event.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
    state->set_class_being_redefined(&the_class, _class_load_kind);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    klassOop k = SystemDictionary::parse_stream(the_class_sym,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
                                                the_class_loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
                                                protection_domain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
                                                &st,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
                                                THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    // Clear class_being_redefined just to be sure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
    state->clear_class_being_redefined();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
    // TODO: if this is retransform, and nothing changed we can skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
    instanceKlassHandle scratch_class (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
    if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
      symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
      // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
      RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
        ex_name->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
      CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
      if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
        return JVMTI_ERROR_UNSUPPORTED_VERSION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
      } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
        return JVMTI_ERROR_INVALID_CLASS_FORMAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
      } else if (ex_name == vmSymbols::java_lang_ClassCircularityError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
        return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      } else if (ex_name == vmSymbols::java_lang_NoClassDefFoundError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
        // The message will be "XXX (wrong name: YYY)"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
        return JVMTI_ERROR_NAMES_DONT_MATCH;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
      } else if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
        return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      } else {  // Just in case more exceptions can be thrown..
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
        return JVMTI_ERROR_FAILS_VERIFICATION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    // Ensure class is linked before redefine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
    if (!the_class->is_linked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
      the_class->link_class(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
      if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
        symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
        // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
        RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
          ex_name->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
        CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
        if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
          return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
          return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    // Do the validity checks in compare_and_normalize_class_versions()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
    // before verifying the byte codes. By doing these checks first, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
    // limit the number of functions that require redirection from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    // the_class to scratch_class. In particular, we don't have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    // modify JNI GetSuperclass() and thus won't change its performance.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    jvmtiError res = compare_and_normalize_class_versions(the_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
                       scratch_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    if (res != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
      return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    // verify what the caller passed us
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
      // The bug 6214132 caused the verification to fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
      // Information about the_class and scratch_class is temporarily
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
      // recorded into jvmtiThreadState. This data is used to redirect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
      // the_class to scratch_class in the JVM_* functions called by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
      // verifier. Please, refer to jvmtiThreadState.hpp for the detailed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
      // description.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
      RedefineVerifyMark rvm(&the_class, &scratch_class, state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
      Verifier::verify(
3820
0a8fbbe180db 6830542: Performance: JVM_DefineClass already verified.
acorn
parents: 2154
diff changeset
   936
        scratch_class, Verifier::ThrowException, true, THREAD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
    if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
      symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
      // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
      RC_TRACE_WITH_THREAD(0x00000002, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
        ("verify_byte_codes exception: '%s'", ex_name->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
        return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
        // tell the caller the bytecodes are bad
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
        return JVMTI_ERROR_FAILS_VERIFICATION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
    res = merge_cp_and_rewrite(the_class, scratch_class, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
    if (res != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
      return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    if (VerifyMergedCPBytecodes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
      // verify what we have done during constant pool merging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
        RedefineVerifyMark rvm(&the_class, &scratch_class, state);
3820
0a8fbbe180db 6830542: Performance: JVM_DefineClass already verified.
acorn
parents: 2154
diff changeset
   962
        Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
      if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
        symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
        // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
        RC_TRACE_WITH_THREAD(0x00000002, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
          ("verify_byte_codes post merge-CP exception: '%s'",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
          ex_name->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
        CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
        if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
          return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
          // tell the caller that constant pool merging screwed up
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
          return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
    Rewriter::rewrite(scratch_class, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
    if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
      symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
      CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
      if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
        return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
        return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
    _scratch_classes[i] = scratch_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    RC_TRACE_WITH_THREAD(0x00000001, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
      ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
      the_class->external_name(), os::available_memory() >> 10));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
// Map old_index to new_index as needed. scratch_cp is only needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
// for RC_TRACE() calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
void VM_RedefineClasses::map_index(constantPoolHandle scratch_cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
       int old_index, int new_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
  if (find_new_index(old_index) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
    // old_index is already mapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  if (old_index == new_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    // no mapping is needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  _index_map_p->at_put(old_index, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  _index_map_count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    scratch_cp->tag_at(old_index).value(), old_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
} // end map_index()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
// Merge old_cp and scratch_cp and return the results of the merge via
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
// merge_cp_p. The number of entries in *merge_cp_p is returned via
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
// merge_cp_length_p. The entries in old_cp occupy the same locations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
// in *merge_cp_p. Also creates a map of indices from entries in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
// scratch_cp to the corresponding entry in *merge_cp_p. Index map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
// entries are only created for entries in scratch_cp that occupy a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
// different location in *merged_cp_p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
       constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
       int *merge_cp_length_p, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  if (merge_cp_p == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    assert(false, "caller must provide scatch constantPool");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
    return false; // robustness
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  if (merge_cp_length_p == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
    assert(false, "caller must provide scatch CP length");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
    return false; // robustness
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
  // Worst case we need old_cp->length() + scratch_cp()->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
  // but the caller might be smart so make sure we have at least
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  // the minimum.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  if ((*merge_cp_p)->length() < old_cp->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    assert(false, "merge area too small");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
    return false; // robustness
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  RC_TRACE_WITH_THREAD(0x00010000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
    ("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    scratch_cp->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // Pass 0:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    // The old_cp is copied to *merge_cp_p; this means that any code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    // using old_cp does not have to change. This work looks like a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    // perfect fit for constantPoolOop::copy_cp_to(), but we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    // handle one special case:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    // - revert JVM_CONSTANT_Class to JVM_CONSTANT_UnresolvedClass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    // This will make verification happy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
    int old_i;  // index into old_cp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
    // index zero (0) is not used in constantPools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
    for (old_i = 1; old_i < old_cp->length(); old_i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
      // leave debugging crumb
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
      jbyte old_tag = old_cp->tag_at(old_i).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
      switch (old_tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
      case JVM_CONSTANT_Class:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
        // revert the copy to JVM_CONSTANT_UnresolvedClass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
        (*merge_cp_p)->unresolved_klass_at_put(old_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
          old_cp->klass_name_at(old_i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
      case JVM_CONSTANT_Double:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
      case JVM_CONSTANT_Long:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
        // just copy the entry to *merge_cp_p, but double and long take
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
        // two constant pool entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
        old_i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
        // just copy the entry to *merge_cp_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
        old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
    } // end for each old_cp entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
    // We don't need to sanity check that *merge_cp_length_p is within
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
    // *merge_cp_p bounds since we have the minimum on-entry check above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
    (*merge_cp_length_p) = old_i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  // merge_cp_len should be the same as old_cp->length() at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  // so this trace message is really a "warm-and-breathing" message.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  RC_TRACE_WITH_THREAD(0x00020000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
    ("after pass 0: merge_cp_len=%d", *merge_cp_length_p));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  int scratch_i;  // index into scratch_cp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    // Pass 1a:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
    // Compare scratch_cp entries to the old_cp entries that we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    // already copied to *merge_cp_p. In this pass, we are eliminating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    // exact duplicates (matching entry at same index) so we only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    // compare entries in the common indice range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
    int increment = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
    int pass1a_length = MIN2(old_cp->length(), scratch_cp->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
    for (scratch_i = 1; scratch_i < pass1a_length; scratch_i += increment) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
      switch (scratch_cp->tag_at(scratch_i).value()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
      case JVM_CONSTANT_Double:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      case JVM_CONSTANT_Long:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
        // double and long take two constant pool entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
        increment = 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
        increment = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
      bool match = scratch_cp->compare_entry_to(scratch_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
        scratch_i, CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
      if (match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
        // found a match at the same index so nothing more to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
      } else if (is_unresolved_class_mismatch(scratch_cp, scratch_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
                                              *merge_cp_p, scratch_i)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
        // The mismatch in compare_entry_to() above is because of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
        // resolved versus unresolved class entry at the same index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
        // with the same string value. Since Pass 0 reverted any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
        // class entries to unresolved class entries in *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
        // we go with the unresolved class entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
      } else if (is_unresolved_string_mismatch(scratch_cp, scratch_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
                                               *merge_cp_p, scratch_i)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
        // The mismatch in compare_entry_to() above is because of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
        // resolved versus unresolved string entry at the same index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
        // with the same string value. We can live with whichever
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
        // happens to be at scratch_i in *merge_cp_p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
      int found_i = scratch_cp->find_matching_entry(scratch_i, *merge_cp_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
        CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
      if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
        guarantee(found_i != scratch_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
          "compare_entry_to() and find_matching_entry() do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
        // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
        // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
        map_index(scratch_cp, scratch_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
      // The find_matching_entry() call above could fail to find a match
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
      // due to a resolved versus unresolved class or string entry situation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
      // like we solved above with the is_unresolved_*_mismatch() calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
      // However, we would have to call is_unresolved_*_mismatch() over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
      // all of *merge_cp_p (potentially) and that doesn't seem to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
      // worth the time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
      // No match found so we have to append this entry and any unique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
      // referenced entries to *merge_cp_p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
      append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
        CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  RC_TRACE_WITH_THREAD(0x00020000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
    ("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
    *merge_cp_length_p, scratch_i, _index_map_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  if (scratch_i < scratch_cp->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    // Pass 1b:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
    // old_cp is smaller than scratch_cp so there are entries in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
    // scratch_cp that we have not yet processed. We take care of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
    // those now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    int increment = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    for (; scratch_i < scratch_cp->length(); scratch_i += increment) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
      switch (scratch_cp->tag_at(scratch_i).value()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
      case JVM_CONSTANT_Double:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
      case JVM_CONSTANT_Long:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
        // double and long take two constant pool entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
        increment = 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
        increment = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
      int found_i =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
        scratch_cp->find_matching_entry(scratch_i, *merge_cp_p, CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
      if (found_i != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
        // Found a matching entry somewhere else in *merge_cp_p so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
        // just need a mapping entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
        map_index(scratch_cp, scratch_i, found_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
      // No match found so we have to append this entry and any unique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
      // referenced entries to *merge_cp_p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
      append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
        CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    RC_TRACE_WITH_THREAD(0x00020000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
      ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
      *merge_cp_length_p, scratch_i, _index_map_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
} // end merge_constant_pools()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
// Merge constant pools between the_class and scratch_class and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
// potentially rewrite bytecodes in scratch_class to use the merged
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
// constant pool.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
             instanceKlassHandle the_class, instanceKlassHandle scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
             TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
  // worst case merged constant pool length is old and new combined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
  int merge_cp_length = the_class->constants()->length()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
        + scratch_class->constants()->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  constantPoolHandle old_cp(THREAD, the_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  constantPoolHandle scratch_cp(THREAD, scratch_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
  // Constant pools are not easily reused so we allocate a new one
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
  // each time.
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1236
  // merge_cp is created unsafe for concurrent GC processing.  It
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1237
  // should be marked safe before discarding it because, even if
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1238
  // garbage.  If it crosses a card boundary, it may be scanned
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1239
  // in order to find the start of the first complete object on the card.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  constantPoolHandle merge_cp(THREAD,
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1241
    oopFactory::new_constantPool(merge_cp_length,
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1242
                                 methodOopDesc::IsUnsafeConc,
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1243
                                 THREAD));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
  int orig_length = old_cp->orig_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
  if (orig_length == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
    // This old_cp is an actual original constant pool. We save
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
    // the original length in the merged constant pool so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    // merge_constant_pools() can be more efficient. If a constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
    // pool has a non-zero orig_length() value, then that constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
    // pool was created by a merge operation in RedefineClasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
    merge_cp->set_orig_length(old_cp->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
    // This old_cp is a merged constant pool from a previous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
    // RedefineClasses() calls so just copy the orig_length()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
    // value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
    merge_cp->set_orig_length(old_cp->orig_length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  _index_map_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  _index_map_p = new intArray(scratch_cp->length(), -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
  bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
                  &merge_cp_length, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
  if (!result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
    // The merge can fail due to memory allocation failure or due
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
    // to robustness checks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
    return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  RC_TRACE_WITH_THREAD(0x00010000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
    ("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
  if (_index_map_count == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
    // there is nothing to map between the new and merged constant pools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
    if (old_cp->length() == scratch_cp->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
      // The old and new constant pools are the same length and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
      // index map is empty. This means that the three constant pools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
      // are equivalent (but not the same). Unfortunately, the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
      // constant pool has not gone through link resolution nor have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
      // the new class bytecodes gone through constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
      // rewriting so we can't use the old constant pool with the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
      // class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1286
      merge_cp()->set_is_conc_safe(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
      merge_cp = constantPoolHandle();  // toss the merged constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
    } else if (old_cp->length() < scratch_cp->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
      // The old constant pool has fewer entries than the new constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
      // pool and the index map is empty. This means the new constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
      // pool is a superset of the old constant pool. However, the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
      // class bytecodes have already gone through constant pool cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
      // rewriting so we can't use the new constant pool with the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
      // class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1296
      merge_cp()->set_is_conc_safe(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
      merge_cp = constantPoolHandle();  // toss the merged constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
      // The old constant pool has more entries than the new constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
      // pool and the index map is empty. This means that both the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
      // and merged constant pools are supersets of the new constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
      // pool.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
      // Replace the new constant pool with a shrunken copy of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
      // merged constant pool; the previous new constant pool will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
      // get GCed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
      set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
        THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
      // drop local ref to the merged constant pool
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1310
      merge_cp()->set_is_conc_safe(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
      merge_cp = constantPoolHandle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
    if (RC_TRACE_ENABLED(0x00040000)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
      // don't want to loop unless we are tracing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
      int count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
      for (int i = 1; i < _index_map_p->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
        int value = _index_map_p->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
        if (value != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
          RC_TRACE_WITH_THREAD(0x00040000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
            ("index_map[%d]: old=%d new=%d", count, i, value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
          count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
    // We have entries mapped between the new and merged constant pools
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
    // so we have to rewrite some constant pool references.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
    if (!rewrite_cp_refs(scratch_class, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
      return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
    // Replace the new constant pool with a shrunken copy of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
    // merged constant pool so now the rewritten bytecodes have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
    // valid references; the previous new constant pool will get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
    // GCed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
    set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
      THREAD);
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1340
    merge_cp()->set_is_conc_safe(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
  }
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1342
  assert(old_cp()->is_conc_safe(), "Just checking");
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  1343
  assert(scratch_cp()->is_conc_safe(), "Just checking");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
} // end merge_cp_and_rewrite()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
// Rewrite constant pool references in klass scratch_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
       TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
  // rewrite constant pool references in the methods:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1355
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  // rewrite constant pool references in the class_annotations:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
  if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1361
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  // rewrite constant pool references in the fields_annotations:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1367
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  // rewrite constant pool references in the methods_annotations:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1373
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  // rewrite constant pool references in the methods_parameter_annotations:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  if (!rewrite_cp_refs_in_methods_parameter_annotations(scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
         THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1380
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  // rewrite constant pool references in the methods_default_annotations:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  if (!rewrite_cp_refs_in_methods_default_annotations(scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
         THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1387
    // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
} // end rewrite_cp_refs()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
// Rewrite constant pool references in the methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
bool VM_RedefineClasses::rewrite_cp_refs_in_methods(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  objArrayHandle methods(THREAD, scratch_class->methods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  if (methods.is_null() || methods->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
    // no methods so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  // rewrite constant pool references in the methods:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  for (int i = methods->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
    methodHandle method(THREAD, (methodOop)methods->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
    methodHandle new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
    rewrite_cp_refs_in_method(method, &new_method, CHECK_false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
    if (!new_method.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
      // the method has been replaced so save the new method version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
      methods->obj_at_put(i, new_method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
// Rewrite constant pool references in the specific method. This code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
// was adapted from Rewriter::rewrite_method().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
       methodHandle *new_method_p, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
  *new_method_p = methodHandle();  // default is no new method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  // We cache a pointer to the bytecodes here in code_base. If GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  // moves the methodOop, then the bytecodes will also move which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  // will likely cause a crash. We create a No_Safepoint_Verifier
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
  // object to detect whether we pass a possible safepoint in this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  // code block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  No_Safepoint_Verifier nsv;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
  // Bytecodes and their length
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  address code_base = method->code_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  int code_length = method->code_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  int bc_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  for (int bci = 0; bci < code_length; bci += bc_length) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
    address bcp = code_base + bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
    Bytecodes::Code c = (Bytecodes::Code)(*bcp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
    bc_length = Bytecodes::length_for(c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
    if (bc_length == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
      // More complicated bytecodes report a length of zero so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
      // we have to try again a slightly different way.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
      bc_length = Bytecodes::length_at(bcp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
    assert(bc_length != 0, "impossible bytecode length");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
    switch (c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
      case Bytecodes::_ldc:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
        int cp_index = *(bcp + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
        int new_index = find_new_index(cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
        if (StressLdcRewrite && new_index == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
          // If we are stressing ldc -> ldc_w rewriting, then we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
          // always need a new_index value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
          new_index = cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
          // the original index is mapped so we have more work to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
          if (!StressLdcRewrite && new_index <= max_jubyte) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
            // The new value can still use ldc instead of ldc_w
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
            // unless we are trying to stress ldc -> ldc_w rewriting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
            RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
              ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
              bcp, cp_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
            *(bcp + 1) = new_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
            RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
              ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
              Bytecodes::name(c), bcp, cp_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
            // the new value needs ldc_w instead of ldc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
            u_char inst_buffer[4]; // max instruction size is 4 bytes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
            bcp = (address)inst_buffer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
            // construct new instruction sequence
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
            *bcp = Bytecodes::_ldc_w;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
            bcp++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
            // Rewriter::rewrite_method() does not rewrite ldc -> ldc_w.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
            // See comment below for difference between put_Java_u2()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
            // and put_native_u2().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
            Bytes::put_Java_u2(bcp, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
            Relocator rc(method, NULL /* no RelocatorListener needed */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
            methodHandle m;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
            {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
              Pause_No_Safepoint_Verifier pnsv(&nsv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
              // ldc is 2 bytes and ldc_w is 3 bytes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
              m = rc.insert_space_at(bci, 3, inst_buffer, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
              if (m.is_null() || HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
                guarantee(false, "insert_space_at() failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
            // return the new method so that the caller can update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
            // the containing class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
            *new_method_p = method = m;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
            // switch our bytecode processing loop from the old method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
            // to the new method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
            code_base = method->code_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
            code_length = method->code_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
            bcp = code_base + bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
            c = (Bytecodes::Code)(*bcp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
            bc_length = Bytecodes::length_for(c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
            assert(bc_length != 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
          } // end we need ldc_w instead of ldc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
        } // end if there is a mapped index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
      } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
      // these bytecodes have a two-byte constant pool index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
      case Bytecodes::_anewarray      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
      case Bytecodes::_checkcast      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
      case Bytecodes::_getfield       : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
      case Bytecodes::_getstatic      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
      case Bytecodes::_instanceof     : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
      case Bytecodes::_invokeinterface: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
      case Bytecodes::_invokespecial  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
      case Bytecodes::_invokestatic   : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
      case Bytecodes::_invokevirtual  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
      case Bytecodes::_ldc_w          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
      case Bytecodes::_ldc2_w         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
      case Bytecodes::_multianewarray : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
      case Bytecodes::_new            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
      case Bytecodes::_putfield       : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
      case Bytecodes::_putstatic      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
        address p = bcp + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
        int cp_index = Bytes::get_Java_u2(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
        int new_index = find_new_index(cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
          // the original index is mapped so update w/ new value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
          RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
            ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
            bcp, cp_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
          // Rewriter::rewrite_method() uses put_native_u2() in this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
          // situation because it is reusing the constant pool index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
          // location for a native index into the constantPoolCache.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
          // Since we are updating the constant pool index prior to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
          // verification and constantPoolCache initialization, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
          // need to keep the new index in Java byte order.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
          Bytes::put_Java_u2(p, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
      } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
  } // end for each bytecode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
} // end rewrite_cp_refs_in_method()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
// Rewrite constant pool references in the class_annotations field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
bool VM_RedefineClasses::rewrite_cp_refs_in_class_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
  typeArrayHandle class_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    scratch_class->class_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
  if (class_annotations.is_null() || class_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    // no class_annotations so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
    ("class_annotations length=%d", class_annotations->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
  int byte_i = 0;  // byte index into class_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  return rewrite_cp_refs_in_annotations_typeArray(class_annotations, byte_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
           THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
// Rewrite constant pool references in an annotations typeArray. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
// "structure" is adapted from the RuntimeVisibleAnnotations_attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
// that is described in section 4.8.15 of the 2nd-edition of the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
// annotations_typeArray {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
//   u2 num_annotations;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
//   annotation annotations[num_annotations];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
bool VM_RedefineClasses::rewrite_cp_refs_in_annotations_typeArray(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
       typeArrayHandle annotations_typeArray, int &byte_i_ref, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
  if ((byte_i_ref + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
    // not enough room for num_annotations field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
    RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
      ("length() is too small for num_annotations field"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
  u2 num_annotations = Bytes::get_Java_u2((address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
                         annotations_typeArray->byte_at_addr(byte_i_ref));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
  byte_i_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
    ("num_annotations=%d", num_annotations));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  int calc_num_annotations = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  for (; calc_num_annotations < num_annotations; calc_num_annotations++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
    if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
           byte_i_ref, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
        ("bad annotation_struct at %d", calc_num_annotations));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1606
      // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  assert(num_annotations == calc_num_annotations, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
} // end rewrite_cp_refs_in_annotations_typeArray()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
// Rewrite constant pool references in the annotation struct portion of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
// an annotations_typeArray. This "structure" is from section 4.8.15 of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
// the 2nd-edition of the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
// struct annotation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
//   u2 type_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
//   u2 num_element_value_pairs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
//   {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
//     u2 element_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
//     element_value value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
//   } element_value_pairs[num_element_value_pairs];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
       typeArrayHandle annotations_typeArray, int &byte_i_ref, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
  if ((byte_i_ref + 2 + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
    // not enough room for smallest annotation_struct
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
    RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
      ("length() is too small for annotation_struct"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
  u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
                    byte_i_ref, "mapped old type_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
  u2 num_element_value_pairs = Bytes::get_Java_u2((address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
                                 annotations_typeArray->byte_at_addr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
                                 byte_i_ref));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
  byte_i_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
    ("type_index=%d  num_element_value_pairs=%d", type_index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
    num_element_value_pairs));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
  int calc_num_element_value_pairs = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
  for (; calc_num_element_value_pairs < num_element_value_pairs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
       calc_num_element_value_pairs++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
    if ((byte_i_ref + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
      // not enough room for another element_name_index, let alone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
      // the rest of another component
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
        ("length() is too small for element_name_index"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
    u2 element_name_index = rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
                              annotations_typeArray, byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
                              "mapped old element_name_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
    RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
      ("element_name_index=%d", element_name_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
    if (!rewrite_cp_refs_in_element_value(annotations_typeArray,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
           byte_i_ref, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
        ("bad element_value at %d", calc_num_element_value_pairs));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1672
      // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
  } // end for each component
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  assert(num_element_value_pairs == calc_num_element_value_pairs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
    "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
} // end rewrite_cp_refs_in_annotation_struct()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
// Rewrite a constant pool reference at the current position in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
// annotations_typeArray if needed. Returns the original constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
// pool reference if a rewrite was not needed or the new constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
// pool reference if a rewrite was needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
     typeArrayHandle annotations_typeArray, int &byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
     const char * trace_mesg, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  address cp_index_addr = (address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    annotations_typeArray->byte_at_addr(byte_i_ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
  u2 new_cp_index = find_new_index(old_cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  if (new_cp_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
    RC_TRACE_WITH_THREAD(0x02000000, THREAD, (trace_mesg, old_cp_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
    Bytes::put_Java_u2(cp_index_addr, new_cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
    old_cp_index = new_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  byte_i_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  return old_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
// Rewrite constant pool references in the element_value portion of an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
// annotations_typeArray. This "structure" is from section 4.8.15.1 of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
// the 2nd-edition of the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
// struct element_value {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
//   u1 tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
//   union {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
//     u2 const_value_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
//     {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
//       u2 type_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
//       u2 const_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
//     } enum_const_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
//     u2 class_info_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
//     annotation annotation_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
//     struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
//       u2 num_values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
//       element_value values[num_values];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
//     } array_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
//   } value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
bool VM_RedefineClasses::rewrite_cp_refs_in_element_value(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
       typeArrayHandle annotations_typeArray, int &byte_i_ref, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  if ((byte_i_ref + 1) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
    // not enough room for a tag let alone the rest of an element_value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
    RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
      ("length() is too small for a tag"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
  u1 tag = annotations_typeArray->byte_at(byte_i_ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
  byte_i_ref++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
  RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("tag='%c'", tag));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
  switch (tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
    // These BaseType tag values are from Table 4.2 in VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
    case 'B':  // byte
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
    case 'C':  // char
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
    case 'D':  // double
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
    case 'F':  // float
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
    case 'I':  // int
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
    case 'J':  // long
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
    case 'S':  // short
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
    case 'Z':  // boolean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
    // The remaining tag values are from Table 4.8 in the 2nd-edition of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
    // the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
    case 's':
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      // For the above tag values (including the BaseType values),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
      // value.const_value_index is right union field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
      if ((byte_i_ref + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
        // not enough room for a const_value_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
        RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
          ("length() is too small for a const_value_index"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      u2 const_value_index = rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
                               annotations_typeArray, byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
                               "mapped old const_value_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
        ("const_value_index=%d", const_value_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
    case 'e':
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
      // for the above tag value, value.enum_const_value is right union field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
      if ((byte_i_ref + 4) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
        // not enough room for a enum_const_value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
        RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
          ("length() is too small for a enum_const_value"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
      u2 type_name_index = rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
                             annotations_typeArray, byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
                             "mapped old type_name_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
      u2 const_name_index = rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
                              annotations_typeArray, byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
                              "mapped old const_name_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
        ("type_name_index=%d  const_name_index=%d", type_name_index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
        const_name_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
    case 'c':
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
      // for the above tag value, value.class_info_index is right union field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
      if ((byte_i_ref + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
        // not enough room for a class_info_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
        RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
          ("length() is too small for a class_info_index"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
      u2 class_info_index = rewrite_cp_ref_in_annotation_data(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
                              annotations_typeArray, byte_i_ref,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
                              "mapped old class_info_index=%d", THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
        ("class_info_index=%d", class_info_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
    case '@':
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
      // For the above tag value, value.attr_value is the right union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
      // field. This is a nested annotation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
      if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
             byte_i_ref, THREAD)) {
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1821
        // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
    case '[':
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
      if ((byte_i_ref + 2) > annotations_typeArray->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
        // not enough room for a num_values field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
        RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
          ("length() is too small for a num_values field"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
      // For the above tag value, value.array_value is the right union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
      // field. This is an array of nested element_value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
      u2 num_values = Bytes::get_Java_u2((address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
                        annotations_typeArray->byte_at_addr(byte_i_ref));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
      byte_i_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
      RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("num_values=%d", num_values));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
      int calc_num_values = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
      for (; calc_num_values < num_values; calc_num_values++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
        if (!rewrite_cp_refs_in_element_value(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
               annotations_typeArray, byte_i_ref, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
          RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
            ("bad nested element_value at %d", calc_num_values));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1848
          // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
      assert(num_values == calc_num_values, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
    } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
      RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad tag=0x%x", tag));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
  } // end decode tag field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
} // end rewrite_cp_refs_in_element_value()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
// Rewrite constant pool references in a fields_annotations field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
  objArrayHandle fields_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    scratch_class->fields_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
  if (fields_annotations.is_null() || fields_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
    // no fields_annotations so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
    ("fields_annotations length=%d", fields_annotations->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  for (int i = 0; i < fields_annotations->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
    typeArrayHandle field_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
      (typeArrayOop)fields_annotations->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
    if (field_annotations.is_null() || field_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
      // this field does not have any annotations so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
    int byte_i = 0;  // byte index into field_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
    if (!rewrite_cp_refs_in_annotations_typeArray(field_annotations, byte_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
           THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
        ("bad field_annotations at %d", i));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1892
      // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
} // end rewrite_cp_refs_in_fields_annotations()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
// Rewrite constant pool references in a methods_annotations field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  objArrayHandle methods_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
    scratch_class->methods_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  if (methods_annotations.is_null() || methods_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
    // no methods_annotations so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
    ("methods_annotations length=%d", methods_annotations->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  for (int i = 0; i < methods_annotations->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
    typeArrayHandle method_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
      (typeArrayOop)methods_annotations->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
    if (method_annotations.is_null() || method_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
      // this method does not have any annotations so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
    int byte_i = 0;  // byte index into method_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
    if (!rewrite_cp_refs_in_annotations_typeArray(method_annotations, byte_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
           THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
        ("bad method_annotations at %d", i));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1929
      // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
} // end rewrite_cp_refs_in_methods_annotations()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
// Rewrite constant pool references in a methods_parameter_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
// field. This "structure" is adapted from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
// RuntimeVisibleParameterAnnotations_attribute described in section
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
// 4.8.17 of the 2nd-edition of the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
// methods_parameter_annotations_typeArray {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
//   u1 num_parameters;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
//   {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
//     u2 num_annotations;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
//     annotation annotations[num_annotations];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
//   } parameter_annotations[num_parameters];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  objArrayHandle methods_parameter_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    scratch_class->methods_parameter_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
  if (methods_parameter_annotations.is_null()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
      || methods_parameter_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
    // no methods_parameter_annotations so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
    ("methods_parameter_annotations length=%d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
    methods_parameter_annotations->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  for (int i = 0; i < methods_parameter_annotations->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
    typeArrayHandle method_parameter_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
      (typeArrayOop)methods_parameter_annotations->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
    if (method_parameter_annotations.is_null()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
        || method_parameter_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
      // this method does not have any parameter annotations so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    if (method_parameter_annotations->length() < 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
      // not enough room for a num_parameters field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
        ("length() is too small for a num_parameters field at %d", i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
    int byte_i = 0;  // byte index into method_parameter_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
    u1 num_parameters = method_parameter_annotations->byte_at(byte_i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
    byte_i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
    RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
      ("num_parameters=%d", num_parameters));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
    int calc_num_parameters = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
    for (; calc_num_parameters < num_parameters; calc_num_parameters++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
      if (!rewrite_cp_refs_in_annotations_typeArray(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
             method_parameter_annotations, byte_i, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
        RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
          ("bad method_parameter_annotations at %d", calc_num_parameters));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  1997
        // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
    assert(num_parameters == calc_num_parameters, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
} // end rewrite_cp_refs_in_methods_parameter_annotations()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
// Rewrite constant pool references in a methods_default_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
// field. This "structure" is adapted from the AnnotationDefault_attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
// that is described in section 4.8.19 of the 2nd-edition of the VM spec:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
// methods_default_annotations_typeArray {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
//   element_value default_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  objArrayHandle methods_default_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
    scratch_class->methods_default_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  if (methods_default_annotations.is_null()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
      || methods_default_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
    // no methods_default_annotations so nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
  RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    ("methods_default_annotations length=%d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
    methods_default_annotations->length()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
  for (int i = 0; i < methods_default_annotations->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
    typeArrayHandle method_default_annotations(THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
      (typeArrayOop)methods_default_annotations->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
    if (method_default_annotations.is_null()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
        || method_default_annotations->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
      // this method does not have any default annotations so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    int byte_i = 0;  // byte index into method_default_annotations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
    if (!rewrite_cp_refs_in_element_value(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
           method_default_annotations, byte_i, THREAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
      RC_TRACE_WITH_THREAD(0x02000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
        ("bad default element_value at %d", i));
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1894
diff changeset
  2047
      // propagate failure back to caller
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
} // end rewrite_cp_refs_in_methods_default_annotations()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
// Rewrite constant pool references in the method's stackmap table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
// These "structures" are adapted from the StackMapTable_attribute that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
// is described in section 4.8.4 of the 6.0 version of the VM spec
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
// (dated 2005.10.26):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
// file:///net/quincunx.sfbay/export/gbracha/ClassFile-Java6.pdf
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
// stack_map {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
//   u2 number_of_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
//   stack_map_frame entries[number_of_entries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
void VM_RedefineClasses::rewrite_cp_refs_in_stack_map_table(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
       methodHandle method, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  if (!method->has_stackmap_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  typeArrayOop stackmap_data = method->stackmap_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
  address stackmap_p = (address)stackmap_data->byte_at_addr(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
  address stackmap_end = stackmap_p + stackmap_data->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  assert(stackmap_p + 2 <= stackmap_end, "no room for number_of_entries");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  u2 number_of_entries = Bytes::get_Java_u2(stackmap_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  RC_TRACE_WITH_THREAD(0x04000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
    ("number_of_entries=%u", number_of_entries));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
  // walk through each stack_map_frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  u2 calc_number_of_entries = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
  for (; calc_number_of_entries < number_of_entries; calc_number_of_entries++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
    // The stack_map_frame structure is a u1 frame_type followed by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
    // 0 or more bytes of data:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
    // union stack_map_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
    //   same_frame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
    //   same_locals_1_stack_item_frame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
    //   same_locals_1_stack_item_frame_extended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
    //   chop_frame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
    //   same_frame_extended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
    //   append_frame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
    //   full_frame;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
    assert(stackmap_p + 1 <= stackmap_end, "no room for frame_type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
    // The Linux compiler does not like frame_type to be u1 or u2. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
    // issues the following warning for the first if-statement below:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
    // "warning: comparison is always true due to limited range of data type"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
    u4 frame_type = *stackmap_p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
    stackmap_p++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
    // same_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
    //   u1 frame_type = SAME; /* 0-63 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
    if (frame_type >= 0 && frame_type <= 63) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
      // nothing more to do for same_frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
    // same_locals_1_stack_item_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
    //   u1 frame_type = SAME_LOCALS_1_STACK_ITEM; /* 64-127 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
    //   verification_type_info stack[1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
    else if (frame_type >= 64 && frame_type <= 127) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
      rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
        calc_number_of_entries, frame_type, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
    // reserved for future use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
    else if (frame_type >= 128 && frame_type <= 246) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
      // nothing more to do for reserved frame_types
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
    // same_locals_1_stack_item_frame_extended {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
    //   u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; /* 247 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
    //   u2 offset_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
    //   verification_type_info stack[1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
    else if (frame_type == 247) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
      rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
        calc_number_of_entries, frame_type, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
    // chop_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
    //   u1 frame_type = CHOP; /* 248-250 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
    //   u2 offset_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
    else if (frame_type >= 248 && frame_type <= 250) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
    // same_frame_extended {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
    //   u1 frame_type = SAME_FRAME_EXTENDED; /* 251*/
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
    //   u2 offset_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
    else if (frame_type == 251) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
    // append_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
    //   u1 frame_type = APPEND; /* 252-254 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
    //   u2 offset_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
    //   verification_type_info locals[frame_type - 251];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
    else if (frame_type >= 252 && frame_type <= 254) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
      assert(stackmap_p + 2 <= stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
        "no room for offset_delta");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
      u1 len = frame_type - 251;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
      for (u1 i = 0; i < len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
        rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
          calc_number_of_entries, frame_type, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    // full_frame {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
    //   u1 frame_type = FULL_FRAME; /* 255 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    //   u2 offset_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
    //   u2 number_of_locals;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    //   verification_type_info locals[number_of_locals];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
    //   u2 number_of_stack_items;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
    //   verification_type_info stack[number_of_stack_items];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
    else if (frame_type == 255) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
      assert(stackmap_p + 2 + 2 <= stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
        "no room for smallest full_frame");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
      u2 number_of_locals = Bytes::get_Java_u2(stackmap_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
      for (u2 locals_i = 0; locals_i < number_of_locals; locals_i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
        rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
          calc_number_of_entries, frame_type, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
      // Use the largest size for the number_of_stack_items, but only get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
      // the right number of bytes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
      u2 number_of_stack_items = Bytes::get_Java_u2(stackmap_p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
      stackmap_p += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
      for (u2 stack_i = 0; stack_i < number_of_stack_items; stack_i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
        rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
          calc_number_of_entries, frame_type, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
  } // end while there is a stack_map_frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
  assert(number_of_entries == calc_number_of_entries, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
} // end rewrite_cp_refs_in_stack_map_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
// Rewrite constant pool references in the verification type info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
// portion of the method's stackmap table. These "structures" are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
// adapted from the StackMapTable_attribute that is described in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
// section 4.8.4 of the 6.0 version of the VM spec (dated 2005.10.26):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
// file:///net/quincunx.sfbay/export/gbracha/ClassFile-Java6.pdf
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
// The verification_type_info structure is a u1 tag followed by 0 or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
// more bytes of data:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
// union verification_type_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
//   Top_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
//   Integer_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
//   Float_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
//   Long_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
//   Double_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
//   Null_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
//   UninitializedThis_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
//   Object_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
//   Uninitialized_variable_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
// }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
void VM_RedefineClasses::rewrite_cp_refs_in_verification_type_info(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
       address& stackmap_p_ref, address stackmap_end, u2 frame_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
       u1 frame_type, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
  assert(stackmap_p_ref + 1 <= stackmap_end, "no room for tag");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
  u1 tag = *stackmap_p_ref;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
  stackmap_p_ref++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
  switch (tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
  // Top_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
  //   u1 tag = ITEM_Top; /* 0 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
  // verificationType.hpp has zero as ITEM_Bogus instead of ITEM_Top
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
  case 0:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
  // Integer_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
  //   u1 tag = ITEM_Integer; /* 1 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  case ITEM_Integer:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  // Float_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
  //   u1 tag = ITEM_Float; /* 2 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
  case ITEM_Float:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
  // Double_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
  //   u1 tag = ITEM_Double; /* 3 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
  case ITEM_Double:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  // Long_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  //   u1 tag = ITEM_Long; /* 4 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
  case ITEM_Long:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
  // Null_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
  //   u1 tag = ITEM_Null; /* 5 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
  case ITEM_Null:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
  // UninitializedThis_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  //   u1 tag = ITEM_UninitializedThis; /* 6 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  case ITEM_UninitializedThis:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
    // nothing more to do for the above tag types
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  // Object_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
  //   u1 tag = ITEM_Object; /* 7 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
  //   u2 cpool_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
  case ITEM_Object:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
    assert(stackmap_p_ref + 2 <= stackmap_end, "no room for cpool_index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
    u2 cpool_index = Bytes::get_Java_u2(stackmap_p_ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
    u2 new_cp_index = find_new_index(cpool_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
    if (new_cp_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
      RC_TRACE_WITH_THREAD(0x04000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
        ("mapped old cpool_index=%d", cpool_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
      Bytes::put_Java_u2(stackmap_p_ref, new_cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
      cpool_index = new_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
    stackmap_p_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
    RC_TRACE_WITH_THREAD(0x04000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
      ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
      frame_type, cpool_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
  } break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  // Uninitialized_variable_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
  //   u1 tag = ITEM_Uninitialized; /* 8 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
  //   u2 offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  case ITEM_Uninitialized:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
    assert(stackmap_p_ref + 2 <= stackmap_end, "no room for offset");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
    stackmap_p_ref += 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
    RC_TRACE_WITH_THREAD(0x04000000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
      ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
    ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
  } // end switch (tag)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
} // end rewrite_cp_refs_in_verification_type_info()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
// Change the constant pool associated with klass scratch_class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
// scratch_cp. If shrink is true, then scratch_cp_length elements
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
// are copied from scratch_cp to a smaller constant pool and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
// smaller constant pool is associated with scratch_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
void VM_RedefineClasses::set_new_constant_pool(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
       instanceKlassHandle scratch_class, constantPoolHandle scratch_cp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
       int scratch_cp_length, bool shrink, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  assert(!shrink || scratch_cp->length() >= scratch_cp_length, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
  if (shrink) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
    // scratch_cp is a merged constant pool and has enough space for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
    // worst case merge situation. We want to associate the minimum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
    // sized constant pool with the klass to save space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
    constantPoolHandle smaller_cp(THREAD,
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  2332
      oopFactory::new_constantPool(scratch_cp_length,
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  2333
                                   methodOopDesc::IsUnsafeConc,
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  2334
                                   THREAD));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
    // preserve orig_length() value in the smaller copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
    int orig_length = scratch_cp->orig_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
    assert(orig_length != 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
    smaller_cp->set_orig_length(orig_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
    scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
    scratch_cp = smaller_cp;
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  2341
    smaller_cp()->set_is_conc_safe(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
  // attach new constant pool to klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
  scratch_cp->set_pool_holder(scratch_class());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
  // attach klass to new constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
  scratch_class->set_constants(scratch_cp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
  int i;  // for portability
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
  // update each field in klass to use new constant pool indices as needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
  typeArrayHandle fields(THREAD, scratch_class->fields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
  int n_fields = fields->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
    jshort cur_index = fields->short_at(i + instanceKlass::name_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
    jshort new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
        ("field-name_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
      fields->short_at_put(i + instanceKlass::name_index_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
    cur_index = fields->short_at(i + instanceKlass::signature_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
    new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
        ("field-signature_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
      fields->short_at_put(i + instanceKlass::signature_index_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
        new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
    cur_index = fields->short_at(i + instanceKlass::initval_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
    new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
        ("field-initval_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
      fields->short_at_put(i + instanceKlass::initval_index_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
    cur_index = fields->short_at(i + instanceKlass::generic_signature_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
    new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
        ("field-generic_signature change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
      fields->short_at_put(i + instanceKlass::generic_signature_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
        new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
  } // end for each field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
  // Update constant pool indices in the inner classes info to use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
  // new constant indices as needed. The inner classes info is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
  // quadruple:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
  // (inner_class_info, outer_class_info, inner_name, inner_access_flags)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
  typeArrayOop inner_class_list = scratch_class->inner_classes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
  int icl_length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
  if (icl_length > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
    typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
    for (int i = 0; i < icl_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
         i += instanceKlass::inner_class_next_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      int cur_index = inner_class_list_h->ushort_at(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
                        + instanceKlass::inner_class_inner_class_info_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
      if (cur_index == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
        continue;  // JVM spec. allows null inner class refs so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
      int new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
      if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
          ("inner_class_info change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
        inner_class_list_h->ushort_at_put(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
          + instanceKlass::inner_class_inner_class_info_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      cur_index = inner_class_list_h->ushort_at(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
                    + instanceKlass::inner_class_outer_class_info_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
      new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
      if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
          ("outer_class_info change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
        inner_class_list_h->ushort_at_put(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
          + instanceKlass::inner_class_outer_class_info_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
      cur_index = inner_class_list_h->ushort_at(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
                    + instanceKlass::inner_class_inner_name_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
      new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
      if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
          ("inner_name change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
        inner_class_list_h->ushort_at_put(i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
          + instanceKlass::inner_class_inner_name_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
    } // end for each inner class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
  } // end if we have inner classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
  // Attach each method in klass to the new constant pool and update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
  // to use new constant pool indices as needed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  objArrayHandle methods(THREAD, scratch_class->methods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
  for (i = methods->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
    methodHandle method(THREAD, (methodOop)methods->obj_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
    method->set_constants(scratch_cp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
    int new_index = find_new_index(method->name_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
        ("method-name_index change: %d to %d", method->name_index(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
        new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
      method->set_name_index(new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
    new_index = find_new_index(method->signature_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
        ("method-signature_index change: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
        method->signature_index(), new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
      method->set_signature_index(new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
    new_index = find_new_index(method->generic_signature_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
    if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
        ("method-generic_signature_index change: %d to %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
        method->generic_signature_index(), new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
      method->set_generic_signature_index(new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
    // Update constant pool indices in the method's checked exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
    // table to use new constant indices as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
    int cext_length = method->checked_exceptions_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
    if (cext_length > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
      CheckedExceptionElement * cext_table =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
        method->checked_exceptions_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
      for (int j = 0; j < cext_length; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
        int cur_index = cext_table[j].class_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
        int new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
          RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
            ("cext-class_cp_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
          cext_table[j].class_cp_index = (u2)new_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
      } // end for each checked exception table entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
    } // end if there are checked exception table entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
    // Update each catch type index in the method's exception table
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
    // to use new constant pool indices as needed. The exception table
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
    // holds quadruple entries of the form:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
    //   (beg_bci, end_bci, handler_bci, klass_index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
    const int beg_bci_offset     = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
    const int end_bci_offset     = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
    const int handler_bci_offset = 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
    const int klass_index_offset = 3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
    const int entry_size         = 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
    typeArrayHandle ex_table (THREAD, method->exception_table());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
    int ext_length = ex_table->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
    assert(ext_length % entry_size == 0, "exception table format has changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
    for (int j = 0; j < ext_length; j += entry_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
      int cur_index = ex_table->int_at(j + klass_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
      int new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
      if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
          ("ext-klass_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
        ex_table->int_at_put(j + klass_index_offset, new_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
    } // end for each exception table entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
    // Update constant pool indices in the method's local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
    // table to use new constant indices as needed. The local variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
    // table hold sextuple entries of the form:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
    // (start_pc, length, name_index, descriptor_index, signature_index, slot)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
    int lvt_length = method->localvariable_table_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
    if (lvt_length > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
      LocalVariableTableElement * lv_table =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
        method->localvariable_table_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
      for (int j = 0; j < lvt_length; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
        int cur_index = lv_table[j].name_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
        int new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
          RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
            ("lvt-name_cp_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
          lv_table[j].name_cp_index = (u2)new_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
        cur_index = lv_table[j].descriptor_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
        new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
          RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
            ("lvt-descriptor_cp_index change: %d to %d", cur_index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
            new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
          lv_table[j].descriptor_cp_index = (u2)new_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
        cur_index = lv_table[j].signature_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
        new_index = find_new_index(cur_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
        if (new_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
          RC_TRACE_WITH_THREAD(0x00080000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
            ("lvt-signature_cp_index change: %d to %d", cur_index, new_index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
          lv_table[j].signature_cp_index = (u2)new_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
      } // end for each local variable table entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
    } // end if there are local variable table entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
    rewrite_cp_refs_in_stack_map_table(method, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
  } // end for each method
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1
diff changeset
  2537
  assert(scratch_cp()->is_conc_safe(), "Just checking");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
} // end set_new_constant_pool()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
// Unevolving classes may point to methods of the_class directly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
// from their constant pool caches, itables, and/or vtables. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
// use the SystemDictionary::classes_do() facility and this helper
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
// to fix up these pointers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
// Note: We currently don't support updating the vtable in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
// arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
void VM_RedefineClasses::adjust_cpool_cache_and_vtable(klassOop k_oop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
       oop initiating_loader, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
  Klass *k = k_oop->klass_part();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  if (k->oop_is_instance()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    HandleMark hm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
    instanceKlass *ik = (instanceKlass *) k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
    // HotSpot specific optimization! HotSpot does not currently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
    // support delegation from the bootstrap class loader to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    // user-defined class loader. This means that if the bootstrap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
    // class loader is the initiating class loader, then it will also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    // be the defining class loader. This also means that classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    // loaded by the bootstrap class loader cannot refer to classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
    // loaded by a user-defined class loader. Note: a user-defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
    // class loader can delegate to the bootstrap class loader.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
    // If the current class being redefined has a user-defined class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
    // loader as its defining class loader, then we can skip all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
    // classes loaded by the bootstrap class loader.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
    bool is_user_defined =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
           instanceKlass::cast(_the_class_oop)->class_loader() != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
    if (is_user_defined && ik->class_loader() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
    // This is a very busy routine. We don't want too much tracing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
    // printed out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
    bool trace_name_printed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
    // Very noisy: only enable this call if you are trying to determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
    // that a specific class gets found by this routine.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
    // RC_TRACE macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
    // RC_TRACE_WITH_THREAD(0x00100000, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
    //   ("adjust check: name=%s", ik->external_name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
    // trace_name_printed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
    // Fix the vtable embedded in the_class and subclasses of the_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
    // if one exists. We discard scratch_class and we don't keep an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
    // instanceKlass around to hold obsolete methods so we don't have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
    // any other instanceKlass embedded vtables to update. The vtable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
    // holds the methodOops for virtual (but not final) methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
    if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
      // ik->vtable() creates a wrapper object; rm cleans it up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
      ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
      ik->vtable()->adjust_method_entries(_matching_old_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
                                          _matching_new_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
                                          _matching_methods_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
                                          &trace_name_printed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
    // If the current class has an itable and we are either redefining an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
    // interface or if the current class is a subclass of the_class, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
    // we potentially have to fix the itable. If we are redefining an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
    // interface, then we have to call adjust_method_entries() for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
    // every instanceKlass that has an itable since there isn't a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
    // subclass relationship between an interface and an instanceKlass.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
    if (ik->itable_length() > 0 && (Klass::cast(_the_class_oop)->is_interface()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
        || ik->is_subclass_of(_the_class_oop))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
      // ik->itable() creates a wrapper object; rm cleans it up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
      ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
      ik->itable()->adjust_method_entries(_matching_old_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
                                          _matching_new_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
                                          _matching_methods_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
                                          &trace_name_printed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
    // The constant pools in other classes (other_cp) can refer to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
    // methods in the_class. We have to update method information in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
    // other_cp's cache. If other_cp has a previous version, then we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
    // have to repeat the process for each previous version. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
    // constant pool cache holds the methodOops for non-virtual
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
    // methods and for virtual, final methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
    // Special case: if the current class is the_class, then new_cp
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
    // has already been attached to the_class and old_cp has already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
    // been added as a previous version. The new_cp doesn't have any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
    // cached references to old methods so it doesn't need to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
    // updated. We can simply start with the previous version(s) in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
    // that case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    constantPoolHandle other_cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
    constantPoolCacheOop cp_cache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
    if (k_oop != _the_class_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
      // this klass' constant pool cache may need adjustment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
      other_cp = constantPoolHandle(ik->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
      cp_cache = other_cp->cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
      if (cp_cache != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
        cp_cache->adjust_method_entries(_matching_old_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
                                        _matching_new_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
                                        _matching_methods_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
                                        &trace_name_printed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
      ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
      // PreviousVersionInfo objects returned via PreviousVersionWalker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
      // contain a GrowableArray of handles. We have to clean up the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
      // GrowableArray _after_ the PreviousVersionWalker destructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
      // has destroyed the handles.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
        // the previous versions' constant pool caches may need adjustment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
        PreviousVersionWalker pvw(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
        for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
             pv_info != NULL; pv_info = pvw.next_previous_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
          other_cp = pv_info->prev_constant_pool_handle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
          cp_cache = other_cp->cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
          if (cp_cache != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
            cp_cache->adjust_method_entries(_matching_old_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
                                            _matching_new_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
                                            _matching_methods_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
                                            &trace_name_printed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
      } // pvw is cleaned up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
    } // rm is cleaned up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
void VM_RedefineClasses::update_jmethod_ids() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
  for (int j = 0; j < _matching_methods_length; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
    methodOop old_method = _matching_old_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
    jmethodID jmid = old_method->find_jmethod_id_or_null();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
    if (jmid != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
      // There is a jmethodID, change it to point to the new method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
      methodHandle new_method_h(_matching_new_methods[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
      JNIHandles::change_method_associated_with_jmethod_id(jmid, new_method_h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
      assert(JNIHandles::resolve_jmethod_id(jmid) == _matching_new_methods[j],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
             "should be replaced");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
void VM_RedefineClasses::check_methods_and_mark_as_obsolete(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
       BitMap *emcp_methods, int * emcp_method_count_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  *emcp_method_count_p = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  int obsolete_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
  int old_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  for (int j = 0; j < _matching_methods_length; ++j, ++old_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
    methodOop old_method = _matching_old_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
    methodOop new_method = _matching_new_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
    methodOop old_array_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
    // Maintain an old_index into the _old_methods array by skipping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
    // deleted methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
    while ((old_array_method = (methodOop) _old_methods->obj_at(old_index))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
                                                            != old_method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
      ++old_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
    if (MethodComparator::methods_EMCP(old_method, new_method)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
      // The EMCP definition from JSR-163 requires the bytecodes to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
      // the same with the exception of constant pool indices which may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
      // differ. However, the constants referred to by those indices
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
      // must be the same.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
      // We use methods_EMCP() for comparison since constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
      // merging can remove duplicate constant pool entries that were
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
      // present in the old method and removed from the rewritten new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
      // method. A faster binary comparison function would consider the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
      // old and new methods to be different when they are actually
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
      // EMCP.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
      // The old and new methods are EMCP and you would think that we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
      // could get rid of one of them here and now and save some space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
      // However, the concept of EMCP only considers the bytecodes and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
      // the constant pool entries in the comparison. Other things,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
      // e.g., the line number table (LNT) or the local variable table
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
      // (LVT) don't count in the comparison. So the new (and EMCP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
      // method can have a new LNT that we need so we can't just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
      // overwrite the new method with the old method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
      // When this routine is called, we have already attached the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
      // methods to the_class so the old methods are effectively
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
      // overwritten. However, if an old method is still executing,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
      // then the old method cannot be collected until sometime after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
      // the old method call has returned. So the overwriting of old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
      // methods by new methods will save us space except for those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
      // (hopefully few) old methods that are still executing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
      // A method refers to a constMethodOop and this presents another
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
      // possible avenue to space savings. The constMethodOop in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
      // new method contains possibly new attributes (LNT, LVT, etc).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
      // At first glance, it seems possible to save space by replacing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
      // the constMethodOop in the old method with the constMethodOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
      // from the new method. The old and new methods would share the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
      // same constMethodOop and we would save the space occupied by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
      // the old constMethodOop. However, the constMethodOop contains
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
      // a back reference to the containing method. Sharing the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
      // constMethodOop between two methods could lead to confusion in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
      // the code that uses the back reference. This would lead to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
      // brittle code that could be broken in non-obvious ways now or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
      // in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
      // Another possibility is to copy the constMethodOop from the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
      // method to the old method and then overwrite the new method with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
      // the old method. Since the constMethodOop contains the bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
      // for the method embedded in the oop, this option would change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
      // the bytecodes out from under any threads executing the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
      // method and make the thread's bcp invalid. Since EMCP requires
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
      // that the bytecodes be the same modulo constant pool indices, it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
      // is straight forward to compute the correct new bcp in the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
      // constMethodOop from the old bcp in the old constMethodOop. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
      // time consuming part would be searching all the frames in all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
      // of the threads to find all of the calls to the old method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
      // It looks like we will have to live with the limited savings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
      // that we get from effectively overwriting the old methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
      // when the new methods are attached to the_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
      // track which methods are EMCP for add_previous_version() call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
      emcp_methods->set_bit(old_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
      (*emcp_method_count_p)++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
      // An EMCP method is _not_ obsolete. An obsolete method has a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
      // different jmethodID than the current method. An EMCP method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
      // has the same jmethodID as the current method. Having the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
      // same jmethodID for all EMCP versions of a method allows for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
      // a consistent view of the EMCP methods regardless of which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
      // EMCP method you happen to have in hand. For example, a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
      // breakpoint set in one EMCP method will work for all EMCP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
      // versions of the method including the current one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
      // mark obsolete methods as such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
      old_method->set_is_obsolete();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
      obsolete_count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
      // obsolete methods need a unique idnum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
      u2 num = instanceKlass::cast(_the_class_oop)->next_method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
      if (num != constMethodOopDesc::UNSET_IDNUM) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
//      u2 old_num = old_method->method_idnum();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
        old_method->set_method_idnum(num);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
// TO DO: attach obsolete annotations to obsolete method's new idnum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
      // With tracing we try not to "yack" too much. The position of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
      // this trace assumes there are fewer obsolete methods than
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
      // EMCP methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
      RC_TRACE(0x00000100, ("mark %s(%s) as obsolete",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
        old_method->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
        old_method->signature()->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
    old_method->set_is_old();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
  for (int i = 0; i < _deleted_methods_length; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
    methodOop old_method = _deleted_methods[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
    assert(old_method->vtable_index() < 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
           "cannot delete methods with vtable entries");;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
    // Mark all deleted methods as old and obsolete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
    old_method->set_is_old();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
    old_method->set_is_obsolete();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
    ++obsolete_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
    // With tracing we try not to "yack" too much. The position of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
    // this trace assumes there are fewer obsolete methods than
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
    // EMCP methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
    RC_TRACE(0x00000100, ("mark deleted %s(%s) as obsolete",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
                          old_method->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
                          old_method->signature()->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
  assert((*emcp_method_count_p + obsolete_count) == _old_methods->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
    "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", *emcp_method_count_p,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
    obsolete_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
// This internal class transfers the native function registration from old methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
// to new methods.  It is designed to handle both the simple case of unchanged
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
// native methods and the complex cases of native method prefixes being added and/or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
// removed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
// It expects only to be used during the VM_RedefineClasses op (a safepoint).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
// This class is used after the new methods have been installed in "the_class".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
// So, for example, the following must be handled.  Where 'm' is a method and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
// a number followed by an underscore is a prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
//                                      Old Name    New Name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
// Simple transfer to new method        m       ->  m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
// Add prefix                           m       ->  1_m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
// Remove prefix                        1_m     ->  m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
// Simultaneous add of prefixes         m       ->  3_2_1_m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
// Simultaneous removal of prefixes     3_2_1_m ->  m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
// Simultaneous add and remove          1_m     ->  2_m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
// Same, caused by prefix removal only  3_2_1_m ->  3_2_m
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
class TransferNativeFunctionRegistration {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
  instanceKlassHandle the_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
  int prefix_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
  char** prefixes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
  // Recursively search the binary tree of possibly prefixed method names.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  // Iteration could be used if all agents were well behaved. Full tree walk is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
  // more resilent to agents not cleaning up intermediate methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  // Branch at each depth in the binary tree is:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
  //    (1) without the prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
  //    (2) with the prefix.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  // where 'prefix' is the prefix at that 'depth' (first prefix, second prefix,...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  methodOop search_prefix_name_space(int depth, char* name_str, size_t name_len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
                                     symbolOop signature) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
    symbolOop name_symbol = SymbolTable::probe(name_str, (int)name_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
    if (name_symbol != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
      methodOop method = Klass::cast(the_class())->lookup_method(name_symbol, signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
      if (method != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
        // Even if prefixed, intermediate methods must exist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
        if (method->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
          // Wahoo, we found a (possibly prefixed) version of the method, return it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
          return method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
        if (depth < prefix_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
          // Try applying further prefixes (other than this one).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
          method = search_prefix_name_space(depth+1, name_str, name_len, signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
          if (method != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
            return method; // found
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
          // Try adding this prefix to the method name and see if it matches
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
          // another method name.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
          char* prefix = prefixes[depth];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
          size_t prefix_len = strlen(prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
          size_t trial_len = name_len + prefix_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
          char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
          strcpy(trial_name_str, prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
          strcat(trial_name_str, name_str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
          method = search_prefix_name_space(depth+1, trial_name_str, trial_len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
                                            signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
          if (method != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
            // If found along this branch, it was prefixed, mark as such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
            method->set_is_prefixed_native();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
            return method; // found
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
    return NULL;  // This whole branch bore nothing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
  // Return the method name with old prefixes stripped away.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
  char* method_name_without_prefixes(methodOop method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
    symbolOop name = method->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
    char* name_str = name->as_utf8();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
    // Old prefixing may be defunct, strip prefixes, if any.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    for (int i = prefix_count-1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
      char* prefix = prefixes[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
      size_t prefix_len = strlen(prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
      if (strncmp(prefix, name_str, prefix_len) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
        name_str += prefix_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
    return name_str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
  // Strip any prefixes off the old native method, then try to find a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  // (possibly prefixed) new native that matches it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  methodOop strip_and_search_for_new_native(methodOop method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
    char* name_str = method_name_without_prefixes(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
    return search_prefix_name_space(0, name_str, strlen(name_str),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
                                    method->signature());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  // Construct a native method transfer processor for this class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
  TransferNativeFunctionRegistration(instanceKlassHandle _the_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
    assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
    the_class = _the_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
    prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
  // Attempt to transfer any of the old or deleted methods that are native
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
  void transfer_registrations(methodOop* old_methods, int methods_length) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
    for (int j = 0; j < methods_length; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
      methodOop old_method = old_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
      if (old_method->is_native() && old_method->has_native_function()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
        methodOop new_method = strip_and_search_for_new_native(old_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
        if (new_method != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
          // Actually set the native function in the new method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
          // Redefine does not send events (except CFLH), certainly not this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
          // behind the scenes re-registration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
          new_method->set_native_function(old_method->native_function(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
                              !methodOopDesc::native_bind_event_is_interesting);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
// Don't lose the association between a native method and its JNI function.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
void VM_RedefineClasses::transfer_old_native_function_registrations(instanceKlassHandle the_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  TransferNativeFunctionRegistration transfer(the_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  transfer.transfer_registrations(_deleted_methods, _deleted_methods_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  transfer.transfer_registrations(_matching_old_methods, _matching_methods_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
// Deoptimize all compiled code that depends on this class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
// If the can_redefine_classes capability is obtained in the onload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
// phase then the compiler has recorded all dependencies from startup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
// In that case we need only deoptimize and throw away all compiled code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
// that depends on the class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
// If can_redefine_classes is obtained sometime after the onload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
// phase then the dependency information may be incomplete. In that case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
// the first call to RedefineClasses causes all compiled code to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
// thrown away. As can_redefine_classes has been obtained then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
// all future compilations will record dependencies so second and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
// subsequent calls to RedefineClasses need only throw away code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
// that depends on the class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
void VM_RedefineClasses::flush_dependent_code(instanceKlassHandle k_h, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
  assert_locked_or_safepoint(Compile_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
  // All dependencies have been recorded from startup or this is a second or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
  // subsequent use of RedefineClasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  if (JvmtiExport::all_dependencies_are_recorded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
    Universe::flush_evol_dependents_on(k_h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
    CodeCache::mark_all_nmethods_for_deoptimization();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
    ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
    DeoptimizationMarker dm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
    // Deoptimize all activations depending on marked nmethods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
    Deoptimization::deoptimize_dependents();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
    // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
    CodeCache::make_marked_nmethods_not_entrant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
    // From now on we know that the dependency information is complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
    JvmtiExport::set_all_dependencies_are_recorded(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
void VM_RedefineClasses::compute_added_deleted_matching_methods() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
  methodOop old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  methodOop new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
  _matching_old_methods = NEW_RESOURCE_ARRAY(methodOop, _old_methods->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
  _matching_new_methods = NEW_RESOURCE_ARRAY(methodOop, _old_methods->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
  _added_methods        = NEW_RESOURCE_ARRAY(methodOop, _new_methods->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  _deleted_methods      = NEW_RESOURCE_ARRAY(methodOop, _old_methods->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  _matching_methods_length = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
  _deleted_methods_length  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
  _added_methods_length    = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  int nj = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  int oj = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
    if (oj >= _old_methods->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
      if (nj >= _new_methods->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
        break; // we've looked at everything, done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
      // New method at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
      new_method = (methodOop) _new_methods->obj_at(nj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
      _added_methods[_added_methods_length++] = new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
      ++nj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
    } else if (nj >= _new_methods->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
      // Old method, at the end, is deleted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
      old_method = (methodOop) _old_methods->obj_at(oj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
      _deleted_methods[_deleted_methods_length++] = old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
      ++oj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
      old_method = (methodOop) _old_methods->obj_at(oj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
      new_method = (methodOop) _new_methods->obj_at(nj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
      if (old_method->name() == new_method->name()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
        if (old_method->signature() == new_method->signature()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
          _matching_old_methods[_matching_methods_length  ] = old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
          _matching_new_methods[_matching_methods_length++] = new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
          ++nj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
          ++oj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
          // added overloaded have already been moved to the end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
          // so this is a deleted overloaded method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
          _deleted_methods[_deleted_methods_length++] = old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
          ++oj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
      } else { // names don't match
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
        if (old_method->name()->fast_compare(new_method->name()) > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
          // new method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
          _added_methods[_added_methods_length++] = new_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
          ++nj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
          // deleted method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
          _deleted_methods[_deleted_methods_length++] = old_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
          ++oj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
  assert(_matching_methods_length + _deleted_methods_length == _old_methods->length(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  assert(_matching_methods_length + _added_methods_length == _new_methods->length(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
// Install the redefinition of a class:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
//    - house keeping (flushing breakpoints and caches, deoptimizing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
//      dependent compiled code)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
//    - replacing parts in the_class with parts from scratch_class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
//    - adding a weak reference to track the obsolete but interesting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
//      parts of the_class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
//    - adjusting constant pool caches and vtables in other classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
//      that refer to methods in the_class. These adjustments use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
//      SystemDictionary::classes_do() facility which only allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
//      a helper method to be specified. The interesting parameters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
//      that we would like to pass to the helper method are saved in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
//      static global fields in the VM operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
       instanceKlassHandle scratch_class, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
  RC_TIMER_START(_timer_rsc_phase1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
  oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
  klassOop the_class_oop = java_lang_Class::as_klassOop(the_class_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
  instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
  // Remove all breakpoints in methods of this class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
  JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
  jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
#endif // !JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
  if (the_class_oop == Universe::reflect_invoke_cache()->klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
    // We are redefining java.lang.reflect.Method. Method.invoke() is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
    // cached and users of the cache care about each active version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
    // the method so we have to track this previous version.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
    // Do this before methods get switched
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
    Universe::reflect_invoke_cache()->add_previous_version(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
      the_class->method_with_idnum(Universe::reflect_invoke_cache()->method_idnum()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
  // Deoptimize all compiled code that depends on this class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
  flush_dependent_code(the_class, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
  _old_methods = the_class->methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
  _new_methods = scratch_class->methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
  _the_class_oop = the_class_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
  compute_added_deleted_matching_methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
  update_jmethod_ids();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
  // Attach new constant pool to the original klass. The original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
  // klass still refers to the old constant pool (for now).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
  scratch_class->constants()->set_pool_holder(the_class());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
  // In theory, with constant pool merging in place we should be able
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
  // to save space by using the new, merged constant pool in place of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
  // the old constant pool(s). By "pool(s)" I mean the constant pool in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
  // the klass version we are replacing now and any constant pool(s) in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
  // previous versions of klass. Nice theory, doesn't work in practice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
  // When this code is enabled, even simple programs throw NullPointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
  // exceptions. I'm guessing that this is caused by some constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  // cache difference between the new, merged constant pool and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
  // constant pool that was just being used by the klass. I'm keeping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
  // this code around to archive the idea, but the code has to remain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  // disabled for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  // Attach each old method to the new constant pool. This can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
  // done here since we are past the bytecode verification and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
  // constant pool optimization phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
  for (int i = _old_methods->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
    methodOop method = (methodOop)_old_methods->obj_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
    method->set_constants(scratch_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
    // walk all previous versions of the klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
    instanceKlass *ik = (instanceKlass *)the_class()->klass_part();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
    PreviousVersionWalker pvw(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
    instanceKlassHandle ikh;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
      ikh = pvw.next_previous_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
      if (!ikh.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
        ik = ikh();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
        // attach previous version of klass to the new constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
        ik->set_constants(scratch_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
        // Attach each method in the previous version of klass to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
        // new constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
        objArrayOop prev_methods = ik->methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
        for (int i = prev_methods->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
          methodOop method = (methodOop)prev_methods->obj_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
          method->set_constants(scratch_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
    } while (!ikh.is_null());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
  // Replace methods and constantpool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
  the_class->set_methods(_new_methods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
  scratch_class->set_methods(_old_methods);     // To prevent potential GCing of the old methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
                                          // and to be able to undo operation easily.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
  constantPoolOop old_constants = the_class->constants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
  the_class->set_constants(scratch_class->constants());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
  scratch_class->set_constants(old_constants);  // See the previous comment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
  // We are swapping the guts of "the new class" with the guts of "the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
  // class". Since the old constant pool has just been attached to "the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3154
  // new class", it seems logical to set the pool holder in the old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
  // constant pool also. However, doing this will change the observable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
  // class hierarchy for any old methods that are still executing. A
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
  // method can query the identity of its "holder" and this query uses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
  // the method's constant pool link to find the holder. The change in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
  // holding class from "the class" to "the new class" can confuse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
  // things.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
  // Setting the old constant pool's holder will also cause
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
  // verification done during vtable initialization below to fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
  // During vtable initialization, the vtable's class is verified to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
  // a subtype of the method's holder. The vtable's class is "the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
  // class" and the method's holder is gotten from the constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
  // link in the method itself. For "the class"'s directly implemented
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
  // methods, the method holder is "the class" itself (as gotten from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
  // the new constant pool). The check works fine in this case. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
  // check also works fine for methods inherited from super classes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
  // Miranda methods are a little more complicated. A miranda method is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  // provided by an interface when the class implementing the interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
  // does not provide its own method.  These interfaces are implemented
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
  // internally as an instanceKlass. These special instanceKlasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
  // share the constant pool of the class that "implements" the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
  // interface. By sharing the constant pool, the method holder of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
  // miranda method is the class that "implements" the interface. In a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
  // non-redefine situation, the subtype check works fine. However, if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
  // the old constant pool's pool holder is modified, then the check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
  // fails because there is no class hierarchy relationship between the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
  // vtable's class and "the new class".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
  old_constants->set_pool_holder(scratch_class());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
  // track which methods are EMCP for add_previous_version() call below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
  BitMap emcp_methods(_old_methods->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
  int emcp_method_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
  emcp_methods.clear();  // clears 0..(length() - 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
  check_methods_and_mark_as_obsolete(&emcp_methods, &emcp_method_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
  transfer_old_native_function_registrations(the_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
  // The class file bytes from before any retransformable agents mucked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
  // with them was cached on the scratch class, move to the_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
  // Note: we still want to do this if nothing needed caching since it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
  // should get cleared in the_class too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
  the_class->set_cached_class_file(scratch_class->get_cached_class_file_bytes(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
                                   scratch_class->get_cached_class_file_len());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
  // Replace inner_classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
  typeArrayOop old_inner_classes = the_class->inner_classes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  the_class->set_inner_classes(scratch_class->inner_classes());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
  scratch_class->set_inner_classes(old_inner_classes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
  // Initialize the vtable and interface table after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
  // methods have been rewritten
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
    ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
    // no exception should happen here since we explicitly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
    // do not check loader constraints.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
    // compare_and_normalize_class_versions has already checked:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
    //  - classloaders unchanged, signatures unchanged
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
    //  - all instanceKlasses for redefined classes reused & contents updated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
    the_class->vtable()->initialize_vtable(false, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
    the_class->itable()->initialize_itable(false, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
    assert(!HAS_PENDING_EXCEPTION || (THREAD->pending_exception()->is_a(SystemDictionary::threaddeath_klass())), "redefine exception");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
  // Leave arrays of jmethodIDs and itable index cache unchanged
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
  // Copy the "source file name" attribute from new class version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
  the_class->set_source_file_name(scratch_class->source_file_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
  // Copy the "source debug extension" attribute from new class version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
  the_class->set_source_debug_extension(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
    scratch_class->source_debug_extension());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  // Use of javac -g could be different in the old and the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
  if (scratch_class->access_flags().has_localvariable_table() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
      the_class->access_flags().has_localvariable_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
    AccessFlags flags = the_class->access_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
    if (scratch_class->access_flags().has_localvariable_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
      flags.set_has_localvariable_table();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
      flags.clear_has_localvariable_table();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
    the_class->set_access_flags(flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
  // Replace class annotation fields values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
  typeArrayOop old_class_annotations = the_class->class_annotations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
  the_class->set_class_annotations(scratch_class->class_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
  scratch_class->set_class_annotations(old_class_annotations);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
  // Replace fields annotation fields values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
  objArrayOop old_fields_annotations = the_class->fields_annotations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
  the_class->set_fields_annotations(scratch_class->fields_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
  scratch_class->set_fields_annotations(old_fields_annotations);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
  // Replace methods annotation fields values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
  objArrayOop old_methods_annotations = the_class->methods_annotations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
  the_class->set_methods_annotations(scratch_class->methods_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
  scratch_class->set_methods_annotations(old_methods_annotations);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
  // Replace methods parameter annotation fields values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
  objArrayOop old_methods_parameter_annotations =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
    the_class->methods_parameter_annotations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
  the_class->set_methods_parameter_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
    scratch_class->methods_parameter_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
  scratch_class->set_methods_parameter_annotations(old_methods_parameter_annotations);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
  // Replace methods default annotation fields values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
  objArrayOop old_methods_default_annotations =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
    the_class->methods_default_annotations();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  the_class->set_methods_default_annotations(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
    scratch_class->methods_default_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
  scratch_class->set_methods_default_annotations(old_methods_default_annotations);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
  // Replace minor version number of class file
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
  u2 old_minor_version = the_class->minor_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
  the_class->set_minor_version(scratch_class->minor_version());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
  scratch_class->set_minor_version(old_minor_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
  // Replace major version number of class file
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
  u2 old_major_version = the_class->major_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
  the_class->set_major_version(scratch_class->major_version());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
  scratch_class->set_major_version(old_major_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
  // Replace CP indexes for class and name+type of enclosing method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
  u2 old_class_idx  = the_class->enclosing_method_class_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
  u2 old_method_idx = the_class->enclosing_method_method_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  the_class->set_enclosing_method_indices(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
    scratch_class->enclosing_method_class_index(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
    scratch_class->enclosing_method_method_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
  scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  // keep track of previous versions of this class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
  the_class->add_previous_version(scratch_class, &emcp_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
    emcp_method_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
  RC_TIMER_STOP(_timer_rsc_phase1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
  RC_TIMER_START(_timer_rsc_phase2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
  // Adjust constantpool caches and vtables for all classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
  // that reference methods of the evolved class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
  SystemDictionary::classes_do(adjust_cpool_cache_and_vtable, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
  if (the_class->oop_map_cache() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
    // Flush references to any obsolete methods from the oop map cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
    // so that obsolete methods are not pinned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
    the_class->oop_map_cache()->flush_obsolete_entries();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
  // increment the classRedefinedCount field in the_class and in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
  // direct and indirect subclasses of the_class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
  increment_class_counter((instanceKlass *)the_class()->klass_part(), THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
  // RC_TRACE macro has an embedded ResourceMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
  RC_TRACE_WITH_THREAD(0x00000001, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
    ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
    the_class->external_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
    java_lang_Class::classRedefinedCount(the_class_mirror),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
    os::available_memory() >> 10));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
  RC_TIMER_STOP(_timer_rsc_phase2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
} // end redefine_single_class()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
// Increment the classRedefinedCount field in the specific instanceKlass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
// and in all direct and indirect subclasses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
void VM_RedefineClasses::increment_class_counter(instanceKlass *ik, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
  oop class_mirror = ik->java_mirror();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  klassOop class_oop = java_lang_Class::as_klassOop(class_mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  if (class_oop != _the_class_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
    // _the_class_oop count is printed at end of redefine_single_class()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
    RC_TRACE_WITH_THREAD(0x00000008, THREAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
      ("updated count in subclass=%s to %d", ik->external_name(), new_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
  for (Klass *subk = ik->subklass(); subk != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
       subk = subk->next_sibling()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
    klassOop sub = subk->as_klassOop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
    instanceKlass *subik = (instanceKlass *)sub->klass_part();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
    // recursively do subclasses of the current subclass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
    increment_class_counter(subik, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
void VM_RedefineClasses::check_class(klassOop k_oop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
       oop initiating_loader, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
  Klass *k = k_oop->klass_part();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  if (k->oop_is_instance()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
    HandleMark hm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
    instanceKlass *ik = (instanceKlass *) k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
    if (ik->vtable_length() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
      ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
      if (!ik->vtable()->check_no_old_entries()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
        tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
        ik->vtable()->dump_vtable();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
        dump_methods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
        assert(false, "OLD method found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
void VM_RedefineClasses::dump_methods() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
        int j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
        tty->print_cr("_old_methods --");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
        for (j = 0; j < _old_methods->length(); ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
          methodOop m = (methodOop) _old_methods->obj_at(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
          tty->print("%4d  (%5d)  ", j, m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
          tty->print(" --  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
          m->print_name(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
        tty->print_cr("_new_methods --");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
        for (j = 0; j < _new_methods->length(); ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
          methodOop m = (methodOop) _new_methods->obj_at(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
          tty->print("%4d  (%5d)  ", j, m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
          tty->print(" --  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
          m->print_name(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
        tty->print_cr("_matching_(old/new)_methods --");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
        for (j = 0; j < _matching_methods_length; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
          methodOop m = _matching_old_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
          tty->print("%4d  (%5d)  ", j, m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
          tty->print(" --  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
          m->print_name(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
          m = _matching_new_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
          tty->print("      (%5d)  ", m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
        tty->print_cr("_deleted_methods --");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
        for (j = 0; j < _deleted_methods_length; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
          methodOop m = _deleted_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
          tty->print("%4d  (%5d)  ", j, m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
          tty->print(" --  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
          m->print_name(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
        tty->print_cr("_added_methods --");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
        for (j = 0; j < _added_methods_length; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
          methodOop m = _added_methods[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
          tty->print("%4d  (%5d)  ", j, m->vtable_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
          m->access_flags().print_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
          tty->print(" --  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
          m->print_name(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
          tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
#endif