Path: blob/master/src/hotspot/share/interpreter/bytecodeUtils.cpp
40949 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:1031// The return type of arraylength is wrong in the bytecodes table (T_VOID).1032stack->pop(1);1033stack->push(bci, T_INT);1034break;10351036case Bytecodes::_checkcast:1037break;10381039case Bytecodes::_multianewarray:1040stack->pop(*(uint8_t*) (code_base + pos + 2));1041stack->push(bci, T_OBJECT);1042break;10431044case Bytecodes::_goto:1045stack->pop(-Bytecodes::depth(code));1046dest_bci = bci + (int16_t) Bytes::get_Java_u2(code_base + pos);1047flow_ended = true;1048break;104910501051case Bytecodes::_goto_w:1052stack->pop(-Bytecodes::depth(code));1053dest_bci = bci + (int32_t) Bytes::get_Java_u4(code_base + pos);1054flow_ended = true;1055break;10561057default:1058// Allow at least the bcis which have stack info to work.1059_all_processed = false;1060_added_one = false;1061delete stack;10621063return len;1064}10651066// Put new stack to the next instruction, if we might reach it from1067// this bci.1068if (!flow_ended) {1069if (_stacks->at(bci + len) == NULL) {1070_added_one = true;1071}1072merge(bci + len, stack);1073}10741075// Put the stack to the branch target too.1076if (dest_bci != -1) {1077if (_stacks->at(dest_bci) == NULL) {1078_added_one = true;1079}1080merge(dest_bci, stack);1081}10821083// If we have more than one branch target, process these too.1084for (int64_t i = 0; i < dests.length(); ++i) {1085if (_stacks->at(dests.at(i)) == NULL) {1086_added_one = true;1087}1088merge(dests.at(i), stack);1089}10901091delete stack;10921093return len;1094}10951096#define INVALID_BYTECODE_ENCOUNTERED -11097#define NPE_EXPLICIT_CONSTRUCTED -21098int ExceptionMessageBuilder::get_NPE_null_slot(int bci) {1099// Get the bytecode.1100address code_base = _method->constMethod()->code_base();1101Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);1102int pos = bci + 1; // Position of argument of the bytecode.1103if (code == Bytecodes::_wide) {1104code = Bytecodes::java_code_at(_method, code_base + bci + 1);1105pos += 1;1106}11071108switch (code) {1109case Bytecodes::_getfield:1110case Bytecodes::_arraylength:1111case Bytecodes::_athrow:1112case Bytecodes::_monitorenter:1113case Bytecodes::_monitorexit:1114return 0;1115case Bytecodes::_iaload:1116case Bytecodes::_faload:1117case Bytecodes::_aaload:1118case Bytecodes::_baload:1119case Bytecodes::_caload:1120case Bytecodes::_saload:1121case Bytecodes::_laload:1122case Bytecodes::_daload:1123return 1;1124case Bytecodes::_iastore:1125case Bytecodes::_fastore:1126case Bytecodes::_aastore:1127case Bytecodes::_bastore:1128case Bytecodes::_castore:1129case Bytecodes::_sastore:1130return 2;1131case Bytecodes::_lastore:1132case Bytecodes::_dastore:1133return 3;1134case Bytecodes::_putfield: {1135int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1136ConstantPool* cp = _method->constants();1137int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1138int type_index = cp->signature_ref_index_at(name_and_type_index);1139Symbol* signature = cp->symbol_at(type_index);1140BasicType bt = Signature::basic_type(signature);1141return type2size[bt];1142}1143case Bytecodes::_invokevirtual:1144case Bytecodes::_invokespecial:1145case Bytecodes::_invokeinterface: {1146int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1147ConstantPool* cp = _method->constants();1148int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1149int name_index = cp->name_ref_index_at(name_and_type_index);1150Symbol* name = cp->symbol_at(name_index);11511152// Assume the the call of a constructor can never cause a NullPointerException1153// (which is true in Java). This is mainly used to avoid generating wrong1154// messages for NullPointerExceptions created explicitly by new in Java code.1155if (name != vmSymbols::object_initializer_name()) {1156int type_index = cp->signature_ref_index_at(name_and_type_index);1157Symbol* signature = cp->symbol_at(type_index);1158// The 'this' parameter was null. Return the slot of it.1159return ArgumentSizeComputer(signature).size();1160} else {1161return NPE_EXPLICIT_CONSTRUCTED;1162}1163}11641165default:1166break;1167}11681169return INVALID_BYTECODE_ENCOUNTERED;1170}11711172bool ExceptionMessageBuilder::print_NPE_cause(outputStream* os, int bci, int slot) {1173if (print_NPE_cause0(os, bci, slot, _max_cause_detail, false, " because \"")) {1174os->print("\" is null");1175return true;1176}1177return false;1178}11791180// Recursively print what was null.1181//1182// Go to the bytecode that pushed slot 'slot' on the operand stack1183// at bytecode 'bci'. Compute a message for that bytecode. If1184// necessary (array, field), recur further.1185// At most do max_detail recursions.1186// Prefix is used to print a proper beginning of the whole1187// sentence.1188// inner_expr is used to omit some text, like 'static' in1189// inner expressions like array subscripts.1190//1191// Returns true if something was printed.1192//1193bool ExceptionMessageBuilder::print_NPE_cause0(outputStream* os, int bci, int slot,1194int max_detail,1195bool inner_expr, const char *prefix) {1196assert(bci >= 0, "BCI too low");1197assert(bci < get_size(), "BCI too large");11981199if (max_detail <= 0) {1200return false;1201}12021203if (_stacks->at(bci) == NULL) {1204return false;1205}12061207SimulatedOperandStack* stack = _stacks->at(bci);1208assert(slot >= 0, "Slot nr. too low");1209assert(slot < stack->get_size(), "Slot nr. too large");12101211StackSlotAnalysisData slotData = stack->get_slot_data(slot);12121213if (!slotData.has_bci()) {1214return false;1215}12161217// Get the bytecode.1218unsigned int source_bci = slotData.get_bci();1219address code_base = _method->constMethod()->code_base();1220Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + source_bci);1221bool is_wide = false;1222int pos = source_bci + 1;12231224if (code == Bytecodes::_wide) {1225is_wide = true;1226code = Bytecodes::java_code_at(_method, code_base + source_bci + 1);1227pos += 1;1228}12291230if (max_detail == _max_cause_detail &&1231prefix != NULL &&1232code != Bytecodes::_invokevirtual &&1233code != Bytecodes::_invokespecial &&1234code != Bytecodes::_invokestatic &&1235code != Bytecodes::_invokeinterface) {1236os->print("%s", prefix);1237}12381239switch (code) {1240case Bytecodes::_iload_0:1241case Bytecodes::_aload_0:1242print_local_var(os, source_bci, _method, 0, !stack->local_slot_was_written(0));1243return true;12441245case Bytecodes::_iload_1:1246case Bytecodes::_aload_1:1247print_local_var(os, source_bci, _method, 1, !stack->local_slot_was_written(1));1248return true;12491250case Bytecodes::_iload_2:1251case Bytecodes::_aload_2:1252print_local_var(os, source_bci, _method, 2, !stack->local_slot_was_written(2));1253return true;12541255case Bytecodes::_iload_3:1256case Bytecodes::_aload_3:1257print_local_var(os, source_bci, _method, 3, !stack->local_slot_was_written(3));1258return true;12591260case Bytecodes::_iload:1261case Bytecodes::_aload: {1262int index;1263if (is_wide) {1264index = Bytes::get_Java_u2(code_base + source_bci + 2);1265} else {1266index = *(uint8_t*) (code_base + source_bci + 1);1267}1268print_local_var(os, source_bci, _method, index, !stack->local_slot_was_written(index));1269return true;1270}12711272case Bytecodes::_aconst_null:1273os->print("null");1274return true;1275case Bytecodes::_iconst_m1:1276os->print("-1");1277return true;1278case Bytecodes::_iconst_0:1279os->print("0");1280return true;1281case Bytecodes::_iconst_1:1282os->print("1");1283return true;1284case Bytecodes::_iconst_2:1285os->print("2");1286return true;1287case Bytecodes::_iconst_3:1288os->print("3");1289return true;1290case Bytecodes::_iconst_4:1291os->print("4");1292return true;1293case Bytecodes::_iconst_5:1294os->print("5");1295return true;1296case Bytecodes::_bipush: {1297jbyte con = *(jbyte*) (code_base + source_bci + 1);1298os->print("%d", con);1299return true;1300}1301case Bytecodes::_sipush: {1302u2 con = Bytes::get_Java_u2(code_base + source_bci + 1);1303os->print("%d", con);1304return true;1305}1306case Bytecodes::_iaload:1307case Bytecodes::_aaload: {1308// Print the 'name' of the array. Go back to the bytecode that1309// pushed the array reference on the operand stack.1310if (!print_NPE_cause0(os, source_bci, 1, max_detail - 1, inner_expr)) {1311// Returned false. Max recursion depth was reached. Print dummy.1312os->print("<array>");1313}1314os->print("[");1315// Print the index expression. Go back to the bytecode that1316// pushed the index on the operand stack.1317// inner_expr == true so we don't print unwanted strings1318// as "The return value of'". And don't decrement max_detail so we always1319// get a value here and only cancel out on the dereference.1320if (!print_NPE_cause0(os, source_bci, 0, max_detail, true)) {1321// Returned false. We don't print complex array index expressions. Print placeholder.1322os->print("...");1323}1324os->print("]");1325return true;1326}13271328case Bytecodes::_getstatic: {1329int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG;1330print_field_and_class(os, _method, cp_index);1331return true;1332}13331334case Bytecodes::_getfield: {1335// Print the sender. Go back to the bytecode that1336// pushed the sender on the operand stack.1337if (print_NPE_cause0(os, source_bci, 0, max_detail - 1, inner_expr)) {1338os->print(".");1339}1340int cp_index = Bytes::get_native_u2(code_base + pos) + ConstantPool::CPCACHE_INDEX_TAG;1341os->print("%s", get_field_name(_method, cp_index));1342return true;1343}13441345case Bytecodes::_invokevirtual:1346case Bytecodes::_invokespecial:1347case Bytecodes::_invokestatic:1348case Bytecodes::_invokeinterface: {1349int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1350if (max_detail == _max_cause_detail && !inner_expr) {1351os->print(" because the return value of \"");1352}1353print_method_name(os, _method, cp_index);1354return true;1355}13561357default: break;1358}1359return false;1360}13611362void ExceptionMessageBuilder::print_NPE_failed_action(outputStream *os, int bci) {13631364// Get the bytecode.1365address code_base = _method->constMethod()->code_base();1366Bytecodes::Code code = Bytecodes::java_code_at(_method, code_base + bci);1367int pos = bci + 1;1368if (code == Bytecodes::_wide) {1369code = Bytecodes::java_code_at(_method, code_base + bci + 1);1370pos += 1;1371}13721373switch (code) {1374case Bytecodes::_iaload:1375os->print("Cannot load from int array"); break;1376case Bytecodes::_faload:1377os->print("Cannot load from float array"); break;1378case Bytecodes::_aaload:1379os->print("Cannot load from object array"); break;1380case Bytecodes::_baload:1381os->print("Cannot load from byte/boolean array"); break;1382case Bytecodes::_caload:1383os->print("Cannot load from char array"); break;1384case Bytecodes::_saload:1385os->print("Cannot load from short array"); break;1386case Bytecodes::_laload:1387os->print("Cannot load from long array"); break;1388case Bytecodes::_daload:1389os->print("Cannot load from double array"); break;13901391case Bytecodes::_iastore:1392os->print("Cannot store to int array"); break;1393case Bytecodes::_fastore:1394os->print("Cannot store to float array"); break;1395case Bytecodes::_aastore:1396os->print("Cannot store to object array"); break;1397case Bytecodes::_bastore:1398os->print("Cannot store to byte/boolean array"); break;1399case Bytecodes::_castore:1400os->print("Cannot store to char array"); break;1401case Bytecodes::_sastore:1402os->print("Cannot store to short array"); break;1403case Bytecodes::_lastore:1404os->print("Cannot store to long array"); break;1405case Bytecodes::_dastore:1406os->print("Cannot store to double array"); break;14071408case Bytecodes::_arraylength:1409os->print("Cannot read the array length"); break;1410case Bytecodes::_athrow:1411os->print("Cannot throw exception"); break;1412case Bytecodes::_monitorenter:1413os->print("Cannot enter synchronized block"); break;1414case Bytecodes::_monitorexit:1415os->print("Cannot exit synchronized block"); break;1416case Bytecodes::_getfield: {1417int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1418ConstantPool* cp = _method->constants();1419int name_and_type_index = cp->name_and_type_ref_index_at(cp_index);1420int name_index = cp->name_ref_index_at(name_and_type_index);1421Symbol* name = cp->symbol_at(name_index);1422os->print("Cannot read field \"%s\"", name->as_C_string());1423} break;1424case Bytecodes::_putfield: {1425int cp_index = Bytes::get_native_u2(code_base + pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1426os->print("Cannot assign field \"%s\"", get_field_name(_method, cp_index));1427} break;1428case Bytecodes::_invokevirtual:1429case Bytecodes::_invokespecial:1430case Bytecodes::_invokeinterface: {1431int cp_index = Bytes::get_native_u2(code_base+ pos) DEBUG_ONLY(+ ConstantPool::CPCACHE_INDEX_TAG);1432os->print("Cannot invoke \"");1433print_method_name(os, _method, cp_index);1434os->print("\"");1435} break;14361437default:1438assert(0, "We should have checked this bytecode in get_NPE_null_slot().");1439break;1440}1441}14421443// Main API1444bool BytecodeUtils::get_NPE_message_at(outputStream* ss, Method* method, int bci) {14451446NoSafepointVerifier _nsv; // Cannot use this object over a safepoint.14471448// If this NPE was created via reflection, we have no real NPE.1449if (method->method_holder() ==1450vmClasses::reflect_NativeConstructorAccessorImpl_klass()) {1451return false;1452}14531454// Analyse the bytecodes.1455ResourceMark rm;1456ExceptionMessageBuilder emb(method, bci);14571458// The slot of the operand stack that contains the null reference.1459// Also checks for NPE explicitly constructed and returns NPE_EXPLICIT_CONSTRUCTED.1460int slot = emb.get_NPE_null_slot(bci);14611462// Build the message.1463if (slot == NPE_EXPLICIT_CONSTRUCTED) {1464// We don't want to print a message.1465return false;1466} else if (slot == INVALID_BYTECODE_ENCOUNTERED) {1467// We encountered a bytecode that does not dereference a reference.1468DEBUG_ONLY(ss->print("There cannot be a NullPointerException at bci %d of method %s",1469bci, method->external_name()));1470NOT_DEBUG(return false);1471} else {1472// Print string describing which action (bytecode) could not be1473// performed because of the null reference.1474emb.print_NPE_failed_action(ss, bci);1475// Print a description of what is null.1476if (!emb.print_NPE_cause(ss, bci, slot)) {1477// Nothing was printed. End the sentence without the 'because'1478// subordinate sentence.1479}1480}1481return true;1482}148314841485