Mercurial > hg > graal-jvmci-8
comparison graal/Compiler/src/com/sun/c1x/ir/ExceptionHandler.java @ 2507:9ec15d6914ca
Pull over of compiler from maxine repository.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 11:43:22 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2506:4a3bf8a5bf41 | 2507:9ec15d6914ca |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, 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 package com.sun.c1x.ir; | |
24 | |
25 import java.util.*; | |
26 | |
27 import com.sun.c1x.lir.*; | |
28 import com.sun.cri.ri.*; | |
29 | |
30 /** | |
31 * The {@code ExceptionHandler} class represents an exception handler for a Java bytecode method. | |
32 * There is exactly one instance of this class for every exception handler without any specific | |
33 * reference to an exception-throwing instruction covered by the handler. Then there is one | |
34 * instance per exception-throwing instruction that is used to record the frame state before | |
35 * execution of the instruction. The latter is used to generate exception adapter blocks | |
36 * (see section 3.4 of the paper <a href="http://www.usenix.org/events/vee05/full_papers/p132-wimmer.pdf"> | |
37 * Optimized Interval Splitting in a Linear Scan Register Allocator</a>) where necessary. | |
38 * | |
39 * @author Ben L. Titzer | |
40 */ | |
41 public final class ExceptionHandler { | |
42 | |
43 public static final List<ExceptionHandler> ZERO_HANDLERS = Collections.emptyList(); | |
44 | |
45 public final RiExceptionHandler handler; | |
46 private BlockBegin entryBlock; | |
47 private LIRList entryCode; | |
48 private int entryCodeOffset; | |
49 private int phiOperand; | |
50 private int scopeCount; | |
51 private int lirOpId; | |
52 | |
53 public ExceptionHandler(RiExceptionHandler handler) { | |
54 this.handler = handler; | |
55 this.entryCodeOffset = -1; | |
56 this.phiOperand = -1; | |
57 this.scopeCount = -1; | |
58 this.lirOpId = -1; | |
59 } | |
60 | |
61 public ExceptionHandler(ExceptionHandler other) { | |
62 this.handler = other.handler; | |
63 this.entryBlock = other.entryBlock; | |
64 this.entryCode = other.entryCode; | |
65 this.entryCodeOffset = other.entryCodeOffset; | |
66 this.phiOperand = other.phiOperand; | |
67 this.scopeCount = other.scopeCount; | |
68 this.lirOpId = other.lirOpId; | |
69 } | |
70 | |
71 @Override | |
72 public String toString() { | |
73 return "XHandler(Block=" + entryBlock.blockID + ") " + handler; | |
74 } | |
75 | |
76 /** | |
77 * Gets the compiler interface object that describes this exception handler, | |
78 * including the bytecode ranges. | |
79 * @return the compiler interface exception handler | |
80 */ | |
81 public RiExceptionHandler handler() { | |
82 return handler; | |
83 } | |
84 | |
85 /** | |
86 * Gets the bytecode index of the handler (catch block). | |
87 * @return the bytecode index of the handler | |
88 */ | |
89 public int handlerBCI() { | |
90 return handler.handlerBCI(); | |
91 } | |
92 | |
93 /** | |
94 * Utility method to check if this exception handler covers the specified bytecode index. | |
95 * @param bci the bytecode index to check | |
96 * @return {@code true} if this exception handler covers the specified bytecode | |
97 */ | |
98 public boolean covers(int bci) { | |
99 return handler.startBCI() <= bci && bci < handler.endBCI(); | |
100 } | |
101 | |
102 /** | |
103 * Gets the entry block for this exception handler. | |
104 * @return the entry block | |
105 */ | |
106 public BlockBegin entryBlock() { | |
107 return entryBlock; | |
108 } | |
109 | |
110 /** | |
111 * Gets the PC offset of the handler entrypoint, which is used by | |
112 * the runtime to forward exception points to their catch sites. | |
113 * @return the pc offset of the handler entrypoint | |
114 */ | |
115 public int entryCodeOffset() { | |
116 return entryCodeOffset; | |
117 } | |
118 | |
119 public int phiOperand() { | |
120 return phiOperand; | |
121 } | |
122 | |
123 public int scopeCount() { | |
124 return scopeCount; | |
125 } | |
126 | |
127 public void setEntryBlock(BlockBegin entry) { | |
128 entryBlock = entry; | |
129 } | |
130 | |
131 public void setEntryCodeOffset(int pco) { | |
132 entryCodeOffset = pco; | |
133 } | |
134 | |
135 public void setPhiOperand(int phi) { | |
136 phiOperand = phi; | |
137 } | |
138 | |
139 public void setScopeCount(int count) { | |
140 scopeCount = count; | |
141 } | |
142 | |
143 public boolean isCatchAll() { | |
144 return handler.catchTypeCPI() == 0; | |
145 } | |
146 | |
147 public static boolean couldCatch(List<ExceptionHandler> exceptionHandlers, RiType klass, boolean typeIsExact) { | |
148 // the type is unknown so be conservative | |
149 if (!klass.isResolved()) { | |
150 return true; | |
151 } | |
152 | |
153 for (int i = 0; i < exceptionHandlers.size(); i++) { | |
154 ExceptionHandler handler = exceptionHandlers.get(i); | |
155 if (handler.isCatchAll()) { | |
156 // catch of ANY | |
157 return true; | |
158 } | |
159 RiType handlerKlass = handler.handler.catchType(); | |
160 // if it's unknown it might be catchable | |
161 if (!handlerKlass.isResolved()) { | |
162 return true; | |
163 } | |
164 // if the throw type is definitely a subtype of the catch type | |
165 // then it can be caught. | |
166 if (klass.isSubtypeOf(handlerKlass)) { | |
167 return true; | |
168 } | |
169 if (!typeIsExact) { | |
170 // If the type isn't exactly known then it can also be caught by | |
171 // catch statements where the inexact type is a subtype of the | |
172 // catch type. | |
173 // given: foo extends bar extends Exception | |
174 // throw bar can be caught by catch foo, catch bar, and catch | |
175 // Exception, however it can't be caught by any handlers without | |
176 // bar in its type hierarchy. | |
177 if (handlerKlass.isSubtypeOf(klass)) { | |
178 return true; | |
179 } | |
180 } | |
181 } | |
182 return false; | |
183 } | |
184 | |
185 public int lirOpId() { | |
186 return lirOpId; | |
187 } | |
188 | |
189 public LIRList entryCode() { | |
190 return entryCode; | |
191 } | |
192 | |
193 public void setLirOpId(int throwingOpId) { | |
194 lirOpId = throwingOpId; | |
195 } | |
196 | |
197 public void setEntryCode(LIRList entryCode) { | |
198 this.entryCode = entryCode; | |
199 | |
200 } | |
201 } |