提交 d5dc0872 编写于 作者: T twisti

7192167: JSR 292: C1 has old broken code which needs to be removed

Reviewed-by: kvn, roland, jrose
上级 eaf72684
...@@ -1646,10 +1646,6 @@ Dependencies* GraphBuilder::dependency_recorder() const { ...@@ -1646,10 +1646,6 @@ Dependencies* GraphBuilder::dependency_recorder() const {
void GraphBuilder::invoke(Bytecodes::Code code) { void GraphBuilder::invoke(Bytecodes::Code code) {
const bool has_receiver =
code == Bytecodes::_invokespecial ||
code == Bytecodes::_invokevirtual ||
code == Bytecodes::_invokeinterface;
const bool is_invokedynamic = (code == Bytecodes::_invokedynamic); const bool is_invokedynamic = (code == Bytecodes::_invokedynamic);
bool will_link; bool will_link;
...@@ -1690,8 +1686,12 @@ void GraphBuilder::invoke(Bytecodes::Code code) { ...@@ -1690,8 +1686,12 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// convert them directly to an invokespecial or invokestatic. // convert them directly to an invokespecial or invokestatic.
if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) { if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
switch (bc_raw) { switch (bc_raw) {
case Bytecodes::_invokevirtual: code = Bytecodes::_invokespecial; break; case Bytecodes::_invokevirtual:
case Bytecodes::_invokehandle: code = Bytecodes::_invokestatic; break; code = Bytecodes::_invokespecial;
break;
case Bytecodes::_invokehandle:
code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
break;
} }
} }
...@@ -1878,11 +1878,13 @@ void GraphBuilder::invoke(Bytecodes::Code code) { ...@@ -1878,11 +1878,13 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// inlining not successful => standard invoke // inlining not successful => standard invoke
bool is_loaded = target->is_loaded(); bool is_loaded = target->is_loaded();
ValueType* result_type = as_ValueType(target->return_type()); ValueType* result_type = as_ValueType(target->return_type());
ValueStack* state_before = copy_state_exhandling();
// We require the debug info to be the "state before" because // The bytecode (code) might change in this method so we are checking this very late.
// invokedynamics may deoptimize. const bool has_receiver =
ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling(); code == Bytecodes::_invokespecial ||
code == Bytecodes::_invokevirtual ||
code == Bytecodes::_invokeinterface;
Values* args = state()->pop_arguments(target->arg_size_no_receiver()); Values* args = state()->pop_arguments(target->arg_size_no_receiver());
Value recv = has_receiver ? apop() : NULL; Value recv = has_receiver ? apop() : NULL;
int vtable_index = methodOopDesc::invalid_vtable_index; int vtable_index = methodOopDesc::invalid_vtable_index;
......
...@@ -369,9 +369,6 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* ...@@ -369,9 +369,6 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values*
_signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0)); _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0));
if (has_receiver()) { if (has_receiver()) {
_signature->append(as_BasicType(receiver()->type())); _signature->append(as_BasicType(receiver()->type()));
} else if (is_invokedynamic()) {
// Add the synthetic MethodHandle argument to the signature.
_signature->append(T_OBJECT);
} }
for (int i = 0; i < number_of_arguments(); i++) { for (int i = 0; i < number_of_arguments(); i++) {
ValueType* t = argument_at(i)->type(); ValueType* t = argument_at(i)->type();
......
...@@ -448,10 +448,10 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { ...@@ -448,10 +448,10 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
switch (op->code()) { switch (op->code()) {
case lir_static_call: case lir_static_call:
case lir_dynamic_call:
call(op, relocInfo::static_call_type); call(op, relocInfo::static_call_type);
break; break;
case lir_optvirtual_call: case lir_optvirtual_call:
case lir_dynamic_call:
call(op, relocInfo::opt_virtual_call_type); call(op, relocInfo::opt_virtual_call_type);
break; break;
case lir_icvirtual_call: case lir_icvirtual_call:
...@@ -460,7 +460,9 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { ...@@ -460,7 +460,9 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
case lir_virtual_call: case lir_virtual_call:
vtable_call(op); vtable_call(op);
break; break;
default: ShouldNotReachHere(); default:
fatal(err_msg_res("unexpected op code: %s", op->name()));
break;
} }
// JSR 292 // JSR 292
......
...@@ -920,7 +920,8 @@ LIR_Opr LIRGenerator::round_item(LIR_Opr opr) { ...@@ -920,7 +920,8 @@ LIR_Opr LIRGenerator::round_item(LIR_Opr opr) {
LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) { LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
assert(type2size[t] == type2size[value->type()], "size mismatch"); assert(type2size[t] == type2size[value->type()],
err_msg_res("size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type())));
if (!value->is_register()) { if (!value->is_register()) {
// force into a register // force into a register
LIR_Opr r = new_register(value->type()); LIR_Opr r = new_register(value->type());
...@@ -2662,8 +2663,9 @@ void LIRGenerator::do_OsrEntry(OsrEntry* x) { ...@@ -2662,8 +2663,9 @@ void LIRGenerator::do_OsrEntry(OsrEntry* x) {
void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) { void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0; assert(args->length() == arg_list->length(),
for (; i < args->length(); i++) { err_msg_res("args=%d, arg_list=%d", args->length(), arg_list->length()));
for (int i = x->has_receiver() ? 1 : 0; i < args->length(); i++) {
LIRItem* param = args->at(i); LIRItem* param = args->at(i);
LIR_Opr loc = arg_list->at(i); LIR_Opr loc = arg_list->at(i);
if (loc->is_register()) { if (loc->is_register()) {
...@@ -2703,15 +2705,9 @@ LIRItemList* LIRGenerator::invoke_visit_arguments(Invoke* x) { ...@@ -2703,15 +2705,9 @@ LIRItemList* LIRGenerator::invoke_visit_arguments(Invoke* x) {
LIRItem* receiver = new LIRItem(x->receiver(), this); LIRItem* receiver = new LIRItem(x->receiver(), this);
argument_items->append(receiver); argument_items->append(receiver);
} }
if (x->is_invokedynamic()) {
// Insert a dummy for the synthetic MethodHandle argument.
argument_items->append(NULL);
}
int idx = x->has_receiver() ? 1 : 0;
for (int i = 0; i < x->number_of_arguments(); i++) { for (int i = 0; i < x->number_of_arguments(); i++) {
LIRItem* param = new LIRItem(x->argument_at(i), this); LIRItem* param = new LIRItem(x->argument_at(i), this);
argument_items->append(param); argument_items->append(param);
idx += (param->type()->is_double_word() ? 2 : 1);
} }
return argument_items; return argument_items;
} }
...@@ -2756,9 +2752,6 @@ void LIRGenerator::do_Invoke(Invoke* x) { ...@@ -2756,9 +2752,6 @@ void LIRGenerator::do_Invoke(Invoke* x) {
CodeEmitInfo* info = state_for(x, x->state()); CodeEmitInfo* info = state_for(x, x->state());
// invokedynamics can deoptimize.
CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL;
invoke_load_arguments(x, args, arg_list); invoke_load_arguments(x, args, arg_list);
if (x->has_receiver()) { if (x->has_receiver()) {
...@@ -2807,41 +2800,8 @@ void LIRGenerator::do_Invoke(Invoke* x) { ...@@ -2807,41 +2800,8 @@ void LIRGenerator::do_Invoke(Invoke* x) {
} }
break; break;
case Bytecodes::_invokedynamic: { case Bytecodes::_invokedynamic: {
ciBytecodeStream bcs(x->scope()->method());
bcs.force_bci(x->state()->bci());
assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
ciCPCache* cpcache = bcs.get_cpcache();
// Get CallSite offset from constant pool cache pointer.
int index = bcs.get_method_index();
size_t call_site_offset = cpcache->get_f1_offset(index);
// Load CallSite object from constant pool cache.
LIR_Opr call_site = new_register(objectType);
__ oop2reg(cpcache->constant_encoding(), call_site);
__ move_wide(new LIR_Address(call_site, call_site_offset, T_OBJECT), call_site);
// If this invokedynamic call site hasn't been executed yet in
// the interpreter, the CallSite object in the constant pool
// cache is still null and we need to deoptimize.
if (cpcache->is_f1_null_at(index)) {
// Only deoptimize if the CallSite object is still null; we don't
// recompile methods in C1 after deoptimization so this call site
// might be resolved the next time we execute it after OSR.
DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
__ cmp(lir_cond_equal, call_site, LIR_OprFact::oopConst(NULL));
__ branch(lir_cond_equal, T_OBJECT, deopt_stub);
}
// Use the receiver register for the synthetic MethodHandle
// argument.
receiver = LIR_Assembler::receiverOpr();
// Load target MethodHandle from CallSite object.
__ load(new LIR_Address(call_site, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
__ call_dynamic(target, receiver, result_register, __ call_dynamic(target, receiver, result_register,
SharedRuntime::get_resolve_opt_virtual_call_stub(), SharedRuntime::get_resolve_static_call_stub(),
arg_list, info); arg_list, info);
break; break;
} }
......
...@@ -158,74 +158,6 @@ JVMState* DirectCallGenerator::generate(JVMState* jvms) { ...@@ -158,74 +158,6 @@ JVMState* DirectCallGenerator::generate(JVMState* jvms) {
return kit.transfer_exceptions_into_jvms(); return kit.transfer_exceptions_into_jvms();
} }
//---------------------------DynamicCallGenerator-----------------------------
// Internal class which handles all out-of-line invokedynamic calls.
class DynamicCallGenerator : public CallGenerator {
public:
DynamicCallGenerator(ciMethod* method)
: CallGenerator(method)
{
}
virtual JVMState* generate(JVMState* jvms);
};
JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
Compile* C = kit.C;
PhaseGVN& gvn = kit.gvn();
if (C->log() != NULL) {
C->log()->elem("dynamic_call bci='%d'", jvms->bci());
}
// Get the constant pool cache from the caller class.
ciMethod* caller_method = jvms->method();
ciBytecodeStream str(caller_method);
str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
ciCPCache* cpcache = str.get_cpcache();
// Get the offset of the CallSite from the constant pool cache
// pointer.
int index = str.get_method_index();
size_t call_site_offset = cpcache->get_f1_offset(index);
// Load the CallSite object from the constant pool cache.
const TypeOopPtr* cpcache_type = TypeOopPtr::make_from_constant(cpcache); // returns TypeAryPtr of type T_OBJECT
const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
Node* cpcache_adr = kit.makecon(cpcache_type);
Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
// The oops in the constant pool cache are not compressed; load then as raw pointers.
Node* call_site = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
// Load the target MethodHandle from the CallSite object.
const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
Node* target_mh = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT);
address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
// invokedynamic is treated as an optimized invokevirtual.
call->set_optimized_virtual(true);
// Take extra care (in the presence of argument motion) not to trash the SP:
call->set_method_handle_invoke(true);
// Pass the target MethodHandle as first argument and shift the
// other arguments.
call->init_req(0 + TypeFunc::Parms, target_mh);
uint nargs = call->method()->arg_size();
for (uint i = 1; i < nargs; i++) {
Node* arg = kit.argument(i - 1);
call->init_req(i + TypeFunc::Parms, arg);
}
kit.set_edges_for_java_call(call);
Node* ret = kit.set_results_for_java_call(call);
kit.push_node(method()->return_type()->basic_type(), ret);
return kit.transfer_exceptions_into_jvms();
}
//--------------------------VirtualCallGenerator------------------------------ //--------------------------VirtualCallGenerator------------------------------
// Internal class which handles all out-of-line calls checking receiver type. // Internal class which handles all out-of-line calls checking receiver type.
class VirtualCallGenerator : public CallGenerator { class VirtualCallGenerator : public CallGenerator {
...@@ -328,12 +260,6 @@ CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { ...@@ -328,12 +260,6 @@ CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
return new VirtualCallGenerator(m, vtable_index); return new VirtualCallGenerator(m, vtable_index);
} }
CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
assert(m->is_compiled_lambda_form(), "for_dynamic_call mismatch");
//@@ FIXME: this should be done via a direct call
return new DynamicCallGenerator(m);
}
// Allow inlining decisions to be delayed // Allow inlining decisions to be delayed
class LateInlineCallGenerator : public DirectCallGenerator { class LateInlineCallGenerator : public DirectCallGenerator {
CallGenerator* _inline_cg; CallGenerator* _inline_cg;
...@@ -347,7 +273,7 @@ class LateInlineCallGenerator : public DirectCallGenerator { ...@@ -347,7 +273,7 @@ class LateInlineCallGenerator : public DirectCallGenerator {
// Convert the CallStaticJava into an inline // Convert the CallStaticJava into an inline
virtual void do_late_inline(); virtual void do_late_inline();
JVMState* generate(JVMState* jvms) { virtual JVMState* generate(JVMState* jvms) {
// Record that this call site should be revisited once the main // Record that this call site should be revisited once the main
// parse is finished. // parse is finished.
Compile::current()->add_late_inline(this); Compile::current()->add_late_inline(this);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册