# HG changeset patch # User Gilles Duboscq # Date 1339767522 -7200 # Node ID b8272646eb479de61ed8a527754f434d247e2f4b # Parent b0f511b40eeee9d6b0d2d44de2805c610a01c875# Parent d50c788195a54ac0fc87a1ccd06cf786e22f854a Merge diff -r b0f511b40eee -r b8272646eb47 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Fri Jun 15 15:35:10 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Fri Jun 15 15:38:42 2012 +0200 @@ -200,6 +200,11 @@ return constantPool; } + /** + * Gets the instance size of this type. If an instance of this type cannot + * be fast path allocated, then the returned value is negative (its absolute + * value gives the size). + */ public int instanceSize() { return instanceSize; } diff -r b0f511b40eee -r b8272646eb47 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java Fri Jun 15 15:35:10 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java Fri Jun 15 15:38:42 2012 +0200 @@ -783,6 +783,7 @@ public XirSnippet genNewInstance(XirSite site, JavaType type) { HotSpotResolvedJavaType resolvedType = (HotSpotResolvedJavaType) type; int instanceSize = resolvedType.instanceSize(); + assert instanceSize >= 0; return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(resolvedType.klassOop())); } diff -r b0f511b40eee -r b8272646eb47 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Fri Jun 15 15:35:10 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Fri Jun 15 15:38:42 2012 +0200 @@ -70,7 +70,7 @@ if (klassState != klassStateFullyInitialized()) { if (logType != null) { Log.print(logType); - Log.println(" - uninitialized"); + Log.println(" - uninit alloc"); } return NewInstanceStubCall.call(hub); } @@ -84,17 +84,21 @@ if (newTop.cmp(BE, end)) { Object instance = cast(top, Object.class); store(thread, 0, threadTlabTopOffset(), newTop); - return formatInstance(hub, size, instance, logType); - } else { + formatInstance(hub, size, instance); if (logType != null) { Log.print(logType); - Log.println(" - stub allocate"); + Log.print(" - fast alloc at "); + Log.printlnAddress(instance); } - return NewInstanceStubCall.call(hub); + return instance; } - } else { - return NewInstanceStubCall.call(hub); } + + if (logType != null) { + Log.print(logType); + Log.println(" - slow alloc"); + } + return NewInstanceStubCall.call(hub); } private static Word asWord(Object object) { @@ -108,7 +112,7 @@ /** * Formats the header of a created instance and zeroes out its body. */ - private static Object formatInstance(Object hub, int size, Object instance, String logType) { + private static void formatInstance(Object hub, int size, Object instance) { Word headerPrototype = cast(load(hub, 0, instanceHeaderPrototypeOffset(), wordKind()), Word.class); store(instance, 0, 0, headerPrototype); store(instance, 0, hubOffset(), hub); @@ -116,13 +120,6 @@ for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { store(instance, 0, offset, 0); } - if (logType != null) { - Log.print("allocated instance of "); - Log.print(logType); - Log.print(" at "); - Log.printlnAddress(instance); - } - return instance; } @Fold @@ -192,6 +189,8 @@ HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass(); HotSpotKlassOop hub = type.klassOop(); int instanceSize = type.instanceSize(); + assert (instanceSize % wordSize()) == 0; + assert instanceSize >= 0; Key key = new Key(newInstance).add("size", instanceSize).add("checkInit", !type.isInitialized()).add("useTLAB", useTLAB).add("logType", LOG_ALLOCATION ? type.name() : null); Arguments arguments = arguments("hub", hub); SnippetTemplate template = cache.get(key); diff -r b0f511b40eee -r b8272646eb47 graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java Fri Jun 15 15:35:10 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java Fri Jun 15 15:38:42 2012 +0200 @@ -36,12 +36,20 @@ Assert.assertTrue(expected != null); Assert.assertTrue(actual != null); super.assertEquals(expected.getClass(), actual.getClass()); + if (expected.getClass() != Object.class) { + try { + expected.getClass().getDeclaredMethod("equals", Object.class); + super.assertEquals(expected, actual); + } catch (Exception e) { + } + } } @Test public void test1() { test("newObject"); test("newBigObject"); + test("newSomeObject"); test("newEmptyString"); test("newString", "value"); test("newHashMap", 31); @@ -55,6 +63,10 @@ return new BigObject(); } + public static SomeObject newSomeObject() { + return new SomeObject(); + } + public static String newEmptyString() { return new String(); } @@ -67,6 +79,30 @@ return new HashMap(initialCapacity); } + static class SomeObject { + String name = "o1"; + HashMap map = new HashMap<>(); + + + public SomeObject() { + map.put(name, this.getClass()); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SomeObject) { + SomeObject so = (SomeObject) obj; + return so.name.equals(name) && so.map.equals(map); + } + return false; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + } + static class BigObject { Object f01; Object f02; diff -r b0f511b40eee -r b8272646eb47 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Jun 15 15:35:10 2012 +0200 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Jun 15 15:38:42 2012 +0200 @@ -1036,6 +1036,10 @@ __ push(rdi); __ push(rbx); +#ifdef GRAAL + __ push(rcx); + __ push(rsi); +#endif if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized @@ -1074,6 +1078,10 @@ __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); +#ifdef GRAAL + __ pop(rsi); + __ pop(rcx); +#endif __ pop(rbx); __ pop(rdi); __ ret(0); @@ -1087,11 +1095,19 @@ __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); +#ifdef GRAAL + __ pop(rsi); + __ pop(rcx); +#endif __ pop(rbx); __ pop(rdi); __ ret(0); __ bind(slow_path); +#ifdef GRAAL + __ pop(rsi); + __ pop(rcx); +#endif __ pop(rbx); __ pop(rdi); } diff -r b0f511b40eee -r b8272646eb47 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Fri Jun 15 15:35:10 2012 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Fri Jun 15 15:38:42 2012 +0200 @@ -278,8 +278,12 @@ if (klass->oop_is_javaArray()) { HotSpotResolvedJavaType::set_isArrayClass(obj, true); } else { + int size = instanceKlass::cast(klass())->size_helper() * HeapWordSize; + if (!instanceKlass::cast(klass())->can_be_fastpath_allocated()) { + size = -size; + } HotSpotResolvedJavaType::set_isArrayClass(obj, false); - HotSpotResolvedJavaType::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize); + HotSpotResolvedJavaType::set_instanceSize(obj, size); HotSpotResolvedJavaType::set_hasFinalizer(obj, klass->has_finalizer()); } diff -r b0f511b40eee -r b8272646eb47 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 15 15:35:10 2012 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Jun 15 15:38:42 2012 +0200 @@ -816,10 +816,15 @@ set_int(env, config, "bciProfileWidth", BciProfileWidth); set_int(env, config, "typeProfileWidth", TypeProfileWidth); + // We use the fast path stub so that we get TLAB refills whenever possible instead of + // unconditionally allocating directly from the heap (which the slow path does). + // The stub must also do initialization when the compiled check fails. + Runtime1::StubID newInstanceStub = Runtime1::fast_new_instance_init_check_id; + set_long(env, config, "debugStub", VmIds::addStub((address)warning)); set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_pointer_id))); - set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id))); + set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(newInstanceStub))); set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id))); set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id))); set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id)));