1 /*
2  * Copyright (c) 2012, 2015, 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 package org.graalvm.compiler.replacements;
26 
27 import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring;
28 
29 import java.io.PrintStream;
30 
31 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
32 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
33 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
34 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
35 import org.graalvm.compiler.word.Word;
36 
37 import jdk.vm.ci.meta.JavaKind;
38 
39 //JaCoCo Exclude
40 
41 /**
42  * Provides {@link PrintStream}-like logging facility.
43  */
44 public final class Log {
45 
46     public static final ForeignCallDescriptor LOG_PRIMITIVE = new ForeignCallDescriptor("logPrimitive", void.class, int.class, long.class, boolean.class);
47     public static final ForeignCallDescriptor LOG_OBJECT = new ForeignCallDescriptor("logObject", void.class, Object.class, boolean.class, boolean.class);
48     public static final ForeignCallDescriptor LOG_PRINTF = new ForeignCallDescriptor("logPrintf", void.class, Word.class, long.class, long.class, long.class);
49 
50     @NodeIntrinsic(ForeignCallNode.class)
log(@onstantNodeParameter ForeignCallDescriptor logObject, Object object, boolean asString, boolean newline)51     private static native void log(@ConstantNodeParameter ForeignCallDescriptor logObject, Object object, boolean asString, boolean newline);
52 
53     @NodeIntrinsic(ForeignCallNode.class)
log(@onstantNodeParameter ForeignCallDescriptor logPrimitive, int typeChar, long value, boolean newline)54     private static native void log(@ConstantNodeParameter ForeignCallDescriptor logPrimitive, int typeChar, long value, boolean newline);
55 
56     @NodeIntrinsic(ForeignCallNode.class)
printf(@onstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3)57     private static native void printf(@ConstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3);
58 
print(boolean value)59     public static void print(boolean value) {
60         log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, false);
61     }
62 
print(byte value)63     public static void print(byte value) {
64         log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, false);
65     }
66 
print(char value)67     public static void print(char value) {
68         log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, false);
69     }
70 
print(short value)71     public static void print(short value) {
72         log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, false);
73     }
74 
print(int value)75     public static void print(int value) {
76         log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, false);
77     }
78 
print(long value)79     public static void print(long value) {
80         log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, false);
81     }
82 
83     /**
84      * Prints a formatted string to the log stream.
85      *
86      * @param format a C style printf format value that can contain at most one conversion specifier
87      *            (i.e., a sequence of characters starting with '%').
88      * @param value the value associated with the conversion specifier
89      */
printf(String format, long value)90     public static void printf(String format, long value) {
91         printf(LOG_PRINTF, cstring(format), value, 0L, 0L);
92     }
93 
printf(String format, long v1, long v2)94     public static void printf(String format, long v1, long v2) {
95         printf(LOG_PRINTF, cstring(format), v1, v2, 0L);
96     }
97 
printf(String format, long v1, long v2, long v3)98     public static void printf(String format, long v1, long v2, long v3) {
99         printf(LOG_PRINTF, cstring(format), v1, v2, v3);
100     }
101 
print(float value)102     public static void print(float value) {
103         if (Float.isNaN(value)) {
104             print("NaN");
105         } else if (value == Float.POSITIVE_INFINITY) {
106             print("Infinity");
107         } else if (value == Float.NEGATIVE_INFINITY) {
108             print("-Infinity");
109         } else {
110             log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), false);
111         }
112     }
113 
print(double value)114     public static void print(double value) {
115         if (Double.isNaN(value)) {
116             print("NaN");
117         } else if (value == Double.POSITIVE_INFINITY) {
118             print("Infinity");
119         } else if (value == Double.NEGATIVE_INFINITY) {
120             print("-Infinity");
121         } else {
122             log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), false);
123         }
124     }
125 
print(String value)126     public static void print(String value) {
127         log(LOG_OBJECT, value, true, false);
128     }
129 
printObject(Object o)130     public static void printObject(Object o) {
131         log(LOG_OBJECT, o, false, false);
132     }
133 
println(boolean value)134     public static void println(boolean value) {
135         log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, true);
136     }
137 
println(byte value)138     public static void println(byte value) {
139         log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, true);
140     }
141 
println(char value)142     public static void println(char value) {
143         log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, true);
144     }
145 
println(short value)146     public static void println(short value) {
147         log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, true);
148     }
149 
println(int value)150     public static void println(int value) {
151         log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, true);
152     }
153 
println(long value)154     public static void println(long value) {
155         log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, true);
156     }
157 
println(float value)158     public static void println(float value) {
159         if (Float.isNaN(value)) {
160             println("NaN");
161         } else if (value == Float.POSITIVE_INFINITY) {
162             println("Infinity");
163         } else if (value == Float.NEGATIVE_INFINITY) {
164             println("-Infinity");
165         } else {
166             log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), true);
167         }
168     }
169 
println(double value)170     public static void println(double value) {
171         if (Double.isNaN(value)) {
172             println("NaN");
173         } else if (value == Double.POSITIVE_INFINITY) {
174             println("Infinity");
175         } else if (value == Double.NEGATIVE_INFINITY) {
176             println("-Infinity");
177         } else {
178             log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), true);
179         }
180     }
181 
println(String value)182     public static void println(String value) {
183         log(LOG_OBJECT, value, true, true);
184     }
185 
printlnObject(Object o)186     public static void printlnObject(Object o) {
187         log(LOG_OBJECT, o, false, true);
188     }
189 
println()190     public static void println() {
191         println("");
192     }
193 }
194