diff --git a/src/share/vm/classfile/symbolTable.cpp b/src/share/vm/classfile/symbolTable.cpp index fc19dd55564f88be56af029bf0ddedb50cf3a7ad..0f8da2d895e8894695fe1f6dd318f961709214ff 100644 --- a/src/share/vm/classfile/symbolTable.cpp +++ b/src/share/vm/classfile/symbolTable.cpp @@ -677,9 +677,14 @@ oop StringTable::lookup(Symbol* symbol) { ResourceMark rm; int length; jchar* chars = symbol->as_unicode(length); - unsigned int hashValue = hash_string(chars, length); - int index = the_table()->hash_to_index(hashValue); - return the_table()->lookup(index, chars, length, hashValue); + return lookup(chars, length); +} + + +oop StringTable::lookup(jchar* name, int len) { + unsigned int hash = hash_string(name, len); + int index = the_table()->hash_to_index(hash); + return the_table()->lookup(index, name, len, hash); } diff --git a/src/share/vm/classfile/symbolTable.hpp b/src/share/vm/classfile/symbolTable.hpp index 3eee99ddbc2543524467f14155d7eccd5b8db75a..a2896382f63a0c352570e34d8fd0117c411c0503 100644 --- a/src/share/vm/classfile/symbolTable.hpp +++ b/src/share/vm/classfile/symbolTable.hpp @@ -287,6 +287,7 @@ public: // Probing static oop lookup(Symbol* symbol); + static oop lookup(jchar* chars, int length); // Interning static oop intern(Symbol* symbol, TRAPS); diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp index 4758210ee0c7d427c58cbb56286e5546eca7fd69..9b3cd297f8aa0c4ea1e804be27382b37378b0df3 100644 --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -254,6 +254,24 @@ WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o)) CompileBroker::queue_size(CompLevel_full_profile) /* C1 */; WB_END +WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) + ResourceMark rm(THREAD); + int len; + jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len); + oop found_string = StringTable::the_table()->lookup(name, len); + if (found_string == NULL) { + return false; + } + return true; +WB_END + + +WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o)) + Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true); + Universe::heap()->collect(GCCause::_last_ditch_collection); +WB_END + + //Some convenience methods to deal with objects from java int WhiteBox::offset_for_field(const char* field_name, oop object, Symbol* signature_symbol) { @@ -343,6 +361,8 @@ static JNINativeMethod methods[] = { CC"(Ljava/lang/reflect/Method;)I", (void*)&WB_GetMethodCompilationLevel}, {CC"getCompileQueuesSize", CC"()I", (void*)&WB_GetCompileQueuesSize}, + {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, + {CC"fullGC", CC"()V", (void*)&WB_FullGC }, }; #undef CC diff --git a/test/runtime/interned/SanityTest.java b/test/runtime/interned/SanityTest.java new file mode 100644 index 0000000000000000000000000000000000000000..779d3fc78c629e7ac155e8b059fa4c2b4a62aa5b --- /dev/null +++ b/test/runtime/interned/SanityTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test SanityTest + * @summary Sanity check of String.intern() & GC + * @library /testlibrary /testlibrary/whitebox + * @build SanityTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SanityTest + */ + +import java.util.*; +import sun.hotspot.WhiteBox; + + +public class SanityTest { + public static Object tmp; + public static void main(String... args) { + + WhiteBox wb = WhiteBox.getWhiteBox(); + StringBuilder sb = new StringBuilder(); + sb.append("1234x"); sb.append("x56789"); + String str = sb.toString(); + + if (wb.isInStringTable(str)) { + throw new RuntimeException("String " + str + " is already interned"); + } + str.intern(); + if (!wb.isInStringTable(str)) { + throw new RuntimeException("String " + str + " is not interned"); + } + str = sb.toString(); + wb.fullGC(); + if (wb.isInStringTable(str)) { + throw new RuntimeException("String " + str + " is in StringTable even after GC"); + } + } +} diff --git a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index c9d23ef5fa5929628f9a6edd80f493b5b2ad44dd..d5d3ab525c56265d1fe35b620f1510db6ee000d8 100644 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -94,4 +94,10 @@ public class WhiteBox { public native int getMethodCompilationLevel(Method method); public native boolean setDontInlineMethod(Method method, boolean value); public native int getCompileQueuesSize(); + + //Intered strings + public native boolean isInStringTable(String str); + + // force Full GC + public native void fullGC(); }