mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
Merge
This commit is contained in:
commit
3f77a1ee13
34 changed files with 433 additions and 514 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -319,24 +319,24 @@ void BlockListBuilder::set_leaders() {
|
||||||
|
|
||||||
case Bytecodes::_tableswitch: {
|
case Bytecodes::_tableswitch: {
|
||||||
// set block for each case
|
// set block for each case
|
||||||
Bytecode_tableswitch *switch_ = Bytecode_tableswitch_at(s.cur_bcp());
|
Bytecode_tableswitch sw(&s);
|
||||||
int l = switch_->length();
|
int l = sw.length();
|
||||||
for (int i = 0; i < l; i++) {
|
for (int i = 0; i < l; i++) {
|
||||||
make_block_at(cur_bci + switch_->dest_offset_at(i), current);
|
make_block_at(cur_bci + sw.dest_offset_at(i), current);
|
||||||
}
|
}
|
||||||
make_block_at(cur_bci + switch_->default_offset(), current);
|
make_block_at(cur_bci + sw.default_offset(), current);
|
||||||
current = NULL;
|
current = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Bytecodes::_lookupswitch: {
|
case Bytecodes::_lookupswitch: {
|
||||||
// set block for each case
|
// set block for each case
|
||||||
Bytecode_lookupswitch *switch_ = Bytecode_lookupswitch_at(s.cur_bcp());
|
Bytecode_lookupswitch sw(&s);
|
||||||
int l = switch_->number_of_pairs();
|
int l = sw.number_of_pairs();
|
||||||
for (int i = 0; i < l; i++) {
|
for (int i = 0; i < l; i++) {
|
||||||
make_block_at(cur_bci + switch_->pair_at(i)->offset(), current);
|
make_block_at(cur_bci + sw.pair_at(i).offset(), current);
|
||||||
}
|
}
|
||||||
make_block_at(cur_bci + switch_->default_offset(), current);
|
make_block_at(cur_bci + sw.default_offset(), current);
|
||||||
current = NULL;
|
current = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1275,15 +1275,15 @@ void GraphBuilder::ret(int local_index) {
|
||||||
|
|
||||||
|
|
||||||
void GraphBuilder::table_switch() {
|
void GraphBuilder::table_switch() {
|
||||||
Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(method()->code() + bci());
|
Bytecode_tableswitch sw(stream());
|
||||||
const int l = switch_->length();
|
const int l = sw.length();
|
||||||
if (CanonicalizeNodes && l == 1) {
|
if (CanonicalizeNodes && l == 1) {
|
||||||
// total of 2 successors => use If instead of switch
|
// total of 2 successors => use If instead of switch
|
||||||
// Note: This code should go into the canonicalizer as soon as it can
|
// Note: This code should go into the canonicalizer as soon as it can
|
||||||
// can handle canonicalized forms that contain more than one node.
|
// can handle canonicalized forms that contain more than one node.
|
||||||
Value key = append(new Constant(new IntConstant(switch_->low_key())));
|
Value key = append(new Constant(new IntConstant(sw.low_key())));
|
||||||
BlockBegin* tsux = block_at(bci() + switch_->dest_offset_at(0));
|
BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0));
|
||||||
BlockBegin* fsux = block_at(bci() + switch_->default_offset());
|
BlockBegin* fsux = block_at(bci() + sw.default_offset());
|
||||||
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
|
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
|
||||||
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
|
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
|
||||||
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
|
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
|
||||||
|
@ -1293,29 +1293,29 @@ void GraphBuilder::table_switch() {
|
||||||
int i;
|
int i;
|
||||||
bool has_bb = false;
|
bool has_bb = false;
|
||||||
for (i = 0; i < l; i++) {
|
for (i = 0; i < l; i++) {
|
||||||
sux->at_put(i, block_at(bci() + switch_->dest_offset_at(i)));
|
sux->at_put(i, block_at(bci() + sw.dest_offset_at(i)));
|
||||||
if (switch_->dest_offset_at(i) < 0) has_bb = true;
|
if (sw.dest_offset_at(i) < 0) has_bb = true;
|
||||||
}
|
}
|
||||||
// add default successor
|
// add default successor
|
||||||
sux->at_put(i, block_at(bci() + switch_->default_offset()));
|
sux->at_put(i, block_at(bci() + sw.default_offset()));
|
||||||
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
||||||
append(new TableSwitch(ipop(), sux, switch_->low_key(), state_before, has_bb));
|
append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GraphBuilder::lookup_switch() {
|
void GraphBuilder::lookup_switch() {
|
||||||
Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(method()->code() + bci());
|
Bytecode_lookupswitch sw(stream());
|
||||||
const int l = switch_->number_of_pairs();
|
const int l = sw.number_of_pairs();
|
||||||
if (CanonicalizeNodes && l == 1) {
|
if (CanonicalizeNodes && l == 1) {
|
||||||
// total of 2 successors => use If instead of switch
|
// total of 2 successors => use If instead of switch
|
||||||
// Note: This code should go into the canonicalizer as soon as it can
|
// Note: This code should go into the canonicalizer as soon as it can
|
||||||
// can handle canonicalized forms that contain more than one node.
|
// can handle canonicalized forms that contain more than one node.
|
||||||
// simplify to If
|
// simplify to If
|
||||||
LookupswitchPair* pair = switch_->pair_at(0);
|
LookupswitchPair pair = sw.pair_at(0);
|
||||||
Value key = append(new Constant(new IntConstant(pair->match())));
|
Value key = append(new Constant(new IntConstant(pair.match())));
|
||||||
BlockBegin* tsux = block_at(bci() + pair->offset());
|
BlockBegin* tsux = block_at(bci() + pair.offset());
|
||||||
BlockBegin* fsux = block_at(bci() + switch_->default_offset());
|
BlockBegin* fsux = block_at(bci() + sw.default_offset());
|
||||||
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
|
bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
|
||||||
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
|
ValueStack* state_before = is_bb ? copy_state_before() : NULL;
|
||||||
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
|
append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
|
||||||
|
@ -1326,13 +1326,13 @@ void GraphBuilder::lookup_switch() {
|
||||||
int i;
|
int i;
|
||||||
bool has_bb = false;
|
bool has_bb = false;
|
||||||
for (i = 0; i < l; i++) {
|
for (i = 0; i < l; i++) {
|
||||||
LookupswitchPair* pair = switch_->pair_at(i);
|
LookupswitchPair pair = sw.pair_at(i);
|
||||||
if (pair->offset() < 0) has_bb = true;
|
if (pair.offset() < 0) has_bb = true;
|
||||||
sux->at_put(i, block_at(bci() + pair->offset()));
|
sux->at_put(i, block_at(bci() + pair.offset()));
|
||||||
keys->at_put(i, pair->match());
|
keys->at_put(i, pair.match());
|
||||||
}
|
}
|
||||||
// add default successor
|
// add default successor
|
||||||
sux->at_put(i, block_at(bci() + switch_->default_offset()));
|
sux->at_put(i, block_at(bci() + sw.default_offset()));
|
||||||
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
||||||
append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
|
append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -369,7 +369,7 @@ static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, meth
|
||||||
if (branch_bci != InvocationEntryBci) {
|
if (branch_bci != InvocationEntryBci) {
|
||||||
// Compute desination bci
|
// Compute desination bci
|
||||||
address pc = method()->code_base() + branch_bci;
|
address pc = method()->code_base() + branch_bci;
|
||||||
Bytecodes::Code branch = Bytecodes::code_at(pc, method());
|
Bytecodes::Code branch = Bytecodes::code_at(method(), pc);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
switch (branch) {
|
switch (branch) {
|
||||||
case Bytecodes::_if_icmplt: case Bytecodes::_iflt:
|
case Bytecodes::_if_icmplt: case Bytecodes::_iflt:
|
||||||
|
@ -659,14 +659,14 @@ JRT_END
|
||||||
|
|
||||||
|
|
||||||
static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
|
static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
|
||||||
Bytecode_field* field_access = Bytecode_field_at(caller, bci);
|
Bytecode_field field_access(caller, bci);
|
||||||
// This can be static or non-static field access
|
// This can be static or non-static field access
|
||||||
Bytecodes::Code code = field_access->code();
|
Bytecodes::Code code = field_access.code();
|
||||||
|
|
||||||
// We must load class, initialize class and resolvethe field
|
// We must load class, initialize class and resolvethe field
|
||||||
FieldAccessInfo result; // initialize class if needed
|
FieldAccessInfo result; // initialize class if needed
|
||||||
constantPoolHandle constants(THREAD, caller->constants());
|
constantPoolHandle constants(THREAD, caller->constants());
|
||||||
LinkResolver::resolve_field(result, constants, field_access->index(), Bytecodes::java_code(code), false, CHECK_NULL);
|
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL);
|
||||||
return result.klass()();
|
return result.klass()();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +767,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||||
|
|
||||||
Events::log("patch_code @ " INTPTR_FORMAT , caller_frame.pc());
|
Events::log("patch_code @ " INTPTR_FORMAT , caller_frame.pc());
|
||||||
|
|
||||||
Bytecodes::Code code = Bytecode_at(caller_method->bcp_from(bci))->java_code();
|
Bytecodes::Code code = caller_method()->java_code_at(bci);
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
// this is used by assertions in the access_field_patching_id
|
// this is used by assertions in the access_field_patching_id
|
||||||
|
@ -779,11 +779,11 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||||
Handle load_klass(THREAD, NULL); // oop needed by load_klass_patching code
|
Handle load_klass(THREAD, NULL); // oop needed by load_klass_patching code
|
||||||
if (stub_id == Runtime1::access_field_patching_id) {
|
if (stub_id == Runtime1::access_field_patching_id) {
|
||||||
|
|
||||||
Bytecode_field* field_access = Bytecode_field_at(caller_method, bci);
|
Bytecode_field field_access(caller_method, bci);
|
||||||
FieldAccessInfo result; // initialize class if needed
|
FieldAccessInfo result; // initialize class if needed
|
||||||
Bytecodes::Code code = field_access->code();
|
Bytecodes::Code code = field_access.code();
|
||||||
constantPoolHandle constants(THREAD, caller_method->constants());
|
constantPoolHandle constants(THREAD, caller_method->constants());
|
||||||
LinkResolver::resolve_field(result, constants, field_access->index(), Bytecodes::java_code(code), false, CHECK);
|
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK);
|
||||||
patch_field_offset = result.field_offset();
|
patch_field_offset = result.field_offset();
|
||||||
|
|
||||||
// If we're patching a field which is volatile then at compile it
|
// If we're patching a field which is volatile then at compile it
|
||||||
|
@ -811,36 +811,36 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_new:
|
case Bytecodes::_new:
|
||||||
{ Bytecode_new* bnew = Bytecode_new_at(caller_method->bcp_from(bci));
|
{ Bytecode_new bnew(caller_method(), caller_method->bcp_from(bci));
|
||||||
k = caller_method->constants()->klass_at(bnew->index(), CHECK);
|
k = caller_method->constants()->klass_at(bnew.index(), CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_multianewarray:
|
case Bytecodes::_multianewarray:
|
||||||
{ Bytecode_multianewarray* mna = Bytecode_multianewarray_at(caller_method->bcp_from(bci));
|
{ Bytecode_multianewarray mna(caller_method(), caller_method->bcp_from(bci));
|
||||||
k = caller_method->constants()->klass_at(mna->index(), CHECK);
|
k = caller_method->constants()->klass_at(mna.index(), CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_instanceof:
|
case Bytecodes::_instanceof:
|
||||||
{ Bytecode_instanceof* io = Bytecode_instanceof_at(caller_method->bcp_from(bci));
|
{ Bytecode_instanceof io(caller_method(), caller_method->bcp_from(bci));
|
||||||
k = caller_method->constants()->klass_at(io->index(), CHECK);
|
k = caller_method->constants()->klass_at(io.index(), CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_checkcast:
|
case Bytecodes::_checkcast:
|
||||||
{ Bytecode_checkcast* cc = Bytecode_checkcast_at(caller_method->bcp_from(bci));
|
{ Bytecode_checkcast cc(caller_method(), caller_method->bcp_from(bci));
|
||||||
k = caller_method->constants()->klass_at(cc->index(), CHECK);
|
k = caller_method->constants()->klass_at(cc.index(), CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_anewarray:
|
case Bytecodes::_anewarray:
|
||||||
{ Bytecode_anewarray* anew = Bytecode_anewarray_at(caller_method->bcp_from(bci));
|
{ Bytecode_anewarray anew(caller_method(), caller_method->bcp_from(bci));
|
||||||
klassOop ek = caller_method->constants()->klass_at(anew->index(), CHECK);
|
klassOop ek = caller_method->constants()->klass_at(anew.index(), CHECK);
|
||||||
k = Klass::cast(ek)->array_klass(CHECK);
|
k = Klass::cast(ek)->array_klass(CHECK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_ldc:
|
case Bytecodes::_ldc:
|
||||||
case Bytecodes::_ldc_w:
|
case Bytecodes::_ldc_w:
|
||||||
{
|
{
|
||||||
Bytecode_loadconstant* cc = Bytecode_loadconstant_at(caller_method, bci);
|
Bytecode_loadconstant cc(caller_method, bci);
|
||||||
k = cc->resolve_constant(CHECK);
|
k = cc.resolve_constant(CHECK);
|
||||||
assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant");
|
assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -761,15 +761,15 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl
|
||||||
case Bytecodes::_tableswitch:
|
case Bytecodes::_tableswitch:
|
||||||
{
|
{
|
||||||
state.spop();
|
state.spop();
|
||||||
Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(s.cur_bcp());
|
Bytecode_tableswitch sw(&s);
|
||||||
int len = switch_->length();
|
int len = sw.length();
|
||||||
int dest_bci;
|
int dest_bci;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
dest_bci = s.cur_bci() + switch_->dest_offset_at(i);
|
dest_bci = s.cur_bci() + sw.dest_offset_at(i);
|
||||||
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
||||||
successors.push(_methodBlocks->block_containing(dest_bci));
|
successors.push(_methodBlocks->block_containing(dest_bci));
|
||||||
}
|
}
|
||||||
dest_bci = s.cur_bci() + switch_->default_offset();
|
dest_bci = s.cur_bci() + sw.default_offset();
|
||||||
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
||||||
successors.push(_methodBlocks->block_containing(dest_bci));
|
successors.push(_methodBlocks->block_containing(dest_bci));
|
||||||
assert(s.next_bci() == limit_bci, "branch must end block");
|
assert(s.next_bci() == limit_bci, "branch must end block");
|
||||||
|
@ -779,15 +779,15 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl
|
||||||
case Bytecodes::_lookupswitch:
|
case Bytecodes::_lookupswitch:
|
||||||
{
|
{
|
||||||
state.spop();
|
state.spop();
|
||||||
Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(s.cur_bcp());
|
Bytecode_lookupswitch sw(&s);
|
||||||
int len = switch_->number_of_pairs();
|
int len = sw.number_of_pairs();
|
||||||
int dest_bci;
|
int dest_bci;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
dest_bci = s.cur_bci() + switch_->pair_at(i)->offset();
|
dest_bci = s.cur_bci() + sw.pair_at(i).offset();
|
||||||
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
||||||
successors.push(_methodBlocks->block_containing(dest_bci));
|
successors.push(_methodBlocks->block_containing(dest_bci));
|
||||||
}
|
}
|
||||||
dest_bci = s.cur_bci() + switch_->default_offset();
|
dest_bci = s.cur_bci() + sw.default_offset();
|
||||||
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block");
|
||||||
successors.push(_methodBlocks->block_containing(dest_bci));
|
successors.push(_methodBlocks->block_containing(dest_bci));
|
||||||
fall_through = false;
|
fall_through = false;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -144,7 +144,7 @@ class ciMethod : public ciObject {
|
||||||
|
|
||||||
Bytecodes::Code java_code_at_bci(int bci) {
|
Bytecodes::Code java_code_at_bci(int bci) {
|
||||||
address bcp = code() + bci;
|
address bcp = code() + bci;
|
||||||
return Bytecodes::java_code_at(bcp);
|
return Bytecodes::java_code_at(NULL, bcp);
|
||||||
}
|
}
|
||||||
BCEscapeAnalyzer *get_bcea();
|
BCEscapeAnalyzer *get_bcea();
|
||||||
ciMethodBlocks *get_method_blocks();
|
ciMethodBlocks *get_method_blocks();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -175,15 +175,15 @@ void ciMethodBlocks::do_analysis() {
|
||||||
case Bytecodes::_tableswitch :
|
case Bytecodes::_tableswitch :
|
||||||
{
|
{
|
||||||
cur_block->set_control_bci(bci);
|
cur_block->set_control_bci(bci);
|
||||||
Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(s.cur_bcp());
|
Bytecode_tableswitch sw(&s);
|
||||||
int len = switch_->length();
|
int len = sw.length();
|
||||||
ciBlock *dest;
|
ciBlock *dest;
|
||||||
int dest_bci;
|
int dest_bci;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
dest_bci = s.cur_bci() + switch_->dest_offset_at(i);
|
dest_bci = s.cur_bci() + sw.dest_offset_at(i);
|
||||||
dest = make_block_at(dest_bci);
|
dest = make_block_at(dest_bci);
|
||||||
}
|
}
|
||||||
dest_bci = s.cur_bci() + switch_->default_offset();
|
dest_bci = s.cur_bci() + sw.default_offset();
|
||||||
make_block_at(dest_bci);
|
make_block_at(dest_bci);
|
||||||
if (s.next_bci() < limit_bci) {
|
if (s.next_bci() < limit_bci) {
|
||||||
dest = make_block_at(s.next_bci());
|
dest = make_block_at(s.next_bci());
|
||||||
|
@ -194,15 +194,15 @@ void ciMethodBlocks::do_analysis() {
|
||||||
case Bytecodes::_lookupswitch:
|
case Bytecodes::_lookupswitch:
|
||||||
{
|
{
|
||||||
cur_block->set_control_bci(bci);
|
cur_block->set_control_bci(bci);
|
||||||
Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(s.cur_bcp());
|
Bytecode_lookupswitch sw(&s);
|
||||||
int len = switch_->number_of_pairs();
|
int len = sw.number_of_pairs();
|
||||||
ciBlock *dest;
|
ciBlock *dest;
|
||||||
int dest_bci;
|
int dest_bci;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
dest_bci = s.cur_bci() + switch_->pair_at(i)->offset();
|
dest_bci = s.cur_bci() + sw.pair_at(i).offset();
|
||||||
dest = make_block_at(dest_bci);
|
dest = make_block_at(dest_bci);
|
||||||
}
|
}
|
||||||
dest_bci = s.cur_bci() + switch_->default_offset();
|
dest_bci = s.cur_bci() + sw.default_offset();
|
||||||
dest = make_block_at(dest_bci);
|
dest = make_block_at(dest_bci);
|
||||||
if (s.next_bci() < limit_bci) {
|
if (s.next_bci() < limit_bci) {
|
||||||
dest = make_block_at(s.next_bci());
|
dest = make_block_at(s.next_bci());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -78,8 +78,8 @@ private:
|
||||||
else { assert(!is_wide(), "must not be a wide instruction"); }
|
else { assert(!is_wide(), "must not be a wide instruction"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
Bytecode* bytecode() const { return Bytecode_at(_bc_start); }
|
Bytecode bytecode() const { return Bytecode(this, _bc_start); }
|
||||||
Bytecode* next_bytecode() const { return Bytecode_at(_pc); }
|
Bytecode next_bytecode() const { return Bytecode(this, _pc); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// End-Of-Bytecodes
|
// End-Of-Bytecodes
|
||||||
|
@ -151,11 +151,11 @@ public:
|
||||||
bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
|
bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
|
||||||
|
|
||||||
int get_index_u1() const {
|
int get_index_u1() const {
|
||||||
return bytecode()->get_index_u1(cur_bc_raw());
|
return bytecode().get_index_u1(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_index_u1_cpcache() const {
|
int get_index_u1_cpcache() const {
|
||||||
return bytecode()->get_index_u1_cpcache(cur_bc_raw());
|
return bytecode().get_index_u1_cpcache(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a byte index following this bytecode.
|
// Get a byte index following this bytecode.
|
||||||
|
@ -169,29 +169,29 @@ public:
|
||||||
|
|
||||||
// Get 2-byte index (byte swapping depending on which bytecode)
|
// Get 2-byte index (byte swapping depending on which bytecode)
|
||||||
int get_index_u2(bool is_wide = false) const {
|
int get_index_u2(bool is_wide = false) const {
|
||||||
return bytecode()->get_index_u2(cur_bc_raw(), is_wide);
|
return bytecode().get_index_u2(cur_bc_raw(), is_wide);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 2-byte index in native byte order. (Rewriter::rewrite makes these.)
|
// Get 2-byte index in native byte order. (Rewriter::rewrite makes these.)
|
||||||
int get_index_u2_cpcache() const {
|
int get_index_u2_cpcache() const {
|
||||||
return bytecode()->get_index_u2_cpcache(cur_bc_raw());
|
return bytecode().get_index_u2_cpcache(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 4-byte index, for invokedynamic.
|
// Get 4-byte index, for invokedynamic.
|
||||||
int get_index_u4() const {
|
int get_index_u4() const {
|
||||||
return bytecode()->get_index_u4(cur_bc_raw());
|
return bytecode().get_index_u4(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_index_u4() const {
|
bool has_index_u4() const {
|
||||||
return bytecode()->has_index_u4(cur_bc_raw());
|
return bytecode().has_index_u4(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get dimensions byte (multinewarray)
|
// Get dimensions byte (multinewarray)
|
||||||
int get_dimensions() const { return *(unsigned char*)(_pc-1); }
|
int get_dimensions() const { return *(unsigned char*)(_pc-1); }
|
||||||
|
|
||||||
// Sign-extended index byte/short, no widening
|
// Sign-extended index byte/short, no widening
|
||||||
int get_constant_u1() const { return bytecode()->get_constant_u1(instruction_size()-1, cur_bc_raw()); }
|
int get_constant_u1() const { return bytecode().get_constant_u1(instruction_size()-1, cur_bc_raw()); }
|
||||||
int get_constant_u2(bool is_wide = false) const { return bytecode()->get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); }
|
int get_constant_u2(bool is_wide = false) const { return bytecode().get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); }
|
||||||
|
|
||||||
// Get a byte signed constant for "iinc". Invalid for other bytecodes.
|
// Get a byte signed constant for "iinc". Invalid for other bytecodes.
|
||||||
// If prefixed with a wide bytecode, get a wide constant
|
// If prefixed with a wide bytecode, get a wide constant
|
||||||
|
@ -199,18 +199,18 @@ public:
|
||||||
|
|
||||||
// 2-byte branch offset from current pc
|
// 2-byte branch offset from current pc
|
||||||
int get_dest() const {
|
int get_dest() const {
|
||||||
return cur_bci() + bytecode()->get_offset_s2(cur_bc_raw());
|
return cur_bci() + bytecode().get_offset_s2(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2-byte branch offset from next pc
|
// 2-byte branch offset from next pc
|
||||||
int next_get_dest() const {
|
int next_get_dest() const {
|
||||||
assert(_pc < _end, "");
|
assert(_pc < _end, "");
|
||||||
return next_bci() + next_bytecode()->get_offset_s2(Bytecodes::_ifeq);
|
return next_bci() + next_bytecode().get_offset_s2(Bytecodes::_ifeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4-byte branch offset from current pc
|
// 4-byte branch offset from current pc
|
||||||
int get_far_dest() const {
|
int get_far_dest() const {
|
||||||
return cur_bci() + bytecode()->get_offset_s4(cur_bc_raw());
|
return cur_bci() + bytecode().get_offset_s4(cur_bc_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// For a lookup or switch table, return target destination
|
// For a lookup or switch table, return target destination
|
||||||
|
@ -407,4 +407,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Implementation for declarations in bytecode.hpp
|
||||||
|
Bytecode::Bytecode(const ciBytecodeStream* stream, address bcp): _bcp(bcp != NULL ? bcp : stream->cur_bcp()), _code(Bytecodes::code_at(NULL, addr_at(0))) {}
|
||||||
|
Bytecode_lookupswitch::Bytecode_lookupswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }
|
||||||
|
Bytecode_tableswitch::Bytecode_tableswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }
|
||||||
|
|
||||||
#endif // SHARE_VM_CI_CISTREAMS_HPP
|
#endif // SHARE_VM_CI_CISTREAMS_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1698,18 +1698,17 @@ ciTypeFlow::Block::successors(ciBytecodeStream* str,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Bytecodes::_tableswitch: {
|
case Bytecodes::_tableswitch: {
|
||||||
Bytecode_tableswitch *tableswitch =
|
Bytecode_tableswitch tableswitch(str);
|
||||||
Bytecode_tableswitch_at(str->cur_bcp());
|
|
||||||
|
|
||||||
int len = tableswitch->length();
|
int len = tableswitch.length();
|
||||||
_successors =
|
_successors =
|
||||||
new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL);
|
new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL);
|
||||||
int bci = current_bci + tableswitch->default_offset();
|
int bci = current_bci + tableswitch.default_offset();
|
||||||
Block* block = analyzer->block_at(bci, jsrs);
|
Block* block = analyzer->block_at(bci, jsrs);
|
||||||
assert(_successors->length() == SWITCH_DEFAULT, "");
|
assert(_successors->length() == SWITCH_DEFAULT, "");
|
||||||
_successors->append(block);
|
_successors->append(block);
|
||||||
while (--len >= 0) {
|
while (--len >= 0) {
|
||||||
int bci = current_bci + tableswitch->dest_offset_at(len);
|
int bci = current_bci + tableswitch.dest_offset_at(len);
|
||||||
block = analyzer->block_at(bci, jsrs);
|
block = analyzer->block_at(bci, jsrs);
|
||||||
assert(_successors->length() >= SWITCH_CASES, "");
|
assert(_successors->length() >= SWITCH_CASES, "");
|
||||||
_successors->append_if_missing(block);
|
_successors->append_if_missing(block);
|
||||||
|
@ -1718,19 +1717,18 @@ ciTypeFlow::Block::successors(ciBytecodeStream* str,
|
||||||
}
|
}
|
||||||
|
|
||||||
case Bytecodes::_lookupswitch: {
|
case Bytecodes::_lookupswitch: {
|
||||||
Bytecode_lookupswitch *lookupswitch =
|
Bytecode_lookupswitch lookupswitch(str);
|
||||||
Bytecode_lookupswitch_at(str->cur_bcp());
|
|
||||||
|
|
||||||
int npairs = lookupswitch->number_of_pairs();
|
int npairs = lookupswitch.number_of_pairs();
|
||||||
_successors =
|
_successors =
|
||||||
new (arena) GrowableArray<Block*>(arena, npairs+1, 0, NULL);
|
new (arena) GrowableArray<Block*>(arena, npairs+1, 0, NULL);
|
||||||
int bci = current_bci + lookupswitch->default_offset();
|
int bci = current_bci + lookupswitch.default_offset();
|
||||||
Block* block = analyzer->block_at(bci, jsrs);
|
Block* block = analyzer->block_at(bci, jsrs);
|
||||||
assert(_successors->length() == SWITCH_DEFAULT, "");
|
assert(_successors->length() == SWITCH_DEFAULT, "");
|
||||||
_successors->append(block);
|
_successors->append(block);
|
||||||
while(--npairs >= 0) {
|
while(--npairs >= 0) {
|
||||||
LookupswitchPair *pair = lookupswitch->pair_at(npairs);
|
LookupswitchPair pair = lookupswitch.pair_at(npairs);
|
||||||
int bci = current_bci + pair->offset();
|
int bci = current_bci + pair.offset();
|
||||||
Block* block = analyzer->block_at(bci, jsrs);
|
Block* block = analyzer->block_at(bci, jsrs);
|
||||||
assert(_successors->length() >= SWITCH_CASES, "");
|
assert(_successors->length() >= SWITCH_CASES, "");
|
||||||
_successors->append_if_missing(block);
|
_successors->append_if_missing(block);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1863,9 +1863,9 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
|
||||||
#ifndef SHARK
|
#ifndef SHARK
|
||||||
if (!method()->is_native()) {
|
if (!method()->is_native()) {
|
||||||
SimpleScopeDesc ssd(this, fr.pc());
|
SimpleScopeDesc ssd(this, fr.pc());
|
||||||
Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
|
Bytecode_invoke call(ssd.method(), ssd.bci());
|
||||||
bool has_receiver = call->has_receiver();
|
bool has_receiver = call.has_receiver();
|
||||||
symbolOop signature = call->signature();
|
symbolOop signature = call.signature();
|
||||||
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
|
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
|
||||||
}
|
}
|
||||||
#endif // !SHARK
|
#endif // !SHARK
|
||||||
|
@ -2698,8 +2698,7 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
||||||
} else if (sd->method()->is_native()) {
|
} else if (sd->method()->is_native()) {
|
||||||
st->print("method is native");
|
st->print("method is native");
|
||||||
} else {
|
} else {
|
||||||
address bcp = sd->method()->bcp_from(sd->bci());
|
Bytecodes::Code bc = sd->method()->java_code_at(sd->bci());
|
||||||
Bytecodes::Code bc = Bytecodes::java_code_at(bcp);
|
|
||||||
st->print(";*%s", Bytecodes::name(bc));
|
st->print(";*%s", Bytecodes::name(bc));
|
||||||
switch (bc) {
|
switch (bc) {
|
||||||
case Bytecodes::_invokevirtual:
|
case Bytecodes::_invokevirtual:
|
||||||
|
@ -2707,10 +2706,10 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
||||||
case Bytecodes::_invokestatic:
|
case Bytecodes::_invokestatic:
|
||||||
case Bytecodes::_invokeinterface:
|
case Bytecodes::_invokeinterface:
|
||||||
{
|
{
|
||||||
Bytecode_invoke* invoke = Bytecode_invoke_at(sd->method(), sd->bci());
|
Bytecode_invoke invoke(sd->method(), sd->bci());
|
||||||
st->print(" ");
|
st->print(" ");
|
||||||
if (invoke->name() != NULL)
|
if (invoke.name() != NULL)
|
||||||
invoke->name()->print_symbol_on(st);
|
invoke.name()->print_symbol_on(st);
|
||||||
else
|
else
|
||||||
st->print("<UNKNOWN>");
|
st->print("<UNKNOWN>");
|
||||||
break;
|
break;
|
||||||
|
@ -2720,10 +2719,10 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
|
||||||
case Bytecodes::_getstatic:
|
case Bytecodes::_getstatic:
|
||||||
case Bytecodes::_putstatic:
|
case Bytecodes::_putstatic:
|
||||||
{
|
{
|
||||||
Bytecode_field* field = Bytecode_field_at(sd->method(), sd->bci());
|
Bytecode_field field(sd->method(), sd->bci());
|
||||||
st->print(" ");
|
st->print(" ");
|
||||||
if (field->name() != NULL)
|
if (field.name() != NULL)
|
||||||
field->name()->print_symbol_on(st);
|
field.name()->print_symbol_on(st);
|
||||||
else
|
else
|
||||||
st->print("<UNKNOWN>");
|
st->print("<UNKNOWN>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -286,16 +286,15 @@ void MethodLiveness::init_basic_blocks() {
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_tableswitch:
|
case Bytecodes::_tableswitch:
|
||||||
{
|
{
|
||||||
Bytecode_tableswitch *tableswitch =
|
Bytecode_tableswitch tableswitch(&bytes);
|
||||||
Bytecode_tableswitch_at(bytes.cur_bcp());
|
|
||||||
|
|
||||||
int len = tableswitch->length();
|
int len = tableswitch.length();
|
||||||
|
|
||||||
dest = _block_map->at(bci + tableswitch->default_offset());
|
dest = _block_map->at(bci + tableswitch.default_offset());
|
||||||
assert(dest != NULL, "branch desination must start a block.");
|
assert(dest != NULL, "branch desination must start a block.");
|
||||||
dest->add_normal_predecessor(current_block);
|
dest->add_normal_predecessor(current_block);
|
||||||
while (--len >= 0) {
|
while (--len >= 0) {
|
||||||
dest = _block_map->at(bci + tableswitch->dest_offset_at(len));
|
dest = _block_map->at(bci + tableswitch.dest_offset_at(len));
|
||||||
assert(dest != NULL, "branch desination must start a block.");
|
assert(dest != NULL, "branch desination must start a block.");
|
||||||
dest->add_normal_predecessor(current_block);
|
dest->add_normal_predecessor(current_block);
|
||||||
}
|
}
|
||||||
|
@ -304,17 +303,16 @@ void MethodLiveness::init_basic_blocks() {
|
||||||
|
|
||||||
case Bytecodes::_lookupswitch:
|
case Bytecodes::_lookupswitch:
|
||||||
{
|
{
|
||||||
Bytecode_lookupswitch *lookupswitch =
|
Bytecode_lookupswitch lookupswitch(&bytes);
|
||||||
Bytecode_lookupswitch_at(bytes.cur_bcp());
|
|
||||||
|
|
||||||
int npairs = lookupswitch->number_of_pairs();
|
int npairs = lookupswitch.number_of_pairs();
|
||||||
|
|
||||||
dest = _block_map->at(bci + lookupswitch->default_offset());
|
dest = _block_map->at(bci + lookupswitch.default_offset());
|
||||||
assert(dest != NULL, "branch desination must start a block.");
|
assert(dest != NULL, "branch desination must start a block.");
|
||||||
dest->add_normal_predecessor(current_block);
|
dest->add_normal_predecessor(current_block);
|
||||||
while(--npairs >= 0) {
|
while(--npairs >= 0) {
|
||||||
LookupswitchPair *pair = lookupswitch->pair_at(npairs);
|
LookupswitchPair pair = lookupswitch.pair_at(npairs);
|
||||||
dest = _block_map->at( bci + pair->offset());
|
dest = _block_map->at( bci + pair.offset());
|
||||||
assert(dest != NULL, "branch desination must start a block.");
|
assert(dest != NULL, "branch desination must start a block.");
|
||||||
dest->add_normal_predecessor(current_block);
|
dest->add_normal_predecessor(current_block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -34,30 +34,6 @@
|
||||||
|
|
||||||
// Implementation of Bytecode
|
// Implementation of Bytecode
|
||||||
|
|
||||||
bool Bytecode::check_must_rewrite(Bytecodes::Code code) const {
|
|
||||||
assert(Bytecodes::can_rewrite(code), "post-check only");
|
|
||||||
|
|
||||||
// Some codes are conditionally rewriting. Look closely at them.
|
|
||||||
switch (code) {
|
|
||||||
case Bytecodes::_aload_0:
|
|
||||||
// Even if RewriteFrequentPairs is turned on,
|
|
||||||
// the _aload_0 code might delay its rewrite until
|
|
||||||
// a following _getfield rewrites itself.
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Bytecodes::_lookupswitch:
|
|
||||||
return false; // the rewrite is not done by the interpreter
|
|
||||||
|
|
||||||
case Bytecodes::_new:
|
|
||||||
// (Could actually look at the class here, but the profit would be small.)
|
|
||||||
return false; // the rewrite is not always done
|
|
||||||
}
|
|
||||||
|
|
||||||
// No other special cases.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
|
||||||
void Bytecode::assert_same_format_as(Bytecodes::Code testbc, bool is_wide) const {
|
void Bytecode::assert_same_format_as(Bytecodes::Code testbc, bool is_wide) const {
|
||||||
|
@ -188,17 +164,16 @@ int Bytecode_member_ref::index() const {
|
||||||
// Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
|
// Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
|
||||||
// at the same time it allocates per-call-site CP cache entries.
|
// at the same time it allocates per-call-site CP cache entries.
|
||||||
Bytecodes::Code rawc = code();
|
Bytecodes::Code rawc = code();
|
||||||
Bytecode* invoke = bytecode();
|
if (has_index_u4(rawc))
|
||||||
if (invoke->has_index_u4(rawc))
|
return get_index_u4(rawc);
|
||||||
return invoke->get_index_u4(rawc);
|
|
||||||
else
|
else
|
||||||
return invoke->get_index_u2_cpcache(rawc);
|
return get_index_u2_cpcache(rawc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bytecode_member_ref::pool_index() const {
|
int Bytecode_member_ref::pool_index() const {
|
||||||
int index = this->index();
|
int index = this->index();
|
||||||
DEBUG_ONLY({
|
DEBUG_ONLY({
|
||||||
if (!bytecode()->has_index_u4(code()))
|
if (!has_index_u4(code()))
|
||||||
index -= constantPoolOopDesc::CPCACHE_INDEX_TAG;
|
index -= constantPoolOopDesc::CPCACHE_INDEX_TAG;
|
||||||
});
|
});
|
||||||
return _method->constants()->cache()->entry_at(index)->constant_pool_index();
|
return _method->constants()->cache()->entry_at(index)->constant_pool_index();
|
||||||
|
@ -214,13 +189,12 @@ void Bytecode_field::verify() const {
|
||||||
// Implementation of Bytecode_loadconstant
|
// Implementation of Bytecode_loadconstant
|
||||||
|
|
||||||
int Bytecode_loadconstant::raw_index() const {
|
int Bytecode_loadconstant::raw_index() const {
|
||||||
Bytecode* bcp = bytecode();
|
Bytecodes::Code rawc = code();
|
||||||
Bytecodes::Code rawc = bcp->code();
|
|
||||||
assert(rawc != Bytecodes::_wide, "verifier prevents this");
|
assert(rawc != Bytecodes::_wide, "verifier prevents this");
|
||||||
if (Bytecodes::java_code(rawc) == Bytecodes::_ldc)
|
if (Bytecodes::java_code(rawc) == Bytecodes::_ldc)
|
||||||
return bcp->get_index_u1(rawc);
|
return get_index_u1(rawc);
|
||||||
else
|
else
|
||||||
return bcp->get_index_u2(rawc, false);
|
return get_index_u2(rawc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bytecode_loadconstant::pool_index() const {
|
int Bytecode_loadconstant::pool_index() const {
|
||||||
|
@ -258,7 +232,7 @@ void Bytecode_lookupswitch::verify() const {
|
||||||
case Bytecodes::_lookupswitch:
|
case Bytecodes::_lookupswitch:
|
||||||
{ int i = number_of_pairs() - 1;
|
{ int i = number_of_pairs() - 1;
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
assert(pair_at(i)->match() < pair_at(i+1)->match(), "unsorted table entries");
|
assert(pair_at(i).match() < pair_at(i+1).match(), "unsorted table entries");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,14 +38,20 @@
|
||||||
# include "bytes_zero.hpp"
|
# include "bytes_zero.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Base class for different kinds of abstractions working
|
class ciBytecodeStream;
|
||||||
// relative to an objects 'this' pointer.
|
|
||||||
|
// The base class for different kinds of bytecode abstractions.
|
||||||
|
// Provides the primitive operations to manipulate code relative
|
||||||
|
// to the bcp.
|
||||||
|
|
||||||
|
class Bytecode: public StackObj {
|
||||||
|
protected:
|
||||||
|
const address _bcp;
|
||||||
|
const Bytecodes::Code _code;
|
||||||
|
|
||||||
class ThisRelativeObj VALUE_OBJ_CLASS_SPEC {
|
|
||||||
public:
|
|
||||||
// Address computation
|
// Address computation
|
||||||
address addr_at (int offset) const { return (address)this + offset; }
|
address addr_at (int offset) const { return (address)_bcp + offset; }
|
||||||
int byte_at (int offset) const { return *(addr_at(offset)); }
|
u_char byte_at(int offset) const { return *addr_at(offset); }
|
||||||
address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
|
address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
|
||||||
int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); }
|
int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); }
|
||||||
|
|
||||||
|
@ -54,31 +60,20 @@ class ThisRelativeObj VALUE_OBJ_CLASS_SPEC {
|
||||||
int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); }
|
int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); }
|
||||||
int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); }
|
int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); }
|
||||||
int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); }
|
int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); }
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// The base class for different kinds of bytecode abstractions.
|
|
||||||
// Provides the primitive operations to manipulate code relative
|
|
||||||
// to an objects 'this' pointer.
|
|
||||||
// FIXME: Make this a ResourceObj, include the enclosing methodOop, and cache the opcode.
|
|
||||||
|
|
||||||
class Bytecode: public ThisRelativeObj {
|
|
||||||
protected:
|
|
||||||
u_char byte_at(int offset) const { return *addr_at(offset); }
|
|
||||||
bool check_must_rewrite(Bytecodes::Code bc) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Bytecode(methodOop method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) {
|
||||||
|
assert(method != NULL, "this form requires a valid methodOop");
|
||||||
|
}
|
||||||
|
// Defined in ciStreams.hpp
|
||||||
|
inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL);
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
address bcp() const { return addr_at(0); }
|
address bcp() const { return _bcp; }
|
||||||
int instruction_size() const { return Bytecodes::length_at(bcp()); }
|
int instruction_size() const { return Bytecodes::length_for_code_at(_code, bcp()); }
|
||||||
|
|
||||||
// Warning: Use code() with caution on live bytecode streams. 4926272
|
Bytecodes::Code code() const { return _code; }
|
||||||
Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); }
|
|
||||||
Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); }
|
Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); }
|
||||||
bool must_rewrite(Bytecodes::Code code) const { return Bytecodes::can_rewrite(code) && check_must_rewrite(code); }
|
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode* Bytecode_at(address bcp);
|
|
||||||
|
|
||||||
// Static functions for parsing bytecodes in place.
|
// Static functions for parsing bytecodes in place.
|
||||||
int get_index_u1(Bytecodes::Code bc) const {
|
int get_index_u1(Bytecodes::Code bc) const {
|
||||||
|
@ -89,7 +84,7 @@ class Bytecode: public ThisRelativeObj {
|
||||||
assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide);
|
assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide);
|
||||||
address p = addr_at(is_wide ? 2 : 1);
|
address p = addr_at(is_wide ? 2 : 1);
|
||||||
if (can_use_native_byte_order(bc, is_wide))
|
if (can_use_native_byte_order(bc, is_wide))
|
||||||
return Bytes::get_native_u2(p);
|
return Bytes::get_native_u2(p);
|
||||||
else return Bytes::get_Java_u2(p);
|
else return Bytes::get_Java_u2(p);
|
||||||
}
|
}
|
||||||
int get_index_u1_cpcache(Bytecodes::Code bc) const {
|
int get_index_u1_cpcache(Bytecodes::Code bc) const {
|
||||||
|
@ -138,20 +133,17 @@ class Bytecode: public ThisRelativeObj {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode* Bytecode_at(address bcp) {
|
|
||||||
// Warning: Use with caution on live bytecode streams. 4926272
|
|
||||||
return (Bytecode*)bcp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Abstractions for lookupswitch bytecode
|
// Abstractions for lookupswitch bytecode
|
||||||
|
class LookupswitchPair VALUE_OBJ_CLASS_SPEC {
|
||||||
class LookupswitchPair: ThisRelativeObj {
|
|
||||||
private:
|
private:
|
||||||
int _match;
|
const address _bcp;
|
||||||
int _offset;
|
|
||||||
|
address addr_at (int offset) const { return _bcp + offset; }
|
||||||
|
int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
LookupswitchPair(address bcp): _bcp(bcp) {}
|
||||||
int match() const { return get_Java_u4_at(0 * jintSize); }
|
int match() const { return get_Java_u4_at(0 * jintSize); }
|
||||||
int offset() const { return get_Java_u4_at(1 * jintSize); }
|
int offset() const { return get_Java_u4_at(1 * jintSize); }
|
||||||
};
|
};
|
||||||
|
@ -159,26 +151,25 @@ class LookupswitchPair: ThisRelativeObj {
|
||||||
|
|
||||||
class Bytecode_lookupswitch: public Bytecode {
|
class Bytecode_lookupswitch: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_lookupswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
|
// Defined in ciStreams.hpp
|
||||||
|
inline Bytecode_lookupswitch(const ciBytecodeStream* stream);
|
||||||
void verify() const PRODUCT_RETURN;
|
void verify() const PRODUCT_RETURN;
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
|
int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
|
||||||
int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
|
int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
|
||||||
LookupswitchPair* pair_at(int i) const { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
|
LookupswitchPair pair_at(int i) const {
|
||||||
return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); }
|
assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
|
||||||
// Creation
|
return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize));
|
||||||
inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp);
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
|
|
||||||
Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Bytecode_tableswitch: public Bytecode {
|
class Bytecode_tableswitch: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_tableswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
|
// Defined in ciStreams.hpp
|
||||||
|
inline Bytecode_tableswitch(const ciBytecodeStream* stream);
|
||||||
void verify() const PRODUCT_RETURN;
|
void verify() const PRODUCT_RETURN;
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -187,52 +178,36 @@ class Bytecode_tableswitch: public Bytecode {
|
||||||
int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
|
int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
|
||||||
int dest_offset_at(int i) const;
|
int dest_offset_at(int i) const;
|
||||||
int length() { return high_key()-low_key()+1; }
|
int length() { return high_key()-low_key()+1; }
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
|
|
||||||
Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Common code for decoding invokes and field references.
|
// Common code for decoding invokes and field references.
|
||||||
|
|
||||||
class Bytecode_member_ref: public ResourceObj {
|
class Bytecode_member_ref: public Bytecode {
|
||||||
protected:
|
protected:
|
||||||
methodHandle _method; // method containing the bytecode
|
const methodHandle _method; // method containing the bytecode
|
||||||
int _bci; // position of the bytecode
|
|
||||||
|
|
||||||
Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {}
|
Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
|
||||||
|
|
||||||
|
methodHandle method() const { return _method; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Attributes
|
|
||||||
methodHandle method() const { return _method; }
|
|
||||||
int bci() const { return _bci; }
|
|
||||||
address bcp() const { return _method->bcp_from(bci()); }
|
|
||||||
Bytecode* bytecode() const { return Bytecode_at(bcp()); }
|
|
||||||
|
|
||||||
int index() const; // cache index (loaded from instruction)
|
int index() const; // cache index (loaded from instruction)
|
||||||
int pool_index() const; // constant pool index
|
int pool_index() const; // constant pool index
|
||||||
symbolOop name() const; // returns the name of the method or field
|
symbolOop name() const; // returns the name of the method or field
|
||||||
symbolOop signature() const; // returns the signature of the method or field
|
symbolOop signature() const; // returns the signature of the method or field
|
||||||
|
|
||||||
BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke
|
BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke
|
||||||
|
|
||||||
Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); }
|
|
||||||
Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Abstraction for invoke_{virtual, static, interface, special}
|
// Abstraction for invoke_{virtual, static, interface, special}
|
||||||
|
|
||||||
class Bytecode_invoke: public Bytecode_member_ref {
|
class Bytecode_invoke: public Bytecode_member_ref {
|
||||||
protected:
|
protected:
|
||||||
Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {}
|
// Constructor that skips verification
|
||||||
|
Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
|
||||||
void verify() const;
|
void verify() const;
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -253,31 +228,20 @@ class Bytecode_invoke: public Bytecode_member_ref {
|
||||||
is_invokespecial() ||
|
is_invokespecial() ||
|
||||||
is_invokedynamic(); }
|
is_invokedynamic(); }
|
||||||
|
|
||||||
// Creation
|
// Helper to skip verification. Used is_valid() to check if the result is really an invoke
|
||||||
inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci);
|
inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci);
|
||||||
|
|
||||||
// Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke.
|
|
||||||
inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
|
inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) {
|
||||||
Bytecode_invoke* b = new Bytecode_invoke(method, bci);
|
return Bytecode_invoke(method, bci, false);
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) {
|
|
||||||
Bytecode_invoke* b = new Bytecode_invoke(method, bci);
|
|
||||||
return b->is_valid() ? b : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Abstraction for all field accesses (put/get field/static)
|
// Abstraction for all field accesses (put/get field/static)
|
||||||
class Bytecode_field: public Bytecode_member_ref {
|
class Bytecode_field: public Bytecode_member_ref {
|
||||||
protected:
|
|
||||||
Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
|
||||||
|
|
||||||
// Testers
|
// Testers
|
||||||
bool is_getfield() const { return java_code() == Bytecodes::_getfield; }
|
bool is_getfield() const { return java_code() == Bytecodes::_getfield; }
|
||||||
bool is_putfield() const { return java_code() == Bytecodes::_putfield; }
|
bool is_putfield() const { return java_code() == Bytecodes::_putfield; }
|
||||||
|
@ -292,131 +256,64 @@ class Bytecode_field: public Bytecode_member_ref {
|
||||||
is_getstatic() ||
|
is_getstatic() ||
|
||||||
is_putstatic(); }
|
is_putstatic(); }
|
||||||
void verify() const;
|
void verify() const;
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) {
|
|
||||||
Bytecode_field* b = new Bytecode_field(method, bci);
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Abstraction for checkcast
|
// Abstraction for checkcast
|
||||||
|
|
||||||
class Bytecode_checkcast: public Bytecode {
|
class Bytecode_checkcast: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_checkcast(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
|
void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }
|
||||||
|
|
||||||
// Returns index
|
// Returns index
|
||||||
long index() const { return get_index_u2(Bytecodes::_checkcast); };
|
long index() const { return get_index_u2(Bytecodes::_checkcast); };
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
|
|
||||||
Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Abstraction for instanceof
|
// Abstraction for instanceof
|
||||||
|
|
||||||
class Bytecode_instanceof: public Bytecode {
|
class Bytecode_instanceof: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_instanceof(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
|
void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }
|
||||||
|
|
||||||
// Returns index
|
// Returns index
|
||||||
long index() const { return get_index_u2(Bytecodes::_instanceof); };
|
long index() const { return get_index_u2(Bytecodes::_instanceof); };
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
|
|
||||||
Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Bytecode_new: public Bytecode {
|
class Bytecode_new: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_new(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
|
void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }
|
||||||
|
|
||||||
// Returns index
|
// Returns index
|
||||||
long index() const { return get_index_u2(Bytecodes::_new); };
|
long index() const { return get_index_u2(Bytecodes::_new); };
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_new* Bytecode_new_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_new* Bytecode_new_at(address bcp) {
|
|
||||||
Bytecode_new* b = (Bytecode_new*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Bytecode_multianewarray: public Bytecode {
|
class Bytecode_multianewarray: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_multianewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
|
void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }
|
||||||
|
|
||||||
// Returns index
|
// Returns index
|
||||||
long index() const { return get_index_u2(Bytecodes::_multianewarray); };
|
long index() const { return get_index_u2(Bytecodes::_multianewarray); };
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
|
|
||||||
Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Bytecode_anewarray: public Bytecode {
|
class Bytecode_anewarray: public Bytecode {
|
||||||
public:
|
public:
|
||||||
|
Bytecode_anewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); }
|
||||||
void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
|
void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }
|
||||||
|
|
||||||
// Returns index
|
// Returns index
|
||||||
long index() const { return get_index_u2(Bytecodes::_anewarray); };
|
long index() const { return get_index_u2(Bytecodes::_anewarray); };
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
|
|
||||||
Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Abstraction for ldc, ldc_w and ldc2_w
|
// Abstraction for ldc, ldc_w and ldc2_w
|
||||||
|
class Bytecode_loadconstant: public Bytecode {
|
||||||
class Bytecode_loadconstant: public ResourceObj {
|
|
||||||
private:
|
private:
|
||||||
int _bci;
|
const methodHandle _method;
|
||||||
methodHandle _method;
|
|
||||||
|
|
||||||
Bytecodes::Code code() const { return bytecode()->code(); }
|
|
||||||
|
|
||||||
int raw_index() const;
|
int raw_index() const;
|
||||||
|
|
||||||
Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Attributes
|
Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }
|
||||||
methodHandle method() const { return _method; }
|
|
||||||
int bci() const { return _bci; }
|
|
||||||
address bcp() const { return _method->bcp_from(bci()); }
|
|
||||||
Bytecode* bytecode() const { return Bytecode_at(bcp()); }
|
|
||||||
|
|
||||||
void verify() const {
|
void verify() const {
|
||||||
assert(_method.not_null(), "must supply method");
|
assert(_method.not_null(), "must supply method");
|
||||||
|
@ -437,15 +334,6 @@ class Bytecode_loadconstant: public ResourceObj {
|
||||||
BasicType result_type() const; // returns the result type of the ldc
|
BasicType result_type() const; // returns the result type of the ldc
|
||||||
|
|
||||||
oop resolve_constant(TRAPS) const;
|
oop resolve_constant(TRAPS) const;
|
||||||
|
|
||||||
// Creation
|
|
||||||
inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) {
|
|
||||||
Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci);
|
|
||||||
DEBUG_ONLY(b->verify());
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SHARE_VM_INTERPRETER_BYTECODE_HPP
|
#endif // SHARE_VM_INTERPRETER_BYTECODE_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -831,11 +831,11 @@ BytecodeInterpreter::run(interpreterState istate) {
|
||||||
// much like trying to deopt at a poll return. In that has we simply
|
// much like trying to deopt at a poll return. In that has we simply
|
||||||
// get out of here
|
// get out of here
|
||||||
//
|
//
|
||||||
if ( Bytecodes::code_at(pc, METHOD) == Bytecodes::_return_register_finalizer) {
|
if ( Bytecodes::code_at(METHOD, pc) == Bytecodes::_return_register_finalizer) {
|
||||||
// this will do the right thing even if an exception is pending.
|
// this will do the right thing even if an exception is pending.
|
||||||
goto handle_return;
|
goto handle_return;
|
||||||
}
|
}
|
||||||
UPDATE_PC(Bytecodes::length_at(pc));
|
UPDATE_PC(Bytecodes::length_at(METHOD, pc));
|
||||||
if (THREAD->has_pending_exception()) goto handle_exception;
|
if (THREAD->has_pending_exception()) goto handle_exception;
|
||||||
goto run;
|
goto run;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -59,7 +59,7 @@ void BaseBytecodeStream::assert_raw_index_size(int size) const {
|
||||||
// in raw mode, pretend indy is "bJJ__"
|
// in raw mode, pretend indy is "bJJ__"
|
||||||
assert(size == 2, "raw invokedynamic instruction has 2-byte index only");
|
assert(size == 2, "raw invokedynamic instruction has 2-byte index only");
|
||||||
} else {
|
} else {
|
||||||
bytecode()->assert_index_size(size, raw_code(), is_wide());
|
bytecode().assert_index_size(size, raw_code(), is_wide());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -105,14 +105,14 @@ class BaseBytecodeStream: StackObj {
|
||||||
bool is_last_bytecode() const { return _next_bci >= _end_bci; }
|
bool is_last_bytecode() const { return _next_bci >= _end_bci; }
|
||||||
|
|
||||||
address bcp() const { return method()->code_base() + _bci; }
|
address bcp() const { return method()->code_base() + _bci; }
|
||||||
Bytecode* bytecode() const { return Bytecode_at(bcp()); }
|
Bytecode bytecode() const { return Bytecode(_method(), bcp()); }
|
||||||
|
|
||||||
// State changes
|
// State changes
|
||||||
void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; }
|
void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; }
|
||||||
|
|
||||||
// Bytecode-specific attributes
|
// Bytecode-specific attributes
|
||||||
int dest() const { return bci() + bytecode()->get_offset_s2(raw_code()); }
|
int dest() const { return bci() + bytecode().get_offset_s2(raw_code()); }
|
||||||
int dest_w() const { return bci() + bytecode()->get_offset_s4(raw_code()); }
|
int dest_w() const { return bci() + bytecode().get_offset_s4(raw_code()); }
|
||||||
|
|
||||||
// One-byte indices.
|
// One-byte indices.
|
||||||
int get_index_u1() const { assert_raw_index_size(1); return *(jubyte*)(bcp()+1); }
|
int get_index_u1() const { assert_raw_index_size(1); return *(jubyte*)(bcp()+1); }
|
||||||
|
@ -189,7 +189,7 @@ class BytecodeStream: public BaseBytecodeStream {
|
||||||
} else {
|
} else {
|
||||||
// get bytecode
|
// get bytecode
|
||||||
address bcp = this->bcp();
|
address bcp = this->bcp();
|
||||||
raw_code = Bytecodes::code_at(bcp);
|
raw_code = Bytecodes::code_at(_method(), bcp);
|
||||||
code = Bytecodes::java_code(raw_code);
|
code = Bytecodes::java_code(raw_code);
|
||||||
// set next bytecode position
|
// set next bytecode position
|
||||||
//
|
//
|
||||||
|
@ -197,7 +197,7 @@ class BytecodeStream: public BaseBytecodeStream {
|
||||||
// tty bytecode otherwise the stepping is wrong!
|
// tty bytecode otherwise the stepping is wrong!
|
||||||
// (carefull: length_for(...) must be used first!)
|
// (carefull: length_for(...) must be used first!)
|
||||||
int l = Bytecodes::length_for(code);
|
int l = Bytecodes::length_for(code);
|
||||||
if (l == 0) l = Bytecodes::length_at(bcp);
|
if (l == 0) l = Bytecodes::length_at(_method(), bcp);
|
||||||
_next_bci += l;
|
_next_bci += l;
|
||||||
assert(_bci < _next_bci, "length must be > 0");
|
assert(_bci < _next_bci, "length must be > 0");
|
||||||
// set attributes
|
// set attributes
|
||||||
|
@ -219,16 +219,16 @@ class BytecodeStream: public BaseBytecodeStream {
|
||||||
Bytecodes::Code code() const { return _code; }
|
Bytecodes::Code code() const { return _code; }
|
||||||
|
|
||||||
// Unsigned indices, widening
|
// Unsigned indices, widening
|
||||||
int get_index() const { return is_wide() ? bytecode()->get_index_u2(raw_code(), true) : get_index_u1(); }
|
int get_index() const { return is_wide() ? bytecode().get_index_u2(raw_code(), true) : get_index_u1(); }
|
||||||
// Get an unsigned 2-byte index, swapping the bytes if necessary.
|
// Get an unsigned 2-byte index, swapping the bytes if necessary.
|
||||||
int get_index_u2() const { assert_raw_stream(false);
|
int get_index_u2() const { assert_raw_stream(false);
|
||||||
return bytecode()->get_index_u2(raw_code(), false); }
|
return bytecode().get_index_u2(raw_code(), false); }
|
||||||
// Get an unsigned 2-byte index in native order.
|
// Get an unsigned 2-byte index in native order.
|
||||||
int get_index_u2_cpcache() const { assert_raw_stream(false);
|
int get_index_u2_cpcache() const { assert_raw_stream(false);
|
||||||
return bytecode()->get_index_u2_cpcache(raw_code()); }
|
return bytecode().get_index_u2_cpcache(raw_code()); }
|
||||||
int get_index_u4() const { assert_raw_stream(false);
|
int get_index_u4() const { assert_raw_stream(false);
|
||||||
return bytecode()->get_index_u4(raw_code()); }
|
return bytecode().get_index_u4(raw_code()); }
|
||||||
bool has_index_u4() const { return bytecode()->has_index_u4(raw_code()); }
|
bool has_index_u4() const { return bytecode().has_index_u4(raw_code()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP
|
#endif // SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -100,9 +100,9 @@ class BytecodePrinter: public BytecodeClosure {
|
||||||
Bytecodes::Code code;
|
Bytecodes::Code code;
|
||||||
if (is_wide()) {
|
if (is_wide()) {
|
||||||
// bcp wasn't advanced if previous bytecode was _wide.
|
// bcp wasn't advanced if previous bytecode was _wide.
|
||||||
code = Bytecodes::code_at(bcp+1);
|
code = Bytecodes::code_at(method(), bcp+1);
|
||||||
} else {
|
} else {
|
||||||
code = Bytecodes::code_at(bcp);
|
code = Bytecodes::code_at(method(), bcp);
|
||||||
}
|
}
|
||||||
_code = code;
|
_code = code;
|
||||||
int bci = bcp - method->code_base();
|
int bci = bcp - method->code_base();
|
||||||
|
@ -127,11 +127,11 @@ class BytecodePrinter: public BytecodeClosure {
|
||||||
void trace(methodHandle method, address bcp, outputStream* st) {
|
void trace(methodHandle method, address bcp, outputStream* st) {
|
||||||
_current_method = method();
|
_current_method = method();
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
Bytecodes::Code code = Bytecodes::code_at(bcp);
|
Bytecodes::Code code = Bytecodes::code_at(method(), bcp);
|
||||||
// Set is_wide
|
// Set is_wide
|
||||||
_is_wide = (code == Bytecodes::_wide);
|
_is_wide = (code == Bytecodes::_wide);
|
||||||
if (is_wide()) {
|
if (is_wide()) {
|
||||||
code = Bytecodes::code_at(bcp+1);
|
code = Bytecodes::code_at(method(), bcp+1);
|
||||||
}
|
}
|
||||||
_code = code;
|
_code = code;
|
||||||
int bci = bcp - method->code_base();
|
int bci = bcp - method->code_base();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -54,18 +54,46 @@ u_char Bytecodes::_lengths [Bytecodes::number_of_codes];
|
||||||
Bytecodes::Code Bytecodes::_java_code [Bytecodes::number_of_codes];
|
Bytecodes::Code Bytecodes::_java_code [Bytecodes::number_of_codes];
|
||||||
u_short Bytecodes::_flags [(1<<BitsPerByte)*2];
|
u_short Bytecodes::_flags [(1<<BitsPerByte)*2];
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
bool Bytecodes::check_method(const methodOopDesc* method, address bcp) {
|
||||||
|
return method->contains(bcp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Bytecodes::Code Bytecodes::code_at(methodOop method, int bci) {
|
bool Bytecodes::check_must_rewrite(Bytecodes::Code code) {
|
||||||
return code_at(method->bcp_from(bci), method);
|
assert(can_rewrite(code), "post-check only");
|
||||||
|
|
||||||
|
// Some codes are conditionally rewriting. Look closely at them.
|
||||||
|
switch (code) {
|
||||||
|
case Bytecodes::_aload_0:
|
||||||
|
// Even if RewriteFrequentPairs is turned on,
|
||||||
|
// the _aload_0 code might delay its rewrite until
|
||||||
|
// a following _getfield rewrites itself.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case Bytecodes::_lookupswitch:
|
||||||
|
return false; // the rewrite is not done by the interpreter
|
||||||
|
|
||||||
|
case Bytecodes::_new:
|
||||||
|
// (Could actually look at the class here, but the profit would be small.)
|
||||||
|
return false; // the rewrite is not always done
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other special cases.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bytecodes::Code Bytecodes::non_breakpoint_code_at(address bcp, methodOop method) {
|
Bytecodes::Code Bytecodes::code_at(methodOop method, int bci) {
|
||||||
if (method == NULL) method = methodOopDesc::method_from_bcp(bcp);
|
return code_at(method, method->bcp_from(bci));
|
||||||
|
}
|
||||||
|
|
||||||
|
Bytecodes::Code Bytecodes::non_breakpoint_code_at(const methodOopDesc* method, address bcp) {
|
||||||
|
assert(method != NULL, "must have the method for breakpoint conversion");
|
||||||
|
assert(method->contains(bcp), "must be valid bcp in method");
|
||||||
return method->orig_bytecode_at(method->bci_from(bcp));
|
return method->orig_bytecode_at(method->bci_from(bcp));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bytecodes::special_length_at(address bcp, address end) {
|
int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end) {
|
||||||
Code code = code_at(bcp);
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case _wide:
|
case _wide:
|
||||||
if (end != NULL && bcp + 1 >= end) {
|
if (end != NULL && bcp + 1 >= end) {
|
||||||
|
@ -120,7 +148,7 @@ int Bytecodes::raw_special_length_at(address bcp, address end) {
|
||||||
if (code == _breakpoint) {
|
if (code == _breakpoint) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return special_length_at(bcp, end);
|
return special_length_at(code, bcp, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -342,6 +342,12 @@ class Bytecodes: AllStatic {
|
||||||
static void pd_initialize(); // platform specific initialization
|
static void pd_initialize(); // platform specific initialization
|
||||||
static Code pd_base_code_for(Code code); // platform specific base_code_for implementation
|
static Code pd_base_code_for(Code code); // platform specific base_code_for implementation
|
||||||
|
|
||||||
|
// Verify that bcp points into method
|
||||||
|
#ifdef ASSERT
|
||||||
|
static bool check_method(const methodOopDesc* method, address bcp);
|
||||||
|
#endif
|
||||||
|
static bool check_must_rewrite(Bytecodes::Code bc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Conversion
|
// Conversion
|
||||||
static void check (Code code) { assert(is_defined(code), "illegal code"); }
|
static void check (Code code) { assert(is_defined(code), "illegal code"); }
|
||||||
|
@ -349,22 +355,30 @@ class Bytecodes: AllStatic {
|
||||||
static Code cast (int code) { return (Code)code; }
|
static Code cast (int code) { return (Code)code; }
|
||||||
|
|
||||||
|
|
||||||
// Fetch a bytecode, hiding breakpoints as necessary:
|
// Fetch a bytecode, hiding breakpoints as necessary. The method
|
||||||
static Code code_at(address bcp, methodOop method = NULL) {
|
// argument is used for conversion of breakpoints into the original
|
||||||
Code code = cast(*bcp); return (code != _breakpoint) ? code : non_breakpoint_code_at(bcp, method);
|
// bytecode. The CI uses these methods but guarantees that
|
||||||
}
|
// breakpoints are hidden so the method argument should be passed as
|
||||||
static Code java_code_at(address bcp, methodOop method = NULL) {
|
// NULL since in that case the bcp and methodOop are unrelated
|
||||||
return java_code(code_at(bcp, method));
|
// memory.
|
||||||
}
|
static Code code_at(const methodOopDesc* method, address bcp) {
|
||||||
|
assert(method == NULL || check_method(method, bcp), "bcp must point into method");
|
||||||
|
Code code = cast(*bcp);
|
||||||
|
assert(code != _breakpoint || method != NULL, "need methodOop to decode breakpoint");
|
||||||
|
return (code != _breakpoint) ? code : non_breakpoint_code_at(method, bcp);
|
||||||
|
}
|
||||||
|
static Code java_code_at(const methodOopDesc* method, address bcp) {
|
||||||
|
return java_code(code_at(method, bcp));
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch a bytecode or a breakpoint:
|
// Fetch a bytecode or a breakpoint:
|
||||||
static Code code_or_bp_at(address bcp) { return (Code)cast(*bcp); }
|
static Code code_or_bp_at(address bcp) { return (Code)cast(*bcp); }
|
||||||
|
|
||||||
static Code code_at(methodOop method, int bci);
|
static Code code_at(methodOop method, int bci);
|
||||||
static bool is_active_breakpoint_at(address bcp) { return (Code)*bcp == _breakpoint; }
|
static bool is_active_breakpoint_at(address bcp) { return (Code)*bcp == _breakpoint; }
|
||||||
|
|
||||||
// find a bytecode, behind a breakpoint if necessary:
|
// find a bytecode, behind a breakpoint if necessary:
|
||||||
static Code non_breakpoint_code_at(address bcp, methodOop method = NULL);
|
static Code non_breakpoint_code_at(const methodOopDesc* method, address bcp);
|
||||||
|
|
||||||
// Bytecode attributes
|
// Bytecode attributes
|
||||||
static bool is_defined (int code) { return 0 <= code && code < number_of_codes && flags(code, false) != 0; }
|
static bool is_defined (int code) { return 0 <= code && code < number_of_codes && flags(code, false) != 0; }
|
||||||
|
@ -379,14 +393,17 @@ class Bytecodes: AllStatic {
|
||||||
static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
|
static bool can_trap (Code code) { check(code); return has_all_flags(code, _bc_can_trap, false); }
|
||||||
static Code java_code (Code code) { check(code); return _java_code [code]; }
|
static Code java_code (Code code) { check(code); return _java_code [code]; }
|
||||||
static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
|
static bool can_rewrite (Code code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); }
|
||||||
|
static bool must_rewrite(Bytecodes::Code code) { return can_rewrite(code) && check_must_rewrite(code); }
|
||||||
static bool native_byte_order(Code code) { check(code); return has_all_flags(code, _fmt_has_nbo, false); }
|
static bool native_byte_order(Code code) { check(code); return has_all_flags(code, _fmt_has_nbo, false); }
|
||||||
static bool uses_cp_cache (Code code) { check(code); return has_all_flags(code, _fmt_has_j, false); }
|
static bool uses_cp_cache (Code code) { check(code); return has_all_flags(code, _fmt_has_j, false); }
|
||||||
// if 'end' is provided, it indicates the end of the code buffer which
|
// if 'end' is provided, it indicates the end of the code buffer which
|
||||||
// should not be read past when parsing.
|
// should not be read past when parsing.
|
||||||
static int special_length_at(address bcp, address end = NULL);
|
static int special_length_at(Bytecodes::Code code, address bcp, address end = NULL);
|
||||||
|
static int special_length_at(methodOop method, address bcp, address end = NULL) { return special_length_at(code_at(method, bcp), bcp, end); }
|
||||||
static int raw_special_length_at(address bcp, address end = NULL);
|
static int raw_special_length_at(address bcp, address end = NULL);
|
||||||
static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
static int length_for_code_at(Bytecodes::Code code, address bcp) { int l = length_for(code); return l > 0 ? l : special_length_at(code, bcp); }
|
||||||
static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
|
static int length_at (methodOop method, address bcp) { return length_for_code_at(code_at(method, bcp), bcp); }
|
||||||
|
static int java_length_at (methodOop method, address bcp) { return length_for_code_at(java_code_at(method, bcp), bcp); }
|
||||||
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
|
static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
|
||||||
|
|
||||||
static bool is_aload (Code code) { return (code == _aload || code == _aload_0 || code == _aload_1
|
static bool is_aload (Code code) { return (code == _aload || code == _aload_0 || code == _aload_1
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -237,10 +237,9 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m)
|
||||||
// Return true if the interpreter can prove that the given bytecode has
|
// Return true if the interpreter can prove that the given bytecode has
|
||||||
// not yet been executed (in Java semantics, not in actual operation).
|
// not yet been executed (in Java semantics, not in actual operation).
|
||||||
bool AbstractInterpreter::is_not_reached(methodHandle method, int bci) {
|
bool AbstractInterpreter::is_not_reached(methodHandle method, int bci) {
|
||||||
address bcp = method->bcp_from(bci);
|
Bytecodes::Code code = method()->code_at(bci);
|
||||||
Bytecodes::Code code = Bytecodes::code_at(bcp, method());
|
|
||||||
|
|
||||||
if (!Bytecode_at(bcp)->must_rewrite(code)) {
|
if (!Bytecodes::must_rewrite(code)) {
|
||||||
// might have been reached
|
// might have been reached
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -286,12 +285,12 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) {
|
||||||
// If deoptimization happens, this function returns the point of next bytecode to continue execution
|
// If deoptimization happens, this function returns the point of next bytecode to continue execution
|
||||||
address AbstractInterpreter::deopt_continue_after_entry(methodOop method, address bcp, int callee_parameters, bool is_top_frame) {
|
address AbstractInterpreter::deopt_continue_after_entry(methodOop method, address bcp, int callee_parameters, bool is_top_frame) {
|
||||||
assert(method->contains(bcp), "just checkin'");
|
assert(method->contains(bcp), "just checkin'");
|
||||||
Bytecodes::Code code = Bytecodes::java_code_at(bcp);
|
Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
|
||||||
assert(!Interpreter::bytecode_should_reexecute(code), "should not reexecute");
|
assert(!Interpreter::bytecode_should_reexecute(code), "should not reexecute");
|
||||||
int bci = method->bci_from(bcp);
|
int bci = method->bci_from(bcp);
|
||||||
int length = -1; // initial value for debugging
|
int length = -1; // initial value for debugging
|
||||||
// compute continuation length
|
// compute continuation length
|
||||||
length = Bytecodes::length_at(bcp);
|
length = Bytecodes::length_at(method, bcp);
|
||||||
// compute result type
|
// compute result type
|
||||||
BasicType type = T_ILLEGAL;
|
BasicType type = T_ILLEGAL;
|
||||||
|
|
||||||
|
@ -303,7 +302,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
||||||
Thread *thread = Thread::current();
|
Thread *thread = Thread::current();
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle mh(thread, method);
|
methodHandle mh(thread, method);
|
||||||
type = Bytecode_invoke_at(mh, bci)->result_type(thread);
|
type = Bytecode_invoke(mh, bci).result_type(thread);
|
||||||
// since the cache entry might not be initialized:
|
// since the cache entry might not be initialized:
|
||||||
// (NOT needed for the old calling convension)
|
// (NOT needed for the old calling convension)
|
||||||
if (!is_top_frame) {
|
if (!is_top_frame) {
|
||||||
|
@ -317,7 +316,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
||||||
Thread *thread = Thread::current();
|
Thread *thread = Thread::current();
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle mh(thread, method);
|
methodHandle mh(thread, method);
|
||||||
type = Bytecode_invoke_at(mh, bci)->result_type(thread);
|
type = Bytecode_invoke(mh, bci).result_type(thread);
|
||||||
// since the cache entry might not be initialized:
|
// since the cache entry might not be initialized:
|
||||||
// (NOT needed for the old calling convension)
|
// (NOT needed for the old calling convension)
|
||||||
if (!is_top_frame) {
|
if (!is_top_frame) {
|
||||||
|
@ -334,7 +333,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
||||||
Thread *thread = Thread::current();
|
Thread *thread = Thread::current();
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle mh(thread, method);
|
methodHandle mh(thread, method);
|
||||||
type = Bytecode_loadconstant_at(mh, bci)->result_type();
|
type = Bytecode_loadconstant(mh, bci).result_type();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +355,7 @@ address AbstractInterpreter::deopt_continue_after_entry(methodOop method, addres
|
||||||
// Interpreter::deopt_entry(vtos, 0) like others
|
// Interpreter::deopt_entry(vtos, 0) like others
|
||||||
address AbstractInterpreter::deopt_reexecute_entry(methodOop method, address bcp) {
|
address AbstractInterpreter::deopt_reexecute_entry(methodOop method, address bcp) {
|
||||||
assert(method->contains(bcp), "just checkin'");
|
assert(method->contains(bcp), "just checkin'");
|
||||||
Bytecodes::Code code = Bytecodes::java_code_at(bcp);
|
Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
|
||||||
#ifdef COMPILER1
|
#ifdef COMPILER1
|
||||||
if(code == Bytecodes::_athrow ) {
|
if(code == Bytecodes::_athrow ) {
|
||||||
return Interpreter::rethrow_exception_entry();
|
return Interpreter::rethrow_exception_entry();
|
||||||
|
|
|
@ -132,9 +132,9 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::C
|
||||||
bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
|
bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle m (thread, method(thread));
|
methodHandle m (thread, method(thread));
|
||||||
Bytecode_loadconstant* ldc = Bytecode_loadconstant_at(m, bci(thread));
|
Bytecode_loadconstant ldc(m, bci(thread));
|
||||||
oop result = ldc->resolve_constant(THREAD);
|
oop result = ldc.resolve_constant(THREAD);
|
||||||
DEBUG_ONLY(ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc->cache_index()));
|
DEBUG_ONLY(ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc.cache_index()));
|
||||||
assert(result == cpce->f1(), "expected result for assembly code");
|
assert(result == cpce->f1(), "expected result for assembly code");
|
||||||
}
|
}
|
||||||
IRT_END
|
IRT_END
|
||||||
|
@ -672,8 +672,8 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
||||||
if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
|
if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
methodHandle m (thread, method(thread));
|
methodHandle m (thread, method(thread));
|
||||||
Bytecode_invoke* call = Bytecode_invoke_at(m, bci(thread));
|
Bytecode_invoke call(m, bci(thread));
|
||||||
symbolHandle signature (thread, call->signature());
|
symbolHandle signature (thread, call.signature());
|
||||||
receiver = Handle(thread,
|
receiver = Handle(thread,
|
||||||
thread->last_frame().interpreter_callee_receiver(signature));
|
thread->last_frame().interpreter_callee_receiver(signature));
|
||||||
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
|
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
|
||||||
|
@ -756,7 +756,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
|
||||||
caller_bci = caller_method->bci_from(caller_bcp);
|
caller_bci = caller_method->bci_from(caller_bcp);
|
||||||
site_index = Bytes::get_native_u4(caller_bcp+1);
|
site_index = Bytes::get_native_u4(caller_bcp+1);
|
||||||
}
|
}
|
||||||
assert(site_index == InterpreterRuntime::bytecode(thread)->get_index_u4(bytecode), "");
|
assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), "");
|
||||||
assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format");
|
assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format");
|
||||||
// there is a second CPC entries that is of interest; it caches signature info:
|
// there is a second CPC entries that is of interest; it caches signature info:
|
||||||
int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
|
int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
|
||||||
|
@ -1241,9 +1241,9 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa
|
||||||
assert(fr.is_interpreted_frame(), "");
|
assert(fr.is_interpreted_frame(), "");
|
||||||
jint bci = fr.interpreter_frame_bci();
|
jint bci = fr.interpreter_frame_bci();
|
||||||
methodHandle mh(thread, fr.interpreter_frame_method());
|
methodHandle mh(thread, fr.interpreter_frame_method());
|
||||||
Bytecode_invoke* invoke = Bytecode_invoke_at(mh, bci);
|
Bytecode_invoke invoke(mh, bci);
|
||||||
ArgumentSizeComputer asc(invoke->signature());
|
ArgumentSizeComputer asc(invoke.signature());
|
||||||
int size_of_arguments = (asc.size() + (invoke->has_receiver() ? 1 : 0)); // receiver
|
int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
|
||||||
Copy::conjoint_jbytes(src_address, dest_address,
|
Copy::conjoint_jbytes(src_address, dest_address,
|
||||||
size_of_arguments * Interpreter::stackElementSize);
|
size_of_arguments * Interpreter::stackElementSize);
|
||||||
IRT_END
|
IRT_END
|
||||||
|
|
|
@ -58,16 +58,16 @@ class InterpreterRuntime: AllStatic {
|
||||||
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
|
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
|
||||||
static Bytecodes::Code code(JavaThread *thread) {
|
static Bytecodes::Code code(JavaThread *thread) {
|
||||||
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
|
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
|
||||||
return Bytecodes::code_at(bcp(thread), method(thread));
|
return Bytecodes::code_at(method(thread), bcp(thread));
|
||||||
}
|
}
|
||||||
static bool already_resolved(JavaThread *thread) { return cache_entry(thread)->is_resolved(code(thread)); }
|
static bool already_resolved(JavaThread *thread) { return cache_entry(thread)->is_resolved(code(thread)); }
|
||||||
static Bytecode* bytecode(JavaThread *thread) { return Bytecode_at(bcp(thread)); }
|
static Bytecode bytecode(JavaThread *thread) { return Bytecode(method(thread), bcp(thread)); }
|
||||||
static int get_index_u1(JavaThread *thread, Bytecodes::Code bc)
|
static int get_index_u1(JavaThread *thread, Bytecodes::Code bc)
|
||||||
{ return bytecode(thread)->get_index_u1(bc); }
|
{ return bytecode(thread).get_index_u1(bc); }
|
||||||
static int get_index_u2(JavaThread *thread, Bytecodes::Code bc)
|
static int get_index_u2(JavaThread *thread, Bytecodes::Code bc)
|
||||||
{ return bytecode(thread)->get_index_u2(bc); }
|
{ return bytecode(thread).get_index_u2(bc); }
|
||||||
static int get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
|
static int get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
|
||||||
{ return bytecode(thread)->get_index_u2_cpcache(bc); }
|
{ return bytecode(thread).get_index_u2_cpcache(bc); }
|
||||||
static int number_of_dimensions(JavaThread *thread) { return bcp(thread)[3]; }
|
static int number_of_dimensions(JavaThread *thread) { return bcp(thread)[3]; }
|
||||||
|
|
||||||
static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); }
|
static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -221,7 +221,7 @@ void Rewriter::scan_method(methodOop method) {
|
||||||
// call to calculate the length.
|
// call to calculate the length.
|
||||||
bc_length = Bytecodes::length_for(c);
|
bc_length = Bytecodes::length_for(c);
|
||||||
if (bc_length == 0) {
|
if (bc_length == 0) {
|
||||||
bc_length = Bytecodes::length_at(bcp);
|
bc_length = Bytecodes::length_at(method, bcp);
|
||||||
|
|
||||||
// length_at will put us at the bytecode after the one modified
|
// length_at will put us at the bytecode after the one modified
|
||||||
// by 'wide'. We don't currently examine any of the bytecodes
|
// by 'wide'. We don't currently examine any of the bytecodes
|
||||||
|
@ -237,9 +237,9 @@ void Rewriter::scan_method(methodOop method) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case Bytecodes::_lookupswitch : {
|
case Bytecodes::_lookupswitch : {
|
||||||
#ifndef CC_INTERP
|
#ifndef CC_INTERP
|
||||||
Bytecode_lookupswitch* bc = Bytecode_lookupswitch_at(bcp);
|
Bytecode_lookupswitch bc(method, bcp);
|
||||||
(*bcp) = (
|
(*bcp) = (
|
||||||
bc->number_of_pairs() < BinarySwitchThreshold
|
bc.number_of_pairs() < BinarySwitchThreshold
|
||||||
? Bytecodes::_fast_linearswitch
|
? Bytecodes::_fast_linearswitch
|
||||||
: Bytecodes::_fast_binaryswitch
|
: Bytecodes::_fast_binaryswitch
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -592,7 +592,7 @@ address TemplateInterpreter::deopt_continue_after_entry(methodOop method, addres
|
||||||
// that do not return "Interpreter::deopt_entry(vtos, 0)"
|
// that do not return "Interpreter::deopt_entry(vtos, 0)"
|
||||||
address TemplateInterpreter::deopt_reexecute_entry(methodOop method, address bcp) {
|
address TemplateInterpreter::deopt_reexecute_entry(methodOop method, address bcp) {
|
||||||
assert(method->contains(bcp), "just checkin'");
|
assert(method->contains(bcp), "just checkin'");
|
||||||
Bytecodes::Code code = Bytecodes::java_code_at(bcp);
|
Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
|
||||||
if (code == Bytecodes::_return) {
|
if (code == Bytecodes::_return) {
|
||||||
// This is used for deopt during registration of finalizers
|
// This is used for deopt during registration of finalizers
|
||||||
// during Object.<init>. We simply need to resume execution at
|
// during Object.<init>. We simply need to resume execution at
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -535,23 +535,23 @@ bool GenerateOopMap::jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int *
|
||||||
(*jmpFct)(this, bcs->dest_w(), data);
|
(*jmpFct)(this, bcs->dest_w(), data);
|
||||||
break;
|
break;
|
||||||
case Bytecodes::_tableswitch:
|
case Bytecodes::_tableswitch:
|
||||||
{ Bytecode_tableswitch *tableswitch = Bytecode_tableswitch_at(bcs->bcp());
|
{ Bytecode_tableswitch tableswitch(method(), bcs->bcp());
|
||||||
int len = tableswitch->length();
|
int len = tableswitch.length();
|
||||||
|
|
||||||
(*jmpFct)(this, bci + tableswitch->default_offset(), data); /* Default. jump address */
|
(*jmpFct)(this, bci + tableswitch.default_offset(), data); /* Default. jump address */
|
||||||
while (--len >= 0) {
|
while (--len >= 0) {
|
||||||
(*jmpFct)(this, bci + tableswitch->dest_offset_at(len), data);
|
(*jmpFct)(this, bci + tableswitch.dest_offset_at(len), data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Bytecodes::_lookupswitch:
|
case Bytecodes::_lookupswitch:
|
||||||
{ Bytecode_lookupswitch *lookupswitch = Bytecode_lookupswitch_at(bcs->bcp());
|
{ Bytecode_lookupswitch lookupswitch(method(), bcs->bcp());
|
||||||
int npairs = lookupswitch->number_of_pairs();
|
int npairs = lookupswitch.number_of_pairs();
|
||||||
(*jmpFct)(this, bci + lookupswitch->default_offset(), data); /* Default. */
|
(*jmpFct)(this, bci + lookupswitch.default_offset(), data); /* Default. */
|
||||||
while(--npairs >= 0) {
|
while(--npairs >= 0) {
|
||||||
LookupswitchPair *pair = lookupswitch->pair_at(npairs);
|
LookupswitchPair pair = lookupswitch.pair_at(npairs);
|
||||||
(*jmpFct)(this, bci + pair->offset(), data);
|
(*jmpFct)(this, bci + pair.offset(), data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -977,7 +977,7 @@ void GenerateOopMap::init_basic_blocks() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (blockNum + 1 < bbNo) {
|
if (blockNum + 1 < bbNo) {
|
||||||
address bcp = _method->bcp_from(bb->_end_bci);
|
address bcp = _method->bcp_from(bb->_end_bci);
|
||||||
int bc_len = Bytecodes::java_length_at(bcp);
|
int bc_len = Bytecodes::java_length_at(_method(), bcp);
|
||||||
assert(bb->_end_bci + bc_len == bb[1]._bci, "unmatched bci info in basicblock");
|
assert(bb->_end_bci + bc_len == bb[1]._bci, "unmatched bci info in basicblock");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -985,7 +985,7 @@ void GenerateOopMap::init_basic_blocks() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
{ BasicBlock *bb = &_basic_blocks[bbNo-1];
|
{ BasicBlock *bb = &_basic_blocks[bbNo-1];
|
||||||
address bcp = _method->bcp_from(bb->_end_bci);
|
address bcp = _method->bcp_from(bb->_end_bci);
|
||||||
int bc_len = Bytecodes::java_length_at(bcp);
|
int bc_len = Bytecodes::java_length_at(_method(), bcp);
|
||||||
assert(bb->_end_bci + bc_len == _method->code_size(), "wrong end bci");
|
assert(bb->_end_bci + bc_len == _method->code_size(), "wrong end bci");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1837,14 +1837,14 @@ void GenerateOopMap::do_jsr(int targ_bci) {
|
||||||
|
|
||||||
|
|
||||||
void GenerateOopMap::do_ldc(int bci) {
|
void GenerateOopMap::do_ldc(int bci) {
|
||||||
Bytecode_loadconstant* ldc = Bytecode_loadconstant_at(method(), bci);
|
Bytecode_loadconstant ldc(method(), bci);
|
||||||
constantPoolOop cp = method()->constants();
|
constantPoolOop cp = method()->constants();
|
||||||
BasicType bt = ldc->result_type();
|
BasicType bt = ldc.result_type();
|
||||||
CellTypeState cts = (bt == T_OBJECT) ? CellTypeState::make_line_ref(bci) : valCTS;
|
CellTypeState cts = (bt == T_OBJECT) ? CellTypeState::make_line_ref(bci) : valCTS;
|
||||||
// Make sure bt==T_OBJECT is the same as old code (is_pointer_entry).
|
// Make sure bt==T_OBJECT is the same as old code (is_pointer_entry).
|
||||||
// Note that CONSTANT_MethodHandle entries are u2 index pairs, not pointer-entries,
|
// Note that CONSTANT_MethodHandle entries are u2 index pairs, not pointer-entries,
|
||||||
// and they are processed by _fast_aldc and the CP cache.
|
// and they are processed by _fast_aldc and the CP cache.
|
||||||
assert((ldc->has_cache_index() || cp->is_pointer_entry(ldc->pool_index()))
|
assert((ldc.has_cache_index() || cp->is_pointer_entry(ldc.pool_index()))
|
||||||
? (bt == T_OBJECT) : true, "expected object type");
|
? (bt == T_OBJECT) : true, "expected object type");
|
||||||
ppush1(cts);
|
ppush1(cts);
|
||||||
}
|
}
|
||||||
|
@ -2343,7 +2343,7 @@ bool GenerateOopMap::rewrite_refval_conflict_inst(BytecodeStream *itr, int from,
|
||||||
bool GenerateOopMap::rewrite_load_or_store(BytecodeStream *bcs, Bytecodes::Code bcN, Bytecodes::Code bc0, unsigned int varNo) {
|
bool GenerateOopMap::rewrite_load_or_store(BytecodeStream *bcs, Bytecodes::Code bcN, Bytecodes::Code bc0, unsigned int varNo) {
|
||||||
assert(bcN == Bytecodes::_astore || bcN == Bytecodes::_aload, "wrong argument (bcN)");
|
assert(bcN == Bytecodes::_astore || bcN == Bytecodes::_aload, "wrong argument (bcN)");
|
||||||
assert(bc0 == Bytecodes::_astore_0 || bc0 == Bytecodes::_aload_0, "wrong argument (bc0)");
|
assert(bc0 == Bytecodes::_astore_0 || bc0 == Bytecodes::_aload_0, "wrong argument (bc0)");
|
||||||
int ilen = Bytecodes::length_at(bcs->bcp());
|
int ilen = Bytecodes::length_at(_method(), bcs->bcp());
|
||||||
int newIlen;
|
int newIlen;
|
||||||
|
|
||||||
if (ilen == 4) {
|
if (ilen == 4) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -417,11 +417,11 @@ void BranchData::print_data_on(outputStream* st) {
|
||||||
int MultiBranchData::compute_cell_count(BytecodeStream* stream) {
|
int MultiBranchData::compute_cell_count(BytecodeStream* stream) {
|
||||||
int cell_count = 0;
|
int cell_count = 0;
|
||||||
if (stream->code() == Bytecodes::_tableswitch) {
|
if (stream->code() == Bytecodes::_tableswitch) {
|
||||||
Bytecode_tableswitch* sw = Bytecode_tableswitch_at(stream->bcp());
|
Bytecode_tableswitch sw(stream->method()(), stream->bcp());
|
||||||
cell_count = 1 + per_case_cell_count * (1 + sw->length()); // 1 for default
|
cell_count = 1 + per_case_cell_count * (1 + sw.length()); // 1 for default
|
||||||
} else {
|
} else {
|
||||||
Bytecode_lookupswitch* sw = Bytecode_lookupswitch_at(stream->bcp());
|
Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
|
||||||
cell_count = 1 + per_case_cell_count * (sw->number_of_pairs() + 1); // 1 for default
|
cell_count = 1 + per_case_cell_count * (sw.number_of_pairs() + 1); // 1 for default
|
||||||
}
|
}
|
||||||
return cell_count;
|
return cell_count;
|
||||||
}
|
}
|
||||||
|
@ -434,35 +434,35 @@ void MultiBranchData::post_initialize(BytecodeStream* stream,
|
||||||
int target_di;
|
int target_di;
|
||||||
int offset;
|
int offset;
|
||||||
if (stream->code() == Bytecodes::_tableswitch) {
|
if (stream->code() == Bytecodes::_tableswitch) {
|
||||||
Bytecode_tableswitch* sw = Bytecode_tableswitch_at(stream->bcp());
|
Bytecode_tableswitch sw(stream->method()(), stream->bcp());
|
||||||
int len = sw->length();
|
int len = sw.length();
|
||||||
assert(array_len() == per_case_cell_count * (len + 1), "wrong len");
|
assert(array_len() == per_case_cell_count * (len + 1), "wrong len");
|
||||||
for (int count = 0; count < len; count++) {
|
for (int count = 0; count < len; count++) {
|
||||||
target = sw->dest_offset_at(count) + bci();
|
target = sw.dest_offset_at(count) + bci();
|
||||||
my_di = mdo->dp_to_di(dp());
|
my_di = mdo->dp_to_di(dp());
|
||||||
target_di = mdo->bci_to_di(target);
|
target_di = mdo->bci_to_di(target);
|
||||||
offset = target_di - my_di;
|
offset = target_di - my_di;
|
||||||
set_displacement_at(count, offset);
|
set_displacement_at(count, offset);
|
||||||
}
|
}
|
||||||
target = sw->default_offset() + bci();
|
target = sw.default_offset() + bci();
|
||||||
my_di = mdo->dp_to_di(dp());
|
my_di = mdo->dp_to_di(dp());
|
||||||
target_di = mdo->bci_to_di(target);
|
target_di = mdo->bci_to_di(target);
|
||||||
offset = target_di - my_di;
|
offset = target_di - my_di;
|
||||||
set_default_displacement(offset);
|
set_default_displacement(offset);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Bytecode_lookupswitch* sw = Bytecode_lookupswitch_at(stream->bcp());
|
Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
|
||||||
int npairs = sw->number_of_pairs();
|
int npairs = sw.number_of_pairs();
|
||||||
assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len");
|
assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len");
|
||||||
for (int count = 0; count < npairs; count++) {
|
for (int count = 0; count < npairs; count++) {
|
||||||
LookupswitchPair *pair = sw->pair_at(count);
|
LookupswitchPair pair = sw.pair_at(count);
|
||||||
target = pair->offset() + bci();
|
target = pair.offset() + bci();
|
||||||
my_di = mdo->dp_to_di(dp());
|
my_di = mdo->dp_to_di(dp());
|
||||||
target_di = mdo->bci_to_di(target);
|
target_di = mdo->bci_to_di(target);
|
||||||
offset = target_di - my_di;
|
offset = target_di - my_di;
|
||||||
set_displacement_at(count, offset);
|
set_displacement_at(count, offset);
|
||||||
}
|
}
|
||||||
target = sw->default_offset() + bci();
|
target = sw.default_offset() + bci();
|
||||||
my_di = mdo->dp_to_di(dp());
|
my_di = mdo->dp_to_di(dp());
|
||||||
target_di = mdo->bci_to_di(target);
|
target_di = mdo->bci_to_di(target);
|
||||||
offset = target_di - my_di;
|
offset = target_di - my_di;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -150,17 +150,6 @@ int methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int thr
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
methodOop methodOopDesc::method_from_bcp(address bcp) {
|
|
||||||
debug_only(static int count = 0; count++);
|
|
||||||
assert(Universe::heap()->is_in_permanent(bcp), "bcp not in perm_gen");
|
|
||||||
// TO DO: this may be unsafe in some configurations
|
|
||||||
HeapWord* p = Universe::heap()->block_start(bcp);
|
|
||||||
assert(Universe::heap()->block_is_obj(p), "must be obj");
|
|
||||||
assert(oop(p)->is_constMethod(), "not a method");
|
|
||||||
return constMethodOop(p)->method();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void methodOopDesc::mask_for(int bci, InterpreterOopMap* mask) {
|
void methodOopDesc::mask_for(int bci, InterpreterOopMap* mask) {
|
||||||
|
|
||||||
Thread* myThread = Thread::current();
|
Thread* myThread = Thread::current();
|
||||||
|
@ -469,11 +458,10 @@ bool methodOopDesc::can_be_statically_bound() const {
|
||||||
bool methodOopDesc::is_accessor() const {
|
bool methodOopDesc::is_accessor() const {
|
||||||
if (code_size() != 5) return false;
|
if (code_size() != 5) return false;
|
||||||
if (size_of_parameters() != 1) return false;
|
if (size_of_parameters() != 1) return false;
|
||||||
methodOop m = (methodOop)this; // pass to code_at() to avoid method_from_bcp
|
if (java_code_at(0) != Bytecodes::_aload_0 ) return false;
|
||||||
if (Bytecodes::java_code_at(code_base()+0, m) != Bytecodes::_aload_0 ) return false;
|
if (java_code_at(1) != Bytecodes::_getfield) return false;
|
||||||
if (Bytecodes::java_code_at(code_base()+1, m) != Bytecodes::_getfield) return false;
|
if (java_code_at(4) != Bytecodes::_areturn &&
|
||||||
if (Bytecodes::java_code_at(code_base()+4, m) != Bytecodes::_areturn &&
|
java_code_at(4) != Bytecodes::_ireturn ) return false;
|
||||||
Bytecodes::java_code_at(code_base()+4, m) != Bytecodes::_ireturn ) return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1414,7 +1402,7 @@ bool CompressedLineNumberReadStream::read_pair() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Bytecodes::Code methodOopDesc::orig_bytecode_at(int bci) {
|
Bytecodes::Code methodOopDesc::orig_bytecode_at(int bci) const {
|
||||||
BreakpointInfo* bp = instanceKlass::cast(method_holder())->breakpoints();
|
BreakpointInfo* bp = instanceKlass::cast(method_holder())->breakpoints();
|
||||||
for (; bp != NULL; bp = bp->next()) {
|
for (; bp != NULL; bp = bp->next()) {
|
||||||
if (bp->match(this, bci)) {
|
if (bp->match(this, bci)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -196,8 +196,15 @@ class methodOopDesc : public oopDesc {
|
||||||
static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature);
|
static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature);
|
||||||
static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature, char* buf, int size);
|
static char* name_and_sig_as_C_string(Klass* klass, symbolOop method_name, symbolOop signature, char* buf, int size);
|
||||||
|
|
||||||
|
Bytecodes::Code java_code_at(int bci) const {
|
||||||
|
return Bytecodes::java_code_at(this, bcp_from(bci));
|
||||||
|
}
|
||||||
|
Bytecodes::Code code_at(int bci) const {
|
||||||
|
return Bytecodes::code_at(this, bcp_from(bci));
|
||||||
|
}
|
||||||
|
|
||||||
// JVMTI breakpoints
|
// JVMTI breakpoints
|
||||||
Bytecodes::Code orig_bytecode_at(int bci);
|
Bytecodes::Code orig_bytecode_at(int bci) const;
|
||||||
void set_orig_bytecode_at(int bci, Bytecodes::Code code);
|
void set_orig_bytecode_at(int bci, Bytecodes::Code code);
|
||||||
void set_breakpoint(int bci);
|
void set_breakpoint(int bci);
|
||||||
void clear_breakpoint(int bci);
|
void clear_breakpoint(int bci);
|
||||||
|
@ -655,8 +662,6 @@ class methodOopDesc : public oopDesc {
|
||||||
void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); }
|
void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); }
|
||||||
void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); }
|
void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); }
|
||||||
|
|
||||||
static methodOop method_from_bcp(address bcp);
|
|
||||||
|
|
||||||
// Resolve all classes in signature, return 'true' if successful
|
// Resolve all classes in signature, return 'true' if successful
|
||||||
static bool load_signature_classes(methodHandle m, TRAPS);
|
static bool load_signature_classes(methodHandle m, TRAPS);
|
||||||
|
|
||||||
|
@ -787,11 +792,11 @@ class BreakpointInfo : public CHeapObj {
|
||||||
void set_next(BreakpointInfo* n) { _next = n; }
|
void set_next(BreakpointInfo* n) { _next = n; }
|
||||||
|
|
||||||
// helps for searchers
|
// helps for searchers
|
||||||
bool match(methodOop m, int bci) {
|
bool match(const methodOopDesc* m, int bci) {
|
||||||
return bci == _bci && match(m);
|
return bci == _bci && match(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match(methodOop m) {
|
bool match(const methodOopDesc* m) {
|
||||||
return _name_index == m->name_index() &&
|
return _name_index == m->name_index() &&
|
||||||
_signature_index == m->signature_index();
|
_signature_index == m->signature_index();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1458,7 +1458,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method,
|
||||||
if (bc_length == 0) {
|
if (bc_length == 0) {
|
||||||
// More complicated bytecodes report a length of zero so
|
// More complicated bytecodes report a length of zero so
|
||||||
// we have to try again a slightly different way.
|
// we have to try again a slightly different way.
|
||||||
bc_length = Bytecodes::length_at(bcp);
|
bc_length = Bytecodes::length_at(method(), bcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bc_length != 0, "impossible bytecode length");
|
assert(bc_length != 0, "impossible bytecode length");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -194,10 +194,10 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
|
||||||
|
|
||||||
case Bytecodes::_ldc : // fall through
|
case Bytecodes::_ldc : // fall through
|
||||||
case Bytecodes::_ldc_w : {
|
case Bytecodes::_ldc_w : {
|
||||||
Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method(), _s_old->bci());
|
Bytecode_loadconstant ldc_old(_s_old->method(), _s_old->bci());
|
||||||
Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method(), _s_new->bci());
|
Bytecode_loadconstant ldc_new(_s_new->method(), _s_new->bci());
|
||||||
int cpi_old = ldc_old->pool_index();
|
int cpi_old = ldc_old.pool_index();
|
||||||
int cpi_new = ldc_new->pool_index();
|
int cpi_new = ldc_new.pool_index();
|
||||||
if (!pool_constants_same(cpi_old, cpi_new))
|
if (!pool_constants_same(cpi_old, cpi_new))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
@ -267,8 +267,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
|
||||||
case Bytecodes::_ifnonnull : // fall through
|
case Bytecodes::_ifnonnull : // fall through
|
||||||
case Bytecodes::_ifnull : // fall through
|
case Bytecodes::_ifnull : // fall through
|
||||||
case Bytecodes::_jsr : {
|
case Bytecodes::_jsr : {
|
||||||
int old_ofs = _s_old->bytecode()->get_offset_s2(c_old);
|
int old_ofs = _s_old->bytecode().get_offset_s2(c_old);
|
||||||
int new_ofs = _s_new->bytecode()->get_offset_s2(c_new);
|
int new_ofs = _s_new->bytecode().get_offset_s2(c_new);
|
||||||
if (_switchable_test) {
|
if (_switchable_test) {
|
||||||
int old_dest = _s_old->bci() + old_ofs;
|
int old_dest = _s_old->bci() + old_ofs;
|
||||||
int new_dest = _s_new->bci() + new_ofs;
|
int new_dest = _s_new->bci() + new_ofs;
|
||||||
|
@ -304,8 +304,8 @@ bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
|
||||||
|
|
||||||
case Bytecodes::_goto_w : // fall through
|
case Bytecodes::_goto_w : // fall through
|
||||||
case Bytecodes::_jsr_w : {
|
case Bytecodes::_jsr_w : {
|
||||||
int old_ofs = _s_old->bytecode()->get_offset_s4(c_old);
|
int old_ofs = _s_old->bytecode().get_offset_s4(c_old);
|
||||||
int new_ofs = _s_new->bytecode()->get_offset_s4(c_new);
|
int new_ofs = _s_new->bytecode().get_offset_s4(c_new);
|
||||||
if (_switchable_test) {
|
if (_switchable_test) {
|
||||||
int old_dest = _s_old->bci() + old_ofs;
|
int old_dest = _s_old->bci() + old_ofs;
|
||||||
int new_dest = _s_new->bci() + new_ofs;
|
int new_dest = _s_new->bci() + new_ofs;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -395,8 +395,8 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||||
{
|
{
|
||||||
HandleMark hm;
|
HandleMark hm;
|
||||||
methodHandle method(thread, array->element(0)->method());
|
methodHandle method(thread, array->element(0)->method());
|
||||||
Bytecode_invoke* invoke = Bytecode_invoke_at_check(method, array->element(0)->bci());
|
Bytecode_invoke invoke = Bytecode_invoke_check(method, array->element(0)->bci());
|
||||||
return_type = (invoke != NULL) ? invoke->result_type(thread) : T_ILLEGAL;
|
return_type = invoke.is_valid() ? invoke.result_type(thread) : T_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute information for handling adapters and adjusting the frame size of the caller.
|
// Compute information for handling adapters and adjusting the frame size of the caller.
|
||||||
|
@ -600,8 +600,8 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||||
cur_code == Bytecodes::_invokespecial ||
|
cur_code == Bytecodes::_invokespecial ||
|
||||||
cur_code == Bytecodes::_invokestatic ||
|
cur_code == Bytecodes::_invokestatic ||
|
||||||
cur_code == Bytecodes::_invokeinterface) {
|
cur_code == Bytecodes::_invokeinterface) {
|
||||||
Bytecode_invoke* invoke = Bytecode_invoke_at(mh, iframe->interpreter_frame_bci());
|
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
|
||||||
symbolHandle signature(thread, invoke->signature());
|
symbolHandle signature(thread, invoke.signature());
|
||||||
ArgumentSizeComputer asc(signature);
|
ArgumentSizeComputer asc(signature);
|
||||||
cur_invoke_parameter_size = asc.size();
|
cur_invoke_parameter_size = asc.size();
|
||||||
if (cur_code != Bytecodes::_invokestatic) {
|
if (cur_code != Bytecodes::_invokestatic) {
|
||||||
|
@ -963,7 +963,7 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re
|
||||||
if (bci == SynchronizationEntryBCI) {
|
if (bci == SynchronizationEntryBCI) {
|
||||||
code_name = "sync entry";
|
code_name = "sync entry";
|
||||||
} else {
|
} else {
|
||||||
Bytecodes::Code code = Bytecodes::code_at(vf->method(), bci);
|
Bytecodes::Code code = vf->method()->code_at(bci);
|
||||||
code_name = Bytecodes::name(code);
|
code_name = Bytecodes::name(code);
|
||||||
}
|
}
|
||||||
tty->print(" - %s", code_name);
|
tty->print(" - %s", code_name);
|
||||||
|
@ -1224,7 +1224,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
|
||||||
ScopeDesc* trap_scope = cvf->scope();
|
ScopeDesc* trap_scope = cvf->scope();
|
||||||
methodHandle trap_method = trap_scope->method();
|
methodHandle trap_method = trap_scope->method();
|
||||||
int trap_bci = trap_scope->bci();
|
int trap_bci = trap_scope->bci();
|
||||||
Bytecodes::Code trap_bc = Bytecode_at(trap_method->bcp_from(trap_bci))->java_code();
|
Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci);
|
||||||
|
|
||||||
// Record this event in the histogram.
|
// Record this event in the histogram.
|
||||||
gather_statistics(reason, action, trap_bc);
|
gather_statistics(reason, action, trap_bc);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -930,10 +930,10 @@ void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool quer
|
||||||
// This is used sometimes for calling into the VM, not for another
|
// This is used sometimes for calling into the VM, not for another
|
||||||
// interpreted or compiled frame.
|
// interpreted or compiled frame.
|
||||||
if (!m->is_native()) {
|
if (!m->is_native()) {
|
||||||
Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci);
|
Bytecode_invoke call = Bytecode_invoke_check(m, bci);
|
||||||
if (call != NULL) {
|
if (call.is_valid()) {
|
||||||
signature = symbolHandle(thread, call->signature());
|
signature = symbolHandle(thread, call.signature());
|
||||||
has_receiver = call->has_receiver();
|
has_receiver = call.has_receiver();
|
||||||
if (map->include_argument_oops() &&
|
if (map->include_argument_oops() &&
|
||||||
interpreter_frame_expression_stack_size() > 0) {
|
interpreter_frame_expression_stack_size() > 0) {
|
||||||
ResourceMark rm(thread); // is this right ???
|
ResourceMark rm(thread); // is this right ???
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -106,7 +106,7 @@ class Relocator : public ResourceObj {
|
||||||
// get the address of in the code_array
|
// get the address of in the code_array
|
||||||
inline char* addr_at(int bci) const { return (char*) &code_array()[bci]; }
|
inline char* addr_at(int bci) const { return (char*) &code_array()[bci]; }
|
||||||
|
|
||||||
int instruction_length_at(int bci) { return Bytecodes::length_at(code_array() + bci); }
|
int instruction_length_at(int bci) { return Bytecodes::length_at(_method(), code_array() + bci); }
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
int align(int n) const { return (n+3) & ~3; }
|
int align(int n) const { return (n+3) & ~3; }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -944,9 +944,9 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
|
||||||
int bci = vfst.bci();
|
int bci = vfst.bci();
|
||||||
|
|
||||||
// Find bytecode
|
// Find bytecode
|
||||||
Bytecode_invoke* bytecode = Bytecode_invoke_at(caller, bci);
|
Bytecode_invoke bytecode(caller, bci);
|
||||||
bc = bytecode->java_code();
|
bc = bytecode.java_code();
|
||||||
int bytecode_index = bytecode->index();
|
int bytecode_index = bytecode.index();
|
||||||
|
|
||||||
// Find receiver for non-static call
|
// Find receiver for non-static call
|
||||||
if (bc != Bytecodes::_invokestatic) {
|
if (bc != Bytecodes::_invokestatic) {
|
||||||
|
@ -957,7 +957,7 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
|
||||||
// Caller-frame is a compiled frame
|
// Caller-frame is a compiled frame
|
||||||
frame callerFrame = stubFrame.sender(®_map2);
|
frame callerFrame = stubFrame.sender(®_map2);
|
||||||
|
|
||||||
methodHandle callee = bytecode->static_target(CHECK_(nullHandle));
|
methodHandle callee = bytecode.static_target(CHECK_(nullHandle));
|
||||||
if (callee.is_null()) {
|
if (callee.is_null()) {
|
||||||
THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle);
|
THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle);
|
||||||
}
|
}
|
||||||
|
@ -1674,10 +1674,9 @@ char* SharedRuntime::generate_class_cast_message(
|
||||||
// Get target class name from the checkcast instruction
|
// Get target class name from the checkcast instruction
|
||||||
vframeStream vfst(thread, true);
|
vframeStream vfst(thread, true);
|
||||||
assert(!vfst.at_end(), "Java frame must exist");
|
assert(!vfst.at_end(), "Java frame must exist");
|
||||||
Bytecode_checkcast* cc = Bytecode_checkcast_at(
|
Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci()));
|
||||||
vfst.method()->bcp_from(vfst.bci()));
|
|
||||||
Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at(
|
Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at(
|
||||||
cc->index(), thread));
|
cc.index(), thread));
|
||||||
return generate_class_cast_message(objName, targetKlass->external_name());
|
return generate_class_cast_message(objName, targetKlass->external_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,11 +1710,11 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
|
||||||
const char* targetType = "the required signature";
|
const char* targetType = "the required signature";
|
||||||
vframeStream vfst(thread, true);
|
vframeStream vfst(thread, true);
|
||||||
if (!vfst.at_end()) {
|
if (!vfst.at_end()) {
|
||||||
Bytecode_invoke* call = Bytecode_invoke_at(vfst.method(), vfst.bci());
|
Bytecode_invoke call(vfst.method(), vfst.bci());
|
||||||
methodHandle target;
|
methodHandle target;
|
||||||
{
|
{
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
target = call->static_target(THREAD);
|
target = call.static_target(THREAD);
|
||||||
if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; }
|
if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; }
|
||||||
}
|
}
|
||||||
if (target.not_null()
|
if (target.not_null()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -399,7 +399,7 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
|
||||||
} else if (TraceDeoptimization) {
|
} else if (TraceDeoptimization) {
|
||||||
tty->print(" ");
|
tty->print(" ");
|
||||||
method()->print_value();
|
method()->print_value();
|
||||||
Bytecodes::Code code = Bytecodes::java_code_at(bcp);
|
Bytecodes::Code code = Bytecodes::java_code_at(method(), bcp);
|
||||||
int bci = method()->bci_from(bcp);
|
int bci = method()->bci_from(bcp);
|
||||||
tty->print(" - %s", Bytecodes::name(code));
|
tty->print(" - %s", Bytecodes::name(code));
|
||||||
tty->print(" @ bci %d ", bci);
|
tty->print(" @ bci %d ", bci);
|
||||||
|
|
|
@ -453,7 +453,7 @@ DumpWriter::DumpWriter(const char* path) {
|
||||||
|
|
||||||
DumpWriter::~DumpWriter() {
|
DumpWriter::~DumpWriter() {
|
||||||
// flush and close dump file
|
// flush and close dump file
|
||||||
if (file_descriptor() >= 0) {
|
if (is_open()) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
if (_buffer != NULL) os::free(_buffer);
|
if (_buffer != NULL) os::free(_buffer);
|
||||||
|
@ -463,9 +463,10 @@ DumpWriter::~DumpWriter() {
|
||||||
// closes dump file (if open)
|
// closes dump file (if open)
|
||||||
void DumpWriter::close() {
|
void DumpWriter::close() {
|
||||||
// flush and close dump file
|
// flush and close dump file
|
||||||
if (file_descriptor() >= 0) {
|
if (is_open()) {
|
||||||
flush();
|
flush();
|
||||||
::close(file_descriptor());
|
::close(file_descriptor());
|
||||||
|
set_file_descriptor(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1935,18 +1936,32 @@ void HeapDumper::dump_heap() {
|
||||||
void HeapDumper::dump_heap(bool oome) {
|
void HeapDumper::dump_heap(bool oome) {
|
||||||
static char base_path[JVM_MAXPATHLEN] = {'\0'};
|
static char base_path[JVM_MAXPATHLEN] = {'\0'};
|
||||||
static uint dump_file_seq = 0;
|
static uint dump_file_seq = 0;
|
||||||
char my_path[JVM_MAXPATHLEN] = {'\0'};
|
char* my_path;
|
||||||
|
const int max_digit_chars = 20;
|
||||||
|
|
||||||
|
const char* dump_file_name = "java_pid";
|
||||||
|
const char* dump_file_ext = ".hprof";
|
||||||
|
|
||||||
// The dump file defaults to java_pid<pid>.hprof in the current working
|
// The dump file defaults to java_pid<pid>.hprof in the current working
|
||||||
// directory. HeapDumpPath=<file> can be used to specify an alternative
|
// directory. HeapDumpPath=<file> can be used to specify an alternative
|
||||||
// dump file name or a directory where dump file is created.
|
// dump file name or a directory where dump file is created.
|
||||||
if (dump_file_seq == 0) { // first time in, we initialize base_path
|
if (dump_file_seq == 0) { // first time in, we initialize base_path
|
||||||
|
// Calculate potentially longest base path and check if we have enough
|
||||||
|
// allocated statically.
|
||||||
|
const size_t total_length =
|
||||||
|
(HeapDumpPath == NULL ? 0 : strlen(HeapDumpPath)) +
|
||||||
|
strlen(os::file_separator()) + max_digit_chars +
|
||||||
|
strlen(dump_file_name) + strlen(dump_file_ext) + 1;
|
||||||
|
if (total_length > sizeof(base_path)) {
|
||||||
|
warning("Cannot create heap dump file. HeapDumpPath is too long.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool use_default_filename = true;
|
bool use_default_filename = true;
|
||||||
if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
|
if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
|
||||||
// HeapDumpPath=<file> not specified
|
// HeapDumpPath=<file> not specified
|
||||||
} else {
|
} else {
|
||||||
assert(strlen(HeapDumpPath) < sizeof(base_path), "HeapDumpPath too long");
|
strncpy(base_path, HeapDumpPath, sizeof(base_path));
|
||||||
strcpy(base_path, HeapDumpPath);
|
|
||||||
// check if the path is a directory (must exist)
|
// check if the path is a directory (must exist)
|
||||||
DIR* dir = os::opendir(base_path);
|
DIR* dir = os::opendir(base_path);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
|
@ -1960,8 +1975,6 @@ void HeapDumper::dump_heap(bool oome) {
|
||||||
char* end = base_path;
|
char* end = base_path;
|
||||||
end += (strlen(base_path) - fs_len);
|
end += (strlen(base_path) - fs_len);
|
||||||
if (strcmp(end, os::file_separator()) != 0) {
|
if (strcmp(end, os::file_separator()) != 0) {
|
||||||
assert(strlen(base_path) + strlen(os::file_separator()) < sizeof(base_path),
|
|
||||||
"HeapDumpPath too long");
|
|
||||||
strcat(base_path, os::file_separator());
|
strcat(base_path, os::file_separator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1969,21 +1982,26 @@ void HeapDumper::dump_heap(bool oome) {
|
||||||
}
|
}
|
||||||
// If HeapDumpPath wasn't a file name then we append the default name
|
// If HeapDumpPath wasn't a file name then we append the default name
|
||||||
if (use_default_filename) {
|
if (use_default_filename) {
|
||||||
char fn[32];
|
const size_t dlen = strlen(base_path); // if heap dump dir specified
|
||||||
sprintf(fn, "java_pid%d", os::current_process_id());
|
jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s",
|
||||||
assert(strlen(base_path) + strlen(fn) + strlen(".hprof") < sizeof(base_path), "HeapDumpPath too long");
|
dump_file_name, os::current_process_id(), dump_file_ext);
|
||||||
strcat(base_path, fn);
|
|
||||||
strcat(base_path, ".hprof");
|
|
||||||
}
|
}
|
||||||
assert(strlen(base_path) < sizeof(my_path), "Buffer too small");
|
const size_t len = strlen(base_path) + 1;
|
||||||
strcpy(my_path, base_path);
|
my_path = (char*)os::malloc(len);
|
||||||
|
if (my_path == NULL) {
|
||||||
|
warning("Cannot create heap dump file. Out of system memory.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strncpy(my_path, base_path, len);
|
||||||
} else {
|
} else {
|
||||||
// Append a sequence number id for dumps following the first
|
// Append a sequence number id for dumps following the first
|
||||||
char fn[33];
|
const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
|
||||||
sprintf(fn, ".%d", dump_file_seq);
|
my_path = (char*)os::malloc(len);
|
||||||
assert(strlen(base_path) + strlen(fn) < sizeof(my_path), "HeapDumpPath too long");
|
if (my_path == NULL) {
|
||||||
strcpy(my_path, base_path);
|
warning("Cannot create heap dump file. Out of system memory.");
|
||||||
strcat(my_path, fn);
|
return;
|
||||||
|
}
|
||||||
|
jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq);
|
||||||
}
|
}
|
||||||
dump_file_seq++; // increment seq number for next time we dump
|
dump_file_seq++; // increment seq number for next time we dump
|
||||||
|
|
||||||
|
@ -1991,4 +2009,5 @@ void HeapDumper::dump_heap(bool oome) {
|
||||||
true /* send to tty */,
|
true /* send to tty */,
|
||||||
oome /* pass along out-of-memory-error flag */);
|
oome /* pass along out-of-memory-error flag */);
|
||||||
dumper.dump(my_path);
|
dumper.dump(my_path);
|
||||||
|
os::free(my_path);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue