hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 3261 c7d5aae8d3f7
child 5688 9052dc91ea67
child 5547 f4b087cbb361
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
/*
3261
c7d5aae8d3f7 6862919: Update copyright year
xdono
parents: 2570
diff changeset
     2
 * Copyright 2005-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
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_jvmtiClassFileReconstituter.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
// FIXME: add Deprecated, LVT, LVTT attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
// FIXME: fix Synthetic attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
// FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes()
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
// Write the field information portion of ClassFile structure
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// JVMSpec|     u2 fields_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
// JVMSpec|     field_info fields[fields_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
void JvmtiClassFileReconstituter::write_field_infos() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  HandleMark hm(thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  typeArrayHandle fields(thread(), ikh()->fields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  int fields_length = fields->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  int num_fields = fields_length / instanceKlass::next_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  objArrayHandle fields_anno(thread(), ikh()->fields_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  write_u2(num_fields);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  for (int index = 0; index < fields_length; index += instanceKlass::next_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    AccessFlags access_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    int flags = fields->ushort_at(index + instanceKlass::access_flags_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    access_flags.set_flags(flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    int name_index = fields->ushort_at(index + instanceKlass::name_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    int signature_index = fields->ushort_at(index + instanceKlass::signature_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    int initial_value_index = fields->ushort_at(index + instanceKlass::initval_index_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    int offset = ikh()->offset_from_fields( index );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    int generic_signature_index =
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
                        fields->ushort_at(index + instanceKlass::generic_signature_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    typeArrayHandle anno(thread(), fields_anno.not_null() ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
                                 (typeArrayOop)(fields_anno->obj_at(index / instanceKlass::next_offset)) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
                                 (typeArrayOop)NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    // JVMSpec|   field_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    // JVMSpec|         u2 access_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    // JVMSpec|         u2 name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    // JVMSpec|         u2 descriptor_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    // JVMSpec|         u2 attributes_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    // JVMSpec|         attribute_info attributes[attributes_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    // JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    write_u2(flags & JVM_RECOGNIZED_FIELD_MODIFIERS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    write_u2(name_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    write_u2(signature_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    int attr_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    if (initial_value_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
      ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    if (access_flags.is_synthetic()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
      // ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    if (generic_signature_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
      ++attr_count;     // has RuntimeVisibleAnnotations attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    write_u2(attr_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    if (initial_value_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
      write_attribute_name_index("ConstantValue");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
      write_u4(2); //length always 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
      write_u2(initial_value_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    if (access_flags.is_synthetic()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      // write_synthetic_attribute();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    if (generic_signature_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
      write_signature_attribute(generic_signature_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
      write_annotations_attribute("RuntimeVisibleAnnotations", anno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
// Write Code attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
// JVMSpec|   Code_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
// JVMSpec|     u2 max_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
// JVMSpec|     u2 max_locals;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
// JVMSpec|     u4 code_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
// JVMSpec|     u1 code[code_length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
// JVMSpec|     u2 exception_table_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
// JVMSpec|     {       u2 start_pc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
// JVMSpec|             u2 end_pc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
// JVMSpec|             u2  handler_pc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
// JVMSpec|             u2  catch_type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
// JVMSpec|     }       exception_table[exception_table_length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
// JVMSpec|     u2 attributes_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// JVMSpec|     attribute_info attributes[attributes_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  constMethodHandle const_method(thread(), method->constMethod());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  u2 line_num_cnt = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  int stackmap_len = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // compute number and length of attributes -- FIXME: for now no LVT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  int attr_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  int attr_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  if (const_method->has_linenumber_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    line_num_cnt = line_number_table_entries(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    if (line_num_cnt != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
      ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
      // Compute the complete size of the line number table attribute:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
      //      LineNumberTable_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
      //        u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
      //        u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
      //        u2 line_number_table_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
      //        {  u2 start_pc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      //           u2 line_number;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
      //        } line_number_table[line_number_table_length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
      //      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
      attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  if (method->has_stackmap_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    stackmap_len = method->stackmap_data()->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    if (stackmap_len != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
      // Compute the  size of the stack map table attribute (VM stores raw):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      //      StackMapTable_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      //        u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      //        u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      //        u2 number_of_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      //        stack_map_frame_entries[number_of_entries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      //      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      attr_size += 2 + 4 + stackmap_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  typeArrayHandle exception_table(thread(), const_method->exception_table());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  int exception_table_length = exception_table->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  int exception_table_entries = exception_table_length / 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  int code_size = const_method->code_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  int size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    2+2+4 +                                // max_stack, max_locals, code_length
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    code_size +                            // code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    2 +                                    // exception_table_length
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    (2+2+2+2) * exception_table_entries +  // exception_table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    2 +                                    // attributes_count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    attr_size;                             // attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  write_attribute_name_index("Code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  write_u4(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  write_u2(method->max_stack());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  write_u2(method->max_locals());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  write_u4(code_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  write_u2(exception_table_entries);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  for (int index = 0; index < exception_table_length; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    write_u2(exception_table->int_at(index++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    write_u2(exception_table->int_at(index++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    write_u2(exception_table->int_at(index++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    write_u2(exception_table->int_at(index++));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  write_u2(attr_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  if (line_num_cnt != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    write_line_number_table_attribute(method, line_num_cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  if (stackmap_len != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    write_stackmap_table_attribute(method, stackmap_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  // FIXME: write LVT attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
// Write Exceptions attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
// JVMSpec|   Exceptions_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
// JVMSpec|     u2 number_of_exceptions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
// JVMSpec|     u2 exception_index_table[number_of_exceptions];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
void JvmtiClassFileReconstituter::write_exceptions_attribute(constMethodHandle const_method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  int checked_exceptions_length = const_method->checked_exceptions_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  int size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    2 +                                    // number_of_exceptions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    2 * checked_exceptions_length;         // exception_index_table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  write_attribute_name_index("Exceptions");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  write_u4(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  write_u2(checked_exceptions_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  for (int index = 0; index < checked_exceptions_length; index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    write_u2(checked_exceptions[index].class_cp_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
// Write SourceFile attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
// JVMSpec|   SourceFile_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
// JVMSpec|     u2 sourcefile_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
void JvmtiClassFileReconstituter::write_source_file_attribute() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  assert(ikh()->source_file_name() != NULL, "caller must check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  write_attribute_name_index("SourceFile");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  write_u4(2);  // always length 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  write_u2(symbol_to_cpool_index(ikh()->source_file_name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
// Write SourceDebugExtension attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
// JSR45|   SourceDebugExtension_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
// JSR45|       u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
// JSR45|       u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
// JSR45|       u2 sourcefile_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
// JSR45|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  assert(ikh()->source_debug_extension() != NULL, "caller must check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  write_attribute_name_index("SourceDebugExtension");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  write_u4(2);  // always length 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  write_u2(symbol_to_cpool_index(ikh()->source_debug_extension()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
// Write (generic) Signature attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
// JVMSpec|   Signature_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
// JVMSpec|     u2 signature_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  write_attribute_name_index("Signature");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  write_u4(2);  // always length 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  write_u2(generic_signature_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
// Compute the number of entries in the InnerClasses attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  typeArrayOop inner_class_list = ikh()->inner_classes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  return (inner_class_list == NULL) ? 0 : inner_class_list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
// Write an annotation attribute.  The VM stores them in raw form, so all we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
// to do is add the attrubute name and fill in the length.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
// JSR202|   *Annotations_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
// JSR202|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
// JSR202|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
// JSR202|     ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
// JSR202|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
                                                              typeArrayHandle annos) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  u4 length = annos->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  write_attribute_name_index(attr_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  write_u4(length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  memcpy(writeable_address(length), annos->byte_at_addr(0), length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
// Write InnerClasses attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
// JVMSpec|   InnerClasses_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
// JVMSpec|     u2 number_of_classes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
// JVMSpec|     {  u2 inner_class_info_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
// JVMSpec|        u2 outer_class_info_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
// JVMSpec|        u2 inner_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
// JVMSpec|        u2 inner_class_access_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
// JVMSpec|     } classes[number_of_classes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  typeArrayOop inner_class_list = ikh()->inner_classes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  guarantee(inner_class_list != NULL && inner_class_list->length() == length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
            "caller must check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  typeArrayHandle inner_class_list_h(thread(), inner_class_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  u2 entry_count = length / instanceKlass::inner_class_next_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  u4 size = 2 + entry_count * (2+2+2+2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  write_attribute_name_index("InnerClasses");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  write_u4(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  write_u2(entry_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    write_u2(inner_class_list_h->ushort_at(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
                      i + instanceKlass::inner_class_inner_class_info_offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    write_u2(inner_class_list_h->ushort_at(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
                      i + instanceKlass::inner_class_outer_class_info_offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    write_u2(inner_class_list_h->ushort_at(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
                      i + instanceKlass::inner_class_inner_name_offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    write_u2(inner_class_list_h->ushort_at(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
                      i + instanceKlass::inner_class_access_flags_offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
// Write Synthetic attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
// JVMSpec|   Synthetic_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
void JvmtiClassFileReconstituter::write_synthetic_attribute() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  write_attribute_name_index("Synthetic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  write_u4(0); //length always zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
// Compute size of LineNumberTable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  // The line number table is compressed so we don't know how big it is until decompressed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  // Decompression is really fast so we just do it twice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  u2 num_entries = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  while (stream.read_pair()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    num_entries++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  return num_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
// Write LineNumberTable attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
// JVMSpec|   LineNumberTable_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
// JVMSpec|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
// JVMSpec|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
// JVMSpec|     u2 line_number_table_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
// JVMSpec|     {  u2 start_pc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
// JVMSpec|        u2 line_number;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
// JVMSpec|     } line_number_table[line_number_table_length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
                                                                    u2 num_entries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  write_attribute_name_index("LineNumberTable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  write_u4(2 + num_entries * (2 + 2));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  write_u2(num_entries);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  while (stream.read_pair()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
    write_u2(stream.bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    write_u2(stream.line());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
// Write stack map table attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
// JSR-202|   StackMapTable_attribute {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
// JSR-202|     u2 attribute_name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
// JSR-202|     u4 attribute_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
// JSR-202|     u2 number_of_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
// JSR-202|     stack_map_frame_entries[number_of_entries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
// JSR-202|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
                                                                 int stackmap_len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  write_attribute_name_index("StackMapTable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  write_u4(stackmap_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  memcpy(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    writeable_address(stackmap_len),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
    (void*)(method->stackmap_data()->byte_at_addr(0)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    stackmap_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
// Write one method_info structure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// JVMSpec|   method_info {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
// JVMSpec|     u2 access_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// JVMSpec|     u2 name_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// JVMSpec|     u2 descriptor_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// JVMSpec|     u2 attributes_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// JVMSpec|     attribute_info attributes[attributes_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
// JVMSpec|   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  AccessFlags access_flags = method->access_flags();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  constMethodHandle const_method(thread(), method->constMethod());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  u2 generic_signature_index = const_method->generic_signature_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  typeArrayHandle anno(thread(), method->annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  typeArrayHandle param_anno(thread(), method->parameter_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  typeArrayHandle default_anno(thread(), method->annotation_default());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  write_u2(const_method->name_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  write_u2(const_method->signature_index());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  // write attributes in the same order javac does, so we can test with byte for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // byte comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  int attr_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  if (const_method->code_size() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    ++attr_count;     // has Code attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  if (const_method->has_checked_exceptions()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
    ++attr_count;     // has Exceptions attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  if (default_anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
    ++attr_count;     // has AnnotationDefault attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  // Deprecated attribute would go here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  if (access_flags.is_synthetic()) { // FIXME
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    // ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  if (generic_signature_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    ++attr_count;     // has RuntimeVisibleAnnotations attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  if (param_anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    ++attr_count;     // has RuntimeVisibleParameterAnnotations attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  write_u2(attr_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  if (const_method->code_size() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    write_code_attribute(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  if (const_method->has_checked_exceptions()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    write_exceptions_attribute(const_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  if (default_anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
    write_annotations_attribute("AnnotationDefault", default_anno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // Deprecated attribute would go here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  if (access_flags.is_synthetic()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    // write_synthetic_attribute();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  if (generic_signature_index != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    write_signature_attribute(generic_signature_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
    write_annotations_attribute("RuntimeVisibleAnnotations", anno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  if (param_anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
// Write the class attributes portion of ClassFile structure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
// JVMSpec|     u2 attributes_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
// JVMSpec|     attribute_info attributes[attributes_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
void JvmtiClassFileReconstituter::write_class_attributes() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  u2 inner_classes_length = inner_classes_attribute_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  symbolHandle generic_signature(thread(), ikh()->generic_signature());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  typeArrayHandle anno(thread(), ikh()->class_annotations());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  int attr_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  if (generic_signature() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  if (ikh()->source_file_name() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  if (ikh()->source_debug_extension() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
    ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  if (inner_classes_length > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
    ++attr_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    ++attr_count;     // has RuntimeVisibleAnnotations attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  write_u2(attr_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  if (generic_signature() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    write_signature_attribute(symbol_to_cpool_index(generic_signature()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  if (ikh()->source_file_name() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    write_source_file_attribute();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  if (ikh()->source_debug_extension() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
    write_source_debug_extension_attribute();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  if (inner_classes_length > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
    write_inner_classes_attribute(inner_classes_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  if (anno.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    write_annotations_attribute("RuntimeVisibleAnnotations", anno);
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
// Write the method information portion of ClassFile structure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
// JVMSpec|     u2 methods_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
// JVMSpec|     method_info methods[methods_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
void JvmtiClassFileReconstituter::write_method_infos() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  HandleMark hm(thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  objArrayHandle methods(thread(), ikh()->methods());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  int num_methods = methods->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  write_u2(num_methods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  if (JvmtiExport::can_maintain_original_method_order()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    int index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    int original_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    int* method_order = NEW_RESOURCE_ARRAY(int, num_methods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    // invert the method order mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    for (index = 0; index < num_methods; index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
      original_index = ikh()->method_ordering()->int_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
      assert(original_index >= 0 && original_index < num_methods,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
             "invalid original method index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
      method_order[original_index] = index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
    // write in original order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
    for (original_index = 0; original_index < num_methods; original_index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
      index = method_order[original_index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
      methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
      write_method_info(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
    // method order not preserved just dump the method infos
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    for (int index = 0; index < num_methods; index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
      methodHandle method(thread(), (methodOop)(ikh()->methods()->obj_at(index)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
      write_method_info(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
void JvmtiClassFileReconstituter::write_class_file_format() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  ReallocMark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  // JVMSpec|   ClassFile {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  // JVMSpec|           u4 magic;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  write_u4(0xCAFEBABE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  // JVMSpec|           u2 minor_version;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  // JVMSpec|           u2 major_version;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  write_u2(ikh()->minor_version());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  u2 major = ikh()->major_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  write_u2(major);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  // JVMSpec|           u2 constant_pool_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  // JVMSpec|           cp_info constant_pool[constant_pool_count-1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  write_u2(cpool()->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  copy_cpool_bytes(writeable_address(cpool_size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  // JVMSpec|           u2 access_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  // JVMSpec|           u2 this_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  // JVMSpec|           u2 super_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  write_u2(class_symbol_to_cpool_index(ikh()->name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  klassOop super_class = ikh()->super();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  write_u2(super_class == NULL? 0 :  // zero for java.lang.Object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
                class_symbol_to_cpool_index(super_class->klass_part()->name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  // JVMSpec|           u2 interfaces_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  // JVMSpec|           u2 interfaces[interfaces_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  objArrayHandle interfaces(thread(), ikh()->local_interfaces());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  int num_interfaces = interfaces->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  write_u2(num_interfaces);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  for (int index = 0; index < num_interfaces; index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    HandleMark hm(thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    instanceKlassHandle iikh(thread(), klassOop(interfaces->obj_at(index)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    write_u2(class_symbol_to_cpool_index(iikh->name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  // JVMSpec|           u2 fields_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  // JVMSpec|           field_info fields[fields_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  write_field_infos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  // JVMSpec|           u2 methods_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  // JVMSpec|           method_info methods[methods_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  write_method_infos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  // JVMSpec|           u2 attributes_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  // JVMSpec|           attribute_info attributes[attributes_count];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  // JVMSpec|   } /* end ClassFile 8?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  write_class_attributes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
address JvmtiClassFileReconstituter::writeable_address(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  size_t used_size = _buffer_ptr - _buffer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  if (size + used_size >= _buffer_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
    // compute the new buffer size: must be at least twice as big as before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    // plus whatever new is being used; then convert to nice clean block boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
                                                         * initial_buffer_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    // VM goes belly-up if the memory isn't available, so cannot do OOM processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    _buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    _buffer_size = new_buffer_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    _buffer_ptr = _buffer + used_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  u1* ret_ptr = _buffer_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  _buffer_ptr += size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  return ret_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  unsigned int hash_ignored;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  symbolOop sym = SymbolTable::lookup_only(name, (int)strlen(name), hash_ignored);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  assert(sym != NULL, "attribute name symbol not found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  u2 attr_name_index = symbol_to_cpool_index(sym);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  assert(attr_name_index != 0, "attribute name symbol not in constant pool");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  write_u2(attr_name_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
void JvmtiClassFileReconstituter::write_u1(u1 x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  *writeable_address(1) = x;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
void JvmtiClassFileReconstituter::write_u2(u2 x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  Bytes::put_Java_u2(writeable_address(2), x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
void JvmtiClassFileReconstituter::write_u4(u4 x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  Bytes::put_Java_u4(writeable_address(4), x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
void JvmtiClassFileReconstituter::write_u8(u8 x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  Bytes::put_Java_u8(writeable_address(8), x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
                                                 unsigned char* bytecodes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  // use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  // and the breakpoint bytecode are converted to their original bytecodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  BytecodeStream bs(mh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  unsigned char* p = bytecodes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  Bytecodes::Code code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  bool is_rewritten = instanceKlass::cast(mh->method_holder())->is_rewritten();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  while ((code = bs.next()) >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    assert(Bytecodes::is_java_code(code), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
    assert(code != Bytecodes::_breakpoint, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    // length of bytecode (mnemonic + operands)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    address bcp = bs.bcp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    int len = bs.next_bcp() - bcp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    assert(len > 0, "length must be > 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
    // copy the bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    *p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
    if (len > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
      memcpy(p+1, bcp+1, len-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    // During linking the get/put and invoke instructions are rewritten
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    // with an index into the constant pool cache. The original constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    // pool index must be returned to caller.  Rewrite the index.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    if (is_rewritten && len >= 3) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
      switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
      case Bytecodes::_getstatic       :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      case Bytecodes::_putstatic       :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
      case Bytecodes::_getfield        :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
      case Bytecodes::_putfield        :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
      case Bytecodes::_invokevirtual   :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      case Bytecodes::_invokespecial   :  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
      case Bytecodes::_invokestatic    :  // fall through
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   662
      case Bytecodes::_invokedynamic   :  // fall through
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
      case Bytecodes::_invokeinterface :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
        assert(len == 3 || (code == Bytecodes::_invokeinterface && len ==5),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
               "sanity check");
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   666
        int cpci = Bytes::get_native_u2(bcp+1);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   667
        bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   668
        if (is_invokedynamic)
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   669
          cpci = Bytes::get_native_u4(bcp+1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
        // cache cannot be pre-fetched since some classes won't have it yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
        ConstantPoolCacheEntry* entry =
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   672
          mh->constants()->cache()->main_entry_at(cpci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
        int i = entry->constant_pool_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
        assert(i < mh->constants()->length(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
        Bytes::put_Java_u2((address)(p+1), (u2)i);     // java byte ordering
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1
diff changeset
   676
        if (is_invokedynamic)  *(p+3) = *(p+4) = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
    p += len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
}