/*
 * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 SAP SE. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "gc/shared/gcLocker.hpp"
#include "interpreter/bytecodeUtils.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/signature.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "utilities/events.hpp"
#include "utilities/ostream.hpp"

class SimulatedOperandStack;
class ExceptionMessageBuilder;

// The entries of a SimulatedOperandStack. They carry the analysis
// information gathered for the slot.
class StackSlotAnalysisData {
 private:

  friend class SimulatedOperandStack;
  friend class ExceptionMessageBuilder;

  unsigned int _bci:17;    // The bci of the bytecode that pushed the current value on the operand stack.
                           // INVALID if ambiguous, e.g. after a control flow merge.
                           // 16 bits for bci (max bytecode size) and one for INVALID.
  unsigned int _type:15;   // The BasicType of the value on the operand stack.

  // Merges this slot data with the given one and returns the result. If
  // the bcis of the two merged objects are different, the bci of the result
  // will be undefined. If the types are different, the result type is T_CONFLICT.
  // (An exception is if one type is an array and the other is object, then
  // the result type will be T_OBJECT).
  StackSlotAnalysisData merge(StackSlotAnalysisData other);

 public:

  // Creates a new object with an invalid bci and the given type.
  StackSlotAnalysisData(BasicType type = T_CONFLICT);

  // Creates a new object with the given bci and type.
  StackSlotAnalysisData(int bci, BasicType type);

  enum {
    // An invalid bytecode index, as > 65535.
    INVALID = 0x1FFFF
  };

  // Returns the bci. If the bci is invalid, INVALID is returned.
  unsigned int get_bci();

  // Returns true, if the bci is not invalid.
  bool has_bci() { return get_bci() != INVALID; }

  // Returns the type of the slot data.
  BasicType get_type();
};

// A stack consisting of SimulatedOperandStackEntries.
// This represents the analysis information for the operand stack
// for a given bytecode at a given bci.
// It also holds an additional field that serves to collect
// information whether local slots were written.
class SimulatedOperandStack: CHeapObj<mtInternal> {

 private:

  friend class ExceptionMessageBuilder;
  friend class StackSlotAnalysisData;

  // The stack.
  GrowableArray<StackSlotAnalysisData> _stack;

  // Optimized bytecode can reuse local variable slots for several
  // local variables.
  // If there is no variable name information, we print 'parameter<i>'
  // if a parameter maps to a local slot. Once a local slot has been
  // written, we don't know any more whether it was written as the
  // corresponding parameter, or whether another local has been
  // mapped to the slot. So we don't want to print 'parameter<i>' any
  // more, but 'local<i>'. Similarly for 'this'.
  // Therefore, during the analysis, we mark a bit for local slots that
  // get written and propagate this information.
  // We only run the analysis for 64 slots. If a method has more
  // parameters, we print 'local<i>' in all cases.
  uint64_t _written_local_slots;

  SimulatedOperandStack(): _written_local_slots(0) { };
  SimulatedOperandStack(const SimulatedOperandStack &copy);

  // Pushes the given slot data.
  void push_raw(StackSlotAnalysisData slotData);

  // Like push_raw, but if the slotData has type long or double, we push two.
  void push(StackSlotAnalysisData slotData);

  // Like push(slotData), but using bci/type to create an instance of
  // StackSlotAnalysisData first.
  void push(int bci, BasicType type);

  // Pops the given number of entries.
  void pop(int slots);

  // Merges this with the given stack by merging all entries. The
  // size of the stacks must be the same.
  void merge(SimulatedOperandStack const& other);

 public:

  // Returns the size of the stack.
  int get_size() const;

  // Returns the slot data at the given index. Slot 0 is top of stack.
  StackSlotAnalysisData get_slot_data(int slot);

  // Mark that local slot i was written.
  void set_local_slot_written(int i);

  // Check whether local slot i was written by this or a previous bytecode.
  bool local_slot_was_written(int i);
};

// Helper class to build internal exception messages for exceptions
// that are thrown because prerequisites to execute a bytecode
// are not met.
// E.g., if a NPE is thrown because an iload can not be executed
// by the VM because the reference to load from is null.
//
// It analyses the bytecode to assemble Java-like message text
// to give precise information where in a larger expression the
// exception occurred.
//
// To assemble this message text, it is needed to know how
// operand stack slot entries were pushed on the operand stack.
// This class contains an analysis over the bytecodes to compute
// this information. The information is stored in a
// SimulatedOperandStack for each bytecode.
class ExceptionMessageBuilder : public StackObj {

  // The stacks for each bytecode.
  GrowableArray<SimulatedOperandStack*>* _stacks;

  // The method.
  Method* _method;

  // The number of entries used (the sum of all entries of all stacks).
  int _nr_of_entries;

  // If true, we have added at least one new stack.
  bool _added_one;

  // If true, we have processed all bytecodes.
  bool _all_processed;

  // The maximum number of entries we want to use. This is used to
  // limit the amount of memory we waste for insane methods (as they
  // appear in JCK tests).
  static const int _max_entries = 1000000;

  static const int _max_cause_detail = 5;

  // Merges the stack at the given bci with the given stack. If there
  // is no stack at the bci, we just put the given stack there. This
  // method doesn't takes ownership of the stack.
  void merge(int bci, SimulatedOperandStack* stack);

  // Processes the instruction at the given bci in the method. Returns
  // the size of the instruction.
  int do_instruction(int bci);

  bool print_NPE_cause0(outputStream *os, int bci, int slot, int max_detail,
                        bool inner_expr = false, const char *prefix = nullptr);

 public:

  // Creates an ExceptionMessageBuilder object and runs the analysis
  // building SimulatedOperandStacks for each bytecode in the given
  // method (the method must be rewritten already). Note that you're
  // not allowed to use this object when crossing a safepoint! If the
  // bci is != -1, we only create the stacks as far as needed to get a
  // stack for the bci.
  ExceptionMessageBuilder(Method* method, int bci = -1);

  // Releases the resources.
  ~ExceptionMessageBuilder();

  // Returns the number of stacks (this is the size of the method).
  int get_size() { return _stacks->length() - 1; }

  // Assuming that a NullPointerException was thrown at the given bci,
  // we return the nr of the slot holding the null reference. If this
  // NPE is created by hand, we return -2 as the slot. If there
  // cannot be a NullPointerException at the bci, -1 is returned.
  int get_NPE_null_slot(int bci);

  // Prints a java-like expression for the bytecode that pushed
  // the value to the given slot being live at the given bci.
  // It constructs the expression by recursing backwards over the
  // bytecode using the results of the analysis done in the
  // constructor of ExceptionMessageBuilder.
  //  os:   The stream to print the message to.
  //  bci:  The index of the bytecode that caused the NPE.
  //  slot: The slot on the operand stack that contains null.
  //        The slots are numbered from TOS downwards, i.e.,
  //        TOS has the slot number 0, that below 1 and so on.
  //
  // Returns false if nothing was printed, else true.
  bool print_NPE_cause(outputStream *os, int bci, int slot);

  // Prints a string describing the failed action.
  void print_NPE_failed_action(outputStream *os, int bci);
};

// Replaces the following well-known class names:
//   java.lang.Object -> Object
//   java.lang.String -> String
static char *trim_well_known_class_names_from_signature(char *signature) {
  size_t len = strlen(signature);
  size_t skip_len = strlen("java.lang.");
  size_t min_pattern_len = strlen("java.lang.String");
  if (len < min_pattern_len) return signature;

  for (size_t isrc = 0, idst = 0; isrc <= len; isrc++, idst++) {
    // We must be careful not to trim names like test.java.lang.String.
    if ((isrc == 0 && strncmp(signature + isrc, "java.lang.Object", min_pattern_len) == 0) ||
        (isrc == 0 && strncmp(signature + isrc, "java.lang.String", min_pattern_len) == 0) ||
        (isrc > 1  && strncmp(signature + isrc-2, ", java.lang.Object", min_pattern_len+2) == 0) ||
        (isrc > 1  && strncmp(signature + isrc-2, ", java.lang.String", min_pattern_len+2) == 0)   ) {
      isrc += skip_len;
    }
    if (idst != isrc) {
      signature[idst] = signature[isrc];
    }
  }
  return signature;
}

// Replaces the following well-known class names:
//   java.lang.Object -> Object
//   java.lang.String -> String
static void print_klass_name(outputStream *os, Symbol *klass) {
  const char *name = klass->as_klass_external_name();
  if (strcmp(name, "java.lang.Object") == 0) name = "Object";
  if (strcmp(name, "java.lang.String") == 0) name = "String";
  os->print("%s", name);
}

// Prints the name of the method that is described at constant pool
// index cp_index in the constant pool of method 'method'.
static void print_method_name(outputStream *os, Method* method, int cp_index, Bytecodes::Code bc) {
  ResourceMark rm;
  ConstantPool* cp  = method->constants();
  Symbol* klass     = cp->klass_ref_at_noresolve(cp_index, bc);
  Symbol* name      = cp->name_ref_at(cp_index, bc);
  Symbol* signature = cp->signature_ref_at(cp_index, bc);

  print_klass_name(os, klass);
  os->print(".%s(", name->as_C_string());
  stringStream sig;
  signature->print_as_signature_external_parameters(&sig);
  os->print("%s)", trim_well_known_class_names_from_signature(sig.as_string()));
}

// Prints the name of the field that is described at constant pool
// index cp_index in the constant pool of method 'method'.
static void print_field_and_class(outputStream *os, Method* method, int cp_index, Bytecodes::Code bc) {
  ResourceMark rm;
  ConstantPool* cp = method->constants();
  Symbol* klass    = cp->klass_ref_at_noresolve(cp_index, bc);
  Symbol *name     = cp->name_ref_at(cp_index, bc);
  print_klass_name(os, klass);
  os->print(".%s", name->as_C_string());
}

// Returns the name of the field that is described at constant pool
// index cp_index in the constant pool of method 'method'.
static char const* get_field_name(Method* method, int cp_index, Bytecodes::Code bc) {
  Symbol* name = method->constants()->name_ref_at(cp_index, bc);
  return name->as_C_string();
}

static void print_local_var(outputStream *os, unsigned int bci, Method* method, int slot, bool is_parameter) {
  if (method->has_localvariable_table()) {
    for (int i = 0; i < method->localvariable_table_length(); i++) {
      LocalVariableTableElement* elem = method->localvariable_table_start() + i;
      unsigned int start = elem->start_bci;
      unsigned int end = start + elem->length;

      if ((bci >= start) && (bci < end) && (elem->slot == slot)) {
        ConstantPool* cp = method->constants();
        char *var =  cp->symbol_at(elem->name_cp_index)->as_C_string();
        os->print("%s", var);

        return;
      }
    }
  }

  // Handle at least some cases we know.
  if (!method->is_static() && (slot == 0) && is_parameter) {
    os->print("this");
  } else {
    int curr = method->is_static() ? 0 : 1;
    SignatureStream ss(method->signature());
    int param_index = 1;
    bool found = false;

    for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) {
      if (ss.at_return_type()) {
        continue;
      }
      int size = type2size[ss.type()];
      if ((slot >= curr) && (slot < curr + size)) {
        found = true;
        break;
      }
      param_index += 1;
      curr += size;
    }

    if (found && is_parameter) {
      os->print("<parameter%d>", param_index);
    } else {
      // This is the best we can do.
      os->print("<local%d>", slot);
    }
  }
}

StackSlotAnalysisData::StackSlotAnalysisData(BasicType type) : _bci(INVALID), _type(type) {}

StackSlotAnalysisData::StackSlotAnalysisData(int bci, BasicType type) : _bci((u2)bci), _type(type) {
  assert(bci >= 0, "BCI must be >= 0");
  assert(bci < 65536, "BCI must be < 65536");
}

unsigned int StackSlotAnalysisData::get_bci() {
  return _bci;
}

BasicType StackSlotAnalysisData::get_type() {
  return (BasicType)_type;
}

StackSlotAnalysisData StackSlotAnalysisData::merge(StackSlotAnalysisData other) {
  if (get_type() != other.get_type()) {
    if (((get_type() == T_OBJECT) || (get_type() == T_ARRAY)) &&
        ((other.get_type() == T_OBJECT) || (other.get_type() == T_ARRAY))) {
      if (get_bci() == other.get_bci()) {
        return StackSlotAnalysisData(get_bci(), T_OBJECT);
      } else {
        return StackSlotAnalysisData(T_OBJECT);
      }
    } else {
      return StackSlotAnalysisData(T_CONFLICT);
    }
  }

  if (get_bci() == other.get_bci()) {
    return *this;
  } else {
    return StackSlotAnalysisData(get_type());
  }
}

SimulatedOperandStack::SimulatedOperandStack(const SimulatedOperandStack &copy) {
  for (int i = 0; i < copy.get_size(); i++) {
    push_raw(copy._stack.at(i));
  }
  _written_local_slots = copy._written_local_slots;
}

void SimulatedOperandStack::push_raw(StackSlotAnalysisData slotData) {
  if (slotData.get_type() == T_VOID) {
    return;
  }

  _stack.push(slotData);
}

void SimulatedOperandStack::push(StackSlotAnalysisData slotData) {
  if (type2size[slotData.get_type()] == 2) {
    push_raw(slotData);
    push_raw(slotData);
  } else {
    push_raw(slotData);
  }
}

void SimulatedOperandStack::push(int bci, BasicType type) {
  push(StackSlotAnalysisData(bci, type));
}

void SimulatedOperandStack::pop(int slots) {
  for (int i = 0; i < slots; ++i) {
    _stack.pop();
  }

  assert(get_size() >= 0, "Popped too many slots");
}

void SimulatedOperandStack::merge(SimulatedOperandStack const& other) {
  assert(get_size() == other.get_size(), "Stacks not of same size");

  for (int i = get_size() - 1; i >= 0; --i) {
    _stack.at_put(i, _stack.at(i).merge(other._stack.at(i)));
  }
  _written_local_slots = _written_local_slots | other._written_local_slots;
}

int SimulatedOperandStack::get_size() const {
  return _stack.length();
}

StackSlotAnalysisData SimulatedOperandStack::get_slot_data(int slot) {
  assert(slot >= 0, "Slot=%d < 0", slot);
  assert(slot < get_size(), "Slot=%d >= size=%d", slot, get_size());

  return _stack.at(get_size() - slot - 1);
}

void SimulatedOperandStack::set_local_slot_written(int i) {
  // Local slots > 63 are very unlikely. Consider these
  // as written all the time. Saves space and complexity
  // for dynamic data size.
  if (i > 63) return;
  _written_local_slots = _written_local_slots | (1ULL << i);
}

bool SimulatedOperandStack::local_slot_was_written(int i) {
  if (i > 63) return true;
  return (_written_local_slots & (1ULL << i)) != 0;
}

ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :
                    _method(method), _nr_of_entries(0),
                    _added_one(true), _all_processed(false) {

  ConstMethod* const_method = method->constMethod();
  const int len = const_method->code_size();

  assert(bci >= 0, "BCI too low: %d", bci);
  assert(bci < len, "BCI too large: %d size: %d", bci, len);

  _stacks = new GrowableArray<SimulatedOperandStack*> (len + 1);

  for (int i = 0; i <= len; ++i) {
    _stacks->push(nullptr);
  }

  // Initialize stack a bci 0.
  _stacks->at_put(0, new SimulatedOperandStack());

  // And initialize the start of all exception handlers.
  if (const_method->has_exception_table()) {
    ExceptionTableElement *et = const_method->exception_table_start();
    for (int i = 0; i < const_method->exception_table_length(); ++i) {
      u2 index = et[i].handler_pc;

      if (_stacks->at(index) == nullptr) {
        _stacks->at_put(index, new SimulatedOperandStack());
        _stacks->at(index)->push(index, T_OBJECT);
      }
    }
  }

  // Do this until each bytecode has a stack or we haven't
  // added a new stack in one iteration.
  while (!_all_processed && _added_one) {
    _all_processed = true;
    _added_one = false;

    for (int i = 0; i < len; ) {
      // Analyse bytecode i. Step by size of the analyzed bytecode to next bytecode.
      i += do_instruction(i);

      // If we want the data only for a certain bci, we can possibly end early.
      if ((bci == i) && (_stacks->at(i) != nullptr)) {
        _all_processed = true;
        break;
      }

      if (_nr_of_entries > _max_entries) {
        return;
      }
    }
  }
}

ExceptionMessageBuilder::~ExceptionMessageBuilder() {
  if (_stacks != nullptr) {
    for (int i = 0; i < _stacks->length(); ++i) {
      delete _stacks->at(i);
    }
  }
}

void ExceptionMessageBuilder::merge(int bci, SimulatedOperandStack* stack) {
  assert(stack != _stacks->at(bci), "Cannot merge itself");

  if (_stacks->at(bci) != nullptr) {
    stack->merge(*_stacks->at(bci));
  } else {
    // Got a new stack, so count the entries.
    _nr_of_entries += stack->get_size();
  }

  // Replace the stack at this bci with a copy of our new merged stack.
  delete _stacks->at(bci);
  _stacks->at_put(bci, new SimulatedOperandStack(*stack));
}

int ExceptionMessageBuilder::do_instruction(int bci) {
  ConstMethod* const_method = _method->constMethod();
  address code_base = _method->constMethod()->code_base();

  // We use the java code, since we don't want to cope with all the fast variants.
  int len = Bytecodes::java_length_at(_method, code_base + bci);

  // If we have no stack for this bci, we cannot process the bytecode now.
  if (_stacks->at(bci) == nullptr) {
    _all_processed = false;
    return len;
  }

  // Make a local copy of the stack for this bci to work on.
  SimulatedOperandStack* stack = new SimulatedOperandStack(*_stacks->at(bci));

  // dest_bci is != -1 if we branch.
  int dest_bci = -1;

  // This is for table and lookup switch.
  static const int initial_length = 2;
  GrowableArray<int> dests(initial_length);

  bool flow_ended = false;

  // Get the bytecode.
  bool is_wide = false;
  Bytecodes::Code raw_code = Bytecodes::code_at(_method, code_base + bci);
  Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);
  int pos = bci + 1;

  if (code == Bytecodes::_wide) {
    is_wide = true;
    code = Bytecodes::java_code_at(_method, code_base + bci + 1);
    pos += 1;
  }

  // Now simulate the action of each bytecode.
  switch (code) {
    case Bytecodes::_nop:
    case Bytecodes::_aconst_null:
    case Bytecodes::_iconst_m1:
    case Bytecodes::_iconst_0:
    case Bytecodes::_iconst_1:
    case Bytecodes::_iconst_2:
    case Bytecodes::_iconst_3:
    case Bytecodes::_iconst_4:
    case Bytecodes::_iconst_5:
    case Bytecodes::_lconst_0:
    case Bytecodes::_lconst_1:
    case Bytecodes::_fconst_0:
    case Bytecodes::_fconst_1:
    case Bytecodes::_fconst_2:
    case Bytecodes::_dconst_0:
    case Bytecodes::_dconst_1:
    case Bytecodes::_bipush:
    case Bytecodes::_sipush:
    case Bytecodes::_iload:
    case Bytecodes::_lload:
    case Bytecodes::_fload:
    case Bytecodes::_dload:
    case Bytecodes::_aload:
    case Bytecodes::_iload_0:
    case Bytecodes::_iload_1:
    case Bytecodes::_iload_2:
    case Bytecodes::_iload_3:
    case Bytecodes::_lload_0:
    case Bytecodes::_lload_1:
    case Bytecodes::_lload_2:
    case Bytecodes::_lload_3:
    case Bytecodes::_fload_0:
    case Bytecodes::_fload_1:
    case Bytecodes::_fload_2:
    case Bytecodes::_fload_3:
    case Bytecodes::_dload_0:
    case Bytecodes::_dload_1:
    case Bytecodes::_dload_2:
    case Bytecodes::_dload_3:
    case Bytecodes::_aload_0:
    case Bytecodes::_aload_1:
    case Bytecodes::_aload_2:
    case Bytecodes::_aload_3:
    case Bytecodes::_iinc:
    case Bytecodes::_new:
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_ldc:
    case Bytecodes::_ldc_w:
    case Bytecodes::_ldc2_w: {
      int cp_index;
      ConstantPool* cp = _method->constants();

      if (code == Bytecodes::_ldc) {
        cp_index = *(uint8_t*) (code_base + pos);

        if (raw_code == Bytecodes::_fast_aldc) {
          cp_index = cp->object_to_cp_index(cp_index);
        }
      } else {
        if (raw_code == Bytecodes::_fast_aldc_w) {
          cp_index = Bytes::get_native_u2(code_base + pos);
          cp_index = cp->object_to_cp_index(cp_index);
        }
        else {
          cp_index = Bytes::get_Java_u2(code_base + pos);
        }
      }

      constantTag tag = cp->constant_tag_at(cp_index);
      if (tag.is_klass()  || tag.is_unresolved_klass() ||
          tag.is_method() || tag.is_interface_method() ||
          tag.is_field()  || tag.is_string()) {
        stack->push(bci, T_OBJECT);
      } else if (tag.is_int()) {
        stack->push(bci, T_INT);
      } else if (tag.is_long()) {
        stack->push(bci, T_LONG);
      } else if (tag.is_float()) {
        stack->push(bci, T_FLOAT);
      } else if (tag.is_double()) {
        stack->push(bci, T_DOUBLE);
      } else {
        assert(false, "Unexpected tag");
      }
      break;
    }

    case Bytecodes::_iaload:
    case Bytecodes::_faload:
    case Bytecodes::_aaload:
    case Bytecodes::_baload:
    case Bytecodes::_caload:
    case Bytecodes::_saload:
    case Bytecodes::_laload:
    case Bytecodes::_daload:
      stack->pop(2);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_istore:
    case Bytecodes::_lstore:
    case Bytecodes::_fstore:
    case Bytecodes::_dstore:
    case Bytecodes::_astore:
      int index;
      if (is_wide) {
        index = Bytes::get_Java_u2(code_base + bci + 2);
      } else {
        index = *(uint8_t*) (code_base + bci + 1);
      }
      stack->set_local_slot_written(index);
      stack->pop(-Bytecodes::depth(code));
      break;
    case Bytecodes::_istore_0:
    case Bytecodes::_lstore_0:
    case Bytecodes::_fstore_0:
    case Bytecodes::_dstore_0:
    case Bytecodes::_astore_0:
      stack->set_local_slot_written(0);
      stack->pop(-Bytecodes::depth(code));
      break;
    case Bytecodes::_istore_1:
    case Bytecodes::_fstore_1:
    case Bytecodes::_lstore_1:
    case Bytecodes::_dstore_1:
    case Bytecodes::_astore_1:
      stack->set_local_slot_written(1);
      stack->pop(-Bytecodes::depth(code));
      break;
    case Bytecodes::_istore_2:
    case Bytecodes::_lstore_2:
    case Bytecodes::_fstore_2:
    case Bytecodes::_dstore_2:
    case Bytecodes::_astore_2:
      stack->set_local_slot_written(2);
      stack->pop(-Bytecodes::depth(code));
      break;
    case Bytecodes::_istore_3:
    case Bytecodes::_lstore_3:
    case Bytecodes::_fstore_3:
    case Bytecodes::_dstore_3:
    case Bytecodes::_astore_3:
      stack->set_local_slot_written(3);
      stack->pop(-Bytecodes::depth(code));
      break;
    case Bytecodes::_iastore:
    case Bytecodes::_lastore:
    case Bytecodes::_fastore:
    case Bytecodes::_dastore:
    case Bytecodes::_aastore:
    case Bytecodes::_bastore:
    case Bytecodes::_castore:
    case Bytecodes::_sastore:
    case Bytecodes::_pop:
    case Bytecodes::_pop2:
    case Bytecodes::_monitorenter:
    case Bytecodes::_monitorexit:
    case Bytecodes::_breakpoint:
      stack->pop(-Bytecodes::depth(code));
      break;

    case Bytecodes::_dup:
      stack->push_raw(stack->get_slot_data(0));
      break;

    case Bytecodes::_dup_x1: {
      StackSlotAnalysisData top1 = stack->get_slot_data(0);
      StackSlotAnalysisData top2 = stack->get_slot_data(1);
      stack->pop(2);
      stack->push_raw(top1);
      stack->push_raw(top2);
      stack->push_raw(top1);
      break;
    }

    case Bytecodes::_dup_x2: {
      StackSlotAnalysisData top1 = stack->get_slot_data(0);
      StackSlotAnalysisData top2 = stack->get_slot_data(1);
      StackSlotAnalysisData top3 = stack->get_slot_data(2);
      stack->pop(3);
      stack->push_raw(top1);
      stack->push_raw(top3);
      stack->push_raw(top2);
      stack->push_raw(top1);
      break;
    }

    case Bytecodes::_dup2:
      stack->push_raw(stack->get_slot_data(1));
      // The former '0' entry is now at '1'.
      stack->push_raw(stack->get_slot_data(1));
      break;

    case Bytecodes::_dup2_x1: {
      StackSlotAnalysisData top1 = stack->get_slot_data(0);
      StackSlotAnalysisData top2 = stack->get_slot_data(1);
      StackSlotAnalysisData top3 = stack->get_slot_data(2);
      stack->pop(3);
      stack->push_raw(top2);
      stack->push_raw(top1);
      stack->push_raw(top3);
      stack->push_raw(top2);
      stack->push_raw(top1);
      break;
    }

    case Bytecodes::_dup2_x2: {
      StackSlotAnalysisData top1 = stack->get_slot_data(0);
      StackSlotAnalysisData top2 = stack->get_slot_data(1);
      StackSlotAnalysisData top3 = stack->get_slot_data(2);
      StackSlotAnalysisData top4 = stack->get_slot_data(3);
      stack->pop(4);
      stack->push_raw(top2);
      stack->push_raw(top1);
      stack->push_raw(top4);
      stack->push_raw(top3);
      stack->push_raw(top2);
      stack->push_raw(top1);
      break;
    }

    case Bytecodes::_swap: {
      StackSlotAnalysisData top1 = stack->get_slot_data(0);
      StackSlotAnalysisData top2 = stack->get_slot_data(1);
      stack->pop(2);
      stack->push(top1);
      stack->push(top2);
      break;
    }

    case Bytecodes::_iadd:
    case Bytecodes::_ladd:
    case Bytecodes::_fadd:
    case Bytecodes::_dadd:
    case Bytecodes::_isub:
    case Bytecodes::_lsub:
    case Bytecodes::_fsub:
    case Bytecodes::_dsub:
    case Bytecodes::_imul:
    case Bytecodes::_lmul:
    case Bytecodes::_fmul:
    case Bytecodes::_dmul:
    case Bytecodes::_idiv:
    case Bytecodes::_ldiv:
    case Bytecodes::_fdiv:
    case Bytecodes::_ddiv:
    case Bytecodes::_irem:
    case Bytecodes::_lrem:
    case Bytecodes::_frem:
    case Bytecodes::_drem:
    case Bytecodes::_iand:
    case Bytecodes::_land:
    case Bytecodes::_ior:
    case Bytecodes::_lor:
    case Bytecodes::_ixor:
    case Bytecodes::_lxor:
      stack->pop(2 * type2size[Bytecodes::result_type(code)]);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_ineg:
    case Bytecodes::_lneg:
    case Bytecodes::_fneg:
    case Bytecodes::_dneg:
      stack->pop(type2size[Bytecodes::result_type(code)]);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_ishl:
    case Bytecodes::_lshl:
    case Bytecodes::_ishr:
    case Bytecodes::_lshr:
    case Bytecodes::_iushr:
    case Bytecodes::_lushr:
      stack->pop(1 + type2size[Bytecodes::result_type(code)]);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_i2l:
    case Bytecodes::_i2f:
    case Bytecodes::_i2d:
    case Bytecodes::_f2i:
    case Bytecodes::_f2l:
    case Bytecodes::_f2d:
    case Bytecodes::_i2b:
    case Bytecodes::_i2c:
    case Bytecodes::_i2s:
      stack->pop(1);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_l2i:
    case Bytecodes::_l2f:
    case Bytecodes::_l2d:
    case Bytecodes::_d2i:
    case Bytecodes::_d2l:
    case Bytecodes::_d2f:
      stack->pop(2);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_lcmp:
    case Bytecodes::_fcmpl:
    case Bytecodes::_fcmpg:
    case Bytecodes::_dcmpl:
    case Bytecodes::_dcmpg:
      stack->pop(1 - Bytecodes::depth(code));
      stack->push(bci, T_INT);
      break;

    case Bytecodes::_ifeq:
    case Bytecodes::_ifne:
    case Bytecodes::_iflt:
    case Bytecodes::_ifge:
    case Bytecodes::_ifgt:
    case Bytecodes::_ifle:
    case Bytecodes::_if_icmpeq:
    case Bytecodes::_if_icmpne:
    case Bytecodes::_if_icmplt:
    case Bytecodes::_if_icmpge:
    case Bytecodes::_if_icmpgt:
    case Bytecodes::_if_icmple:
    case Bytecodes::_if_acmpeq:
    case Bytecodes::_if_acmpne:
    case Bytecodes::_ifnull:
    case Bytecodes::_ifnonnull:
      stack->pop(-Bytecodes::depth(code));
      dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);
      break;

    case Bytecodes::_jsr:
      // NOTE: Bytecodes has wrong depth for jsr.
      stack->push(bci, T_ADDRESS);
      dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);
      flow_ended = true;
      break;

    case Bytecodes::_jsr_w: {
      // NOTE: Bytecodes has wrong depth for jsr.
      stack->push(bci, T_ADDRESS);
      dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);
      flow_ended = true;
      break;
    }

    case Bytecodes::_ret:
      // We don't track local variables, so we cannot know were we
      // return. This makes the stacks imprecise, but we have to
      // live with that.
      flow_ended = true;
      break;

    case Bytecodes::_tableswitch: {
      stack->pop(1);
      pos = (pos + 3) & ~3;
      dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);
      int low = (int32_t) Bytes::get_Java_u4(code_base + pos + 4);
      int high = (int32_t) Bytes::get_Java_u4(code_base + pos + 8);

      for (int64_t i = low; i <= high; ++i) {
        dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 4 * (i - low)));
      }

      break;
    }

    case Bytecodes::_lookupswitch: {
      stack->pop(1);
      pos = (pos + 3) & ~3;
      dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);
      int nr_of_dests = (int32_t) Bytes::get_Java_u4(code_base + pos + 4);

      for (int i = 0; i < nr_of_dests; ++i) {
        dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 8 * i));
      }

      break;
    }

    case Bytecodes::_ireturn:
    case Bytecodes::_lreturn:
    case Bytecodes::_freturn:
    case Bytecodes::_dreturn:
    case Bytecodes::_areturn:
    case Bytecodes::_return:
    case Bytecodes::_athrow:
      stack->pop(-Bytecodes::depth(code));
      flow_ended = true;
      break;

    case Bytecodes::_getstatic:
    case Bytecodes::_getfield: {
      // Find out the type of the field accessed.
      int cp_index = Bytes::get_native_u2(code_base + pos);
      ConstantPool* cp = _method->constants();
      int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
      int type_index = cp->signature_ref_index_at(name_and_type_index);
      Symbol* signature = cp->symbol_at(type_index);
      // Simulate the bytecode: pop the address, push the 'value' loaded
      // from the field.
      stack->pop(1 - Bytecodes::depth(code));
      stack->push(bci, Signature::basic_type(signature));
      break;
    }

    case Bytecodes::_putstatic:
    case Bytecodes::_putfield: {
      int cp_index = Bytes::get_native_u2(code_base + pos);
      ConstantPool* cp = _method->constants();
      int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
      int type_index = cp->signature_ref_index_at(name_and_type_index);
      Symbol* signature = cp->symbol_at(type_index);
      BasicType bt = Signature::basic_type(signature);
      stack->pop(type2size[bt] - Bytecodes::depth(code) - 1);
      break;
    }

    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokestatic:
    case Bytecodes::_invokeinterface:
    case Bytecodes::_invokedynamic: {
      ConstantPool* cp = _method->constants();
      int cp_index;

      if (code == Bytecodes::_invokedynamic) {
        cp_index = ((int) Bytes::get_native_u4(code_base + pos));
      } else {
        cp_index = Bytes::get_native_u2(code_base + pos);
      }

      int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
      int type_index = cp->signature_ref_index_at(name_and_type_index);
      Symbol* signature = cp->symbol_at(type_index);

      if ((code != Bytecodes::_invokestatic) && (code != Bytecodes::_invokedynamic)) {
        // Pop receiver.
        stack->pop(1);
      }

      stack->pop(ArgumentSizeComputer(signature).size());
      ResultTypeFinder result_type(signature);
      stack->push(bci, result_type.type());
      break;
    }

    case Bytecodes::_newarray:
    case Bytecodes::_anewarray:
    case Bytecodes::_instanceof:
      stack->pop(1);
      stack->push(bci, Bytecodes::result_type(code));
      break;

    case Bytecodes::_arraylength:
      stack->pop(1);
      stack->push(bci, T_INT);
      break;

    case Bytecodes::_checkcast:
      break;

    case Bytecodes::_multianewarray:
      stack->pop(*(uint8_t*) (code_base + pos + 2));
      stack->push(bci, T_OBJECT);
      break;

   case Bytecodes::_goto:
      stack->pop(-Bytecodes::depth(code));
      dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);
      flow_ended = true;
      break;


   case Bytecodes::_goto_w:
      stack->pop(-Bytecodes::depth(code));
      dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);
      flow_ended = true;
      break;

    default:
      // Allow at least the bcis which have stack info to work.
      _all_processed = false;
      _added_one = false;
      delete stack;

      return len;
  }

  // Put new stack to the next instruction, if we might reach it from
  // this bci.
  if (!flow_ended) {
    if (_stacks->at(bci + len) == nullptr) {
      _added_one = true;
    }
    merge(bci + len, stack);
  }

  // Put the stack to the branch target too.
  if (dest_bci != -1) {
    if (_stacks->at(dest_bci) == nullptr) {
      _added_one = true;
    }
    merge(dest_bci, stack);
  }

  // If we have more than one branch target, process these too.
  for (int i = 0; i < dests.length(); ++i) {
    if (_stacks->at(dests.at(i)) == nullptr) {
      _added_one = true;
    }
    merge(dests.at(i), stack);
  }

  delete stack;

  return len;
}

#define INVALID_BYTECODE_ENCOUNTERED -1
#define NPE_EXPLICIT_CONSTRUCTED -2
int ExceptionMessageBuilder::get_NPE_null_slot(int bci) {
  // Get the bytecode.
  address code_base = _method->constMethod()->code_base();
  Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);
  int pos = bci + 1;  // Position of argument of the bytecode.
  if (code == Bytecodes::_wide) {
    code = Bytecodes::java_code_at(_method, code_base + bci + 1);
    pos += 1;
  }

  switch (code) {
    case Bytecodes::_getfield:
    case Bytecodes::_arraylength:
    case Bytecodes::_athrow:
    case Bytecodes::_monitorenter:
    case Bytecodes::_monitorexit:
      return 0;
    case Bytecodes::_iaload:
    case Bytecodes::_faload:
    case Bytecodes::_aaload:
    case Bytecodes::_baload:
    case Bytecodes::_caload:
    case Bytecodes::_saload:
    case Bytecodes::_laload:
    case Bytecodes::_daload:
      return 1;
    case Bytecodes::_iastore:
    case Bytecodes::_fastore:
    case Bytecodes::_aastore:
    case Bytecodes::_bastore:
    case Bytecodes::_castore:
    case Bytecodes::_sastore:
      return 2;
    case Bytecodes::_lastore:
    case Bytecodes::_dastore:
      return 3;
    case Bytecodes::_putfield: {
        int cp_index = Bytes::get_native_u2(code_base + pos);
        ConstantPool* cp = _method->constants();
        int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
        int type_index = cp->signature_ref_index_at(name_and_type_index);
        Symbol* signature = cp->symbol_at(type_index);
        BasicType bt = Signature::basic_type(signature);
        return type2size[bt];
      }
    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokeinterface: {
        int cp_index = Bytes::get_native_u2(code_base+ pos);
        ConstantPool* cp = _method->constants();
        int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
        int name_index = cp->name_ref_index_at(name_and_type_index);
        Symbol* name = cp->symbol_at(name_index);

        // Assume the call of a constructor can never cause a NullPointerException
        // (which is true in Java). This is mainly used to avoid generating wrong
        // messages for NullPointerExceptions created explicitly by new in Java code.
        if (name != vmSymbols::object_initializer_name()) {
          int     type_index = cp->signature_ref_index_at(name_and_type_index);
          Symbol* signature  = cp->symbol_at(type_index);
          // The 'this' parameter was null. Return the slot of it.
          return ArgumentSizeComputer(signature).size();
        } else {
          return NPE_EXPLICIT_CONSTRUCTED;
        }
      }

    default:
      break;
  }

  return INVALID_BYTECODE_ENCOUNTERED;
}

bool ExceptionMessageBuilder::print_NPE_cause(outputStream* os, int bci, int slot) {
  if (print_NPE_cause0(os, bci, slot, _max_cause_detail, false, " because \"")) {
    os->print("\" is null");
    return true;
  }
  return false;
}

// Recursively print what was null.
//
// Go to the bytecode that pushed slot 'slot' on the operand stack
// at bytecode 'bci'. Compute a message for that bytecode. If
// necessary (array, field), recur further.
// At most do max_detail recursions.
// Prefix is used to print a proper beginning of the whole
// sentence.
// inner_expr is used to omit some text, like 'static' in
// inner expressions like array subscripts.
//
// Returns true if something was printed.
//
bool ExceptionMessageBuilder::print_NPE_cause0(outputStream* os, int bci, int slot,
                                               int max_detail,
                                               bool inner_expr, const char *prefix) {
  assert(bci >= 0, "BCI too low");
  assert(bci < get_size(), "BCI too large");

  if (max_detail <= 0) {
    return false;
  }

  if (_stacks->at(bci) == nullptr) {
    return false;
  }

  SimulatedOperandStack* stack = _stacks->at(bci);
  assert(slot >= 0, "Slot nr. too low");
  assert(slot < stack->get_size(), "Slot nr. too large");

  StackSlotAnalysisData slotData = stack->get_slot_data(slot);

  if (!slotData.has_bci()) {
    return false;
  }

  // Get the bytecode.
  unsigned int source_bci = slotData.get_bci();
  address code_base = _method->constMethod()->code_base();
  Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci);
  bool is_wide = false;
  int pos = source_bci + 1;

  if (code == Bytecodes::_wide) {
    is_wide = true;
    code = Bytecodes::java_code_at(_method, code_base + source_bci + 1);
    pos += 1;
  }

  if (max_detail == _max_cause_detail &&
      prefix != nullptr &&
      code != Bytecodes::_invokevirtual &&
      code != Bytecodes::_invokespecial &&
      code != Bytecodes::_invokestatic &&
      code != Bytecodes::_invokeinterface) {
    os->print("%s", prefix);
  }

  switch (code) {
    case Bytecodes::_iload_0:
    case Bytecodes::_aload_0:
      print_local_var(os, source_bci, _method, 0, !stack->local_slot_was_written(0));
      return true;

    case Bytecodes::_iload_1:
    case Bytecodes::_aload_1:
      print_local_var(os, source_bci, _method, 1, !stack->local_slot_was_written(1));
      return true;

    case Bytecodes::_iload_2:
    case Bytecodes::_aload_2:
      print_local_var(os, source_bci, _method, 2, !stack->local_slot_was_written(2));
      return true;

    case Bytecodes::_iload_3:
    case Bytecodes::_aload_3:
      print_local_var(os, source_bci, _method, 3, !stack->local_slot_was_written(3));
      return true;

    case Bytecodes::_iload:
    case Bytecodes::_aload: {
      int index;
      if (is_wide) {
        index = Bytes::get_Java_u2(code_base + source_bci + 2);
      } else {
        index = *(uint8_t*) (code_base + source_bci + 1);
      }
      print_local_var(os, source_bci, _method, index, !stack->local_slot_was_written(index));
      return true;
    }

    case Bytecodes::_aconst_null:
      os->print("null");
      return true;
    case Bytecodes::_iconst_m1:
      os->print("-1");
      return true;
    case Bytecodes::_iconst_0:
      os->print("0");
      return true;
    case Bytecodes::_iconst_1:
      os->print("1");
      return true;
    case Bytecodes::_iconst_2:
      os->print("2");
      return true;
    case Bytecodes::_iconst_3:
      os->print("3");
      return true;
    case Bytecodes::_iconst_4:
      os->print("4");
      return true;
    case Bytecodes::_iconst_5:
      os->print("5");
      return true;
    case Bytecodes::_bipush: {
      jbyte con = *(jbyte*) (code_base + source_bci + 1);
      os->print("%d", con);
      return true;
    }
    case Bytecodes::_sipush: {
      u2 con = Bytes::get_Java_u2(code_base + source_bci + 1);
      os->print("%d", con);
      return true;
    }
   case Bytecodes::_iaload:
   case Bytecodes::_aaload: {
      // Print the 'name' of the array. Go back to the bytecode that
      // pushed the array reference on the operand stack.
     if (!print_NPE_cause0(os, source_bci, 1, max_detail - 1, inner_expr)) {
        //  Returned false. Max recursion depth was reached. Print dummy.
        os->print("<array>");
      }
      os->print("[");
      // Print the index expression. Go back to the bytecode that
      // pushed the index on the operand stack.
      // inner_expr == true so we don't print unwanted strings
      // as "The return value of'". And don't decrement max_detail so we always
      // get a value here and only cancel out on the dereference.
      if (!print_NPE_cause0(os, source_bci, 0, max_detail, true)) {
        // Returned false. We don't print complex array index expressions. Print placeholder.
        os->print("...");
      }
      os->print("]");
      return true;
    }

    case Bytecodes::_getstatic: {
      int cp_index = Bytes::get_native_u2(code_base + pos);
      print_field_and_class(os, _method, cp_index, code);
      return true;
    }

    case Bytecodes::_getfield: {
      // Print the sender. Go back to the bytecode that
      // pushed the sender on the operand stack.
      if (print_NPE_cause0(os, source_bci, 0, max_detail - 1, inner_expr)) {
        os->print(".");
      }
      int cp_index = Bytes::get_native_u2(code_base + pos);
      os->print("%s", get_field_name(_method, cp_index, code));
      return true;
    }

    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokestatic:
    case Bytecodes::_invokeinterface: {
      int cp_index = Bytes::get_native_u2(code_base + pos);
      if (max_detail == _max_cause_detail && !inner_expr) {
        os->print(" because the return value of \"");
      }
      print_method_name(os, _method, cp_index, code);
      return true;
    }

    default: break;
  }
  return false;
}

void ExceptionMessageBuilder::print_NPE_failed_action(outputStream *os, int bci) {

  // Get the bytecode.
  address code_base = _method->constMethod()->code_base();
  Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);
  int pos = bci + 1;
  if (code == Bytecodes::_wide) {
    code = Bytecodes::java_code_at(_method, code_base + bci + 1);
    pos += 1;
  }

  switch (code) {
    case Bytecodes::_iaload:
      os->print("Cannot load from int array"); break;
    case Bytecodes::_faload:
      os->print("Cannot load from float array"); break;
    case Bytecodes::_aaload:
      os->print("Cannot load from object array"); break;
    case Bytecodes::_baload:
      os->print("Cannot load from byte/boolean array"); break;
    case Bytecodes::_caload:
      os->print("Cannot load from char array"); break;
    case Bytecodes::_saload:
      os->print("Cannot load from short array"); break;
    case Bytecodes::_laload:
      os->print("Cannot load from long array"); break;
    case Bytecodes::_daload:
      os->print("Cannot load from double array"); break;

    case Bytecodes::_iastore:
      os->print("Cannot store to int array"); break;
    case Bytecodes::_fastore:
      os->print("Cannot store to float array"); break;
    case Bytecodes::_aastore:
      os->print("Cannot store to object array"); break;
    case Bytecodes::_bastore:
      os->print("Cannot store to byte/boolean array"); break;
    case Bytecodes::_castore:
      os->print("Cannot store to char array"); break;
    case Bytecodes::_sastore:
      os->print("Cannot store to short array"); break;
    case Bytecodes::_lastore:
      os->print("Cannot store to long array"); break;
    case Bytecodes::_dastore:
      os->print("Cannot store to double array"); break;

    case Bytecodes::_arraylength:
      os->print("Cannot read the array length"); break;
    case Bytecodes::_athrow:
      os->print("Cannot throw exception"); break;
    case Bytecodes::_monitorenter:
      os->print("Cannot enter synchronized block"); break;
    case Bytecodes::_monitorexit:
      os->print("Cannot exit synchronized block"); break;
    case Bytecodes::_getfield: {
        int cp_index = Bytes::get_native_u2(code_base + pos);
        ConstantPool* cp = _method->constants();
        int name_and_type_index = cp->name_and_type_ref_index_at(cp_index, code);
        int name_index = cp->name_ref_index_at(name_and_type_index);
        Symbol* name = cp->symbol_at(name_index);
        os->print("Cannot read field \"%s\"", name->as_C_string());
      } break;
    case Bytecodes::_putfield: {
        int cp_index = Bytes::get_native_u2(code_base + pos);
        os->print("Cannot assign field \"%s\"", get_field_name(_method, cp_index, code));
      } break;
    case Bytecodes::_invokevirtual:
    case Bytecodes::_invokespecial:
    case Bytecodes::_invokeinterface: {
        int cp_index = Bytes::get_native_u2(code_base+ pos);
        os->print("Cannot invoke \"");
        print_method_name(os, _method, cp_index, code);
        os->print("\"");
      } break;

    default:
      assert(0, "We should have checked this bytecode in get_NPE_null_slot().");
      break;
  }
}

// Main API
bool BytecodeUtils::get_NPE_message_at(outputStream* ss, Method* method, int bci) {

  NoSafepointVerifier _nsv;   // Cannot use this object over a safepoint.

  // If this NPE was created via reflection, we have no real NPE.
  if (method->method_holder() ==
      vmClasses::reflect_DirectConstructorHandleAccessor_NativeAccessor_klass()) {
    return false;
  }

  // Analyse the bytecodes.
  ResourceMark rm;
  ExceptionMessageBuilder emb(method, bci);

  // The slot of the operand stack that contains the null reference.
  // Also checks for NPE explicitly constructed and returns NPE_EXPLICIT_CONSTRUCTED.
  int slot = emb.get_NPE_null_slot(bci);

  // Build the message.
  if (slot == NPE_EXPLICIT_CONSTRUCTED) {
    // We don't want to print a message.
    return false;
  } else if (slot == INVALID_BYTECODE_ENCOUNTERED) {
    // We encountered a bytecode that does not dereference a reference.
    DEBUG_ONLY(ss->print("There cannot be a NullPointerException at bci %d of method %s",
                         bci, method->external_name()));
    NOT_DEBUG(return false);
  } else {
    // Print string describing which action (bytecode) could not be
    // performed because of the null reference.
    emb.print_NPE_failed_action(ss, bci);
    // Print a description of what is null.
    if (!emb.print_NPE_cause(ss, bci, slot)) {
      // Nothing was printed. End the sentence without the 'because'
      // subordinate sentence.
    }
  }
  return true;
}
