Mercurial > hg > graal-jvmci-8
annotate src/share/vm/prims/jvmtiClassFileReconstituter.cpp @ 10241:d17700c82d7d
8006088: Incompatible heap size flags accepted by VM
Summary: Make processing of minimum, initial and maximum heap size more intiutive by removing previous limitations on allowed values, and make error reporting consistent. Further, fix errors in ergonomic heap sizing.
Reviewed-by: johnc, jwilhelm, tamao
author | tschatzl |
---|---|
date | Mon, 06 May 2013 17:19:42 +0200 |
parents | 8aaef2cee3b2 |
children | c456f4510385 |
rev | line source |
---|---|
0 | 1 /* |
5922
ff29ce866f23
7118280: The gbyc00102 JCK7 test causes an assert in JVM 7.0 fastdebug mode
dsamersoff
parents:
4718
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" | |
27 #include "interpreter/bytecodeStream.hpp" | |
3938 | 28 #include "oops/fieldStreams.hpp" |
1972 | 29 #include "prims/jvmtiClassFileReconstituter.hpp" |
30 #include "runtime/signature.hpp" | |
31 #ifdef TARGET_ARCH_x86 | |
32 # include "bytes_x86.hpp" | |
33 #endif | |
34 #ifdef TARGET_ARCH_sparc | |
35 # include "bytes_sparc.hpp" | |
36 #endif | |
37 #ifdef TARGET_ARCH_zero | |
38 # include "bytes_zero.hpp" | |
39 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
40 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
41 # include "bytes_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
42 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
43 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
44 # include "bytes_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
45 #endif |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
46 // FIXME: add Deprecated attribute |
0 | 47 // FIXME: fix Synthetic attribute |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
48 // FIXME: per Serguei, add error return handling for ConstantPool::copy_cpool_bytes() |
0 | 49 |
50 | |
51 // Write the field information portion of ClassFile structure | |
52 // JVMSpec| u2 fields_count; | |
53 // JVMSpec| field_info fields[fields_count]; | |
54 void JvmtiClassFileReconstituter::write_field_infos() { | |
55 HandleMark hm(thread()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
56 Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations(); |
0 | 57 |
3938 | 58 // Compute the real number of Java fields |
59 int java_fields = ikh()->java_fields_count(); | |
60 | |
3944 | 61 write_u2(java_fields); |
3938 | 62 for (JavaFieldStream fs(ikh()); !fs.done(); fs.next()) { |
63 AccessFlags access_flags = fs.access_flags(); | |
64 int name_index = fs.name_index(); | |
65 int signature_index = fs.signature_index(); | |
66 int initial_value_index = fs.initval_index(); | |
0 | 67 guarantee(name_index != 0 && signature_index != 0, "bad constant pool index for field"); |
3938 | 68 // int offset = ikh()->field_offset( index ); |
69 int generic_signature_index = fs.generic_signature_index(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
70 AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); |
0 | 71 |
72 // JVMSpec| field_info { | |
73 // JVMSpec| u2 access_flags; | |
74 // JVMSpec| u2 name_index; | |
75 // JVMSpec| u2 descriptor_index; | |
76 // JVMSpec| u2 attributes_count; | |
77 // JVMSpec| attribute_info attributes[attributes_count]; | |
78 // JVMSpec| } | |
79 | |
3938 | 80 write_u2(access_flags.as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); |
0 | 81 write_u2(name_index); |
82 write_u2(signature_index); | |
83 int attr_count = 0; | |
84 if (initial_value_index != 0) { | |
85 ++attr_count; | |
86 } | |
87 if (access_flags.is_synthetic()) { | |
88 // ++attr_count; | |
89 } | |
90 if (generic_signature_index != 0) { | |
91 ++attr_count; | |
92 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
93 if (anno != NULL) { |
0 | 94 ++attr_count; // has RuntimeVisibleAnnotations attribute |
95 } | |
96 | |
97 write_u2(attr_count); | |
98 | |
99 if (initial_value_index != 0) { | |
100 write_attribute_name_index("ConstantValue"); | |
101 write_u4(2); //length always 2 | |
102 write_u2(initial_value_index); | |
103 } | |
104 if (access_flags.is_synthetic()) { | |
105 // write_synthetic_attribute(); | |
106 } | |
107 if (generic_signature_index != 0) { | |
108 write_signature_attribute(generic_signature_index); | |
109 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
110 if (anno != NULL) { |
0 | 111 write_annotations_attribute("RuntimeVisibleAnnotations", anno); |
112 } | |
113 } | |
114 } | |
115 | |
116 // Write Code attribute | |
117 // JVMSpec| Code_attribute { | |
118 // JVMSpec| u2 attribute_name_index; | |
119 // JVMSpec| u4 attribute_length; | |
120 // JVMSpec| u2 max_stack; | |
121 // JVMSpec| u2 max_locals; | |
122 // JVMSpec| u4 code_length; | |
123 // JVMSpec| u1 code[code_length]; | |
124 // JVMSpec| u2 exception_table_length; | |
125 // JVMSpec| { u2 start_pc; | |
126 // JVMSpec| u2 end_pc; | |
127 // JVMSpec| u2 handler_pc; | |
128 // JVMSpec| u2 catch_type; | |
129 // JVMSpec| } exception_table[exception_table_length]; | |
130 // JVMSpec| u2 attributes_count; | |
131 // JVMSpec| attribute_info attributes[attributes_count]; | |
132 // JVMSpec| } | |
133 void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
134 ConstMethod* const_method = method->constMethod(); |
0 | 135 u2 line_num_cnt = 0; |
136 int stackmap_len = 0; | |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
137 int local_variable_table_length = 0; |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
138 int local_variable_type_table_length = 0; |
0 | 139 |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
140 // compute number and length of attributes |
0 | 141 int attr_count = 0; |
142 int attr_size = 0; | |
143 if (const_method->has_linenumber_table()) { | |
144 line_num_cnt = line_number_table_entries(method); | |
145 if (line_num_cnt != 0) { | |
146 ++attr_count; | |
147 // Compute the complete size of the line number table attribute: | |
148 // LineNumberTable_attribute { | |
149 // u2 attribute_name_index; | |
150 // u4 attribute_length; | |
151 // u2 line_number_table_length; | |
152 // { u2 start_pc; | |
153 // u2 line_number; | |
154 // } line_number_table[line_number_table_length]; | |
155 // } | |
156 attr_size += 2 + 4 + 2 + line_num_cnt * (2 + 2); | |
157 } | |
158 } | |
159 if (method->has_stackmap_table()) { | |
160 stackmap_len = method->stackmap_data()->length(); | |
161 if (stackmap_len != 0) { | |
162 ++attr_count; | |
163 // Compute the size of the stack map table attribute (VM stores raw): | |
164 // StackMapTable_attribute { | |
165 // u2 attribute_name_index; | |
166 // u4 attribute_length; | |
167 // u2 number_of_entries; | |
168 // stack_map_frame_entries[number_of_entries]; | |
169 // } | |
170 attr_size += 2 + 4 + stackmap_len; | |
171 } | |
172 } | |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
173 if (method->has_localvariable_table()) { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
174 local_variable_table_length = method->localvariable_table_length(); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
175 if (local_variable_table_length != 0) { |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
176 ++attr_count; |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
177 // Compute the size of the local variable table attribute (VM stores raw): |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
178 // LocalVariableTable_attribute { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
179 // u2 attribute_name_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
180 // u4 attribute_length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
181 // u2 local_variable_table_length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
182 // { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
183 // u2 start_pc; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
184 // u2 length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
185 // u2 name_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
186 // u2 descriptor_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
187 // u2 index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
188 // } |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
189 attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2); |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
190 |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
191 // Local variables with generic signatures must have LVTT entries |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
192 LocalVariableTableElement *elem = method->localvariable_table_start(); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
193 for (int idx = 0; idx < local_variable_table_length; idx++) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
194 if (elem[idx].signature_cp_index != 0) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
195 local_variable_type_table_length++; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
196 } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
197 } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
198 |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
199 if (local_variable_type_table_length != 0) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
200 ++attr_count; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
201 // Compute the size of the local variable type table attribute (VM stores raw): |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
202 // LocalVariableTypeTable_attribute { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
203 // u2 attribute_name_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
204 // u4 attribute_length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
205 // u2 local_variable_type_table_length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
206 // { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
207 // u2 start_pc; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
208 // u2 length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
209 // u2 name_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
210 // u2 signature_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
211 // u2 index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
212 // } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
213 attr_size += 2 + 4 + 2 + local_variable_type_table_length * (2 + 2 + 2 + 2 + 2); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
214 } |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
215 } |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
216 } |
0 | 217 |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
218 ExceptionTable exception_table(method()); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
219 int exception_table_length = exception_table.length(); |
0 | 220 int code_size = const_method->code_size(); |
221 int size = | |
222 2+2+4 + // max_stack, max_locals, code_length | |
223 code_size + // code | |
224 2 + // exception_table_length | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
225 (2+2+2+2) * exception_table_length + // exception_table |
0 | 226 2 + // attributes_count |
227 attr_size; // attributes | |
228 | |
229 write_attribute_name_index("Code"); | |
230 write_u4(size); | |
6975
64812523d72e
7194607: VerifyLocalVariableTableOnRetransformTest.sh fails after JSR-292 merge
sspitsyn
parents:
6772
diff
changeset
|
231 write_u2(method->verifier_max_stack()); |
0 | 232 write_u2(method->max_locals()); |
233 write_u4(code_size); | |
234 copy_bytecodes(method, (unsigned char*)writeable_address(code_size)); | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
235 write_u2(exception_table_length); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
236 for (int index = 0; index < exception_table_length; index++) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
237 write_u2(exception_table.start_pc(index)); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
238 write_u2(exception_table.end_pc(index)); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
239 write_u2(exception_table.handler_pc(index)); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
240 write_u2(exception_table.catch_type_index(index)); |
0 | 241 } |
242 write_u2(attr_count); | |
243 if (line_num_cnt != 0) { | |
244 write_line_number_table_attribute(method, line_num_cnt); | |
245 } | |
246 if (stackmap_len != 0) { | |
247 write_stackmap_table_attribute(method, stackmap_len); | |
248 } | |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
249 if (local_variable_table_length != 0) { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
250 write_local_variable_table_attribute(method, local_variable_table_length); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
251 } |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
252 if (local_variable_type_table_length != 0) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
253 write_local_variable_type_table_attribute(method, local_variable_type_table_length); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
254 } |
0 | 255 } |
256 | |
257 // Write Exceptions attribute | |
258 // JVMSpec| Exceptions_attribute { | |
259 // JVMSpec| u2 attribute_name_index; | |
260 // JVMSpec| u4 attribute_length; | |
261 // JVMSpec| u2 number_of_exceptions; | |
262 // JVMSpec| u2 exception_index_table[number_of_exceptions]; | |
263 // JVMSpec| } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
264 void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_method) { |
0 | 265 CheckedExceptionElement* checked_exceptions = const_method->checked_exceptions_start(); |
266 int checked_exceptions_length = const_method->checked_exceptions_length(); | |
267 int size = | |
268 2 + // number_of_exceptions | |
269 2 * checked_exceptions_length; // exception_index_table | |
270 | |
271 write_attribute_name_index("Exceptions"); | |
272 write_u4(size); | |
273 write_u2(checked_exceptions_length); | |
274 for (int index = 0; index < checked_exceptions_length; index++) { | |
275 write_u2(checked_exceptions[index].class_cp_index); | |
276 } | |
277 } | |
278 | |
279 // Write SourceFile attribute | |
280 // JVMSpec| SourceFile_attribute { | |
281 // JVMSpec| u2 attribute_name_index; | |
282 // JVMSpec| u4 attribute_length; | |
283 // JVMSpec| u2 sourcefile_index; | |
284 // JVMSpec| } | |
285 void JvmtiClassFileReconstituter::write_source_file_attribute() { | |
286 assert(ikh()->source_file_name() != NULL, "caller must check"); | |
287 | |
288 write_attribute_name_index("SourceFile"); | |
289 write_u4(2); // always length 2 | |
290 write_u2(symbol_to_cpool_index(ikh()->source_file_name())); | |
291 } | |
292 | |
293 // Write SourceDebugExtension attribute | |
294 // JSR45| SourceDebugExtension_attribute { | |
295 // JSR45| u2 attribute_name_index; | |
296 // JSR45| u4 attribute_length; | |
6203
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
297 // JSR45| u1 debug_extension[attribute_length]; |
0 | 298 // JSR45| } |
299 void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() { | |
300 assert(ikh()->source_debug_extension() != NULL, "caller must check"); | |
301 | |
302 write_attribute_name_index("SourceDebugExtension"); | |
6203
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
303 int len = (int)strlen(ikh()->source_debug_extension()); |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
304 write_u4(len); |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
305 u1* ext = (u1*)ikh()->source_debug_extension(); |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
306 for (int i=0; i<len; i++) { |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
307 write_u1(ext[i]); |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
5967
diff
changeset
|
308 } |
0 | 309 } |
310 | |
311 // Write (generic) Signature attribute | |
312 // JVMSpec| Signature_attribute { | |
313 // JVMSpec| u2 attribute_name_index; | |
314 // JVMSpec| u4 attribute_length; | |
315 // JVMSpec| u2 signature_index; | |
316 // JVMSpec| } | |
317 void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature_index) { | |
318 write_attribute_name_index("Signature"); | |
319 write_u4(2); // always length 2 | |
320 write_u2(generic_signature_index); | |
321 } | |
322 | |
323 // Compute the number of entries in the InnerClasses attribute | |
324 u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() { | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
325 InnerClassesIterator iter(ikh()); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
326 return iter.length(); |
0 | 327 } |
328 | |
329 // Write an annotation attribute. The VM stores them in raw form, so all we need | |
330 // to do is add the attrubute name and fill in the length. | |
331 // JSR202| *Annotations_attribute { | |
332 // JSR202| u2 attribute_name_index; | |
333 // JSR202| u4 attribute_length; | |
334 // JSR202| ... | |
335 // JSR202| } | |
336 void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
337 AnnotationArray* annos) { |
0 | 338 u4 length = annos->length(); |
339 write_attribute_name_index(attr_name); | |
340 write_u4(length); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
341 memcpy(writeable_address(length), annos->adr_at(0), length); |
0 | 342 } |
343 | |
344 | |
345 // Write InnerClasses attribute | |
346 // JVMSpec| InnerClasses_attribute { | |
347 // JVMSpec| u2 attribute_name_index; | |
348 // JVMSpec| u4 attribute_length; | |
349 // JVMSpec| u2 number_of_classes; | |
350 // JVMSpec| { u2 inner_class_info_index; | |
351 // JVMSpec| u2 outer_class_info_index; | |
352 // JVMSpec| u2 inner_name_index; | |
353 // JVMSpec| u2 inner_class_access_flags; | |
354 // JVMSpec| } classes[number_of_classes]; | |
355 // JVMSpec| } | |
356 void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) { | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
357 InnerClassesIterator iter(ikh()); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
358 guarantee(iter.length() != 0 && iter.length() == length, |
0 | 359 "caller must check"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
360 u2 entry_count = length / InstanceKlass::inner_class_next_offset; |
0 | 361 u4 size = 2 + entry_count * (2+2+2+2); |
362 | |
363 write_attribute_name_index("InnerClasses"); | |
364 write_u4(size); | |
365 write_u2(entry_count); | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
366 for (; !iter.done(); iter.next()) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
367 write_u2(iter.inner_class_info_index()); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
368 write_u2(iter.outer_class_info_index()); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
369 write_u2(iter.inner_name_index()); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
5922
diff
changeset
|
370 write_u2(iter.inner_access_flags()); |
0 | 371 } |
372 } | |
373 | |
374 // Write Synthetic attribute | |
375 // JVMSpec| Synthetic_attribute { | |
376 // JVMSpec| u2 attribute_name_index; | |
377 // JVMSpec| u4 attribute_length; | |
378 // JVMSpec| } | |
379 void JvmtiClassFileReconstituter::write_synthetic_attribute() { | |
380 write_attribute_name_index("Synthetic"); | |
381 write_u4(0); //length always zero | |
382 } | |
383 | |
384 // Compute size of LineNumberTable | |
385 u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) { | |
386 // The line number table is compressed so we don't know how big it is until decompressed. | |
387 // Decompression is really fast so we just do it twice. | |
388 u2 num_entries = 0; | |
389 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); | |
390 while (stream.read_pair()) { | |
391 num_entries++; | |
392 } | |
393 return num_entries; | |
394 } | |
395 | |
396 // Write LineNumberTable attribute | |
397 // JVMSpec| LineNumberTable_attribute { | |
398 // JVMSpec| u2 attribute_name_index; | |
399 // JVMSpec| u4 attribute_length; | |
400 // JVMSpec| u2 line_number_table_length; | |
401 // JVMSpec| { u2 start_pc; | |
402 // JVMSpec| u2 line_number; | |
403 // JVMSpec| } line_number_table[line_number_table_length]; | |
404 // JVMSpec| } | |
405 void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method, | |
406 u2 num_entries) { | |
407 | |
408 write_attribute_name_index("LineNumberTable"); | |
409 write_u4(2 + num_entries * (2 + 2)); | |
410 write_u2(num_entries); | |
411 | |
412 CompressedLineNumberReadStream stream(method->compressed_linenumber_table()); | |
413 while (stream.read_pair()) { | |
414 write_u2(stream.bci()); | |
415 write_u2(stream.line()); | |
416 } | |
417 } | |
418 | |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
419 // Write LocalVariableTable attribute |
4718
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
420 // JVMSpec| LocalVariableTable_attribute { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
421 // JVMSpec| u2 attribute_name_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
422 // JVMSpec| u4 attribute_length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
423 // JVMSpec| u2 local_variable_table_length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
424 // JVMSpec| { u2 start_pc; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
425 // JVMSpec| u2 length; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
426 // JVMSpec| u2 name_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
427 // JVMSpec| u2 descriptor_index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
428 // JVMSpec| u2 index; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
429 // JVMSpec| } local_variable_table[local_variable_table_length]; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
430 // JVMSpec| } |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
431 void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
432 write_attribute_name_index("LocalVariableTable"); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
433 write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2)); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
434 write_u2(num_entries); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
435 |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
436 assert(method->localvariable_table_length() == num_entries, "just checking"); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
437 |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
438 LocalVariableTableElement *elem = method->localvariable_table_start(); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
439 for (int j=0; j<method->localvariable_table_length(); j++) { |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
440 write_u2(elem->start_bci); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
441 write_u2(elem->length); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
442 write_u2(elem->name_cp_index); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
443 write_u2(elem->descriptor_cp_index); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
444 write_u2(elem->slot); |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
445 elem++; |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
446 } |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
447 } |
c01e115b095e
7064927: retransformClasses() does not pass in LocalVariableTable of a method
coleenp
parents:
3944
diff
changeset
|
448 |
6772
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
449 // Write LocalVariableTypeTable attribute |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
450 // JVMSpec| LocalVariableTypeTable_attribute { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
451 // JVMSpec| u2 attribute_name_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
452 // JVMSpec| u4 attribute_length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
453 // JVMSpec| u2 local_variable_type_table_length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
454 // JVMSpec| { u2 start_pc; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
455 // JVMSpec| u2 length; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
456 // JVMSpec| u2 name_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
457 // JVMSpec| u2 signature_index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
458 // JVMSpec| u2 index; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
459 // JVMSpec| } local_variable_type_table[local_variable_type_table_length]; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
460 // JVMSpec| } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
461 void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
462 write_attribute_name_index("LocalVariableTypeTable"); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
463 write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2)); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
464 write_u2(num_entries); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
465 |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
466 LocalVariableTableElement *elem = method->localvariable_table_start(); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
467 for (int j=0; j<method->localvariable_table_length(); j++) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
468 if (elem->signature_cp_index > 0) { |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
469 // Local variable has a generic signature - write LVTT attribute entry |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
470 write_u2(elem->start_bci); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
471 write_u2(elem->length); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
472 write_u2(elem->name_cp_index); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
473 write_u2(elem->signature_cp_index); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
474 write_u2(elem->slot); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
475 num_entries--; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
476 } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
477 elem++; |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
478 } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
479 assert(num_entries == 0, "just checking"); |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
480 } |
1cb8583c3da8
7191786: retransformClasses() does not pass in LocalVariableTypeTable of a method
minqi
parents:
6725
diff
changeset
|
481 |
0 | 482 // Write stack map table attribute |
483 // JSR-202| StackMapTable_attribute { | |
484 // JSR-202| u2 attribute_name_index; | |
485 // JSR-202| u4 attribute_length; | |
486 // JSR-202| u2 number_of_entries; | |
487 // JSR-202| stack_map_frame_entries[number_of_entries]; | |
488 // JSR-202| } | |
489 void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method, | |
490 int stackmap_len) { | |
491 | |
492 write_attribute_name_index("StackMapTable"); | |
493 write_u4(stackmap_len); | |
494 memcpy( | |
495 writeable_address(stackmap_len), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
496 (void*)(method->stackmap_data()->adr_at(0)), |
0 | 497 stackmap_len); |
498 } | |
499 | |
500 // Write one method_info structure | |
501 // JVMSpec| method_info { | |
502 // JVMSpec| u2 access_flags; | |
503 // JVMSpec| u2 name_index; | |
504 // JVMSpec| u2 descriptor_index; | |
505 // JVMSpec| u2 attributes_count; | |
506 // JVMSpec| attribute_info attributes[attributes_count]; | |
507 // JVMSpec| } | |
508 void JvmtiClassFileReconstituter::write_method_info(methodHandle method) { | |
509 AccessFlags access_flags = method->access_flags(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
510 ConstMethod* const_method = method->constMethod(); |
0 | 511 u2 generic_signature_index = const_method->generic_signature_index(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
512 AnnotationArray* anno = method->annotations(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
513 AnnotationArray* param_anno = method->parameter_annotations(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
514 AnnotationArray* default_anno = method->annotation_default(); |
0 | 515 |
516 write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS); | |
517 write_u2(const_method->name_index()); | |
518 write_u2(const_method->signature_index()); | |
519 | |
520 // write attributes in the same order javac does, so we can test with byte for | |
521 // byte comparison | |
522 int attr_count = 0; | |
523 if (const_method->code_size() != 0) { | |
524 ++attr_count; // has Code attribute | |
525 } | |
526 if (const_method->has_checked_exceptions()) { | |
527 ++attr_count; // has Exceptions attribute | |
528 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
529 if (default_anno != NULL) { |
0 | 530 ++attr_count; // has AnnotationDefault attribute |
531 } | |
532 // Deprecated attribute would go here | |
533 if (access_flags.is_synthetic()) { // FIXME | |
534 // ++attr_count; | |
535 } | |
536 if (generic_signature_index != 0) { | |
537 ++attr_count; | |
538 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
539 if (anno != NULL) { |
0 | 540 ++attr_count; // has RuntimeVisibleAnnotations attribute |
541 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
542 if (param_anno != NULL) { |
0 | 543 ++attr_count; // has RuntimeVisibleParameterAnnotations attribute |
544 } | |
545 | |
546 write_u2(attr_count); | |
547 if (const_method->code_size() > 0) { | |
548 write_code_attribute(method); | |
549 } | |
550 if (const_method->has_checked_exceptions()) { | |
551 write_exceptions_attribute(const_method); | |
552 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
553 if (default_anno != NULL) { |
0 | 554 write_annotations_attribute("AnnotationDefault", default_anno); |
555 } | |
556 // Deprecated attribute would go here | |
557 if (access_flags.is_synthetic()) { | |
558 // write_synthetic_attribute(); | |
559 } | |
560 if (generic_signature_index != 0) { | |
561 write_signature_attribute(generic_signature_index); | |
562 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
563 if (anno != NULL) { |
0 | 564 write_annotations_attribute("RuntimeVisibleAnnotations", anno); |
565 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
566 if (param_anno != NULL) { |
0 | 567 write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); |
568 } | |
569 } | |
570 | |
571 // Write the class attributes portion of ClassFile structure | |
572 // JVMSpec| u2 attributes_count; | |
573 // JVMSpec| attribute_info attributes[attributes_count]; | |
574 void JvmtiClassFileReconstituter::write_class_attributes() { | |
575 u2 inner_classes_length = inner_classes_attribute_length(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
576 Symbol* generic_signature = ikh()->generic_signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
577 AnnotationArray* anno = ikh()->class_annotations(); |
0 | 578 |
579 int attr_count = 0; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
580 if (generic_signature != NULL) { |
0 | 581 ++attr_count; |
582 } | |
583 if (ikh()->source_file_name() != NULL) { | |
584 ++attr_count; | |
585 } | |
586 if (ikh()->source_debug_extension() != NULL) { | |
587 ++attr_count; | |
588 } | |
589 if (inner_classes_length > 0) { | |
590 ++attr_count; | |
591 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
592 if (anno != NULL) { |
0 | 593 ++attr_count; // has RuntimeVisibleAnnotations attribute |
594 } | |
595 | |
596 write_u2(attr_count); | |
597 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
598 if (generic_signature != NULL) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
599 write_signature_attribute(symbol_to_cpool_index(generic_signature)); |
0 | 600 } |
601 if (ikh()->source_file_name() != NULL) { | |
602 write_source_file_attribute(); | |
603 } | |
604 if (ikh()->source_debug_extension() != NULL) { | |
605 write_source_debug_extension_attribute(); | |
606 } | |
607 if (inner_classes_length > 0) { | |
608 write_inner_classes_attribute(inner_classes_length); | |
609 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
610 if (anno != NULL) { |
0 | 611 write_annotations_attribute("RuntimeVisibleAnnotations", anno); |
612 } | |
613 } | |
614 | |
615 // Write the method information portion of ClassFile structure | |
616 // JVMSpec| u2 methods_count; | |
617 // JVMSpec| method_info methods[methods_count]; | |
618 void JvmtiClassFileReconstituter::write_method_infos() { | |
619 HandleMark hm(thread()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
620 Array<Method*>* methods = ikh()->methods(); |
0 | 621 int num_methods = methods->length(); |
622 | |
623 write_u2(num_methods); | |
624 if (JvmtiExport::can_maintain_original_method_order()) { | |
625 int index; | |
626 int original_index; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
627 intArray method_order(num_methods, 0); |
0 | 628 |
629 // invert the method order mapping | |
630 for (index = 0; index < num_methods; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
631 original_index = ikh()->method_ordering()->at(index); |
0 | 632 assert(original_index >= 0 && original_index < num_methods, |
633 "invalid original method index"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
634 method_order.at_put(original_index, index); |
0 | 635 } |
636 | |
637 // write in original order | |
638 for (original_index = 0; original_index < num_methods; original_index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
639 index = method_order.at(original_index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
640 methodHandle method(thread(), methods->at(index)); |
0 | 641 write_method_info(method); |
642 } | |
643 } else { | |
644 // method order not preserved just dump the method infos | |
645 for (int index = 0; index < num_methods; index++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
646 methodHandle method(thread(), methods->at(index)); |
0 | 647 write_method_info(method); |
648 } | |
649 } | |
650 } | |
651 | |
652 void JvmtiClassFileReconstituter::write_class_file_format() { | |
653 ReallocMark(); | |
654 | |
655 // JVMSpec| ClassFile { | |
656 // JVMSpec| u4 magic; | |
657 write_u4(0xCAFEBABE); | |
658 | |
659 // JVMSpec| u2 minor_version; | |
660 // JVMSpec| u2 major_version; | |
661 write_u2(ikh()->minor_version()); | |
662 u2 major = ikh()->major_version(); | |
663 write_u2(major); | |
664 | |
665 // JVMSpec| u2 constant_pool_count; | |
666 // JVMSpec| cp_info constant_pool[constant_pool_count-1]; | |
667 write_u2(cpool()->length()); | |
668 copy_cpool_bytes(writeable_address(cpool_size())); | |
669 | |
670 // JVMSpec| u2 access_flags; | |
671 write_u2(ikh()->access_flags().get_flags() & JVM_RECOGNIZED_CLASS_MODIFIERS); | |
672 | |
673 // JVMSpec| u2 this_class; | |
674 // JVMSpec| u2 super_class; | |
675 write_u2(class_symbol_to_cpool_index(ikh()->name())); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
676 Klass* super_class = ikh()->super(); |
0 | 677 write_u2(super_class == NULL? 0 : // zero for java.lang.Object |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
678 class_symbol_to_cpool_index(super_class->name())); |
0 | 679 |
680 // JVMSpec| u2 interfaces_count; | |
681 // JVMSpec| u2 interfaces[interfaces_count]; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
682 Array<Klass*>* interfaces = ikh()->local_interfaces(); |
0 | 683 int num_interfaces = interfaces->length(); |
684 write_u2(num_interfaces); | |
685 for (int index = 0; index < num_interfaces; index++) { | |
686 HandleMark hm(thread()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
687 instanceKlassHandle iikh(thread(), interfaces->at(index)); |
0 | 688 write_u2(class_symbol_to_cpool_index(iikh->name())); |
689 } | |
690 | |
691 // JVMSpec| u2 fields_count; | |
692 // JVMSpec| field_info fields[fields_count]; | |
693 write_field_infos(); | |
694 | |
695 // JVMSpec| u2 methods_count; | |
696 // JVMSpec| method_info methods[methods_count]; | |
697 write_method_infos(); | |
698 | |
699 // JVMSpec| u2 attributes_count; | |
700 // JVMSpec| attribute_info attributes[attributes_count]; | |
701 // JVMSpec| } /* end ClassFile 8? | |
702 write_class_attributes(); | |
703 } | |
704 | |
705 address JvmtiClassFileReconstituter::writeable_address(size_t size) { | |
706 size_t used_size = _buffer_ptr - _buffer; | |
707 if (size + used_size >= _buffer_size) { | |
708 // compute the new buffer size: must be at least twice as big as before | |
709 // plus whatever new is being used; then convert to nice clean block boundary | |
710 size_t new_buffer_size = (size + _buffer_size*2 + 1) / initial_buffer_size | |
711 * initial_buffer_size; | |
712 | |
713 // VM goes belly-up if the memory isn't available, so cannot do OOM processing | |
714 _buffer = REALLOC_RESOURCE_ARRAY(u1, _buffer, _buffer_size, new_buffer_size); | |
715 _buffer_size = new_buffer_size; | |
716 _buffer_ptr = _buffer + used_size; | |
717 } | |
718 u1* ret_ptr = _buffer_ptr; | |
719 _buffer_ptr += size; | |
720 return ret_ptr; | |
721 } | |
722 | |
723 void JvmtiClassFileReconstituter::write_attribute_name_index(const char* name) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
724 TempNewSymbol sym = SymbolTable::probe(name, (int)strlen(name)); |
0 | 725 assert(sym != NULL, "attribute name symbol not found"); |
726 u2 attr_name_index = symbol_to_cpool_index(sym); | |
727 assert(attr_name_index != 0, "attribute name symbol not in constant pool"); | |
728 write_u2(attr_name_index); | |
729 } | |
730 | |
731 void JvmtiClassFileReconstituter::write_u1(u1 x) { | |
732 *writeable_address(1) = x; | |
733 } | |
734 | |
735 void JvmtiClassFileReconstituter::write_u2(u2 x) { | |
736 Bytes::put_Java_u2(writeable_address(2), x); | |
737 } | |
738 | |
739 void JvmtiClassFileReconstituter::write_u4(u4 x) { | |
740 Bytes::put_Java_u4(writeable_address(4), x); | |
741 } | |
742 | |
743 void JvmtiClassFileReconstituter::write_u8(u8 x) { | |
744 Bytes::put_Java_u8(writeable_address(8), x); | |
745 } | |
746 | |
747 void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh, | |
748 unsigned char* bytecodes) { | |
749 // use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes | |
750 // and the breakpoint bytecode are converted to their original bytecodes. | |
751 | |
752 BytecodeStream bs(mh); | |
753 | |
754 unsigned char* p = bytecodes; | |
755 Bytecodes::Code code; | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6772
diff
changeset
|
756 bool is_rewritten = mh->method_holder()->is_rewritten(); |
0 | 757 |
758 while ((code = bs.next()) >= 0) { | |
759 assert(Bytecodes::is_java_code(code), "sanity check"); | |
760 assert(code != Bytecodes::_breakpoint, "sanity check"); | |
761 | |
762 // length of bytecode (mnemonic + operands) | |
763 address bcp = bs.bcp(); | |
1565 | 764 int len = bs.instruction_size(); |
0 | 765 assert(len > 0, "length must be > 0"); |
766 | |
767 // copy the bytecodes | |
768 *p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code); | |
769 if (len > 1) { | |
770 memcpy(p+1, bcp+1, len-1); | |
771 } | |
772 | |
773 // During linking the get/put and invoke instructions are rewritten | |
774 // with an index into the constant pool cache. The original constant | |
775 // pool index must be returned to caller. Rewrite the index. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
776 if (is_rewritten && len > 1) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
777 bool is_wide = false; |
0 | 778 switch (code) { |
779 case Bytecodes::_getstatic : // fall through | |
780 case Bytecodes::_putstatic : // fall through | |
781 case Bytecodes::_getfield : // fall through | |
782 case Bytecodes::_putfield : // fall through | |
783 case Bytecodes::_invokevirtual : // fall through | |
784 case Bytecodes::_invokespecial : // fall through | |
785 case Bytecodes::_invokestatic : // fall through | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
786 case Bytecodes::_invokedynamic : // fall through |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
787 case Bytecodes::_invokeinterface : { |
5922
ff29ce866f23
7118280: The gbyc00102 JCK7 test causes an assert in JVM 7.0 fastdebug mode
dsamersoff
parents:
4718
diff
changeset
|
788 assert(len == 3 || |
ff29ce866f23
7118280: The gbyc00102 JCK7 test causes an assert in JVM 7.0 fastdebug mode
dsamersoff
parents:
4718
diff
changeset
|
789 (code == Bytecodes::_invokeinterface && len == 5) || |
ff29ce866f23
7118280: The gbyc00102 JCK7 test causes an assert in JVM 7.0 fastdebug mode
dsamersoff
parents:
4718
diff
changeset
|
790 (code == Bytecodes::_invokedynamic && len == 5), |
0 | 791 "sanity check"); |
5922
ff29ce866f23
7118280: The gbyc00102 JCK7 test causes an assert in JVM 7.0 fastdebug mode
dsamersoff
parents:
4718
diff
changeset
|
792 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
793 int cpci = Bytes::get_native_u2(bcp+1); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
794 bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
795 ConstantPoolCacheEntry* entry; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
796 if (is_invokedynamic) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
797 cpci = Bytes::get_native_u4(bcp+1); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
798 entry = mh->constants()->invokedynamic_cp_cache_entry_at(cpci); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
799 } else { |
0 | 800 // cache cannot be pre-fetched since some classes won't have it yet |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
801 entry = mh->constants()->cache()->entry_at(cpci); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
802 } |
0 | 803 int i = entry->constant_pool_index(); |
804 assert(i < mh->constants()->length(), "sanity check"); | |
805 Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
806 if (is_invokedynamic) *(p+3) = *(p+4) = 0; |
0 | 807 break; |
808 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
809 case Bytecodes::_ldc_w: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
810 is_wide = true; // fall through |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
811 case Bytecodes::_ldc: { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
812 if (bs.raw_code() == Bytecodes::_fast_aldc || bs.raw_code() == Bytecodes::_fast_aldc_w) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
813 int cpci = is_wide ? Bytes::get_native_u2(bcp+1) : (u1)(*(bcp+1)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
814 int i = mh->constants()->object_to_cp_index(cpci); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
815 assert(i < mh->constants()->length(), "sanity check"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
816 if (is_wide) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
817 Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
818 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
819 *(p+1) = (u1)i; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
820 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
821 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
822 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
823 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
824 } |
0 | 825 } |
826 | |
827 p += len; | |
828 } | |
829 } |