/*
* 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 "c1/c1_Instruction.hpp"
#include "c1/c1_InstructionPrinter.hpp"
#include "c1/c1_ValueStack.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciTypeArrayKlass.hpp"
// Implementation of Instruction
switch (cond) {
}
return eql;
}
switch (cond) {
}
return eql;
}
if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) {
assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind");
} else {
}
}
Instruction* p = NULL;
Instruction* q = block;
while (q != this) {
p = q; q = q->next();
}
return p;
}
if (state_before() != NULL) {
state_before()->values_do(f);
}
if (exception_state() != NULL){
exception_state()->values_do(f);
}
}
#ifndef PRODUCT
}
}
}
ip.print_line(this);
}
ip.print_head();
ip.print_line(this);
}
#endif // PRODUCT
// perform constant and interval tests on index value
return false;
}
}
return true;
}
// for primitive arrays, the declared type is the exact type
if (type->is_type_array_klass()) {
return type;
} else if (type->is_instance_klass()) {
return type;
}
} else if (type->is_obj_array_klass()) {
if (base->is_instance_klass()) {
return type;
}
} else if (base->is_primitive_type()) {
return type;
}
}
return NULL;
}
}
return NULL;
}
if (array_type == NULL) {
return NULL;
}
return ik;
}
}
return NULL;
}
if (array_type == NULL) {
return NULL;
}
return ak->element_type();
}
}
// for primitive arrays, the declared type is the exact type
if (type->is_type_array_klass()) {
return type;
}
if (type->is_instance_klass()) {
return type;
}
}
return NULL;
}
}
}
return exact_type();
}
return klass();
}
return exact_type();
}
return klass();
}
if (klass()->is_instance_klass()) {
return ik;
}
}
return NULL;
}
// Implementation of ArithmeticOp
switch (op()) {
}
return false;
}
switch (op()) {
}
return false;
}
// Implementation of LogicOp
#ifdef ASSERT
switch (op()) {
default : ShouldNotReachHere();
}
#endif
// all LogicOps are commutative
return true;
}
// Implementation of IfOp
}
// Implementation of StateSplit
NOT_PRODUCT(bool assigned = false;)
if (*b == old_block) {
*b = new_block;
NOT_PRODUCT(assigned = true;)
}
}
}
}
}
for (int i = 0; i < number_of_exception_states(); i++) {
exception_state_at(i)->values_do(f);
}
}
}
// Implementation of Invoke
{
#ifdef ASSERT
#endif
// provide an initial guess of signature size.
if (has_receiver()) {
}
for (int i = 0; i < number_of_arguments(); i++) {
}
}
}
return t;
}
// Implementation of Contant
if (state_before() == NULL) {
case intTag:
case longTag:
{
}
case floatTag:
case doubleTag:
{
}
case objectTag:
}
}
return 0;
}
if (v->as_Constant() == NULL) return false;
case intTag:
{
}
case longTag:
{
}
case floatTag:
{
}
case doubleTag:
{
}
case objectTag:
{
}
}
return false;
}
// other is not a constant
// different types
case intTag: {
switch (cond) {
}
break;
}
case longTag: {
switch (cond) {
}
break;
}
case objectTag: {
switch (cond) {
}
}
break;
}
}
return not_comparable;
}
// Implementation of BlockBegin
return;
}
clear_end();
// Set the new end
_successors.clear();
// Now reset successors list based on BlockEnd
for (int i = 0; i < end->number_of_sux(); i++) {
}
}
// Must make the predecessors/successors match up with the
// BlockEnd's notion.
// disconnect from the old end
// disconnect this block from it's current successors
for (int i = 0; i < _successors.length(); i++) {
}
}
}
// disconnect any edges between from and to
#ifndef PRODUCT
}
#endif
for (int s = 0; s < from->number_of_sux();) {
if (index >= 0) {
}
} else {
s++;
}
}
}
// disconnect this block from all other blocks
for (int p = 0; p < number_of_preds(); p++) {
pred_at(p)->remove_successor(this);
}
for (int s = 0; s < number_of_sux(); s++) {
sux_at(s)->remove_predecessor(this);
}
}
// modify predecessors before substituting successors
for (int i = 0; i < number_of_sux(); i++) {
// remove old predecessor before adding new predecessor
// otherwise there is a dead predecessor in the list
new_sux->add_predecessor(this);
}
}
old_sux->remove_predecessor(this);
}
// In general it is not possible to calculate a value for the field "depth_first_number"
// of the inserted block, without recomputing the values of the other blocks
// in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless.
// mark this block (special treatment when block order is computed)
// This goto is not a safepoint.
// setup states
// link predecessor to new block
// The ordering needs to be the same, so remove the link that the
// set_end call above added and substitute the new_sux for this
// block.
// the successor could be the target of a switch so it might have
// multiple copies of this predecessor, so substitute the new_sux
// for the first and delete the rest.
bool assigned = false;
if (*b == this) {
if (assigned) {
// reprocess this index
i--;
} else {
assigned = true;
*b = new_sux;
}
// link the new block back to it's predecessors.
new_sux->add_predecessor(this);
}
}
return new_sux;
}
int idx;
}
}
}
int idx;
}
}
// add only if not in the list already
}
if (_exception_states == NULL) {
}
}
{ for (int i = number_of_exception_handlers() - 1; i >= 0; i--) exception_handler_at(i)->iterate_preorder(mark, closure); }
{ for (int i = e->number_of_sux () - 1; i >= 0; i--) e->sux_at (i)->iterate_preorder(mark, closure); }
}
}
{ for (int i = number_of_exception_handlers() - 1; i >= 0; i--) exception_handler_at(i)->iterate_postorder(mark, closure); }
{ for (int i = e->number_of_sux () - 1; i >= 0; i--) e->sux_at (i)->iterate_postorder(mark, closure); }
}
}
}
}
}
#ifndef PRODUCT
#else
#endif
// local variables used for state iteration
int index;
if (existing_state == NULL) {
return false; // BAILOUT in caller
}
// copy state because it is altered
// Use method liveness to invalidate dead locals
}
}
}
TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", new_state->stack_at(index)->type()->tchar(), new_state->stack_at(index)->id(), index));
}
bool requires_phi = requires_phi_function.at(index) || (new_value->type()->is_double_word() && requires_phi_function.at(index + 1));
if (requires_phi || !SelectivePhiFunctions) {
TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", new_state->local_at(index)->type()->tchar(), new_state->local_at(index)->id(), index));
}
}
}
// initialize state of block
return false; // BAILOUT in caller
}
// The old code invalidated the phi function here
// Because dead locals are replaced with NULL, this is a very rare case now, so simply bail out
return false; // BAILOUT in caller
}
}
#ifdef ASSERT
// check that all necessary phi functions are present
assert(existing_value->as_Phi() != NULL && existing_value->as_Phi()->block() == this, "phi function required");
}
assert(existing_value == new_state->local_at(index) || (existing_value->as_Phi() != NULL && existing_value->as_Phi()->as_Phi()->block() == this), "phi function required");
}
#endif
} else {
// create necessary phi functions for stack
TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", existing_state->stack_at(index)->type()->tchar(), existing_state->stack_at(index)->id(), index));
}
}
// create necessary phi functions for locals
} else if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) {
TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", existing_state->local_at(index)->type()->tchar(), existing_state->local_at(index)->id(), index));
}
}
}
} else {
assert(false, "stack or locks not matching (invalid bytecodes)");
return false;
}
return true;
}
#ifndef PRODUCT
print_block(ip, false);
}
ip.print_inline_level(this);
ip.print_head();
ip.print_line(n);
}
}
}
#endif // PRODUCT
// Implementation of BlockList
const int l = length();
}
}
}
}
#ifndef PRODUCT
for (int i = 0; i < length(); i++) {
if (cfg_only) {
} else {
}
}
}
#endif // PRODUCT
// Implementation of BlockEnd
// copy our sux list
for (int i = 0; i < _begin->number_of_sux(); i++) {
}
}
}
}
// Implementation of Phi
// Normal phi functions take their operands from the last instruction of the
// predecessor. Special handling is needed for xhanlder entries because there
// the state of arbitrary instructions are needed.
} else {
}
if (is_local()) {
} else {
}
}
return _block->number_of_exception_states();
} else {
return _block->number_of_preds();
}
}
}