From paul.sandoz at oracle.com Tue Apr 1 09:44:38 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 1 Apr 2014 11:44:38 +0200 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <53305D76.7080009@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> Message-ID: <15133BFB-B289-41AE-A530-1D34FC64EF72@oracle.com> Hi Vladimir, This looks good. Minor stuff below. I too prefer *_TYPE instead of Int/Float/Void etc as those are not v. friendly for static imports. Paul. LambaForm: -- private static int fixResult(int result, Name[] names) { if (result == LAST_RESULT) result = names.length - 1; // might still be void if (result >= 0 && names[result].type == V_TYPE) result = -1; return result; } change to "result = -1" to: result = VOID_RESULT; ? Change: LambdaForm addArguments(int pos, List> types) { BasicType[] basicTypes = new BasicType[types.size()]; for (int i = 0; i < basicTypes.length; i++) basicTypes[i] = basicType(types.get(i)); return addArguments(pos, basicTypes); } to: LambdaForm addArguments(int pos, List> types) { return addArguments(pos, basicTypes(types)); } ? Methods not used, i cannot tell which may be there for future code or are referenced indirectly: String basicTypeSignature() { //return LambdaForm.basicTypeSignature(resolvedHandle.type()); return LambdaForm.basicTypeSignature(methodType()); } void resolve() { for (Name n : names) n.resolve(); } static LambdaForm identityForm(BasicType type) { return LF_identityForm[type.ordinal()]; } static LambdaForm zeroForm(BasicType type) { return LF_zeroForm[type.ordinal()]; } BoundMethodHandle: -- Methods not used: SpeciesData extendWith(Class type) { return extendWith(basicType(type)); } SpeciesData extendWithChar(char type) { return extendWith(basicType(type)); } static void initStatics() {} static { SpeciesData.initStatics(); } Deprecated method in ASM (there are also a few others): mv.visitMethodInsn(INVOKESPECIAL, className, "", makeSignature(types, true)); I think you need to append false as the last parameter. Unused first parameter "cbmhClass": static NamedFunction[] makeNominalGetters(Class cbmhClass, String types, NamedFunction[] nfs, MethodHandle[] getters) { InvokerByteCodeGenerator -- private int loadInsnOpcode(BasicType type) throws InternalError { int opcode; switch (type) { case I_TYPE: opcode = Opcodes.ILOAD; break; case J_TYPE: opcode = Opcodes.LLOAD; break; case F_TYPE: opcode = Opcodes.FLOAD; break; case D_TYPE: opcode = Opcodes.DLOAD; break; case L_TYPE: opcode = Opcodes.ALOAD; break; default: throw new InternalError("unknown type: " + type); } return opcode; } Could just do: case I_TYPE: return Opcodes.ILOAD; etc. Same for "storeInsnOpcode" method. Unused? static int nfi = 0; MethodHandle -- Unused? /*non-public*/ MethodHandle bindImmediate(int pos, BasicType basicType, Object value) { // Bind an immediate value to a position in the arguments. // This means, elide the respective argument, // and replace all references to it in NamedFunction args with the specified value. // CURRENT RESTRICTIONS // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others) assert pos == 0 && basicType == L_TYPE && value instanceof Unsafe; MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver! LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos return copyWith(type2, form2); } On Mar 24, 2014, at 5:29 PM, Vladimir Ivanov wrote: > Updated version: > http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03/ > > - changed the way how arrays of types are created: > static final BasicType[] ALL_TYPES = BasicType.values(); > static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); > > - added a test for BasicType (LambdaFormTest.testBasicType). > > Best regards, > Vladimir Ivanov -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From paul.sandoz at oracle.com Tue Apr 1 09:55:22 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 1 Apr 2014 11:55:22 +0200 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: <53232FF3.9020803@oracle.com> References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> Message-ID: <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> On Mar 14, 2014, at 5:36 PM, Vladimir Ivanov wrote: >> Doh! crossed webrevs, thanks. >> >> Just had a quick look, this looks like a really nice improvement to the array setter/getter support, definitely simplified. IIUC the mh.viewAsType will now handle the appropriate casting. I believe it might reduce the "ceremony" for array setter/getter MHs [1]. >> >> I see there is a PROFILE_LEVEL option, by default set to 0, that results in casts not being emitted: >> >> + if (VerifyType.isNullConversion(Object.class, pclass, false)) { >> + if (PROFILE_LEVEL > 0) >> + emitReferenceCast(Object.class, arg); >> + return; >> + } >> ... >> + mv.visitLdcInsn(constantPlaceholder(cls)); >> + mv.visitTypeInsn(Opcodes.CHECKCAST, CLS); >> + mv.visitInsn(Opcodes.SWAP); >> + mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false); >> + if (Object[].class.isAssignableFrom(cls)) >> + mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); >> + else if (PROFILE_LEVEL > 0) >> + mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ); >> >> Can you explain a bit the rational for that? > These casts are redundant - they aren't required for bytecode correctness. The idea behind PROFILE_LEVEL is to provide more type information to JIT-compiler. Right now, type profiling occurs on every checkcast instruction. So, having these additional instructions we can feed C2 with more accurate information about types. > > Consider this as a hack to overcome some of the limitations of current profiling implementation in VM. > Apologies for the late reply this dropped off my radar... Ah! i may have just had a minor epiphany :-) So that is why in DirectMethodHandle there are casts for fields, via say Accessor.checkCast? @Override Object checkCast(Object obj) { return fieldType.cast(obj); } if so could PROFILE_LEVEL be supported in that code too? Perhaps the JIT could derive some profile information from the MethodType of the MethodHandle? I notice that in my experiments for enhanced access to instances of fields that casts are almost optimized away but a null-check is left [*], which is also seems redundant and could impact performance get/set of null values. Paul. [*] 0x000000010d050f70: test %r10d,%r10d 0x000000010d050f73: je 0x000000010d050f9d ... 0x000000010d050f9d: mov %rsi,%rbp 0x000000010d050fa0: mov %r10d,0x4(%rsp) 0x000000010d050fa5: mov $0xffffffad,%esi 0x000000010d050faa: nop 0x000000010d050fab: callq 0x000000010d0163e0 ; OopMap{rbp=Oop [4]=NarrowOop off=112} ;*ifnull ; - java.lang.Class::cast at 1 (line 3253) ; - java.lang.invoke.InstanceFieldHandle::checkCast at 2 (line 133) ; - java.lang.invoke.InstanceFieldHandle::set at 19 (line 153) ; - java.lang.invoke.VarHandle::set at 21 (line 127) ; - VarHandleTest::testLoopOne at 8 (line 157) ; {runtime_call} 0x000000010d050fb0: callq 0x000000010c39d330 ;*ifnull ; - java.lang.Class::cast at 1 (line 3253) ; - java.lang.invoke.InstanceFieldHandle::checkCast at 2 (line 133) ; - java.lang.invoke.InstanceFieldHandle::set at 19 (line 153) ; - java.lang.invoke.VarHandle::set at 21 (line 127) ; - VarHandleTest::testLoopOne at 8 (line 157) ; {runtime_call} -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From vladimir.x.ivanov at oracle.com Tue Apr 1 13:57:35 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 01 Apr 2014 17:57:35 +0400 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <15133BFB-B289-41AE-A530-1D34FC64EF72@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <15133BFB-B289-41AE-A530-1D34FC64EF72@oracle.com> Message-ID: <533AC5CF.5060404@oracle.com> Paul, thanks for review. Updated webrev: http://cr.openjdk.java.net/~vlivanov/8037210/webrev.04/ Best regards, Vladimir Ivanov On 4/1/14 1:44 PM, Paul Sandoz wrote: > Hi Vladimir, > > This looks good. Minor stuff below. > > I too prefer *_TYPE instead of Int/Float/Void etc as those are not v. friendly for static imports. > > Paul. > > LambaForm: > -- > > private static int fixResult(int result, Name[] names) { > if (result == LAST_RESULT) > result = names.length - 1; // might still be void > if (result >= 0 && names[result].type == V_TYPE) > result = -1; > return result; > } > > change to "result = -1" to: > > result = VOID_RESULT; > > ? Done. > > > Change: > > LambdaForm addArguments(int pos, List> types) { > BasicType[] basicTypes = new BasicType[types.size()]; > for (int i = 0; i < basicTypes.length; i++) > basicTypes[i] = basicType(types.get(i)); > return addArguments(pos, basicTypes); > } > > to: > > LambdaForm addArguments(int pos, List> types) { > return addArguments(pos, basicTypes(types)); > } > > ? Done. > > > Methods not used, i cannot tell which may be there for future code or are referenced indirectly: > > String basicTypeSignature() { > //return LambdaForm.basicTypeSignature(resolvedHandle.type()); > return LambdaForm.basicTypeSignature(methodType()); > } > > void resolve() { > for (Name n : names) n.resolve(); > } > > static LambdaForm identityForm(BasicType type) { > return LF_identityForm[type.ordinal()]; > } > static LambdaForm zeroForm(BasicType type) { > return LF_zeroForm[type.ordinal()]; > } > Removed. > > > BoundMethodHandle: > -- > > Methods not used: > > SpeciesData extendWith(Class type) { > return extendWith(basicType(type)); > } > > SpeciesData extendWithChar(char type) { > return extendWith(basicType(type)); > } > > static void initStatics() {} > static { SpeciesData.initStatics(); } Removed. > > > Deprecated method in ASM (there are also a few others): > > mv.visitMethodInsn(INVOKESPECIAL, className, "", makeSignature(types, true)); > > I think you need to append false as the last parameter. Fixed. > > > Unused first parameter "cbmhClass": > > static NamedFunction[] makeNominalGetters(Class cbmhClass, String types, NamedFunction[] nfs, MethodHandle[] getters) { Removed. > InvokerByteCodeGenerator > -- > > private int loadInsnOpcode(BasicType type) throws InternalError { > int opcode; > switch (type) { > case I_TYPE: opcode = Opcodes.ILOAD; break; > case J_TYPE: opcode = Opcodes.LLOAD; break; > case F_TYPE: opcode = Opcodes.FLOAD; break; > case D_TYPE: opcode = Opcodes.DLOAD; break; > case L_TYPE: opcode = Opcodes.ALOAD; break; > default: > throw new InternalError("unknown type: " + type); > } > return opcode; > } > > Could just do: > > case I_TYPE: return Opcodes.ILOAD; > > etc. Same for "storeInsnOpcode" method. Changed as you suggest. > > > Unused? > > static int nfi = 0; Removed. > MethodHandle > -- > > Unused? > > /*non-public*/ > MethodHandle bindImmediate(int pos, BasicType basicType, Object value) { > // Bind an immediate value to a position in the arguments. > // This means, elide the respective argument, > // and replace all references to it in NamedFunction args with the specified value. > > // CURRENT RESTRICTIONS > // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others) > assert pos == 0 && basicType == L_TYPE && value instanceof Unsafe; > MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver! > LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos > return copyWith(type2, form2); > } Removed. Best regards, Vladimir Ivanov > > > On Mar 24, 2014, at 5:29 PM, Vladimir Ivanov wrote: > >> Updated version: >> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03/ >> >> - changed the way how arrays of types are created: >> static final BasicType[] ALL_TYPES = BasicType.values(); >> static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); >> >> - added a test for BasicType (LambdaFormTest.testBasicType). >> >> Best regards, >> Vladimir Ivanov > > > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From vladimir.x.ivanov at oracle.com Tue Apr 1 14:10:12 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 01 Apr 2014 18:10:12 +0400 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> Message-ID: <533AC8C4.9080601@oracle.com> Paul, Unfortunately, additional profiling doesn't work for Accessor.checkCast case. The problem is Accessor.checkCast is called from multiple places, so type profile is very likely to be polluted. And it kills the benefits. I don't think MethodType helps with profiling in any way. It represents type info which is necessary for correctness checks. Profiling collects more fine-grained information (e.g. exact types, values). Regarding redundant null check, do you have a test case so I can play with it myself? Best regards, Vladimir Ivanov On 4/1/14 1:55 PM, Paul Sandoz wrote: > On Mar 14, 2014, at 5:36 PM, Vladimir Ivanov wrote: >>> Doh! crossed webrevs, thanks. >>> >>> Just had a quick look, this looks like a really nice improvement to the array setter/getter support, definitely simplified. IIUC the mh.viewAsType will now handle the appropriate casting. I believe it might reduce the "ceremony" for array setter/getter MHs [1]. >>> >>> I see there is a PROFILE_LEVEL option, by default set to 0, that results in casts not being emitted: >>> >>> + if (VerifyType.isNullConversion(Object.class, pclass, false)) { >>> + if (PROFILE_LEVEL > 0) >>> + emitReferenceCast(Object.class, arg); >>> + return; >>> + } >>> ... >>> + mv.visitLdcInsn(constantPlaceholder(cls)); >>> + mv.visitTypeInsn(Opcodes.CHECKCAST, CLS); >>> + mv.visitInsn(Opcodes.SWAP); >>> + mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false); >>> + if (Object[].class.isAssignableFrom(cls)) >>> + mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); >>> + else if (PROFILE_LEVEL > 0) >>> + mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ); >>> >>> Can you explain a bit the rational for that? >> These casts are redundant - they aren't required for bytecode correctness. The idea behind PROFILE_LEVEL is to provide more type information to JIT-compiler. Right now, type profiling occurs on every checkcast instruction. So, having these additional instructions we can feed C2 with more accurate information about types. >> >> Consider this as a hack to overcome some of the limitations of current profiling implementation in VM. >> > > Apologies for the late reply this dropped off my radar... > > Ah! i may have just had a minor epiphany :-) > > So that is why in DirectMethodHandle there are casts for fields, via say Accessor.checkCast? > > @Override Object checkCast(Object obj) { > return fieldType.cast(obj); > } > > if so could PROFILE_LEVEL be supported in that code too? > > Perhaps the JIT could derive some profile information from the MethodType of the MethodHandle? > > I notice that in my experiments for enhanced access to instances of fields that casts are almost optimized away but a null-check is left [*], which is also seems redundant and could impact performance get/set of null values. > > Paul. > > [*] > > 0x000000010d050f70: test %r10d,%r10d > 0x000000010d050f73: je 0x000000010d050f9d > ... > 0x000000010d050f9d: mov %rsi,%rbp > 0x000000010d050fa0: mov %r10d,0x4(%rsp) > 0x000000010d050fa5: mov $0xffffffad,%esi > 0x000000010d050faa: nop > 0x000000010d050fab: callq 0x000000010d0163e0 ; OopMap{rbp=Oop [4]=NarrowOop off=112} > ;*ifnull > ; - java.lang.Class::cast at 1 (line 3253) > ; - java.lang.invoke.InstanceFieldHandle::checkCast at 2 (line 133) > ; - java.lang.invoke.InstanceFieldHandle::set at 19 (line 153) > ; - java.lang.invoke.VarHandle::set at 21 (line 127) > ; - VarHandleTest::testLoopOne at 8 (line 157) > ; {runtime_call} > 0x000000010d050fb0: callq 0x000000010c39d330 ;*ifnull > ; - java.lang.Class::cast at 1 (line 3253) > ; - java.lang.invoke.InstanceFieldHandle::checkCast at 2 (line 133) > ; - java.lang.invoke.InstanceFieldHandle::set at 19 (line 153) > ; - java.lang.invoke.VarHandle::set at 21 (line 127) > ; - VarHandleTest::testLoopOne at 8 (line 157) > ; {runtime_call} > From paul.sandoz at oracle.com Tue Apr 1 15:29:31 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 1 Apr 2014 17:29:31 +0200 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: <533AC8C4.9080601@oracle.com> References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> <533AC8C4.9080601@oracle.com> Message-ID: On Apr 1, 2014, at 4:10 PM, Vladimir Ivanov wrote: > Paul, > > Unfortunately, additional profiling doesn't work for Accessor.checkCast case. The problem is Accessor.checkCast is called from multiple places, so type profile is very likely to be polluted. And it kills the benefits. > So is there any point in doing such a cast in this case? The type performing the cast is the field type declared as a parameter in the MethodType of the MethodHandle and also held by the Accessor. IIUC the Invokers.checkExactType should ensure no "unsavoury" instances of the wrong type gets through? (the holder instance is only checked for null, via checkBase). > I don't think MethodType helps with profiling in any way. It represents type info which is necessary for correctness checks. Profiling collects more fine-grained information (e.g. exact types, values). > OK. > Regarding redundant null check, do you have a test case so I can play with it myself? > I will send something to you later today or tomorrow. Paul. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From paul.sandoz at oracle.com Tue Apr 1 15:42:37 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 1 Apr 2014 17:42:37 +0200 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <533AC5CF.5060404@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <15133BFB-B289-41AE-A530-1D34FC64EF72@oracle.com> <533AC5CF.5060404@oracle.com> Message-ID: On Apr 1, 2014, at 3:57 PM, Vladimir Ivanov wrote: > Paul, thanks for review. > > Updated webrev: > http://cr.openjdk.java.net/~vlivanov/8037210/webrev.04/ > +1 Paul. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From vladimir.x.ivanov at oracle.com Tue Apr 1 15:47:34 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 01 Apr 2014 19:47:34 +0400 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <15133BFB-B289-41AE-A530-1D34FC64EF72@oracle.com> <533AC5CF.5060404@oracle.com> Message-ID: <533ADF96.4010602@oracle.com> Thank you, Paul. Best regards, Vladimir Ivanov On 4/1/14 7:42 PM, Paul Sandoz wrote: > > On Apr 1, 2014, at 3:57 PM, Vladimir Ivanov wrote: > >> Paul, thanks for review. >> >> Updated webrev: >> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.04/ >> > > +1 > > Paul. > From vladimir.x.ivanov at oracle.com Tue Apr 1 16:21:10 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 01 Apr 2014 20:21:10 +0400 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> <533AC8C4.9080601@oracle.com> Message-ID: <533AE776.20209@oracle.com> Best regards, Vladimir Ivanov On 4/1/14 7:29 PM, Paul Sandoz wrote: > > On Apr 1, 2014, at 4:10 PM, Vladimir Ivanov wrote: > >> Paul, >> >> Unfortunately, additional profiling doesn't work for Accessor.checkCast case. The problem is Accessor.checkCast is called from multiple places, so type profile is very likely to be polluted. And it kills the benefits. >> > > So is there any point in doing such a cast in this case? > > The type performing the cast is the field type declared as a parameter in the MethodType of the MethodHandle and also held by the Accessor. > > IIUC the Invokers.checkExactType should ensure no "unsavoury" instances of the wrong type gets through? (the holder instance is only checked for null, via checkBase). I don't see any point in doing profiling for this particular case. Such shape should be well optimized by JIT if it sees that an instance of Accessor is a constant. As I understand, it should be the case for most of the usage scenarios. Best regards, Vladimir Ivanov > > >> I don't think MethodType helps with profiling in any way. It represents type info which is necessary for correctness checks. Profiling collects more fine-grained information (e.g. exact types, values). >> > > OK. > > >> Regarding redundant null check, do you have a test case so I can play with it myself? >> > > I will send something to you later today or tomorrow. > > Paul. > From paul.sandoz at oracle.com Wed Apr 2 14:16:21 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 2 Apr 2014 16:16:21 +0200 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: <533AE776.20209@oracle.com> References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> <533AC8C4.9080601@oracle.com> <533AE776.20209@oracle.com> Message-ID: <4C2465F9-CE7B-4B43-AD73-A822C6B86F97@oracle.com> On Apr 1, 2014, at 6:21 PM, Vladimir Ivanov wrote: > On 4/1/14 7:29 PM, Paul Sandoz wrote: >> >> On Apr 1, 2014, at 4:10 PM, Vladimir Ivanov wrote: >> >>> Paul, >>> >>> Unfortunately, additional profiling doesn't work for Accessor.checkCast case. The problem is Accessor.checkCast is called from multiple places, so type profile is very likely to be polluted. And it kills the benefits. >>> >> Though... i wonder why the accessor cast is any more or less unique than casts performed for lambda form. >> So is there any point in doing such a cast in this case? >> >> The type performing the cast is the field type declared as a parameter in the MethodType of the MethodHandle and also held by the Accessor. >> >> IIUC the Invokers.checkExactType should ensure no "unsavoury" instances of the wrong type gets through? (the holder instance is only checked for null, via checkBase). > I don't see any point in doing profiling for this particular case. Such shape should be well optimized by JIT if it sees that an instance of Accessor is a constant. As I understand, it should be the case for most of the usage scenarios. > Perhaps conservatively we could retain the existing casts if PROFILE > 0. I can provide a patch if that helps? Also, just double checking, i would presume the same would be applicable for MH setter/getters to arrays as per your patch improving those? >>> Regarding redundant null check, do you have a test case so I can play with it myself? >>> >> >> I will send something to you later today or tomorrow. >> Still plan to send you something today :-) but later on... Paul. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From paul.sandoz at oracle.com Wed Apr 2 19:19:01 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 2 Apr 2014 21:19:01 +0200 Subject: [9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms In-Reply-To: <4C2465F9-CE7B-4B43-AD73-A822C6B86F97@oracle.com> References: <5322EBF2.7030209@oracle.com> <5322F3D7.9010103@oracle.com> <94F61B19-8904-42FA-9E16-CC0A6B30FD79@oracle.com> <53230184.9090007@oracle.com> <2FCC64E3-3753-4CE0-9CC6-849FF737BFB5@oracle.com> <53232FF3.9020803@oracle.com> <6562A055-4B0E-4992-8BF9-A16EFDB09CD6@oracle.com> <533AC8C4.9080601@oracle.com> <533AE776.20209@oracle.com> <4C2465F9-CE7B-4B43-AD73-A822C6B86F97@oracle.com> Message-ID: On Apr 2, 2014, at 4:16 PM, Paul Sandoz wrote: > >>>> Regarding redundant null check, do you have a test case so I can play with it myself? >>>> >>> >>> I will send something to you later today or tomorrow. >>> > > > Still plan to send you something today :-) but later on... > See below for an inline trace, the assembler and the class that was executed with -XX:-TieredCompilation using Java 8. Paul. Inlining _isInstance on constant Class java/lang/String ! @ 9 MHFieldTest::testLoopOne (25 bytes) inline (hot) @ 8 java.lang.invoke.LambdaForm$MH/617901222::invokeExact_MT (15 bytes) inline (hot) @ 2 java.lang.invoke.Invokers::checkExactType (30 bytes) inline (hot) @ 11 java.lang.invoke.MethodHandle::type (5 bytes) accessor @ 11 java.lang.invoke.LambdaForm$MH/523429237::putObjectFieldCast (32 bytes) inline (hot) @ 1 java.lang.invoke.DirectMethodHandle::fieldOffset (9 bytes) inline (hot) @ 6 java.lang.invoke.DirectMethodHandle::checkBase (7 bytes) inline (hot) @ 1 java.lang.Object::getClass (0 bytes) (intrinsic) @ 13 java.lang.invoke.DirectMethodHandle::checkCast (9 bytes) inline (hot) @ 5 java.lang.invoke.DirectMethodHandle$Accessor::checkCast (9 bytes) inline (hot) @ 5 java.lang.Class::cast (27 bytes) inline (hot) @ 6 java.lang.Class::isInstance (0 bytes) (intrinsic) @ 28 sun.misc.Unsafe::putObject (0 bytes) (intrinsic) [Verified Entry Point] 0x000000010ccf0da0: mov %eax,-0x14000(%rsp) 0x000000010ccf0da7: push %rbp 0x000000010ccf0da8: sub $0x20,%rsp ;*synchronization entry ; - MHFieldTest::testLoopOne at -1 (line 57) 0x000000010ccf0dac: mov 0xc(%rsi),%r10d ;*getfield a ; - MHFieldTest::testLoopOne at 5 (line 57) 0x000000010ccf0db0: test %r10d,%r10d 0x000000010ccf0db3: je 0x000000010ccf0ddd ;*ifnull ; - java.lang.Class::cast at 1 (line 3257) ; - java.lang.invoke.DirectMethodHandle$Accessor::checkCast at 5 (line 441) ; - java.lang.invoke.DirectMethodHandle::checkCast at 5 (line 510) ; - java.lang.invoke.LambdaForm$MH/640070680::putObjectFieldCast at 13 ; - java.lang.invoke.LambdaForm$MH/789451787::invokeExact_MT at 11 ; - MHFieldTest::testLoopOne at 8 (line 57) 0x000000010ccf0db5: add $0x10,%rsi 0x000000010ccf0db9: mov %r10d,(%rsi) 0x000000010ccf0dbc: mov %rsi,%r10 0x000000010ccf0dbf: shr $0x9,%r10 0x000000010ccf0dc3: mov $0x18f780000,%r11 0x000000010ccf0dcd: mov %r12b,(%r11,%r10,1) ;*getfield a ; - MHFieldTest::testLoopOne at 5 (line 57) 0x000000010ccf0dd1: add $0x20,%rsp 0x000000010ccf0dd5: pop %rbp 0x000000010ccf0dd6: test %eax,-0x113ddc(%rip) # 0x000000010cbdd000 ; {poll_return} 0x000000010ccf0ddc: retq 0x000000010ccf0ddd: mov %rsi,%rbp 0x000000010ccf0de0: mov %r10d,0x4(%rsp) 0x000000010ccf0de5: mov $0xffffffad,%esi 0x000000010ccf0dea: nop 0x000000010ccf0deb: callq 0x000000010ccbc120 ; OopMap{rbp=Oop [4]=NarrowOop off=112} ;*ifnull ; - java.lang.Class::cast at 1 (line 3257) ; - java.lang.invoke.DirectMethodHandle$Accessor::checkCast at 5 (line 441) ; - java.lang.invoke.DirectMethodHandle::checkCast at 5 (line 510) ; - java.lang.invoke.LambdaForm$MH/640070680::putObjectFieldCast at 13 ; - java.lang.invoke.LambdaForm$MH/789451787::invokeExact_MT at 11 ; - MHFieldTest::testLoopOne at 8 (line 57) ; {runtime_call} 0x000000010ccf0df0: callq 0x000000010c07ace4 ;*ifnull ; - java.lang.Class::cast at 1 (line 3257) ; - java.lang.invoke.DirectMethodHandle$Accessor::checkCast at 5 (line 441) ; - java.lang.invoke.DirectMethodHandle::checkCast at 5 (line 510) ; - java.lang.invoke.LambdaForm$MH/640070680::putObjectFieldCast at 13 ; - java.lang.invoke.LambdaForm$MH/789451787::invokeExact_MT at 11 ; - MHFieldTest::testLoopOne at 8 (line 57) ; {runtime_call} import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; public class MHFieldTest { volatile String a = "A"; public String b; static final MethodHandle b_setter; static { try { b_setter = MethodHandles.lookup().findSetter(MHFieldTest.class, "b", String.class); } catch (Exception e) { throw new Error(e); } } public static void main(String[] args) { new MHFieldTest().testLoop(); } void testLoop() { for (int i = 0; i < 1000000; i++) { testLoopOne(); } } void testLoopOne() { try { b_setter.invokeExact(this, a); } catch (Throwable t) { throw new Error(t); } } } -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From christian.thalinger at oracle.com Thu Apr 3 22:33:36 2014 From: christian.thalinger at oracle.com (Christian Thalinger) Date: Thu, 3 Apr 2014 15:33:36 -0700 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <5332EBD5.8090100@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> Message-ID: <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> On Mar 26, 2014, at 8:01 AM, Vladimir Ivanov wrote: > Here's a version with the new naming scheme: > http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03.naming > > I like existing naming scheme and OBJECT/VOID/LONG/etc names are quite popular(e.g. Wrapper & ASM (Opcodes) use them). Of course they are popular because these are the type names. There is no type L; it?s an object. I don?t understand why we have to use different names just because they are used in other namespaces. This is not a C define. > So, I'm in favor of leaving it as is. > > Best regards, > Vladimir Ivanov > > On 3/26/14 12:24 AM, Christian Thalinger wrote: >> + enum BasicType { >> + L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types >> + I_TYPE('I', int.class, Wrapper.INT), >> + J_TYPE('J', long.class, Wrapper.LONG), >> + F_TYPE('F', float.class, Wrapper.FLOAT), >> + D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types >> + V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts >> >> I would suggest to not name them X_TYPE but give them meaningful names like Int, Float, Void. The enum BasicType already infers that it?s a type. If you think it?s not clear that it?s a type just use BasicType.Double in that places. >> >> On Mar 24, 2014, at 9:29 AM, Vladimir Ivanov wrote: >> >>> Updated version: >>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03/ >>> >>> - changed the way how arrays of types are created: >>> static final BasicType[] ALL_TYPES = BasicType.values(); >>> static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); >>> >>> - added a test for BasicType (LambdaFormTest.testBasicType). >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> On 3/22/14 2:08 AM, Vladimir Ivanov wrote: >>>> John, thanks for the feedback. >>>> >>>> Updated webrev: >>>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.02 >>>> >>>> Also moved LambdaForm.testShortenSignature() into a stand-alone unit test. >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> On 3/21/14 10:54 PM, John Rose wrote: >>>>> On Mar 21, 2014, at 8:49 AM, Vladimir Ivanov >>>>> > >>>>> wrote: >>>>> >>>>>> Thanks for the feedback. >>>>>> >>>>>> What do you think about the following: >>>>>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.01/ >>>>> >>>>> That looks nice. Strong typing; who woulda' thunk it. :-) >>>>> >>>>> The uses of ".ordinal()" are the extra cost relative to using just small >>>>> integers. They seem totally reasonable in the code. >>>>> >>>>> I suggest either wrapping "ordinal" as something like "id" or else >>>>> changing temp names like "id" to "ord", to reinforce the use of a common >>>>> name. >>>>> >>>>> Don't make the enum class public. And especially don't make the mutable >>>>> arrays public: >>>>> >>>>> + public static final BasicType[] ALL_TYPES = { L_TYPE, I_TYPE, >>>>> J_TYPE, F_TYPE, D_TYPE, V_TYPE }; >>>>> + public static final BasicType[] ARG_TYPES = { L_TYPE, I_TYPE, >>>>> J_TYPE, F_TYPE, D_TYPE }; >>>>> >>>>> ? John >>>>> >>>>> P.S. That would only be safe if we had (what we don't yet) a notion of >>>>> frozen arrays like: >>>>> >>>>> + public static final BasicType final[] ALL_TYPES = { L_TYPE, >>>>> I_TYPE, J_TYPE, F_TYPE, D_TYPE, V_TYPE }; >>>>> + public static final BasicType final[] ARG_TYPES = { L_TYPE, >>>>> I_TYPE, J_TYPE, F_TYPE, D_TYPE }; >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> mlvm-dev mailing list >>>>> mlvm-dev at openjdk.java.net >>>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>>>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From john.r.rose at oracle.com Fri Apr 4 04:44:49 2014 From: john.r.rose at oracle.com (John Rose) Date: Fri, 4 Apr 2014 00:44:49 -0400 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> Message-ID: On Apr 3, 2014, at 6:33 PM, Christian Thalinger wrote: > Of course they are popular because these are the type names. There is no type L; it?s an object. I don?t understand why we have to use different names just because they are used in other namespaces. This is not a C define. They stand for JVM signatures as well as basic types. The letters are signature letters. Can we move on from this? ? John -------------- next part -------------- An HTML attachment was scrubbed... URL: From christian.thalinger at oracle.com Fri Apr 4 23:31:53 2014 From: christian.thalinger at oracle.com (Christian Thalinger) Date: Fri, 4 Apr 2014 16:31:53 -0700 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> Message-ID: On Apr 3, 2014, at 9:44 PM, John Rose wrote: > On Apr 3, 2014, at 6:33 PM, Christian Thalinger wrote: > >> Of course they are popular because these are the type names. There is no type L; it?s an object. I don?t understand why we have to use different names just because they are used in other namespaces. This is not a C define. > > They stand for JVM signatures as well as basic types. The letters are signature letters. Can we move on from this? Sure. Push it. > > ? John > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From vladimir.x.ivanov at oracle.com Mon Apr 7 23:53:15 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 08 Apr 2014 03:53:15 +0400 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> Message-ID: <53433A6B.50203@oracle.com> Thanks, Chris. I have to do one more iteration: http://cr.openjdk.java.net/~vlivanov/8037210/webrev.05/ I have to revert changes related to BMH::reinvokerTarget. Removal of reinvokerTarget in generated concrete BMH classes introduces serious performance regression, since BMH::reinvokerTarget is much more complex than an accessor and it disturbs inlining decisions in too many places. Best regards, Vladimir Ivanov On 4/5/14 3:31 AM, Christian Thalinger wrote: > > On Apr 3, 2014, at 9:44 PM, John Rose > wrote: > >> On Apr 3, 2014, at 6:33 PM, Christian Thalinger >> > > wrote: >> >>> Of course they are popular because these are the type names. There >>> is no type L; it?s an object. I don?t understand why we have to use >>> different names just because they are used in other namespaces. This >>> is not a C define. >> >> They stand for JVM signatures as well as basic types. The letters are >> signature letters. Can we move on from this? > > Sure. Push it. > >> >> ? John >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From vladimir.x.ivanov at oracle.com Tue Apr 8 09:20:11 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 08 Apr 2014 13:20:11 +0400 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> Message-ID: <5343BF4B.2000104@oracle.com> Chris, sorry for the late reply. >> Here's a version with the new naming scheme: >> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03.naming >> >> I like existing naming scheme and OBJECT/VOID/LONG/etc names are quite popular(e.g. Wrapper & ASM (Opcodes) use them). > > Of course they are popular because these are the type names. There is no type L; it?s an object. I don?t understand why we have to use different names just because they are used in other namespaces. This is not a C define. I see 2 problems with the naming scheme you propose. (1) Wrapper, Opcodes & BasicType collide in some places. If element names are the same, static import doesn't work and all usages should be disambiguated. (2) BasicType.I_TYPE corresponds to 5 primitive types. It's misleading to call it BasicType.INT (or BasicType.INTEGER) (consider Wrapper.INT vs BasicType.INT). Current naming scheme makes correspondence with JVM basic types explicit. Best regards, Vladimir Ivanov > >> So, I'm in favor of leaving it as is. >> >> Best regards, >> Vladimir Ivanov >> >> On 3/26/14 12:24 AM, Christian Thalinger wrote: >>> + enum BasicType { >>> + L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types >>> + I_TYPE('I', int.class, Wrapper.INT), >>> + J_TYPE('J', long.class, Wrapper.LONG), >>> + F_TYPE('F', float.class, Wrapper.FLOAT), >>> + D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types >>> + V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts >>> >>> I would suggest to not name them X_TYPE but give them meaningful names like Int, Float, Void. The enum BasicType already infers that it?s a type. If you think it?s not clear that it?s a type just use BasicType.Double in that places. >>> >>> On Mar 24, 2014, at 9:29 AM, Vladimir Ivanov wrote: >>> >>>> Updated version: >>>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.03/ >>>> >>>> - changed the way how arrays of types are created: >>>> static final BasicType[] ALL_TYPES = BasicType.values(); >>>> static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); >>>> >>>> - added a test for BasicType (LambdaFormTest.testBasicType). >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> On 3/22/14 2:08 AM, Vladimir Ivanov wrote: >>>>> John, thanks for the feedback. >>>>> >>>>> Updated webrev: >>>>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.02 >>>>> >>>>> Also moved LambdaForm.testShortenSignature() into a stand-alone unit test. >>>>> >>>>> Best regards, >>>>> Vladimir Ivanov >>>>> >>>>> On 3/21/14 10:54 PM, John Rose wrote: >>>>>> On Mar 21, 2014, at 8:49 AM, Vladimir Ivanov >>>>>> > >>>>>> wrote: >>>>>> >>>>>>> Thanks for the feedback. >>>>>>> >>>>>>> What do you think about the following: >>>>>>> http://cr.openjdk.java.net/~vlivanov/8037210/webrev.01/ >>>>>> >>>>>> That looks nice. Strong typing; who woulda' thunk it. :-) >>>>>> >>>>>> The uses of ".ordinal()" are the extra cost relative to using just small >>>>>> integers. They seem totally reasonable in the code. >>>>>> >>>>>> I suggest either wrapping "ordinal" as something like "id" or else >>>>>> changing temp names like "id" to "ord", to reinforce the use of a common >>>>>> name. >>>>>> >>>>>> Don't make the enum class public. And especially don't make the mutable >>>>>> arrays public: >>>>>> >>>>>> + public static final BasicType[] ALL_TYPES = { L_TYPE, I_TYPE, >>>>>> J_TYPE, F_TYPE, D_TYPE, V_TYPE }; >>>>>> + public static final BasicType[] ARG_TYPES = { L_TYPE, I_TYPE, >>>>>> J_TYPE, F_TYPE, D_TYPE }; >>>>>> >>>>>> ? John >>>>>> >>>>>> P.S. That would only be safe if we had (what we don't yet) a notion of >>>>>> frozen arrays like: >>>>>> >>>>>> + public static final BasicType final[] ALL_TYPES = { L_TYPE, >>>>>> I_TYPE, J_TYPE, F_TYPE, D_TYPE, V_TYPE }; >>>>>> + public static final BasicType final[] ARG_TYPES = { L_TYPE, >>>>>> I_TYPE, J_TYPE, F_TYPE, D_TYPE }; >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> mlvm-dev mailing list >>>>>> mlvm-dev at openjdk.java.net >>>>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>>>>> >>>> _______________________________________________ >>>> mlvm-dev mailing list >>>> mlvm-dev at openjdk.java.net >>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From paul.sandoz at oracle.com Tue Apr 8 12:47:09 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 8 Apr 2014 14:47:09 +0200 Subject: RFR (L) 8037210: Get rid of char-based descriptions 'J' of basic types In-Reply-To: <53433A6B.50203@oracle.com> References: <5322E7C6.3050603@oracle.com> <659B1DAF-A57F-457F-9F68-8856795555BF@oracle.com> <532C5F6D.30500@oracle.com> <0C91BFD6-57CA-47B1-8DD3-88E0E4B9D252@oracle.com> <532CB847.3080809@oracle.com> <53305D76.7080009@oracle.com> <5332EBD5.8090100@oracle.com> <433BC760-0B2E-4894-988B-7B4D388A9F71@oracle.com> <53433A6B.50203@oracle.com> Message-ID: On Apr 8, 2014, at 1:53 AM, Vladimir Ivanov wrote: > Thanks, Chris. > > I have to do one more iteration: > http://cr.openjdk.java.net/~vlivanov/8037210/webrev.05/ > > I have to revert changes related to BMH::reinvokerTarget. > > Removal of reinvokerTarget in generated concrete BMH classes introduces serious performance regression, since BMH::reinvokerTarget is much more complex than an accessor and it disturbs inlining decisions in too many places. > OK, IIUC it's just reintroducing some original code back into BMH, nothing else has changed. If so +1 , lets get this pushed :-) I can now see why it might cause a perf issue if the following was used instead: @Override MethodHandle reinvokerTarget() { try { return (MethodHandle) argL(0); } catch (Throwable ex) { throw newInternalError(ex); } } Paul. [1] http://www.diffnow.com/?report=biopj -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From brian.goetz at oracle.com Wed Apr 9 19:36:20 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 09 Apr 2014 15:36:20 -0400 Subject: Call for Speakers -- 2014 JVM Language Summit Message-ID: <5345A134.8060000@oracle.com> === CALL FOR SPEAKERS -- JVM LANGUAGE SUMMIT, July 2014 === Dear colleague; We are pleased to announce the 2014 JVM Language Summit to be held at Oracle's Santa Clara campus on July 28-30, 2014. Registration is now open for speaker submissions (presentations and workshops) and will remain open until May 16, 2014. There is no registration fee for speakers. General attendee registration will open on May 7. For Oracle employees who wish to register as general attendees, please contact the organizers at inquire at jvmlangsummit.com. The JVM Language Summit is an open technical collaboration among language designers, compiler writers, tool builders, runtime engineers, and VM architects. We will share our experiences as creators of programming languages for the JVM and of the JVM itself. We also welcome non-JVM developers on similar technologies to attend or speak on their runtime, VM, or language of choice. The format this year will be similar to previous years; we've divided the schedule equally between traditional presentations and "Workshops". Workshops are informal, facilitated discussion groups among smaller, self-selected participants, and should enable "deeper dives" into the subject matter. If there is interest, there will also be impromptu "lightning talks". We encourage speakers to submit both a presentation and a workshop; we will arrange to schedule the presentation before the workshop, so that the presentation can spark people's interest and the workshop will allow those who are really interested to go deeper into the subject area. Workshop facilitators may, but are not expected to, prepare presentation materials, but they should come prepared to guide a deep technical discussion. The Summit is being organized by language and JVM engineers; no marketers involved! So bring your slide rules and be prepared for some seriously geeky discussions. Speaker registration is now open at: http://registration.jvmlangsummit.com If you have any questions, send inquiries to inquire at jvmlangsummit.com. We hope to see you in July! From peter.levart at gmail.com Thu Apr 17 21:49:06 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 17 Apr 2014 23:49:06 +0200 Subject: RFR: 8000975: (process) Merge UNIXProcess.java.bsd & UNIXProcess.java.linux (& .solaris & .aix) In-Reply-To: References: <5332F00D.1020806@gmail.com> <5332FDD5.8030801@oracle.com> <533ABC14.50304@gmail.com> <533AC3E9.3060406@oracle.com> <533ADEB3.2040306@gmail.com> <533AF19A.1060709@gmail.com> <533B17CA.6030203@oracle.com> <533BEB31.6050307@gmail.com> <533C0DFF.5020508@oracle.com> <533C3549.3030602@gmail.com> <533F06FC.40102@oracle.com> <534FF438.7000601@gmail.com> Message-ID: <53504C52.3020509@gmail.com> Hi, I'm cross-posting this on the mlvm-dev mailing list, because I think it concerns internal MHs implementation. While replacing some inner classes with lambdas in java.lang.UNIXProcess class, a jtreg test started failing. This test is employing a security manager with an unusual configuration. It defines "java.util" as a package for which access should be checked against the set of permissions. The class initialization of UNIXProcess class initializes some lambdas and their initialization fails with the following stack-trace: java.lang.ExceptionInInitializerError at java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(DirectMethodHandle.java:256) at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:221) at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:210) at java.lang.invoke.DirectMethodHandle.make(DirectMethodHandle.java:82) at java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:1638) at java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:1602) at java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:1778) at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1727) at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:442) at java.lang.UNIXProcess$Platform.get(UNIXProcess.java:147) at java.lang.UNIXProcess.(UNIXProcess.java:160) at java.lang.ProcessImpl.start(ProcessImpl.java:130) at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023) at java.lang.Runtime.exec(Runtime.java:620) at java.lang.Runtime.exec(Runtime.java:485) at SecurityManagerClinit.main(SecurityManagerClinit.java:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:484) at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) at java.lang.Thread.run(Thread.java:744) Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.java.util") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457) at java.security.AccessController.checkPermission(AccessController.java:884) at java.lang.SecurityManager.checkPermission(SecurityManager.java:541) at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1481) * at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:305)* at java.lang.ClassLoader.loadClass(ClassLoader.java:359) at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:83) * at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:54)* at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41) at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:911) at java.lang.invoke.MemberName.getMethodType(MemberName.java:144) at java.lang.invoke.LambdaForm.computeInitialPreparedForms(LambdaForm.java:477) at java.lang.invoke.LambdaForm.(LambdaForm.java:1641) I think I found the root cause of the problem. It's nothing wrong with the test (although making "java.util" as an access-checked package is a little unusual). The problem, I think, is in MH's LambdaForm implementation. Although the UNIXProcess class is a system class (loaded by bootstrap class loader), MHs created by evaluating lambda expressions in this class, trigger loading a class in "java.util" package using AppClassLoader as the initiating class loader, which involves package access checks. This should not happen, I think, if only the system classes are involved in constructing MHs. I checked the code and there's a ClassLoader parameter passed to the *BytecodeDescriptor.parseMethod *method. This ClassLoader is taken as the defining class loader of the MemberName's declaring class for which the getMethoType() is requested. All the types involved in such MemberName (return type, parameter types) should be resolvable from the MemberName's declaring class' class loader. In our case, the class loader of the declaring class of the particular MemberName is bootstrap class loader, so null is passed as the ClassLoader parameter to the *BytecodeDescriptor.parseMethod *method. This method checks for null ClassLoader and replaces it with ClassLoader.getSystemClassLoader() before calling parseSig() with it, because parseSig() uses the ClassLoader instance to invoke loadClass() method on it. The ClassLoader.getSystemClassLoader() is the application class-loader (AppClassLoader). I think the right thing to do would be to use bootstrap class loader if the ClassLoader parameter passed to *BytecodeDescriptor.parseMethod *was null. The fix would be as follows: =================================================================== --- jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770:8371276d52c0) +++ jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770+:8371276d52c0+) @@ -43,8 +43,6 @@ static List> parseMethod(String bytecodeSignature, int start, int end, ClassLoader loader) { - if (loader == null) - loader = ClassLoader.getSystemClassLoader(); String str = bytecodeSignature; int[] i = {start}; ArrayList> ptypes = new ArrayList>(); @@ -80,7 +78,7 @@ i[0] = endc+1; String name = str.substring(begc, endc).replace('/', '.'); try { - return loader.loadClass(name); + return Class.forName(name, false, loader); } catch (ClassNotFoundException ex) { throw new TypeNotPresentException(name, ex); } What do you think? Am I right? Regards, Peter Regards, Peter On 04/17/2014 06:50 PM, Martin Buchholz wrote: > This test tries to make sure we have all of the doPrivileged blocks in > place. Which is hard to do. I don't recall the details. It would > seem better to simply test that processes can be executed if the very > specific permission to do just that was provided. Which IIRC > ProcessBuilder/Basic.java already has tests for. Ohhh.... but to test > clinit behavior, they have to be in a new JVM instance, so the > existing tests in Basic are insufficient for that purpose. But it > would be cumbersome to transplant current security tests from Basic > into an environment where it's the only invocation of the process api. > > > On Thu, Apr 17, 2014 at 8:33 AM, Peter Levart > wrote: > > Hi Martin, > > Since you are the author of the > test/java/lang/ProcessBuilder/SecurityManagerClinit.java test, I > thought I'll ask you about the purpose of the following line in > the test just before setting up the Policy and SecurityManager: > > // A funky contrived security setup, just for bug repro > purposes. > java.security.Security.setProperty("package.access", > "java.util"); > > The merge of UNIXProcess.java.* sources fails this test since it > now uses lambdas in various places and it seems that MHs are > involved that need access to java.util package from a class loaded > by AppClassLoader. Would it defeat the purpose of the test if > "java.util" package was replaced by say "sun.misc" which is > normally restricted? > > Regards, Peter > > > On 04/04/2014 09:24 PM, roger riggs wrote: > > Hi Peter, > > I ran into one test problem when running this through its paces. > > The test: test/java/lang/ProcessBuilder/SecurityManagerClinit.java > throws a package access exception while creating a lambda > due to the wacky security manager and forbidding of access to > java.util. > I hacked the test to remove the limitation on java.util. > > This looks good to me but a more experienced Reviewer should > look at it. > > Thanks, Roger > > > Right, > > Here it is: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/UNIXProcess/webrev.06/ > > > > > Stack dump from test: > java.lang.ExceptionInInitializerError > at > java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(DirectMethodHandle.java:256) > at > java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:221) > at > java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:210) > at > java.lang.invoke.DirectMethodHandle.make(DirectMethodHandle.java:82) > at > java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:1638) > at > java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:1602) > at > java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:1778) > at > java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1727) > at > java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:442) > at > java.lang.UNIXProcess$Platform.get(UNIXProcess.java:147) > at java.lang.UNIXProcess.(UNIXProcess.java:160) > at java.lang.ProcessImpl.start(ProcessImpl.java:130) > at > java.lang.ProcessBuilder.start(ProcessBuilder.java:1023) > at java.lang.Runtime.exec(Runtime.java:620) > at java.lang.Runtime.exec(Runtime.java:485) > at > SecurityManagerClinit.main(SecurityManagerClinit.java:70) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native > Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:484) > at > com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) > at java.lang.Thread.run(Thread.java:744) > Caused by: java.security.AccessControlException: access denied > ("java.lang.RuntimePermission" "accessClassInPackage.java.util") > at > java.security.AccessControlContext.checkPermission(AccessControlContext.java:457) > at > java.security.AccessController.checkPermission(AccessController.java:884) > at > java.lang.SecurityManager.checkPermission(SecurityManager.java:541) > at > java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1481) > at > sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:305) > at java.lang.ClassLoader.loadClass(ClassLoader.java:359) > at > sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:83) > at > sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:54) > at > sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41) > at > java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:911) > at > java.lang.invoke.MemberName.getMethodType(MemberName.java:144) > at > java.lang.invoke.LambdaForm.computeInitialPreparedForms(LambdaForm.java:477) > at > java.lang.invoke.LambdaForm.(LambdaForm.java:1641) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From paul.sandoz at oracle.com Wed Apr 23 14:21:00 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 23 Apr 2014 16:21:00 +0200 Subject: RFR: 8000975: (process) Merge UNIXProcess.java.bsd & UNIXProcess.java.linux (& .solaris & .aix) In-Reply-To: <53504C52.3020509@gmail.com> References: <5332F00D.1020806@gmail.com> <5332FDD5.8030801@oracle.com> <533ABC14.50304@gmail.com> <533AC3E9.3060406@oracle.com> <533ADEB3.2040306@gmail.com> <533AF19A.1060709@gmail.com> <533B17CA.6030203@oracle.com> <533BEB31.6050307@gmail.com> <533C0DFF.5020508@oracle.com> <533C3549.3030602@gmail.com> <533F06FC.40102@oracle.com> <534FF438.7000601@gmail.com> <53504C52.3020509@gmail.com> Message-ID: Hi Peter, IMHO such security manager usage by the test is v. fragile and we should try and find a safer alternative if possible. However, there may also be an issue with lambda form code. (About a month ago i too was looking, internally, at this kind of issue and thought there was a questionable use of the application/system class loader when initializing the LambdaForm class, but then i got distracted with other stuff and forgot about it.) Your one-liner fix seems to do the trick, but I think we need Vladimir to confirm this is OK. Paul. On Apr 17, 2014, at 11:49 PM, Peter Levart wrote: > Hi, > > I'm cross-posting this on the mlvm-dev mailing list, because I think it concerns internal MHs implementation. > > While replacing some inner classes with lambdas in java.lang.UNIXProcess class, a jtreg test started failing. This test is employing a security manager with an unusual configuration. It defines "java.util" as a package for which access should be checked against the set of permissions. The class initialization of UNIXProcess class initializes some lambdas and their initialization fails with the following stack-trace: > > > java.lang.ExceptionInInitializerError > at java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(DirectMethodHandle.java:256) > at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:221) > at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:210) > at java.lang.invoke.DirectMethodHandle.make(DirectMethodHandle.java:82) > at java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:1638) > at java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:1602) > at java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:1778) > at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1727) > at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:442) > at java.lang.UNIXProcess$Platform.get(UNIXProcess.java:147) > at java.lang.UNIXProcess.(UNIXProcess.java:160) > at java.lang.ProcessImpl.start(ProcessImpl.java:130) > at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023) > at java.lang.Runtime.exec(Runtime.java:620) > at java.lang.Runtime.exec(Runtime.java:485) > at SecurityManagerClinit.main(SecurityManagerClinit.java:70) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:484) > at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) > at java.lang.Thread.run(Thread.java:744) > Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.java.util") > at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457) > at java.security.AccessController.checkPermission(AccessController.java:884) > at java.lang.SecurityManager.checkPermission(SecurityManager.java:541) > at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1481) > * at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:305)* > at java.lang.ClassLoader.loadClass(ClassLoader.java:359) > at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:83) > * at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:54)* > at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41) > at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:911) > at java.lang.invoke.MemberName.getMethodType(MemberName.java:144) > at java.lang.invoke.LambdaForm.computeInitialPreparedForms(LambdaForm.java:477) > at java.lang.invoke.LambdaForm.(LambdaForm.java:1641) > > > I think I found the root cause of the problem. It's nothing wrong with the test (although making "java.util" as an access-checked package is a little unusual). The problem, I think, is in MH's LambdaForm implementation. Although the UNIXProcess class is a system class (loaded by bootstrap class loader), MHs created by evaluating lambda expressions in this class, trigger loading a class in "java.util" package using AppClassLoader as the initiating class loader, which involves package access checks. This should not happen, I think, if only the system classes are involved in constructing MHs. > > I checked the code and there's a ClassLoader parameter passed to the *BytecodeDescriptor.parseMethod *method. This ClassLoader is taken as the defining class loader of the MemberName's declaring class for which the getMethoType() is requested. All the types involved in such MemberName (return type, parameter types) should be resolvable from the MemberName's declaring class' class loader. In our case, the class loader of the declaring class of the particular MemberName is bootstrap class loader, so null is passed as the ClassLoader parameter to the *BytecodeDescriptor.parseMethod *method. This method checks for null ClassLoader and replaces it with ClassLoader.getSystemClassLoader() before calling parseSig() with it, because parseSig() uses the ClassLoader instance to invoke loadClass() method on it. The ClassLoader.getSystemClassLoader() is the application class-loader (AppClassLoader). > > I think the right thing to do would be to use bootstrap class loader if the ClassLoader parameter passed to *BytecodeDescriptor.parseMethod *was null. The fix would be as follows: > > > =================================================================== > --- jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770:8371276d52c0) > +++ jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770+:8371276d52c0+) > @@ -43,8 +43,6 @@ > > static List> parseMethod(String bytecodeSignature, > int start, int end, ClassLoader loader) { > - if (loader == null) > - loader = ClassLoader.getSystemClassLoader(); > String str = bytecodeSignature; > int[] i = {start}; > ArrayList> ptypes = new ArrayList>(); > @@ -80,7 +78,7 @@ > i[0] = endc+1; > String name = str.substring(begc, endc).replace('/', '.'); > try { > - return loader.loadClass(name); > + return Class.forName(name, false, loader); > } catch (ClassNotFoundException ex) { > throw new TypeNotPresentException(name, ex); > } > > > > What do you think? Am I right? > > > Regards, Peter -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From headius at headius.com Thu Apr 24 07:44:27 2014 From: headius at headius.com (Charles Oliver Nutter) Date: Thu, 24 Apr 2014 15:44:27 +0800 Subject: FORK Message-ID: What would it take to make Hotspot forkable? Obviously we'd need to pause all VM threads and restarting them on the other side (or perhaps a prefork mode that doesn't spin up threads?) but I know there's challenges with signal handlers etc. I ask for a few reasons... * Dalvik has shown what you can do with a "larval" preforking setup. This is a big reason why Android apps can run in such a small amount of memory and start up so quickly. * Startup time! If we could fork an already-hot JVM, we could hit the ground running with *every* command, *and* still have truly separate processes. * There's a lot of development and scaling patterns that depend on forking, and we get constant questions about forking on JRuby. * Rubinius -- a Ruby VM with partially-concurrent GC, a signal-handling thread, JIT threads, and real parallel Ruby threads -- supports forking. They bring the threads to a safe point, fork, and restart them on the other side. Color me jealous. So...given that OpenJDK is rapidly expanding into smaller-profile devices and new languages and development patterns, perhaps it's time to make it fit into the UNIX philosophy. Where do we start? - Charlie From christian.thalinger at oracle.com Thu Apr 24 17:42:36 2014 From: christian.thalinger at oracle.com (Christian Thalinger) Date: Thu, 24 Apr 2014 07:42:36 -1000 Subject: FORK In-Reply-To: References: Message-ID: On Apr 23, 2014, at 9:44 PM, Charles Oliver Nutter wrote: > What would it take to make Hotspot forkable? Obviously we'd need to > pause all VM threads and restarting them on the other side (or perhaps > a prefork mode that doesn't spin up threads?) but I know there's > challenges with signal handlers etc. > > I ask for a few reasons... > > * Dalvik has shown what you can do with a "larval" preforking setup. > This is a big reason why Android apps can run in such a small amount > of memory and start up so quickly. > * Startup time! If we could fork an already-hot JVM, we could hit the > ground running with *every* command, *and* still have truly separate > processes. > * There's a lot of development and scaling patterns that depend on > forking, and we get constant questions about forking on JRuby. > * Rubinius -- a Ruby VM with partially-concurrent GC, a > signal-handling thread, JIT threads, and real parallel Ruby threads -- > supports forking. They bring the threads to a safe point, fork, and > restart them on the other side. Color me jealous. > > So...given that OpenJDK is rapidly expanding into smaller-profile > devices and new languages and development patterns, perhaps it's time > to make it fit into the UNIX philosophy. Where do we start? Good question. I think you should bring this up on the hotspot-dev mailing list. People from the runtime team might have some input to this (at least I hope; because I don?t, really). > > - Charlie > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From peter.levart at gmail.com Fri Apr 25 10:04:34 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 25 Apr 2014 12:04:34 +0200 Subject: RFR: 8000975: (process) Merge UNIXProcess.java.bsd & UNIXProcess.java.linux (& .solaris & .aix) In-Reply-To: References: <5332F00D.1020806@gmail.com> <5332FDD5.8030801@oracle.com> <533ABC14.50304@gmail.com> <533AC3E9.3060406@oracle.com> <533ADEB3.2040306@gmail.com> <533AF19A.1060709@gmail.com> <533B17CA.6030203@oracle.com> <533BEB31.6050307@gmail.com> <533C0DFF.5020508@oracle.com> <533C3549.3030602@gmail.com> <533F06FC.40102@oracle.com> <534FF438.7000601@gmail.com> <53504C52.3020509@gmail.com> Message-ID: <535A3332.4070909@gmail.com> This is a ping for any Reviewer and also a question for Vladimir. Hello Vladimir, What do you think about the classloader issue in the resolving of classes in MemberName.getMethodType() described below? Regards, Peter On 04/23/2014 04:21 PM, Paul Sandoz wrote: > Hi Peter, > > IMHO such security manager usage by the test is v. fragile and we should try and find a safer alternative if possible. > > However, there may also be an issue with lambda form code. (About a month ago i too was looking, internally, at this kind of issue and thought there was a questionable use of the application/system class loader when initializing the LambdaForm class, but then i got distracted with other stuff and forgot about it.) > > Your one-liner fix seems to do the trick, but I think we need Vladimir to confirm this is OK. > > Paul. > > On Apr 17, 2014, at 11:49 PM, Peter Levart wrote: > >> Hi, >> >> I'm cross-posting this on the mlvm-dev mailing list, because I think it concerns internal MHs implementation. >> >> While replacing some inner classes with lambdas in java.lang.UNIXProcess class, a jtreg test started failing. This test is employing a security manager with an unusual configuration. It defines "java.util" as a package for which access should be checked against the set of permissions. The class initialization of UNIXProcess class initializes some lambdas and their initialization fails with the following stack-trace: >> >> >> java.lang.ExceptionInInitializerError >> at java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(DirectMethodHandle.java:256) >> at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:221) >> at java.lang.invoke.DirectMethodHandle.preparedLambdaForm(DirectMethodHandle.java:210) >> at java.lang.invoke.DirectMethodHandle.make(DirectMethodHandle.java:82) >> at java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:1638) >> at java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:1602) >> at java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:1778) >> at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1727) >> at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:442) >> at java.lang.UNIXProcess$Platform.get(UNIXProcess.java:147) >> at java.lang.UNIXProcess.(UNIXProcess.java:160) >> at java.lang.ProcessImpl.start(ProcessImpl.java:130) >> at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023) >> at java.lang.Runtime.exec(Runtime.java:620) >> at java.lang.Runtime.exec(Runtime.java:485) >> at SecurityManagerClinit.main(SecurityManagerClinit.java:70) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.lang.reflect.Method.invoke(Method.java:484) >> at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) >> at java.lang.Thread.run(Thread.java:744) >> Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.java.util") >> at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457) >> at java.security.AccessController.checkPermission(AccessController.java:884) >> at java.lang.SecurityManager.checkPermission(SecurityManager.java:541) >> at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1481) >> * at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:305)* >> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >> at sun.invoke.util.BytecodeDescriptor.parseSig(BytecodeDescriptor.java:83) >> * at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:54)* >> at sun.invoke.util.BytecodeDescriptor.parseMethod(BytecodeDescriptor.java:41) >> at java.lang.invoke.MethodType.fromMethodDescriptorString(MethodType.java:911) >> at java.lang.invoke.MemberName.getMethodType(MemberName.java:144) >> at java.lang.invoke.LambdaForm.computeInitialPreparedForms(LambdaForm.java:477) >> at java.lang.invoke.LambdaForm.(LambdaForm.java:1641) >> >> >> I think I found the root cause of the problem. It's nothing wrong with the test (although making "java.util" as an access-checked package is a little unusual). The problem, I think, is in MH's LambdaForm implementation. Although the UNIXProcess class is a system class (loaded by bootstrap class loader), MHs created by evaluating lambda expressions in this class, trigger loading a class in "java.util" package using AppClassLoader as the initiating class loader, which involves package access checks. This should not happen, I think, if only the system classes are involved in constructing MHs. >> >> I checked the code and there's a ClassLoader parameter passed to the *BytecodeDescriptor.parseMethod *method. This ClassLoader is taken as the defining class loader of the MemberName's declaring class for which the getMethoType() is requested. All the types involved in such MemberName (return type, parameter types) should be resolvable from the MemberName's declaring class' class loader. In our case, the class loader of the declaring class of the particular MemberName is bootstrap class loader, so null is passed as the ClassLoader parameter to the *BytecodeDescriptor.parseMethod *method. This method checks for null ClassLoader and replaces it with ClassLoader.getSystemClassLoader() before calling parseSig() with it, because parseSig() uses the ClassLoader instance to invoke loadClass() method on it. The ClassLoader.getSystemClassLoader() is the application class-loader (AppClassLoader). >> >> I think the right thing to do would be to use bootstrap class loader if the ClassLoader parameter passed to *BytecodeDescriptor.parseMethod *was null. The fix would be as follows: >> >> >> =================================================================== >> --- jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770:8371276d52c0) >> +++ jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java (revision 9770+:8371276d52c0+) >> @@ -43,8 +43,6 @@ >> >> static List> parseMethod(String bytecodeSignature, >> int start, int end, ClassLoader loader) { >> - if (loader == null) >> - loader = ClassLoader.getSystemClassLoader(); >> String str = bytecodeSignature; >> int[] i = {start}; >> ArrayList> ptypes = new ArrayList>(); >> @@ -80,7 +78,7 @@ >> i[0] = endc+1; >> String name = str.substring(begc, endc).replace('/', '.'); >> try { >> - return loader.loadClass(name); >> + return Class.forName(name, false, loader); >> } catch (ClassNotFoundException ex) { >> throw new TypeNotPresentException(name, ex); >> } >> >> >> >> What do you think? Am I right? >> >> >> Regards, Peter From paul.sandoz at oracle.com Fri Apr 25 10:44:23 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 25 Apr 2014 12:44:23 +0200 Subject: RFR: 8000975: (process) Merge UNIXProcess.java.bsd & UNIXProcess.java.linux (& .solaris & .aix) In-Reply-To: <535A3332.4070909@gmail.com> References: <5332F00D.1020806@gmail.com> <5332FDD5.8030801@oracle.com> <533ABC14.50304@gmail.com> <533AC3E9.3060406@oracle.com> <533ADEB3.2040306@gmail.com> <533AF19A.1060709@gmail.com> <533B17CA.6030203@oracle.com> <533BEB31.6050307@gmail.com> <533C0DFF.5020508@oracle.com> <533C3549.3030602@gmail.com> <533F06FC.40102@oracle.com> <534FF438.7000601@gmail.com> <53504C52.3020509@gmail.com> <535A3332.4070909@gmail.com> Message-ID: On Apr 25, 2014, at 12:04 PM, Peter Levart wrote: > This is a ping for any Reviewer and also a question for Vladimir. > > Hello Vladimir, > > What do you think about the classloader issue in the resolving of classes in MemberName.getMethodType() described below? > I looked a bit more closely and no longer think the one-liner will is sufficient, since it will break the behaviour of MethodType.fromMethodDescriptorString: public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader) throws IllegalArgumentException, TypeNotPresentException /** * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor. * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. * Any class or interface name embedded in the descriptor string * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)} * on the given loader (or if it is null, on the system class loader). The observations do suggest there may be some unexpected future surprises in store for bootclasspath code in restricted packages when a SM is enabled. (The more code we can get off the boot classpath the better off we will be.... hopefully Jigsaw FTW!) It is be better if the jtreg process test did not monkey around with the restricted package list, it's asking for a poke in the eye! IMHO we should prioritize fixing the test rather than fixing the lambda code to make that test work. Paul. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From peter.levart at gmail.com Fri Apr 25 16:28:32 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 25 Apr 2014 18:28:32 +0200 Subject: RFR: 8000975: (process) Merge UNIXProcess.java.bsd & UNIXProcess.java.linux (& .solaris & .aix) In-Reply-To: References: <5332F00D.1020806@gmail.com> <5332FDD5.8030801@oracle.com> <533ABC14.50304@gmail.com> <533AC3E9.3060406@oracle.com> <533ADEB3.2040306@gmail.com> <533AF19A.1060709@gmail.com> <533B17CA.6030203@oracle.com> <533BEB31.6050307@gmail.com> <533C0DFF.5020508@oracle.com> <533C3549.3030602@gmail.com> <533F06FC.40102@oracle.com> <534FF438.7000601@gmail.com> <53504C52.3020509@gmail.com> <535A3332.4070909@gmail.com> Message-ID: <535A8D30.90806@gmail.com> On 04/25/2014 12:44 PM, Paul Sandoz wrote: > On Apr 25, 2014, at 12:04 PM, Peter Levart wrote: > >> This is a ping for any Reviewer and also a question for Vladimir. >> >> Hello Vladimir, >> >> What do you think about the classloader issue in the resolving of classes in MemberName.getMethodType() described below? >> > I looked a bit more closely and no longer think the one-liner will is sufficient, since it will break the behaviour of MethodType.fromMethodDescriptorString: > > public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader) > throws IllegalArgumentException, TypeNotPresentException > > /** > * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor. > * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. > * Any class or interface name embedded in the descriptor string > * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)} > * on the given loader (or if it is null, on the system class loader). Ah, yes - I missed that part. MethodType.fromMethodDescriptorString() is public API with defined specification, so we can't change that. It is sensible for public API to use null as the system class loader. But all internal usages would be more correct, I think, if null meant the bootstrap class loader. So perhaps the right fix for this is to create a package-private variant of this method (say parseMethodDescriptorString()) which would work as expected for internal usage... > > The observations do suggest there may be some unexpected future surprises in store for bootclasspath code in restricted packages when a SM is enabled. (The more code we can get off the boot classpath the better off we will be.... hopefully Jigsaw FTW!) > > It is be better if the jtreg process test did not monkey around with the restricted package list, it's asking for a poke in the eye! > > IMHO we should prioritize fixing the test rather than fixing the lambda code to make that test work. > > Paul. Agreed. Regards, Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: