RE: Proposed API for JEP 259: Stack-Walking API
Hi Mandy, I like the API shape and this capability is very much needed. Thanks! It does bring something related to mind and that is that the current Java ecosystem is already very dependent on accurate stack frames (i.e. not removing them when inlining) and with this API this will probably only become worse. So it might be worth considering making this a hard spec requirement. Regards, Jeroen > -Original Message- > From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On > Behalf Of Mandy Chung > Sent: Friday, October 30, 2015 20:05 > To: core-libs-dev> Subject: Proposed API for JEP 259: Stack-Walking API > > JEP 259: http://openjdk.java.net/jeps/259 > > Javadoc for the proposed StackWalker API: > > http://cr.openjdk.java.net/~mchung/jdk9/jep259/api/java/lang/StackWalker > .html > > A simple way to walk the stack: > >StackWalker walker = new > StackWalker(StackWalker.Option.CLASS_REFERENCE); >walker.walk((s) -> s.filter(f -> > interestingClasses.contains(f.getDeclaringClass())).findFirst()); > > The current usage of sun.reflect.Reflection.getCallerClass(int depth) > can be replaced with this StackWalker API. > > Any feedback on the proposed API is appreciated. > > Mandy > > P.S. webrev of the current implementation: >http://cr.openjdk.java.net/~mchung/jdk9/jep259/webrev.00/ > > > > > >
RE: RFR: Faster ZipFile.getEntry()/entries()
Hi Sherman, As a (minor) data point, IKVM.NET has been using a pure Java ZipFile implementation since day one (based on the GNU Classpath version) and other than a few compat bugs in the early days people have never complained about it. For obvious reasons, I'd certainly prefer the pure Java version (to minimize the amount of work I have to do ;-)), but I've also always thought that it was quite a hard sell that the native zip code was faster than pure Java code, given the overhead of JNI and the cost of native memory interop/pinning. Regards, Jeroen -Original Message- From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On Behalf Of Xueming Shen Sent: Wednesday, May 21, 2014 23:19 To: core-libs-dev@openjdk.java.net Subject: Re: RFR: Faster ZipFile.getEntry()/entries() Hi, This one didn't make into jdk8. Here is an updated webrev for the jdk9 repo http://cr.openjdk.java.net/~sherman/zipfile_j/webrev And a pure java version of j.u.ZipFile is also available at http://cr.openjdk.java.net/~sherman/zipfile_jj/webrev/ We do have incident reports and requests that suggest a pure Java version of j.u.ZipFile might be preferred, especially to eliminate the possibility of jvm crash at native level, mostly triggered by the mmap usage and/or use scenario that the target zip/jar file is being overwritten while reading. And java implementation also brings in the benefits of better memory usage (all memory allocated in java heap), no more expensive jni invocations... Opinion/comments are appreciated. Thanks! -Sherman On 09/05/2013 04:16 PM, Xueming Shen wrote: Hi, The change proposed here is to bring the zip entry handing code from the native level to the java level. This effectively solves the performance issues of ZipFile.getEntry and entries() that is caused by multiple jni invocation steps to generate one single ZipEntry (see ZipFile.getZipEntry()). A simple non-scientific benchmark test of simply iterating the ZipFile via the Enumeration from entries() on rt.jar/charsets.jar suggests a 50%+ speed boost. http://cr.openjdk.java.net/~sherman/zipfile_j/webrev Couple notes: (1) Ideally it might be desired to go further to bring all the native code of ZipFile to java level (which should help completely remove that mmap crash issue, have better file and memory management... ), but it is suggested that it might be better to limit the scope of the change at this late release circle. (2) JavaFile.read0() is the version that uses getPrimitiveArrayCritical to read file bits into the java array directly (instead of using a stack buffer and then copy into the java array), which appears to be 5% faster. But I can't make up my mind of which one would be better. Given (1) the trouble we had before in De/Infalter code (when the getPrimitiveArrayCritical is being heavily used), (2) FileInputStream uses the same copy approach, I'm staying with the copy appraoch, but option appreciated. (3) We will have to keep the native implementation (zip_util.c) for the vm directly access. Thanks! -Sherman
RE: JEP 193: Enhanced Volatiles
David Holmes wrote: But if the JVM acts upon annotations to change how it executes those bytecodes then, as Peter said, the JVM is implementing the language semantics. The JVM synthesizes a native method, this has *nothing* to do with language semantics. From the language point of view, native method implementations magically appear. This is just another instance of that. Regards, Jeroen
RE: JEP 193: Enhanced Volatiles
The JVM should be picking up the annotations (otherwise, you'd still need to design a public API to deal with atomics). BTW, it was explained to me at the JVM Language Summit that the commonly held belief about annotations, is not in fact true. Regards, Jeroen -Original Message- From: paulus.benedic...@gmail.com [mailto:paulus.benedic...@gmail.com] On Behalf Of Paul Benedict Sent: Wednesday, March 5, 2014 16:19 To: Christoph Engelbert Cc: Jeroen Frijters; core-libs-dev@openjdk.java.net Subject: Re: JEP 193: Enhanced Volatiles This idea really close very the commonly held belief that annotations shouldn't be used to extend the language -- and thus will not be accepted. If the compiler is picking up these annotations to emit different code, that is obviously shoehorning annotations into a language feature. On Wed, Mar 5, 2014 at 1:51 AM, Christoph Engelbert m...@noctarius.com mailto:m...@noctarius.com wrote: Am 05.03.2014 um 08:40 schrieb Jeroen Frijters jer...@sumatra.nl mailto:jer...@sumatra.nl : My goal here is to make sure that expert users can get their job done somehow, *without* making the job of mainstream developers harder. The add lvalues to Java so experts can write CAS-libraries fails that test miserably. Why not go for something far less intrusive then? Here's my straw man proposal: Add an annotation that can be placed on native methods to synthesize atomic accessor methods. Example usage: @AtomicField(next) private native boolean compareAndSet(Node expected, Node newValue); @AtomicArray private static native boolean compareAndSet(Node[] array, Node expected, Node newValue); (Note that the method name is not significant, the operation can be derived from the signature, or explicit in the annotation, if necessary.) This requires no changes to the language and adds only a slight burden on the developer (but it's very easy to add tooling support). Regards, Jeroen That looks like a good fit towards what was mentioned earlier using method handles. The JVM or compiler could just look out for those annotations and generate corresponding method / field handles to execute it. Thanks, Chris -- Cheers, Paul
RE: JEP 193: Enhanced Volatiles
Brian Goetz wrote: I'm all for unintrusive. Though note that the intrusiveness metric on language features I(f) is not uniform across observers :) Indeed :-) Here's my straw man proposal: Add an annotation that can be placed on native methods to synthesize atomic accessor methods. I suspect you were expecting this response: we don't add language semantics through annotations. Technically, we're not adding language semantics. The JVM is the one interpreting the annotations. BTW, as I mentioned in another post in this thread, I specifically asked about this at the JVM Language Summit (in 2012 IIRC) and the answer was (by Alex IIRC) that there is no such rule. I'm not trying to frustrate you; evolving a language with millions of users is really, really hard. And one of the things that makes it hard is recognizing our intrinsic conflicts of interest between what good will this do me and what harm will it do others. I understand, that's why I want to avoid adding language support for this niche/specialist feature. Regards, Jeroen
RE: JEP 193: Enhanced Volatiles
Sorry Peter, but that is a nonsensical definition of language semantics. By using your definition, if Microsoft adds a feature to the CLR using custom attributes, the Java language semantics change, because on IKVM you can use these custom attributes in your Java code. Regards, Jeroen -Original Message- From: Peter Levart [mailto:peter.lev...@gmail.com] Sent: Wednesday, March 5, 2014 18:07 To: Jeroen Frijters; Brian Goetz; core-libs-dev@openjdk.java.net; Doug Lea Subject: Re: JEP 193: Enhanced Volatiles On 03/05/2014 05:55 PM, Jeroen Frijters wrote: Brian Goetz wrote: I suspect you were expecting this response: we don't add language semantics through annotations. Technically, we're not adding language semantics. The JVM is the one interpreting the annotations. And the JVM is the one implementing the language semantics (together with javac which feeds the JVM with bytecodes). Language semantcis are implemented by the combination of javac and JVM. If you say that this feature does not require any change to javac, you're just saying that you put all the burden on the JVM, but you *are* implementing the language semantics using annotations nevertheless... Regards, Peter I'm not trying to frustrate you; evolving a language with millions of users is really, really hard. And one of the things that makes it hard is recognizing our intrinsic conflicts of interest between what good will this do me and what harm will it do others. I understand, that's why I want to avoid adding language support for this niche/specialist feature. Regards, Jeroen
RE: JEP 193: Enhanced Volatiles
Brian Goetz wrote: Right now, the semantics of method calls in Java are simple -- everything (primitives, object references) is passed by value. Adding pass-by-reference would add significant complexity. And method calls are not a niche feature; that added complexity will be borne by every developer, every day. We'll just have to disagree on this. VB developers are not more sophisticated than Java developers and they've dealt with ByRef just fine (even though many don't understand it). In practice they don't run into it that often. My goal here is to make sure that expert users can get their job done somehow, *without* making the job of mainstream developers harder. The add lvalues to Java so experts can write CAS-libraries fails that test miserably. Why not go for something far less intrusive then? Here's my straw man proposal: Add an annotation that can be placed on native methods to synthesize atomic accessor methods. Example usage: @AtomicField(next) private native boolean compareAndSet(Node expected, Node newValue); @AtomicArray private static native boolean compareAndSet(Node[] array, Node expected, Node newValue); (Note that the method name is not significant, the operation can be derived from the signature, or explicit in the annotation, if necessary.) This requires no changes to the language and adds only a slight burden on the developer (but it's very easy to add tooling support). Regards, Jeroen
RE: JEP 193: Enhanced Volatiles
Brian Goetz wrote: Embedded in this proposal is the desire to not provide a full-blown lvalue form for variables; supporting any form of pass-by-reference at the language level is a super-non-goal here. Why is this? It solves these problems in an extremely clean way and also provides lots of other value (for example, for JEP 191: Foreign Function Interface). I understand pass-by-reference is an expensive feature, but IMNSHO poluting Java with this proposal will prove to be more expensive in the long run. It's like erased generics all over again. Regards, Jeroen
RE: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods
David Holmes wrote: I don't think this is workable. Exposing a monitor as Lock would allow you to break the guarantees/requirements involving balanced-locking for monitors. Where are these guarantees/requirements documented? Regards, Jeroen
RE: Request: Remove System.out check from Class.checkInitted()
System.out can be null, because System.setOut(null) is legal. Regards, Jeroen From: David Holmes [mailto:david.hol...@oracle.com] Sent: Thursday, December 19, 2013 11:14 To: Alan Bateman Cc: Jeroen Frijters; core-libs-dev@openjdk.java.net Subject: Re: Request: Remove System.out check from Class.checkInitted() On 4/12/2013 7:00 PM, Alan Bateman wrote: On 04/12/2013 08:24, Jeroen Frijters wrote: Hi, I'd like to propose to change Class.checkInitted() to check if the VM initialization has completed by using sun.misc.VM.isBooted() instead of System.out != null. This should be changed (I can only guess that whoever added this wasn't aware of VM.isBooted). Not necessarily. The question is, are there any code paths that lead to checkInitted being called after setOut0(newPrintStream(fdOut, props.getProperty(sun.stdout.encoding))) but before the call to sun.misc.VM.booted(). If so these would fail under the proposed change. The initialization sequence is fragile and intimately tied to the Hotspot VM - ie the VM initialization process initiates the core class initialization. In a normal initialization System is initialized before Class and Class must be initialized before checkInitted can be called, so this doesn't trigger initialization of System. I also don't see how System.out being null can be valid post- initialization state given the call to setOut0(newPrintStream(fdOut, props.getProperty(sun.stdout.encoding))) David - -Alan.
Request: Remove System.out check from Class.checkInitted()
Hi, I'd like to propose to change Class.checkInitted() to check if the VM initialization has completed by using sun.misc.VM.isBooted() instead of System.out != null. The current check needlessly triggers System class initialization (thus complicating bootstrap initialization order on VMs that don't have a strict initialization bootstrap) and is also not strictly correct, because System.out == null is a valid state after initialization has completed. Thanks, Jeroen
RE: shared value in java.lang.StringBuilder
John Rose wrote: I think the next interesting version of String will mix header and body together in a hybrid layout, with private char (or byte) elements and a few instance variables at the beginning of the layout. It would be good to prepare for this by modifying the JNI spec to explicitly disallow AllocObject (and subsequent constructor invocations) on String. Regards, Jeroen
RE: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass
Hi Mandy, Thank you. Patch looks good. Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Mandy Chung Sent: Friday, November 1, 2013 19:16 To: core-libs-dev@openjdk.java.net Subject: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass Webrev at: http://cr.openjdk.java.net/~mchung/jdk8/webrevs/8027351/webrev.00/ This fixes the finalization implementation to invoke the finalize method via shared secret so that it will call the same method as the bytecode invocation. The current implementation uses JNI_GetMethodID to find the finalize method of a given instance. JNI_GetMethodID returns the private finalize method which gets invoked during finalization (which is different than the method looked up via invokevirtual). If there is a static method matching the name and descriptor, it will throw NoSuchMethodError even if the base class has a matching instance method. JDK-8027270 is filed for this JNI_GetMethodID issue. This change replaces the JNI call to the finalize method with the shared secret as Jeroen suggests [1]. This will resolve this bug independent of JDK-8027270 and also avoid the overhead of the JNI calls. The behavioral change with this fix should rarely impact any existing application. It would only impact code that defines a finalize method in a base class and also a private finalize method in a subclass. The only way to have a private finalize method is to write to the bytecode directly. thanks Mandy P.S. I would love to use Martin's beloved GcFinalization utility that we can extend our testlibrary in the future. The new regression test is simple enough that a counter would do its work. [1] http://weblog.ikvm.net/PermaLink.aspx?guid=87432f77-7e58-4f37-9f6d- d5bac453c7d6 [2] https://bugs.openjdk.java.net/browse/JDK-8027351
RE: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass
Hi Mandy (and Mark), The getter can be optimized away, the static field can't, so this is probably a tiny bit more expensive. Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Mandy Chung Sent: Friday, November 1, 2013 22:11 To: mark.reinh...@oracle.com Cc: core-libs-dev@openjdk.java.net Subject: Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass On 11/1/13 1:37 PM, mark.reinh...@oracle.com wrote: 2013/11/1 4:15 -0700, mandy.ch...@oracle.com: http://cr.openjdk.java.net/~mchung/jdk8/webrevs/8027351/webrev.00/ Looks good. Just one question: In Finalizer.java, at line 97 you look up the JavaLangAccess object every single time. Is it worth caching that earlier, maybe when the finalize thread starts, since it will never change? I was expecting that would get optimized during runtime and it's a simple getter method. It's a good suggestion to cache it at the finalize thread start time and here is the revised webrev: http://cr.openjdk.java.net/~mchung/jdk8/webrevs/8027351/webrev.01/ Thanks for the review. Mandy
RE: Thoughts on adding getElementClass() method to StackTraceElement?
Nick Williams wrote: What if we also added a getStackFrames() method to Throwable? That would meet my needs but it would also satisfy what I'm observing is a desire to have a new API for this (StackFrame) instead of adding it to StackTraceElement. I'm very open to how it's implemented, as long as it satisfies my use case. :-) The stack trace of a Throwable can be filled in on demand when getStackTrace() is called the first time, so that the overhead isn't incurred when creating and throwing the exception. Presumably, we would need to do something similar with getStackFrames(), especially since calling it would be less common. Thoughts on this? Yes that is reasonable, but I'd add a static method to StackFrame instead. Something like StackFrame[] capture(Throwable). Regards, Jeroen
RE: Time to put a stop to Thread.stop?
IMO Thread.currentThread().stop(new Throwable()) should continue to work. It is not unsafe and it is probably used in a lot of code to workaround the madness that is checked exceptions. -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Alan Bateman Sent: Tuesday, May 14, 2013 16:25 To: core-libs-dev Subject: Time to put a stop to Thread.stop? I would like to broach the subject of pulling out the implementation of Thread.stop(Throwable), maybe suspend/resume later. By pulling out I mean changing it to unconditionally throw UnsupportedOperationException. As we all know, these methods have been deprecated since 1998 so that's 15 years to design out any need for these methods. That said, I periodically come across code that uses no-arg Thread.stop(). David Holmes mentioned to me recently that he came across a usage in the recent past too. I don't think I've ever come across code using Thread.stop(Throwable) and this one is arguably the most dangerous of the group. So I'm curious if anyone has come across a Thread.stop(Throwable) usage in recent times. Clearly changing this would be a significant change but the real impact might be close to zero. If we decide this is the right thing to do then there is a bit of detail to work out, that's for later. -Alan.
RE: Time to put a stop to Thread.stop?
I agree that (ab)using generics is the better way, but that doesn't matter, this trick is much older so it is probably used somewhere and there is no good reason to break it. I'm fully in favor of removing the ability to throw arbitrary exceptions on other threads. IKVM doesn't support this and I've never seen any code break. Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Remi Forax Sent: Tuesday, May 14, 2013 17:29 To: core-libs-dev@openjdk.java.net Subject: Re: Time to put a stop to Thread.stop? On 05/14/2013 04:45 PM, Jeroen Frijters wrote: IMO Thread.currentThread().stop(new Throwable()) should continue to work. It is not unsafe and it is probably used in a lot of code to workaround the madness that is checked exceptions. This hack doesn't work well because Thread.stop(Throwable) can call the security manager. Using a raw type to see an Exception as a RuntimeException is a better hack, obviously tunnelling the exception in a runtimee one (as a cause) is the safe way to do that. Rémi -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Alan Bateman Sent: Tuesday, May 14, 2013 16:25 To: core-libs-dev Subject: Time to put a stop to Thread.stop? I would like to broach the subject of pulling out the implementation of Thread.stop(Throwable), maybe suspend/resume later. By pulling out I mean changing it to unconditionally throw UnsupportedOperationException. As we all know, these methods have been deprecated since 1998 so that's 15 years to design out any need for these methods. That said, I periodically come across code that uses no-arg Thread.stop(). David Holmes mentioned to me recently that he came across a usage in the recent past too. I don't think I've ever come across code using Thread.stop(Throwable) and this one is arguably the most dangerous of the group. So I'm curious if anyone has come across a Thread.stop(Throwable) usage in recent times. Clearly changing this would be a significant change but the real impact might be close to zero. If we decide this is the right thing to do then there is a bit of detail to work out, that's for later. -Alan.
RE: Review request for 7198429: need checked categorization of caller-sensitive methods in the JDK
Hi, Thanks for this. This is a really great change. I reviewed the changes and my only comment is that there is a typo in java/lang/reflect/Field.java (scurity). Somewhat unrelated (but relevant for my implementation of CallerSensitive), but would it be possible to mark java.lang.Runtime as final, or at least make the CallerSensitive methods final? The interaction between CallerSensitive and method overriding is non trivial, so IMO it is best avoided. Thanks, Jeroen From: core-libs-dev-boun...@openjdk.java.net [core-libs-dev-boun...@openjdk.java.net] on behalf of Mandy Chung [mandy.ch...@oracle.com] Sent: Wednesday, April 03, 2013 8:49 PM To: John Rose Cc: Christian Thalinger; core-libs-dev Subject: Re: Review request for 7198429: need checked categorization of caller-sensitive methods in the JDK This version has corrected to use Class.getMethod to determine if the checkMemberAccess method is overridden in the subclass: http://cr.openjdk.java.net/~mchung/jdk8/webrevs/7198429/webrev.02/ thanks Mandy On 4/2/2013 9:25 PM, John Rose wrote: So getDM has a bug and getM is correct wrt inheritance. Thanks Peter!
RE: JDK 8 code review request for JDK-8004979 java.lang.reflect.Modifier.toString should include default
Hi Joe, I notice that Method.isDefault() returns true for static interface methods. I assume that is not correct. Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Joe Darcy Sent: Thursday, March 28, 2013 8:03 To: Core-Libs-Dev Subject: JDK 8 code review request for JDK-8004979 java.lang.reflect.Modifier.toString should include default Hello, Please review these changes to add support for the default modifier to the output of Method.to[Generic]String: 8004979 java.lang.reflect.Modifier.toString should include default http://cr.openjdk.java.net/~darcy/8004979.0/ Patch also included below. Thanks, -Joe diff -r d254a5f9b93f src/share/classes/java/lang/reflect/Constructor.java --- a/src/share/classes/java/lang/reflect/Constructor.javaWed Mar 27 13:40:26 2013 -0400 +++ b/src/share/classes/java/lang/reflect/Constructor.javaThu Mar 28 00:02:06 2013 -0700 @@ -284,9 +284,13 @@ * modifiers {@code public}, {@code protected} or * {@code private}. Only one of these may appear, or none if the * constructor has default (package) access. + * + * @return a string describing this {@code Constructor} + * @jls 8.8.3. Constructor Modifiers */ public String toString() { return sharedToString(Modifier.constructorModifiers(), + false, parameterTypes, exceptionTypes); } @@ -328,10 +332,11 @@ * include type parameters * * @since 1.5 + * @jls 8.8.3. Constructor Modifiers */ @Override public String toGenericString() { -return sharedToGenericString(Modifier.constructorModifiers()); +return sharedToGenericString(Modifier.constructorModifiers(), false); } @Override diff -r d254a5f9b93f src/share/classes/java/lang/reflect/Executable.java --- a/src/share/classes/java/lang/reflect/Executable.javaWed Mar 27 13:40:26 2013 -0400 +++ b/src/share/classes/java/lang/reflect/Executable.javaThu Mar 28 00:02:06 2013 -0700 @@ -89,20 +89,24 @@ } -void printModifiersIfNonzero(StringBuilder sb, int mask) { +void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) { int mod = getModifiers() mask; if (mod != 0) { sb.append(Modifier.toString(mod)).append(' '); } +if (isDefault) { +sb.append(default ); +} } String sharedToString(int modifierMask, + boolean isDefault, Class?[] parameterTypes, Class?[] exceptionTypes) { try { StringBuilder sb = new StringBuilder(); -printModifiersIfNonzero(sb, modifierMask); +printModifiersIfNonzero(sb, modifierMask, isDefault); specificToStringHeader(sb); sb.append('('); @@ -124,11 +128,11 @@ */ abstract void specificToStringHeader(StringBuilder sb); -String sharedToGenericString(int modifierMask) { +String sharedToGenericString(int modifierMask, boolean isDefault) { try { StringBuilder sb = new StringBuilder(); -printModifiersIfNonzero(sb, modifierMask); +printModifiersIfNonzero(sb, modifierMask, isDefault); TypeVariable?[] typeparms = getTypeParameters(); if (typeparms.length 0) { diff -r d254a5f9b93f src/share/classes/java/lang/reflect/Field.java --- a/src/share/classes/java/lang/reflect/Field.javaWed Mar 27 13:40:26 2013 -0400 +++ b/src/share/classes/java/lang/reflect/Field.javaThu Mar 28 00:02:06 2013 -0700 @@ -288,6 +288,9 @@ * {@code protected} or {@code private} first, and then other * modifiers in the following order: {@code static}, {@code final}, * {@code transient}, {@code volatile}. + * + * @return a string describing this {@code Field} + * @jls 8.3.1 Field Modifiers */ public String toString() { int mod = getModifiers(); @@ -315,6 +318,7 @@ * its generic type * * @since 1.5 + * @jls 8.3.1 Field Modifiers */ public String toGenericString() { int mod = getModifiers(); diff -r d254a5f9b93f src/share/classes/java/lang/reflect/Method.java --- a/src/share/classes/java/lang/reflect/Method.javaWed Mar 27 13:40:26 2013 -0400 +++ b/src/share/classes/java/lang/reflect/Method.javaThu Mar 28 00:02:06 2013 -0700 @@ -343,10 +343,16 @@ * {@code public}, {@code protected} or {@code private} first, * and then other modifiers in the following order: * {@code abstract}, {@code static}, {@code final}, - * {@code
RE: JEP 176: Mechanical Checking of Caller-Sensitive Methods
John Rose wrote: Remi's idea (using invokedynamic) makes a good proof of concept, too. But because we use getCallerClass to observe a non-forgeable caller identity, the @CS mechanism has to be something that works underneath any visible bytecode pattern, at least in the caller. Yes. In IKVM CallerID also serves the purpose of making it non-forgeable by the caller. The CallerID object that is passed must be a subclass of CallerID that is nested inside the class it represents, that way .NET code can't forge a CallerID either (for Java code it is a non-issue since it can't see the CallerID parameter anyway). Thinking out loud... In JVM terms, a @CS method might also be implemented with two entry points like this: class ImportantSystemAPI { ... /** Returns the name of the class of the calling method. */ @CallerSensitive public static String currentClassName() { return currentClassName(Reflection.getCallerClass()); } private static String currentClassName(Class caller) { return caller.getName(); } } Maybe I'm misunderstanding, but I think my preference would be to hide the pattern from the Java developers, making the code less verbose and less fragile. HotSpot could simply add the extra parameter and turn Reflection.getCallerClass() into an intrinsic that loads the parameter. In fact, the derived values are more interesting than the class itself. I haven't used it beyond Class and ClassLoader, but the CallerID indirection does make it easy to cache additional information (at the expense of having a field in every CallerID instance). And if we are ever to share linkage information across classes (a desirable thing, judging by experience in the ME world) then we need to be able to make resolved @CS sites be applicable across a group of classes (all sharing a common package or CL). I don't think I understand this bit, but one thing my scheme lacks is a distinction between requiring the caller's Class and just its ClassLoader. It would be more efficient to be able to share a single CallerID between all classes in a ClassLoader. Regards, Jeroen
RE: JEP 176: Mechanical Checking of Caller-Sensitive Methods
Hi John, This is really great. I've been using an annotation for caller sensitive methods for many year in IKVM as a performance enhancement and I can say that my experiences with my simple mechanism are really great. I've got a class ikvm.internal.CallerID that looks something like this: public final class CallerID { @Internal (IKVM specific annotation meaning that it is only public in the module) public native Call getCallerClass(); @Internal public native ClassLoader getClassClassLoader(); @Internal public static native getCallerID(); } Any (trusted) method with an ikvm.internal.HasCallerID annotation can call the CallerID.getCallerID() intrinsic and from there on the CallerID object gets explicitly passed around to other methods when necessary. I modified sun.reflect.MethodAccessor.invoke() to have an additional CallerID parameter and MethodHandles.Lookup is also CallerID based. JNI methods automatically act as if they have a HasCalleriD annotation and store the caller on a stack inside the thread's JNIEnv. (I'm not suggesting HotSpot uses the same design, that probably doesn't make sense. Just that in the many years I've used this, I've found the explicit caller sensitive annotation and explicitly passing around a cookie that represents the caller to be an efficient and secure way to handle this.) Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of mark.reinh...@oracle.com Sent: Friday, March 1, 2013 18:59 To: john.r.r...@oracle.com Cc: core-libs-dev@openjdk.java.net Subject: JEP 176: Mechanical Checking of Caller-Sensitive Methods Posted: http://openjdk.java.net/jeps/176 - Mark
RE: JEP 176: Mechanical Checking of Caller-Sensitive Methods
Remi Forax wrote: I've always found that getCallerClass() was done at the wrong side of the problem, i.e. asked inside the callee instead of being inserted at callsite. Yes, I agree and in fact in the IKVM implementation a CallerID parameter is added to each method that has the HasCallerID annotation. The reason for the CallerID abstraction instead of simply passing a Class is performance. Constructing a Class is expensive on IKVM (and was even more expensive back when CallerID was introduced) and in many cases caller sensitive methods are only sometimes caller sensitive, so I want the class construction to be lazy. It's also possible to return the ClassLoader without actually constructing the class. From the .NET side an IKVM HasCallerID method looks something like this: public class Class { [EditorBrowsable(Never)] // hide from .NET IDEs public static Class forName(String name, CallerID callerID) { ... } public static Class forName(String name) { return forName(name, CallerID.create(new StackFrame(1))); } } The Java compiler calls the method with the explicit CallerID parameter and .NET code can simply call the other method. Regards, Jeroen
RE: @Supported design issues
I agree, but at the same time CLASS retention is really the worst of both worlds in my opinion. It doesn't have any (convenient) runtime benefit, but you can be sure that someone will depend on it at runtime by parsing the class files (this happens surprisingly often). I'd really like to see this be SOURCE initially and only after it is well understood, move it to RUNTIME in some future version of the platform (and then make it a public API instead of a jdk specific thing). Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Martin Buchholz Sent: Saturday, February 23, 2013 0:42 To: mark.reinh...@oracle.com Cc: core-libs-dev@openjdk.java.net Subject: Re: @Supported design issues One more thought. @Supported has RUNTIME retention, and it will be inevitable that some people will check the annotation at runtime. As a practical matter, once the annotation is added, it will never be removed (or removed only if the corresponding API is itself removed), (for fear of breaking someone), including by third parties like IcedTea.
RE: CloneNotSupportedException should extends RuntimeException not Exception
Hi Rémi, The point about a non-final class being cloneable is simply that a base class can always implement Cloneable, so that interface is currently meaningless. With the static method approach, the Cloneable interface becomes a valid way to opt in to that, but I see two downsides to the static method approach: 1. Once you allow your object to be cloneable, you can't prevent others from cloning your instances. So this pattern wouldn't work: public Foo copy() { Foo theCopy = (Foo)shallowClone(); theCopy.someArray = theCopy.someArray.clone(); return theCopy; } 2. The Cloneable interface check is an unnecessary perf hit. The admittedly ugly downcast in the above code can be easily optimized away. The perf is not a showstopper, but 1. is in my opinion. Regards, Jeroen From: Remi Forax [fo...@univ-mlv.fr] Sent: Monday, October 15, 2012 7:08 PM To: Jeroen Frijters Cc: David Holmes; core-libs-dev@openjdk.java.net Subject: Re: CloneNotSupportedException should extends RuntimeException not Exception Hi Jeroen, On 10/15/2012 01:48 PM, Jeroen Frijters wrote: The solution is actually pretty easy. Just deprecate Object.clone() and add a new method to Object: protected final native Object shallowClone(); It doesn't require the useless Cloneable interface and doesn't conflate shallow and deep cloning. (This is similar to .NET's Object.MemberwiseClone().) Note that this means that any non-final class is cloneable, BUT THAT IS ALREADY THE CASE even though some people want to pretend otherwise. To avoid collisions it can be a static method of Object or j.u.Objects that uses generics to be nicely typed. static native T T shallowClone(T object); and I disagree about Cloneable, while a non-final class is by definition mutable, it doesn't mean that a non final class can be cloned because it may share some states that should not be shared, at least without the consent from the author the class. The other nice property is that any cloneable class will be publicly cloneable. I also believe that the checkcast generated by javac before calling shallowClone can be removed by the JIT, currently this cast is not removed when you call clone. Regards, Jeroen regards, Rémi
RE: CloneNotSupportedException should extends RuntimeException not Exception
I wrote: The point about a non-final class being cloneable is simply that a base class can always implement Cloneable, so that interface is currently meaningless. Obviously that should read ... a derived class can always implement Cloneable... Regards, Jeroen From: core-libs-dev-boun...@openjdk.java.net [core-libs-dev-boun...@openjdk.java.net] on behalf of Jeroen Frijters [jer...@sumatra.nl] Sent: Monday, October 15, 2012 9:30 PM To: Remi Forax Cc: David Holmes; core-libs-dev@openjdk.java.net Subject: RE: CloneNotSupportedException should extends RuntimeException not Exception Hi Rémi, The point about a non-final class being cloneable is simply that a base class can always implement Cloneable, so that interface is currently meaningless. With the static method approach, the Cloneable interface becomes a valid way to opt in to that, but I see two downsides to the static method approach: 1. Once you allow your object to be cloneable, you can't prevent others from cloning your instances. So this pattern wouldn't work: public Foo copy() { Foo theCopy = (Foo)shallowClone(); theCopy.someArray = theCopy.someArray.clone(); return theCopy; } 2. The Cloneable interface check is an unnecessary perf hit. The admittedly ugly downcast in the above code can be easily optimized away. The perf is not a showstopper, but 1. is in my opinion. Regards, Jeroen From: Remi Forax [fo...@univ-mlv.fr] Sent: Monday, October 15, 2012 7:08 PM To: Jeroen Frijters Cc: David Holmes; core-libs-dev@openjdk.java.net Subject: Re: CloneNotSupportedException should extends RuntimeException not Exception Hi Jeroen, On 10/15/2012 01:48 PM, Jeroen Frijters wrote: The solution is actually pretty easy. Just deprecate Object.clone() and add a new method to Object: protected final native Object shallowClone(); It doesn't require the useless Cloneable interface and doesn't conflate shallow and deep cloning. (This is similar to .NET's Object.MemberwiseClone().) Note that this means that any non-final class is cloneable, BUT THAT IS ALREADY THE CASE even though some people want to pretend otherwise. To avoid collisions it can be a static method of Object or j.u.Objects that uses generics to be nicely typed. static native T T shallowClone(T object); and I disagree about Cloneable, while a non-final class is by definition mutable, it doesn't mean that a non final class can be cloned because it may share some states that should not be shared, at least without the consent from the author the class. The other nice property is that any cloneable class will be publicly cloneable. I also believe that the checkcast generated by javac before calling shallowClone can be removed by the JIT, currently this cast is not removed when you call clone. Regards, Jeroen regards, Rémi
RE: code review request: 7051946: Runtime.exec(String command) / ProcessBuilder command parsing issues
Hi, I'm not a formal reviewer, but I've implemented this same thing for IKVM.NET which has to simulate the behavior of CreateProcess when running on Windows (because it uses the .NET API to start a process and that doesn't have this hack). Your algorithm doesn't match CreateProcess, because that also takes into account various directories to search (the application's directory, the current directory, the system directory, the windows directory and the PATH). Regards, Jeroen From: core-libs-dev-boun...@openjdk.java.net [core-libs-dev-boun...@openjdk.java.net] on behalf of Michael McMahon [michael.x.mcma...@oracle.com] Sent: Tuesday, September 13, 2011 6:17 PM To: core-libs-dev@openjdk.java.net Subject: code review request: 7051946: Runtime.exec(String command) / ProcessBuilder command parsing issues Can I get the following webrev reviewed please? http://cr.openjdk.java.net/~michaelm/7051946/webrev.1/ The problem is when calling Runtime.exec(String) with a program name containing white space (on win32), it is difficult to distinguish between the program name and any parameters to it. Eg. C:\A B\C D\E foo bar. Does this string represent the program name or are foo and bar arguments to a program called E? And there are many other possibilities. We just pass the whole string to windows and it does an ok job of disambiguating according to a defined algorithm. There are two problems however: 1) our security check doesn't do exactly the same thing as windows. So we may end up checking for a different file to what gets executed. 2) when the file doesn't exist, the error returned is truncated. In the example above, it would think C:\A is the non-existing program. The problem doesn't occur on Solaris/Linux because those OSes never try to disambiguate the way windows does. So, there is currently already consistency between the security check and the path to be run. Effectively, this way of calling Runtime.exec() never worked on those platforms and you always had to use one of the other multi-arg methods. So, the solution is first to refactor ProcessBuilder and ProcessImpl, by moving the generation of the exception down to ProcessImpl (when the file is not found) and also to move the security check down to ProcessImpl, where we can do the windows specific checking, and for Solaris and Windows there's no change in behavior beyond that. Thanks, Michael.
RE: Suspected regression: fix for 6735255 causes delay in GC of ZipFile InputStreams, increase in heap demand
Xueming Shen wrote: I'm not a GC guy, so I might be missing something here, but if close() is being explicitly invoked by some thread, means someone has a strong reference to it, I don't think the finalize() can kick in until that close() returns This is not correct. You can re-publish the reference from another finalizer method and thereby allow another thread to access the object concurrently with the finalizer. Here's a possible sequence of events: 1) GC runs and determines that A and B are finalizable 2) Finalizer thread run A.finalize() 3) A.finalize publishes reference to B in static variable 4a) Another thread reads the static variable and calls B.close() 4b) Finalizer thread runs B.finalize() Regards, Jeroen
RE: Code review request for 4881419 The type of X[].clone() should be X[]
David Holmes wrote: The fact that Object.clone() is implemented via a native call into the VM is simply an implementation detail. That's not what we're talking about. We're talking about the fact that arrays (appear to) have a *public* clone method. The argument is about the return type[1] of this method: according to the JLS it is X[], but according to the VMSpec it is Object. This difference is fine, but I'm arguing that the JLS fiction should be in the JLS, not in the Object.clone() documentation. Regards, Jeroen [1] Not the runtime class of the object returned.
RE: Code review request for 4881419 The type of X[].clone() should be X[]
Sorry to be late with my comment, but as a VM implementer I can't really agree with this modification. The return type of X[].clone() is clearly Object, not X{]. That illusion is a javac compiler trick. IMHO it belongs in the JLS not in the Object.clone() documentation. Regards, Jeroen -Original Message- From: core-libs-dev-boun...@openjdk.java.net [mailto:core-libs-dev- boun...@openjdk.java.net] On Behalf Of Joe Darcy Sent: Saturday, September 04, 2010 12:01 AM To: Martin Buchholz Cc: core-libs-dev Subject: Re: Code review request for 4881419 The type of X[].clone() should be X[] Martin Buchholz wrote: On Thu, Sep 2, 2010 at 17:50, Joe Darcy joe.da...@oracle.com mailto:joe.da...@oracle.com wrote: Martin Buchholz wrote: The usage T[] suggests that T is a reference type, as with generics, which is not the case here. More precisely, both the runtime types and compiletime types of the object returned from clone of any array is identical to its input. Is there a non-confusing way of saying that? How about ...and that the return type of the {...@code clone} method of an array type {...@code T[]} is {...@code T[]} where T is either a reference or a primitive type.? So I went and actually read the Object.clone spec, and it does indeed guarantee that the (runtime) class of the returned value is the same as the class of the argument, for arrays. As for the compile-time type, an experiment demonstrates that the return type is indeed exactly the same, including for non-reifiable array element types, e.g. this compiles: Class? extends Number[] a = (Class? extends Number[]) (new Class?[42]); Class? extends Number[] clone = a.clone(); So Ulf's restriction to non-reifiable T seems not to be correct. My suggested wording is: ...and that the return type of the {...@code clone} method of an array type {...@code T[]} is {...@code T[]} where T is any reference or primitive type. Martin Objects have class; Variables have type Sounds good to me; change pushed! Thanks, -Joe
RE: Threads should not be Cloneable
David Holmes wrote: Fortunately, as Brian stated, compatibility is not an end unto itself here and we often do have documented incompatibilities across major releases. In this case there is far more harm, in my opinion, leaving the possibility of people trying to clone threads than there is in breaking a hypothetical program that is unlikely to be functioning correctly anyway. Thread should never have been cloneable in any way - the fact that this has flown under the radar for so long is a strong indicator that nobody actually does this in practice (else they would have complained that it didn't work). I really don't understand your position. It clearly doesn't make sense to call Object.clone() on a Thread, but you can have a perfectly safe clone() on a Thread subclass: public final MyCloneableThread extends Thread { public Object clone() { return new MyCloneableThread(); } } On the other hand, there is no reason to make clone() in Thread final other than some vague notion that you want to prevent people from writing new code like the above, but given that Java is an old and stable platform that argument doesn't carry much weight either. BTW, from a security standpoint, overriding clone doesn't help. An attacker can simply create a Thread subclass that doesn't have the ACC_SUPER flag set and that class will be able to call Object.clone() just fine. Regards, Jeroen
RE: Date precision on Windows
Andrew Haley wrote: Please, someone tell me Windows isn't still using the old 18.2 Hz DOS timer for its system clock. No Not that it is true, but why would that be bad? By default (most) multi core/cpu Windows systems run at a 15 ms timer interrupt interval (10 ms for single cpu/core systems), but programs can request a smaller interval (down to 1 ms). Running the timer interrupt at a lower frequency helps if you care about throughput and/or battery life. Regards, Jeroen