Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp
41144 views
1
/*
2
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "classfile/symbolTable.hpp"
27
#include "interpreter/bytecodeStream.hpp"
28
#include "memory/universe.hpp"
29
#include "oops/fieldStreams.inline.hpp"
30
#include "oops/recordComponent.hpp"
31
#include "prims/jvmtiClassFileReconstituter.hpp"
32
#include "runtime/handles.inline.hpp"
33
#include "runtime/signature.hpp"
34
#include "utilities/bytes.hpp"
35
36
// FIXME: add Deprecated attribute
37
// FIXME: fix Synthetic attribute
38
// FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes()
39
40
JvmtiConstantPoolReconstituter::JvmtiConstantPoolReconstituter(InstanceKlass* ik) {
41
set_error(JVMTI_ERROR_NONE);
42
_ik = ik;
43
_cpool = constantPoolHandle(Thread::current(), ik->constants());
44
_symmap = new SymbolHashMap();
45
_classmap = new SymbolHashMap();
46
_cpool_size = _cpool->hash_entries_to(_symmap, _classmap);
47
if (_cpool_size == 0) {
48
set_error(JVMTI_ERROR_OUT_OF_MEMORY);
49
} else if (_cpool_size < 0) {
50
set_error(JVMTI_ERROR_INTERNAL);
51
}
52
}
53
54
// Write the field information portion of ClassFile structure
55
// JVMSpec| u2 fields_count;
56
// JVMSpec| field_info fields[fields_count];
57
void JvmtiClassFileReconstituter::write_field_infos() {
58
HandleMark hm(thread());
59
Array<AnnotationArray*>* fields_anno = ik()->fields_annotations();
60
Array<AnnotationArray*>* fields_type_anno = ik()->fields_type_annotations();
61
62
// Compute the real number of Java fields
63
int java_fields = ik()->java_fields_count();
64
65
write_u2(java_fields);
66
for (JavaFieldStream fs(ik()); !fs.done(); fs.next()) {
67
AccessFlags access_flags = fs.access_flags();
68
int name_index = fs.name_index();
69
int signature_index = fs.signature_index();
70
int initial_value_index = fs.initval_index();
71
guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field");
72
// int offset = ik()->field_offset( index );
73
int generic_signature_index = fs.generic_signature_index();
74
AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());
75
AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());
76
77
// JVMSpec| field_info {
78
// JVMSpec| u2 access_flags;
79
// JVMSpec| u2 name_index;
80
// JVMSpec| u2 descriptor_index;
81
// JVMSpec| u2 attributes_count;
82
// JVMSpec| attribute_info attributes[attributes_count];
83
// JVMSpec| }
84
85
write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
86
write_u2(name_index);
87
write_u2(signature_index);
88
int attr_count = 0;
89
if (initial_value_index != 0) {
90
++attr_count;
91
}
92
if (access_flags.is_synthetic()) {
93
// ++attr_count;
94
}
95
if (generic_signature_index != 0) {
96
++attr_count;
97
}
98
if (anno != NULL) {
99
++attr_count; // has RuntimeVisibleAnnotations attribute
100
}
101
if (type_anno != NULL) {
102
++attr_count; // has RuntimeVisibleTypeAnnotations attribute
103
}
104
105
write_u2(attr_count);
106
107
if (initial_value_index != 0) {
108
write_attribute_name_index("ConstantValue");
109
write_u4(2); //length always 2
110
write_u2(initial_value_index);
111
}
112
if (access_flags.is_synthetic()) {
113
// write_synthetic_attribute();
114
}
115
if (generic_signature_index != 0) {
116
write_signature_attribute(generic_signature_index);
117
}
118
if (anno != NULL) {
119
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
120
}
121
if (type_anno != NULL) {
122
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
123
}
124
}
125
}
126
127
// Write Code attribute
128
// JVMSpec| Code_attribute {
129
// JVMSpec| u2 attribute_name_index;
130
// JVMSpec| u4 attribute_length;
131
// JVMSpec| u2 max_stack;
132
// JVMSpec| u2 max_locals;
133
// JVMSpec| u4 code_length;
134
// JVMSpec| u1 code[code_length];
135
// JVMSpec| u2 exception_table_length;
136
// JVMSpec| { u2 start_pc;
137
// JVMSpec| u2 end_pc;
138
// JVMSpec| u2 handler_pc;
139
// JVMSpec| u2 catch_type;
140
// JVMSpec| } exception_table[exception_table_length];
141
// JVMSpec| u2 attributes_count;
142
// JVMSpec| attribute_info attributes[attributes_count];
143
// JVMSpec| }
144
void JvmtiClassFileReconstituter::write_code_attribute(const methodHandle& method) {
145
ConstMethod* const_method = method->constMethod();
146
u2 line_num_cnt = 0;
147
int stackmap_len = 0;
148
int local_variable_table_length = 0;
149
int local_variable_type_table_length = 0;
150
151
// compute number and length of attributes
152
int attr_count = 0;
153
int attr_size = 0;
154
if (const_method->has_linenumber_table()) {
155
line_num_cnt = line_number_table_entries(method);
156
if (line_num_cnt != 0) {
157
++attr_count;
158
// Compute the complete size of the line number table attribute:
159
// LineNumberTable_attribute {
160
// u2 attribute_name_index;
161
// u4 attribute_length;
162
// u2 line_number_table_length;
163
// { u2 start_pc;
164
// u2 line_number;
165
// } line_number_table[line_number_table_length];
166
// }
167
attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2);
168
}
169
}
170
if (method->has_stackmap_table()) {
171
stackmap_len = method->stackmap_data()->length();
172
if (stackmap_len != 0) {
173
++attr_count;
174
// Compute the size of the stack map table attribute (VM stores raw):
175
// StackMapTable_attribute {
176
// u2 attribute_name_index;
177
// u4 attribute_length;
178
// u2 number_of_entries;
179
// stack_map_frame_entries[number_of_entries];
180
// }
181
attr_size += 2 + 4 + stackmap_len;
182
}
183
}
184
if (method->has_localvariable_table()) {
185
local_variable_table_length = method->localvariable_table_length();
186
if (local_variable_table_length != 0) {
187
++attr_count;
188
// Compute the size of the local variable table attribute (VM stores raw):
189
// LocalVariableTable_attribute {
190
// u2 attribute_name_index;
191
// u4 attribute_length;
192
// u2 local_variable_table_length;
193
// {
194
// u2 start_pc;
195
// u2 length;
196
// u2 name_index;
197
// u2 descriptor_index;
198
// u2 index;
199
// }
200
attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
201
202
// Local variables with generic signatures must have LVTT entries
203
LocalVariableTableElement *elem = method->localvariable_table_start();
204
for (int idx = 0; idx < local_variable_table_length; idx++) {
205
if (elem[idx].signature_cp_index != 0) {
206
local_variable_type_table_length++;
207
}
208
}
209
210
if (local_variable_type_table_length != 0) {
211
++attr_count;
212
// Compute the size of the local variable type table attribute (VM stores raw):
213
// LocalVariableTypeTable_attribute {
214
// u2 attribute_name_index;
215
// u4 attribute_length;
216
// u2 local_variable_type_table_length;
217
// {
218
// u2 start_pc;
219
// u2 length;
220
// u2 name_index;
221
// u2 signature_index;
222
// u2 index;
223
// }
224
attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2);
225
}
226
}
227
}
228
229
ExceptionTable exception_table(method());
230
int exception_table_length = exception_table.length();
231
int code_size = const_method->code_size();
232
int size =
233
2+2+4 + // max_stack, max_locals, code_length
234
code_size + // code
235
2 + // exception_table_length
236
(2+2+2+2) * exception_table_length + // exception_table
237
2 + // attributes_count
238
attr_size; // attributes
239
240
write_attribute_name_index("Code");
241
write_u4(size);
242
write_u2(method->verifier_max_stack());
243
write_u2(method->max_locals());
244
write_u4(code_size);
245
copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
246
write_u2(exception_table_length);
247
for (int index = 0; index < exception_table_length; index++) {
248
write_u2(exception_table.start_pc(index));
249
write_u2(exception_table.end_pc(index));
250
write_u2(exception_table.handler_pc(index));
251
write_u2(exception_table.catch_type_index(index));
252
}
253
write_u2(attr_count);
254
if (line_num_cnt != 0) {
255
write_line_number_table_attribute(method, line_num_cnt);
256
}
257
if (stackmap_len != 0) {
258
write_stackmap_table_attribute(method, stackmap_len);
259
}
260
if (local_variable_table_length != 0) {
261
write_local_variable_table_attribute(method, local_variable_table_length);
262
}
263
if (local_variable_type_table_length != 0) {
264
write_local_variable_type_table_attribute(method, local_variable_type_table_length);
265
}
266
}
267
268
// Write Exceptions attribute
269
// JVMSpec| Exceptions_attribute {
270
// JVMSpec| u2 attribute_name_index;
271
// JVMSpec| u4 attribute_length;
272
// JVMSpec| u2 number_of_exceptions;
273
// JVMSpec| u2 exception_index_table[number_of_exceptions];
274
// JVMSpec| }
275
void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) {
276
CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start();
277
int checked_exceptions_length = const_method->checked_exceptions_length();
278
int size =
279
2 + // number_of_exceptions
280
2 * checked_exceptions_length; // exception_index_table
281
282
write_attribute_name_index("Exceptions");
283
write_u4(size);
284
write_u2(checked_exceptions_length);
285
for (int index = 0; index < checked_exceptions_length; index++) {
286
write_u2(checked_exceptions[index].class_cp_index);
287
}
288
}
289
290
// Write SourceFile attribute
291
// JVMSpec| SourceFile_attribute {
292
// JVMSpec| u2 attribute_name_index;
293
// JVMSpec| u4 attribute_length;
294
// JVMSpec| u2 sourcefile_index;
295
// JVMSpec| }
296
void JvmtiClassFileReconstituter::write_source_file_attribute() {
297
assert(ik()->source_file_name() != NULL, "caller must check");
298
299
write_attribute_name_index("SourceFile");
300
write_u4(2); // always length 2
301
write_u2(symbol_to_cpool_index(ik()->source_file_name()));
302
}
303
304
// Write SourceDebugExtension attribute
305
// JSR45| SourceDebugExtension_attribute {
306
// JSR45| u2 attribute_name_index;
307
// JSR45| u4 attribute_length;
308
// JSR45| u1 debug_extension[attribute_length];
309
// JSR45| }
310
void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
311
assert(ik()->source_debug_extension() != NULL, "caller must check");
312
313
write_attribute_name_index("SourceDebugExtension");
314
int len = (int)strlen(ik()->source_debug_extension());
315
write_u4(len);
316
u1* ext = (u1*)ik()->source_debug_extension();
317
for (int i=0; i<len; i++) {
318
write_u1(ext[i]);
319
}
320
}
321
322
// Write (generic) Signature attribute
323
// JVMSpec| Signature_attribute {
324
// JVMSpec| u2 attribute_name_index;
325
// JVMSpec| u4 attribute_length;
326
// JVMSpec| u2 signature_index;
327
// JVMSpec| }
328
void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) {
329
write_attribute_name_index("Signature");
330
write_u4(2); // always length 2
331
write_u2(generic_signature_index);
332
}
333
334
// Compute the number of entries in the InnerClasses attribute
335
u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
336
InnerClassesIterator iter(ik());
337
return iter.length();
338
}
339
340
// Write an annotation attribute. The VM stores them in raw form, so all we need
341
// to do is add the attrubute name and fill in the length.
342
// JSR202| *Annotations_attribute {
343
// JSR202| u2 attribute_name_index;
344
// JSR202| u4 attribute_length;
345
// JSR202| ...
346
// JSR202| }
347
void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,
348
AnnotationArray* annos) {
349
u4 length = annos->length();
350
write_attribute_name_index(attr_name);
351
write_u4(length);
352
memcpy(writeable_address(length), annos->adr_at(0), length);
353
}
354
355
// BootstrapMethods_attribute {
356
// u2 attribute_name_index;
357
// u4 attribute_length;
358
// u2 num_bootstrap_methods;
359
// { u2 bootstrap_method_ref;
360
// u2 num_bootstrap_arguments;
361
// u2 bootstrap_arguments[num_bootstrap_arguments];
362
// } bootstrap_methods[num_bootstrap_methods];
363
// }
364
void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
365
Array<u2>* operands = cpool()->operands();
366
write_attribute_name_index("BootstrapMethods");
367
int num_bootstrap_methods = ConstantPool::operand_array_length(operands);
368
369
// calculate length of attribute
370
int length = sizeof(u2); // num_bootstrap_methods
371
for (int n = 0; n < num_bootstrap_methods; n++) {
372
u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
373
length += sizeof(u2); // bootstrap_method_ref
374
length += sizeof(u2); // num_bootstrap_arguments
375
length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
376
}
377
write_u4(length);
378
379
// write attribute
380
write_u2(num_bootstrap_methods);
381
for (int n = 0; n < num_bootstrap_methods; n++) {
382
u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
383
u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
384
write_u2(bootstrap_method_ref);
385
write_u2(num_bootstrap_arguments);
386
for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
387
u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
388
write_u2(bootstrap_argument);
389
}
390
}
391
}
392
393
// NestHost_attribute {
394
// u2 attribute_name_index;
395
// u4 attribute_length;
396
// u2 host_class_index;
397
// }
398
void JvmtiClassFileReconstituter::write_nest_host_attribute() {
399
int length = sizeof(u2);
400
int host_class_index = ik()->nest_host_index();
401
402
write_attribute_name_index("NestHost");
403
write_u4(length);
404
write_u2(host_class_index);
405
}
406
407
// NestMembers_attribute {
408
// u2 attribute_name_index;
409
// u4 attribute_length;
410
// u2 number_of_classes;
411
// u2 classes[number_of_classes];
412
// }
413
void JvmtiClassFileReconstituter::write_nest_members_attribute() {
414
Array<u2>* nest_members = ik()->nest_members();
415
int number_of_classes = nest_members->length();
416
int length = sizeof(u2) * (1 + number_of_classes);
417
418
write_attribute_name_index("NestMembers");
419
write_u4(length);
420
write_u2(number_of_classes);
421
for (int i = 0; i < number_of_classes; i++) {
422
u2 class_cp_index = nest_members->at(i);
423
write_u2(class_cp_index);
424
}
425
}
426
427
// PermittedSubclasses {
428
// u2 attribute_name_index;
429
// u4 attribute_length;
430
// u2 number_of_classes;
431
// u2 classes[number_of_classes];
432
// }
433
void JvmtiClassFileReconstituter::write_permitted_subclasses_attribute() {
434
Array<u2>* permitted_subclasses = ik()->permitted_subclasses();
435
int number_of_classes = permitted_subclasses->length();
436
int length = sizeof(u2) * (1 + number_of_classes); // '1 +' is for number_of_classes field
437
438
write_attribute_name_index("PermittedSubclasses");
439
write_u4(length);
440
write_u2(number_of_classes);
441
for (int i = 0; i < number_of_classes; i++) {
442
u2 class_cp_index = permitted_subclasses->at(i);
443
write_u2(class_cp_index);
444
}
445
}
446
447
// Record {
448
// u2 attribute_name_index;
449
// u4 attribute_length;
450
// u2 components_count;
451
// component_info components[components_count];
452
// }
453
// component_info {
454
// u2 name_index;
455
// u2 descriptor_index
456
// u2 attributes_count;
457
// attribute_info_attributes[attributes_count];
458
// }
459
void JvmtiClassFileReconstituter::write_record_attribute() {
460
Array<RecordComponent*>* components = ik()->record_components();
461
int number_of_components = components->length();
462
463
// Each component has a u2 for name, descr, attribute count
464
int length = sizeof(u2) + (sizeof(u2) * 3 * number_of_components);
465
for (int x = 0; x < number_of_components; x++) {
466
RecordComponent* component = components->at(x);
467
if (component->generic_signature_index() != 0) {
468
length += 8; // Signature attribute size
469
assert(component->attributes_count() > 0, "Bad component attributes count");
470
}
471
if (component->annotations() != NULL) {
472
length += 6 + component->annotations()->length();
473
}
474
if (component->type_annotations() != NULL) {
475
length += 6 + component->type_annotations()->length();
476
}
477
}
478
479
write_attribute_name_index("Record");
480
write_u4(length);
481
write_u2(number_of_components);
482
for (int i = 0; i < number_of_components; i++) {
483
RecordComponent* component = components->at(i);
484
write_u2(component->name_index());
485
write_u2(component->descriptor_index());
486
write_u2(component->attributes_count());
487
if (component->generic_signature_index() != 0) {
488
write_signature_attribute(component->generic_signature_index());
489
}
490
if (component->annotations() != NULL) {
491
write_annotations_attribute("RuntimeVisibleAnnotations", component->annotations());
492
}
493
if (component->type_annotations() != NULL) {
494
write_annotations_attribute("RuntimeVisibleTypeAnnotations", component->type_annotations());
495
}
496
}
497
}
498
499
// Write InnerClasses attribute
500
// JVMSpec| InnerClasses_attribute {
501
// JVMSpec| u2 attribute_name_index;
502
// JVMSpec| u4 attribute_length;
503
// JVMSpec| u2 number_of_classes;
504
// JVMSpec| { u2 inner_class_info_index;
505
// JVMSpec| u2 outer_class_info_index;
506
// JVMSpec| u2 inner_name_index;
507
// JVMSpec| u2 inner_class_access_flags;
508
// JVMSpec| } classes[number_of_classes];
509
// JVMSpec| }
510
void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
511
InnerClassesIterator iter(ik());
512
guarantee(iter.length() != 0 && iter.length() == length,
513
"caller must check");
514
u2 entry_count = length / InstanceKlass::inner_class_next_offset;
515
u4 size = 2 + entry_count * (2+2+2+2);
516
517
write_attribute_name_index("InnerClasses");
518
write_u4(size);
519
write_u2(entry_count);
520
for (; !iter.done(); iter.next()) {
521
write_u2(iter.inner_class_info_index());
522
write_u2(iter.outer_class_info_index());
523
write_u2(iter.inner_name_index());
524
write_u2(iter.inner_access_flags());
525
}
526
}
527
528
// Write Synthetic attribute
529
// JVMSpec| Synthetic_attribute {
530
// JVMSpec| u2 attribute_name_index;
531
// JVMSpec| u4 attribute_length;
532
// JVMSpec| }
533
void JvmtiClassFileReconstituter::write_synthetic_attribute() {
534
write_attribute_name_index("Synthetic");
535
write_u4(0); //length always zero
536
}
537
538
// Compute size of LineNumberTable
539
u2 JvmtiClassFileReconstituter::line_number_table_entries(const methodHandle& method) {
540
// The line number table is compressed so we don't know how big it is until decompressed.
541
// Decompression is really fast so we just do it twice.
542
u2 num_entries = 0;
543
CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
544
while (stream.read_pair()) {
545
num_entries++;
546
}
547
return num_entries;
548
}
549
550
// Write LineNumberTable attribute
551
// JVMSpec| LineNumberTable_attribute {
552
// JVMSpec| u2 attribute_name_index;
553
// JVMSpec| u4 attribute_length;
554
// JVMSpec| u2 line_number_table_length;
555
// JVMSpec| { u2 start_pc;
556
// JVMSpec| u2 line_number;
557
// JVMSpec| } line_number_table[line_number_table_length];
558
// JVMSpec| }
559
void JvmtiClassFileReconstituter::write_line_number_table_attribute(const methodHandle& method,
560
u2 num_entries) {
561
562
write_attribute_name_index("LineNumberTable");
563
write_u4(2 + num_entries * (2 + 2));
564
write_u2(num_entries);
565
566
CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
567
while (stream.read_pair()) {
568
write_u2(stream.bci());
569
write_u2(stream.line());
570
}
571
}
572
573
// Write LocalVariableTable attribute
574
// JVMSpec| LocalVariableTable_attribute {
575
// JVMSpec| u2 attribute_name_index;
576
// JVMSpec| u4 attribute_length;
577
// JVMSpec| u2 local_variable_table_length;
578
// JVMSpec| { u2 start_pc;
579
// JVMSpec| u2 length;
580
// JVMSpec| u2 name_index;
581
// JVMSpec| u2 descriptor_index;
582
// JVMSpec| u2 index;
583
// JVMSpec| } local_variable_table[local_variable_table_length];
584
// JVMSpec| }
585
void JvmtiClassFileReconstituter::write_local_variable_table_attribute(const methodHandle& method, u2 num_entries) {
586
write_attribute_name_index("LocalVariableTable");
587
write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
588
write_u2(num_entries);
589
590
assert(method->localvariable_table_length() == num_entries, "just checking");
591
592
LocalVariableTableElement *elem = method->localvariable_table_start();
593
for (int j=0; j<method->localvariable_table_length(); j++) {
594
write_u2(elem->start_bci);
595
write_u2(elem->length);
596
write_u2(elem->name_cp_index);
597
write_u2(elem->descriptor_cp_index);
598
write_u2(elem->slot);
599
elem++;
600
}
601
}
602
603
// Write LocalVariableTypeTable attribute
604
// JVMSpec| LocalVariableTypeTable_attribute {
605
// JVMSpec| u2 attribute_name_index;
606
// JVMSpec| u4 attribute_length;
607
// JVMSpec| u2 local_variable_type_table_length;
608
// JVMSpec| { u2 start_pc;
609
// JVMSpec| u2 length;
610
// JVMSpec| u2 name_index;
611
// JVMSpec| u2 signature_index;
612
// JVMSpec| u2 index;
613
// JVMSpec| } local_variable_type_table[local_variable_type_table_length];
614
// JVMSpec| }
615
void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries) {
616
write_attribute_name_index("LocalVariableTypeTable");
617
write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
618
write_u2(num_entries);
619
620
LocalVariableTableElement *elem = method->localvariable_table_start();
621
for (int j=0; j<method->localvariable_table_length(); j++) {
622
if (elem->signature_cp_index > 0) {
623
// Local variable has a generic signature - write LVTT attribute entry
624
write_u2(elem->start_bci);
625
write_u2(elem->length);
626
write_u2(elem->name_cp_index);
627
write_u2(elem->signature_cp_index);
628
write_u2(elem->slot);
629
num_entries--;
630
}
631
elem++;
632
}
633
assert(num_entries == 0, "just checking");
634
}
635
636
// Write stack map table attribute
637
// JSR-202| StackMapTable_attribute {
638
// JSR-202| u2 attribute_name_index;
639
// JSR-202| u4 attribute_length;
640
// JSR-202| u2 number_of_entries;
641
// JSR-202| stack_map_frame_entries[number_of_entries];
642
// JSR-202| }
643
void JvmtiClassFileReconstituter::write_stackmap_table_attribute(const methodHandle& method,
644
int stackmap_len) {
645
646
write_attribute_name_index("StackMapTable");
647
write_u4(stackmap_len);
648
memcpy(
649
writeable_address(stackmap_len),
650
(void*)(method->stackmap_data()->adr_at(0)),
651
stackmap_len);
652
}
653
654
// Write one method_info structure
655
// JVMSpec| method_info {
656
// JVMSpec| u2 access_flags;
657
// JVMSpec| u2 name_index;
658
// JVMSpec| u2 descriptor_index;
659
// JVMSpec| u2 attributes_count;
660
// JVMSpec| attribute_info attributes[attributes_count];
661
// JVMSpec| }
662
void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) {
663
AccessFlags access_flags = method->access_flags();
664
ConstMethod* const_method = method->constMethod();
665
u2 generic_signature_index = const_method->generic_signature_index();
666
AnnotationArray* anno = method->annotations();
667
AnnotationArray* param_anno = method->parameter_annotations();
668
AnnotationArray* default_anno = method->annotation_default();
669
AnnotationArray* type_anno = method->type_annotations();
670
671
// skip generated default interface methods
672
if (method->is_overpass()) {
673
return;
674
}
675
676
write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
677
write_u2(const_method->name_index());
678
write_u2(const_method->signature_index());
679
680
// write attributes in the same order javac does, so we can test with byte for
681
// byte comparison
682
int attr_count = 0;
683
if (const_method->code_size() != 0) {
684
++attr_count; // has Code attribute
685
}
686
if (const_method->has_checked_exceptions()) {
687
++attr_count; // has Exceptions attribute
688
}
689
if (default_anno != NULL) {
690
++attr_count; // has AnnotationDefault attribute
691
}
692
// Deprecated attribute would go here
693
if (access_flags.is_synthetic()) { // FIXME
694
// ++attr_count;
695
}
696
if (generic_signature_index != 0) {
697
++attr_count;
698
}
699
if (anno != NULL) {
700
++attr_count; // has RuntimeVisibleAnnotations attribute
701
}
702
if (param_anno != NULL) {
703
++attr_count; // has RuntimeVisibleParameterAnnotations attribute
704
}
705
if (type_anno != NULL) {
706
++attr_count; // has RuntimeVisibleTypeAnnotations attribute
707
}
708
709
write_u2(attr_count);
710
if (const_method->code_size() > 0) {
711
write_code_attribute(method);
712
}
713
if (const_method->has_checked_exceptions()) {
714
write_exceptions_attribute(const_method);
715
}
716
if (default_anno != NULL) {
717
write_annotations_attribute("AnnotationDefault", default_anno);
718
}
719
// Deprecated attribute would go here
720
if (access_flags.is_synthetic()) {
721
// write_synthetic_attribute();
722
}
723
if (generic_signature_index != 0) {
724
write_signature_attribute(generic_signature_index);
725
}
726
if (anno != NULL) {
727
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
728
}
729
if (param_anno != NULL) {
730
write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
731
}
732
if (type_anno != NULL) {
733
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
734
}
735
}
736
737
// Write the class attributes portion of ClassFile structure
738
// JVMSpec| u2 attributes_count;
739
// JVMSpec| attribute_info attributes[attributes_count];
740
void JvmtiClassFileReconstituter::write_class_attributes() {
741
u2 inner_classes_length = inner_classes_attribute_length();
742
Symbol* generic_signature = ik()->generic_signature();
743
AnnotationArray* anno = ik()->class_annotations();
744
AnnotationArray* type_anno = ik()->class_type_annotations();
745
746
int attr_count = 0;
747
if (generic_signature != NULL) {
748
++attr_count;
749
}
750
if (ik()->source_file_name() != NULL) {
751
++attr_count;
752
}
753
if (ik()->source_debug_extension() != NULL) {
754
++attr_count;
755
}
756
if (inner_classes_length > 0) {
757
++attr_count;
758
}
759
if (anno != NULL) {
760
++attr_count; // has RuntimeVisibleAnnotations attribute
761
}
762
if (type_anno != NULL) {
763
++attr_count; // has RuntimeVisibleTypeAnnotations attribute
764
}
765
if (cpool()->operands() != NULL) {
766
++attr_count;
767
}
768
if (ik()->nest_host_index() != 0) {
769
++attr_count;
770
}
771
if (ik()->nest_members() != Universe::the_empty_short_array()) {
772
++attr_count;
773
}
774
if (ik()->permitted_subclasses() != Universe::the_empty_short_array()) {
775
++attr_count;
776
}
777
if (ik()->record_components() != NULL) {
778
++attr_count;
779
}
780
781
write_u2(attr_count);
782
783
if (generic_signature != NULL) {
784
write_signature_attribute(symbol_to_cpool_index(generic_signature));
785
}
786
if (ik()->source_file_name() != NULL) {
787
write_source_file_attribute();
788
}
789
if (ik()->source_debug_extension() != NULL) {
790
write_source_debug_extension_attribute();
791
}
792
if (anno != NULL) {
793
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
794
}
795
if (type_anno != NULL) {
796
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
797
}
798
if (ik()->nest_host_index() != 0) {
799
write_nest_host_attribute();
800
}
801
if (ik()->nest_members() != Universe::the_empty_short_array()) {
802
write_nest_members_attribute();
803
}
804
if (ik()->permitted_subclasses() != Universe::the_empty_short_array()) {
805
write_permitted_subclasses_attribute();
806
}
807
if (ik()->record_components() != NULL) {
808
write_record_attribute();
809
}
810
if (cpool()->operands() != NULL) {
811
write_bootstrapmethod_attribute();
812
}
813
if (inner_classes_length > 0) {
814
write_inner_classes_attribute(inner_classes_length);
815
}
816
}
817
818
// Write the method information portion of ClassFile structure
819
// JVMSpec| u2 methods_count;
820
// JVMSpec| method_info methods[methods_count];
821
void JvmtiClassFileReconstituter::write_method_infos() {
822
HandleMark hm(thread());
823
Array<Method*>* methods = ik()->methods();
824
int num_methods = methods->length();
825
int num_overpass = 0;
826
827
// count the generated default interface methods
828
// these will not be re-created by write_method_info
829
// and should not be included in the total count
830
for (int index = 0; index < num_methods; index++) {
831
Method* method = methods->at(index);
832
if (method->is_overpass()) {
833
num_overpass++;
834
}
835
}
836
837
write_u2(num_methods - num_overpass);
838
if (JvmtiExport::can_maintain_original_method_order()) {
839
int index;
840
int original_index;
841
intArray method_order(num_methods, num_methods, 0);
842
843
// invert the method order mapping
844
for (index = 0; index < num_methods; index++) {
845
original_index = ik()->method_ordering()->at(index);
846
assert(original_index >= 0 && original_index < num_methods,
847
"invalid original method index");
848
method_order.at_put(original_index, index);
849
}
850
851
// write in original order
852
for (original_index = 0; original_index < num_methods; original_index++) {
853
index = method_order.at(original_index);
854
methodHandle method(thread(), methods->at(index));
855
write_method_info(method);
856
}
857
} else {
858
// method order not preserved just dump the method infos
859
for (int index = 0; index < num_methods; index++) {
860
methodHandle method(thread(), methods->at(index));
861
write_method_info(method);
862
}
863
}
864
}
865
866
void JvmtiClassFileReconstituter::write_class_file_format() {
867
ReallocMark();
868
869
// JVMSpec| ClassFile {
870
// JVMSpec| u4 magic;
871
write_u4(0xCAFEBABE);
872
873
// JVMSpec| u2 minor_version;
874
// JVMSpec| u2 major_version;
875
write_u2(ik()->minor_version());
876
u2 major = ik()->major_version();
877
write_u2(major);
878
879
// JVMSpec| u2 constant_pool_count;
880
// JVMSpec| cp_info constant_pool[constant_pool_count-1];
881
write_u2(cpool()->length());
882
copy_cpool_bytes(writeable_address(cpool_size()));
883
884
// JVMSpec| u2 access_flags;
885
write_u2(ik()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS);
886
887
// JVMSpec| u2 this_class;
888
// JVMSpec| u2 super_class;
889
write_u2(class_symbol_to_cpool_index(ik()->name()));
890
Klass* super_class = ik()->super();
891
write_u2(super_class == NULL? 0 : // zero for java.lang.Object
892
class_symbol_to_cpool_index(super_class->name()));
893
894
// JVMSpec| u2 interfaces_count;
895
// JVMSpec| u2 interfaces[interfaces_count];
896
Array<InstanceKlass*>* interfaces = ik()->local_interfaces();
897
int num_interfaces = interfaces->length();
898
write_u2(num_interfaces);
899
for (int index = 0; index < num_interfaces; index++) {
900
HandleMark hm(thread());
901
InstanceKlass* iik = interfaces->at(index);
902
write_u2(class_symbol_to_cpool_index(iik->name()));
903
}
904
905
// JVMSpec| u2 fields_count;
906
// JVMSpec| field_info fields[fields_count];
907
write_field_infos();
908
909
// JVMSpec| u2 methods_count;
910
// JVMSpec| method_info methods[methods_count];
911
write_method_infos();
912
913
// JVMSpec| u2 attributes_count;
914
// JVMSpec| attribute_info attributes[attributes_count];
915
// JVMSpec| } /* end ClassFile 8?
916
write_class_attributes();
917
}
918
919
address JvmtiClassFileReconstituter::writeable_address(size_t size) {
920
size_t used_size = _buffer_ptr - _buffer;
921
if (size + used_size >= _buffer_size) {
922
// compute the new buffer size: must be at least twice as big as before
923
// plus whatever new is being used; then convert to nice clean block boundary
924
size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size
925
* initial_buffer_size;
926
927
// VM goes belly-up if the memory isn't available, so cannot do OOM processing
928
_buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size);
929
_buffer_size = new_buffer_size;
930
_buffer_ptr = _buffer + used_size;
931
}
932
u1* ret_ptr = _buffer_ptr;
933
_buffer_ptr += size;
934
return ret_ptr;
935
}
936
937
void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) {
938
TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name));
939
assert(sym != NULL, "attribute name symbol not found");
940
u2 attr_name_index = symbol_to_cpool_index(sym);
941
assert(attr_name_index != 0, "attribute name symbol not in constant pool");
942
write_u2(attr_name_index);
943
}
944
945
void JvmtiClassFileReconstituter::write_u1(u1 x) {
946
*writeable_address(1) = x;
947
}
948
949
void JvmtiClassFileReconstituter::write_u2(u2 x) {
950
Bytes::put_Java_u2(writeable_address(2), x);
951
}
952
953
void JvmtiClassFileReconstituter::write_u4(u4 x) {
954
Bytes::put_Java_u4(writeable_address(4), x);
955
}
956
957
void JvmtiClassFileReconstituter::write_u8(u8 x) {
958
Bytes::put_Java_u8(writeable_address(8), x);
959
}
960
961
void JvmtiClassFileReconstituter::copy_bytecodes(const methodHandle& mh,
962
unsigned char* bytecodes) {
963
// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes
964
// and the breakpoint bytecode are converted to their original bytecodes.
965
966
BytecodeStream bs(mh);
967
968
unsigned char* p = bytecodes;
969
Bytecodes::Code code;
970
bool is_rewritten = mh->method_holder()->is_rewritten();
971
972
while ((code = bs.next()) >= 0) {
973
assert(Bytecodes::is_java_code(code), "sanity check");
974
assert(code != Bytecodes::_breakpoint, "sanity check");
975
976
// length of bytecode (mnemonic + operands)
977
address bcp = bs.bcp();
978
int len = bs.instruction_size();
979
assert(len > 0, "length must be > 0");
980
981
// copy the bytecodes
982
*p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code);
983
if (len > 1) {
984
memcpy(p+1, bcp+1, len-1);
985
}
986
987
// During linking the get/put and invoke instructions are rewritten
988
// with an index into the constant pool cache. The original constant
989
// pool index must be returned to caller. Rewrite the index.
990
if (is_rewritten && len > 1) {
991
bool is_wide = false;
992
switch (code) {
993
case Bytecodes::_getstatic : // fall through
994
case Bytecodes::_putstatic : // fall through
995
case Bytecodes::_getfield : // fall through
996
case Bytecodes::_putfield : // fall through
997
case Bytecodes::_invokevirtual : // fall through
998
case Bytecodes::_invokespecial : // fall through
999
case Bytecodes::_invokestatic : // fall through
1000
case Bytecodes::_invokedynamic : // fall through
1001
case Bytecodes::_invokeinterface : {
1002
assert(len == 3 ||
1003
(code == Bytecodes::_invokeinterface && len == 5) ||
1004
(code == Bytecodes::_invokedynamic && len == 5),
1005
"sanity check");
1006
1007
int cpci = Bytes::get_native_u2(bcp+1);
1008
bool is_invokedynamic = (code == Bytecodes::_invokedynamic);
1009
ConstantPoolCacheEntry* entry;
1010
if (is_invokedynamic) {
1011
cpci = Bytes::get_native_u4(bcp+1);
1012
entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci);
1013
} else {
1014
// cache cannot be pre-fetched since some classes won't have it yet
1015
entry = mh->constants()->cache()->entry_at(cpci);
1016
}
1017
int i = entry->constant_pool_index();
1018
assert(i < mh->constants()->length(), "sanity check");
1019
Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering
1020
if (is_invokedynamic) *(p+3) = *(p+4) = 0;
1021
break;
1022
}
1023
case Bytecodes::_ldc_w:
1024
is_wide = true; // fall through
1025
case Bytecodes::_ldc: {
1026
if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) {
1027
int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1));
1028
int i = mh->constants()->object_to_cp_index(cpci);
1029
assert(i < mh->constants()->length(), "sanity check");
1030
if (is_wide) {
1031
Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering
1032
} else {
1033
*(p+1) = (u1)i;
1034
}
1035
}
1036
break;
1037
}
1038
default:
1039
break;
1040
}
1041
}
1042
1043
p += len;
1044
}
1045
}
1046
1047