1 | /* |
2 | * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "opto/regalloc.hpp" |
27 | |
28 | static const int NodeRegsOverflowSize = 200; |
29 | |
30 | void (*PhaseRegAlloc::_alloc_statistics[MAX_REG_ALLOCATORS])(); |
31 | int PhaseRegAlloc::_num_allocators = 0; |
32 | #ifndef PRODUCT |
33 | int PhaseRegAlloc::_total_framesize = 0; |
34 | int PhaseRegAlloc::_max_framesize = 0; |
35 | #endif |
36 | |
37 | PhaseRegAlloc::PhaseRegAlloc( uint unique, PhaseCFG &cfg, |
38 | Matcher &matcher, |
39 | void (*pr_stats)() ): |
40 | Phase(Register_Allocation), |
41 | _node_regs(0), |
42 | _node_regs_max_index(0), |
43 | _node_oops(Thread::current()->resource_area()), |
44 | _cfg(cfg), |
45 | _framesize(0xdeadbeef), |
46 | _matcher(matcher) |
47 | { |
48 | int i; |
49 | |
50 | for (i=0; i < _num_allocators; i++) { |
51 | if (_alloc_statistics[i] == pr_stats) |
52 | return; |
53 | } |
54 | assert((_num_allocators + 1) < MAX_REG_ALLOCATORS, "too many register allocators" ); |
55 | _alloc_statistics[_num_allocators++] = pr_stats; |
56 | } |
57 | |
58 | |
59 | //------------------------------reg2offset------------------------------------- |
60 | int PhaseRegAlloc::reg2offset_unchecked( OptoReg::Name reg ) const { |
61 | // Slots below _max_in_arg_stack_reg are offset by the entire frame. |
62 | // Slots above _max_in_arg_stack_reg are frame_slots and are not offset. |
63 | int slot = (reg < _matcher._new_SP) |
64 | ? reg - OptoReg::stack0() + _framesize |
65 | : reg - _matcher._new_SP; |
66 | // Note: We use the direct formula (reg - SharedInfo::stack0) instead of |
67 | // OptoReg::reg2stack(reg), in order to avoid asserts in the latter |
68 | // function. This routine must remain unchecked, so that dump_frame() |
69 | // can do its work undisturbed. |
70 | // %%% not really clear why reg2stack would assert here |
71 | |
72 | return slot*VMRegImpl::stack_slot_size; |
73 | } |
74 | |
75 | int PhaseRegAlloc::reg2offset( OptoReg::Name reg ) const { |
76 | |
77 | // Not allowed in the out-preserve area. |
78 | // In-preserve area is allowed so Intel can fetch the return pc out. |
79 | assert( reg < _matcher._old_SP || |
80 | (reg >= OptoReg::add(_matcher._old_SP,C->out_preserve_stack_slots()) && |
81 | reg < _matcher._in_arg_limit) || |
82 | reg >= OptoReg::add(_matcher._new_SP, C->out_preserve_stack_slots()) || |
83 | // Allow return_addr in the out-preserve area. |
84 | reg == _matcher.return_addr(), |
85 | "register allocated in a preserve area" ); |
86 | return reg2offset_unchecked( reg ); |
87 | } |
88 | |
89 | //------------------------------offset2reg------------------------------------- |
90 | OptoReg::Name PhaseRegAlloc::offset2reg(int stk_offset) const { |
91 | int slot = stk_offset / jintSize; |
92 | int reg = (slot < (int) _framesize) |
93 | ? slot + _matcher._new_SP |
94 | : OptoReg::stack2reg(slot) - _framesize; |
95 | assert(stk_offset == reg2offset((OptoReg::Name) reg), |
96 | "offset2reg does not invert properly" ); |
97 | return (OptoReg::Name) reg; |
98 | } |
99 | |
100 | //------------------------------set_oop---------------------------------------- |
101 | void PhaseRegAlloc::set_oop( const Node *n, bool is_an_oop ) { |
102 | if( is_an_oop ) { |
103 | _node_oops.set(n->_idx); |
104 | } |
105 | } |
106 | |
107 | //------------------------------is_oop----------------------------------------- |
108 | bool PhaseRegAlloc::is_oop( const Node *n ) const { |
109 | return _node_oops.test(n->_idx) != 0; |
110 | } |
111 | |
112 | // Allocate _node_regs table with at least "size" elements |
113 | void PhaseRegAlloc::alloc_node_regs(int size) { |
114 | _node_regs_max_index = size + (size >> 1) + NodeRegsOverflowSize; |
115 | _node_regs = NEW_RESOURCE_ARRAY( OptoRegPair, _node_regs_max_index ); |
116 | // We assume our caller will fill in all elements up to size-1, so |
117 | // only the extra space we allocate is initialized here. |
118 | for( uint i = size; i < _node_regs_max_index; ++i ) |
119 | _node_regs[i].set_bad(); |
120 | } |
121 | |
122 | #ifndef PRODUCT |
123 | void |
124 | PhaseRegAlloc::print_statistics() { |
125 | tty->print_cr("Total frameslots = %d, Max frameslots = %d" , _total_framesize, _max_framesize); |
126 | int i; |
127 | |
128 | for (i=0; i < _num_allocators; i++) { |
129 | _alloc_statistics[i](); |
130 | } |
131 | } |
132 | #endif |
133 | |