< prev index next >

src/hotspot/share/interpreter/bytecodeUtils.cpp

Print this page
rev 56326 : 8218628: Add detailed message to NullPointerException describing what is null.
Summary: This is the implementation of JEP 358: Helpful NullPointerExceptions.
Reviewed-by: coleenp, clanger, rschmelter
rev 56327 : [mq]: find_local_stores.patch


  65   StackSlotAnalysisData(int bci, BasicType type);
  66 
  67   enum {
  68     // An invalid bytecode index, as > 65535.
  69     INVALID = 0x1FFFF
  70   };
  71 
  72   // Returns the bci. If the bci is invalid, INVALID is returned.
  73   unsigned int get_bci();
  74 
  75   // Returns true, if the bci is not invalid.
  76   bool has_bci() { return get_bci() != INVALID; }
  77 
  78   // Returns the type of the slot data.
  79   BasicType get_type();
  80 };
  81 
  82 // A stack consisting of SimulatedOperandStackEntries.
  83 // This represents the analysis information for the operand stack
  84 // for a given bytecode at a given bci.


  85 class SimulatedOperandStack: CHeapObj<mtInternal> {
  86 
  87  private:
  88 
  89   friend class ExceptionMessageBuilder;
  90   friend class StackSlotAnalysisData;
  91 
  92   // The stack.
  93   GrowableArray<StackSlotAnalysisData> _stack;
  94 
  95   SimulatedOperandStack() { };














  96   SimulatedOperandStack(const SimulatedOperandStack &copy);
  97 
  98   // Pushes the given slot data.
  99   void push_raw(StackSlotAnalysisData slotData);
 100 
 101   // Like push_raw, but if the slotData has type long or double, we push two.
 102   void push(StackSlotAnalysisData slotData);
 103 
 104   // Like push(slotData), but using bci/type to create an instance of
 105   // StackSlotAnalysisData first.
 106   void push(int bci, BasicType type);
 107 
 108   // Pops the given number of entries.
 109   void pop(int slots);
 110 
 111   // Merges this with the given stack by merging all entries. The
 112   // size of the stacks must be the same.
 113   void merge(SimulatedOperandStack const& other);
 114 
 115  public:
 116 
 117   // Returns the size of the stack.
 118   int get_size() const;
 119 
 120   // Returns the slot data at the given index. Slot 0 is top of stack.
 121   StackSlotAnalysisData get_slot_data(int slot);






 122 };
 123 
 124 // Helper class to build internal exception messages for exceptions
 125 // that are thrown because prerequisites to execute a bytecode
 126 // are not met.
 127 // E.g., if a NPE is thrown because an iload can not be executed
 128 // by the VM because the reference to load from is null.
 129 //
 130 // It analyses the bytecode to assemble Java-like message text
 131 // to give precise information where in a larger expression the
 132 // exception occured.
 133 //
 134 // To assemble this message text, it is needed to know how
 135 // operand stack slot entries were pushed on the operand stack.
 136 // This class contains an analysis over the bytecodes to compute
 137 // this information. The information is stored in a
 138 // SimulatedOperandStack for each bytecode.
 139 class ExceptionMessageBuilder : public StackObj {
 140 
 141   // The stacks for each bytecode.


 263 }
 264 
 265 // Prints the name of the field that is described at constant pool
 266 // index cp_index in the constant pool of method 'method'.
 267 static void print_field_and_class(outputStream *os, Method* method, int cp_index) {
 268   ResourceMark rm;
 269   ConstantPool* cp = method->constants();
 270   Symbol* klass    = cp->klass_ref_at_noresolve(cp_index);
 271   Symbol *name     = cp->name_ref_at(cp_index);
 272   print_klass_name(os, klass);
 273   os->print(".%s", name->as_C_string());
 274 }
 275 
 276 // Returns the name of the field that is described at constant pool
 277 // index cp_index in the constant pool of method 'method'.
 278 static char const* get_field_name(Method* method, int cp_index) {
 279   Symbol* name = method->constants()->name_ref_at(cp_index);
 280   return name->as_C_string();
 281 }
 282 
 283 static void print_local_var(outputStream *os, unsigned int bci, Method* method, int slot) {
 284   if (method->has_localvariable_table()) {
 285     for (int i = 0; i < method->localvariable_table_length(); i++) {
 286       LocalVariableTableElement* elem = method->localvariable_table_start() + i;
 287       unsigned int start = elem->start_bci;
 288       unsigned int end = start + elem->length;
 289 
 290       if ((bci >= start) && (bci < end) && (elem->slot == slot)) {
 291         ConstantPool* cp = method->constants();
 292         char *var =  cp->symbol_at(elem->name_cp_index)->as_C_string();
 293         os->print("%s", var);
 294 
 295         return;
 296       }
 297     }
 298   }
 299 
 300   // Handle at least some cases we know.
 301   if (!method->is_static() && (slot == 0)) {
 302     os->print("this");
 303   } else {
 304     int curr = method->is_static() ? 0 : 1;
 305     SignatureStream ss(method->signature());
 306     int param_index = 1;
 307     bool found = false;
 308 
 309     for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) {
 310       if (ss.at_return_type()) {
 311         continue;
 312       }
 313       int size = type2size[ss.type()];
 314       if ((slot >= curr) && (slot < curr + size)) {
 315         found = true;
 316         break;
 317       }
 318       param_index += 1;
 319       curr += size;
 320     }
 321 
 322     if (found) {
 323       os->print("<parameter%d>", param_index);
 324     } else {
 325       // This is the best we can do.
 326       os->print("<local%d>", slot);
 327     }
 328   }
 329 }
 330 
 331 StackSlotAnalysisData::StackSlotAnalysisData(BasicType type) : _bci(INVALID), _type(type) {}
 332 
 333 StackSlotAnalysisData::StackSlotAnalysisData(int bci, BasicType type) : _bci(bci), _type(type) {
 334   assert(bci >= 0, "BCI must be >= 0");
 335   assert(bci < 65536, "BCI must be < 65536");
 336 }
 337 
 338 unsigned int StackSlotAnalysisData::get_bci() {
 339   return _bci;
 340 }
 341 
 342 BasicType StackSlotAnalysisData::get_type() {


 351         return StackSlotAnalysisData(get_bci(), T_OBJECT);
 352       } else {
 353         return StackSlotAnalysisData(T_OBJECT);
 354       }
 355     } else {
 356       return StackSlotAnalysisData(T_CONFLICT);
 357     }
 358   }
 359 
 360   if (get_bci() == other.get_bci()) {
 361     return *this;
 362   } else {
 363     return StackSlotAnalysisData(get_type());
 364   }
 365 }
 366 
 367 SimulatedOperandStack::SimulatedOperandStack(const SimulatedOperandStack &copy) {
 368   for (int i = 0; i < copy.get_size(); i++) {
 369     push_raw(copy._stack.at(i));
 370   }

 371 }
 372 
 373 void SimulatedOperandStack::push_raw(StackSlotAnalysisData slotData) {
 374   if (slotData.get_type() == T_VOID) {
 375     return;
 376   }
 377 
 378   _stack.push(slotData);
 379 }
 380 
 381 void SimulatedOperandStack::push(StackSlotAnalysisData slotData) {
 382   if (type2size[slotData.get_type()] == 2) {
 383     push_raw(slotData);
 384     push_raw(slotData);
 385   } else {
 386     push_raw(slotData);
 387   }
 388 }
 389 
 390 void SimulatedOperandStack::push(int bci, BasicType type) {
 391   push(StackSlotAnalysisData(bci, type));
 392 }
 393 
 394 void SimulatedOperandStack::pop(int slots) {
 395   for (int i = 0; i < slots; ++i) {
 396     _stack.pop();
 397   }
 398 
 399   assert(get_size() >= 0, "Popped too many slots");
 400 }
 401 
 402 void SimulatedOperandStack::merge(SimulatedOperandStack const& other) {
 403   assert(get_size() == other.get_size(), "Stacks not of same size");
 404 
 405   for (int i = get_size() - 1; i >= 0; --i) {
 406     _stack.at_put(i, _stack.at(i).merge(other._stack.at(i)));
 407   }

 408 }
 409 
 410 int SimulatedOperandStack::get_size() const {
 411   return _stack.length();
 412 }
 413 
 414 StackSlotAnalysisData SimulatedOperandStack::get_slot_data(int slot) {
 415   assert(slot >= 0, "Slot < 0");
 416   assert(slot < get_size(), "Slot >= size");
 417 
 418   return _stack.at(get_size() - slot - 1);
 419 }
 420 













 421 ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :
 422                     _method(method), _nr_of_entries(0),
 423                     _added_one(true), _all_processed(false) {
 424   assert(bci >= 0, "BCI too low");
 425   assert(bci < get_size(), "BCI too large");
 426 
 427   ConstMethod* const_method = method->constMethod();
 428   const int len = const_method->code_size();
 429 
 430   _stacks = new GrowableArray<SimulatedOperandStack*> (len + 1);
 431 
 432   for (int i = 0; i <= len; ++i) {
 433     _stacks->push(NULL);
 434   }
 435 
 436   // Initialize stack a bci 0.
 437   _stacks->at_put(0, new SimulatedOperandStack());
 438 
 439   // And initialize the start of all exception handlers.
 440   if (const_method->has_exception_handler()) {


 504 
 505   // If we have no stack for this bci, we cannot process the bytecode now.
 506   if (_stacks->at(bci) == NULL) {
 507     _all_processed = false;
 508     return len;
 509   }
 510 
 511   // Make a local copy of the stack for this bci to work on.
 512   SimulatedOperandStack* stack = new SimulatedOperandStack(*_stacks->at(bci));
 513 
 514   // dest_bci is != -1 if we branch.
 515   int dest_bci = -1;
 516 
 517   // This is for table and lookup switch.
 518   static const int initial_length = 2;
 519   GrowableArray<int> dests(initial_length);
 520 
 521   bool flow_ended = false;
 522 
 523   // Get the bytecode.

 524   Bytecodes::Code raw_code = Bytecodes::code_at(_method, code_base + bci);
 525   Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);
 526   int pos = bci + 1;
 527 
 528   if (code == Bytecodes::_wide) {

 529     code = Bytecodes::java_code_at(_method, code_base + bci + 1);
 530     pos += 1;
 531   }
 532 
 533   // Now simulate the action of each bytecode.
 534   switch (code) {
 535     case Bytecodes::_nop:
 536     case Bytecodes::_aconst_null:
 537     case Bytecodes::_iconst_m1:
 538     case Bytecodes::_iconst_0:
 539     case Bytecodes::_iconst_1:
 540     case Bytecodes::_iconst_2:
 541     case Bytecodes::_iconst_3:
 542     case Bytecodes::_iconst_4:
 543     case Bytecodes::_iconst_5:
 544     case Bytecodes::_lconst_0:
 545     case Bytecodes::_lconst_1:
 546     case Bytecodes::_fconst_0:
 547     case Bytecodes::_fconst_1:
 548     case Bytecodes::_fconst_2:


 621       break;
 622     }
 623 
 624     case Bytecodes::_iaload:
 625     case Bytecodes::_faload:
 626     case Bytecodes::_aaload:
 627     case Bytecodes::_baload:
 628     case Bytecodes::_caload:
 629     case Bytecodes::_saload:
 630     case Bytecodes::_laload:
 631     case Bytecodes::_daload:
 632       stack->pop(2);
 633       stack->push(bci, Bytecodes::result_type(code));
 634       break;
 635 
 636     case Bytecodes::_istore:
 637     case Bytecodes::_lstore:
 638     case Bytecodes::_fstore:
 639     case Bytecodes::_dstore:
 640     case Bytecodes::_astore:









 641     case Bytecodes::_istore_0:
 642     case Bytecodes::_istore_1:
 643     case Bytecodes::_istore_2:
 644     case Bytecodes::_istore_3:
 645     case Bytecodes::_lstore_0:
 646     case Bytecodes::_lstore_1:
 647     case Bytecodes::_lstore_2:
 648     case Bytecodes::_lstore_3:
 649     case Bytecodes::_fstore_0:
 650     case Bytecodes::_fstore_1:
 651     case Bytecodes::_fstore_2:
 652     case Bytecodes::_fstore_3:
 653     case Bytecodes::_dstore_0:
 654     case Bytecodes::_dstore_1:
 655     case Bytecodes::_dstore_2:
 656     case Bytecodes::_dstore_3:
 657     case Bytecodes::_astore_0:







 658     case Bytecodes::_astore_1:







 659     case Bytecodes::_astore_2:







 660     case Bytecodes::_astore_3:



 661     case Bytecodes::_iastore:
 662     case Bytecodes::_lastore:
 663     case Bytecodes::_fastore:
 664     case Bytecodes::_dastore:
 665     case Bytecodes::_aastore:
 666     case Bytecodes::_bastore:
 667     case Bytecodes::_castore:
 668     case Bytecodes::_sastore:
 669     case Bytecodes::_pop:
 670     case Bytecodes::_pop2:
 671     case Bytecodes::_monitorenter:
 672     case Bytecodes::_monitorexit:
 673     case Bytecodes::_breakpoint:
 674       stack->pop(-Bytecodes::depth(code));
 675       break;
 676 
 677     case Bytecodes::_dup:
 678       stack->push_raw(stack->get_slot_data(0));
 679       break;
 680 


1160   int pos = source_bci + 1;
1161 
1162   if (code == Bytecodes::_wide) {
1163     is_wide = true;
1164     code = Bytecodes::java_code_at(_method, code_base + source_bci + 1);
1165     pos += 1;
1166   }
1167 
1168   if (max_detail == _max_cause_detail &&
1169       prefix != NULL &&
1170       code != Bytecodes::_invokevirtual &&
1171       code != Bytecodes::_invokespecial &&
1172       code != Bytecodes::_invokestatic &&
1173       code != Bytecodes::_invokeinterface) {
1174     os->print("%s", prefix);
1175   }
1176 
1177   switch (code) {
1178     case Bytecodes::_iload_0:
1179     case Bytecodes::_aload_0:
1180       print_local_var(os, source_bci, _method, 0);
1181       return true;
1182 
1183     case Bytecodes::_iload_1:
1184     case Bytecodes::_aload_1:
1185       print_local_var(os, source_bci, _method, 1);
1186       return true;
1187 
1188     case Bytecodes::_iload_2:
1189     case Bytecodes::_aload_2:
1190       print_local_var(os, source_bci, _method, 2);
1191       return true;
1192 
1193     case Bytecodes::_iload_3:
1194     case Bytecodes::_aload_3:
1195       print_local_var(os, source_bci, _method, 3);
1196       return true;
1197 
1198     case Bytecodes::_iload:
1199     case Bytecodes::_aload: {
1200       int index;
1201       if (is_wide) {
1202         index = Bytes::get_Java_u2(code_base + source_bci + 2);
1203       } else {
1204         index = *(uint8_t*) (code_base + source_bci + 1);
1205       }
1206       print_local_var(os, source_bci, _method, index);
1207       return true;
1208     }
1209 
1210     case Bytecodes::_aconst_null:
1211       os->print("null");
1212       return true;
1213     case Bytecodes::_iconst_m1:
1214       os->print("-1");
1215       return true;
1216     case Bytecodes::_iconst_0:
1217       os->print("0");
1218       return true;
1219     case Bytecodes::_iconst_1:
1220       os->print("1");
1221       return true;
1222     case Bytecodes::_iconst_2:
1223       os->print("2");
1224       return true;
1225     case Bytecodes::_iconst_3:
1226       os->print("3");




  65   StackSlotAnalysisData(int bci, BasicType type);
  66 
  67   enum {
  68     // An invalid bytecode index, as > 65535.
  69     INVALID = 0x1FFFF
  70   };
  71 
  72   // Returns the bci. If the bci is invalid, INVALID is returned.
  73   unsigned int get_bci();
  74 
  75   // Returns true, if the bci is not invalid.
  76   bool has_bci() { return get_bci() != INVALID; }
  77 
  78   // Returns the type of the slot data.
  79   BasicType get_type();
  80 };
  81 
  82 // A stack consisting of SimulatedOperandStackEntries.
  83 // This represents the analysis information for the operand stack
  84 // for a given bytecode at a given bci.
  85 // It also holds an additional field that serves to collect
  86 // information whether local slots were written.
  87 class SimulatedOperandStack: CHeapObj<mtInternal> {
  88 
  89  private:
  90 
  91   friend class ExceptionMessageBuilder;
  92   friend class StackSlotAnalysisData;
  93 
  94   // The stack.
  95   GrowableArray<StackSlotAnalysisData> _stack;
  96 
  97   // Optimized bytecode can reuse local variable slots for several
  98   // local variables.
  99   // If there is no variable name information, we print 'parameter<i>'
 100   // if a parameter maps to a local slot. Once a local slot has been
 101   // written, we don't know any more whether it was written as the
 102   // corresponding parameter, or whether another local has been
 103   // mapped to the slot. So we don't want to print 'parameter<i>' any
 104   // more, but 'local<i>'. Similary for 'this'.
 105   // Therefore, during the analysis, we mark a bit for local slots that
 106   // get written and propagate this information.
 107   // We only run the analysis for 64 slots. If a method has more
 108   // parameters, we print 'local<i>' in all cases.
 109   uint64_t _written_local_slots;
 110 
 111   SimulatedOperandStack(): _written_local_slots(0) { };
 112   SimulatedOperandStack(const SimulatedOperandStack &copy);
 113 
 114   // Pushes the given slot data.
 115   void push_raw(StackSlotAnalysisData slotData);
 116 
 117   // Like push_raw, but if the slotData has type long or double, we push two.
 118   void push(StackSlotAnalysisData slotData);
 119 
 120   // Like push(slotData), but using bci/type to create an instance of
 121   // StackSlotAnalysisData first.
 122   void push(int bci, BasicType type);
 123 
 124   // Pops the given number of entries.
 125   void pop(int slots);
 126 
 127   // Merges this with the given stack by merging all entries. The
 128   // size of the stacks must be the same.
 129   void merge(SimulatedOperandStack const& other);
 130 
 131  public:
 132 
 133   // Returns the size of the stack.
 134   int get_size() const;
 135 
 136   // Returns the slot data at the given index. Slot 0 is top of stack.
 137   StackSlotAnalysisData get_slot_data(int slot);
 138 
 139   // Mark that local slot i was written.
 140   void set_local_slot_written(int i);
 141 
 142   // Check whether local slot i was written by this or a previous bytecode.
 143   bool local_slot_was_written(int i);
 144 };
 145 
 146 // Helper class to build internal exception messages for exceptions
 147 // that are thrown because prerequisites to execute a bytecode
 148 // are not met.
 149 // E.g., if a NPE is thrown because an iload can not be executed
 150 // by the VM because the reference to load from is null.
 151 //
 152 // It analyses the bytecode to assemble Java-like message text
 153 // to give precise information where in a larger expression the
 154 // exception occured.
 155 //
 156 // To assemble this message text, it is needed to know how
 157 // operand stack slot entries were pushed on the operand stack.
 158 // This class contains an analysis over the bytecodes to compute
 159 // this information. The information is stored in a
 160 // SimulatedOperandStack for each bytecode.
 161 class ExceptionMessageBuilder : public StackObj {
 162 
 163   // The stacks for each bytecode.


 285 }
 286 
 287 // Prints the name of the field that is described at constant pool
 288 // index cp_index in the constant pool of method 'method'.
 289 static void print_field_and_class(outputStream *os, Method* method, int cp_index) {
 290   ResourceMark rm;
 291   ConstantPool* cp = method->constants();
 292   Symbol* klass    = cp->klass_ref_at_noresolve(cp_index);
 293   Symbol *name     = cp->name_ref_at(cp_index);
 294   print_klass_name(os, klass);
 295   os->print(".%s", name->as_C_string());
 296 }
 297 
 298 // Returns the name of the field that is described at constant pool
 299 // index cp_index in the constant pool of method 'method'.
 300 static char const* get_field_name(Method* method, int cp_index) {
 301   Symbol* name = method->constants()->name_ref_at(cp_index);
 302   return name->as_C_string();
 303 }
 304 
 305 static void print_local_var(outputStream *os, unsigned int bci, Method* method, int slot, bool is_parameter) {
 306   if (method->has_localvariable_table()) {
 307     for (int i = 0; i < method->localvariable_table_length(); i++) {
 308       LocalVariableTableElement* elem = method->localvariable_table_start() + i;
 309       unsigned int start = elem->start_bci;
 310       unsigned int end = start + elem->length;
 311 
 312       if ((bci >= start) && (bci < end) && (elem->slot == slot)) {
 313         ConstantPool* cp = method->constants();
 314         char *var =  cp->symbol_at(elem->name_cp_index)->as_C_string();
 315         os->print("%s", var);
 316 
 317         return;
 318       }
 319     }
 320   }
 321 
 322   // Handle at least some cases we know.
 323   if (!method->is_static() && (slot == 0) && is_parameter) {
 324     os->print("this");
 325   } else {
 326     int curr = method->is_static() ? 0 : 1;
 327     SignatureStream ss(method->signature());
 328     int param_index = 1;
 329     bool found = false;
 330 
 331     for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) {
 332       if (ss.at_return_type()) {
 333         continue;
 334       }
 335       int size = type2size[ss.type()];
 336       if ((slot >= curr) && (slot < curr + size)) {
 337         found = true;
 338         break;
 339       }
 340       param_index += 1;
 341       curr += size;
 342     }
 343 
 344     if (found && is_parameter) {
 345       os->print("<parameter%d>", param_index);
 346     } else {
 347       // This is the best we can do.
 348       os->print("<local%d>", slot);
 349     }
 350   }
 351 }
 352 
 353 StackSlotAnalysisData::StackSlotAnalysisData(BasicType type) : _bci(INVALID), _type(type) {}
 354 
 355 StackSlotAnalysisData::StackSlotAnalysisData(int bci, BasicType type) : _bci(bci), _type(type) {
 356   assert(bci >= 0, "BCI must be >= 0");
 357   assert(bci < 65536, "BCI must be < 65536");
 358 }
 359 
 360 unsigned int StackSlotAnalysisData::get_bci() {
 361   return _bci;
 362 }
 363 
 364 BasicType StackSlotAnalysisData::get_type() {


 373         return StackSlotAnalysisData(get_bci(), T_OBJECT);
 374       } else {
 375         return StackSlotAnalysisData(T_OBJECT);
 376       }
 377     } else {
 378       return StackSlotAnalysisData(T_CONFLICT);
 379     }
 380   }
 381 
 382   if (get_bci() == other.get_bci()) {
 383     return *this;
 384   } else {
 385     return StackSlotAnalysisData(get_type());
 386   }
 387 }
 388 
 389 SimulatedOperandStack::SimulatedOperandStack(const SimulatedOperandStack &copy) {
 390   for (int i = 0; i < copy.get_size(); i++) {
 391     push_raw(copy._stack.at(i));
 392   }
 393   _written_local_slots = copy._written_local_slots;
 394 }
 395 
 396 void SimulatedOperandStack::push_raw(StackSlotAnalysisData slotData) {
 397   if (slotData.get_type() == T_VOID) {
 398     return;
 399   }
 400 
 401   _stack.push(slotData);
 402 }
 403 
 404 void SimulatedOperandStack::push(StackSlotAnalysisData slotData) {
 405   if (type2size[slotData.get_type()] == 2) {
 406     push_raw(slotData);
 407     push_raw(slotData);
 408   } else {
 409     push_raw(slotData);
 410   }
 411 }
 412 
 413 void SimulatedOperandStack::push(int bci, BasicType type) {
 414   push(StackSlotAnalysisData(bci, type));
 415 }
 416 
 417 void SimulatedOperandStack::pop(int slots) {
 418   for (int i = 0; i < slots; ++i) {
 419     _stack.pop();
 420   }
 421 
 422   assert(get_size() >= 0, "Popped too many slots");
 423 }
 424 
 425 void SimulatedOperandStack::merge(SimulatedOperandStack const& other) {
 426   assert(get_size() == other.get_size(), "Stacks not of same size");
 427 
 428   for (int i = get_size() - 1; i >= 0; --i) {
 429     _stack.at_put(i, _stack.at(i).merge(other._stack.at(i)));
 430   }
 431   _written_local_slots = _written_local_slots | other._written_local_slots;
 432 }
 433 
 434 int SimulatedOperandStack::get_size() const {
 435   return _stack.length();
 436 }
 437 
 438 StackSlotAnalysisData SimulatedOperandStack::get_slot_data(int slot) {
 439   assert(slot >= 0, "Slot < 0");
 440   assert(slot < get_size(), "Slot >= size");
 441 
 442   return _stack.at(get_size() - slot - 1);
 443 }
 444 
 445 void SimulatedOperandStack::set_local_slot_written(int i) {
 446   // Local slots > 63 are very unlikely. Consider these
 447   // as written all the time. Saves space and complexity
 448   // for dynamic data size.
 449   if (i > 63) return;
 450   _written_local_slots = _written_local_slots | (1 << i);
 451 }
 452 
 453 bool SimulatedOperandStack::local_slot_was_written(int i) {
 454   if (i > 63) return true;
 455   return (_written_local_slots & (1 << i)) != 0;
 456 }
 457 
 458 ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :
 459                     _method(method), _nr_of_entries(0),
 460                     _added_one(true), _all_processed(false) {
 461   assert(bci >= 0, "BCI too low");
 462   assert(bci < get_size(), "BCI too large");
 463 
 464   ConstMethod* const_method = method->constMethod();
 465   const int len = const_method->code_size();
 466 
 467   _stacks = new GrowableArray<SimulatedOperandStack*> (len + 1);
 468 
 469   for (int i = 0; i <= len; ++i) {
 470     _stacks->push(NULL);
 471   }
 472 
 473   // Initialize stack a bci 0.
 474   _stacks->at_put(0, new SimulatedOperandStack());
 475 
 476   // And initialize the start of all exception handlers.
 477   if (const_method->has_exception_handler()) {


 541 
 542   // If we have no stack for this bci, we cannot process the bytecode now.
 543   if (_stacks->at(bci) == NULL) {
 544     _all_processed = false;
 545     return len;
 546   }
 547 
 548   // Make a local copy of the stack for this bci to work on.
 549   SimulatedOperandStack* stack = new SimulatedOperandStack(*_stacks->at(bci));
 550 
 551   // dest_bci is != -1 if we branch.
 552   int dest_bci = -1;
 553 
 554   // This is for table and lookup switch.
 555   static const int initial_length = 2;
 556   GrowableArray<int> dests(initial_length);
 557 
 558   bool flow_ended = false;
 559 
 560   // Get the bytecode.
 561   bool is_wide = false;
 562   Bytecodes::Code raw_code = Bytecodes::code_at(_method, code_base + bci);
 563   Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);
 564   int pos = bci + 1;
 565 
 566   if (code == Bytecodes::_wide) {
 567     is_wide = true;
 568     code = Bytecodes::java_code_at(_method, code_base + bci + 1);
 569     pos += 1;
 570   }
 571 
 572   // Now simulate the action of each bytecode.
 573   switch (code) {
 574     case Bytecodes::_nop:
 575     case Bytecodes::_aconst_null:
 576     case Bytecodes::_iconst_m1:
 577     case Bytecodes::_iconst_0:
 578     case Bytecodes::_iconst_1:
 579     case Bytecodes::_iconst_2:
 580     case Bytecodes::_iconst_3:
 581     case Bytecodes::_iconst_4:
 582     case Bytecodes::_iconst_5:
 583     case Bytecodes::_lconst_0:
 584     case Bytecodes::_lconst_1:
 585     case Bytecodes::_fconst_0:
 586     case Bytecodes::_fconst_1:
 587     case Bytecodes::_fconst_2:


 660       break;
 661     }
 662 
 663     case Bytecodes::_iaload:
 664     case Bytecodes::_faload:
 665     case Bytecodes::_aaload:
 666     case Bytecodes::_baload:
 667     case Bytecodes::_caload:
 668     case Bytecodes::_saload:
 669     case Bytecodes::_laload:
 670     case Bytecodes::_daload:
 671       stack->pop(2);
 672       stack->push(bci, Bytecodes::result_type(code));
 673       break;
 674 
 675     case Bytecodes::_istore:
 676     case Bytecodes::_lstore:
 677     case Bytecodes::_fstore:
 678     case Bytecodes::_dstore:
 679     case Bytecodes::_astore:
 680       int index;
 681       if (is_wide) {
 682         index = Bytes::get_Java_u2(code_base + bci + 2);
 683       } else {
 684         index = *(uint8_t*) (code_base + bci + 1);
 685       }
 686       stack->set_local_slot_written(index);
 687       stack->pop(-Bytecodes::depth(code));
 688       break;
 689     case Bytecodes::_istore_0:



 690     case Bytecodes::_lstore_0:



 691     case Bytecodes::_fstore_0:



 692     case Bytecodes::_dstore_0:



 693     case Bytecodes::_astore_0:
 694       stack->set_local_slot_written(0);
 695       stack->pop(-Bytecodes::depth(code));
 696       break;
 697     case Bytecodes::_istore_1:
 698     case Bytecodes::_fstore_1:
 699     case Bytecodes::_lstore_1:
 700     case Bytecodes::_dstore_1:
 701     case Bytecodes::_astore_1:
 702       stack->set_local_slot_written(1);
 703       stack->pop(-Bytecodes::depth(code));
 704       break;
 705     case Bytecodes::_istore_2:
 706     case Bytecodes::_lstore_2:
 707     case Bytecodes::_fstore_2:
 708     case Bytecodes::_dstore_2:
 709     case Bytecodes::_astore_2:
 710       stack->set_local_slot_written(2);
 711       stack->pop(-Bytecodes::depth(code));
 712       break;
 713     case Bytecodes::_istore_3:
 714     case Bytecodes::_lstore_3:
 715     case Bytecodes::_fstore_3:
 716     case Bytecodes::_dstore_3:
 717     case Bytecodes::_astore_3:
 718       stack->set_local_slot_written(3);
 719       stack->pop(-Bytecodes::depth(code));
 720       break;
 721     case Bytecodes::_iastore:
 722     case Bytecodes::_lastore:
 723     case Bytecodes::_fastore:
 724     case Bytecodes::_dastore:
 725     case Bytecodes::_aastore:
 726     case Bytecodes::_bastore:
 727     case Bytecodes::_castore:
 728     case Bytecodes::_sastore:
 729     case Bytecodes::_pop:
 730     case Bytecodes::_pop2:
 731     case Bytecodes::_monitorenter:
 732     case Bytecodes::_monitorexit:
 733     case Bytecodes::_breakpoint:
 734       stack->pop(-Bytecodes::depth(code));
 735       break;
 736 
 737     case Bytecodes::_dup:
 738       stack->push_raw(stack->get_slot_data(0));
 739       break;
 740 


1220   int pos = source_bci + 1;
1221 
1222   if (code == Bytecodes::_wide) {
1223     is_wide = true;
1224     code = Bytecodes::java_code_at(_method, code_base + source_bci + 1);
1225     pos += 1;
1226   }
1227 
1228   if (max_detail == _max_cause_detail &&
1229       prefix != NULL &&
1230       code != Bytecodes::_invokevirtual &&
1231       code != Bytecodes::_invokespecial &&
1232       code != Bytecodes::_invokestatic &&
1233       code != Bytecodes::_invokeinterface) {
1234     os->print("%s", prefix);
1235   }
1236 
1237   switch (code) {
1238     case Bytecodes::_iload_0:
1239     case Bytecodes::_aload_0:
1240       print_local_var(os, source_bci, _method, 0, !stack->local_slot_was_written(0));
1241       return true;
1242 
1243     case Bytecodes::_iload_1:
1244     case Bytecodes::_aload_1:
1245       print_local_var(os, source_bci, _method, 1, !stack->local_slot_was_written(1));
1246       return true;
1247 
1248     case Bytecodes::_iload_2:
1249     case Bytecodes::_aload_2:
1250       print_local_var(os, source_bci, _method, 2, !stack->local_slot_was_written(2));
1251       return true;
1252 
1253     case Bytecodes::_iload_3:
1254     case Bytecodes::_aload_3:
1255       print_local_var(os, source_bci, _method, 3, !stack->local_slot_was_written(3));
1256       return true;
1257 
1258     case Bytecodes::_iload:
1259     case Bytecodes::_aload: {
1260       int index;
1261       if (is_wide) {
1262         index = Bytes::get_Java_u2(code_base + source_bci + 2);
1263       } else {
1264         index = *(uint8_t*) (code_base + source_bci + 1);
1265       }
1266       print_local_var(os, source_bci, _method, index, !stack->local_slot_was_written(index));
1267       return true;
1268     }
1269 
1270     case Bytecodes::_aconst_null:
1271       os->print("null");
1272       return true;
1273     case Bytecodes::_iconst_m1:
1274       os->print("-1");
1275       return true;
1276     case Bytecodes::_iconst_0:
1277       os->print("0");
1278       return true;
1279     case Bytecodes::_iconst_1:
1280       os->print("1");
1281       return true;
1282     case Bytecodes::_iconst_2:
1283       os->print("2");
1284       return true;
1285     case Bytecodes::_iconst_3:
1286       os->print("3");


< prev index next >