Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_LinearScan.cpp @ 1819:f02a8bbe6ed4
6986046: C1 valuestack cleanup
Summary: fixes an historical oddity in C1 with inlining where all of the expression stacks are kept in the topmost ValueStack instead of being in their respective ValueStacks.
Reviewed-by: never
Contributed-by: Christian Wimmer <cwimmer@uci.edu>
author | roland |
---|---|
date | Tue, 29 Dec 2009 19:08:54 +0100 |
parents | 87b64980e2f1 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1817:c40600e85311 | 1819:f02a8bbe6ed4 |
---|---|
2272 assert(d1->caller() == NULL && d2->caller() == NULL, "not equal"); | 2272 assert(d1->caller() == NULL && d2->caller() == NULL, "not equal"); |
2273 } | 2273 } |
2274 } | 2274 } |
2275 | 2275 |
2276 void check_stack_depth(CodeEmitInfo* info, int stack_end) { | 2276 void check_stack_depth(CodeEmitInfo* info, int stack_end) { |
2277 if (info->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) { | 2277 if (info->stack()->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) { |
2278 Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->bci()); | 2278 Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci()); |
2279 switch (code) { | 2279 switch (code) { |
2280 case Bytecodes::_ifnull : // fall through | 2280 case Bytecodes::_ifnull : // fall through |
2281 case Bytecodes::_ifnonnull : // fall through | 2281 case Bytecodes::_ifnonnull : // fall through |
2282 case Bytecodes::_ifeq : // fall through | 2282 case Bytecodes::_ifeq : // fall through |
2283 case Bytecodes::_ifne : // fall through | 2283 case Bytecodes::_ifne : // fall through |
2377 } | 2377 } |
2378 } | 2378 } |
2379 | 2379 |
2380 // add oops from lock stack | 2380 // add oops from lock stack |
2381 assert(info->stack() != NULL, "CodeEmitInfo must always have a stack"); | 2381 assert(info->stack() != NULL, "CodeEmitInfo must always have a stack"); |
2382 int locks_count = info->stack()->locks_size(); | 2382 int locks_count = info->stack()->total_locks_size(); |
2383 for (int i = 0; i < locks_count; i++) { | 2383 for (int i = 0; i < locks_count; i++) { |
2384 map->set_oop(frame_map()->monitor_object_regname(i)); | 2384 map->set_oop(frame_map()->monitor_object_regname(i)); |
2385 } | 2385 } |
2386 | 2386 |
2387 return map; | 2387 return map; |
2760 return 1; | 2760 return 1; |
2761 } | 2761 } |
2762 } | 2762 } |
2763 | 2763 |
2764 | 2764 |
2765 IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state, int cur_bci, int stack_end, int locks_end) { | 2765 IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state) { |
2766 IRScopeDebugInfo* caller_debug_info = NULL; | 2766 IRScopeDebugInfo* caller_debug_info = NULL; |
2767 int stack_begin, locks_begin; | 2767 |
2768 | 2768 ValueStack* caller_state = cur_state->caller_state(); |
2769 ValueStack* caller_state = cur_scope->caller_state(); | |
2770 if (caller_state != NULL) { | 2769 if (caller_state != NULL) { |
2771 // process recursively to compute outermost scope first | 2770 // process recursively to compute outermost scope first |
2772 stack_begin = caller_state->stack_size(); | 2771 caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state); |
2773 locks_begin = caller_state->locks_size(); | |
2774 caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state, cur_scope->caller_bci(), stack_begin, locks_begin); | |
2775 } else { | |
2776 stack_begin = 0; | |
2777 locks_begin = 0; | |
2778 } | 2772 } |
2779 | 2773 |
2780 // initialize these to null. | 2774 // initialize these to null. |
2781 // If we don't need deopt info or there are no locals, expressions or monitors, | 2775 // If we don't need deopt info or there are no locals, expressions or monitors, |
2782 // then these get recorded as no information and avoids the allocation of 0 length arrays. | 2776 // then these get recorded as no information and avoids the allocation of 0 length arrays. |
2783 GrowableArray<ScopeValue*>* locals = NULL; | 2777 GrowableArray<ScopeValue*>* locals = NULL; |
2784 GrowableArray<ScopeValue*>* expressions = NULL; | 2778 GrowableArray<ScopeValue*>* expressions = NULL; |
2785 GrowableArray<MonitorValue*>* monitors = NULL; | 2779 GrowableArray<MonitorValue*>* monitors = NULL; |
2786 | 2780 |
2787 // describe local variable values | 2781 // describe local variable values |
2788 int nof_locals = cur_scope->method()->max_locals(); | 2782 int nof_locals = cur_state->locals_size(); |
2789 if (nof_locals > 0) { | 2783 if (nof_locals > 0) { |
2790 locals = new GrowableArray<ScopeValue*>(nof_locals); | 2784 locals = new GrowableArray<ScopeValue*>(nof_locals); |
2791 | 2785 |
2792 int pos = 0; | 2786 int pos = 0; |
2793 while (pos < nof_locals) { | 2787 while (pos < nof_locals) { |
2798 | 2792 |
2799 assert(locals->length() == pos, "must match"); | 2793 assert(locals->length() == pos, "must match"); |
2800 } | 2794 } |
2801 assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals"); | 2795 assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals"); |
2802 assert(locals->length() == cur_state->locals_size(), "wrong number of locals"); | 2796 assert(locals->length() == cur_state->locals_size(), "wrong number of locals"); |
2803 } | 2797 } else if (cur_scope->method()->max_locals() > 0) { |
2804 | 2798 assert(cur_state->kind() == ValueStack::EmptyExceptionState, "should be"); |
2799 nof_locals = cur_scope->method()->max_locals(); | |
2800 locals = new GrowableArray<ScopeValue*>(nof_locals); | |
2801 for(int i = 0; i < nof_locals; i++) { | |
2802 locals->append(&_illegal_value); | |
2803 } | |
2804 } | |
2805 | 2805 |
2806 // describe expression stack | 2806 // describe expression stack |
2807 // | 2807 int nof_stack = cur_state->stack_size(); |
2808 // When we inline methods containing exception handlers, the | |
2809 // "lock_stacks" are changed to preserve expression stack values | |
2810 // in caller scopes when exception handlers are present. This | |
2811 // can cause callee stacks to be smaller than caller stacks. | |
2812 if (stack_end > innermost_state->stack_size()) { | |
2813 stack_end = innermost_state->stack_size(); | |
2814 } | |
2815 | |
2816 | |
2817 | |
2818 int nof_stack = stack_end - stack_begin; | |
2819 if (nof_stack > 0) { | 2808 if (nof_stack > 0) { |
2820 expressions = new GrowableArray<ScopeValue*>(nof_stack); | 2809 expressions = new GrowableArray<ScopeValue*>(nof_stack); |
2821 | 2810 |
2822 int pos = stack_begin; | 2811 int pos = 0; |
2823 while (pos < stack_end) { | 2812 while (pos < nof_stack) { |
2824 Value expression = innermost_state->stack_at_inc(pos); | 2813 Value expression = cur_state->stack_at_inc(pos); |
2825 append_scope_value(op_id, expression, expressions); | 2814 append_scope_value(op_id, expression, expressions); |
2826 | 2815 |
2827 assert(expressions->length() + stack_begin == pos, "must match"); | 2816 assert(expressions->length() == pos, "must match"); |
2828 } | 2817 } |
2818 assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries"); | |
2829 } | 2819 } |
2830 | 2820 |
2831 // describe monitors | 2821 // describe monitors |
2832 assert(locks_begin <= locks_end, "error in scope iteration"); | 2822 int nof_locks = cur_state->locks_size(); |
2833 int nof_locks = locks_end - locks_begin; | |
2834 if (nof_locks > 0) { | 2823 if (nof_locks > 0) { |
2824 int lock_offset = cur_state->caller_state() != NULL ? cur_state->caller_state()->total_locks_size() : 0; | |
2835 monitors = new GrowableArray<MonitorValue*>(nof_locks); | 2825 monitors = new GrowableArray<MonitorValue*>(nof_locks); |
2836 for (int i = locks_begin; i < locks_end; i++) { | 2826 for (int i = 0; i < nof_locks; i++) { |
2837 monitors->append(location_for_monitor_index(i)); | 2827 monitors->append(location_for_monitor_index(lock_offset + i)); |
2838 } | 2828 } |
2839 } | 2829 } |
2840 | 2830 |
2841 return new IRScopeDebugInfo(cur_scope, cur_bci, locals, expressions, monitors, caller_debug_info); | 2831 return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info); |
2842 } | 2832 } |
2843 | 2833 |
2844 | 2834 |
2845 void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) { | 2835 void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) { |
2846 TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id)); | 2836 TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id)); |
2848 IRScope* innermost_scope = info->scope(); | 2838 IRScope* innermost_scope = info->scope(); |
2849 ValueStack* innermost_state = info->stack(); | 2839 ValueStack* innermost_state = info->stack(); |
2850 | 2840 |
2851 assert(innermost_scope != NULL && innermost_state != NULL, "why is it missing?"); | 2841 assert(innermost_scope != NULL && innermost_state != NULL, "why is it missing?"); |
2852 | 2842 |
2853 int stack_end = innermost_state->stack_size(); | 2843 DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size())); |
2854 int locks_end = innermost_state->locks_size(); | |
2855 | |
2856 DEBUG_ONLY(check_stack_depth(info, stack_end)); | |
2857 | 2844 |
2858 if (info->_scope_debug_info == NULL) { | 2845 if (info->_scope_debug_info == NULL) { |
2859 // compute debug information | 2846 // compute debug information |
2860 info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state, info->bci(), stack_end, locks_end); | 2847 info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state); |
2861 } else { | 2848 } else { |
2862 // debug information already set. Check that it is correct from the current point of view | 2849 // debug information already set. Check that it is correct from the current point of view |
2863 DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state, info->bci(), stack_end, locks_end))); | 2850 DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state))); |
2864 } | 2851 } |
2865 } | 2852 } |
2866 | 2853 |
2867 | 2854 |
2868 void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { | 2855 void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { |