Mercurial > hg > truffle
comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 12882:ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
Summary: x86 interpreter and c1 type profiling for return values at calls
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Sat, 12 Oct 2013 12:12:59 +0200 |
parents | d13d7aba8c12 |
children | 5ccbab1c69f3 |
comparison
equal
deleted
inserted
replaced
12881:ed2c74787eb5 | 12882:ce0cc25bc5e2 |
---|---|
1464 } | 1464 } |
1465 | 1465 |
1466 // State at end of inlined method is the state of the caller | 1466 // State at end of inlined method is the state of the caller |
1467 // without the method parameters on stack, including the | 1467 // without the method parameters on stack, including the |
1468 // return value, if any, of the inlined method on operand stack. | 1468 // return value, if any, of the inlined method on operand stack. |
1469 int invoke_bci = state()->caller_state()->bci(); | |
1469 set_state(state()->caller_state()->copy_for_parsing()); | 1470 set_state(state()->caller_state()->copy_for_parsing()); |
1470 if (x != NULL) { | 1471 if (x != NULL) { |
1471 state()->push(x->type(), x); | 1472 state()->push(x->type(), x); |
1473 if (profile_calls() && MethodData::profile_return() && x->type()->is_object_kind()) { | |
1474 ciMethod* caller = state()->scope()->method(); | |
1475 ciMethodData* md = caller->method_data_or_null(); | |
1476 ciProfileData* data = md->bci_to_data(invoke_bci); | |
1477 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | |
1478 bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return(); | |
1479 // May not be true in case of an inlined call through a method handle intrinsic. | |
1480 if (has_return) { | |
1481 profile_return_type(x, method(), caller, invoke_bci); | |
1482 } | |
1483 } | |
1484 } | |
1472 } | 1485 } |
1473 Goto* goto_callee = new Goto(continuation(), false); | 1486 Goto* goto_callee = new Goto(continuation(), false); |
1474 | 1487 |
1475 // See whether this is the first return; if so, store off some | 1488 // See whether this is the first return; if so, store off some |
1476 // of the state for later examination | 1489 // of the state for later examination |
2005 if (method()->is_strict()) { | 2018 if (method()->is_strict()) { |
2006 push(result_type, round_fp(result)); | 2019 push(result_type, round_fp(result)); |
2007 } else { | 2020 } else { |
2008 push(result_type, result); | 2021 push(result_type, result); |
2009 } | 2022 } |
2023 } | |
2024 if (profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { | |
2025 profile_return_type(result, target); | |
2010 } | 2026 } |
2011 } | 2027 } |
2012 | 2028 |
2013 | 2029 |
2014 void GraphBuilder::new_instance(int klass_index) { | 2030 void GraphBuilder::new_instance(int klass_index) { |
3554 preserves_state, cantrap); | 3570 preserves_state, cantrap); |
3555 // append instruction & push result | 3571 // append instruction & push result |
3556 Value value = append_split(result); | 3572 Value value = append_split(result); |
3557 if (result_type != voidType) push(result_type, value); | 3573 if (result_type != voidType) push(result_type, value); |
3558 | 3574 |
3575 if (callee != method() && profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { | |
3576 profile_return_type(result, callee); | |
3577 } | |
3578 | |
3559 // done | 3579 // done |
3560 return true; | 3580 return true; |
3561 } | 3581 } |
3562 | 3582 |
3563 | 3583 |
4310 | 4330 |
4311 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { | 4331 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { |
4312 append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); | 4332 append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); |
4313 } | 4333 } |
4314 | 4334 |
4335 void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m, int invoke_bci) { | |
4336 assert((m == NULL) == (invoke_bci < 0), "invalid method and invalid bci together"); | |
4337 if (m == NULL) { | |
4338 m = method(); | |
4339 } | |
4340 if (invoke_bci < 0) { | |
4341 invoke_bci = bci(); | |
4342 } | |
4343 ciMethodData* md = m->method_data_or_null(); | |
4344 ciProfileData* data = md->bci_to_data(invoke_bci); | |
4345 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | |
4346 append(new ProfileReturnType(m , invoke_bci, callee, ret)); | |
4347 } | |
4348 } | |
4349 | |
4315 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { | 4350 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { |
4316 append(new ProfileInvoke(callee, state)); | 4351 append(new ProfileInvoke(callee, state)); |
4317 } | 4352 } |