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