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) {