30 #include "memory/resourceArea.hpp" |
30 #include "memory/resourceArea.hpp" |
31 #include "runtime/signature.hpp" |
31 #include "runtime/signature.hpp" |
32 #include "utilities/events.hpp" |
32 #include "utilities/events.hpp" |
33 |
33 |
34 /* |
34 /* |
35 * Returns the name of the klass that is described at constant pool |
35 * Prints the name of the method that is described at constant pool |
36 * index cp_index in the constant pool of method 'method'. |
36 * index cp_index in the constant pool of method 'method'. |
37 */ |
37 */ |
38 char const* MethodBytecodePrinter::get_klass_name(Method* method, int cp_index) { |
38 static void print_method_name(outputStream *os, Method* method, int cp_index) { |
39 ConstantPool* cp = method->constants(); |
|
40 int class_index = cp->klass_ref_index_at(cp_index); |
|
41 Symbol* klass = cp->klass_at_noresolve(class_index); |
|
42 |
|
43 return klass->as_klass_external_name(); |
|
44 } |
|
45 |
|
46 /* |
|
47 * Returns the name of the method that is described at constant pool |
|
48 * index cp_index in the constant pool of method 'method'. |
|
49 */ |
|
50 char const* MethodBytecodePrinter::get_method_name(Method* method, int cp_index) { |
|
51 ConstantPool* cp = method->constants(); |
39 ConstantPool* cp = method->constants(); |
52 int class_index = cp->klass_ref_index_at(cp_index); |
40 int class_index = cp->klass_ref_index_at(cp_index); |
53 Symbol* klass = cp->klass_at_noresolve(class_index); |
41 Symbol* klass = cp->klass_at_noresolve(class_index); |
54 |
42 |
55 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
43 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
56 int name_index = cp->name_ref_index_at(name_and_type_index); |
44 int name_index = cp->name_ref_index_at(name_and_type_index); |
57 int type_index = cp->signature_ref_index_at(name_and_type_index); |
45 int type_index = cp->signature_ref_index_at(name_and_type_index); |
58 Symbol* name = cp->symbol_at(name_index); |
46 Symbol* name = cp->symbol_at(name_index); |
59 Symbol* signature = cp->symbol_at(type_index); |
47 Symbol* signature = cp->symbol_at(type_index); |
60 |
48 |
61 stringStream ss; |
49 signature->print_as_signature_external_return_type(os); |
62 ss.print("%s.%s%s", klass->as_klass_external_name(), name->as_C_string(), signature->as_C_string()); |
50 os->print(" %s.%s(", klass->as_klass_external_name(), name->as_C_string()); |
63 return ss.as_string(); |
51 signature->print_as_signature_external_parameters(os); |
|
52 os->print(")"); |
|
53 } |
|
54 |
|
55 /* |
|
56 * Prints the name of the field that is described at constant pool |
|
57 * index cp_index in the constant pool of method 'method'. |
|
58 */ |
|
59 static void print_field_and_class(outputStream *os, Method* method, int cp_index) { |
|
60 ConstantPool* cp = method->constants(); |
|
61 int class_index = cp->klass_ref_index_at(cp_index); |
|
62 Symbol* klass = cp->klass_at_noresolve(class_index); |
|
63 |
|
64 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
|
65 int name_index = cp->name_ref_index_at(name_and_type_index); |
|
66 Symbol* name = cp->symbol_at(name_index); |
|
67 |
|
68 os->print("%s.%s", klass->as_klass_external_name(), name->as_C_string()); |
64 } |
69 } |
65 |
70 |
66 /* |
71 /* |
67 * Returns the name of the field that is described at constant pool |
72 * Returns the name of the field that is described at constant pool |
68 * index cp_index in the constant pool of method 'method'. |
73 * index cp_index in the constant pool of method 'method'. |
69 */ |
74 */ |
70 char const* MethodBytecodePrinter::get_field_and_class(Method* method, int cp_index) { |
75 static char const* get_field_name(Method* method, int cp_index) { |
71 ConstantPool* cp = method->constants(); |
|
72 int class_index = cp->klass_ref_index_at(cp_index); |
|
73 Symbol* klass = cp->klass_at_noresolve(class_index); |
|
74 |
|
75 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
|
76 int name_index = cp->name_ref_index_at(name_and_type_index); |
|
77 Symbol* name = cp->symbol_at(name_index); |
|
78 |
|
79 stringStream ss; |
|
80 ss.print("%s.%s", klass->as_klass_external_name(), name->as_C_string()); |
|
81 return ss.as_string(); |
|
82 } |
|
83 |
|
84 /* |
|
85 * Returns the name of the field that is described at constant pool |
|
86 * index cp_index in the constant pool of method 'method'. |
|
87 */ |
|
88 char const* MethodBytecodePrinter::get_field_name(Method* method, int cp_index) { |
|
89 ConstantPool* cp = method->constants(); |
76 ConstantPool* cp = method->constants(); |
90 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
77 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
91 int name_index = cp->name_ref_index_at(name_and_type_index); |
78 int name_index = cp->name_ref_index_at(name_and_type_index); |
92 Symbol* name = cp->symbol_at(name_index); |
79 Symbol* name = cp->symbol_at(name_index); |
93 return name->as_C_string(); |
80 return name->as_C_string(); |
94 } |
81 } |
95 |
82 |
|
83 static void print_local_var(outputStream *os, int bci, Method* method, int slot) { |
|
84 if (method->has_localvariable_table()) { |
|
85 for (int i = 0; i < method->localvariable_table_length(); i++) { |
|
86 LocalVariableTableElement* elem = method->localvariable_table_start() + i; |
|
87 int start = elem->start_bci; |
|
88 int end = start + elem->length; |
|
89 |
|
90 if ((bci >= start) && (bci < end) && (elem->slot == slot)) { |
|
91 ConstantPool* cp = method->constants(); |
|
92 char *var = cp->symbol_at(elem->name_cp_index)->as_C_string(); |
|
93 os->print("%s", var); |
|
94 |
|
95 return; |
|
96 } |
|
97 } |
|
98 } |
|
99 |
|
100 // Handle at least some cases we know. |
|
101 if (!method->is_static() && (slot == 0)) { |
|
102 os->print("this"); |
|
103 } else { |
|
104 int curr = method->is_static() ? 0 : 1; |
|
105 SignatureStream ss(method->signature()); |
|
106 int param_index = 0; |
|
107 bool found = false; |
|
108 |
|
109 for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) { |
|
110 if (ss.at_return_type()) { |
|
111 continue; |
|
112 } |
|
113 int size = type2size[ss.type()]; |
|
114 if ((slot >= curr) && (slot < curr + size)) { |
|
115 found = true; |
|
116 break; |
|
117 } |
|
118 param_index += 1; |
|
119 curr += size; |
|
120 } |
|
121 |
|
122 if (found) { |
|
123 os->print("<parameter%d>", 1 + param_index); |
|
124 } else { |
|
125 // This is the best we can do. |
|
126 os->print("<local%d>", slot); |
|
127 } |
|
128 } |
|
129 } |
|
130 |
96 TrackingStackEntry::TrackingStackEntry(BasicType type) : _entry(INVALID + type * SCALE) { } |
131 TrackingStackEntry::TrackingStackEntry(BasicType type) : _entry(INVALID + type * SCALE) { } |
97 |
132 |
98 TrackingStackEntry::TrackingStackEntry(int bci, BasicType type) : _entry(bci + type * SCALE) { |
133 TrackingStackEntry::TrackingStackEntry(int bci, BasicType type) : _entry(bci + type * SCALE) { |
99 assert(bci >= 0, "BCI must be >= 0"); |
134 assert(bci >= 0, "BCI must be >= 0"); |
100 assert(bci < 65536, "BCI must be < 65536"); |
135 assert(bci < 65536, "BCI must be < 65536"); |
180 TrackingStackEntry TrackingStack::get_entry(int slot) { |
215 TrackingStackEntry TrackingStack::get_entry(int slot) { |
181 assert(slot >= 0, "Slot < 0"); |
216 assert(slot >= 0, "Slot < 0"); |
182 assert(slot < get_size(), "Slot >= size"); |
217 assert(slot < get_size(), "Slot >= size"); |
183 |
218 |
184 return _stack.at(get_size() - slot - 1); |
219 return _stack.at(get_size() - slot - 1); |
185 } |
|
186 |
|
187 |
|
188 |
|
189 static TrackingStackSource createInvalidSource(int bci) { |
|
190 return TrackingStackSource(TrackingStackSource::INVALID, bci, "invalid"); |
|
191 } |
|
192 |
|
193 static TrackingStackSource createLocalVarSource(int bci, Method* method, int slot) { |
|
194 // We assume outermost caller has ResourceMark. |
|
195 stringStream reason; |
|
196 |
|
197 if (method->has_localvariable_table()) { |
|
198 for (int i = 0; i < method->localvariable_table_length(); i++) { |
|
199 LocalVariableTableElement* elem = method->localvariable_table_start() + i; |
|
200 int start = elem->start_bci; |
|
201 int end = start + elem->length; |
|
202 |
|
203 if ((bci >= start) && (bci < end) && (elem->slot == slot)) { |
|
204 ConstantPool* cp = method->constants(); |
|
205 char *var = cp->symbol_at(elem->name_cp_index)->as_C_string(); |
|
206 if (strlen(var) == 4 && strcmp(var, "this") == 0) { |
|
207 reason.print("this"); |
|
208 } else { |
|
209 reason.print("%s", var); |
|
210 } |
|
211 |
|
212 return TrackingStackSource(TrackingStackSource::LOCAL_VAR, bci, reason.as_string()); |
|
213 } |
|
214 } |
|
215 } |
|
216 |
|
217 // Handle at least some cases we know. |
|
218 if (!method->is_static() && (slot == 0)) { |
|
219 reason.print("this"); |
|
220 } else { |
|
221 int curr = method->is_static() ? 0 : 1; |
|
222 SignatureStream ss(method->signature()); |
|
223 int param_index = 0; |
|
224 bool found = false; |
|
225 |
|
226 for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) { |
|
227 if (ss.at_return_type()) { |
|
228 continue; |
|
229 } |
|
230 |
|
231 int size = type2size[ss.type()]; |
|
232 |
|
233 if ((slot >= curr) && (slot < curr + size)) { |
|
234 found = true; |
|
235 break; |
|
236 } |
|
237 |
|
238 param_index += 1; |
|
239 curr += size; |
|
240 } |
|
241 |
|
242 if (found) { |
|
243 reason.print("<parameter%d>", 1 + param_index); |
|
244 } else { |
|
245 // This is the best we can do. |
|
246 reason.print("<local%d>", slot); |
|
247 } |
|
248 } |
|
249 |
|
250 return TrackingStackSource(TrackingStackSource::LOCAL_VAR, bci, reason.as_string()); |
|
251 } |
|
252 |
|
253 |
|
254 static TrackingStackSource createConstantSource(int bci, const char *text) { |
|
255 return TrackingStackSource(TrackingStackSource::CONSTANT, bci, text); |
|
256 } |
|
257 |
|
258 static TrackingStackSource createArraySource(int bci, TrackingStackSource const& array_source, |
|
259 TrackingStackSource const& index_source) { |
|
260 // We assume outermost caller has ResourceMark. |
|
261 stringStream reason; |
|
262 |
|
263 if (array_source.get_type() != TrackingStackSource::INVALID) { |
|
264 reason.print("%s", array_source.as_string()); |
|
265 } else { |
|
266 reason.print("array"); |
|
267 } |
|
268 if (index_source.get_type() != TrackingStackSource::INVALID) { |
|
269 reason.print("[%s]", index_source.as_string()); |
|
270 } else { |
|
271 reason.print("[...]"); |
|
272 } |
|
273 |
|
274 return TrackingStackSource(TrackingStackSource::ARRAY_ELEM, bci, reason.as_string()); |
|
275 } |
|
276 |
|
277 static TrackingStackSource createFieldSource(int bci, Method* method, int cp_index, |
|
278 TrackingStackSource const& object_source) { |
|
279 // We assume outermost caller has ResourceMark. |
|
280 stringStream reason; |
|
281 |
|
282 // GLGL We could also print the type of the field. Should we do that? |
|
283 //MethodBytecodePrinter::get_klass_name(method, cp_index) |
|
284 if (object_source.get_type() != TrackingStackSource::INVALID) { |
|
285 reason.print("%s.", object_source.as_string()); |
|
286 } |
|
287 reason.print("%s", MethodBytecodePrinter::get_field_name(method, cp_index)); |
|
288 |
|
289 return TrackingStackSource(TrackingStackSource::FIELD_ELEM, bci, reason.as_string()); |
|
290 } |
|
291 |
|
292 static TrackingStackSource createStaticFieldSource(int bci, Method* method, int cp_index) { |
|
293 // We assume outermost caller has ResourceMark. |
|
294 stringStream reason; |
|
295 reason.print("static %s", |
|
296 MethodBytecodePrinter::get_field_and_class(method, cp_index)); |
|
297 |
|
298 return TrackingStackSource(TrackingStackSource::FIELD_ELEM, bci, reason.as_string()); |
|
299 } |
220 } |
300 |
221 |
301 TrackingStackCreator::TrackingStackCreator(Method* method, int bci) : _method(method) { |
222 TrackingStackCreator::TrackingStackCreator(Method* method, int bci) : _method(method) { |
302 ConstMethod* const_method = method->constMethod(); |
223 ConstMethod* const_method = method->constMethod(); |
303 |
224 |
910 delete stack; |
831 delete stack; |
911 |
832 |
912 return len; |
833 return len; |
913 } |
834 } |
914 |
835 |
915 TrackingStackSource TrackingStackCreator::get_source(int bci, int slot, int max_detail) { |
836 int TrackingStackCreator::get_NPE_null_slot(int bci) { |
916 assert(bci >= 0, "BCI too low"); |
837 // If this NPE was created via reflection, we have no real NPE. |
917 assert(bci < get_size(), "BCI to large"); |
838 if (_method->method_holder() == SystemDictionary::reflect_NativeConstructorAccessorImpl_klass()) { |
918 |
839 return -2; |
919 if (max_detail <= 0) { |
840 } |
920 return createInvalidSource(bci); |
|
921 } |
|
922 |
|
923 if (_stacks->at(bci) == NULL) { |
|
924 return createInvalidSource(bci); |
|
925 } |
|
926 |
|
927 TrackingStack* stack = _stacks->at(bci); |
|
928 assert(slot >= 0, "Slot nr. too low"); |
|
929 assert(slot < stack->get_size(), "Slot nr. too large"); |
|
930 |
|
931 TrackingStackEntry entry = stack->get_entry(slot); |
|
932 |
|
933 if (!entry.has_bci()) { |
|
934 return createInvalidSource(bci); |
|
935 } |
|
936 |
|
937 // Get the bytecode. |
841 // Get the bytecode. |
938 int source_bci = entry.get_bci(); |
|
939 address code_base = _method->constMethod()->code_base(); |
842 address code_base = _method->constMethod()->code_base(); |
940 Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci); |
843 Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
941 bool is_wide = false; |
844 int pos = bci + 1; |
942 int pos = source_bci + 1; |
|
943 |
|
944 if (code == Bytecodes::_wide) { |
845 if (code == Bytecodes::_wide) { |
945 is_wide = true; |
846 code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
946 code = Bytecodes::java_code_at(_method, code_base + source_bci + 1); |
|
947 pos += 1; |
847 pos += 1; |
948 } |
848 } |
949 |
849 |
950 switch (code) { |
850 switch (code) { |
951 case Bytecodes::_iload: |
851 case Bytecodes::_getfield: |
952 case Bytecodes::_lload: |
852 case Bytecodes::_arraylength: |
953 case Bytecodes::_fload: |
853 case Bytecodes::_athrow: |
954 case Bytecodes::_dload: |
854 case Bytecodes::_monitorenter: |
955 case Bytecodes::_aload: { |
855 case Bytecodes::_monitorexit: |
956 int index; |
856 return 0; |
957 |
|
958 if (is_wide) { |
|
959 index = Bytes::get_Java_u2(code_base + source_bci + 2); |
|
960 } else { |
|
961 index = *(uint8_t*) (code_base + source_bci + 1); |
|
962 } |
|
963 |
|
964 return createLocalVarSource(source_bci, _method, index); |
|
965 } |
|
966 |
|
967 case Bytecodes::_iload_0: |
|
968 case Bytecodes::_lload_0: |
|
969 case Bytecodes::_fload_0: |
|
970 case Bytecodes::_dload_0: |
|
971 case Bytecodes::_aload_0: |
|
972 return createLocalVarSource(source_bci, _method, 0); |
|
973 |
|
974 case Bytecodes::_iload_1: |
|
975 case Bytecodes::_lload_1: |
|
976 case Bytecodes::_fload_1: |
|
977 case Bytecodes::_dload_1: |
|
978 case Bytecodes::_aload_1: |
|
979 return createLocalVarSource(source_bci, _method, 1); |
|
980 |
|
981 case Bytecodes::_iload_2: |
|
982 case Bytecodes::_lload_2: |
|
983 case Bytecodes::_fload_2: |
|
984 case Bytecodes::_dload_2: |
|
985 case Bytecodes::_aload_2: |
|
986 return createLocalVarSource(source_bci, _method, 2); |
|
987 |
|
988 case Bytecodes::_lload_3: |
|
989 case Bytecodes::_iload_3: |
|
990 case Bytecodes::_fload_3: |
|
991 case Bytecodes::_dload_3: |
|
992 case Bytecodes::_aload_3: |
|
993 return createLocalVarSource(source_bci, _method, 3); |
|
994 |
|
995 case Bytecodes::_aconst_null: |
|
996 return createConstantSource(source_bci, "null"); |
|
997 case Bytecodes::_iconst_m1: |
|
998 return createConstantSource(source_bci, "-1"); |
|
999 case Bytecodes::_iconst_0: |
|
1000 return createConstantSource(source_bci, "0"); |
|
1001 case Bytecodes::_iconst_1: |
|
1002 return createConstantSource(source_bci, "1"); |
|
1003 case Bytecodes::_iconst_2: |
|
1004 return createConstantSource(source_bci, "2"); |
|
1005 case Bytecodes::_iconst_3: |
|
1006 return createConstantSource(source_bci, "3"); |
|
1007 case Bytecodes::_iconst_4: |
|
1008 return createConstantSource(source_bci, "4"); |
|
1009 case Bytecodes::_iconst_5: |
|
1010 return createConstantSource(source_bci, "5"); |
|
1011 case Bytecodes::_lconst_0: |
|
1012 return createConstantSource(source_bci, "0L"); |
|
1013 case Bytecodes::_lconst_1: |
|
1014 return createConstantSource(source_bci, "1L"); |
|
1015 case Bytecodes::_fconst_0: |
|
1016 return createConstantSource(source_bci, "0.0f"); |
|
1017 case Bytecodes::_fconst_1: |
|
1018 return createConstantSource(source_bci, "1.0f"); |
|
1019 case Bytecodes::_fconst_2: |
|
1020 return createConstantSource(source_bci, "2.0f"); |
|
1021 case Bytecodes::_dconst_0: |
|
1022 return createConstantSource(source_bci, "0.0"); |
|
1023 case Bytecodes::_dconst_1: |
|
1024 return createConstantSource(source_bci, "1.0"); |
|
1025 case Bytecodes::_bipush: { |
|
1026 jbyte con = *(jbyte*) (code_base + source_bci + 1); |
|
1027 stringStream ss; |
|
1028 ss.print("%d", con); |
|
1029 return createConstantSource(source_bci, ss.as_string()); |
|
1030 } |
|
1031 case Bytecodes::_sipush: { |
|
1032 u2 con = Bytes::get_Java_u2(code_base + source_bci + 1); |
|
1033 stringStream ss; |
|
1034 ss.print("%d", con); |
|
1035 return createConstantSource(source_bci, ss.as_string()); |
|
1036 } |
|
1037 case Bytecodes::_iaload: |
857 case Bytecodes::_iaload: |
1038 case Bytecodes::_faload: |
858 case Bytecodes::_faload: |
1039 case Bytecodes::_aaload: |
859 case Bytecodes::_aaload: |
1040 case Bytecodes::_baload: |
860 case Bytecodes::_baload: |
1041 case Bytecodes::_caload: |
861 case Bytecodes::_caload: |
1042 case Bytecodes::_saload: |
862 case Bytecodes::_saload: |
1043 case Bytecodes::_laload: |
863 case Bytecodes::_laload: |
1044 case Bytecodes::_daload: { |
|
1045 TrackingStackSource array_source = get_source(source_bci, 1, max_detail - 1); |
|
1046 TrackingStackSource index_source = get_source(source_bci, 0, max_detail - 1); |
|
1047 return createArraySource(source_bci, array_source, index_source); |
|
1048 } |
|
1049 |
|
1050 case Bytecodes::_invokevirtual: |
|
1051 case Bytecodes::_invokespecial: |
|
1052 case Bytecodes::_invokestatic: |
|
1053 case Bytecodes::_invokeinterface: { |
|
1054 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1055 // We assume outermost caller has ResourceMark. |
|
1056 stringStream reason; |
|
1057 if (max_detail == 5 /* Todo: introduce a constant ... */) { |
|
1058 reason.print("The return value of '%s'", MethodBytecodePrinter::get_method_name(_method, cp_index)); |
|
1059 } else { |
|
1060 reason.print("%s", MethodBytecodePrinter::get_method_name(_method, cp_index)); |
|
1061 } |
|
1062 return TrackingStackSource(TrackingStackSource::METHOD, source_bci, reason.as_string()); |
|
1063 } |
|
1064 |
|
1065 case Bytecodes::_getstatic: |
|
1066 return createStaticFieldSource(source_bci, _method, |
|
1067 Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG); |
|
1068 |
|
1069 case Bytecodes::_getfield: { |
|
1070 int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG; |
|
1071 TrackingStackSource object_source = get_source(source_bci, 0, max_detail - 1); |
|
1072 return createFieldSource(source_bci, _method, cp_index, object_source); |
|
1073 } |
|
1074 |
|
1075 default: |
|
1076 return createInvalidSource(bci); |
|
1077 } |
|
1078 } |
|
1079 |
|
1080 int TrackingStackCreator::get_null_pointer_slot(int bci, char const** reason) { |
|
1081 // If this NPE was created via reflection, we have no real NPE. |
|
1082 if (_method->method_holder() == SystemDictionary::reflect_NativeConstructorAccessorImpl_klass()) { |
|
1083 return -2; |
|
1084 } |
|
1085 |
|
1086 // Get the bytecode. |
|
1087 address code_base = _method->constMethod()->code_base(); |
|
1088 Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
|
1089 int pos = bci + 1; |
|
1090 |
|
1091 if (code == Bytecodes::_wide) { |
|
1092 code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
|
1093 pos += 1; |
|
1094 } |
|
1095 |
|
1096 int result = -1; |
|
1097 |
|
1098 switch (code) { |
|
1099 case Bytecodes::_iaload: |
|
1100 if (reason != NULL) { |
|
1101 *reason = "Can not load from null int array."; |
|
1102 } |
|
1103 |
|
1104 result = 1; |
|
1105 break; |
|
1106 |
|
1107 case Bytecodes::_faload: |
|
1108 if (reason != NULL) { |
|
1109 *reason = "Can not load from null float array."; |
|
1110 } |
|
1111 |
|
1112 result = 1; |
|
1113 break; |
|
1114 |
|
1115 case Bytecodes::_aaload: |
|
1116 if (reason != NULL) { |
|
1117 *reason = "Can not load from null object array."; |
|
1118 } |
|
1119 |
|
1120 result = 1; |
|
1121 break; |
|
1122 |
|
1123 case Bytecodes::_baload: |
|
1124 if (reason != NULL) { |
|
1125 *reason = "Can not load from null byte/boolean array."; |
|
1126 } |
|
1127 |
|
1128 result = 1; |
|
1129 break; |
|
1130 |
|
1131 case Bytecodes::_caload: |
|
1132 if (reason != NULL) { |
|
1133 *reason = "Can not load from null char array."; |
|
1134 } |
|
1135 |
|
1136 result = 1; |
|
1137 break; |
|
1138 |
|
1139 case Bytecodes::_saload: |
|
1140 if (reason != NULL) { |
|
1141 *reason = "Can not load from null short array."; |
|
1142 } |
|
1143 |
|
1144 result = 1; |
|
1145 break; |
|
1146 |
|
1147 case Bytecodes::_laload: |
|
1148 if (reason != NULL) { |
|
1149 *reason = "Can not load from null long array."; |
|
1150 } |
|
1151 |
|
1152 result = 1; |
|
1153 break; |
|
1154 |
|
1155 case Bytecodes::_daload: |
864 case Bytecodes::_daload: |
1156 if (reason != NULL) { |
865 return 1; |
1157 *reason = "Can not load from null double array."; |
|
1158 } |
|
1159 |
|
1160 result = 1; |
|
1161 break; |
|
1162 |
|
1163 case Bytecodes::_iastore: |
866 case Bytecodes::_iastore: |
1164 if (reason != NULL) { |
867 case Bytecodes::_fastore: |
1165 *reason = "Can not store to null int array."; |
868 case Bytecodes::_aastore: |
1166 } |
869 case Bytecodes::_bastore: |
1167 |
870 case Bytecodes::_castore: |
1168 result = 2; |
871 case Bytecodes::_sastore: |
1169 break; |
872 return 2; |
1170 |
|
1171 case Bytecodes::_lastore: |
873 case Bytecodes::_lastore: |
1172 if (reason != NULL) { |
|
1173 *reason = "Can not store to null long array."; |
|
1174 } |
|
1175 |
|
1176 result = 3; |
|
1177 break; |
|
1178 |
|
1179 case Bytecodes::_fastore: |
|
1180 if (reason != NULL) { |
|
1181 *reason = "Can not store to null float array."; |
|
1182 } |
|
1183 |
|
1184 result = 2; |
|
1185 break; |
|
1186 |
|
1187 case Bytecodes::_dastore: |
874 case Bytecodes::_dastore: |
1188 if (reason != NULL) { |
875 return 3; |
1189 *reason = "Can not store to null double array."; |
876 case Bytecodes::_putfield: { |
1190 } |
|
1191 |
|
1192 result = 3; |
|
1193 break; |
|
1194 |
|
1195 case Bytecodes::_aastore: |
|
1196 if (reason != NULL) { |
|
1197 *reason = "Can not store to null object array."; |
|
1198 } |
|
1199 |
|
1200 result = 2; |
|
1201 break; |
|
1202 |
|
1203 case Bytecodes::_bastore: |
|
1204 if (reason != NULL) { |
|
1205 *reason = "Can not store to to null byte/boolean array."; |
|
1206 } |
|
1207 |
|
1208 result = 2; |
|
1209 break; |
|
1210 |
|
1211 case Bytecodes::_castore: |
|
1212 if (reason != NULL) { |
|
1213 *reason = "Can not store to to null char array."; |
|
1214 } |
|
1215 |
|
1216 result = 2; |
|
1217 break; |
|
1218 |
|
1219 case Bytecodes::_sastore: |
|
1220 if (reason != NULL) { |
|
1221 *reason = "Can not store to null short array."; |
|
1222 } |
|
1223 |
|
1224 result = 2; |
|
1225 break; |
|
1226 |
|
1227 case Bytecodes::_getfield: |
|
1228 { |
|
1229 if (reason != NULL) { |
|
1230 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1231 ConstantPool* cp = _method->constants(); |
|
1232 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
|
1233 int name_index = cp->name_ref_index_at(name_and_type_index); |
|
1234 Symbol* name = cp->symbol_at(name_index); |
|
1235 stringStream ss; |
|
1236 ss.print("Can not read field '%s'.", name->as_C_string()); |
|
1237 *reason = ss.as_string(); |
|
1238 } |
|
1239 |
|
1240 result = 0; |
|
1241 } |
|
1242 |
|
1243 break; |
|
1244 |
|
1245 case Bytecodes::_arraylength: |
|
1246 if (reason != NULL) { |
|
1247 *reason = "Can not read the array length."; |
|
1248 } |
|
1249 |
|
1250 result = 0; |
|
1251 break; |
|
1252 |
|
1253 case Bytecodes::_athrow: |
|
1254 if (reason != NULL) { |
|
1255 *reason = "Can not throw a null exception object."; |
|
1256 } |
|
1257 |
|
1258 result = 0; |
|
1259 break; |
|
1260 |
|
1261 case Bytecodes::_monitorenter: |
|
1262 if (reason != NULL) { |
|
1263 *reason = "Can not enter a null monitor."; |
|
1264 } |
|
1265 |
|
1266 result = 0; |
|
1267 break; |
|
1268 |
|
1269 case Bytecodes::_monitorexit: |
|
1270 if (reason != NULL) { |
|
1271 *reason = "Can not exit a null monitor."; |
|
1272 } |
|
1273 |
|
1274 result = 0; |
|
1275 break; |
|
1276 |
|
1277 case Bytecodes::_putfield: |
|
1278 { |
|
1279 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
877 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
1280 ConstantPool* cp = _method->constants(); |
878 ConstantPool* cp = _method->constants(); |
1281 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
879 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
1282 int type_index = cp->signature_ref_index_at(name_and_type_index); |
880 int type_index = cp->signature_ref_index_at(name_and_type_index); |
1283 Symbol* signature = cp->symbol_at(type_index); |
881 Symbol* signature = cp->symbol_at(type_index); |
1284 |
882 return type2size[char2type((char) signature->char_at(0))]; |
1285 if (reason != NULL) { |
883 } |
1286 stringStream ss; |
|
1287 ss.print("Can not write field '%s'.", |
|
1288 MethodBytecodePrinter::get_field_name(_method, cp_index)); |
|
1289 *reason = ss.as_string(); |
|
1290 } |
|
1291 |
|
1292 result = type2size[char2type((char) signature->char_at(0))]; |
|
1293 } |
|
1294 |
|
1295 break; |
|
1296 |
|
1297 case Bytecodes::_invokevirtual: |
884 case Bytecodes::_invokevirtual: |
1298 case Bytecodes::_invokespecial: |
885 case Bytecodes::_invokespecial: |
1299 case Bytecodes::_invokeinterface: |
886 case Bytecodes::_invokeinterface: |
1300 { |
887 { |
1301 int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
888 int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
1308 |
895 |
1309 // Assume the the call of a constructor can never cause a NullPointerException |
896 // Assume the the call of a constructor can never cause a NullPointerException |
1310 // (which is true in Java). This is mainly used to avoid generating wrong |
897 // (which is true in Java). This is mainly used to avoid generating wrong |
1311 // messages for NullPointerExceptions created explicitly by new in Java code. |
898 // messages for NullPointerExceptions created explicitly by new in Java code. |
1312 if (name != vmSymbols::object_initializer_name()) { |
899 if (name != vmSymbols::object_initializer_name()) { |
1313 if (reason != NULL) { |
900 return ArgumentSizeComputer(signature).size(); |
1314 stringStream ss; |
901 } else { |
1315 ss.print("Can not invoke method '%s'.", |
902 return -2; |
1316 MethodBytecodePrinter::get_method_name(_method, cp_index)); |
|
1317 *reason = ss.as_string(); |
|
1318 } |
|
1319 |
|
1320 result = ArgumentSizeComputer(signature).size(); |
|
1321 } |
903 } |
1322 else { |
904 } |
1323 result = -2; |
|
1324 } |
|
1325 } |
|
1326 |
|
1327 break; |
|
1328 |
905 |
1329 default: |
906 default: |
1330 break; |
907 break; |
1331 } |
908 } |
1332 |
909 |
1333 return result; |
910 return -1; |
1334 } |
911 } |
1335 |
912 |
|
913 const int TrackingStackCreator::_max_cause_detail = 5; |
|
914 |
|
915 void TrackingStackCreator::TrackingStackCreator::print_NPE_cause(outputStream *os, int bci, int slot) { |
|
916 if (print_NPE_cause0(os, bci, slot, _max_cause_detail, "'")) { |
|
917 os->print("' is null. "); |
|
918 } |
|
919 } |
|
920 |
|
921 /* Recursively print what was null. |
|
922 * |
|
923 * Go the the bytecode that pushed slot 'slot' on the operant stack |
|
924 * at bytecode 'bci'. Compute a message for that bytecode. If |
|
925 * necessary (array, field), recur further. |
|
926 * At most do max_detail recursions. |
|
927 * |
|
928 * Returns true if something was printed. |
|
929 */ |
|
930 bool TrackingStackCreator::TrackingStackCreator::print_NPE_cause0(outputStream *os, int bci, int slot, |
|
931 int max_detail, const char *prefix) { |
|
932 assert(bci >= 0, "BCI too low"); |
|
933 assert(bci < get_size(), "BCI to large"); |
|
934 |
|
935 if (max_detail <= 0) { |
|
936 return false; |
|
937 } |
|
938 |
|
939 if (_stacks->at(bci) == NULL) { |
|
940 return false; |
|
941 } |
|
942 |
|
943 TrackingStack* stack = _stacks->at(bci); |
|
944 assert(slot >= 0, "Slot nr. too low"); |
|
945 assert(slot < stack->get_size(), "Slot nr. too large"); |
|
946 |
|
947 TrackingStackEntry entry = stack->get_entry(slot); |
|
948 |
|
949 if (!entry.has_bci()) { |
|
950 return false; |
|
951 } |
|
952 |
|
953 // Get the bytecode. |
|
954 int source_bci = entry.get_bci(); |
|
955 address code_base = _method->constMethod()->code_base(); |
|
956 Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci); |
|
957 bool is_wide = false; |
|
958 int pos = source_bci + 1; |
|
959 |
|
960 if (code == Bytecodes::_wide) { |
|
961 is_wide = true; |
|
962 code = Bytecodes::java_code_at(_method, code_base + source_bci + 1); |
|
963 pos += 1; |
|
964 } |
|
965 |
|
966 if (max_detail == _max_cause_detail && |
|
967 prefix != NULL && |
|
968 code != Bytecodes::_invokevirtual && |
|
969 code != Bytecodes::_invokespecial && |
|
970 code != Bytecodes::_invokestatic && |
|
971 code != Bytecodes::_invokeinterface) { |
|
972 os->print("%s", prefix); |
|
973 } |
|
974 |
|
975 switch (code) { |
|
976 case Bytecodes::_iload_0: |
|
977 //case Bytecodes::_lload_0: // ? |
|
978 //case Bytecodes::_fload_0: // ? |
|
979 //case Bytecodes::_dload_0: // ? |
|
980 case Bytecodes::_aload_0: |
|
981 print_local_var(os, source_bci, _method, 0); |
|
982 return true; |
|
983 |
|
984 case Bytecodes::_iload_1: |
|
985 //case Bytecodes::_lload_1: // ? |
|
986 //case Bytecodes::_fload_1: // ? |
|
987 //case Bytecodes::_dload_1: // ? |
|
988 case Bytecodes::_aload_1: |
|
989 print_local_var(os, source_bci, _method, 1); |
|
990 return true; |
|
991 |
|
992 case Bytecodes::_iload_2: |
|
993 //case Bytecodes::_lload_2: // ? |
|
994 //case Bytecodes::_fload_2: // ? |
|
995 //case Bytecodes::_dload_2: // ? |
|
996 case Bytecodes::_aload_2: |
|
997 print_local_var(os, source_bci, _method, 2); |
|
998 return true; |
|
999 |
|
1000 case Bytecodes::_iload_3: |
|
1001 //case Bytecodes::_lload_3: // ? |
|
1002 //case Bytecodes::_fload_3: // ? |
|
1003 //case Bytecodes::_dload_3: // ? |
|
1004 case Bytecodes::_aload_3: |
|
1005 print_local_var(os, source_bci, _method, 3); |
|
1006 return true; |
|
1007 |
|
1008 case Bytecodes::_iload: |
|
1009 //case Bytecodes::_lload: // ? |
|
1010 //case Bytecodes::_fload: // ? |
|
1011 //case Bytecodes::_dload: // ? |
|
1012 case Bytecodes::_aload: { |
|
1013 int index; |
|
1014 |
|
1015 if (is_wide) { |
|
1016 index = Bytes::get_Java_u2(code_base + source_bci + 2); |
|
1017 } else { |
|
1018 index = *(uint8_t*) (code_base + source_bci + 1); |
|
1019 } |
|
1020 |
|
1021 print_local_var(os, source_bci, _method, index); |
|
1022 return true; |
|
1023 } |
|
1024 |
|
1025 case Bytecodes::_aconst_null: |
|
1026 os->print("null"); |
|
1027 return true; |
|
1028 case Bytecodes::_iconst_m1: |
|
1029 os->print("-1"); |
|
1030 return true; |
|
1031 case Bytecodes::_iconst_0: |
|
1032 os->print("0"); |
|
1033 return true; |
|
1034 case Bytecodes::_iconst_1: |
|
1035 os->print("1"); |
|
1036 return true; |
|
1037 case Bytecodes::_iconst_2: |
|
1038 os->print("2"); |
|
1039 return true; |
|
1040 case Bytecodes::_iconst_3: |
|
1041 os->print("3"); |
|
1042 return true; |
|
1043 case Bytecodes::_iconst_4: |
|
1044 os->print("4"); |
|
1045 return true; |
|
1046 case Bytecodes::_iconst_5: |
|
1047 os->print("5"); |
|
1048 return true; |
|
1049 /* |
|
1050 case Bytecodes::_lconst_0: // ? |
|
1051 os->print("0L"); |
|
1052 return true; |
|
1053 case Bytecodes::_lconst_1: // ? |
|
1054 os->print("1L"); |
|
1055 return true; |
|
1056 case Bytecodes::_fconst_0: // ? |
|
1057 os->print("0.0f"); |
|
1058 return true; |
|
1059 case Bytecodes::_fconst_1: // ? |
|
1060 os->print("1.0f"); |
|
1061 return true; |
|
1062 case Bytecodes::_fconst_2: // ? |
|
1063 os->print("2.0f"); |
|
1064 return true; |
|
1065 case Bytecodes::_dconst_0: // ? |
|
1066 os->print("0.0"); |
|
1067 return true; |
|
1068 case Bytecodes::_dconst_1: // ? |
|
1069 os->print("1.0"); |
|
1070 return true; |
|
1071 */ |
|
1072 case Bytecodes::_bipush: { |
|
1073 jbyte con = *(jbyte*) (code_base + source_bci + 1); |
|
1074 os->print("%d", con); |
|
1075 return true; |
|
1076 } |
|
1077 case Bytecodes::_sipush: { |
|
1078 u2 con = Bytes::get_Java_u2(code_base + source_bci + 1); |
|
1079 os->print("%d", con); |
|
1080 return true; |
|
1081 } |
|
1082 case Bytecodes::_iaload: |
|
1083 //case Bytecodes::_faload: // ? |
|
1084 case Bytecodes::_aaload: { |
|
1085 //case Bytecodes::_baload: // ? |
|
1086 //case Bytecodes::_caload: // ? |
|
1087 //case Bytecodes::_saload: // ? |
|
1088 //case Bytecodes::_laload: // ? |
|
1089 //case Bytecodes::_daload: { // ? |
|
1090 |
|
1091 // Print the 'name' of the array. Go back to the bytecode that |
|
1092 // pushed the array reference on the operand stack. |
|
1093 if (!print_NPE_cause0(os, source_bci, 1, max_detail-1)) { |
|
1094 // Returned false. Max recursion depth was reached. Print dummy. |
|
1095 os->print("<array>"); |
|
1096 } |
|
1097 os->print("["); |
|
1098 // Print the index expression. Go back to the bytecode that |
|
1099 // pushed the index on the operand stack. |
|
1100 // Don't decrement maxdetail so we get a value here and only |
|
1101 // cancel out on the dereference. |
|
1102 if (!print_NPE_cause0(os, source_bci, 0, max_detail)) { |
|
1103 // Returned false. We don't print complex array index expressions. Print placeholder. |
|
1104 os->print("..."); |
|
1105 } |
|
1106 os->print("]"); |
|
1107 return true; |
|
1108 } |
|
1109 |
|
1110 case Bytecodes::_getstatic: { |
|
1111 int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG; |
|
1112 os->print("static "); |
|
1113 print_field_and_class(os, _method, cp_index); |
|
1114 return true; |
|
1115 } |
|
1116 |
|
1117 case Bytecodes::_getfield: { |
|
1118 // Print the sender. Go back to the bytecode that |
|
1119 // pushed the sender on the operand stack. |
|
1120 if (print_NPE_cause0(os, source_bci, 0, max_detail - 1)) { |
|
1121 os->print("."); |
|
1122 } |
|
1123 int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG; |
|
1124 os->print("%s", get_field_name(_method, cp_index)); |
|
1125 return true; |
|
1126 } |
|
1127 |
|
1128 case Bytecodes::_invokevirtual: |
|
1129 case Bytecodes::_invokespecial: |
|
1130 case Bytecodes::_invokestatic: |
|
1131 case Bytecodes::_invokeinterface: { |
|
1132 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1133 if (max_detail == _max_cause_detail) { |
|
1134 os->print("The return value of '"); |
|
1135 } |
|
1136 print_method_name(os, _method, cp_index); |
|
1137 return true; |
|
1138 } |
|
1139 |
|
1140 default: break; |
|
1141 } |
|
1142 return false; |
|
1143 } |
|
1144 |
|
1145 void TrackingStackCreator::print_NPE_failedAction(outputStream *os, int bci) { |
|
1146 // If this NPE was created via reflection, we have no real NPE. |
|
1147 assert(_method->method_holder() != SystemDictionary::reflect_NativeConstructorAccessorImpl_klass(), |
|
1148 "We should have checked for reflection in get_NPE_null_slot()."); |
|
1149 |
|
1150 // Get the bytecode. |
|
1151 address code_base = _method->constMethod()->code_base(); |
|
1152 Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
|
1153 int pos = bci + 1; |
|
1154 if (code == Bytecodes::_wide) { |
|
1155 code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
|
1156 pos += 1; |
|
1157 } |
|
1158 |
|
1159 switch (code) { |
|
1160 case Bytecodes::_iaload: |
|
1161 os->print("Can not load from null int array."); break; |
|
1162 case Bytecodes::_faload: |
|
1163 os->print("Can not load from null float array."); break; |
|
1164 case Bytecodes::_aaload: |
|
1165 os->print("Can not load from null object array."); break; |
|
1166 case Bytecodes::_baload: |
|
1167 os->print("Can not load from null byte/boolean array."); break; |
|
1168 case Bytecodes::_caload: |
|
1169 os->print("Can not load from null char array."); break; |
|
1170 case Bytecodes::_saload: |
|
1171 os->print("Can not load from null short array."); break; |
|
1172 case Bytecodes::_laload: |
|
1173 os->print("Can not load from null long array."); break; |
|
1174 case Bytecodes::_daload: |
|
1175 os->print("Can not load from null double array."); break; |
|
1176 |
|
1177 case Bytecodes::_iastore: |
|
1178 os->print("Can not store to null int array."); break; |
|
1179 case Bytecodes::_fastore: |
|
1180 os->print("Can not store to null float array."); break; |
|
1181 case Bytecodes::_aastore: |
|
1182 os->print("Can not store to null object array."); break; |
|
1183 case Bytecodes::_bastore: |
|
1184 os->print("Can not store to null byte/boolean array."); break; |
|
1185 case Bytecodes::_castore: |
|
1186 os->print("Can not store to null char array."); break; |
|
1187 case Bytecodes::_sastore: |
|
1188 os->print("Can not store to null short array."); break; |
|
1189 case Bytecodes::_lastore: |
|
1190 os->print("Can not store to null long array."); break; |
|
1191 case Bytecodes::_dastore: |
|
1192 os->print("Can not store to null double array."); break; |
|
1193 |
|
1194 case Bytecodes::_arraylength: |
|
1195 os->print("Can not read the array length."); break; |
|
1196 case Bytecodes::_athrow: |
|
1197 os->print("Can not throw a null exception object."); break; |
|
1198 case Bytecodes::_monitorenter: |
|
1199 os->print("Can not enter a null monitor."); break; |
|
1200 case Bytecodes::_monitorexit: |
|
1201 os->print("Can not exit a null monitor."); break; |
|
1202 case Bytecodes::_getfield: { |
|
1203 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1204 ConstantPool* cp = _method->constants(); |
|
1205 int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
|
1206 int name_index = cp->name_ref_index_at(name_and_type_index); |
|
1207 Symbol* name = cp->symbol_at(name_index); |
|
1208 os->print("Can not read field '%s'.", name->as_C_string()); |
|
1209 } break; |
|
1210 case Bytecodes::_putfield: { |
|
1211 int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1212 os->print("Can not write field '%s'.", get_field_name(_method, cp_index)); |
|
1213 } break; |
|
1214 case Bytecodes::_invokevirtual: |
|
1215 case Bytecodes::_invokespecial: |
|
1216 case Bytecodes::_invokeinterface: { |
|
1217 int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG); |
|
1218 os->print("Can not invoke method '"); |
|
1219 print_method_name(os, _method, cp_index); |
|
1220 os->print("'."); |
|
1221 } break; |
|
1222 |
|
1223 default: |
|
1224 assert(0, "We should have checked this bytecode in get_NPE_null_slot()."); |
|
1225 break; |
|
1226 } |
|
1227 } |
|
1228 |