001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.compilers.opt; 014 015 import java.io.PrintWriter; 016 import java.io.StringWriter; 017 import org.jikesrvm.classloader.TypeReference; 018 019 /** 020 * Use this exception if we encounter a runtime error in the dynamic 021 * optimizing compiler. The caller can recover by calling the 022 * non-optimizing compiler instead (or by reverting to the previous 023 * version of compiled code). 024 */ 025 public class OptimizingCompilerException extends RuntimeException { 026 /** Support for exception serialization */ 027 static final long serialVersionUID = -868535710873341956L; 028 029 /** 030 * Capture illegal upcasts from magic types to java.lang.Object 031 */ 032 public static final class IllegalUpcast extends RuntimeException { 033 /** Support for exception serialization */ 034 static final long serialVersionUID = -847866659938089530L; 035 /** Unboxed type that was attempted to convert to an Object */ 036 final transient TypeReference magicType; 037 038 public IllegalUpcast(TypeReference type) { 039 super("Illegal upcast from " + type + " to java.lang.Object"); 040 magicType = type; 041 } 042 } 043 044 /** 045 * When running in the RVM, typically optimizing compiler 046 * exceptions are caught, optionally a message is printed, and we 047 * fallback to using the baseline compiler. However, this 048 * may not be desirable when running regression testing because 049 * an optimizing compiler exception may be a symptom of a serious failure. 050 * Thus, the code throwing the exception can use an optional boolean value 051 * to indicate if the exception is "normal" or if it should be treated 052 * as a fatal failure for the purpose of regression testing. 053 */ 054 public boolean isFatal = true; 055 056 public OptimizingCompilerException() { } 057 058 /** 059 * @param b is the exception fatal? 060 */ 061 public OptimizingCompilerException(boolean b) { 062 isFatal = b; 063 } 064 065 /** 066 * @param err message describing reason for exception 067 */ 068 public OptimizingCompilerException(String err) { 069 super(err); 070 } 071 072 /** 073 * @param err message describing reason for exception 074 * @param b is the exception fatal? 075 */ 076 public OptimizingCompilerException(String err, boolean b) { 077 super(err); 078 isFatal = b; 079 } 080 081 /** 082 * @param module opt compiler module in which exception was raised 083 * @param err message describing reason for exception 084 */ 085 public OptimizingCompilerException(String module, String err) { 086 super("ERROR produced in module:" + module + "\n " + err + "\n"); 087 } 088 089 /** 090 * @param module opt compiler module in which exception was raised 091 * @param err1 message describing reason for exception 092 * @param err2 message describing reason for exception 093 */ 094 public OptimizingCompilerException(String module, String err1, String err2) { 095 super("ERROR produced in module:" + module + "\n " + err1 + " " + err2 + "\n"); 096 } 097 098 /** 099 * @param module opt compiler module in which exception was raised 100 * @param err1 message describing reason for exception 101 * @param obj object to print describing reason for exception 102 */ 103 public OptimizingCompilerException(String module, String err1, Object obj) { 104 this(module, err1, obj.toString()); 105 } 106 107 /** 108 * @param module opt compiler module in which exception was raised 109 * @param err1 message describing reason for exception 110 * @param val integer to print describing reason for exception 111 */ 112 public OptimizingCompilerException(String module, String err1, int val) { 113 this(module, err1, Integer.toString(val)); 114 } 115 116 /** 117 * @param module opt compiler module in which exception was raised 118 * @param err1 message describing reason for exception 119 * @param err2 message describing reason for exception 120 * @param err3 message describing reason for exception 121 */ 122 public OptimizingCompilerException(String module, String err1, String err2, String err3) { 123 super("ERROR produced in module:" + module + "\n " + err1 + " " + err2 + "\n" + err3 + "\n"); 124 } 125 126 /** 127 * @param module opt compiler module in which exception was raised 128 * @param err1 message describing reason for exception 129 * @param err2 message describing reason for exception 130 * @param obj object to print describing reason for exception 131 */ 132 public OptimizingCompilerException(String module, String err1, String err2, Object obj) { 133 this(module, err1, err2, obj.toString()); 134 } 135 136 /** 137 * @param module opt compiler module in which exception was raised 138 * @param err1 message describing reason for exception 139 * @param err2 message describing reason for exception 140 * @param val integer to print describing reason for exception 141 */ 142 OptimizingCompilerException(String module, String err1, String err2, int val) { 143 this(module, err1, err2, Integer.toString(val)); 144 } 145 146 /** 147 * Use the UNREACHABLE methods to mark code that should never execute 148 * eg, unexpected cases of switch statments and nested if/then/else 149 * @exception OptimizingCompilerException 150 */ 151 public static void UNREACHABLE() throws OptimizingCompilerException { 152 throw new OptimizingCompilerException("Executed UNREACHABLE code"); 153 } 154 155 /** 156 * Use the UNREACHABLE methods to mark code that should never execute 157 * e.g., unexpected cases of switch statements and nested if/then/else 158 * @param module module in which exception occurred 159 * @exception OptimizingCompilerException 160 */ 161 public static void UNREACHABLE(String module) throws OptimizingCompilerException { 162 throw new OptimizingCompilerException(module, "Executed UNREACHABLE code"); 163 } 164 165 /** 166 * Use the UNREACHABLE methods to mark code that should never execute 167 * e.g., unexpected cases of switch statements and nested if/then/else 168 * @param module opt compiler module in which exception was raised 169 * @param err1 message describing reason for exception 170 * @exception OptimizingCompilerException 171 */ 172 public static void UNREACHABLE(String module, String err1) throws OptimizingCompilerException { 173 throw new OptimizingCompilerException(module, "Executed UNREACHABLE code", err1); 174 } 175 176 /** 177 * Use the UNREACHABLE methods to mark code that should never execute 178 * e.g., unexpected cases of switch statements and nested if/then/else 179 * @param module opt compiler module in which exception was raised 180 * @param err1 message describing reason for exception 181 * @param err2 message describing reason for exception 182 * @exception OptimizingCompilerException 183 */ 184 public static void UNREACHABLE(String module, String err1, String err2) throws OptimizingCompilerException { 185 throw new OptimizingCompilerException(module, "Executed UNREACHABLE code", err1, err2); 186 } 187 188 /** 189 * Incomplete function in IA32 port. 190 * @exception OptimizingCompilerException 191 */ 192 public static void TODO() throws OptimizingCompilerException { 193 throw new OptimizingCompilerException("Unsupported function in IA32 port"); 194 } 195 196 /** 197 * Incomplete function in IA32 port. 198 * @param module opt compiler module in which exception was raised 199 * @exception OptimizingCompilerException 200 */ 201 public static void TODO(String module) throws OptimizingCompilerException { 202 throw new OptimizingCompilerException(module, "Unsupported function in IA32 port"); 203 } 204 205 /** 206 * Return a string that is the printout of level stackframes in the stacktrace. 207 * @param level the number of levels to print 208 * @return n-level dump of stacktrace 209 */ 210 public String trace(int level) { 211 StringWriter sw = new StringWriter(); 212 PrintWriter pw = new PrintWriter(sw); 213 printStackTrace(pw); 214 int count = 0, i = 0; 215 StringBuffer sb = sw.getBuffer(); 216 for (; i < sb.length() && count < level + 1; i++) { 217 if (sb.charAt(i) == '\n') { 218 count++; 219 } 220 } 221 sb.setLength(i); 222 return sb.toString(); 223 } 224 }