File: | jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp |
Warning: | line 538, column 16 Value stored to 'const_method' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. |
3 | * Copyright (c) 2019 SAP SE. All rights reserved. |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 | * |
6 | * This code is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 only, as |
8 | * published by the Free Software Foundation. |
9 | * |
10 | * This code is distributed in the hope that it will be useful, but WITHOUT |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
13 | * version 2 for more details (a copy is included in the LICENSE file that |
14 | * accompanied this code). |
15 | * |
16 | * You should have received a copy of the GNU General Public License version |
17 | * 2 along with this work; if not, write to the Free Software Foundation, |
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | * |
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
21 | * or visit www.oracle.com if you need additional information or have any |
22 | * questions. |
23 | * |
24 | */ |
25 | |
26 | #include "precompiled.hpp" |
27 | #include "classfile/vmClasses.hpp" |
28 | #include "classfile/vmSymbols.hpp" |
29 | #include "gc/shared/gcLocker.hpp" |
30 | #include "interpreter/bytecodeUtils.hpp" |
31 | #include "memory/resourceArea.hpp" |
32 | #include "runtime/signature.hpp" |
33 | #include "runtime/safepointVerifiers.hpp" |
34 | #include "utilities/events.hpp" |
35 | #include "utilities/ostream.hpp" |
36 | |
37 | class SimulatedOperandStack; |
38 | class ExceptionMessageBuilder; |
39 | |
40 | // The entries of a SimulatedOperandStack. They carry the analysis |
41 | // information gathered for the slot. |
42 | class StackSlotAnalysisData { |
43 | private: |
44 | |
45 | friend class SimulatedOperandStack; |
46 | friend class ExceptionMessageBuilder; |
47 | |
48 | unsigned int _bci:17; // The bci of the bytecode that pushed the current value on the operand stack. |
49 | // INVALID if ambiguous, e.g. after a control flow merge. |
50 | // 16 bits for bci (max bytecode size) and one for INVALID. |
51 | unsigned int _type:15; // The BasicType of the value on the operand stack. |
52 | |
53 | // Merges this slot data with the given one and returns the result. If |
54 | // the bcis of the two merged objects are different, the bci of the result |
55 | // will be undefined. If the types are different, the result type is T_CONFLICT. |
56 | // (An exception is if one type is an array and the other is object, then |
57 | // the result type will be T_OBJECT). |
58 | StackSlotAnalysisData merge(StackSlotAnalysisData other); |
59 | |
60 | public: |
61 | |
62 | // Creates a new object with an invalid bci and the given type. |
63 | StackSlotAnalysisData(BasicType type = T_CONFLICT); |
64 | |
65 | // Creates a new object with the given bci and type. |
66 | StackSlotAnalysisData(int bci, BasicType type); |
67 | |
68 | enum { |
69 | // An invalid bytecode index, as > 65535. |
70 | INVALID = 0x1FFFF |
71 | }; |
72 | |
73 | // Returns the bci. If the bci is invalid, INVALID is returned. |
74 | unsigned int get_bci(); |
75 | |
76 | // Returns true, if the bci is not invalid. |
77 | bool has_bci() { return get_bci() != INVALID; } |
78 | |
79 | // Returns the type of the slot data. |
80 | BasicType get_type(); |
81 | }; |
82 | |
83 | // A stack consisting of SimulatedOperandStackEntries. |
84 | // This represents the analysis information for the operand stack |
85 | // for a given bytecode at a given bci. |
86 | // It also holds an additional field that serves to collect |
87 | // information whether local slots were written. |
88 | class SimulatedOperandStack: CHeapObj<mtInternal> { |
89 | |
90 | private: |
91 | |
92 | friend class ExceptionMessageBuilder; |
93 | friend class StackSlotAnalysisData; |
94 | |
95 | // The stack. |
96 | GrowableArray<StackSlotAnalysisData> _stack; |
97 | |
98 | // Optimized bytecode can reuse local variable slots for several |
99 | // local variables. |
100 | // If there is no variable name information, we print 'parameter<i>' |
101 | // if a parameter maps to a local slot. Once a local slot has been |
102 | // written, we don't know any more whether it was written as the |
103 | // corresponding parameter, or whether another local has been |
104 | // mapped to the slot. So we don't want to print 'parameter<i>' any |
105 | // more, but 'local<i>'. Similary for 'this'. |
106 | // Therefore, during the analysis, we mark a bit for local slots that |
107 | // get written and propagate this information. |
108 | // We only run the analysis for 64 slots. If a method has more |
109 | // parameters, we print 'local<i>' in all cases. |
110 | uint64_t _written_local_slots; |
111 | |
112 | SimulatedOperandStack(): _written_local_slots(0) { }; |
113 | SimulatedOperandStack(const SimulatedOperandStack ©); |
114 | |
115 | // Pushes the given slot data. |
116 | void push_raw(StackSlotAnalysisData slotData); |
117 | |
118 | // Like push_raw, but if the slotData has type long or double, we push two. |
119 | void push(StackSlotAnalysisData slotData); |
120 | |
121 | // Like push(slotData), but using bci/type to create an instance of |
122 | // StackSlotAnalysisData first. |
123 | void push(int bci, BasicType type); |
124 | |
125 | // Pops the given number of entries. |
126 | void pop(int slots); |
127 | |
128 | // Merges this with the given stack by merging all entries. The |
129 | // size of the stacks must be the same. |
130 | void merge(SimulatedOperandStack const& other); |
131 | |
132 | public: |
133 | |
134 | // Returns the size of the stack. |
135 | int get_size() const; |
136 | |
137 | // Returns the slot data at the given index. Slot 0 is top of stack. |
138 | StackSlotAnalysisData get_slot_data(int slot); |
139 | |
140 | // Mark that local slot i was written. |
141 | void set_local_slot_written(int i); |
142 | |
143 | // Check whether local slot i was written by this or a previous bytecode. |
144 | bool local_slot_was_written(int i); |
145 | }; |
146 | |
147 | // Helper class to build internal exception messages for exceptions |
148 | // that are thrown because prerequisites to execute a bytecode |
149 | // are not met. |
150 | // E.g., if a NPE is thrown because an iload can not be executed |
151 | // by the VM because the reference to load from is null. |
152 | // |
153 | // It analyses the bytecode to assemble Java-like message text |
154 | // to give precise information where in a larger expression the |
155 | // exception occured. |
156 | // |
157 | // To assemble this message text, it is needed to know how |
158 | // operand stack slot entries were pushed on the operand stack. |
159 | // This class contains an analysis over the bytecodes to compute |
160 | // this information. The information is stored in a |
161 | // SimulatedOperandStack for each bytecode. |
162 | class ExceptionMessageBuilder : public StackObj { |
163 | |
164 | // The stacks for each bytecode. |
165 | GrowableArray<SimulatedOperandStack*>* _stacks; |
166 | |
167 | // The method. |
168 | Method* _method; |
169 | |
170 | // The number of entries used (the sum of all entries of all stacks). |
171 | int _nr_of_entries; |
172 | |
173 | // If true, we have added at least one new stack. |
174 | bool _added_one; |
175 | |
176 | // If true, we have processed all bytecodes. |
177 | bool _all_processed; |
178 | |
179 | // The maximum number of entries we want to use. This is used to |
180 | // limit the amount of memory we waste for insane methods (as they |
181 | // appear in JCK tests). |
182 | static const int _max_entries = 1000000; |
183 | |
184 | static const int _max_cause_detail = 5; |
185 | |
186 | // Merges the stack the the given bci with the given stack. If there |
187 | // is no stack at the bci, we just put the given stack there. This |
188 | // method doesn't takes ownership of the stack. |
189 | void merge(int bci, SimulatedOperandStack* stack); |
190 | |
191 | // Processes the instruction at the given bci in the method. Returns |
192 | // the size of the instruction. |
193 | int do_instruction(int bci); |
194 | |
195 | bool print_NPE_cause0(outputStream *os, int bci, int slot, int max_detail, |
196 | bool inner_expr = false, const char *prefix = NULL__null); |
197 | |
198 | public: |
199 | |
200 | // Creates an ExceptionMessageBuilder object and runs the analysis |
201 | // building SimulatedOperandStacks for each bytecode in the given |
202 | // method (the method must be rewritten already). Note that you're |
203 | // not allowed to use this object when crossing a safepoint! If the |
204 | // bci is != -1, we only create the stacks as far as needed to get a |
205 | // stack for the bci. |
206 | ExceptionMessageBuilder(Method* method, int bci = -1); |
207 | |
208 | // Releases the resources. |
209 | ~ExceptionMessageBuilder(); |
210 | |
211 | // Returns the number of stacks (this is the size of the method). |
212 | int get_size() { return _stacks->length() - 1; } |
213 | |
214 | // Assuming that a NullPointerException was thrown at the given bci, |
215 | // we return the nr of the slot holding the null reference. If this |
216 | // NPE is created by hand, we return -2 as the slot. If there |
217 | // cannot be a NullPointerException at the bci, -1 is returned. |
218 | int get_NPE_null_slot(int bci); |
219 | |
220 | // Prints a java-like expression for the bytecode that pushed |
221 | // the value to the given slot being live at the given bci. |
222 | // It constructs the expression by recursing backwards over the |
223 | // bytecode using the results of the analysis done in the |
224 | // constructor of ExceptionMessageBuilder. |
225 | // os: The stream to print the message to. |
226 | // bci: The index of the bytecode that caused the NPE. |
227 | // slot: The slot on the operand stack that contains null. |
228 | // The slots are numbered from TOS downwards, i.e., |
229 | // TOS has the slot number 0, that below 1 and so on. |
230 | // |
231 | // Returns false if nothing was printed, else true. |
232 | bool print_NPE_cause(outputStream *os, int bci, int slot); |
233 | |
234 | // Prints a string describing the failed action. |
235 | void print_NPE_failed_action(outputStream *os, int bci); |
236 | }; |
237 | |
238 | // Replaces the following well-known class names: |
239 | // java.lang.Object -> Object |
240 | // java.lang.String -> String |
241 | static char *trim_well_known_class_names_from_signature(char *signature) { |
242 | size_t len = strlen(signature); |
243 | size_t skip_len = strlen("java.lang."); |
244 | size_t min_pattern_len = strlen("java.lang.String"); |
245 | if (len < min_pattern_len) return signature; |
246 | |
247 | for (size_t isrc = 0, idst = 0; isrc <= len; isrc++, idst++) { |
248 | // We must be careful not to trim names like test.java.lang.String. |
249 | if ((isrc == 0 && strncmp(signature + isrc, "java.lang.Object", min_pattern_len) == 0) || |
250 | (isrc == 0 && strncmp(signature + isrc, "java.lang.String", min_pattern_len) == 0) || |
251 | (isrc > 1 && strncmp(signature + isrc-2, ", java.lang.Object", min_pattern_len+2) == 0) || |
252 | (isrc > 1 && strncmp(signature + isrc-2, ", java.lang.String", min_pattern_len+2) == 0) ) { |
253 | isrc += skip_len; |
254 | } |
255 | if (idst != isrc) { |
256 | signature[idst] = signature[isrc]; |
257 | } |
258 | } |
259 | return signature; |
260 | } |
261 | |
262 | // Replaces the following well-known class names: |
263 | // java.lang.Object -> Object |
264 | // java.lang.String -> String |
265 | static void print_klass_name(outputStream *os, Symbol *klass) { |
266 | const char *name = klass->as_klass_external_name(); |
267 | if (strcmp(name, "java.lang.Object") == 0) name = "Object"; |
268 | if (strcmp(name, "java.lang.String") == 0) name = "String"; |
269 | os->print("%s", name); |
270 | } |
271 | |
272 | // Prints the name of the method that is described at constant pool |
273 | // index cp_index in the constant pool of method 'method'. |
274 | static void print_method_name(outputStream *os, Method* method, int cp_index) { |
275 | ResourceMark rm; |
276 | ConstantPool* cp = method->constants(); |
277 | Symbol* klass = cp->klass_ref_at_noresolve(cp_index); |
278 | Symbol* name = cp->name_ref_at(cp_index); |
279 | Symbol* signature = cp->signature_ref_at(cp_index); |
280 | |
281 | print_klass_name(os, klass); |
282 | os->print(".%s(", name->as_C_string()); |
283 | stringStream sig; |
284 | signature->print_as_signature_external_parameters(&sig); |
285 | os->print("%s)", trim_well_known_class_names_from_signature(sig.as_string())); |
286 | } |
287 | |
288 | // Prints the name of the field that is described at constant pool |
289 | // index cp_index in the constant pool of method 'method'. |
290 | static void print_field_and_class(outputStream *os, Method* method, int cp_index) { |
291 | ResourceMark rm; |
292 | ConstantPool* cp = method->constants(); |
293 | Symbol* klass = cp->klass_ref_at_noresolve(cp_index); |
294 | Symbol *name = cp->name_ref_at(cp_index); |
295 | print_klass_name(os, klass); |
296 | os->print(".%s", name->as_C_string()); |
297 | } |
298 | |
299 | // Returns the name of the field that is described at constant pool |
300 | // index cp_index in the constant pool of method 'method'. |
301 | static char const* get_field_name(Method* method, int cp_index) { |
302 | Symbol* name = method->constants()->name_ref_at(cp_index); |
303 | return name->as_C_string(); |
304 | } |
305 | |
306 | static void print_local_var(outputStream *os, unsigned int bci, Method* method, int slot, bool is_parameter) { |
307 | if (method->has_localvariable_table()) { |
308 | for (int i = 0; i < method->localvariable_table_length(); i++) { |
309 | LocalVariableTableElement* elem = method->localvariable_table_start() + i; |
310 | unsigned int start = elem->start_bci; |
311 | unsigned int end = start + elem->length; |
312 | |
313 | if ((bci >= start) && (bci < end) && (elem->slot == slot)) { |
314 | ConstantPool* cp = method->constants(); |
315 | char *var = cp->symbol_at(elem->name_cp_index)->as_C_string(); |
316 | os->print("%s", var); |
317 | |
318 | return; |
319 | } |
320 | } |
321 | } |
322 | |
323 | // Handle at least some cases we know. |
324 | if (!method->is_static() && (slot == 0) && is_parameter) { |
325 | os->print("this"); |
326 | } else { |
327 | int curr = method->is_static() ? 0 : 1; |
328 | SignatureStream ss(method->signature()); |
329 | int param_index = 1; |
330 | bool found = false; |
331 | |
332 | for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) { |
333 | if (ss.at_return_type()) { |
334 | continue; |
335 | } |
336 | int size = type2size[ss.type()]; |
337 | if ((slot >= curr) && (slot < curr + size)) { |
338 | found = true; |
339 | break; |
340 | } |
341 | param_index += 1; |
342 | curr += size; |
343 | } |
344 | |
345 | if (found && is_parameter) { |
346 | os->print("<parameter%d>", param_index); |
347 | } else { |
348 | // This is the best we can do. |
349 | os->print("<local%d>", slot); |
350 | } |
351 | } |
352 | } |
353 | |
354 | StackSlotAnalysisData::StackSlotAnalysisData(BasicType type) : _bci(INVALID), _type(type) {} |
355 | |
356 | StackSlotAnalysisData::StackSlotAnalysisData(int bci, BasicType type) : _bci(bci), _type(type) { |
357 | assert(bci >= 0, "BCI must be >= 0")do { if (!(bci >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 357, "assert(" "bci >= 0" ") failed", "BCI must be >= 0" ); ::breakpoint(); } } while (0); |
358 | assert(bci < 65536, "BCI must be < 65536")do { if (!(bci < 65536)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 358, "assert(" "bci < 65536" ") failed", "BCI must be < 65536" ); ::breakpoint(); } } while (0); |
359 | } |
360 | |
361 | unsigned int StackSlotAnalysisData::get_bci() { |
362 | return _bci; |
363 | } |
364 | |
365 | BasicType StackSlotAnalysisData::get_type() { |
366 | return (BasicType)_type; |
367 | } |
368 | |
369 | StackSlotAnalysisData StackSlotAnalysisData::merge(StackSlotAnalysisData other) { |
370 | if (get_type() != other.get_type()) { |
371 | if (((get_type() == T_OBJECT) || (get_type() == T_ARRAY)) && |
372 | ((other.get_type() == T_OBJECT) || (other.get_type() == T_ARRAY))) { |
373 | if (get_bci() == other.get_bci()) { |
374 | return StackSlotAnalysisData(get_bci(), T_OBJECT); |
375 | } else { |
376 | return StackSlotAnalysisData(T_OBJECT); |
377 | } |
378 | } else { |
379 | return StackSlotAnalysisData(T_CONFLICT); |
380 | } |
381 | } |
382 | |
383 | if (get_bci() == other.get_bci()) { |
384 | return *this; |
385 | } else { |
386 | return StackSlotAnalysisData(get_type()); |
387 | } |
388 | } |
389 | |
390 | SimulatedOperandStack::SimulatedOperandStack(const SimulatedOperandStack ©) { |
391 | for (int i = 0; i < copy.get_size(); i++) { |
392 | push_raw(copy._stack.at(i)); |
393 | } |
394 | _written_local_slots = copy._written_local_slots; |
395 | } |
396 | |
397 | void SimulatedOperandStack::push_raw(StackSlotAnalysisData slotData) { |
398 | if (slotData.get_type() == T_VOID) { |
399 | return; |
400 | } |
401 | |
402 | _stack.push(slotData); |
403 | } |
404 | |
405 | void SimulatedOperandStack::push(StackSlotAnalysisData slotData) { |
406 | if (type2size[slotData.get_type()] == 2) { |
407 | push_raw(slotData); |
408 | push_raw(slotData); |
409 | } else { |
410 | push_raw(slotData); |
411 | } |
412 | } |
413 | |
414 | void SimulatedOperandStack::push(int bci, BasicType type) { |
415 | push(StackSlotAnalysisData(bci, type)); |
416 | } |
417 | |
418 | void SimulatedOperandStack::pop(int slots) { |
419 | for (int i = 0; i < slots; ++i) { |
420 | _stack.pop(); |
421 | } |
422 | |
423 | assert(get_size() >= 0, "Popped too many slots")do { if (!(get_size() >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 423, "assert(" "get_size() >= 0" ") failed", "Popped too many slots" ); ::breakpoint(); } } while (0); |
424 | } |
425 | |
426 | void SimulatedOperandStack::merge(SimulatedOperandStack const& other) { |
427 | assert(get_size() == other.get_size(), "Stacks not of same size")do { if (!(get_size() == other.get_size())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 427, "assert(" "get_size() == other.get_size()" ") failed", "Stacks not of same size"); ::breakpoint(); } } while (0); |
428 | |
429 | for (int i = get_size() - 1; i >= 0; --i) { |
430 | _stack.at_put(i, _stack.at(i).merge(other._stack.at(i))); |
431 | } |
432 | _written_local_slots = _written_local_slots | other._written_local_slots; |
433 | } |
434 | |
435 | int SimulatedOperandStack::get_size() const { |
436 | return _stack.length(); |
437 | } |
438 | |
439 | StackSlotAnalysisData SimulatedOperandStack::get_slot_data(int slot) { |
440 | assert(slot >= 0, "Slot=%d < 0", slot)do { if (!(slot >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 440, "assert(" "slot >= 0" ") failed", "Slot=%d < 0", slot); ::breakpoint(); } } while (0); |
441 | assert(slot < get_size(), "Slot=%d >= size=%d", slot, get_size())do { if (!(slot < get_size())) { (*g_assert_poison) = 'X'; ; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 441, "assert(" "slot < get_size()" ") failed", "Slot=%d >= size=%d" , slot, get_size()); ::breakpoint(); } } while (0); |
442 | |
443 | return _stack.at(get_size() - slot - 1); |
444 | } |
445 | |
446 | void SimulatedOperandStack::set_local_slot_written(int i) { |
447 | // Local slots > 63 are very unlikely. Consider these |
448 | // as written all the time. Saves space and complexity |
449 | // for dynamic data size. |
450 | if (i > 63) return; |
451 | _written_local_slots = _written_local_slots | (1ULL << i); |
452 | } |
453 | |
454 | bool SimulatedOperandStack::local_slot_was_written(int i) { |
455 | if (i > 63) return true; |
456 | return (_written_local_slots & (1ULL << i)) != 0; |
457 | } |
458 | |
459 | ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) : |
460 | _method(method), _nr_of_entries(0), |
461 | _added_one(true), _all_processed(false) { |
462 | |
463 | ConstMethod* const_method = method->constMethod(); |
464 | const int len = const_method->code_size(); |
465 | |
466 | assert(bci >= 0, "BCI too low: %d", bci)do { if (!(bci >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 466, "assert(" "bci >= 0" ") failed", "BCI too low: %d", bci); ::breakpoint(); } } while (0); |
467 | assert(bci < len, "BCI too large: %d size: %d", bci, len)do { if (!(bci < len)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 467, "assert(" "bci < len" ") failed", "BCI too large: %d size: %d" , bci, len); ::breakpoint(); } } while (0); |
468 | |
469 | _stacks = new GrowableArray<SimulatedOperandStack*> (len + 1); |
470 | |
471 | for (int i = 0; i <= len; ++i) { |
472 | _stacks->push(NULL__null); |
473 | } |
474 | |
475 | // Initialize stack a bci 0. |
476 | _stacks->at_put(0, new SimulatedOperandStack()); |
477 | |
478 | // And initialize the start of all exception handlers. |
479 | if (const_method->has_exception_handler()) { |
480 | ExceptionTableElement *et = const_method->exception_table_start(); |
481 | for (int i = 0; i < const_method->exception_table_length(); ++i) { |
482 | u2 index = et[i].handler_pc; |
483 | |
484 | if (_stacks->at(index) == NULL__null) { |
485 | _stacks->at_put(index, new SimulatedOperandStack()); |
486 | _stacks->at(index)->push(index, T_OBJECT); |
487 | } |
488 | } |
489 | } |
490 | |
491 | // Do this until each bytecode has a stack or we haven't |
492 | // added a new stack in one iteration. |
493 | while (!_all_processed && _added_one) { |
494 | _all_processed = true; |
495 | _added_one = false; |
496 | |
497 | for (int i = 0; i < len; ) { |
498 | // Analyse bytecode i. Step by size of the analyzed bytecode to next bytecode. |
499 | i += do_instruction(i); |
500 | |
501 | // If we want the data only for a certain bci, we can possibly end early. |
502 | if ((bci == i) && (_stacks->at(i) != NULL__null)) { |
503 | _all_processed = true; |
504 | break; |
505 | } |
506 | |
507 | if (_nr_of_entries > _max_entries) { |
508 | return; |
509 | } |
510 | } |
511 | } |
512 | } |
513 | |
514 | ExceptionMessageBuilder::~ExceptionMessageBuilder() { |
515 | if (_stacks != NULL__null) { |
516 | for (int i = 0; i < _stacks->length(); ++i) { |
517 | delete _stacks->at(i); |
518 | } |
519 | } |
520 | } |
521 | |
522 | void ExceptionMessageBuilder::merge(int bci, SimulatedOperandStack* stack) { |
523 | assert(stack != _stacks->at(bci), "Cannot merge itself")do { if (!(stack != _stacks->at(bci))) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 523, "assert(" "stack != _stacks->at(bci)" ") failed", "Cannot merge itself" ); ::breakpoint(); } } while (0); |
524 | |
525 | if (_stacks->at(bci) != NULL__null) { |
526 | stack->merge(*_stacks->at(bci)); |
527 | } else { |
528 | // Got a new stack, so count the entries. |
529 | _nr_of_entries += stack->get_size(); |
530 | } |
531 | |
532 | // Replace the stack at this bci with a copy of our new merged stack. |
533 | delete _stacks->at(bci); |
534 | _stacks->at_put(bci, new SimulatedOperandStack(*stack)); |
535 | } |
536 | |
537 | int ExceptionMessageBuilder::do_instruction(int bci) { |
538 | ConstMethod* const_method = _method->constMethod(); |
Value stored to 'const_method' during its initialization is never read | |
539 | address code_base = _method->constMethod()->code_base(); |
540 | |
541 | // We use the java code, since we don't want to cope with all the fast variants. |
542 | int len = Bytecodes::java_length_at(_method, code_base + bci); |
543 | |
544 | // If we have no stack for this bci, we cannot process the bytecode now. |
545 | if (_stacks->at(bci) == NULL__null) { |
546 | _all_processed = false; |
547 | return len; |
548 | } |
549 | |
550 | // Make a local copy of the stack for this bci to work on. |
551 | SimulatedOperandStack* stack = new SimulatedOperandStack(*_stacks->at(bci)); |
552 | |
553 | // dest_bci is != -1 if we branch. |
554 | int dest_bci = -1; |
555 | |
556 | // This is for table and lookup switch. |
557 | static const int initial_length = 2; |
558 | GrowableArray<int> dests(initial_length); |
559 | |
560 | bool flow_ended = false; |
561 | |
562 | // Get the bytecode. |
563 | bool is_wide = false; |
564 | Bytecodes::Code raw_code = Bytecodes::code_at(_method, code_base + bci); |
565 | Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
566 | int pos = bci + 1; |
567 | |
568 | if (code == Bytecodes::_wide) { |
569 | is_wide = true; |
570 | code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
571 | pos += 1; |
572 | } |
573 | |
574 | // Now simulate the action of each bytecode. |
575 | switch (code) { |
576 | case Bytecodes::_nop: |
577 | case Bytecodes::_aconst_null: |
578 | case Bytecodes::_iconst_m1: |
579 | case Bytecodes::_iconst_0: |
580 | case Bytecodes::_iconst_1: |
581 | case Bytecodes::_iconst_2: |
582 | case Bytecodes::_iconst_3: |
583 | case Bytecodes::_iconst_4: |
584 | case Bytecodes::_iconst_5: |
585 | case Bytecodes::_lconst_0: |
586 | case Bytecodes::_lconst_1: |
587 | case Bytecodes::_fconst_0: |
588 | case Bytecodes::_fconst_1: |
589 | case Bytecodes::_fconst_2: |
590 | case Bytecodes::_dconst_0: |
591 | case Bytecodes::_dconst_1: |
592 | case Bytecodes::_bipush: |
593 | case Bytecodes::_sipush: |
594 | case Bytecodes::_iload: |
595 | case Bytecodes::_lload: |
596 | case Bytecodes::_fload: |
597 | case Bytecodes::_dload: |
598 | case Bytecodes::_aload: |
599 | case Bytecodes::_iload_0: |
600 | case Bytecodes::_iload_1: |
601 | case Bytecodes::_iload_2: |
602 | case Bytecodes::_iload_3: |
603 | case Bytecodes::_lload_0: |
604 | case Bytecodes::_lload_1: |
605 | case Bytecodes::_lload_2: |
606 | case Bytecodes::_lload_3: |
607 | case Bytecodes::_fload_0: |
608 | case Bytecodes::_fload_1: |
609 | case Bytecodes::_fload_2: |
610 | case Bytecodes::_fload_3: |
611 | case Bytecodes::_dload_0: |
612 | case Bytecodes::_dload_1: |
613 | case Bytecodes::_dload_2: |
614 | case Bytecodes::_dload_3: |
615 | case Bytecodes::_aload_0: |
616 | case Bytecodes::_aload_1: |
617 | case Bytecodes::_aload_2: |
618 | case Bytecodes::_aload_3: |
619 | case Bytecodes::_iinc: |
620 | case Bytecodes::_new: |
621 | stack->push(bci, Bytecodes::result_type(code)); |
622 | break; |
623 | |
624 | case Bytecodes::_ldc: |
625 | case Bytecodes::_ldc_w: |
626 | case Bytecodes::_ldc2_w: { |
627 | int cp_index; |
628 | ConstantPool* cp = _method->constants(); |
629 | |
630 | if (code == Bytecodes::_ldc) { |
631 | cp_index = *(uint8_t*) (code_base + pos); |
632 | |
633 | if (raw_code == Bytecodes::_fast_aldc) { |
634 | cp_index = cp->object_to_cp_index(cp_index); |
635 | } |
636 | } else { |
637 | if (raw_code == Bytecodes::_fast_aldc_w) { |
638 | cp_index = Bytes::get_native_u2(code_base + pos); |
639 | cp_index = cp->object_to_cp_index(cp_index); |
640 | } |
641 | else { |
642 | cp_index = Bytes::get_Java_u2(code_base + pos); |
643 | } |
644 | } |
645 | |
646 | constantTag tag = cp->tag_at(cp_index); |
647 | if (tag.is_klass() || tag.is_unresolved_klass() || |
648 | tag.is_method() || tag.is_interface_method() || |
649 | tag.is_field() || tag.is_string()) { |
650 | stack->push(bci, T_OBJECT); |
651 | } else if (tag.is_int()) { |
652 | stack->push(bci, T_INT); |
653 | } else if (tag.is_long()) { |
654 | stack->push(bci, T_LONG); |
655 | } else if (tag.is_float()) { |
656 | stack->push(bci, T_FLOAT); |
657 | } else if (tag.is_double()) { |
658 | stack->push(bci, T_DOUBLE); |
659 | } else { |
660 | assert(false, "Unexpected tag")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 660, "assert(" "false" ") failed", "Unexpected tag"); ::breakpoint (); } } while (0); |
661 | } |
662 | break; |
663 | } |
664 | |
665 | case Bytecodes::_iaload: |
666 | case Bytecodes::_faload: |
667 | case Bytecodes::_aaload: |
668 | case Bytecodes::_baload: |
669 | case Bytecodes::_caload: |
670 | case Bytecodes::_saload: |
671 | case Bytecodes::_laload: |
672 | case Bytecodes::_daload: |
673 | stack->pop(2); |
674 | stack->push(bci, Bytecodes::result_type(code)); |
675 | break; |
676 | |
677 | case Bytecodes::_istore: |
678 | case Bytecodes::_lstore: |
679 | case Bytecodes::_fstore: |
680 | case Bytecodes::_dstore: |
681 | case Bytecodes::_astore: |
682 | int index; |
683 | if (is_wide) { |
684 | index = Bytes::get_Java_u2(code_base + bci + 2); |
685 | } else { |
686 | index = *(uint8_t*) (code_base + bci + 1); |
687 | } |
688 | stack->set_local_slot_written(index); |
689 | stack->pop(-Bytecodes::depth(code)); |
690 | break; |
691 | case Bytecodes::_istore_0: |
692 | case Bytecodes::_lstore_0: |
693 | case Bytecodes::_fstore_0: |
694 | case Bytecodes::_dstore_0: |
695 | case Bytecodes::_astore_0: |
696 | stack->set_local_slot_written(0); |
697 | stack->pop(-Bytecodes::depth(code)); |
698 | break; |
699 | case Bytecodes::_istore_1: |
700 | case Bytecodes::_fstore_1: |
701 | case Bytecodes::_lstore_1: |
702 | case Bytecodes::_dstore_1: |
703 | case Bytecodes::_astore_1: |
704 | stack->set_local_slot_written(1); |
705 | stack->pop(-Bytecodes::depth(code)); |
706 | break; |
707 | case Bytecodes::_istore_2: |
708 | case Bytecodes::_lstore_2: |
709 | case Bytecodes::_fstore_2: |
710 | case Bytecodes::_dstore_2: |
711 | case Bytecodes::_astore_2: |
712 | stack->set_local_slot_written(2); |
713 | stack->pop(-Bytecodes::depth(code)); |
714 | break; |
715 | case Bytecodes::_istore_3: |
716 | case Bytecodes::_lstore_3: |
717 | case Bytecodes::_fstore_3: |
718 | case Bytecodes::_dstore_3: |
719 | case Bytecodes::_astore_3: |
720 | stack->set_local_slot_written(3); |
721 | stack->pop(-Bytecodes::depth(code)); |
722 | break; |
723 | case Bytecodes::_iastore: |
724 | case Bytecodes::_lastore: |
725 | case Bytecodes::_fastore: |
726 | case Bytecodes::_dastore: |
727 | case Bytecodes::_aastore: |
728 | case Bytecodes::_bastore: |
729 | case Bytecodes::_castore: |
730 | case Bytecodes::_sastore: |
731 | case Bytecodes::_pop: |
732 | case Bytecodes::_pop2: |
733 | case Bytecodes::_monitorenter: |
734 | case Bytecodes::_monitorexit: |
735 | case Bytecodes::_breakpoint: |
736 | stack->pop(-Bytecodes::depth(code)); |
737 | break; |
738 | |
739 | case Bytecodes::_dup: |
740 | stack->push_raw(stack->get_slot_data(0)); |
741 | break; |
742 | |
743 | case Bytecodes::_dup_x1: { |
744 | StackSlotAnalysisData top1 = stack->get_slot_data(0); |
745 | StackSlotAnalysisData top2 = stack->get_slot_data(1); |
746 | stack->pop(2); |
747 | stack->push_raw(top1); |
748 | stack->push_raw(top2); |
749 | stack->push_raw(top1); |
750 | break; |
751 | } |
752 | |
753 | case Bytecodes::_dup_x2: { |
754 | StackSlotAnalysisData top1 = stack->get_slot_data(0); |
755 | StackSlotAnalysisData top2 = stack->get_slot_data(1); |
756 | StackSlotAnalysisData top3 = stack->get_slot_data(2); |
757 | stack->pop(3); |
758 | stack->push_raw(top1); |
759 | stack->push_raw(top3); |
760 | stack->push_raw(top2); |
761 | stack->push_raw(top1); |
762 | break; |
763 | } |
764 | |
765 | case Bytecodes::_dup2: |
766 | stack->push_raw(stack->get_slot_data(1)); |
767 | // The former '0' entry is now at '1'. |
768 | stack->push_raw(stack->get_slot_data(1)); |
769 | break; |
770 | |
771 | case Bytecodes::_dup2_x1: { |
772 | StackSlotAnalysisData top1 = stack->get_slot_data(0); |
773 | StackSlotAnalysisData top2 = stack->get_slot_data(1); |
774 | StackSlotAnalysisData top3 = stack->get_slot_data(2); |
775 | stack->pop(3); |
776 | stack->push_raw(top2); |
777 | stack->push_raw(top1); |
778 | stack->push_raw(top3); |
779 | stack->push_raw(top2); |
780 | stack->push_raw(top1); |
781 | break; |
782 | } |
783 | |
784 | case Bytecodes::_dup2_x2: { |
785 | StackSlotAnalysisData top1 = stack->get_slot_data(0); |
786 | StackSlotAnalysisData top2 = stack->get_slot_data(1); |
787 | StackSlotAnalysisData top3 = stack->get_slot_data(2); |
788 | StackSlotAnalysisData top4 = stack->get_slot_data(3); |
789 | stack->pop(4); |
790 | stack->push_raw(top2); |
791 | stack->push_raw(top1); |
792 | stack->push_raw(top4); |
793 | stack->push_raw(top3); |
794 | stack->push_raw(top2); |
795 | stack->push_raw(top1); |
796 | break; |
797 | } |
798 | |
799 | case Bytecodes::_swap: { |
800 | StackSlotAnalysisData top1 = stack->get_slot_data(0); |
801 | StackSlotAnalysisData top2 = stack->get_slot_data(1); |
802 | stack->pop(2); |
803 | stack->push(top1); |
804 | stack->push(top2); |
805 | break; |
806 | } |
807 | |
808 | case Bytecodes::_iadd: |
809 | case Bytecodes::_ladd: |
810 | case Bytecodes::_fadd: |
811 | case Bytecodes::_dadd: |
812 | case Bytecodes::_isub: |
813 | case Bytecodes::_lsub: |
814 | case Bytecodes::_fsub: |
815 | case Bytecodes::_dsub: |
816 | case Bytecodes::_imul: |
817 | case Bytecodes::_lmul: |
818 | case Bytecodes::_fmul: |
819 | case Bytecodes::_dmul: |
820 | case Bytecodes::_idiv: |
821 | case Bytecodes::_ldiv: |
822 | case Bytecodes::_fdiv: |
823 | case Bytecodes::_ddiv: |
824 | case Bytecodes::_irem: |
825 | case Bytecodes::_lrem: |
826 | case Bytecodes::_frem: |
827 | case Bytecodes::_drem: |
828 | case Bytecodes::_iand: |
829 | case Bytecodes::_land: |
830 | case Bytecodes::_ior: |
831 | case Bytecodes::_lor: |
832 | case Bytecodes::_ixor: |
833 | case Bytecodes::_lxor: |
834 | stack->pop(2 * type2size[Bytecodes::result_type(code)]); |
835 | stack->push(bci, Bytecodes::result_type(code)); |
836 | break; |
837 | |
838 | case Bytecodes::_ineg: |
839 | case Bytecodes::_lneg: |
840 | case Bytecodes::_fneg: |
841 | case Bytecodes::_dneg: |
842 | stack->pop(type2size[Bytecodes::result_type(code)]); |
843 | stack->push(bci, Bytecodes::result_type(code)); |
844 | break; |
845 | |
846 | case Bytecodes::_ishl: |
847 | case Bytecodes::_lshl: |
848 | case Bytecodes::_ishr: |
849 | case Bytecodes::_lshr: |
850 | case Bytecodes::_iushr: |
851 | case Bytecodes::_lushr: |
852 | stack->pop(1 + type2size[Bytecodes::result_type(code)]); |
853 | stack->push(bci, Bytecodes::result_type(code)); |
854 | break; |
855 | |
856 | case Bytecodes::_i2l: |
857 | case Bytecodes::_i2f: |
858 | case Bytecodes::_i2d: |
859 | case Bytecodes::_f2i: |
860 | case Bytecodes::_f2l: |
861 | case Bytecodes::_f2d: |
862 | case Bytecodes::_i2b: |
863 | case Bytecodes::_i2c: |
864 | case Bytecodes::_i2s: |
865 | stack->pop(1); |
866 | stack->push(bci, Bytecodes::result_type(code)); |
867 | break; |
868 | |
869 | case Bytecodes::_l2i: |
870 | case Bytecodes::_l2f: |
871 | case Bytecodes::_l2d: |
872 | case Bytecodes::_d2i: |
873 | case Bytecodes::_d2l: |
874 | case Bytecodes::_d2f: |
875 | stack->pop(2); |
876 | stack->push(bci, Bytecodes::result_type(code)); |
877 | break; |
878 | |
879 | case Bytecodes::_lcmp: |
880 | case Bytecodes::_fcmpl: |
881 | case Bytecodes::_fcmpg: |
882 | case Bytecodes::_dcmpl: |
883 | case Bytecodes::_dcmpg: |
884 | stack->pop(1 - Bytecodes::depth(code)); |
885 | stack->push(bci, T_INT); |
886 | break; |
887 | |
888 | case Bytecodes::_ifeq: |
889 | case Bytecodes::_ifne: |
890 | case Bytecodes::_iflt: |
891 | case Bytecodes::_ifge: |
892 | case Bytecodes::_ifgt: |
893 | case Bytecodes::_ifle: |
894 | case Bytecodes::_if_icmpeq: |
895 | case Bytecodes::_if_icmpne: |
896 | case Bytecodes::_if_icmplt: |
897 | case Bytecodes::_if_icmpge: |
898 | case Bytecodes::_if_icmpgt: |
899 | case Bytecodes::_if_icmple: |
900 | case Bytecodes::_if_acmpeq: |
901 | case Bytecodes::_if_acmpne: |
902 | case Bytecodes::_ifnull: |
903 | case Bytecodes::_ifnonnull: |
904 | stack->pop(-Bytecodes::depth(code)); |
905 | dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos); |
906 | break; |
907 | |
908 | case Bytecodes::_jsr: |
909 | // NOTE: Bytecodes has wrong depth for jsr. |
910 | stack->push(bci, T_ADDRESS); |
911 | dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos); |
912 | flow_ended = true; |
913 | break; |
914 | |
915 | case Bytecodes::_jsr_w: { |
916 | // NOTE: Bytecodes has wrong depth for jsr. |
917 | stack->push(bci, T_ADDRESS); |
918 | dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos); |
919 | flow_ended = true; |
920 | break; |
921 | } |
922 | |
923 | case Bytecodes::_ret: |
924 | // We don't track local variables, so we cannot know were we |
925 | // return. This makes the stacks imprecise, but we have to |
926 | // live with that. |
927 | flow_ended = true; |
928 | break; |
929 | |
930 | case Bytecodes::_tableswitch: { |
931 | stack->pop(1); |
932 | pos = (pos + 3) & ~3; |
933 | dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos); |
934 | int low = (int32_t) Bytes::get_Java_u4(code_base + pos + 4); |
935 | int high = (int32_t) Bytes::get_Java_u4(code_base + pos + 8); |
936 | |
937 | for (int64_t i = low; i <= high; ++i) { |
938 | dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 4 * (i - low))); |
939 | } |
940 | |
941 | break; |
942 | } |
943 | |
944 | case Bytecodes::_lookupswitch: { |
945 | stack->pop(1); |
946 | pos = (pos + 3) & ~3; |
947 | dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos); |
948 | int nr_of_dests = (int32_t) Bytes::get_Java_u4(code_base + pos + 4); |
949 | |
950 | for (int i = 0; i < nr_of_dests; ++i) { |
951 | dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 8 * i)); |
952 | } |
953 | |
954 | break; |
955 | } |
956 | |
957 | case Bytecodes::_ireturn: |
958 | case Bytecodes::_lreturn: |
959 | case Bytecodes::_freturn: |
960 | case Bytecodes::_dreturn: |
961 | case Bytecodes::_areturn: |
962 | case Bytecodes::_return: |
963 | case Bytecodes::_athrow: |
964 | stack->pop(-Bytecodes::depth(code)); |
965 | flow_ended = true; |
966 | break; |
967 | |
968 | case Bytecodes::_getstatic: |
969 | case Bytecodes::_getfield: { |
970 | // Find out the type of the field accessed. |
971 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
972 | ConstantPool* cp = _method->constants(); |
973 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
974 | int type_index = cp->signature_ref_index_at(name_and_type_index); |
975 | Symbol* signature = cp->symbol_at(type_index); |
976 | // Simulate the bytecode: pop the address, push the 'value' loaded |
977 | // from the field. |
978 | stack->pop(1 - Bytecodes::depth(code)); |
979 | stack->push(bci, Signature::basic_type(signature)); |
980 | break; |
981 | } |
982 | |
983 | case Bytecodes::_putstatic: |
984 | case Bytecodes::_putfield: { |
985 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
986 | ConstantPool* cp = _method->constants(); |
987 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
988 | int type_index = cp->signature_ref_index_at(name_and_type_index); |
989 | Symbol* signature = cp->symbol_at(type_index); |
990 | BasicType bt = Signature::basic_type(signature); |
991 | stack->pop(type2size[bt] - Bytecodes::depth(code) - 1); |
992 | break; |
993 | } |
994 | |
995 | case Bytecodes::_invokevirtual: |
996 | case Bytecodes::_invokespecial: |
997 | case Bytecodes::_invokestatic: |
998 | case Bytecodes::_invokeinterface: |
999 | case Bytecodes::_invokedynamic: { |
1000 | ConstantPool* cp = _method->constants(); |
1001 | int cp_index; |
1002 | |
1003 | if (code == Bytecodes::_invokedynamic) { |
1004 | cp_index = ((int) Bytes::get_native_u4(code_base + pos)); |
1005 | } else { |
1006 | cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1007 | } |
1008 | |
1009 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
1010 | int type_index = cp->signature_ref_index_at(name_and_type_index); |
1011 | Symbol* signature = cp->symbol_at(type_index); |
1012 | |
1013 | if ((code != Bytecodes::_invokestatic) && (code != Bytecodes::_invokedynamic)) { |
1014 | // Pop receiver. |
1015 | stack->pop(1); |
1016 | } |
1017 | |
1018 | stack->pop(ArgumentSizeComputer(signature).size()); |
1019 | ResultTypeFinder result_type(signature); |
1020 | stack->push(bci, result_type.type()); |
1021 | break; |
1022 | } |
1023 | |
1024 | case Bytecodes::_newarray: |
1025 | case Bytecodes::_anewarray: |
1026 | case Bytecodes::_instanceof: |
1027 | stack->pop(1); |
1028 | stack->push(bci, Bytecodes::result_type(code)); |
1029 | break; |
1030 | |
1031 | case Bytecodes::_arraylength: |
1032 | stack->pop(1); |
1033 | stack->push(bci, T_INT); |
1034 | break; |
1035 | |
1036 | case Bytecodes::_checkcast: |
1037 | break; |
1038 | |
1039 | case Bytecodes::_multianewarray: |
1040 | stack->pop(*(uint8_t*) (code_base + pos + 2)); |
1041 | stack->push(bci, T_OBJECT); |
1042 | break; |
1043 | |
1044 | case Bytecodes::_goto: |
1045 | stack->pop(-Bytecodes::depth(code)); |
1046 | dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos); |
1047 | flow_ended = true; |
1048 | break; |
1049 | |
1050 | |
1051 | case Bytecodes::_goto_w: |
1052 | stack->pop(-Bytecodes::depth(code)); |
1053 | dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos); |
1054 | flow_ended = true; |
1055 | break; |
1056 | |
1057 | default: |
1058 | // Allow at least the bcis which have stack info to work. |
1059 | _all_processed = false; |
1060 | _added_one = false; |
1061 | delete stack; |
1062 | |
1063 | return len; |
1064 | } |
1065 | |
1066 | // Put new stack to the next instruction, if we might reach it from |
1067 | // this bci. |
1068 | if (!flow_ended) { |
1069 | if (_stacks->at(bci + len) == NULL__null) { |
1070 | _added_one = true; |
1071 | } |
1072 | merge(bci + len, stack); |
1073 | } |
1074 | |
1075 | // Put the stack to the branch target too. |
1076 | if (dest_bci != -1) { |
1077 | if (_stacks->at(dest_bci) == NULL__null) { |
1078 | _added_one = true; |
1079 | } |
1080 | merge(dest_bci, stack); |
1081 | } |
1082 | |
1083 | // If we have more than one branch target, process these too. |
1084 | for (int64_t i = 0; i < dests.length(); ++i) { |
1085 | if (_stacks->at(dests.at(i)) == NULL__null) { |
1086 | _added_one = true; |
1087 | } |
1088 | merge(dests.at(i), stack); |
1089 | } |
1090 | |
1091 | delete stack; |
1092 | |
1093 | return len; |
1094 | } |
1095 | |
1096 | #define INVALID_BYTECODE_ENCOUNTERED-1 -1 |
1097 | #define NPE_EXPLICIT_CONSTRUCTED-2 -2 |
1098 | int ExceptionMessageBuilder::get_NPE_null_slot(int bci) { |
1099 | // Get the bytecode. |
1100 | address code_base = _method->constMethod()->code_base(); |
1101 | Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
1102 | int pos = bci + 1; // Position of argument of the bytecode. |
1103 | if (code == Bytecodes::_wide) { |
1104 | code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
1105 | pos += 1; |
1106 | } |
1107 | |
1108 | switch (code) { |
1109 | case Bytecodes::_getfield: |
1110 | case Bytecodes::_arraylength: |
1111 | case Bytecodes::_athrow: |
1112 | case Bytecodes::_monitorenter: |
1113 | case Bytecodes::_monitorexit: |
1114 | return 0; |
1115 | case Bytecodes::_iaload: |
1116 | case Bytecodes::_faload: |
1117 | case Bytecodes::_aaload: |
1118 | case Bytecodes::_baload: |
1119 | case Bytecodes::_caload: |
1120 | case Bytecodes::_saload: |
1121 | case Bytecodes::_laload: |
1122 | case Bytecodes::_daload: |
1123 | return 1; |
1124 | case Bytecodes::_iastore: |
1125 | case Bytecodes::_fastore: |
1126 | case Bytecodes::_aastore: |
1127 | case Bytecodes::_bastore: |
1128 | case Bytecodes::_castore: |
1129 | case Bytecodes::_sastore: |
1130 | return 2; |
1131 | case Bytecodes::_lastore: |
1132 | case Bytecodes::_dastore: |
1133 | return 3; |
1134 | case Bytecodes::_putfield: { |
1135 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1136 | ConstantPool* cp = _method->constants(); |
1137 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
1138 | int type_index = cp->signature_ref_index_at(name_and_type_index); |
1139 | Symbol* signature = cp->symbol_at(type_index); |
1140 | BasicType bt = Signature::basic_type(signature); |
1141 | return type2size[bt]; |
1142 | } |
1143 | case Bytecodes::_invokevirtual: |
1144 | case Bytecodes::_invokespecial: |
1145 | case Bytecodes::_invokeinterface: { |
1146 | int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1147 | ConstantPool* cp = _method->constants(); |
1148 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
1149 | int name_index = cp->name_ref_index_at(name_and_type_index); |
1150 | Symbol* name = cp->symbol_at(name_index); |
1151 | |
1152 | // Assume the the call of a constructor can never cause a NullPointerException |
1153 | // (which is true in Java). This is mainly used to avoid generating wrong |
1154 | // messages for NullPointerExceptions created explicitly by new in Java code. |
1155 | if (name != vmSymbols::object_initializer_name()) { |
1156 | int type_index = cp->signature_ref_index_at(name_and_type_index); |
1157 | Symbol* signature = cp->symbol_at(type_index); |
1158 | // The 'this' parameter was null. Return the slot of it. |
1159 | return ArgumentSizeComputer(signature).size(); |
1160 | } else { |
1161 | return NPE_EXPLICIT_CONSTRUCTED-2; |
1162 | } |
1163 | } |
1164 | |
1165 | default: |
1166 | break; |
1167 | } |
1168 | |
1169 | return INVALID_BYTECODE_ENCOUNTERED-1; |
1170 | } |
1171 | |
1172 | bool ExceptionMessageBuilder::print_NPE_cause(outputStream* os, int bci, int slot) { |
1173 | if (print_NPE_cause0(os, bci, slot, _max_cause_detail, false, " because \"")) { |
1174 | os->print("\" is null"); |
1175 | return true; |
1176 | } |
1177 | return false; |
1178 | } |
1179 | |
1180 | // Recursively print what was null. |
1181 | // |
1182 | // Go to the bytecode that pushed slot 'slot' on the operand stack |
1183 | // at bytecode 'bci'. Compute a message for that bytecode. If |
1184 | // necessary (array, field), recur further. |
1185 | // At most do max_detail recursions. |
1186 | // Prefix is used to print a proper beginning of the whole |
1187 | // sentence. |
1188 | // inner_expr is used to omit some text, like 'static' in |
1189 | // inner expressions like array subscripts. |
1190 | // |
1191 | // Returns true if something was printed. |
1192 | // |
1193 | bool ExceptionMessageBuilder::print_NPE_cause0(outputStream* os, int bci, int slot, |
1194 | int max_detail, |
1195 | bool inner_expr, const char *prefix) { |
1196 | assert(bci >= 0, "BCI too low")do { if (!(bci >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 1196, "assert(" "bci >= 0" ") failed", "BCI too low"); :: breakpoint(); } } while (0); |
1197 | assert(bci < get_size(), "BCI too large")do { if (!(bci < get_size())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 1197, "assert(" "bci < get_size()" ") failed", "BCI too large" ); ::breakpoint(); } } while (0); |
1198 | |
1199 | if (max_detail <= 0) { |
1200 | return false; |
1201 | } |
1202 | |
1203 | if (_stacks->at(bci) == NULL__null) { |
1204 | return false; |
1205 | } |
1206 | |
1207 | SimulatedOperandStack* stack = _stacks->at(bci); |
1208 | assert(slot >= 0, "Slot nr. too low")do { if (!(slot >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 1208, "assert(" "slot >= 0" ") failed", "Slot nr. too low" ); ::breakpoint(); } } while (0); |
1209 | assert(slot < stack->get_size(), "Slot nr. too large")do { if (!(slot < stack->get_size())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 1209, "assert(" "slot < stack->get_size()" ") failed" , "Slot nr. too large"); ::breakpoint(); } } while (0); |
1210 | |
1211 | StackSlotAnalysisData slotData = stack->get_slot_data(slot); |
1212 | |
1213 | if (!slotData.has_bci()) { |
1214 | return false; |
1215 | } |
1216 | |
1217 | // Get the bytecode. |
1218 | unsigned int source_bci = slotData.get_bci(); |
1219 | address code_base = _method->constMethod()->code_base(); |
1220 | Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci); |
1221 | bool is_wide = false; |
1222 | int pos = source_bci + 1; |
1223 | |
1224 | if (code == Bytecodes::_wide) { |
1225 | is_wide = true; |
1226 | code = Bytecodes::java_code_at(_method, code_base + source_bci + 1); |
1227 | pos += 1; |
1228 | } |
1229 | |
1230 | if (max_detail == _max_cause_detail && |
1231 | prefix != NULL__null && |
1232 | code != Bytecodes::_invokevirtual && |
1233 | code != Bytecodes::_invokespecial && |
1234 | code != Bytecodes::_invokestatic && |
1235 | code != Bytecodes::_invokeinterface) { |
1236 | os->print("%s", prefix); |
1237 | } |
1238 | |
1239 | switch (code) { |
1240 | case Bytecodes::_iload_0: |
1241 | case Bytecodes::_aload_0: |
1242 | print_local_var(os, source_bci, _method, 0, !stack->local_slot_was_written(0)); |
1243 | return true; |
1244 | |
1245 | case Bytecodes::_iload_1: |
1246 | case Bytecodes::_aload_1: |
1247 | print_local_var(os, source_bci, _method, 1, !stack->local_slot_was_written(1)); |
1248 | return true; |
1249 | |
1250 | case Bytecodes::_iload_2: |
1251 | case Bytecodes::_aload_2: |
1252 | print_local_var(os, source_bci, _method, 2, !stack->local_slot_was_written(2)); |
1253 | return true; |
1254 | |
1255 | case Bytecodes::_iload_3: |
1256 | case Bytecodes::_aload_3: |
1257 | print_local_var(os, source_bci, _method, 3, !stack->local_slot_was_written(3)); |
1258 | return true; |
1259 | |
1260 | case Bytecodes::_iload: |
1261 | case Bytecodes::_aload: { |
1262 | int index; |
1263 | if (is_wide) { |
1264 | index = Bytes::get_Java_u2(code_base + source_bci + 2); |
1265 | } else { |
1266 | index = *(uint8_t*) (code_base + source_bci + 1); |
1267 | } |
1268 | print_local_var(os, source_bci, _method, index, !stack->local_slot_was_written(index)); |
1269 | return true; |
1270 | } |
1271 | |
1272 | case Bytecodes::_aconst_null: |
1273 | os->print("null"); |
1274 | return true; |
1275 | case Bytecodes::_iconst_m1: |
1276 | os->print("-1"); |
1277 | return true; |
1278 | case Bytecodes::_iconst_0: |
1279 | os->print("0"); |
1280 | return true; |
1281 | case Bytecodes::_iconst_1: |
1282 | os->print("1"); |
1283 | return true; |
1284 | case Bytecodes::_iconst_2: |
1285 | os->print("2"); |
1286 | return true; |
1287 | case Bytecodes::_iconst_3: |
1288 | os->print("3"); |
1289 | return true; |
1290 | case Bytecodes::_iconst_4: |
1291 | os->print("4"); |
1292 | return true; |
1293 | case Bytecodes::_iconst_5: |
1294 | os->print("5"); |
1295 | return true; |
1296 | case Bytecodes::_bipush: { |
1297 | jbyte con = *(jbyte*) (code_base + source_bci + 1); |
1298 | os->print("%d", con); |
1299 | return true; |
1300 | } |
1301 | case Bytecodes::_sipush: { |
1302 | u2 con = Bytes::get_Java_u2(code_base + source_bci + 1); |
1303 | os->print("%d", con); |
1304 | return true; |
1305 | } |
1306 | case Bytecodes::_iaload: |
1307 | case Bytecodes::_aaload: { |
1308 | // Print the 'name' of the array. Go back to the bytecode that |
1309 | // pushed the array reference on the operand stack. |
1310 | if (!print_NPE_cause0(os, source_bci, 1, max_detail - 1, inner_expr)) { |
1311 | // Returned false. Max recursion depth was reached. Print dummy. |
1312 | os->print("<array>"); |
1313 | } |
1314 | os->print("["); |
1315 | // Print the index expression. Go back to the bytecode that |
1316 | // pushed the index on the operand stack. |
1317 | // inner_expr == true so we don't print unwanted strings |
1318 | // as "The return value of'". And don't decrement max_detail so we always |
1319 | // get a value here and only cancel out on the dereference. |
1320 | if (!print_NPE_cause0(os, source_bci, 0, max_detail, true)) { |
1321 | // Returned false. We don't print complex array index expressions. Print placeholder. |
1322 | os->print("..."); |
1323 | } |
1324 | os->print("]"); |
1325 | return true; |
1326 | } |
1327 | |
1328 | case Bytecodes::_getstatic: { |
1329 | int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG; |
1330 | print_field_and_class(os, _method, cp_index); |
1331 | return true; |
1332 | } |
1333 | |
1334 | case Bytecodes::_getfield: { |
1335 | // Print the sender. Go back to the bytecode that |
1336 | // pushed the sender on the operand stack. |
1337 | if (print_NPE_cause0(os, source_bci, 0, max_detail - 1, inner_expr)) { |
1338 | os->print("."); |
1339 | } |
1340 | int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG; |
1341 | os->print("%s", get_field_name(_method, cp_index)); |
1342 | return true; |
1343 | } |
1344 | |
1345 | case Bytecodes::_invokevirtual: |
1346 | case Bytecodes::_invokespecial: |
1347 | case Bytecodes::_invokestatic: |
1348 | case Bytecodes::_invokeinterface: { |
1349 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1350 | if (max_detail == _max_cause_detail && !inner_expr) { |
1351 | os->print(" because the return value of \""); |
1352 | } |
1353 | print_method_name(os, _method, cp_index); |
1354 | return true; |
1355 | } |
1356 | |
1357 | default: break; |
1358 | } |
1359 | return false; |
1360 | } |
1361 | |
1362 | void ExceptionMessageBuilder::print_NPE_failed_action(outputStream *os, int bci) { |
1363 | |
1364 | // Get the bytecode. |
1365 | address code_base = _method->constMethod()->code_base(); |
1366 | Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci); |
1367 | int pos = bci + 1; |
1368 | if (code == Bytecodes::_wide) { |
1369 | code = Bytecodes::java_code_at(_method, code_base + bci + 1); |
1370 | pos += 1; |
1371 | } |
1372 | |
1373 | switch (code) { |
1374 | case Bytecodes::_iaload: |
1375 | os->print("Cannot load from int array"); break; |
1376 | case Bytecodes::_faload: |
1377 | os->print("Cannot load from float array"); break; |
1378 | case Bytecodes::_aaload: |
1379 | os->print("Cannot load from object array"); break; |
1380 | case Bytecodes::_baload: |
1381 | os->print("Cannot load from byte/boolean array"); break; |
1382 | case Bytecodes::_caload: |
1383 | os->print("Cannot load from char array"); break; |
1384 | case Bytecodes::_saload: |
1385 | os->print("Cannot load from short array"); break; |
1386 | case Bytecodes::_laload: |
1387 | os->print("Cannot load from long array"); break; |
1388 | case Bytecodes::_daload: |
1389 | os->print("Cannot load from double array"); break; |
1390 | |
1391 | case Bytecodes::_iastore: |
1392 | os->print("Cannot store to int array"); break; |
1393 | case Bytecodes::_fastore: |
1394 | os->print("Cannot store to float array"); break; |
1395 | case Bytecodes::_aastore: |
1396 | os->print("Cannot store to object array"); break; |
1397 | case Bytecodes::_bastore: |
1398 | os->print("Cannot store to byte/boolean array"); break; |
1399 | case Bytecodes::_castore: |
1400 | os->print("Cannot store to char array"); break; |
1401 | case Bytecodes::_sastore: |
1402 | os->print("Cannot store to short array"); break; |
1403 | case Bytecodes::_lastore: |
1404 | os->print("Cannot store to long array"); break; |
1405 | case Bytecodes::_dastore: |
1406 | os->print("Cannot store to double array"); break; |
1407 | |
1408 | case Bytecodes::_arraylength: |
1409 | os->print("Cannot read the array length"); break; |
1410 | case Bytecodes::_athrow: |
1411 | os->print("Cannot throw exception"); break; |
1412 | case Bytecodes::_monitorenter: |
1413 | os->print("Cannot enter synchronized block"); break; |
1414 | case Bytecodes::_monitorexit: |
1415 | os->print("Cannot exit synchronized block"); break; |
1416 | case Bytecodes::_getfield: { |
1417 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1418 | ConstantPool* cp = _method->constants(); |
1419 | int name_and_type_index = cp->name_and_type_ref_index_at(cp_index); |
1420 | int name_index = cp->name_ref_index_at(name_and_type_index); |
1421 | Symbol* name = cp->symbol_at(name_index); |
1422 | os->print("Cannot read field \"%s\"", name->as_C_string()); |
1423 | } break; |
1424 | case Bytecodes::_putfield: { |
1425 | int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1426 | os->print("Cannot assign field \"%s\"", get_field_name(_method, cp_index)); |
1427 | } break; |
1428 | case Bytecodes::_invokevirtual: |
1429 | case Bytecodes::_invokespecial: |
1430 | case Bytecodes::_invokeinterface: { |
1431 | int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG)+ ConstantPool::CPCACHE_INDEX_TAG; |
1432 | os->print("Cannot invoke \""); |
1433 | print_method_name(os, _method, cp_index); |
1434 | os->print("\""); |
1435 | } break; |
1436 | |
1437 | default: |
1438 | assert(0, "We should have checked this bytecode in get_NPE_null_slot().")do { if (!(0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/interpreter/bytecodeUtils.cpp" , 1438, "assert(" "0" ") failed", "We should have checked this bytecode in get_NPE_null_slot()." ); ::breakpoint(); } } while (0); |
1439 | break; |
1440 | } |
1441 | } |
1442 | |
1443 | // Main API |
1444 | bool BytecodeUtils::get_NPE_message_at(outputStream* ss, Method* method, int bci) { |
1445 | |
1446 | NoSafepointVerifier _nsv; // Cannot use this object over a safepoint. |
1447 | |
1448 | // If this NPE was created via reflection, we have no real NPE. |
1449 | if (method->method_holder() == |
1450 | vmClasses::reflect_NativeConstructorAccessorImpl_klass()) { |
1451 | return false; |
1452 | } |
1453 | |
1454 | // Analyse the bytecodes. |
1455 | ResourceMark rm; |
1456 | ExceptionMessageBuilder emb(method, bci); |
1457 | |
1458 | // The slot of the operand stack that contains the null reference. |
1459 | // Also checks for NPE explicitly constructed and returns NPE_EXPLICIT_CONSTRUCTED. |
1460 | int slot = emb.get_NPE_null_slot(bci); |
1461 | |
1462 | // Build the message. |
1463 | if (slot == NPE_EXPLICIT_CONSTRUCTED-2) { |
1464 | // We don't want to print a message. |
1465 | return false; |
1466 | } else if (slot == INVALID_BYTECODE_ENCOUNTERED-1) { |
1467 | // We encountered a bytecode that does not dereference a reference. |
1468 | DEBUG_ONLY(ss->print("There cannot be a NullPointerException at bci %d of method %s",ss->print("There cannot be a NullPointerException at bci %d of method %s" , bci, method->external_name()) |
1469 | bci, method->external_name()))ss->print("There cannot be a NullPointerException at bci %d of method %s" , bci, method->external_name()); |
1470 | NOT_DEBUG(return false); |
1471 | } else { |
1472 | // Print string describing which action (bytecode) could not be |
1473 | // performed because of the null reference. |
1474 | emb.print_NPE_failed_action(ss, bci); |
1475 | // Print a description of what is null. |
1476 | if (!emb.print_NPE_cause(ss, bci, slot)) { |
1477 | // Nothing was printed. End the sentence without the 'because' |
1478 | // subordinate sentence. |
1479 | } |
1480 | } |
1481 | return true; |
1482 | } |