001/* 002 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.common; 024 025import java.util.*; 026 027/** 028 * Indicates a condition in JVMCI related code that should never occur during normal operation. 029 */ 030public class JVMCIError extends Error { 031 032 private static final long serialVersionUID = 531632331813456233L; 033 private final ArrayList<String> context = new ArrayList<>(); 034 035 public static RuntimeException unimplemented() { 036 throw new JVMCIError("unimplemented"); 037 } 038 039 public static RuntimeException unimplemented(String msg) { 040 throw new JVMCIError("unimplemented: %s", msg); 041 } 042 043 public static RuntimeException shouldNotReachHere() { 044 throw new JVMCIError("should not reach here"); 045 } 046 047 public static RuntimeException shouldNotReachHere(String msg) { 048 throw new JVMCIError("should not reach here: %s", msg); 049 } 050 051 public static RuntimeException shouldNotReachHere(Throwable cause) { 052 throw new JVMCIError(cause); 053 } 054 055 /** 056 * Checks a given condition and throws a {@link JVMCIError} if it is false. Guarantees are 057 * stronger than assertions in that they are always checked. Error messages for guarantee 058 * violations should clearly indicate the nature of the problem as well as a suggested solution 059 * if possible. 060 * 061 * @param condition the condition to check 062 * @param msg the message that will be associated with the error, in 063 * {@link String#format(String, Object...)} syntax 064 * @param args arguments to the format string 065 */ 066 public static void guarantee(boolean condition, String msg, Object... args) { 067 if (!condition) { 068 throw new JVMCIError("failed guarantee: " + msg, args); 069 } 070 } 071 072 /** 073 * This constructor creates a {@link JVMCIError} with a message assembled via 074 * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to 075 * always generate the same output. 076 * 077 * @param msg the message that will be associated with the error, in String.format syntax 078 * @param args parameters to String.format - parameters that implement {@link Iterable} will be 079 * expanded into a [x, x, ...] representation. 080 */ 081 public JVMCIError(String msg, Object... args) { 082 super(format(msg, args)); 083 } 084 085 /** 086 * This constructor creates a {@link JVMCIError} for a given causing Throwable instance. 087 * 088 * @param cause the original exception that contains additional information on this error 089 */ 090 public JVMCIError(Throwable cause) { 091 super(cause); 092 } 093 094 /** 095 * This constructor creates a {@link JVMCIError} and adds all the 096 * {@linkplain #addContext(String) context} of another {@link JVMCIError}. 097 * 098 * @param e the original {@link JVMCIError} 099 */ 100 public JVMCIError(JVMCIError e) { 101 super(e); 102 context.addAll(e.context); 103 } 104 105 @Override 106 public String toString() { 107 StringBuilder str = new StringBuilder(); 108 str.append(super.toString()); 109 for (String s : context) { 110 str.append("\n\tat ").append(s); 111 } 112 return str.toString(); 113 } 114 115 private static String format(String msg, Object... args) { 116 if (args != null) { 117 // expand Iterable parameters into a list representation 118 for (int i = 0; i < args.length; i++) { 119 if (args[i] instanceof Iterable<?>) { 120 ArrayList<Object> list = new ArrayList<>(); 121 for (Object o : (Iterable<?>) args[i]) { 122 list.add(o); 123 } 124 args[i] = list.toString(); 125 } 126 } 127 } 128 return String.format(Locale.ENGLISH, msg, args); 129 } 130 131 public JVMCIError addContext(String newContext) { 132 this.context.add(newContext); 133 return this; 134 } 135 136 public JVMCIError addContext(String name, Object obj) { 137 return addContext(format("%s: %s", name, obj)); 138 } 139}