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