# HG changeset patch # User Doug Simon # Date 1395752268 -3600 # Node ID 0cb5c4d276d4535747cee406c765f88fc6635706 # Parent 209cf6959421b4854bdea52746c9cd2ff4a09c8c use raw data support to fix incorrect use of String.intern() for embedding strings in code diff -r 209cf6959421 -r 0cb5c4d276d4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 25 13:56:52 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 25 13:57:48 2014 +0100 @@ -22,18 +22,18 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.graph.UnsafeAccess.*; +import java.util.*; -import com.oracle.graal.nodes.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; /** - * Converts a compile-time constant Java string into a malloc'ed C string. The malloc'ed string is - * never reclaimed so this should only be used for strings in permanent code such as compiled stubs. + * Converts a compile-time constant Java string into a C string installed with the generated code. */ -public final class CStringNode extends FloatingNode implements Lowerable { +public final class CStringNode extends FloatingNode implements LIRGenLowerable { private final String string; @@ -42,16 +42,18 @@ this.string = string; } - @Override - public void lower(LoweringTool tool) { - byte[] formatBytes = string.getBytes(); - long cstring = unsafe.allocateMemory(formatBytes.length + 1); - for (int i = 0; i < formatBytes.length; i++) { - unsafe.putByte(cstring + i, formatBytes[i]); - } - unsafe.putByte(cstring + formatBytes.length, (byte) 0); - ConstantNode replacement = ConstantNode.forLong(cstring, graph()); - graph().replaceFloating(this, replacement); + public void generate(LIRGenerator gen) { + gen.setResult(this, gen.emitMove(new RawDataValue(gen.target().wordKind, toCString(string)))); + } + + /** + * Converts a String to a null terminated byte array suitable for use as a C string value. + */ + public static byte[] toCString(String value) { + byte[] bytes = value.getBytes(); + byte[] nulTerminated = Arrays.copyOf(bytes, bytes.length + 1); + nulTerminated[bytes.length] = 0; + return nulTerminated; } @NodeIntrinsic(setStampFromReturnType = true) diff -r 209cf6959421 -r 0cb5c4d276d4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 25 13:56:52 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 25 13:57:48 2014 +0100 @@ -22,6 +22,9 @@ */ package com.oracle.graal.hotspot.nodes; +import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.hotspot.nodes.CStringNode.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; @@ -38,7 +41,7 @@ private final String format; @Input private ValueNode value; - public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, Object.class, Object.class, long.class); + public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, long.class, long.class, long.class); private VMErrorNode(String format, ValueNode value) { super(StampFactory.forVoid()); @@ -48,14 +51,22 @@ @Override public void generate(LIRGenerator gen) { - String whereString = "in compiled code for " + graph(); - - // As these strings will end up embedded as oops in the code, they - // must be interned or else they will cause the nmethod to be unloaded - // (nmethods are a) weak GC roots and b) unloaded if any of their - // embedded oops become unreachable). - Constant whereArg = Constant.forObject(whereString.intern()); - Constant formatArg = Constant.forObject(format.intern()); + String whereString; + if (getState() != null) { + String nl = CodeUtil.NEW_LINE; + StringBuilder sb = new StringBuilder("in compiled code associated with frame state:"); + FrameState fs = getState(); + while (fs != null) { + MetaUtil.appendLocation(sb.append(nl).append("\t"), fs.method(), fs.bci); + fs = fs.outerFrameState(); + } + whereString = sb.toString(); + } else { + ResolvedJavaMethod method = graph().method(); + whereString = "in compiled code for " + (method == null ? graph().toString() : format("%H.%n(%p)", method)); + } + Value whereArg = new RawDataValue(gen.target().wordKind, toCString(whereString)); + Value formatArg = new RawDataValue(gen.target().wordKind, toCString(format)); ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(VMErrorNode.VM_ERROR); gen.emitForeignCall(linkage, null, whereArg, formatArg, gen.operand(value)); diff -r 209cf6959421 -r 0cb5c4d276d4 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Tue Mar 25 13:56:52 2014 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Tue Mar 25 13:57:48 2014 +0100 @@ -438,13 +438,12 @@ return (jint)ret; JRT_END -JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value)) +JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, jlong where, jlong format, jlong value)) ResourceMark rm; - assert(where == NULL || java_lang_String::is_instance(where), "must be"); - const char *error_msg = where == NULL ? "" : java_lang_String::as_utf8_string(where); + const char *error_msg = where == 0L ? "" : (char*) (address) where; char *detail_msg = NULL; - if (format != NULL) { - const char* buf = java_lang_String::as_utf8_string(format); + if (format != 0L) { + const char* buf = (char*) (address) format; size_t detail_msg_length = strlen(buf) * 2; detail_msg = (char *) NEW_RESOURCE_ARRAY(u_char, detail_msg_length); jio_snprintf(detail_msg, detail_msg_length, buf, value); diff -r 209cf6959421 -r 0cb5c4d276d4 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Tue Mar 25 13:56:52 2014 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Tue Mar 25 13:57:48 2014 +0100 @@ -43,7 +43,7 @@ static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); static void create_null_exception(JavaThread* thread); static void create_out_of_bounds_exception(JavaThread* thread, jint index); - static void vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value); + static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); static oopDesc* load_and_clear_exception(JavaThread* thread); static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3); static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);