/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciCPCache.hpp"
#include "ci/ciCallSite.hpp"
#include "ci/ciConstant.hpp"
#include "ci/ciField.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciUtilities.hpp"
// ciExceptionHandlerStream
//
// Walk over some selected set of a methods exception handlers.
// ------------------------------------------------------------------
// ciExceptionHandlerStream::count
//
// How many exception handlers are there in this stream?
//
// Implementation note: Compiler2 needs this functionality, so I had
int count = 0;
_pos = -1;
next();
while (!is_done()) {
count++;
next();
}
return count;
}
int count = 0;
while (!is_done()) {
count++;
next();
}
return count;
}
// ciBytecodeStream
//
// The class is used to iterate over the bytecodes of a method.
// providing accessors for constant pool items.
// ------------------------------------------------------------------
// ciBytecodeStream::next_wide_or_table
//
// Special handling for switch ops
switch (bc) { // Check for special bytecode handling
// Special handling for the wide bytcode
// Get following bytecode; do not return wide
break;
case Bytecodes::_lookupswitch:
_pc++; // Skip wide bytecode
// table_base[0] is default far_dest
// Table has 2 lead elements (default, length), then pairs of u4 values.
// So load table length, and compute address at end of table
break;
case Bytecodes::_tableswitch: {
_pc++; // Skip wide bytecode
// table_base[0] is default far_dest
break;
}
default:
fatal("unhandled bytecode");
}
return bc;
}
// ------------------------------------------------------------------
// ciBytecodeStream::reset_to_bci
}
// ------------------------------------------------------------------
// ciBytecodeStream::force_bci
if (bci < 0) {
reset_to_bci(0);
} else {
next();
}
}
// ------------------------------------------------------------------
// Constant pool access
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ciBytecodeStream::get_klass_index
//
// If this bytecodes references a klass, return the index of the
// referenced klass.
switch(cur_bc()) {
return get_index_u1();
case Bytecodes::_checkcast:
case Bytecodes::_instanceof:
case Bytecodes::_anewarray:
case Bytecodes::_multianewarray:
return get_index_u2();
default:
return 0;
}
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_klass
//
// If this bytecode is a new, newarray, multianewarray, instanceof,
// or checkcast, get the referenced klass.
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_raw_index
//
// If this bytecode is one of the ldc variants, get the index of the
// referenced constant.
// work-alike for Bytecode_loadconstant::raw_index()
switch (cur_bc()) {
return get_index_u1();
return get_index_u2();
default:
return 0;
}
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_pool_index
// Decode any CP cache index into a regular pool index.
// work-alike for Bytecode_loadconstant::pool_index()
if (has_cache_index()) {
}
return index;
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_cache_index
// Return the CP cache index, or -1 if there isn't any.
// work-alike for Bytecode_loadconstant::cache_index()
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_constant
//
// If this bytecode is one of the ldc variants, get the referenced
// constant.
if (has_cache_index()) {
pool_index = -1;
}
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_pool_tag
//
// If this bytecode is one of the ldc variants, get the referenced
// constant.
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_field_index
//
// If this is a field access bytecode, get the constant pool
// index of the referenced field.
return get_index_u2_cpcache();
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_field
//
// If this bytecode is one of get_field, get_static, put_field,
// or put_static, get the referenced field.
return f;
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_declared_field_holder
//
// Get the declared holder of the currently referenced field.
//
// Usage note: the holder() of a ciField class returns the canonical
// holder of the field, rather than the holder declared in the
// bytecodes.
//
// There is no "will_link" result passed back. The user is responsible
// for checking linkability when retrieving the associated field.
bool ignore;
->as_instance_klass();
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_field_holder_index
//
// Get the constant pool index of the declared holder of the field
// referenced by the current bytecode. Used for generating
// deoptimization information.
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_field_signature_index
//
// Get the constant pool index of the signature of the field
// referenced by the current bytecode. Used for generating
// deoptimization information.
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method_index
//
// If this is a method invocation bytecode, get the constant pool
// index of the invoked method.
#ifdef ASSERT
switch (cur_bc()) {
case Bytecodes::_invokeinterface:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
case Bytecodes::_invokedynamic:
break;
default:
}
#endif
if (has_index_u4())
return get_index_u4(); // invokedynamic
return get_index_u2_cpcache();
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method
//
// If this is a method invocation bytecode, get the invoked method.
// Additionally return the declared signature to get more concrete
// type information if required (Cf. invokedynamic and invokehandle).
// Use the MethodType stored in the CP cache to create a signature
// with correct types (in respect to class loaders).
if (has_method_type()) {
ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type);
} else {
(*declared_signature_result) = m->signature();
}
return m;
}
// ------------------------------------------------------------------
// ciBytecodeStream::has_appendix
//
// Returns true if there is an appendix argument stored in the
// constant pool cache at the current bci.
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_appendix
//
// Return the appendix argument stored in the constant pool cache at
// the current bci.
}
// ------------------------------------------------------------------
// ciBytecodeStream::has_method_type
//
// Returns true if there is a MethodType argument stored in the
// constant pool cache at the current bci.
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method_type
//
// Return the MethodType stored in the constant pool cache at
// the current bci.
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_declared_method_holder
//
// Get the declared holder of the currently referenced method.
//
// Usage note: the holder() of a ciMethod class returns the canonical
// holder of the method, rather than the holder declared in the
// bytecodes.
//
// There is no "will_link" result passed back. The user is responsible
// for checking linkability when retrieving the associated method.
bool ignore;
// report as MethodHandle for invokedynamic, which is syntactically classless
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method_holder_index
//
// Get the constant pool index of the declared holder of the method
// referenced by the current bytecode. Used for generating
// deoptimization information.
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_method_signature_index
//
// Get the constant pool index of the signature of the method
// referenced by the current bytecode. Used for generating
// deoptimization information.
const int method_index = get_method_index();
)
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_cpcache
// Get the constant pool.
}
return _cpcache;
}
// ------------------------------------------------------------------
// ciBytecodeStream::get_call_site
// Get the constant pool.
// Get the CallSite from the constant pool cache.
// Create a CallSite object and return it.
}