Path: blob/master/src/hotspot/share/interpreter/bytecodeUtils.cpp
64440 views
/*1* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2019 SAP SE. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "classfile/vmClasses.hpp"27#include "classfile/vmSymbols.hpp"28#include "gc/shared/gcLocker.hpp"29#include "interpreter/bytecodeUtils.hpp"30#include "memory/resourceArea.hpp"31#include "runtime/signature.hpp"32#include "runtime/safepointVerifiers.hpp"33#include "utilities/events.hpp"34#include "utilities/ostream.hpp"3536class SimulatedOperandStack;37class ExceptionMessageBuilder;3839// The entries of a SimulatedOperandStack. They carry the analysis40// information gathered for the slot.41class StackSlotAnalysisData {42private:4344friend class SimulatedOperandStack;45friend class ExceptionMessageBuilder;4647unsigned int _bci:17; // The bci of the bytecode that pushed the current value on the operand stack.48// INVALID if ambiguous, e.g. after a control flow merge.49// 16 bits for bci (max bytecode size) and one for INVALID.50unsigned int _type:15; // The BasicType of the value on the operand stack.5152// Merges this slot data with the given one and returns the result. If53// the bcis of the two merged objects are different, the bci of the result54// will be undefined. If the types are different, the result type is T_CONFLICT.55// (An exception is if one type is an array and the other is object, then56// the result type will be T_OBJECT).57StackSlotAnalysisData merge(StackSlotAnalysisData other);5859public:6061// Creates a new object with an invalid bci and the given type.62StackSlotAnalysisData(BasicType type = T_CONFLICT);6364// Creates a new object with the given bci and type.65StackSlotAnalysisData(int bci, BasicType type);6667enum {68// An invalid bytecode index, as > 65535.69INVALID = 0x1FFFF70};7172// Returns the bci. If the bci is invalid, INVALID is returned.73unsigned int get_bci();7475// Returns true, if the bci is not invalid.76bool has_bci() { return get_bci() != INVALID; }7778// Returns the type of the slot data.79BasicType get_type();80};8182// A stack consisting of SimulatedOperandStackEntries.83// This represents the analysis information for the operand stack84// for a given bytecode at a given bci.85// It also holds an additional field that serves to collect86// information whether local slots were written.87class SimulatedOperandStack: CHeapObj<mtInternal> {8889private:9091friend class ExceptionMessageBuilder;92friend class StackSlotAnalysisData;9394// The stack.95GrowableArray<StackSlotAnalysisData> _stack;9697// Optimized bytecode can reuse local variable slots for several98// 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 been101// written, we don't know any more whether it was written as the102// corresponding parameter, or whether another local has been103// mapped to the slot. So we don't want to print 'parameter<i>' any104// more, but 'local<i>'. Similary for 'this'.105// Therefore, during the analysis, we mark a bit for local slots that106// get written and propagate this information.107// We only run the analysis for 64 slots. If a method has more108// parameters, we print 'local<i>' in all cases.109uint64_t _written_local_slots;110111SimulatedOperandStack(): _written_local_slots(0) { };112SimulatedOperandStack(const SimulatedOperandStack ©);113114// Pushes the given slot data.115void push_raw(StackSlotAnalysisData slotData);116117// Like push_raw, but if the slotData has type long or double, we push two.118void push(StackSlotAnalysisData slotData);119120// Like push(slotData), but using bci/type to create an instance of121// StackSlotAnalysisData first.122void push(int bci, BasicType type);123124// Pops the given number of entries.125void pop(int slots);126127// Merges this with the given stack by merging all entries. The128// size of the stacks must be the same.129void merge(SimulatedOperandStack const& other);130131public:132133// Returns the size of the stack.134int get_size() const;135136// Returns the slot data at the given index. Slot 0 is top of stack.137StackSlotAnalysisData get_slot_data(int slot);138139// Mark that local slot i was written.140void set_local_slot_written(int i);141142// Check whether local slot i was written by this or a previous bytecode.143bool local_slot_was_written(int i);144};145146// Helper class to build internal exception messages for exceptions147// that are thrown because prerequisites to execute a bytecode148// are not met.149// E.g., if a NPE is thrown because an iload can not be executed150// by the VM because the reference to load from is null.151//152// It analyses the bytecode to assemble Java-like message text153// to give precise information where in a larger expression the154// exception occured.155//156// To assemble this message text, it is needed to know how157// operand stack slot entries were pushed on the operand stack.158// This class contains an analysis over the bytecodes to compute159// this information. The information is stored in a160// SimulatedOperandStack for each bytecode.161class ExceptionMessageBuilder : public StackObj {162163// The stacks for each bytecode.164GrowableArray<SimulatedOperandStack*>* _stacks;165166// The method.167Method* _method;168169// The number of entries used (the sum of all entries of all stacks).170int _nr_of_entries;171172// If true, we have added at least one new stack.173bool _added_one;174175// If true, we have processed all bytecodes.176bool _all_processed;177178// The maximum number of entries we want to use. This is used to179// limit the amount of memory we waste for insane methods (as they180// appear in JCK tests).181static const int _max_entries = 1000000;182183static const int _max_cause_detail = 5;184185// Merges the stack the the given bci with the given stack. If there186// is no stack at the bci, we just put the given stack there. This187// method doesn't takes ownership of the stack.188void merge(int bci, SimulatedOperandStack* stack);189190// Processes the instruction at the given bci in the method. Returns191// the size of the instruction.192int do_instruction(int bci);193194bool print_NPE_cause0(outputStream *os, int bci, int slot, int max_detail,195bool inner_expr = false, const char *prefix = NULL);196197public:198199// Creates an ExceptionMessageBuilder object and runs the analysis200// building SimulatedOperandStacks for each bytecode in the given201// method (the method must be rewritten already). Note that you're202// not allowed to use this object when crossing a safepoint! If the203// bci is != -1, we only create the stacks as far as needed to get a204// stack for the bci.205ExceptionMessageBuilder(Method* method, int bci = -1);206207// Releases the resources.208~ExceptionMessageBuilder();209210// Returns the number of stacks (this is the size of the method).211int get_size() { return _stacks->length() - 1; }212213// Assuming that a NullPointerException was thrown at the given bci,214// we return the nr of the slot holding the null reference. If this215// NPE is created by hand, we return -2 as the slot. If there216// cannot be a NullPointerException at the bci, -1 is returned.217int get_NPE_null_slot(int bci);218219// Prints a java-like expression for the bytecode that pushed220// the value to the given slot being live at the given bci.221// It constructs the expression by recursing backwards over the222// bytecode using the results of the analysis done in the223// constructor of ExceptionMessageBuilder.224// os: The stream to print the message to.225// bci: The index of the bytecode that caused the NPE.226// slot: The slot on the operand stack that contains null.227// The slots are numbered from TOS downwards, i.e.,228// TOS has the slot number 0, that below 1 and so on.229//230// Returns false if nothing was printed, else true.231bool print_NPE_cause(outputStream *os, int bci, int slot);232233// Prints a string describing the failed action.234void print_NPE_failed_action(outputStream *os, int bci);235};236237// Replaces the following well-known class names:238// java.lang.Object -> Object239// java.lang.String -> String240static char *trim_well_known_class_names_from_signature(char *signature) {241size_t len = strlen(signature);242size_t skip_len = strlen("java.lang.");243size_t min_pattern_len = strlen("java.lang.String");244if (len < min_pattern_len) return signature;245246for (size_t isrc = 0, idst = 0; isrc <= len; isrc++, idst++) {247// We must be careful not to trim names like test.java.lang.String.248if ((isrc == 0 && strncmp(signature + isrc, "java.lang.Object", min_pattern_len) == 0) ||249(isrc == 0 && strncmp(signature + isrc, "java.lang.String", min_pattern_len) == 0) ||250(isrc > 1 && strncmp(signature + isrc-2, ", java.lang.Object", min_pattern_len+2) == 0) ||251(isrc > 1 && strncmp(signature + isrc-2, ", java.lang.String", min_pattern_len+2) == 0) ) {252isrc += skip_len;253}254if (idst != isrc) {255signature[idst] = signature[isrc];256}257}258return signature;259}260261// Replaces the following well-known class names:262// java.lang.Object -> Object263// java.lang.String -> String264static void print_klass_name(outputStream *os, Symbol *klass) {265const char *name = klass->as_klass_external_name();266if (strcmp(name, "java.lang.Object") == 0) name = "Object";267if (strcmp(name, "java.lang.String") == 0) name = "String";268os->print("%s", name);269}270271// Prints the name of the method that is described at constant pool272// index cp_index in the constant pool of method 'method'.273static void print_method_name(outputStream *os, Method* method, int cp_index) {274ResourceMark rm;275ConstantPool* cp = method->constants();276Symbol* klass = cp->klass_ref_at_noresolve(cp_index);277Symbol* name = cp->name_ref_at(cp_index);278Symbol* signature = cp->signature_ref_at(cp_index);279280print_klass_name(os, klass);281os->print(".%s(", name->as_C_string());282stringStream sig;283signature->print_as_signature_external_parameters(&sig);284os->print("%s)", trim_well_known_class_names_from_signature(sig.as_string()));285}286287// Prints the name of the field that is described at constant pool288// index cp_index in the constant pool of method 'method'.289static void print_field_and_class(outputStream *os, Method* method, int cp_index) {290ResourceMark rm;291ConstantPool* cp = method->constants();292Symbol* klass = cp->klass_ref_at_noresolve(cp_index);293Symbol *name = cp->name_ref_at(cp_index);294print_klass_name(os, klass);295os->print(".%s", name->as_C_string());296}297298// Returns the name of the field that is described at constant pool299// index cp_index in the constant pool of method 'method'.300static char const* get_field_name(Method* method, int cp_index) {301Symbol* name = method->constants()->name_ref_at(cp_index);302return name->as_C_string();303}304305static void print_local_var(outputStream *os, unsigned int bci, Method* method, int slot, bool is_parameter) {306if (method->has_localvariable_table()) {307for (int i = 0; i < method->localvariable_table_length(); i++) {308LocalVariableTableElement* elem = method->localvariable_table_start() + i;309unsigned int start = elem->start_bci;310unsigned int end = start + elem->length;311312if ((bci >= start) && (bci < end) && (elem->slot == slot)) {313ConstantPool* cp = method->constants();314char *var = cp->symbol_at(elem->name_cp_index)->as_C_string();315os->print("%s", var);316317return;318}319}320}321322// Handle at least some cases we know.323if (!method->is_static() && (slot == 0) && is_parameter) {324os->print("this");325} else {326int curr = method->is_static() ? 0 : 1;327SignatureStream ss(method->signature());328int param_index = 1;329bool found = false;330331for (SignatureStream ss(method->signature()); !ss.is_done(); ss.next()) {332if (ss.at_return_type()) {333continue;334}335int size = type2size[ss.type()];336if ((slot >= curr) && (slot < curr + size)) {337found = true;338break;339}340param_index += 1;341curr += size;342}343344if (found && is_parameter) {345os->print("<parameter%d>", param_index);346} else {347// This is the best we can do.348os->print("<local%d>", slot);349}350}351}352353StackSlotAnalysisData::StackSlotAnalysisData(BasicType type) : _bci(INVALID), _type(type) {}354355StackSlotAnalysisData::StackSlotAnalysisData(int bci, BasicType type) : _bci(bci), _type(type) {356assert(bci >= 0, "BCI must be >= 0");357assert(bci < 65536, "BCI must be < 65536");358}359360unsigned int StackSlotAnalysisData::get_bci() {361return _bci;362}363364BasicType StackSlotAnalysisData::get_type() {365return (BasicType)_type;366}367368StackSlotAnalysisData StackSlotAnalysisData::merge(StackSlotAnalysisData other) {369if (get_type() != other.get_type()) {370if (((get_type() == T_OBJECT) || (get_type() == T_ARRAY)) &&371((other.get_type() == T_OBJECT) || (other.get_type() == T_ARRAY))) {372if (get_bci() == other.get_bci()) {373return StackSlotAnalysisData(get_bci(), T_OBJECT);374} else {375return StackSlotAnalysisData(T_OBJECT);376}377} else {378return StackSlotAnalysisData(T_CONFLICT);379}380}381382if (get_bci() == other.get_bci()) {383return *this;384} else {385return StackSlotAnalysisData(get_type());386}387}388389SimulatedOperandStack::SimulatedOperandStack(const SimulatedOperandStack ©) {390for (int i = 0; i < copy.get_size(); i++) {391push_raw(copy._stack.at(i));392}393_written_local_slots = copy._written_local_slots;394}395396void SimulatedOperandStack::push_raw(StackSlotAnalysisData slotData) {397if (slotData.get_type() == T_VOID) {398return;399}400401_stack.push(slotData);402}403404void SimulatedOperandStack::push(StackSlotAnalysisData slotData) {405if (type2size[slotData.get_type()] == 2) {406push_raw(slotData);407push_raw(slotData);408} else {409push_raw(slotData);410}411}412413void SimulatedOperandStack::push(int bci, BasicType type) {414push(StackSlotAnalysisData(bci, type));415}416417void SimulatedOperandStack::pop(int slots) {418for (int i = 0; i < slots; ++i) {419_stack.pop();420}421422assert(get_size() >= 0, "Popped too many slots");423}424425void SimulatedOperandStack::merge(SimulatedOperandStack const& other) {426assert(get_size() == other.get_size(), "Stacks not of same size");427428for (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}433434int SimulatedOperandStack::get_size() const {435return _stack.length();436}437438StackSlotAnalysisData SimulatedOperandStack::get_slot_data(int slot) {439assert(slot >= 0, "Slot=%d < 0", slot);440assert(slot < get_size(), "Slot=%d >= size=%d", slot, get_size());441442return _stack.at(get_size() - slot - 1);443}444445void SimulatedOperandStack::set_local_slot_written(int i) {446// Local slots > 63 are very unlikely. Consider these447// as written all the time. Saves space and complexity448// for dynamic data size.449if (i > 63) return;450_written_local_slots = _written_local_slots | (1ULL << i);451}452453bool SimulatedOperandStack::local_slot_was_written(int i) {454if (i > 63) return true;455return (_written_local_slots & (1ULL << i)) != 0;456}457458ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :459_method(method), _nr_of_entries(0),460_added_one(true), _all_processed(false) {461462ConstMethod* const_method = method->constMethod();463const int len = const_method->code_size();464465assert(bci >= 0, "BCI too low: %d", bci);466assert(bci < len, "BCI too large: %d size: %d", bci, len);467468_stacks = new GrowableArray<SimulatedOperandStack*> (len + 1);469470for (int i = 0; i <= len; ++i) {471_stacks->push(NULL);472}473474// Initialize stack a bci 0.475_stacks->at_put(0, new SimulatedOperandStack());476477// And initialize the start of all exception handlers.478if (const_method->has_exception_handler()) {479ExceptionTableElement *et = const_method->exception_table_start();480for (int i = 0; i < const_method->exception_table_length(); ++i) {481u2 index = et[i].handler_pc;482483if (_stacks->at(index) == NULL) {484_stacks->at_put(index, new SimulatedOperandStack());485_stacks->at(index)->push(index, T_OBJECT);486}487}488}489490// Do this until each bytecode has a stack or we haven't491// added a new stack in one iteration.492while (!_all_processed && _added_one) {493_all_processed = true;494_added_one = false;495496for (int i = 0; i < len; ) {497// Analyse bytecode i. Step by size of the analyzed bytecode to next bytecode.498i += do_instruction(i);499500// If we want the data only for a certain bci, we can possibly end early.501if ((bci == i) && (_stacks->at(i) != NULL)) {502_all_processed = true;503break;504}505506if (_nr_of_entries > _max_entries) {507return;508}509}510}511}512513ExceptionMessageBuilder::~ExceptionMessageBuilder() {514if (_stacks != NULL) {515for (int i = 0; i < _stacks->length(); ++i) {516delete _stacks->at(i);517}518}519}520521void ExceptionMessageBuilder::merge(int bci, SimulatedOperandStack* stack) {522assert(stack != _stacks->at(bci), "Cannot merge itself");523524if (_stacks->at(bci) != NULL) {525stack->merge(*_stacks->at(bci));526} else {527// Got a new stack, so count the entries.528_nr_of_entries += stack->get_size();529}530531// Replace the stack at this bci with a copy of our new merged stack.532delete _stacks->at(bci);533_stacks->at_put(bci, new SimulatedOperandStack(*stack));534}535536int ExceptionMessageBuilder::do_instruction(int bci) {537ConstMethod* const_method = _method->constMethod();538address code_base = _method->constMethod()->code_base();539540// We use the java code, since we don't want to cope with all the fast variants.541int len = Bytecodes::java_length_at(_method, code_base + bci);542543// If we have no stack for this bci, we cannot process the bytecode now.544if (_stacks->at(bci) == NULL) {545_all_processed = false;546return len;547}548549// Make a local copy of the stack for this bci to work on.550SimulatedOperandStack* stack = new SimulatedOperandStack(*_stacks->at(bci));551552// dest_bci is != -1 if we branch.553int dest_bci = -1;554555// This is for table and lookup switch.556static const int initial_length = 2;557GrowableArray<int> dests(initial_length);558559bool flow_ended = false;560561// Get the bytecode.562bool is_wide = false;563Bytecodes::Code raw_code = Bytecodes::code_at(_method, code_base + bci);564Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);565int pos = bci + 1;566567if (code == Bytecodes::_wide) {568is_wide = true;569code = Bytecodes::java_code_at(_method, code_base + bci + 1);570pos += 1;571}572573// Now simulate the action of each bytecode.574switch (code) {575case Bytecodes::_nop:576case Bytecodes::_aconst_null:577case Bytecodes::_iconst_m1:578case Bytecodes::_iconst_0:579case Bytecodes::_iconst_1:580case Bytecodes::_iconst_2:581case Bytecodes::_iconst_3:582case Bytecodes::_iconst_4:583case Bytecodes::_iconst_5:584case Bytecodes::_lconst_0:585case Bytecodes::_lconst_1:586case Bytecodes::_fconst_0:587case Bytecodes::_fconst_1:588case Bytecodes::_fconst_2:589case Bytecodes::_dconst_0:590case Bytecodes::_dconst_1:591case Bytecodes::_bipush:592case Bytecodes::_sipush:593case Bytecodes::_iload:594case Bytecodes::_lload:595case Bytecodes::_fload:596case Bytecodes::_dload:597case Bytecodes::_aload:598case Bytecodes::_iload_0:599case Bytecodes::_iload_1:600case Bytecodes::_iload_2:601case Bytecodes::_iload_3:602case Bytecodes::_lload_0:603case Bytecodes::_lload_1:604case Bytecodes::_lload_2:605case Bytecodes::_lload_3:606case Bytecodes::_fload_0:607case Bytecodes::_fload_1:608case Bytecodes::_fload_2:609case Bytecodes::_fload_3:610case Bytecodes::_dload_0:611case Bytecodes::_dload_1:612case Bytecodes::_dload_2:613case Bytecodes::_dload_3:614case Bytecodes::_aload_0:615case Bytecodes::_aload_1:616case Bytecodes::_aload_2:617case Bytecodes::_aload_3:618case Bytecodes::_iinc:619case Bytecodes::_new:620stack->push(bci, Bytecodes::result_type(code));621break;622623case Bytecodes::_ldc:624case Bytecodes::_ldc_w:625case Bytecodes::_ldc2_w: {626int cp_index;627ConstantPool* cp = _method->constants();628629if (code == Bytecodes::_ldc) {630cp_index = *(uint8_t*) (code_base + pos);631632if (raw_code == Bytecodes::_fast_aldc) {633cp_index = cp->object_to_cp_index(cp_index);634}635} else {636if (raw_code == Bytecodes::_fast_aldc_w) {637cp_index = Bytes::get_native_u2(code_base + pos);638cp_index = cp->object_to_cp_index(cp_index);639}640else {641cp_index = Bytes::get_Java_u2(code_base + pos);642}643}644645constantTag tag = cp->tag_at(cp_index);646if (tag.is_klass() || tag.is_unresolved_klass() ||647tag.is_method() || tag.is_interface_method() ||648tag.is_field() || tag.is_string()) {649stack->push(bci, T_OBJECT);650} else if (tag.is_int()) {651stack->push(bci, T_INT);652} else if (tag.is_long()) {653stack->push(bci, T_LONG);654} else if (tag.is_float()) {655stack->push(bci, T_FLOAT);656} else if (tag.is_double()) {657stack->push(bci, T_DOUBLE);658} else {659assert(false, "Unexpected tag");660}661break;662}663664case Bytecodes::_iaload:665case Bytecodes::_faload:666case Bytecodes::_aaload:667case Bytecodes::_baload:668case Bytecodes::_caload:669case Bytecodes::_saload:670case Bytecodes::_laload:671case Bytecodes::_daload:672stack->pop(2);673stack->push(bci, Bytecodes::result_type(code));674break;675676case Bytecodes::_istore:677case Bytecodes::_lstore:678case Bytecodes::_fstore:679case Bytecodes::_dstore:680case Bytecodes::_astore:681int index;682if (is_wide) {683index = Bytes::get_Java_u2(code_base + bci + 2);684} else {685index = *(uint8_t*) (code_base + bci + 1);686}687stack->set_local_slot_written(index);688stack->pop(-Bytecodes::depth(code));689break;690case Bytecodes::_istore_0:691case Bytecodes::_lstore_0:692case Bytecodes::_fstore_0:693case Bytecodes::_dstore_0:694case Bytecodes::_astore_0:695stack->set_local_slot_written(0);696stack->pop(-Bytecodes::depth(code));697break;698case Bytecodes::_istore_1:699case Bytecodes::_fstore_1:700case Bytecodes::_lstore_1:701case Bytecodes::_dstore_1:702case Bytecodes::_astore_1:703stack->set_local_slot_written(1);704stack->pop(-Bytecodes::depth(code));705break;706case Bytecodes::_istore_2:707case Bytecodes::_lstore_2:708case Bytecodes::_fstore_2:709case Bytecodes::_dstore_2:710case Bytecodes::_astore_2:711stack->set_local_slot_written(2);712stack->pop(-Bytecodes::depth(code));713break;714case Bytecodes::_istore_3:715case Bytecodes::_lstore_3:716case Bytecodes::_fstore_3:717case Bytecodes::_dstore_3:718case Bytecodes::_astore_3:719stack->set_local_slot_written(3);720stack->pop(-Bytecodes::depth(code));721break;722case Bytecodes::_iastore:723case Bytecodes::_lastore:724case Bytecodes::_fastore:725case Bytecodes::_dastore:726case Bytecodes::_aastore:727case Bytecodes::_bastore:728case Bytecodes::_castore:729case Bytecodes::_sastore:730case Bytecodes::_pop:731case Bytecodes::_pop2:732case Bytecodes::_monitorenter:733case Bytecodes::_monitorexit:734case Bytecodes::_breakpoint:735stack->pop(-Bytecodes::depth(code));736break;737738case Bytecodes::_dup:739stack->push_raw(stack->get_slot_data(0));740break;741742case Bytecodes::_dup_x1: {743StackSlotAnalysisData top1 = stack->get_slot_data(0);744StackSlotAnalysisData top2 = stack->get_slot_data(1);745stack->pop(2);746stack->push_raw(top1);747stack->push_raw(top2);748stack->push_raw(top1);749break;750}751752case Bytecodes::_dup_x2: {753StackSlotAnalysisData top1 = stack->get_slot_data(0);754StackSlotAnalysisData top2 = stack->get_slot_data(1);755StackSlotAnalysisData top3 = stack->get_slot_data(2);756stack->pop(3);757stack->push_raw(top1);758stack->push_raw(top3);759stack->push_raw(top2);760stack->push_raw(top1);761break;762}763764case Bytecodes::_dup2:765stack->push_raw(stack->get_slot_data(1));766// The former '0' entry is now at '1'.767stack->push_raw(stack->get_slot_data(1));768break;769770case Bytecodes::_dup2_x1: {771StackSlotAnalysisData top1 = stack->get_slot_data(0);772StackSlotAnalysisData top2 = stack->get_slot_data(1);773StackSlotAnalysisData top3 = stack->get_slot_data(2);774stack->pop(3);775stack->push_raw(top2);776stack->push_raw(top1);777stack->push_raw(top3);778stack->push_raw(top2);779stack->push_raw(top1);780break;781}782783case Bytecodes::_dup2_x2: {784StackSlotAnalysisData top1 = stack->get_slot_data(0);785StackSlotAnalysisData top2 = stack->get_slot_data(1);786StackSlotAnalysisData top3 = stack->get_slot_data(2);787StackSlotAnalysisData top4 = stack->get_slot_data(3);788stack->pop(4);789stack->push_raw(top2);790stack->push_raw(top1);791stack->push_raw(top4);792stack->push_raw(top3);793stack->push_raw(top2);794stack->push_raw(top1);795break;796}797798case Bytecodes::_swap: {799StackSlotAnalysisData top1 = stack->get_slot_data(0);800StackSlotAnalysisData top2 = stack->get_slot_data(1);801stack->pop(2);802stack->push(top1);803stack->push(top2);804break;805}806807case Bytecodes::_iadd:808case Bytecodes::_ladd:809case Bytecodes::_fadd:810case Bytecodes::_dadd:811case Bytecodes::_isub:812case Bytecodes::_lsub:813case Bytecodes::_fsub:814case Bytecodes::_dsub:815case Bytecodes::_imul:816case Bytecodes::_lmul:817case Bytecodes::_fmul:818case Bytecodes::_dmul:819case Bytecodes::_idiv:820case Bytecodes::_ldiv:821case Bytecodes::_fdiv:822case Bytecodes::_ddiv:823case Bytecodes::_irem:824case Bytecodes::_lrem:825case Bytecodes::_frem:826case Bytecodes::_drem:827case Bytecodes::_iand:828case Bytecodes::_land:829case Bytecodes::_ior:830case Bytecodes::_lor:831case Bytecodes::_ixor:832case Bytecodes::_lxor:833stack->pop(2 * type2size[Bytecodes::result_type(code)]);834stack->push(bci, Bytecodes::result_type(code));835break;836837case Bytecodes::_ineg:838case Bytecodes::_lneg:839case Bytecodes::_fneg:840case Bytecodes::_dneg:841stack->pop(type2size[Bytecodes::result_type(code)]);842stack->push(bci, Bytecodes::result_type(code));843break;844845case Bytecodes::_ishl:846case Bytecodes::_lshl:847case Bytecodes::_ishr:848case Bytecodes::_lshr:849case Bytecodes::_iushr:850case Bytecodes::_lushr:851stack->pop(1 + type2size[Bytecodes::result_type(code)]);852stack->push(bci, Bytecodes::result_type(code));853break;854855case Bytecodes::_i2l:856case Bytecodes::_i2f:857case Bytecodes::_i2d:858case Bytecodes::_f2i:859case Bytecodes::_f2l:860case Bytecodes::_f2d:861case Bytecodes::_i2b:862case Bytecodes::_i2c:863case Bytecodes::_i2s:864stack->pop(1);865stack->push(bci, Bytecodes::result_type(code));866break;867868case Bytecodes::_l2i:869case Bytecodes::_l2f:870case Bytecodes::_l2d:871case Bytecodes::_d2i:872case Bytecodes::_d2l:873case Bytecodes::_d2f:874stack->pop(2);875stack->push(bci, Bytecodes::result_type(code));876break;877878case Bytecodes::_lcmp:879case Bytecodes::_fcmpl:880case Bytecodes::_fcmpg:881case Bytecodes::_dcmpl:882case Bytecodes::_dcmpg:883stack->pop(1 - Bytecodes::depth(code));884stack->push(bci, T_INT);885break;886887case Bytecodes::_ifeq:888case Bytecodes::_ifne:889case Bytecodes::_iflt:890case Bytecodes::_ifge:891case Bytecodes::_ifgt:892case Bytecodes::_ifle:893case Bytecodes::_if_icmpeq:894case Bytecodes::_if_icmpne:895case Bytecodes::_if_icmplt:896case Bytecodes::_if_icmpge:897case Bytecodes::_if_icmpgt:898case Bytecodes::_if_icmple:899case Bytecodes::_if_acmpeq:900case Bytecodes::_if_acmpne:901case Bytecodes::_ifnull:902case Bytecodes::_ifnonnull:903stack->pop(-Bytecodes::depth(code));904dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);905break;906907case Bytecodes::_jsr:908// NOTE: Bytecodes has wrong depth for jsr.909stack->push(bci, T_ADDRESS);910dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);911flow_ended = true;912break;913914case Bytecodes::_jsr_w: {915// NOTE: Bytecodes has wrong depth for jsr.916stack->push(bci, T_ADDRESS);917dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);918flow_ended = true;919break;920}921922case Bytecodes::_ret:923// We don't track local variables, so we cannot know were we924// return. This makes the stacks imprecise, but we have to925// live with that.926flow_ended = true;927break;928929case Bytecodes::_tableswitch: {930stack->pop(1);931pos = (pos + 3) & ~3;932dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);933int low = (int32_t) Bytes::get_Java_u4(code_base + pos + 4);934int high = (int32_t) Bytes::get_Java_u4(code_base + pos + 8);935936for (int64_t i = low; i <= high; ++i) {937dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 4 * (i - low)));938}939940break;941}942943case Bytecodes::_lookupswitch: {944stack->pop(1);945pos = (pos + 3) & ~3;946dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);947int nr_of_dests = (int32_t) Bytes::get_Java_u4(code_base + pos + 4);948949for (int i = 0; i < nr_of_dests; ++i) {950dests.push(bci + (int32_t) Bytes::get_Java_u4(code_base + pos + 12 + 8 * i));951}952953break;954}955956case Bytecodes::_ireturn:957case Bytecodes::_lreturn:958case Bytecodes::_freturn:959case Bytecodes::_dreturn:960case Bytecodes::_areturn:961case Bytecodes::_return:962case Bytecodes::_athrow:963stack->pop(-Bytecodes::depth(code));964flow_ended = true;965break;966967case Bytecodes::_getstatic:968case Bytecodes::_getfield: {969// Find out the type of the field accessed.970int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);971ConstantPool* cp = _method->constants();972int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);973int type_index = cp->signature_ref_index_at(name_and_type_index);974Symbol* signature = cp->symbol_at(type_index);975// Simulate the bytecode: pop the address, push the 'value' loaded976// from the field.977stack->pop(1 - Bytecodes::depth(code));978stack->push(bci, Signature::basic_type(signature));979break;980}981982case Bytecodes::_putstatic:983case Bytecodes::_putfield: {984int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);985ConstantPool* cp = _method->constants();986int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);987int type_index = cp->signature_ref_index_at(name_and_type_index);988Symbol* signature = cp->symbol_at(type_index);989BasicType bt = Signature::basic_type(signature);990stack->pop(type2size[bt] - Bytecodes::depth(code) - 1);991break;992}993994case Bytecodes::_invokevirtual:995case Bytecodes::_invokespecial:996case Bytecodes::_invokestatic:997case Bytecodes::_invokeinterface:998case Bytecodes::_invokedynamic: {999ConstantPool* cp = _method->constants();1000int cp_index;10011002if (code == Bytecodes::_invokedynamic) {1003cp_index = ((int) Bytes::get_native_u4(code_base + pos));1004} else {1005cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1006}10071008int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1009int type_index = cp->signature_ref_index_at(name_and_type_index);1010Symbol* signature = cp->symbol_at(type_index);10111012if ((code != Bytecodes::_invokestatic) && (code != Bytecodes::_invokedynamic)) {1013// Pop receiver.1014stack->pop(1);1015}10161017stack->pop(ArgumentSizeComputer(signature).size());1018ResultTypeFinder result_type(signature);1019stack->push(bci, result_type.type());1020break;1021}10221023case Bytecodes::_newarray:1024case Bytecodes::_anewarray:1025case Bytecodes::_instanceof:1026stack->pop(1);1027stack->push(bci, Bytecodes::result_type(code));1028break;10291030case Bytecodes::_arraylength:1031stack->pop(1);1032stack->push(bci, T_INT);1033break;10341035case Bytecodes::_checkcast:1036break;10371038case Bytecodes::_multianewarray:1039stack->pop(*(uint8_t*) (code_base + pos + 2));1040stack->push(bci, T_OBJECT);1041break;10421043case Bytecodes::_goto:1044stack->pop(-Bytecodes::depth(code));1045dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);1046flow_ended = true;1047break;104810491050case Bytecodes::_goto_w:1051stack->pop(-Bytecodes::depth(code));1052dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);1053flow_ended = true;1054break;10551056default:1057// Allow at least the bcis which have stack info to work.1058_all_processed = false;1059_added_one = false;1060delete stack;10611062return len;1063}10641065// Put new stack to the next instruction, if we might reach it from1066// this bci.1067if (!flow_ended) {1068if (_stacks->at(bci + len) == NULL) {1069_added_one = true;1070}1071merge(bci + len, stack);1072}10731074// Put the stack to the branch target too.1075if (dest_bci != -1) {1076if (_stacks->at(dest_bci) == NULL) {1077_added_one = true;1078}1079merge(dest_bci, stack);1080}10811082// If we have more than one branch target, process these too.1083for (int64_t i = 0; i < dests.length(); ++i) {1084if (_stacks->at(dests.at(i)) == NULL) {1085_added_one = true;1086}1087merge(dests.at(i), stack);1088}10891090delete stack;10911092return len;1093}10941095#define INVALID_BYTECODE_ENCOUNTERED -11096#define NPE_EXPLICIT_CONSTRUCTED -21097int ExceptionMessageBuilder::get_NPE_null_slot(int bci) {1098// Get the bytecode.1099address code_base = _method->constMethod()->code_base();1100Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);1101int pos = bci + 1; // Position of argument of the bytecode.1102if (code == Bytecodes::_wide) {1103code = Bytecodes::java_code_at(_method, code_base + bci + 1);1104pos += 1;1105}11061107switch (code) {1108case Bytecodes::_getfield:1109case Bytecodes::_arraylength:1110case Bytecodes::_athrow:1111case Bytecodes::_monitorenter:1112case Bytecodes::_monitorexit:1113return 0;1114case Bytecodes::_iaload:1115case Bytecodes::_faload:1116case Bytecodes::_aaload:1117case Bytecodes::_baload:1118case Bytecodes::_caload:1119case Bytecodes::_saload:1120case Bytecodes::_laload:1121case Bytecodes::_daload:1122return 1;1123case Bytecodes::_iastore:1124case Bytecodes::_fastore:1125case Bytecodes::_aastore:1126case Bytecodes::_bastore:1127case Bytecodes::_castore:1128case Bytecodes::_sastore:1129return 2;1130case Bytecodes::_lastore:1131case Bytecodes::_dastore:1132return 3;1133case Bytecodes::_putfield: {1134int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1135ConstantPool* cp = _method->constants();1136int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1137int type_index = cp->signature_ref_index_at(name_and_type_index);1138Symbol* signature = cp->symbol_at(type_index);1139BasicType bt = Signature::basic_type(signature);1140return type2size[bt];1141}1142case Bytecodes::_invokevirtual:1143case Bytecodes::_invokespecial:1144case Bytecodes::_invokeinterface: {1145int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1146ConstantPool* cp = _method->constants();1147int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1148int name_index = cp->name_ref_index_at(name_and_type_index);1149Symbol* name = cp->symbol_at(name_index);11501151// Assume the the call of a constructor can never cause a NullPointerException1152// (which is true in Java). This is mainly used to avoid generating wrong1153// messages for NullPointerExceptions created explicitly by new in Java code.1154if (name != vmSymbols::object_initializer_name()) {1155int type_index = cp->signature_ref_index_at(name_and_type_index);1156Symbol* signature = cp->symbol_at(type_index);1157// The 'this' parameter was null. Return the slot of it.1158return ArgumentSizeComputer(signature).size();1159} else {1160return NPE_EXPLICIT_CONSTRUCTED;1161}1162}11631164default:1165break;1166}11671168return INVALID_BYTECODE_ENCOUNTERED;1169}11701171bool ExceptionMessageBuilder::print_NPE_cause(outputStream* os, int bci, int slot) {1172if (print_NPE_cause0(os, bci, slot, _max_cause_detail, false, " because \"")) {1173os->print("\" is null");1174return true;1175}1176return false;1177}11781179// Recursively print what was null.1180//1181// Go to the bytecode that pushed slot 'slot' on the operand stack1182// at bytecode 'bci'. Compute a message for that bytecode. If1183// necessary (array, field), recur further.1184// At most do max_detail recursions.1185// Prefix is used to print a proper beginning of the whole1186// sentence.1187// inner_expr is used to omit some text, like 'static' in1188// inner expressions like array subscripts.1189//1190// Returns true if something was printed.1191//1192bool ExceptionMessageBuilder::print_NPE_cause0(outputStream* os, int bci, int slot,1193int max_detail,1194bool inner_expr, const char *prefix) {1195assert(bci >= 0, "BCI too low");1196assert(bci < get_size(), "BCI too large");11971198if (max_detail <= 0) {1199return false;1200}12011202if (_stacks->at(bci) == NULL) {1203return false;1204}12051206SimulatedOperandStack* stack = _stacks->at(bci);1207assert(slot >= 0, "Slot nr. too low");1208assert(slot < stack->get_size(), "Slot nr. too large");12091210StackSlotAnalysisData slotData = stack->get_slot_data(slot);12111212if (!slotData.has_bci()) {1213return false;1214}12151216// Get the bytecode.1217unsigned int source_bci = slotData.get_bci();1218address code_base = _method->constMethod()->code_base();1219Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci);1220bool is_wide = false;1221int pos = source_bci + 1;12221223if (code == Bytecodes::_wide) {1224is_wide = true;1225code = Bytecodes::java_code_at(_method, code_base + source_bci + 1);1226pos += 1;1227}12281229if (max_detail == _max_cause_detail &&1230prefix != NULL &&1231code != Bytecodes::_invokevirtual &&1232code != Bytecodes::_invokespecial &&1233code != Bytecodes::_invokestatic &&1234code != Bytecodes::_invokeinterface) {1235os->print("%s", prefix);1236}12371238switch (code) {1239case Bytecodes::_iload_0:1240case Bytecodes::_aload_0:1241print_local_var(os, source_bci, _method, 0, !stack->local_slot_was_written(0));1242return true;12431244case Bytecodes::_iload_1:1245case Bytecodes::_aload_1:1246print_local_var(os, source_bci, _method, 1, !stack->local_slot_was_written(1));1247return true;12481249case Bytecodes::_iload_2:1250case Bytecodes::_aload_2:1251print_local_var(os, source_bci, _method, 2, !stack->local_slot_was_written(2));1252return true;12531254case Bytecodes::_iload_3:1255case Bytecodes::_aload_3:1256print_local_var(os, source_bci, _method, 3, !stack->local_slot_was_written(3));1257return true;12581259case Bytecodes::_iload:1260case Bytecodes::_aload: {1261int index;1262if (is_wide) {1263index = Bytes::get_Java_u2(code_base + source_bci + 2);1264} else {1265index = *(uint8_t*) (code_base + source_bci + 1);1266}1267print_local_var(os, source_bci, _method, index, !stack->local_slot_was_written(index));1268return true;1269}12701271case Bytecodes::_aconst_null:1272os->print("null");1273return true;1274case Bytecodes::_iconst_m1:1275os->print("-1");1276return true;1277case Bytecodes::_iconst_0:1278os->print("0");1279return true;1280case Bytecodes::_iconst_1:1281os->print("1");1282return true;1283case Bytecodes::_iconst_2:1284os->print("2");1285return true;1286case Bytecodes::_iconst_3:1287os->print("3");1288return true;1289case Bytecodes::_iconst_4:1290os->print("4");1291return true;1292case Bytecodes::_iconst_5:1293os->print("5");1294return true;1295case Bytecodes::_bipush: {1296jbyte con = *(jbyte*) (code_base + source_bci + 1);1297os->print("%d", con);1298return true;1299}1300case Bytecodes::_sipush: {1301u2 con = Bytes::get_Java_u2(code_base + source_bci + 1);1302os->print("%d", con);1303return true;1304}1305case Bytecodes::_iaload:1306case Bytecodes::_aaload: {1307// Print the 'name' of the array. Go back to the bytecode that1308// pushed the array reference on the operand stack.1309if (!print_NPE_cause0(os, source_bci, 1, max_detail - 1, inner_expr)) {1310// Returned false. Max recursion depth was reached. Print dummy.1311os->print("<array>");1312}1313os->print("[");1314// Print the index expression. Go back to the bytecode that1315// pushed the index on the operand stack.1316// inner_expr == true so we don't print unwanted strings1317// as "The return value of'". And don't decrement max_detail so we always1318// get a value here and only cancel out on the dereference.1319if (!print_NPE_cause0(os, source_bci, 0, max_detail, true)) {1320// Returned false. We don't print complex array index expressions. Print placeholder.1321os->print("...");1322}1323os->print("]");1324return true;1325}13261327case Bytecodes::_getstatic: {1328int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG;1329print_field_and_class(os, _method, cp_index);1330return true;1331}13321333case Bytecodes::_getfield: {1334// Print the sender. Go back to the bytecode that1335// pushed the sender on the operand stack.1336if (print_NPE_cause0(os, source_bci, 0, max_detail - 1, inner_expr)) {1337os->print(".");1338}1339int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG;1340os->print("%s", get_field_name(_method, cp_index));1341return true;1342}13431344case Bytecodes::_invokevirtual:1345case Bytecodes::_invokespecial:1346case Bytecodes::_invokestatic:1347case Bytecodes::_invokeinterface: {1348int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1349if (max_detail == _max_cause_detail && !inner_expr) {1350os->print(" because the return value of \"");1351}1352print_method_name(os, _method, cp_index);1353return true;1354}13551356default: break;1357}1358return false;1359}13601361void ExceptionMessageBuilder::print_NPE_failed_action(outputStream *os, int bci) {13621363// Get the bytecode.1364address code_base = _method->constMethod()->code_base();1365Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);1366int pos = bci + 1;1367if (code == Bytecodes::_wide) {1368code = Bytecodes::java_code_at(_method, code_base + bci + 1);1369pos += 1;1370}13711372switch (code) {1373case Bytecodes::_iaload:1374os->print("Cannot load from int array"); break;1375case Bytecodes::_faload:1376os->print("Cannot load from float array"); break;1377case Bytecodes::_aaload:1378os->print("Cannot load from object array"); break;1379case Bytecodes::_baload:1380os->print("Cannot load from byte/boolean array"); break;1381case Bytecodes::_caload:1382os->print("Cannot load from char array"); break;1383case Bytecodes::_saload:1384os->print("Cannot load from short array"); break;1385case Bytecodes::_laload:1386os->print("Cannot load from long array"); break;1387case Bytecodes::_daload:1388os->print("Cannot load from double array"); break;13891390case Bytecodes::_iastore:1391os->print("Cannot store to int array"); break;1392case Bytecodes::_fastore:1393os->print("Cannot store to float array"); break;1394case Bytecodes::_aastore:1395os->print("Cannot store to object array"); break;1396case Bytecodes::_bastore:1397os->print("Cannot store to byte/boolean array"); break;1398case Bytecodes::_castore:1399os->print("Cannot store to char array"); break;1400case Bytecodes::_sastore:1401os->print("Cannot store to short array"); break;1402case Bytecodes::_lastore:1403os->print("Cannot store to long array"); break;1404case Bytecodes::_dastore:1405os->print("Cannot store to double array"); break;14061407case Bytecodes::_arraylength:1408os->print("Cannot read the array length"); break;1409case Bytecodes::_athrow:1410os->print("Cannot throw exception"); break;1411case Bytecodes::_monitorenter:1412os->print("Cannot enter synchronized block"); break;1413case Bytecodes::_monitorexit:1414os->print("Cannot exit synchronized block"); break;1415case Bytecodes::_getfield: {1416int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1417ConstantPool* cp = _method->constants();1418int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1419int name_index = cp->name_ref_index_at(name_and_type_index);1420Symbol* name = cp->symbol_at(name_index);1421os->print("Cannot read field \"%s\"", name->as_C_string());1422} break;1423case Bytecodes::_putfield: {1424int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1425os->print("Cannot assign field \"%s\"", get_field_name(_method, cp_index));1426} break;1427case Bytecodes::_invokevirtual:1428case Bytecodes::_invokespecial:1429case Bytecodes::_invokeinterface: {1430int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1431os->print("Cannot invoke \"");1432print_method_name(os, _method, cp_index);1433os->print("\"");1434} break;14351436default:1437assert(0, "We should have checked this bytecode in get_NPE_null_slot().");1438break;1439}1440}14411442// Main API1443bool BytecodeUtils::get_NPE_message_at(outputStream* ss, Method* method, int bci) {14441445NoSafepointVerifier _nsv; // Cannot use this object over a safepoint.14461447// If this NPE was created via reflection, we have no real NPE.1448if (method->method_holder() ==1449vmClasses::reflect_NativeConstructorAccessorImpl_klass()) {1450return false;1451}14521453// Analyse the bytecodes.1454ResourceMark rm;1455ExceptionMessageBuilder emb(method, bci);14561457// The slot of the operand stack that contains the null reference.1458// Also checks for NPE explicitly constructed and returns NPE_EXPLICIT_CONSTRUCTED.1459int slot = emb.get_NPE_null_slot(bci);14601461// Build the message.1462if (slot == NPE_EXPLICIT_CONSTRUCTED) {1463// We don't want to print a message.1464return false;1465} else if (slot == INVALID_BYTECODE_ENCOUNTERED) {1466// We encountered a bytecode that does not dereference a reference.1467DEBUG_ONLY(ss->print("There cannot be a NullPointerException at bci %d of method %s",1468bci, method->external_name()));1469NOT_DEBUG(return false);1470} else {1471// Print string describing which action (bytecode) could not be1472// performed because of the null reference.1473emb.print_NPE_failed_action(ss, bci);1474// Print a description of what is null.1475if (!emb.print_NPE_cause(ss, bci, slot)) {1476// Nothing was printed. End the sentence without the 'because'1477// subordinate sentence.1478}1479}1480return true;1481}148214831484