Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-02 Thread Peter Levart


On 11/01/2013 10:11 PM, Mandy Chung wrote:

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



Hi Mandy,

FWIW, I don't know if you gain anything by caching static field in a 
static field, performance wise.It looks nicer at use site though. If 
performance was really extremely important in this use case (which I 
think is not) then jla should be a local variable inside 
FinalizerThread.run() (and possibly in the anonymous Runnables too) and 
passed as an argument to Finalizer.runFinalizer().


Looking at code once more, I see a possible data race. Is it remotely 
possible, that either Finalizer.runFinalization() or 
Finalizer.runAllFinalizers() is executed and new secondary finalizer 
thread spawned and executed before FinalizerThread manages to call 
ensureAccessAvailable(), therefore executing the 
Finalizer.runFinalizer() methods before static Finalizer.jla is 
initialized? Even though jla field was initialized, what guarantees it's 
value being visible in spawned secondary finalizer threads? 
FinalizerThread is started in Finalizer's static initializer, yes, but 
ensureAccessAvailable() is called by FinalizerThread after it starts...


Considering all this, it might be safer to just ready the SharedSecrets 
field every time it's needed.



Regards, Peter



Assorted annotation optimizations

2013-11-02 Thread Peter Levart

Hi,

I propose a set of straightforward optimizations of annotations in the 
field of minimizing garbage creation and execution performance. Here's a 
webrev containing the changes:


http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/webrev.01/


Changes grouped by class/method:


AnnotationInvocationHandler.invoke(): Use reference comparison among 
interned strings instead of equals() to dispatch the invocation and use 
Method.getParameterCount() instead of Method.getParameterTypes() to 
avoid creating Class[] array for each invocation.


AnnotationInvocationHandler.toStringImpl(): Use StringBuilder instead of 
StringBuffer


AnnotationInvocationHandler.equalsImpl(): Don't call asOneOfUs(o) in a 
loop for each member and restructure the code to have basically two 
independent implementations: the one based on memberValues map if the 
other annotation is OneOfUs (the common case) and the one based on 
AnnotationType.members() map of member methods. Caching of member 
methods privately in each AnnotationInvocationHandler instance is not 
needed - use the AnnotationType.members() map instead - this improves 
annotation instance footprint too.


AnnotationInvocationHandler.getMemberValue(): new static package-private 
method used in AnnotationSupport for fast retrieval of shared value 
array in container annotations.



AnnotationSupport.getDirectlyAndIndirectlyPresent(): minimize number of 
garbage objects and array copies. This method delegates to 
getSharedIndirectlyPresent() which might return a shared array which is 
only cloned if needed.


AnnotationSupport.getSharedIndirectlyPresent(): private method instead 
of getIndirectlyPresent() that may return a shared array.


AnnotationSupport.getSharedValueArray(): private method that may return 
a shared array. This method is based on new 
AnnotationInvocationHandler.getMemberValue() method and now also 
incorporates a call to checkTypes().


AnnotationSupport.getValueArray(): now based on getSharedValueArray() 
and cloneArray()


AnnotationSupport.cloneArray(): new private method which clones the array

AnnotationSupport.newArray(): new private constructor for annotation 
arrays (to localize @SuppressWarnings(unchecked))



AnnotationType constructor: member Methods are now all made 
setAccessible(true) in advance so that value member method for 
container annotations doesn't need to be made setAccessible(true) each 
time a container of a particular type is flattened.



All in all these changes make common operations such as retrieving the 
annotation member values and obtaining repeatable annotations faster and 
with less produced garbage objects. Here are the results of some 
micro-benchmarks:


http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/perf_results.txt

These results are obtained with the following test:

http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/AnnotationDispatchPerfTest.java
http://cr.openjdk.java.net/~plevart/jdk8-tl/AnnotationOptimizations/test/si/pele/microbench/TestRunner.java


In short:
- Invoking Annotation.annotationType() is 6x faster
- Retrieving a scalar member value is 2x faster
- Annotation.equals for annotation with 3 int members is 2.5x faster
- Class.getDeclaredAnnotationsByType for direct-only case is 2x faster
- Class.getDeclaredAnnotationsByType for in-direct-only case is 2.2x faster
- Class.getDeclaredAnnotationsByType for mixed case is 1.7x faster



So what do you think?

Regards, Peter



Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-03 Thread Peter Levart

On 11/04/2013 05:45 AM, Mandy Chung wrote:


On 11/3/2013 5:32 PM, David Holmes wrote:

Hi Mandy,

On 2/11/2013 7:11 AM, Mandy Chung wrote:

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/


I'm missing something basic - how did you get this to compile:

   public void invokeFinalize(Object o) throws Throwable {
 o.finalize();
   }

given finalize is protected ??



protected members can be accessed by the same package and subclasses.  
This is the implementation of JavaLangAccess in java.lang.System that 
is in the same package as java.lang.Object.


Also VM.awaitBooted seems inherently risky as a general method as you 
would have to make sure that it is never called by the main VM 
initialization thread. Perhaps handle this in 
sun.misc.SharedSecrets.getJavaLangAccess so it is less 'general'? 


That sounds a good idea.  Let me think about it and get back to this.

That said I think Peter may be right that there could be races with 
agents triggerring explicit finalization requests early in the VM 
initialization process - which means any blocking operation dependent 
on other parts of the initialization sequence could be problematic.


Hmm... agents calling System.runFinalization during startup - like 
Alan described, the agent is playing fire.


Hi Mandy,

Isn't System.runFinalization() just a hint? Like System.gc() for 
example...


 * p
 * Calling this method suggests that the Java Virtual Machine expend
 * effort toward running the codefinalize/code methods of objects
 * that have been found to be discarded but whose codefinalize/code
 * methods have not yet been run. When control returns from the
 * method call, the Java Virtual Machine has made a *best effort* to
 * complete all outstanding finalizations.
 * p

Couldn't the request just be ignored when called before VM.isBooted() ? 
The finalizers will be executed nevertheless asynchronously later by the 
finalizer thread...


Regards, Peter



The potential issue that could happen is that during the VM 
initialization the heap is so small that triggers GC and also the 
startup code has finalizers and those objects with finalizers are 
awaiting for finalization in order for the sufficient memory to be 
freed up.  The VM initialization couldn't get completed and the 
Finalizer thread is blocked and thus due to insufficient memory, 
eventually it would get out of memory.  An agent instrumenting classes 
early in the startup and creates lots of objects and finalizers, that 
might also cause problem.


I think it's good to have the secondary finalizer thread to call 
ensureAccessAvailable (with some modification to ensure jla is 
initialized).




Overall I think a safer approach may be to fix the native JNI code so 
that if it gets a private version of finalize() it looks up the 
method in the superclass.


There is other issue (e.g. static method with same name/descriptor) 
that JNI_GetMethodID has to resolve.  This will be a bigger change in 
the VM that probably can't make jdk8.


I think the proposed patch with slight change in the secondary 
finalizer thread is a relative safe approach (I wil revise the patch 
and send out another rev tomorrow).


thanks
Mandy




Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-03 Thread Peter Levart

On 11/04/2013 07:52 AM, Peter Levart wrote:
Also VM.awaitBooted seems inherently risky as a general method as 
you would have to make sure that it is never called by the main VM 
initialization thread. Perhaps handle this in 
sun.misc.SharedSecrets.getJavaLangAccess so it is less 'general'? 


That sounds a good idea.  Let me think about it and get back to this.

That said I think Peter may be right that there could be races with 
agents triggerring explicit finalization requests early in the VM 
initialization process - which means any blocking operation 
dependent on other parts of the initialization sequence could be 
problematic.


Hmm... agents calling System.runFinalization during startup - like 
Alan described, the agent is playing fire.


Hi Mandy,

Isn't System.runFinalization() just a hint? Like System.gc() for 
example...


 * p
 * Calling this method suggests that the Java Virtual Machine expend
 * effort toward running the codefinalize/code methods of objects
 * that have been found to be discarded but whose 
codefinalize/code

 * methods have not yet been run. When control returns from the
 * method call, the Java Virtual Machine has made a *best effort* to
 * complete all outstanding finalizations.
 * p

Couldn't the request just be ignored when called before VM.isBooted() 
? The finalizers will be executed nevertheless asynchronously later by 
the finalizer thread...


...if you do it like the following:

/* Called by Runtime.runFinalization() */
static void runFinalization() {
if (VM.isBooted()) { // ignore requests early in the VM boot-up sequence
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
running = true;
for (;;) {
Finalizer f = (Finalizer)queue.poll();
if (f == null) break;
f.runFinalizer();
}
}
});
}
 }

*and* use the SharedSecrets.getJavaLangAccess() directly, the code also 
passes the formal proof of having no data races, since you have the 
following sequence:


boot-up thread:

  write to SharedSecrets.javaLangAccess
  volatile write to VM.booted

thread calling getJavaLangAccess():

  volatile read from VM.booted
  read from SharedSecrets.javaLangAccess


I still don't see any advantage of caching JavaLangAccess instance in a 
private static Finalizer.jla field other than to complicate synchronization.


Regards, Peter



Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-04 Thread Peter Levart

On 11/04/2013 05:45 AM, Mandy Chung wrote:
That said I think Peter may be right that there could be races with 
agents triggerring explicit finalization requests early in the VM 
initialization process - which means any blocking operation dependent 
on other parts of the initialization sequence could be problematic.


Hmm... agents calling System.runFinalization during startup - like 
Alan described, the agent is playing fire.


The potential issue that could happen is that during the VM 
initialization the heap is so small that triggers GC and also the 
startup code has finalizers and those objects with finalizers are 
awaiting for finalization in order for the sufficient memory to be 
freed up.  The VM initialization couldn't get completed and the 
Finalizer thread is blocked and thus due to insufficient memory, 
eventually it would get out of memory.  An agent instrumenting classes 
early in the startup and creates lots of objects and finalizers, that 
might also cause problem.


I think it's good to have the secondary finalizer thread to call 
ensureAccessAvailable (with some modification to ensure jla is 
initialized). 


Hi Mandy,

What about the following helper class in java.lang package:


package java.lang;

import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;

/**
 * Access to protected Object methods. Only accessible to system classes.
 */
public final class ObjectAccess {
private static final ObjectAccess theInstance = new ObjectAccess();

@CallerSensitive
public static ObjectAccess getInstance() {
Class? caller = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(caller.getClassLoader()))
throw new SecurityException(ObjectAccess);
return theInstance;
}

public void finalizeObject(Object o) throws Throwable {
o.finalize();
}

public Object cloneObject(Object o) throws CloneNotSupportedException {
return o.clone();
}
}


...is such code permissible to be executed in the Finalizer's static 
initializer even before VM.isBooted() ?



Regards, Peter



Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-04 Thread Peter Levart

On 11/04/2013 09:48 AM, Alan Bateman wrote:

On 04/11/2013 08:33, Peter Levart wrote:

:

What about the following helper class in java.lang package:
If public then it leaks into the Java SE API. I think using 
SharedSecrets should be okay, assuming we can sort out any potential 
races getting to JavaLangAccess.


-Alan.


The problem is that we would like Finalizers to be executed even before 
VM.isBooted(). Currently this is possible, because native code is used 
to access Object.finalize(). java.lang.Thread is initialized earlier, 
but initializing SharedSecrets.javaLangAccess in Thread's static 
initializer doesn't work (VM crashes). I think this is because 
SharedSecrets also initialize sun.misc.Unsafe via .getUnsafe() method 
and this needs the caller ClassLoader to check access... SharedSecrets 
is already too encumbered to be used that early in boot-up sequence.


So what about the following simple class in sun.misc:


package sun.misc;

/**
 * Access to protected Object methods.
 */
public abstract class ObjectAccess {
private static ObjectAccess theInstance;

public static ObjectAccess getInstance() {
return theInstance;
}

public static void setInstance(ObjectAccess instance) {
theInstance = instance;
}

public abstract void finalizeObject(Object o) throws Throwable;
}


...with the following initialization in java.lang.Thread:


public
class Thread implements Runnable {
/* Make sure registerNatives is the first thing clinit does. */
private static native void registerNatives();
static {
registerNatives();
*sun.misc.ObjectAccess.setInstance(new ObjectAccess() {**
**@Override**
**public void finalizeObject(Object o) throws Throwable {**
**o.finalize();**
**}**
**});*
}


I tried executing JVM with these two changes and is seems to work - i.e. 
does not cause JVM to crash at startup.


Regards, Peter



Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-04 Thread Peter Levart

On 11/05/2013 03:21 AM, Mandy Chung wrote:

On 11/4/2013 6:03 PM, David Holmes wrote:

Hi Mandy,

This all seems quite reasonable to me.

Two minor nits:

1. The delay ntil typo in Finalizer.java is still present.



Missed that :(

2. In VM.java. booted need not be volatile now that it is only 
accessed within a locked region. Also awaitBooted might as well be 
void as it can only ever return true.




Fixed.  Revised webrev at:
http://cr.openjdk.java.net/~mchung/jdk8/webrevs/8027351/webrev.03/


Hi Mandy,

Just a nit. You are assigning SharedSecrets.getJavaLangAccess() to a 
local 'jla' variable declared outside Runnables, which makes it 
effectively a final field. You could declare and assign the 'jla' inside 
run() methods of both Runnables, just before the loop - like it is done 
in the FinalizerThread...


Regards, Peter

P.S. I'm curious about the strange seemingly unneeded code fragments in 
FinalizerThread and both Runnables. For example:


 169 forkSecondaryFinalizer(new Runnable() {
 170*private volatile boolean running;*
 171 public void run() {
 172*if (running)*
 173*return;*
 174*running = true;*
 

The FinalizerThread and each Runnable instance is only executed once. 
Why these checks then? Does anybody know?



Regards, Peter



Thanks for the review.
Mandy


Thanks,
David

On 5/11/2013 6:04 AM, Mandy Chung wrote:

Thank you all for the suggestions.

Before the VM initialization is completed, any agent ought to be 
careful
in what things it can do and what shouldn't do.  I think it's 
reasonable

to ignore System.runFinalization if it's called at early startup phase.
I'm unclear if there is any use case that we really require 
finalization
to happen before VM is booted (I can imagine other problems may 
happen).

I change the runFinalization and runAllFinalizers methods to return if
it's not booted and also change runFinalizer method to take
JavaLangAccess to simplify the synchronization instead of caching it in
the static field.

http://cr.openjdk.java.net/~mchung/jdk8/webrevs/8027351/webrev.02/

David - I decided to leave VM.awaitBooted as it is.  Having the 
callsite

to call awaitBooted makes it explicit and clear that it's blocking and
we will keep SharedSecrets.getJavaLangAccess method consistent with the
other SharedSecrets methods that they are all getter methods. If any
future change calls SharedSecrets.getJavaLangAccess before it's booted,
it's a little easier to diagnose (NPE vs hangs).

Peter - thanks for the ObjectAccess idea.  I don't think supporting
finalization to happen before VM is booted buys us anything and I would
rather keep this change simple.

Mandy






Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-05 Thread Peter Levart

Hi Robert,

I think this fix is not complete. When one sets the system property 
sun.reflect.noInflation=true, reflection proxy is still attempted to be 
generated for anonymous classes (see 
ReflectionFactory.newMethodAccessor/newConstructorAccessor).


I would also restructure the Method/Constructor accessor logic 
differently. The check for ReflectUtil.isVMAnonymousClass() can be 
performed just once (in the newMethodAccessor/newConstructorAccessor 
methods) and based on this check, create accessor:


- for classic declaring class - as is / unchanged
- for anonymous declaring class - just create and return 
NativeMethodAccessorImpl without a parent


Then in NativeMethodAccessorImpl (and same for constructor), modify the 
inflation checking logic:


if (*parent != null  *++numInvocations  
ReflectionFactory.inflationThreshold()) {

MethodAccessorImpl acc = (MethodAccessorImpl)
new MethodAccessorGenerator().
generateMethod(method.getDeclaringClass(),
   method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
parent.setDelegate(acc);
}

Regards, Peter

On 11/04/2013 07:12 PM, robert.fi...@oracle.com wrote:

Changeset: 51b002381b35
Author:rfield
Date:  2013-11-04 10:12 -0800
URL:   http://hg.openjdk.java.net/jdk8/tl/jdk/rev/51b002381b35

7194897: JSR 292: Cannot create more than 16 instances of an anonymous class
8027681: Lambda serialization fails once reflection proxy generation kicks in
Reviewed-by: ksrini, briangoetz, jfranck
Contributed-by: joel.fra...@oracle.com, brian.go...@oracle.com, 
robert.fi...@oracle.com

! src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
! src/share/classes/sun/reflect/NativeMethodAccessorImpl.java
! src/share/classes/sun/reflect/misc/ReflectUtil.java
+ test/java/lang/invoke/lambda/RepetitiveLambdaSerialization.java
! 
test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
+ test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java





Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-05 Thread Peter Levart

On 11/04/2013 07:12 PM, robert.fi...@oracle.com wrote:

Changeset: 51b002381b35
Author:rfield
Date:  2013-11-04 10:12 -0800
URL:   http://hg.openjdk.java.net/jdk8/tl/jdk/rev/51b002381b35

7194897: JSR 292: Cannot create more than 16 instances of an anonymous class
8027681: Lambda serialization fails once reflection proxy generation kicks in
Reviewed-by: ksrini, briangoetz, jfranck
Contributed-by: joel.fra...@oracle.com, brian.go...@oracle.com, 
robert.fi...@oracle.com

! src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
! src/share/classes/sun/reflect/NativeMethodAccessorImpl.java
! src/share/classes/sun/reflect/misc/ReflectUtil.java
+ test/java/lang/invoke/lambda/RepetitiveLambdaSerialization.java
! 
test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
+ test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java


Hi Robert,

I also propose a much faster variant of:

+ /**
+ * Checks if {@code Class cls} is a VM-anonymous class
+ * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+ * (not to be confused with a Java Language anonymous inner class).
+ */
+ public static boolean isVMAnonymousClass(Class? cls) {
+ return cls.getSimpleName().contains(/);
+ }


The following:

public static boolean isVMAnonymousClassFAST(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '.') return false;
if (c == '/') return true;
}
return false; // root package
}

It's about 12..25x faster for typical class names and doesn't produce 
any garbage.



Regards, Peter



Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-05 Thread Peter Levart

Hi John,

Speaking of names, the following test:

package pkg;

public class Test {
public static void main(String[] args)
{
Runnable r = () - {};
Class? c = r.getClass();
Class? ac = java.lang.reflect.Array.newInstance(c, 0).getClass();
System.out.println(c:  + c.getName() +  /  + 
c.getSimpleName());
System.out.println(ac:  + ac.getName() +  /  + 
ac.getSimpleName());

}
}


Prints:

c: pkg.Test$$Lambda$1/798154996 / Test$$Lambda$1/798154996
ac: [Lpkg.Test$$Lambda$1; / Test$$Lambda$1/798154996[]


I think the array class name is missing the trailing '/798154996' just 
before ';'



Regards, Peter

On 11/05/2013 09:55 AM, Peter Levart wrote:

On 11/04/2013 07:12 PM, robert.fi...@oracle.com wrote:

Changeset: 51b002381b35
Author:rfield
Date:  2013-11-04 10:12 -0800
URL:http://hg.openjdk.java.net/jdk8/tl/jdk/rev/51b002381b35

7194897: JSR 292: Cannot create more than 16 instances of an anonymous class
8027681: Lambda serialization fails once reflection proxy generation kicks in
Reviewed-by: ksrini, briangoetz, jfranck
Contributed-by:joel.fra...@oracle.com,brian.go...@oracle.com,robert.fi...@oracle.com

! src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
! src/share/classes/sun/reflect/NativeMethodAccessorImpl.java
! src/share/classes/sun/reflect/misc/ReflectUtil.java
+ test/java/lang/invoke/lambda/RepetitiveLambdaSerialization.java
! 
test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
+ test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java


Hi Robert,

I also propose a much faster variant of:

+ /**
+ * Checks if {@code Class cls} is a VM-anonymous class
+ * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+ * (not to be confused with a Java Language anonymous inner class).
+ */
+ public static boolean isVMAnonymousClass(Class? cls) {
+ return cls.getSimpleName().contains(/);
+ }


The following:

public static boolean isVMAnonymousClassFAST(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '.') return false;
if (c == '/') return true;
}
return false; // root package
}

It's about 12..25x faster for typical class names and doesn't produce 
any garbage.



Regards, Peter





Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-05 Thread Peter Levart

On 11/05/2013 10:33 AM, Joel Borggrén-Franck wrote:

I would also restructure the Method/Constructor accessor logic differently. 
The check for ReflectUtil.isVMAnonymousClass() can be performed just once (in the 
newMethodAccessor/newConstructorAccessor methods) and based on this check, create 
accessor:

- for classic declaring class - as is / unchanged
- for anonymous declaring class - just create and return 
NativeMethodAccessorImpl without a parent

Then in NativeMethodAccessorImpl (and same for constructor), modify the 
inflation checking logic:

 if (parent != null  ++numInvocations  
ReflectionFactory.inflationThreshold()) {
 MethodAccessorImpl acc = (MethodAccessorImpl)
 new MethodAccessorGenerator().
 generateMethod(method.getDeclaringClass(),
method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
 parent.setDelegate(acc);
 }

I don't like adding even more special cases to this check. IMHO a better way 
that we discussed and rejected, opting for a smaller change, is to create a 
NonInflatingMethodAccessor and just drop in one of those without a delegate for 
when creating the accessor for methods/ctors on anonymous classes.


Even better. I would name the new class NativeMethodAccessorImpl and the 
one doing inflation InflatingNativeMethodAccessorImpl which would extend 
NativeMethodAccessorImpl, override invoke() and call super.invoke()... 
This way, no native methods duplication is needed. invoke() is already 
an interface method with 2 implementations. Now it will have 3. Does 
this present any difference for dispatch optimization?


Regards, Peter



cheers
/Joel




Re: JDK-8027351: (ref) Base's class finalize method not invoked if a private finalize method exists in its subclass

2013-11-05 Thread Peter Levart

On 11/05/2013 12:33 PM, Chris Hegarty wrote:

On 05/11/2013 10:59, Paul Sandoz wrote:

On Nov 5, 2013, at 8:26 AM, Peter Levartpeter.lev...@gmail.com  wrote:


P.S. I'm curious about the strange seemingly unneeded code fragments 
in FinalizerThread and both Runnables. For example:


169 forkSecondaryFinalizer(new Runnable() {
170*private volatile boolean running;*
171 public void run() {
172*if (running)*
173*return;*
174*running = true;*

The FinalizerThread and each Runnable instance is only executed 
once. Why these checks then? Does anybody know?




I was wondering that too. A Thread is an instance of Runnable. So a 
finalize method could re-exec the current finalizer thread on another 
another thread.


Right. I added these a while back to ensure that this does not happen.

-Chris.


That's really mean 8-)

Peter





Paul.




Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-06 Thread Peter Levart


On 11/06/2013 11:37 AM, Remi Forax wrote:

On 11/05/2013 11:11 AM, Joel Borggrén-Franck wrote:

On 5 nov 2013, at 10:51, Peter Levart peter.lev...@gmail.com wrote:


On 11/05/2013 10:33 AM, Joel Borggrén-Franck wrote:
I would also restructure the Method/Constructor accessor logic 
differently. The check for ReflectUtil.isVMAnonymousClass() can 
be performed just once (in the 
newMethodAccessor/newConstructorAccessor methods) and based on 
this check, create accessor:


- for classic declaring class - as is / unchanged
- for anonymous declaring class - just create and return 
NativeMethodAccessorImpl without a parent


Then in NativeMethodAccessorImpl (and same for constructor), 
modify the inflation checking logic:


 if (parent != null  ++numInvocations  
ReflectionFactory.inflationThreshold()) {

 MethodAccessorImpl acc = (MethodAccessorImpl)
 new MethodAccessorGenerator().
generateMethod(method.getDeclaringClass(),
method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
 parent.setDelegate(acc);
 }
I don't like adding even more special cases to this check. IMHO a 
better way that we discussed and rejected, opting for a smaller 
change, is to create a NonInflatingMethodAccessor and just drop in 
one of those without a delegate for when creating the accessor for 
methods/ctors on anonymous classes.
Even better. I would name the new class NativeMethodAccessorImpl and 
the one doing inflation InflatingNativeMethodAccessorImpl which 
would extend NativeMethodAccessorImpl, override invoke() and call 
super.invoke()... This way, no native methods duplication is needed. 
invoke() is already an interface method with 2 implementations. Now 
it will have 3. Does this present any difference for dispatch 
optimization?


FWIW i think the magic number is 4, but I don't know where I got 
that. Anyhow, this might be slightly controversial, but for all code 
I care about (reflective invocation of methods/ctors on 
non-VM-anonymous classes) the check happens exactly once as is.


No, the magic number is 2 (by default),
you can look for TypeProfileWidth in the vm code.


I forgot that each generated method accessor is a separate class with a 
separate method. So the number of implementations is already much more 
than 2 today...


Regards, Peter



regards,
Rémi





Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-06 Thread Peter Levart


On 11/05/2013 10:10 AM, Brian Goetz wrote:

Ineexof(char) sounds like as fast and simpler?


Well, indexOf(char) or lastIndexOf(char) searches for a single char. We 
can do better searching backwards for two chars at the same time.


If the name of VM-anonymous class is always ending with pattern: 
slash followed by some decimal digits then the following would be even 
faster:


public static boolean isVMAnonymousClassFAST(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '/') return true;
if (c  '0' || c  '9') return false;
}
return false;
}

Regards, Peter



Sent from my iPhone

On Nov 5, 2013, at 8:55 AM, Peter Levart peter.lev...@gmail.com 
mailto:peter.lev...@gmail.com wrote:



On 11/04/2013 07:12 PM, robert.fi...@oracle.com wrote:

Changeset: 51b002381b35
Author:rfield
Date:  2013-11-04 10:12 -0800
URL:http://hg.openjdk.java.net/jdk8/tl/jdk/rev/51b002381b35

7194897: JSR 292: Cannot create more than 16 instances of an anonymous class
8027681: Lambda serialization fails once reflection proxy generation kicks in
Reviewed-by: ksrini, briangoetz, jfranck
Contributed-by:joel.fra...@oracle.com,brian.go...@oracle.com,robert.fi...@oracle.com

! src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
! src/share/classes/sun/reflect/NativeMethodAccessorImpl.java
! src/share/classes/sun/reflect/misc/ReflectUtil.java
+ test/java/lang/invoke/lambda/RepetitiveLambdaSerialization.java
! 
test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
+ test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java


Hi Robert,

I also propose a much faster variant of:

+ /**
+ * Checks if {@code Class cls} is a VM-anonymous class
+ * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+ * (not to be confused with a Java Language anonymous inner class).
+ */
+ public static boolean isVMAnonymousClass(Class? cls) {
+ return cls.getSimpleName().contains(/);
+ }


The following:

public static boolean isVMAnonymousClassFAST(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '.') return false;
if (c == '/') return true;
}
return false; // root package
}

It's about 12..25x faster for typical class names and doesn't produce 
any garbage.



Regards, Peter





Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-07 Thread Peter Levart

On 11/07/2013 02:20 AM, John Rose wrote:
On Nov 6, 2013, at 11:30 AM, Peter Levart peter.lev...@gmail.com 
mailto:peter.lev...@gmail.com wrote:


Well, indexOf(char) or lastIndexOf(char) searches for a single char. 
We can do better searching backwards for two chars at the same time.


If the name of VM-anonymous class is always ending with pattern: 
slash followed by some decimal digits then the following would be 
even faster:


Although this reasoning is plausible, it is not a reliable conclusion, 
and should not drive edits of Java code without careful measurement. 
 The reasoning assumes a performance model based on the interpreter 
and bytecode count.  But performance depends on native code produced 
by the JIT.


I agree. I should have measured it...



An optimizing JIT will usually transform the code deeply.  For string 
scanning, for example, HotSpot has an intrinsic for 
String.indexOf(String) that uses totally different code from a 
user-coded loop.  (It is not currently so for String.indexOf(int), but 
String.indexOf(/) is potentially very fast.)


Also, with your example code, the combined loop may often be faster 
than two back-to-back loops, but simpler loops can sometimes be 
vectorized more robustly, to the point where back-to-back simple 
loops, if vectorized, may be competitive with a hand-fused loop.


So loop complexity and method intrinsics can create surprises for 
those who rely on simple performance modesl


Some day we will get to a world where loops are specified stream-wise, 
and robustly optimized without this sort of manual intervention.  In 
the mean time, be careful about advising hand-optimizations of Java 
code.  They can backfire, by confusing the JIT and preventing 
optimizations that would apply to simpler code.


— John


So I did measure it. I took two classes with the following names:

com.test.pkg.PerfTest$Classic$1
com.test.pkg.PerfTest$$Lambda$1/925858445

Typically package names will be even relatively longer than in this example.

I measured the following implementations:

public static boolean isVMAnonymousClass(Class? cls) {
return cls.getSimpleName().contains(/);
}

public static boolean isVMAnonymousClass_FAST1(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '.') return false;
if (c == '/') return true;
}
return false;
}

public static boolean isVMAnonymousClass_FAST2(Class? cls) {
String name = cls.getName();
for (int i = name.length() - 1; i = 0; i--) {
char c = name.charAt(i);
if (c == '/') return true;
if (c  '0' || c  '9') return false;
}
return false;
}

public static boolean isVMAnonymousClass_indexOf(Class? cls) {
return cls.getName().indexOf(/)  -1;
}


I also tried String.lastIndexOf(String) and it is a little faster for 
true return, since it only scans backwards until the / is found, but 
it is slower than String.indexOf(String) for false return. Is it not 
intrinsified?


Here are the results:

http://cr.openjdk.java.net/~plevart/jdk8-tl/isVmAnonymousClass/results.txt

I think that any of the above implementations that doesn't use 
Class.getSimpleName() is good. The FAST2 variant is favourable for false 
return since it typically decides after examining a single character at 
end of class name and is still among the fastest for true return...


Here's the code I used for testing:

http://cr.openjdk.java.net/~plevart/jdk8-tl/isVmAnonymousClass/com/test/pkg/PerfTest.java
http://cr.openjdk.java.net/~plevart/jdk8-tl/isVmAnonymousClass/si/pele/microbench/TestRunner.java


Regards, Peter



Re: Signature of MethodHandleInfo.reflectAs is not specific enough

2013-11-10 Thread Peter Levart

On 11/11/2013 02:24 AM, Ali Ebrahimi wrote:

This is another workaround:

public T extends MemberAnnotatedElement, R R reflectAs(Class? 
super T expected, Lookup lookup);


info.reflectAs(Member.class, lookup);//works
info.reflectAs(AnnotatedElement.class, lookup);//works
info.reflectAs(Member.class, lookup);//works
info.reflectAs(AnnotatedElement.class, lookup);//works


info.reflectAs(Object.class, lookup);doesn't work.
info.reflectAs(Other.class, lookup);doesn't work.

with this does not need to your javadoc and is more type safe. .


Hm... it doesn't look very compile-time type-safe:

String s = info.reflectAs(Method.class, lookup); // compiles !!!


IMO, I would rather remove the Class parameter altogether. It serves no 
purpose in the method implementation other than to perform a cast-check 
on the returned object. The method could simply be:


public T extends Member T reflect(Lookup lookup);

This would not solve the problem Remi put forward. I.e. this would not 
compile:


AnnotatedElement ae = info.reflect(lookup);

But with an explicit cast, It compiles:

AnnotatedElement ae = (AnnotatedElement) info.reflect(lookup);

And compared to what we would have with Class parameter and loosened 
compile-time type-safety as per Remi's suggestion, it is still shorter:


AnnotatedElement ae = info.reflectAs(AnnotatedElement.class, 
lookup); // this is longer!


A type-unsafe variant is possible too (I'm not advocating it):

public T T reflect(Lookup lookup);

Now that Generalized Target-Type Inference 
http://openjdk.java.net/projects/jdk8/features#101 is part of Java 8, 
using ClassT parameters just as hints to the compiler is not needed in 
many cases. But if one needs to hint the compiler, explicit type 
parameters can be used as an escape hatch as always:


Object o = info.Methodreflect(lookup);


Regards, Peter






On Mon, Nov 11, 2013 at 1:59 AM, Remi Forax fo...@univ-mlv.fr 
mailto:fo...@univ-mlv.fr wrote:


The is a stupid issue with the signature of
MethodHandleInfo.reflectAs,
j.l.r.Field, Method or Constructor implement two interfaces Member and
AnnotatedElement, with the current signature, the code
   info.reflectAs(Member.class, lookup)
works but the code
   info.reflectAs(AnnotatedElement.class, lookup)
doesn't work.

Because there is no way to do an 'or' between several bounds of
a type variable, I think that the signature of reflectAs should be
changed from :
   public T extends Member T reflectAs(ClassT expected, Lookup
lookup);
to
   public T T reflectAs(ClassT expected, Lookup lookup);

and the javadoc should be modified to explain that a Member or
AnnotatedElement are
valid bounds of T.

As a side effect, the signature of MethodHandles.reflectAs(ClassT,
MethodHandle)
should be updated accordingly.

There is a workaround, one can write:
   (AnnotatedElement)info.reflectAs(Member.class, lookup)
but it's at best weird.

cheers,
Rémi

___
mlvm-dev mailing list
mlvm-...@openjdk.java.net mailto:mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev




___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev




Re: Signature of MethodHandleInfo.reflectAs is not specific enough

2013-11-11 Thread Peter Levart

On 11/11/2013 08:14 AM, Peter Levart wrote:

The method could simply be:

public T extends Member T reflect(Lookup lookup);


But if one needs to hint the compiler, explicit type parameters can be 
used as an escape hatch as always:


Object o = info.Methodreflect(lookup);



Well, well, explicit type parameters for method invocation are not 
needed in above example:


Object o = info.reflect(lookup); // compiles

One would only need them in situations like:

info.Methodreflect(lookup).invoke(...);


Regards, Peter



Re: hg: jdk8/tl/jdk: 7194897: JSR 292: Cannot create more than 16 instances of an anonymous class; ...

2013-11-11 Thread Peter Levart

On 11/05/2013 12:29 AM, Remi Forax wrote:
But you are right that there is a performance pothole in the 
interoperation between lambdas and reflection.


This implementation RFE, to use method handles instead of code 
spinning, would take care of that particular problem:

https://bugs.openjdk.java.net/browse/JDK-6824466


I remember writing a code like that a long time ago, to see if it was 
possible,
as far as I remember, the main issue was to be able to say, please 
compiler

compile this method handle chain into a blob that I can reuse.



— John


regards,
Rémi


Hi John, Remi,

I tried to create a prototype to see how it compares to 
bytecode-generated method accessor. Here it is:


https://bugs.openjdk.java.net/browse/JDK-6824466#comment-13426571

It seems that lambda forms do their job quite well. Do experts have any 
suggestion how to improve it?


Regards, Peter



Re: Why stream from BufferedReader::lines is not closing the reader?

2013-11-18 Thread Peter Levart

On 11/18/2013 03:28 PM, Brian Goetz wrote:
Which means that, if your stream holds non-memory resources, the 
flatMapper should create a stream that closes the underlying stream, 
like:


  blah.flatMap(path - {
 BufferedReader br = new BufferedReader(path);
 return br.lines.onClose(br::close);
  }
  ... 


...the only problem with above code is that it doesn't compile, because 
of IOException declared on BufferedReader (FileReader actually!) 
constructor and BufferedReader.close() method. The solutions to this 
have already been discussed on the list some time ago, and one of the 
propositions was to create interfaces like:



public interface IOFunctionT, R extends FunctionT, R {
default R apply(T t) {
try {
return applyIO(t);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

R applyIO(T t) throws IOException;
}


public interface IORunnable  extends Runnable {
default void run() {
try {
runIO();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

void ruinIO() throws IOException;
}


...etc, and use them in code like this:


ListString paths = ...
paths
.stream()
.flatMap((IOFunctionString, StreamString) path - {
BufferedReader br = new BufferedReader(new FileReader(path));
return br.lines().onClose((IORunnable) br::close);
})
.forEach(System.out::println);



Regards, Peter




Re: CallerSensitive access rights problems

2013-11-18 Thread Peter Levart

On 11/18/2013 04:31 PM, Alan Bateman wrote:

On 18/11/2013 14:59, Jochen Theodorou wrote:

Hi,

java.lang.Class has multiple methods annotated with CallerSensitive 
(see 
http://hg.openjdk.java.net/jdk8/jdk8-gate/jdk/file/tip/src/share/classes/java/lang/Class.java). 



Now if we in Groovy here want to build our runtime structure for this 
class, and the security manager is not allowing access to 
sun.reflect, then we get into trouble. 
https://jira.codehaus.org/browse/GROOVY-6405 is caused by this.


What do you suggest people with this problem, if adding 
accessClassInPackage.sun.reflect is no option?
Is it sun.reflect.CallerSensitive.class.getDeclaredMethods that is 
failing?


-Alan.


From GROOVY-6405 discussion I think it is, yes.

The work-around suggested in GROOVY-6405 does not work, because it has a 
bug. It should be written as:


private static void setAnnotationMetaData(Annotation[] annotations 
/*, AnnotatedNode an */) {

for (Annotation annotation : annotations) {
if (annotation*.annotationType()*.getPackage() == null ||

!sun.reflect.equals(annotation*.annotationType()*.getPackage().getName())) 
{
System.out.println(Processing:  + 
annotation.annotationType().getName());

} else {
System.out.println(Skipping:  + 
annotation.annotationType().getName());

}
}
}


... i.e. don't call annotation.*getClass()* because what you get is a 
dynamic Proxy class implementing the annotation interface and such Proxy 
class does not live in the same package as the annotation interface...


There is another such annotation to watch for, in another protected 
package: *sun.misc.Contended* ...


Regards, Peter



Re: Map.Entry.setValue as a default method

2013-11-21 Thread Peter Levart

On 11/21/2013 03:56 PM, Remi Forax wrote:

Maybe one of:
  interface KoolReusablePair {
default boolean defaultEquals(Object x) { ... }
static int hashCode(KoolReusablePair self) { ... }
...
  }

  class KoolImpl implements KoolReusablePair {
@Override //manual opt-in:
public boolean equals(Object x) { return 
KoolReusablePair.super.defaultEquals(x); }

@Override //manual opt-in:
public int hashCode() { return KoolReusablePair.hashCode(this); }
...
  }

— John


The plumber in me think that a static method unlike a default method 
will not pollute the itable.


...and static interface method, unlike default, will not pollute the 
public API (static interface methods are not inherited).


Regards, Peter



regards,
Rémi 




Re: RFR (S + L test) : 8016839 : JSR292: AME instead of IAE when calling a method

2013-11-27 Thread Peter Levart

On 11/27/2013 08:40 AM, David Holmes wrote:



On 27/11/2013 2:16 AM, David Chase wrote:


On 2013-11-26, at 8:12 AM, David Chase david.r.ch...@oracle.com wrote:
On 2013-11-26, at 7:32 AM, David Holmes david.hol...@oracle.com 
wrote:

On 26/11/2013 10:16 PM, David Chase wrote:


On 2013-11-26, at 7:12 AM, David Holmes david.hol...@oracle.com 
wrote:

On 26/11/2013 9:56 PM, David Chase wrote:


On 2013-11-25, at 9:18 PM, David Holmes 
david.hol...@oracle.com wrote:
We do have the jdk.internal namespace. But I think Unsafe is as 
good a place as any - though maybe sun.misc.VM is marginally 
better?


Does anyone have any problems with sun.misc.VM as a choice?
I have to do a minor revision to the hotspot commit anyway.
Is sun.misc.VM also loaded very early anyway?


No you would have to add it as for Unsafe.


But it's loaded early anyway as a normal consequence of other 
class loading, right?


What do you mean by early? It isn't a pre-loaded class but it 
will be loaded during system initialization. It is approx the 120th 
class to be loaded. Unsafe is about 135th.


120 is earlier than 135, so by that measure it is superior.
Do you see any other problems with the change?
The method's not at all Unsafe in the technical sense of the word, 
so it is just a matter of choosing a good home.


On further investigation, change to sun.misc.VM would be the first 
time that hotspot knows of the existence of sun.misc.VM; 
sun.misc.Unsafe is already filled with methods that the runtime knows 
about (intrinsics, etc).  I think Unsafe is better.


Okay.

David


Hi David(s),

Excuse me for my ignorance, but does pre-loading the class involve it's 
initialization? Is static initializer called at that time? Even if it is 
not at that time, it surely should be called before first invocation of 
a method on that class (the throwIllegalAccessError() method in this 
case). You need a reference to this method very early - even before 
system initialization starts. How early do you expect first faulty 
invocations could occur that need to call this method? What if calling 
that method triggers non-trivial initialization which in turn encounters 
another faulty invocation?


sun.misc.Unsafe has a non-trivial static initialization which involves 
registerNatives() native method invocation, and it also calls:


sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, getUnsafe);

...which initializes hell lot of things (like java.util.HashMap for 
example, which in who knows which incarnation included random hash seed 
initialization which triggered random number generator initialization 
with gathering of random seed from various sources, ...)


sun.misc.VM on the other hand, only has the following static initialization:

private static final Object lock = new Object();

static {
initialize();
}
private native static void initialize();


Are you okay with all possible interactions of this initialization on 
all platforms?


I think a new class with only this method would be a safer choice. 
Regarding back-porting, even if sun.misc.Unsafe is used as the holder 
for that method, this new method will have to be added to 
sun.misc.Unsafe on those legacy platforms in order to obtain this new 
Method *. If the method is not found, the VM would have to behave as 
before. Couldn't the pre-loading of classes be made such that some of 
them are optional?



Regard, Peter




David





Re: RFR (S + L test) : 8016839 : JSR292: AME instead of IAE when calling a method

2013-11-27 Thread Peter Levart

On 11/27/2013 11:03 AM, David Holmes wrote:

Hi Peter,

On 27/11/2013 7:20 PM, Peter Levart wrote:

On 11/27/2013 08:40 AM, David Holmes wrote:

On 27/11/2013 2:16 AM, David Chase wrote:
On 2013-11-26, at 8:12 AM, David Chase david.r.ch...@oracle.com 
wrote:

On 2013-11-26, at 7:32 AM, David Holmes david.hol...@oracle.com
wrote:

On 26/11/2013 10:16 PM, David Chase wrote:

On 2013-11-26, at 7:12 AM, David Holmes david.hol...@oracle.com
wrote:

On 26/11/2013 9:56 PM, David Chase wrote:

On 2013-11-25, at 9:18 PM, David Holmes
david.hol...@oracle.com wrote:

We do have the jdk.internal namespace. But I think Unsafe is as
good a place as any - though maybe sun.misc.VM is marginally
better?


Does anyone have any problems with sun.misc.VM as a choice?
I have to do a minor revision to the hotspot commit anyway.
Is sun.misc.VM also loaded very early anyway?


No you would have to add it as for Unsafe.


But it's loaded early anyway as a normal consequence of other
class loading, right?


What do you mean by early? It isn't a pre-loaded class but it
will be loaded during system initialization. It is approx the 120th
class to be loaded. Unsafe is about 135th.


120 is earlier than 135, so by that measure it is superior.
Do you see any other problems with the change?
The method's not at all Unsafe in the technical sense of the word,
so it is just a matter of choosing a good home.


On further investigation, change to sun.misc.VM would be the first
time that hotspot knows of the existence of sun.misc.VM;
sun.misc.Unsafe is already filled with methods that the runtime knows
about (intrinsics, etc).  I think Unsafe is better.


Okay.

David


Hi David(s),

Excuse me for my ignorance, but does pre-loading the class involve it's
initialization? Is static initializer called at that time?


No, pre-load is simply loading not initialization. Static 
initialization gets triggerred via a controlled process as it is very 
delicate.


Even if it is

not at that time, it surely should be called before first invocation of
a method on that class (the throwIllegalAccessError() method in this
case). You need a reference to this method very early - even before
system initialization starts. How early do you expect first faulty
invocations could occur that need to call this method? What if calling
that method triggers non-trivial initialization which in turn encounters
another faulty invocation?


These faults should only appear in application classes so generally 
everything should be initialized well before you need to use this 
method. If a core library class has a bug that triggered this need to 
call this method then yes it is possible that it might happen too 
early to succeed - but that is quite normal for the core classes, 
there are a number of things that can happen too early in the 
initialization process to work (eg throwing exceptions, using 
assertions).


That said I'm not sure how this could fail in that all we need is a 
reference to the method to put in the vtable and we have that after 
loading. Then all that can go wrong is that we can't actually throw 
the exception.



sun.misc.Unsafe has a non-trivial static initialization which involves
registerNatives() native method invocation, and it also calls:


registerNative is not an issue

sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, 
getUnsafe);


...which initializes hell lot of things (like java.util.HashMap for
example, which in who knows which incarnation included random hash seed
initialization which triggered random number generator initialization
with gathering of random seed from various sources, ...)



sun.misc.VM on the other hand, only has the following static
initialization:

 private static final Object lock = new Object();

 static {
 initialize();
 }
 private native static void initialize();


Are you okay with all possible interactions of this initialization on
all platforms?


The only time the initialization order would be changed by this fix is 
if one of the classes initialized before-hand had a bug that required 
this fix to come into affect. That is obviously a JDK bug and is 
extremely unlikely to happen.


Note that sun.misc.VM is currently initialized 44th while Unsafe is 61st.

I don't see any issues with this fix in that regard.


I see. Thanks for explanation, David.




I think a new class with only this method would be a safer choice.
Regarding back-porting, even if sun.misc.Unsafe is used as the holder
for that method, this new method will have to be added to
sun.misc.Unsafe on those legacy platforms in order to obtain this new
Method *. If the method is not found, the VM would have to behave as
before. Couldn't the pre-loading of classes be made such that some of
them are optional?


It already supports optional classes.


Ah, I have misunderstood the back-porting issue. It was not about not 
having new class but about which existing class to use as a host that 
might not exist in older version

Re: RFR (S + L test) : 8016839 : JSR292: AME instead of IAE when calling a method

2013-11-27 Thread Peter Levart

On 11/27/2013 02:40 PM, David Chase wrote:

On 2013-11-27, at 6:53 AM, Peter Levart peter.lev...@gmail.com wrote:

Ah, I have misunderstood the back-porting issue. It was not about not having 
new class but about which existing class to use as a host that might not exist 
in older version of platform...

Sorry for noise.

Noise is okay.  This fix was a PITA, init order can hide surprises, and I don't 
mind going over the details.

As to the activation of the code in question, practically never, except in tests or when 
bozo-bytecode-generators (a remark I resemble) are making mistakes.  The 
initialize of the throwIAE method is deferred until loading of a class that 
performs an illegal-access-override of an interface method -- e.g., interface I { int 
m(); } class C implements I { private int m(); } so even that requires an inconsistent 
set of classes, which is
unlikely in any normal initialization.

Longer-term/hoped-for plan is to create a custom throwIAE method each time this happens 
so that an informative error message can be included -- C.m() overrides I.m() but 
is private (or protected, or package-inaccessible) -- but that is tricky because we 
don't have a good place to put the method; by the time we learn this about class C, we 
have rewritten its constant pool and it is difficult to add more, and the constant pool 
cache is fragile-yet-critical-to-interpreter-performance.  So for now, I did this.

I did test it as much as I could figure out how, including running the 
regression test in Netbeans and poking around, and also running it under jdb on 
some embedded platforms and trying to think of commands that might trigger 
embarrassing failures.

The push is in the pipeline, but if you have other tests you can suggest, it is 
not too late to pull the emergency stop (in particular, I am gatekeeper for 
hs-comp this month, so I can put off the next turn of the crank till the last 
moment).

David



Your and David Holmes' answers have pretty much silenced me. I can't 
think of any more troubles...


About creating an informative error message: is there a way to 
dynamically dig-out from the VM, while executing the single system-wide 
throwIAE method, the symbolic invocation attributes of a call-site 
together with the target object in case of instance method invocation? 
From that data it could be possible to re-compute the context in 
question, I assume...


Regards, Peter



Re: 8029281: Synchronization issues in Logger and LogManager

2013-11-27 Thread Peter Levart

Hi Daniel,

I have started looking at the LogManager change first, and here's the 
1st race I found...


 The new method LoggerWeakRef.dispose() can be called from 3 places:

- LoggerContext.addLocalLogger
- LoggerContext.findLogger
- LogManager.drainLoggerRefQueueBounded which is called from public 
method LogManager.addLogger


The 1st and 2nd are guarded by LoggerContext.this lock, but the 3rd is 
unguarded.


What can happen is the following:

Thread1:
LogManager.addLogger(someLogger)
LogManager.drainLoggerRefQueueBounded() // finds some enqueued 
LoggerWeakRef for name == 'X.Y' and...

LoggerWeakRef.dispose() // this is 1st call to dispose, so...
synchronized (LoggerWeakRef.this) {
   disposed = true;
}

---context switch---

Thread2:
LogManager.addLogger(logger{name=='X.Y'})
LogManager.drainLoggerRefQueueBounded()  // no enqueued refs...
LoggerContext.addLocalLogger(logger{name=='X.Y'}, true)
LoggerWeakRef ref = namedLoggers.get(name); // returns 
a non-null ref ('X.Y' still points to a cleared weak ref)

if (ref.get() == null) {
ref.dispose(); // this is a 2nd call to this ref, 
so it returns quickly

}
// ... namedLoggers gets new entry, etc...
LogNode node = getNode(name); // get node for 'X.Y'
*node.loggerRef = ref;*

---context switch---

Thread1: (still in LoggerWeakRef.dispose())
if (node != null) {
*node.loggerRef = null;*  // clear LogNode's weak ref to 
us *!!! NOT QUITE !!!*



... so Thread1 erroneously clears the reference from Node to new 
LoggerWeakRef that was just added by Thread2 ...



One way to fix this is to synchronize the clearing of node.logerRef on 
node.context too. I would make LoggerWeakRef.node and parentRef fields 
volatile and do the following:



final class LoggerWeakRef extends WeakReferenceLogger {
private String name; // for 
namedLoggers cleanup
private volatile LogNode   node; // for loggerRef 
cleanup
private volatile WeakReferenceLogger parentRef;  // for kids 
cleanup


LoggerWeakRef(Logger logger) {
super(logger, loggerRefQueue);
name = logger.getName();  // save for namedLoggers cleanup
}

// dispose of this LoggerWeakRef object
void dispose() {
LogNode node = this.node;
if (node != null) {
synchronized (node.context) {
node = this.node; // double-checked locking
if (node != null) {
// if we have a LogNode, then we were a named 
Logger

// so clear namedLoggers weak ref to us
node.context.removeLoggerRef(name, this);
name = null;  // clear our ref to the Logger's name

node.loggerRef = null;  // clear LogNode's weak 
ref to us

this.node = null;   // clear our ref to LogNode
}
}
}

WeakReferenceLogger parentRef = this.parentRef;
if (parentRef != null) {
// this LoggerWeakRef has or had a parent Logger
this.parentRef = null;  // clear our weak ref to the 
parent Logger (racy, but harmless)

Logger parent = parentRef.get();
if (parent != null) {
// the parent Logger is still there so clear the
// parent Logger's weak ref to us
parent.removeChildLogger(this);
}
}
}

...


What do you think?

That's all for today. Will check the rest of patch tomorrow.


Regards, Peter



On 11/27/2013 08:23 PM, Daniel Fuchs wrote:

Hi,

Please find below a webrev for:

8029281: Synchronization issues in Logger and LogManager
https://bugs.openjdk.java.net/browse/JDK-8029281:

I believe this changeset will also fix JDK-8027670 and
JDK-8029092 - which I have thus closed as duplicates of JDK-8029281.

webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8029281/webrev.00/

Now some comments on the fix:

LogManager:

When a logger was garbage collected, and then a new logger
of the same name requested, addlocalLogger used to call
LoggerContext.removeLogger to remove the stale reference
and replace it by a new one. But sometime, the stale reference
was still in the reference queue, which caused the *new* logger
to be wrongly removed later when the reference queue was drained.

LogManager was also missing some synchronization for its 'props'
variable.

Logger:

userBundle  resourceBundleName were sometimes accessed within
a synchronized block, and sometimes without. In particular the
getters were not synchronized, which could cause race conditions
because an other thread 

Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-11-28 Thread Peter Levart

On 11/28/2013 08:53 AM, Shi Jun Zhang wrote:
The problem is that we use a logger in CustomerFormatter and this 
causes Logger.log call Logger.log itself. As FileHandler.publish and 
StreamHandler.publish is synchronized, but the iteration to call 
publish method for all handlers in Logger.log is not synchronized, the 
deadlock happens. 


Hello Shi Jun Zhang,

Why do you use Logger.log in the CustomerFormatter? What are you 
achieving by it? Do you want to re-route and re-format messages destined 
for one handler to some other Logger and consequently handler?


On 11/28/2013 08:53 AM, Shi Jun Zhang wrote:
This violates the Java doc for java.util.logging.Logger that says All 
methods on Logger are multi-thread safe. 


I don't know for sure, but I think that multi-thread-safe does not 
imply dead-lock-safe. It would be good if java logging used less locks 
and be less deadlock-prone though. So we should see if it is possible to 
remove some locks, not to add more locking...


Regards, Peter



Re: 8029281: Synchronization issues in Logger and LogManager

2013-12-02 Thread Peter Levart

Hi Daniel,

1st sorry for the delay. I promised looking at the patch, but was then 
distracted by other things. I think that synchronization in LogManager 
is correct now. The fact that Mandy thinks so is also reassuring.


I wonder if calling LoggerWeakRef.dispose() from 
LoggerContext.addLocalLoger() is needed now that you check the 
LogNode.loggerRef before clearing in LoggerWeakRef.dispose():


if (n.loggerRef == this) {
n.loggerRef = null;  // clear LogNode's weak 
ref to us

}


The LoggerContext.addLocalLoger() will already overwrite the 
namedLoggers Hashtable entry for the logger's name with new LoggerWeakRef:


namedLoggers.put(name, ref);

...and it will already overwrite the LogNode.loggerRef with new 
LoggerWeakRef:


// Find the new node and its parent.
LogNode node = getNode(name);
node.loggerRef = ref;

So the only effect of calling LoggerWeakRef.dispose() from 
LoggerContext.addLocalLoger() is a more prompt unlinking of 
LoggerWeakRef child, which has already been cleared but not yet 
disposed(), from parent logger. This will eventually happen in a call to 
LogManager.drainLoggerRefQueueBounded(), called from public 
LogManager.addLogger(), which is the only entry point to 
LoggerContext.addLocalLoger(). But it's not wrong as it is now when you 
also ensure more prompt unlinking of cleared LoggerWeakRef and code is 
more uniform and less fragile then it would be if you created and called 
a hypothetical disposeFromParent() which only took care of unlinking 
from parent logger...


Regards, Peter


On 11/29/2013 12:41 PM, Daniel Fuchs wrote:

Hi,

Here is a new revision that includes Peter's findings.
Thanks again for that Peter!

http://cr.openjdk.java.net/~dfuchs/webrev_8029281/webrev.01/

It has passed all jdk_core tests and running the new tests
in a loop hasn't triggered any of the issues that appeared
before the fix.

-- daniel

On 11/28/13 3:26 PM, Daniel Fuchs wrote:

On 11/27/13 10:34 PM, Peter Levart wrote:

Hi Daniel,

I have started looking at the LogManager change first, and here's the
1st race I found...


Hi Peter,

Thanks a lot for your feedback! see below...


  The new method LoggerWeakRef.dispose() can be called from 3 places:

- LoggerContext.addLocalLogger
- LoggerContext.findLogger
- LogManager.drainLoggerRefQueueBounded which is called from public
method LogManager.addLogger

The 1st and 2nd are guarded by LoggerContext.this lock, but the 3rd is
unguarded.

What can happen is the following:

Thread1:
 LogManager.addLogger(someLogger)
 LogManager.drainLoggerRefQueueBounded() // finds some enqueued
LoggerWeakRef for name == 'X.Y' and...
 LoggerWeakRef.dispose() // this is 1st call to dispose,
so...
 synchronized (LoggerWeakRef.this) {
disposed = true;
 }

---context switch---

Thread2:
 LogManager.addLogger(logger{name=='X.Y'})
 LogManager.drainLoggerRefQueueBounded()  // no enqueued
refs...
 LoggerContext.addLocalLogger(logger{name=='X.Y'}, true)
 LoggerWeakRef ref = namedLoggers.get(name); // returns
a non-null ref ('X.Y' still points to a cleared weak ref)
 if (ref.get() == null) {
 ref.dispose(); // this is a 2nd call to this ref,
so it returns quickly
 }
 // ... namedLoggers gets new entry, etc...
 LogNode node = getNode(name); // get node for 'X.Y'
*node.loggerRef = ref;*

---context switch---

Thread1: (still in LoggerWeakRef.dispose())
 if (node != null) {
*node.loggerRef = null;*  // clear LogNode's weak 
ref to

us *!!! NOT QUITE !!!*


... so Thread1 erroneously clears the reference from Node to new
LoggerWeakRef that was just added by Thread2 ...


Damn. I believe that you're right! I overlooked the fact that LogNode is
reused.

Locking on LogNode.context is indeed a good way of solving the issue.
The only method that we will call from within the lock is
LogNode.context.rmoveLoggerRef(name this) - and that already requires
a lock on LogNode.context so it would be safe.

I have also double checked the places where LogNode.loggerRef is set,
and all those places (except in dispose() so far) are already from
within a lock on LoggerContext.

I think I would prefer however to keep the 'disposed' flag - and to
check whether LogNode.loggerRef == this before clearing it.

Given that - as I said - LogNode.loggerRef is always modified
from within a lock on LoggerContext I think the following would
work:

void dispose() {
 synchronized(this) {
 if (disposed) return;
 disposed = true;
 }

 final LogNode n = node;
 if (n != null) {
 synchronized (n.context) {
 n.context.removeLoggerRef(name, this);
 name = null;
 if (n.loggerRef

Theoretical data race on java.util.logging.Handler.sealed

2013-12-03 Thread Peter Levart

Hi,

While browsing the code of java.util.logging.Handler, I noticed a 
theoretical possibility that a security check in a j.u.l.StreamHandler 
be circumvented using a data race.


There is a plain boolean instance field 'sealed' in j.u.l.Handler that 
is pre-initialized to 'true' in field initializer. StreamHandler 
sublcass' constructors overwrite this value with 'false' at the 
beginning, then issue some operations which circumvent security checks, 
and finally they reset the 'sealed' value back to 'true' at the end.


If a reference to an instance of StreamHandler or subclass is passed to 
some thread without synchronization via data-race, this thread can see 
'true' or 'false' as the possible values of 'sealed' variable, thus it 
is possible to circumvent security checks.


One possibility to fix this is moving the field to StreamHandler and 
making it final:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.01/

Just making the field volatile might not work. There is an ongoing 
debate on concurrency-interest which suggests that volatile fields are 
not exceptional in constructors like final fields are...



Regards, Peter



Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-03 Thread Peter Levart

On 12/03/2013 09:51 AM, Peter Levart wrote:

Hi,

While browsing the code of java.util.logging.Handler, I noticed a 
theoretical possibility that a security check in a j.u.l.StreamHandler 
be circumvented using a data race.


There is a plain boolean instance field 'sealed' in j.u.l.Handler that 
is pre-initialized to 'true' in field initializer. StreamHandler 
sublcass' constructors overwrite this value with 'false' at the 
beginning, then issue some operations which circumvent security 
checks, and finally they reset the 'sealed' value back to 'true' at 
the end.


If a reference to an instance of StreamHandler or subclass is passed 
to some thread without synchronization via data-race, this thread can 
see 'true' or 'false' as the possible values of 'sealed' variable, 
thus it is possible to circumvent security checks.


One possibility to fix this is moving the field to StreamHandler and 
making it final:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.01/

Just making the field volatile might not work. There is an ongoing 
debate on concurrency-interest which suggests that volatile fields are 
not exceptional in constructors like final fields are...



Regards, Peter



The proposed patch is not complete. There are several subclasses of 
StreamHandler in the java.util.logging package that also need a way to 
bypass security checks for some operations in their constructors. So 
here's the updated webrev which updates them with the same code as 
StreamHandler. This means that there are two copies of 'sealed' flag in 
object of type ConsoleHandler, for example, but only the one declared in 
ConsoleHandler is relevant for governing access checks:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.02/

Before filing the bug, I'm asking the list whether this can be 
considered a bug...


Regards, Peter



Re: RFR [6968459] JNDI timeout fails before timeout is reached

2013-12-03 Thread Peter Levart

On 11/29/2013 09:06 PM, Ivan Gerasimov wrote:

Thank you Alan for the reply!

On 29.11.2013 21:03, Alan Bateman wrote:

On 19/11/2013 17:58, Ivan Gerasimov wrote:

Hello all!

Would you please help review a fix for the bug?
https://bugs.openjdk.java.net/browse/JDK-6968459

It was reported that creating new InitialLdapContext() can fail with 
javax.naming.NamingException: LDAP response read timed out, timeout 
used:3ms, even though the specified timeout hadn't been elapsed.


The fix was provided by the filer of the bug some time ago.
Here's the webrev with this fix:
http://cr.openjdk.java.net/~igerasim/6968459/0/webrev/


I haven't seen any replies to this but I've cc'ed Vinnie and Xuelei 
as they are more familiar with this area.


If I understand correctly then the issue is that the timeout handling 
doesn't take account of wakeups when aren't any BerDecoders to 
dequeue. The changes mean it will retry the wait with a decreasing 
timeout until a reply is received or the timeout elapses. That seems 
reasonable, assuming the time doesn't change :-)   You might find the 
code is a bit clearer if you have a remaining time as that would 
allow you get rid of timedOut, timeOut and endTime.



I modified the patch in the way you suggest.
http://cr.openjdk.java.net/~igerasim/6968459/1/webrev/

The timeOut variable now holds the remaining time.
If the system time had changed back, we start counting from the 
beginning.
If it had changed forward, we have no way to catch it and the timeout 
gets elapsed earlier.


I see the patch doesn't come with a test. Is there any test 
infrastructure for testing LDAP without require a complete server?



I didn't find anything like that, that's why I set 'noreg-hard' label.

Sincerely yours,
Ivan



-Alan.






Hi Ivan,

From quick look I notice a danger that Connection.readReply() pauses 
(for the timeOut time) in spite of the fact that a reply is ready and 
enqueued before waiting.


Imagine a situation where the 1st try of obtaining result returns null:

 450 // Get the reply if it is already available.
 451 BerDecoder rber = ldr.getReplyBer();


...after that, but before reaching the following lines:

 471 synchronized (ldr) {
 472 ldr.wait(timeOut);
 473 }
 

The other thread enqueues a reply (LdapRequest.addReplyBer()) because 
the code in readReply() is executing without holding a lock on ldr. 
When this thread (executing readReply()) finally enters synchronized 
block and waits, it will wait until wait() times out or another reply is 
enqueued which will issue another notify(). This can lead to unnecessary 
pauses. Old code does not exhibit this problem, because it re-checks the 
readiness of a reply immediately after entering the synchronized block.



Regards, Peter



Re: RFR [6968459] JNDI timeout fails before timeout is reached

2013-12-03 Thread Peter Levart

On 12/03/2013 03:35 PM, Ivan Gerasimov wrote:

Hi Peter!

Thank you for your review!

You are right, the patch changed the behavior of the code.
I've reverted back all the unnecessary changes. This should minimize 
the risk.


I've also made another correction: After decrementing the remaining 
timeOut, the startTime should be set to currTime.


Would you please help review the updated webrev:
http://cr.openjdk.java.net/~igerasim/6968459/2/webrev/

Sincerely yours,
Ivan


Hi Ivan,

That's better. You could move the initial request for ldr.getReplyBer() 
(line 447) out of while loop, since it is not needed in the loop (all 
further ldr.getReplyBer() calls in loop are performed in synchronized 
block already - line 465). else { break; } (line 469) is not needed in 
that case. I would also make timeOut variable long to avoid overflows. 
Simplified logic could look like this:



BerDecoder readReply(LdapRequest ldr)
throws IOException, NamingException {
long timeOut = (readTimeout  0) ?
readTimeout : 15 * 1000; // Default read timeout of 15 sec

long currTime = System.currentTimeMillis();

BerDecoder rber = ldr.getReplyBer();

while (rber == null  timeOut  0L) {
long startTime = currTime;
// If socket closed, don't even try
synchronized (this) {
if (sock == null) {
throw new ServiceUnavailableException(host + : + 
port +

; socket closed);
}
}
synchronized (ldr) {
// check if condition has changed since our last check
rber = ldr.getReplyBer();
if (rber == null) {
try {
ldr.wait(timeOut);
} catch (InterruptedException ex) {
throw new InterruptedNamingException(
Interrupted during LDAP operation);
}
}
}
currTime = System.currentTimeMillis();
if (startTime  currTime) {
timeOut -= (currTime - startTime);
}
// else system time must have changed backwards (or not at all)
}

if (rber == null  readTimeout  0) {
removeRequest(ldr);
throw new NamingException(LDAP response read timed out, 
timeout used:

+ readTimeout + ms. );
}

return rber;
}


What do you think?

Regards, Peter





From quick look I notice a danger that Connection.readReply() pauses 
(for the timeOut time) in spite of the fact that a reply is ready and 
enqueued before waiting.


Imagine a situation where the 1st try of obtaining result returns null:

 450 // Get the reply if it is already available.
 451 BerDecoder rber = ldr.getReplyBer();


...after that, but before reaching the following lines:

 471 synchronized (ldr) {
 472 ldr.wait(timeOut);
 473 }


The other thread enqueues a reply (LdapRequest.addReplyBer()) 
because the code in readReply() is executing without holding a lock 
on ldr. When this thread (executing readReply()) finally enters 
synchronized block and waits, it will wait until wait() times out or 
another reply is enqueued which will issue another notify(). This can 
lead to unnecessary pauses. Old code does not exhibit this problem, 
because it re-checks the readiness of a reply immediately after 
entering the synchronized block.



Regards, Peter









Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-05 Thread Peter Levart


On 12/05/2013 07:54 AM, Shi Jun Zhang wrote:

On 11/30/2013 12:05 AM, Daniel Fuchs wrote:

On 11/29/13 4:56 PM, Alan Bateman wrote:

On 29/11/2013 10:08, Daniel Fuchs wrote:


However, removing or just moving the lock around might well 
introduce new

unknown issues - so it will need to be carefully anaIyzed, and I am
not sure
it can/should be attempted in a minor JDK release.


Yes, we have to be very careful as the logging code has a history of
biting the hand of those that try to improve it. For various 
reasons, it

seems there is a lot of code that has subtle dependencies on the
implementation, on the initialization in particular. In any case, you
are to be applauded for tackling the synchronization issues and it 
would
be a good project to re-examine all of this in JDK 9 to see how it 
would

be simplified.

On documenting the locking details in an @implNote (which seems to be
one of the suggestions here) then we also need to be careful as I think
we need some flexibility to change some of this going forward.


Yes - that's a two edged sword indeed. We certainly don't want to set
that in stone... On the other hand I empathizes with developers who
struggle to find out what they can - and can't do - when extending
j.u.l APIs...

Anyway, if usage of the 'synchronized' keyword never appears in
the Javadoc I guess that's for good reasons...

Thanks Alan,

-- daniel



-Alan



Hi Daniel,

This thread is silent for several days, do you have any finding in 
Handler.publish?




Hi Shi Jun Zhang,

I have looked at this, creating a prototype. It re-arranged 
synchronization in a way so that all Formatter methods are invoked out 
of synchronized sections. I haven't come forward with this yet, because 
of two issues:
- Formatter implementations would suddenly be called multi-threaded. 
Currently they are invoked from within Handler-instance synchronized 
sections.
- Formatter would have to be invoked optimistically to obtain head and 
tail strings, so it could happen that a head, for example, would be 
requested concurrently multiple times, but only one of returned heads 
would be written to stream then.


The 1st thing seems problematic. I can imagine there exist Formatters 
that are not thread-safe (for example, using single instance of 
MessageFormat, which is not multi-threaded) and now just happen to work 
as a consequence of current StreamHandler implementation detail, but 
would break if called multi-threaded.


One way to remedy this is to add a boolean property to Formatter API, 
say Formatter.isMultiThreaded(), and arrange so that appropriate 
instances return appropriate values also considering 
backwards-compatibility...


So all-in-all this is not a simple patch and I doubt it can be made for 
JDK8. In JDK9, I think, it will be possible to re-visit this issue, so 
It would be good to file it as a BUG or RFI.



Regards, Peter



Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-08 Thread Peter Levart


On 12/04/2013 12:27 AM, Mandy Chung wrote:


On 12/3/2013 1:44 AM, Peter Levart wrote:

On 12/03/2013 09:51 AM, Peter Levart wrote:

Hi,

While browsing the code of java.util.logging.Handler, I noticed a 
theoretical possibility that a security check in a 
j.u.l.StreamHandler be circumvented using a data race.


There is a plain boolean instance field 'sealed' in j.u.l.Handler 
that is pre-initialized to 'true' in field initializer. 
StreamHandler sublcass' constructors overwrite this value with 
'false' at the beginning, then issue some operations which 
circumvent security checks, and finally they reset the 'sealed' 
value back to 'true' at the end.


If a reference to an instance of StreamHandler or subclass is passed 
to some thread without synchronization via data-race, this thread 
can see 'true' or 'false' as the possible values of 'sealed' 
variable, thus it is possible to circumvent security checks.


One possibility to fix this is moving the field to StreamHandler and 
making it final:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.01/ 



Just making the field volatile might not work. There is an ongoing 
debate on concurrency-interest which suggests that volatile fields 
are not exceptional in constructors like final fields are...



Regards, Peter



The proposed patch is not complete. There are several subclasses of 
StreamHandler in the java.util.logging package that also need a way 
to bypass security checks for some operations in their constructors. 
So here's the updated webrev which updates them with the same code as 
StreamHandler. This means that there are two copies of 'sealed' flag 
in object of type ConsoleHandler, for example, but only the one 
declared in ConsoleHandler is relevant for governing access checks:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.02/ 



Before filing the bug, I'm asking the list whether this can be 
considered a bug...




This does look a possible data race that might return a partially 
constructed object with sealed = false.  I am not sure how likely we 
will run into this race though.


W.r.t. the patch, it might be better to get rid of the sealed field 
and wrap the calls with doPrivileged with limited privilege (just 
LoggingPermission(control))


Mandy


H Mandy,

I created an issue for it nevertheless:

https://bugs.openjdk.java.net/browse/JDK-8029781

You're right, doPrivileged() is a more straight-forward approach than 
'sealed' variable. Since this might only be considered for inclusion in 
JDK9 when lambdas are already a tried technology, how do you feel about 
using them for platform code like logging? As far as I know (just 
checked), lambda meta-factory is not using any j.u.logging, so there is 
no danger of initialization loops or similar:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/


Regards, Peter



Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-09 Thread Peter Levart

On 12/09/2013 08:02 AM, Shi Jun Zhang wrote:

Peter,

I think you are misunderstanding this problem. This deadlock is not 
related to the formatter synchronization, we can make 
CustomerFormatter.format not synchronized and not call super.format, 
the deadlock still happens.


I'm not saying that your formatters are explicitly synchronized - all 
formatters are currently effectively synchronized by LogHandlers. The 
Formatter is invoked from within LogHandler's publish() method which is 
synchronized (on LogHandler.this). If formatters were invoked out of 
this synchronized section, there would be no danger of deadlocks when 
using Logger.log from within custom formatters. But then other issues 
would arise as a consequence of non-multithreaded formatters being 
invoked concurrently...


Regards, Peter



Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-09 Thread Peter Levart

On 12/09/2013 09:28 AM, Peter Levart wrote:

On 12/09/2013 08:02 AM, Shi Jun Zhang wrote:

Peter,

I think you are misunderstanding this problem. This deadlock is not 
related to the formatter synchronization, we can make 
CustomerFormatter.format not synchronized and not call super.format, 
the deadlock still happens.


I'm not saying that your formatters are explicitly synchronized - all 
formatters are currently effectively synchronized by LogHandlers. The 
Formatter is invoked from within LogHandler's publish() method which 
is synchronized (on LogHandler.this). If formatters were invoked out 
of this synchronized section, there would be no danger of deadlocks 
when using Logger.log from within custom formatters. But then other 
issues would arise as a consequence of non-multithreaded formatters 
being invoked concurrently...


Regards, Peter



I think the best solution to your problem (or a work-around if you say 
so) was suggested by Jason Mehrens few messages ago - decoupling of user 
code from publishing of log records - by creating an AsyncLogHandler 
that is just feeding a FIFO queue with log records which are processed 
by a background thread by pop-ing them out of queue and sticking them in 
the actual LogHandler.publish(). If the queue is unbouded or large 
enough so that it never fills up, there's no danger of dead-locks even 
if you invoke Logger.log from custom formatters in such background 
publishing thread.


Regards, Peter



Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-09 Thread Peter Levart

On 12/09/2013 09:51 AM, Shi Jun Zhang wrote:

On 12/9/2013 4:28 PM, Peter Levart wrote:

On 12/09/2013 08:02 AM, Shi Jun Zhang wrote:

Peter,

I think you are misunderstanding this problem. This deadlock is not 
related to the formatter synchronization, we can make 
CustomerFormatter.format not synchronized and not call super.format, 
the deadlock still happens.


I'm not saying that your formatters are explicitly synchronized - all 
formatters are currently effectively synchronized by LogHandlers. The 
Formatter is invoked from within LogHandler's publish() method which 
is synchronized (on LogHandler.this). If formatters were invoked out 
of this synchronized section, there would be no danger of deadlocks 
when using Logger.log from within custom formatters. But then other 
issues would arise as a consequence of non-multithreaded formatters 
being invoked concurrently...


Regards, Peter


Hi Peter,

We have thought about moving formatter out of the synchronized section 
of Handler.publish(), it can avoid the deadlock. However, we can 
reproduce the similar deadlock by extending the Writer in Handler and 
using logger in the customized Writer.




That's right. And the remedy for that situation would also be what Jason 
Mehrens suggested - asynchronous publishing.


Regards, Peter


Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-09 Thread Peter Levart

On 12/09/2013 10:50 AM, Shi Jun Zhang wrote:

On 12/9/2013 4:40 PM, Peter Levart wrote:

On 12/09/2013 09:28 AM, Peter Levart wrote:

On 12/09/2013 08:02 AM, Shi Jun Zhang wrote:

Peter,

I think you are misunderstanding this problem. This deadlock is not 
related to the formatter synchronization, we can make 
CustomerFormatter.format not synchronized and not call 
super.format, the deadlock still happens.


I'm not saying that your formatters are explicitly synchronized - 
all formatters are currently effectively synchronized by 
LogHandlers. The Formatter is invoked from within LogHandler's 
publish() method which is synchronized (on LogHandler.this). If 
formatters were invoked out of this synchronized section, there 
would be no danger of deadlocks when using Logger.log from within 
custom formatters. But then other issues would arise as a 
consequence of non-multithreaded formatters being invoked 
concurrently...


Regards, Peter



I think the best solution to your problem (or a work-around if you 
say so) was suggested by Jason Mehrens few messages ago - decoupling 
of user code from publishing of log records - by creating an 
AsyncLogHandler that is just feeding a FIFO queue with log records 
which are processed by a background thread by pop-ing them out of 
queue and sticking them in the actual LogHandler.publish(). If the 
queue is unbouded or large enough so that it never fills up, there's 
no danger of dead-locks even if you invoke Logger.log from custom 
formatters in such background publishing thread.


Regards, Peter


Hi Peter,

Would the following situation happen if we use AsyncLogHandler? Some 
error happens and it causes the jvm crashes or System.exit() is 
called, however the related log record which contains important 
message is still in the queue and not printed. If so, I think it's 
unacceptable.




You could install a shutdown-hook that would make sure the remaining 
queue is flushed before completing the VM exit...


Regards, Peter



Re: Deadlock between FileHandler and ConsoleHandler when using customized formatter

2013-12-09 Thread Peter Levart

On 12/09/2013 11:12 AM, Daniel Fuchs wrote:

On 12/9/13 9:58 AM, Peter Levart wrote:

On 12/09/2013 09:51 AM, Shi Jun Zhang wrote:

On 12/9/2013 4:28 PM, Peter Levart wrote:

On 12/09/2013 08:02 AM, Shi Jun Zhang wrote:

Peter,

I think you are misunderstanding this problem. This deadlock is not
related to the formatter synchronization, we can make
CustomerFormatter.format not synchronized and not call super.format,
the deadlock still happens.


I'm not saying that your formatters are explicitly synchronized - all
formatters are currently effectively synchronized by LogHandlers. The
Formatter is invoked from within LogHandler's publish() method which
is synchronized (on LogHandler.this). If formatters were invoked out
of this synchronized section, there would be no danger of deadlocks
when using Logger.log from within custom formatters. But then other
issues would arise as a consequence of non-multithreaded formatters
being invoked concurrently...

Regards, Peter


Hi Peter,

We have thought about moving formatter out of the synchronized section
of Handler.publish(), it can avoid the deadlock. However, we can
reproduce the similar deadlock by extending the Writer in Handler and
using logger in the customized Writer.



That's right. And the remedy for that situation would also be what Jason
Mehrens suggested - asynchronous publishing.


Hi,

I agree with Peter  Jason - asynchronous publishing seems like a good
solution. I believe the LogManager will close all handlers on exiting,
so you might want to make sure that your asynchronous handler flushes
the queue before quitting - which could still be tricky if flushing
the queue produces new log messages for the queue - and also because
you will want Handler.close() to wait until the queue is empty.


You're right, Daniel. There already is a global shut-down hook installed 
in LogManager that close()s all

active handlers when VM is shutting down.

Shi Jun Zhang, here's a quick mock-up of a prototype AsyncHandler that 
might work for you:


http://cr.openjdk.java.net/~plevart/misc/jul.AsyncHandler/AsyncHandler.java

Regards, Peter



Anyway - the best advice still is IMHO - don't call Logger.log while
publishing a log message. This should save you from a lot of issues,
like the one you encountered - but also possible stack overflows etc...

best regards,

-- daniel




Regards, Peter






Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-14 Thread Peter Levart

Hi Mandy,

On 12/13/2013 12:37 AM, Mandy Chung wrote:

Hi Peter,

On 12/8/2013 11:19 AM, Peter Levart wrote:

H Mandy,

I created an issue for it nevertheless:

https://bugs.openjdk.java.net/browse/JDK-8029781

You're right, doPrivileged() is a more straight-forward approach than 
'sealed' variable. Since this might only be considered for inclusion 
in JDK9 when lambdas are already a tried technology, how do you feel 
about using them for platform code like logging? As far as I know 
(just checked), lambda meta-factory is not using any j.u.logging, so 
there is no danger of initialization loops or similar:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/ 



Sorry for the delay to get to this.


No rush. We have time before JDK9 gets set-up and running...



Alan is right that java.lang.invoke.ProxyClassesDumper does use 
PlatformLogger which will forward calls to j.u.logging if 
-Djava.util.logging.config.file is set or java.util.logging has been 
initialized (via other j.u.logging call).  It means that it may lead 
to recursive initialization.  Also the current PlatformLogger 
implementation formats the message in the same way as j.u.logging that 
may load locale providers and other classes. I am afraid there are 
issues to tease out and resolve.


It's unfortunate that a lambda debugging feature prevents us from using 
a basic language feature in j.u.logging code. As far as I know, 
java.lang.invoke.ProxyClassesDumper is only used if 
'jdk.internal.lambda.dumpProxyClasses' system property is set to point 
to a directory where lambda proxy class files are to be dumped as they 
are generated - a debugging hook therefore. Wouldn't it be good-enough 
if error messages about not-being able to set-up/use the dump facility 
were output to System.err directly - not using PlatformLogger at all?




The overloads the doPrivileged method makes it cumbersome to use 
lambda that causes you to workaround it by adding a new 
PrivilegedVoidAction interface which is clever.  So I think it isn't 
too bad for this patch to use anonymous inner class and have the 
doPrivileged call in the constructor.


Right. I have prepared a modified webrev which doesn't use lambdas:

http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.04/

In attempt to minimize the boilerplate, I haven't just replaced lambdas 
with anonymous inner classes, but rather turned all private configure() 
methods into ConfigureAction inner classes. In two occasions 
(SocketHandler and StreamHandler), they are extended with anonymous 
inner classes to append some actions. In SocketHandler I kept the 
mechanics of transporting the checked IOException out of 
PrivilegedAction by wrapping it with Unchecked IOException and later 
unwrapping and throwing it, rather than using PrivilegedExceptionAction 
which would further complicate exception handling, since it declares 
throwing a general j.l.Exception, but the SocketHandler constructor only 
declares throwing IOException...


I think this could be backported to 7u as-is.

Regards, Peter




Mandy




Re: Review request for 8021368: Launch of Java Web Start app fails with ClassCircularityError exception

2013-12-14 Thread Peter Levart


On 12/12/2013 07:29 PM, Mandy Chung wrote:
JDK-8021368: Launch of Java Web Start app fails with 
ClassCircularityError exception in 7u25

https://bugs.openjdk.java.net/browse/JDK-8021368

This is a fix for 7u60 only.  It's a regression in 7u25 due to 
JDK-8010117 where it calls Class.getMethod to determine if the 
checkMemberAccess method is overridden in a SecurityManager subclass 
but Class.getMethod causes parameter types and returned type of other 
public methods to be resolved and hence ClassCircularityError.  It is 
not an issue in JDK 8 as SecurityManager.checkMemberAccess is 
deprecated and not called by the JDK (see JDK-8007035).


Webrev at:
http://cr.openjdk.java.net/~mchung/jdk7u/webrevs/8021368/webrev.00/

An alternative implementation is to add a new VM entry point to look 
up the declaring class of an overridden method instead of using 
JNI_GetMethodID and get a reflective method for a faster query. Since 
this check is only performed once in most cases, this performance cost 
of using JNI is not too bad that the new VM entry point doesn't 
necessarily buy much more.


thanks
Mandy


Hi Mandy,

I tried the following:


public class Test {

static class A {}

static class B {}

static class X {
public void x() { }
}

static class Y extends X {
public A a(B b) { return null; }
public B b(A a) { return null; }
public void x() { }
}

public static void main(String[] args) throws Exception {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(Y.class, x, 
MethodType.methodType(void.class, new Class[0]));

MethodHandleInfo mhi = lookup.revealDirect(mh);
System.out.println(mhi.getDeclaringClass() == Y.class);
}
}


The above code does not trigger loading of classes A or B. But 
unfortunately it prints true even if I comment-out the declaration of 
method Y.x(). I don't know if this is a bug though. I should ask on the 
mlvm-dev list...


Anyway, your approach seems more appropriate as it doesn't depend on 
method handles and their peculiarities...


Some nits:

2241  * Finds the checkMemberAccess method of the given 
SecurityManager*instance*.


...I think it should read ...of the given SecurityManager*class*. instead, 
since the method parameter is of type Class.


2210 private static class SecurityManagerHelper {
2211 private final SecurityManager smgr;
2212 private final boolean overrideCheckMemberAccess;


...the fields could be declared package-private so that no synthetic access 
methods are generated...


Regards, Peter



Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-14 Thread Peter Levart

Hi,

Daniel reminded me of a couple of issues the 4th revision of the patch 
would have when backporting to 7u. So here's another variant that tries 
to be more backport-friendly:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.05/

This variant could be backported by simply replacing a limited variant 
of doPrivileged (introduced in JDK 8) with full variant and still not 
elevate the privilege of Socket creation in SocketHandler. I also 
removed the need to subclass various ConfigureAction(s) with annonymous 
inner subclasses by introducing overloaded constructors to 
ConfigureActions(s) that follow the overloaded constructors of various 
Handlers.


Regards, Peter

On 12/14/2013 12:25 PM, Peter Levart wrote:

Hi Mandy,

On 12/13/2013 12:37 AM, Mandy Chung wrote:

Hi Peter,

On 12/8/2013 11:19 AM, Peter Levart wrote:

H Mandy,

I created an issue for it nevertheless:

https://bugs.openjdk.java.net/browse/JDK-8029781

You're right, doPrivileged() is a more straight-forward approach 
than 'sealed' variable. Since this might only be considered for 
inclusion in JDK9 when lambdas are already a tried technology, how 
do you feel about using them for platform code like logging? As far 
as I know (just checked), lambda meta-factory is not using any 
j.u.logging, so there is no danger of initialization loops or similar:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/ 



Sorry for the delay to get to this.


No rush. We have time before JDK9 gets set-up and running...



Alan is right that java.lang.invoke.ProxyClassesDumper does use 
PlatformLogger which will forward calls to j.u.logging if 
-Djava.util.logging.config.file is set or java.util.logging has been 
initialized (via other j.u.logging call).  It means that it may lead 
to recursive initialization.  Also the current PlatformLogger 
implementation formats the message in the same way as j.u.logging 
that may load locale providers and other classes.  I am afraid there 
are issues to tease out and resolve.


It's unfortunate that a lambda debugging feature prevents us from 
using a basic language feature in j.u.logging code. As far as I know, 
java.lang.invoke.ProxyClassesDumper is only used if 
'jdk.internal.lambda.dumpProxyClasses' system property is set to point 
to a directory where lambda proxy class files are to be dumped as they 
are generated - a debugging hook therefore. Wouldn't it be good-enough 
if error messages about not-being able to set-up/use the dump facility 
were output to System.err directly - not using PlatformLogger at all?




The overloads the doPrivileged method makes it cumbersome to use 
lambda that causes you to workaround it by adding a new 
PrivilegedVoidAction interface which is clever.  So I think it isn't 
too bad for this patch to use anonymous inner class and have the 
doPrivileged call in the constructor.


Right. I have prepared a modified webrev which doesn't use lambdas:

http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.04/

In attempt to minimize the boilerplate, I haven't just replaced 
lambdas with anonymous inner classes, but rather turned all private 
configure() methods into ConfigureAction inner classes. In two 
occasions (SocketHandler and StreamHandler), they are extended with 
anonymous inner classes to append some actions. In SocketHandler I 
kept the mechanics of transporting the checked IOException out of 
PrivilegedAction by wrapping it with Unchecked IOException and later 
unwrapping and throwing it, rather than using 
PrivilegedExceptionAction which would further complicate exception 
handling, since it declares throwing a general j.l.Exception, but the 
SocketHandler constructor only declares throwing IOException...


I think this could be backported to 7u as-is.

Regards, Peter




Mandy






Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-17 Thread Peter Levart

On 12/17/2013 11:29 AM, Daniel Fuchs wrote:

On 12/16/13 10:14 PM, Mandy Chung wrote:

On 12/14/2013 9:38 AM, Peter Levart wrote:

Hi,

Daniel reminded me of a couple of issues the 4th revision of the patch
would have when backporting to 7u. So here's another variant that
tries to be more backport-friendly:

http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.05/ 



This looks good in general.

SocketHandler line 200 - it looks to me that this is an existing bug
that should call setOutputStream within doPrivileged.


I was asking myself the same question.



I'm not sure I would qualify this as a bug: if you want to create a
SocketHandler that sends to a specific host/port you need the
LoggingPermission(control).


What is being protected with permission checking in Handler(s) is 
changing various properties of Handler(s). What we are granting with 
doPriviliged is a temporary elevation of privilege for changing the 
properties of the instance of Handler that is being constructed - just 
for the act of constructing the instance of Handler. Anybody should be 
able to instantiate new Handler instance - that doesn't present any 
special capability. Putting new Handler into service is already 
additionally protected (for example Logger.addHandler()). So in case of 
SocketHandler, one should be able to instantiate new SocketHandler for 
specified host/port if she has permission to create a Socket to that 
host/port, but nothing more should be required. To put such Handler into 
service (to direct logging messages generated by logging system to it), 
additional LoggingPermission(control) is already required.


So I think Mandy is right and that is an existing bug, although not very 
critical, since it only affects those that want to instantiate new 
SocketHandler although they are not able to use it in the logging system 
(maybe they use it somewhere else?).


Regards, Peter




I think it'd be simpler if SocketHandler no-arg constructor can first
get the port and host from the logging properties so that it doesn't
need to differentiate hostAndPortSet is set and ConfigureAction no-arg
constructor can be removed.

Daniel/Peter - do we have tests to cover these permission check for
these handlers?


Shockingly:

$ cd jdk/test/java/util/logging
$ find . -type f -exec grep SocketHandler {} /dev/null \;

reveals nothing. So it seams we have no unit tests for SocketHandler!

-- daniel



Mandy



This variant could be backported by simply replacing a limited variant
of doPrivileged (introduced in JDK 8) with full variant and still not
elevate the privilege of Socket creation in SocketHandler. I also
removed the need to subclass various ConfigureAction(s) with
annonymous inner subclasses by introducing overloaded constructors to
ConfigureActions(s) that follow the overloaded constructors of various
Handlers.

Regards, Peter

On 12/14/2013 12:25 PM, Peter Levart wrote:

Hi Mandy,

On 12/13/2013 12:37 AM, Mandy Chung wrote:

Hi Peter,

On 12/8/2013 11:19 AM, Peter Levart wrote:

H Mandy,

I created an issue for it nevertheless:

https://bugs.openjdk.java.net/browse/JDK-8029781

You're right, doPrivileged() is a more straight-forward approach
than 'sealed' variable. Since this might only be considered for
inclusion in JDK9 when lambdas are already a tried technology, how
do you feel about using them for platform code like logging? As far
as I know (just checked), lambda meta-factory is not using any
j.u.logging, so there is no danger of initialization loops or 
similar:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/ 





Sorry for the delay to get to this.


No rush. We have time before JDK9 gets set-up and running...



Alan is right that java.lang.invoke.ProxyClassesDumper does use
PlatformLogger which will forward calls to j.u.logging if
-Djava.util.logging.config.file is set or java.util.logging has been
initialized (via other j.u.logging call).  It means that it may lead
to recursive initialization.  Also the current PlatformLogger
implementation formats the message in the same way as j.u.logging
that may load locale providers and other classes.  I am afraid there
are issues to tease out and resolve.


It's unfortunate that a lambda debugging feature prevents us from
using a basic language feature in j.u.logging code. As far as I know,
java.lang.invoke.ProxyClassesDumper is only used if
'jdk.internal.lambda.dumpProxyClasses' system property is set to
point to a directory where lambda proxy class files are to be dumped
as they are generated - a debugging hook therefore. Wouldn't it be
good-enough if error messages about not-being able to set-up/use the
dump facility were output to System.err directly - not using
PlatformLogger at all?



The overloads the doPrivileged method makes it cumbersome to use
lambda that causes you to workaround it by adding a new
PrivilegedVoidAction interface which is clever.  So I think it isn't
too bad for this patch to use anonymous

Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-17 Thread Peter Levart

On 12/17/2013 04:29 PM, Jason Mehrens wrote:
Handlers can be subclassed.  Is it a security concern when 
doPrivileged is invoking non-final public/protected methods?  For example,


@Override
public void setOutputStream(OutputStream out) {
 LogManager.getLogManager().reset();
}

@Override
public void setLevel(Level l) {
LogManager.getLogManager().reset();
}

Jason


Good catch! The 'sealed' field did not allow that, since there was no 
elevation of privilege. So doPrivileged is out of question, right?


Peter



 Date: Mon, 16 Dec 2013 13:14:03 -0800
 From: mandy.ch...@oracle.com
 To: peter.lev...@gmail.com
 Subject: Re: Theoretical data race on java.util.logging.Handler.sealed
 CC: core-libs-dev@openjdk.java.net

 On 12/14/2013 9:38 AM, Peter Levart wrote:
  Hi,
 
  Daniel reminded me of a couple of issues the 4th revision of the 
patch

  would have when backporting to 7u. So here's another variant that
  tries to be more backport-friendly:
 
  
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.05/


 This looks good in general.

 SocketHandler line 200 - it looks to me that this is an existing bug
 that should call setOutputStream within doPrivileged.

 I think it'd be simpler if SocketHandler no-arg constructor can first
 get the port and host from the logging properties so that it doesn't
 need to differentiate hostAndPortSet is set and ConfigureAction no-arg
 constructor can be removed.

 Daniel/Peter - do we have tests to cover these permission check for
 these handlers?

 Mandy

 
  This variant could be backported by simply replacing a limited 
variant

  of doPrivileged (introduced in JDK 8) with full variant and still not
  elevate the privilege of Socket creation in SocketHandler. I also
  removed the need to subclass various ConfigureAction(s) with
  annonymous inner subclasses by introducing overloaded constructors to
  ConfigureActions(s) that follow the overloaded constructors of 
various

  Handlers.
 
  Regards, Peter
 
  On 12/14/2013 12:25 PM, Peter Levart wrote:
  Hi Mandy,
 
  On 12/13/2013 12:37 AM, Mandy Chung wrote:
  Hi Peter,
 
  On 12/8/2013 11:19 AM, Peter Levart wrote:
  H Mandy,
 
  I created an issue for it nevertheless:
 
  https://bugs.openjdk.java.net/browse/JDK-8029781
 
  You're right, doPrivileged() is a more straight-forward approach
  than 'sealed' variable. Since this might only be considered for
  inclusion in JDK9 when lambdas are already a tried technology, how
  do you feel about using them for platform code like logging? As 
far

  as I know (just checked), lambda meta-factory is not using any
  j.u.logging, so there is no danger of initialization loops or 
similar:

 
  
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/

 
 
  Sorry for the delay to get to this.
 
  No rush. We have time before JDK9 gets set-up and running...
 
 
  Alan is right that java.lang.invoke.ProxyClassesDumper does use
  PlatformLogger which will forward calls to j.u.logging if
  -Djava.util.logging.config.file is set or java.util.logging has 
been

  initialized (via other j.u.logging call). It means that it may lead
  to recursive initialization. Also the current PlatformLogger
  implementation formats the message in the same way as j.u.logging
  that may load locale providers and other classes. I am afraid there
  are issues to tease out and resolve.
 
  It's unfortunate that a lambda debugging feature prevents us from
  using a basic language feature in j.u.logging code. As far as I 
know,

  java.lang.invoke.ProxyClassesDumper is only used if
  'jdk.internal.lambda.dumpProxyClasses' system property is set to
  point to a directory where lambda proxy class files are to be dumped
  as they are generated - a debugging hook therefore. Wouldn't it be
  good-enough if error messages about not-being able to set-up/use the
  dump facility were output to System.err directly - not using
  PlatformLogger at all?
 
 
  The overloads the doPrivileged method makes it cumbersome to use
  lambda that causes you to workaround it by adding a new
  PrivilegedVoidAction interface which is clever. So I think it isn't
  too bad for this patch to use anonymous inner class and have the
  doPrivileged call in the constructor.
 
  Right. I have prepared a modified webrev which doesn't use lambdas:
 
  
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.04/

 
  In attempt to minimize the boilerplate, I haven't just replaced
  lambdas with anonymous inner classes, but rather turned all private
  configure() methods into ConfigureAction inner classes. In two
  occasions (SocketHandler and StreamHandler), they are extended with
  anonymous inner classes to append some actions. In SocketHandler I
  kept the mechanics of transporting the checked IOException out of
  PrivilegedAction by wrapping it with Unchecked IOException and later
  unwrapping and throwing it, rather than using
  PrivilegedExceptionAction which would further

Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-17 Thread Peter Levart

On 12/17/2013 05:26 PM, Mandy Chung wrote:
This is a good point.   The patch for JDK 8 and above uses limited 
doPrivileged that only grants LoggingPermission(control) access even 
though the system class has all permissions and it should be no 
difference than the current implementation.   When we backport to 7u, 
it would be an issue.


I think it's an issue for limited doPrivileged use too (JDK 8). 
LoggingPermission(control) is a permission used to protect the whole 
logging system. So what was not possible with 'sealed' field would be 
possible with doPermission's temporary elevation of privilege even if it 
is just for LoggingPermission(control).




We shall look into this and it's an existing issue to the current 
implementation.


I don't think so. The 'sealed' field only pertains to permission checks 
inside the Handler instance - not globally. I think we must fix the bug 
by keeping 'sealed' field. One variant is by having final 'sealed' 
field(s) in each Handler's subclass (as proposed initialy), the other 
would be to replace the primitive boolean sealed field in Handler with:


final AtomicBoolean sealed = new AtomicBoolean(true);

Which one do you prefer?

Regards, Peter



thanks
Mandy

On 12/17/2013 7:29 AM, Jason Mehrens wrote:
Handlers can be subclassed.  Is it a security concern when 
doPrivileged is invoking non-final public/protected methods?  For 
example,


@Override
public void setOutputStream(OutputStream out) {
 LogManager.getLogManager().reset();
}

@Override
public void setLevel(Level l) {
LogManager.getLogManager().reset();
}

Jason

 Date: Mon, 16 Dec 2013 13:14:03 -0800
 From: mandy.ch...@oracle.com
 To: peter.lev...@gmail.com
 Subject: Re: Theoretical data race on java.util.logging.Handler.sealed
 CC: core-libs-dev@openjdk.java.net

 On 12/14/2013 9:38 AM, Peter Levart wrote:
  Hi,
 
  Daniel reminded me of a couple of issues the 4th revision of the 
patch

  would have when backporting to 7u. So here's another variant that
  tries to be more backport-friendly:
 
  
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.05/


 This looks good in general.

 SocketHandler line 200 - it looks to me that this is an existing bug
 that should call setOutputStream within doPrivileged.

 I think it'd be simpler if SocketHandler no-arg constructor can first
 get the port and host from the logging properties so that it doesn't
 need to differentiate hostAndPortSet is set and ConfigureAction no-arg
 constructor can be removed.

 Daniel/Peter - do we have tests to cover these permission check for
 these handlers?

 Mandy

 
  This variant could be backported by simply replacing a limited 
variant
  of doPrivileged (introduced in JDK 8) with full variant and still 
not

  elevate the privilege of Socket creation in SocketHandler. I also
  removed the need to subclass various ConfigureAction(s) with
  annonymous inner subclasses by introducing overloaded 
constructors to
  ConfigureActions(s) that follow the overloaded constructors of 
various

  Handlers.
 
  Regards, Peter
 
  On 12/14/2013 12:25 PM, Peter Levart wrote:
  Hi Mandy,
 
  On 12/13/2013 12:37 AM, Mandy Chung wrote:
  Hi Peter,
 
  On 12/8/2013 11:19 AM, Peter Levart wrote:
  H Mandy,
 
  I created an issue for it nevertheless:
 
  https://bugs.openjdk.java.net/browse/JDK-8029781
 
  You're right, doPrivileged() is a more straight-forward approach
  than 'sealed' variable. Since this might only be considered for
  inclusion in JDK9 when lambdas are already a tried technology, 
how
  do you feel about using them for platform code like logging? 
As far

  as I know (just checked), lambda meta-factory is not using any
  j.u.logging, so there is no danger of initialization loops or 
similar:

 
  
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.03/ 


 
 
  Sorry for the delay to get to this.
 
  No rush. We have time before JDK9 gets set-up and running...
 
 
  Alan is right that java.lang.invoke.ProxyClassesDumper does use
  PlatformLogger which will forward calls to j.u.logging if
  -Djava.util.logging.config.file is set or java.util.logging has 
been
  initialized (via other j.u.logging call). It means that it may 
lead

  to recursive initialization. Also the current PlatformLogger
  implementation formats the message in the same way as j.u.logging
  that may load locale providers and other classes. I am afraid 
there

  are issues to tease out and resolve.
 
  It's unfortunate that a lambda debugging feature prevents us from
  using a basic language feature in j.u.logging code. As far as I 
know,

  java.lang.invoke.ProxyClassesDumper is only used if
  'jdk.internal.lambda.dumpProxyClasses' system property is set to
  point to a directory where lambda proxy class files are to be 
dumped

  as they are generated - a debugging hook therefore. Wouldn't it be
  good-enough if error messages about not-being able to set-up/use 
the

  dump facility were output to System.err

Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-17 Thread Peter Levart


On 12/17/2013 11:02 PM, Daniel Fuchs wrote:

On 12/17/13 6:02 PM, Peter Levart wrote:

On 12/17/2013 05:26 PM, Mandy Chung wrote:

This is a good point.   The patch for JDK 8 and above uses limited
doPrivileged that only grants LoggingPermission(control) access even
though the system class has all permissions and it should be no
difference than the current implementation.   When we backport to 7u,
it would be an issue.


I think it's an issue for limited doPrivileged use too (JDK 8).
LoggingPermission(control) is a permission used to protect the whole
logging system. So what was not possible with 'sealed' field would be
possible with doPermission's temporary elevation of privilege even if it
is just for LoggingPermission(control).


Hi Peter,

I don't think that is an issue - because if Handler is subclassed
and the custom subclass attempts to call something requiring
LoggingPermission(control) then the custom subclass will
*still need* to  have the control permission  - otherwise a
security exception will be  thrown. This is because the
custom subclass's protection domain will be in the code
path:

- callers call new XxxxHandler
  - XxxxHandler call Handler's super constructor
 - super constructor calls doPrivileged
   - super constructor calls e.g. this.setLevel()
 which is redefined as XxxxHandler.setLevel
 - setLevel calls something else requiring control

At this point you have XxxxHandler.class in the code path so
the security manager will check that XxxxHandler.class has the
control permission.


Ah, I see. Thanks for the explanation. I haven't thought of different 
protection domains. I have studied the AccessControler javadocs and I 
think I understand the behavior now. So there's no problem even if 
unlimited doPrivileged is used, or am I missing something?


But then we have another problem with doPrivileged approach, since it is 
even more restrictive than 'sealed' field approach. Currently the 
Handler's subclass that overrides a setter and calls super, works:



@Override
public void setOutputStream(OutputStream out) {
super.setOutputStream(out);
}


With doPrivileged wrapping setOutputStream in the superclass 
constructor, it will throw SecurityException if the subclass protection 
domain does not have the control permission...


Can this break custom handlers in some environment?


Regards, Peter




We shall look into this and it's an existing issue to the current
implementation.


I don't think so. The 'sealed' field only pertains to permission checks
inside the Handler instance - not globally. I think we must fix the bug
by keeping 'sealed' field. One variant is by having final 'sealed'
field(s) in each Handler's subclass (as proposed initialy), the other
would be to replace the primitive boolean sealed field in Handler with:

final AtomicBoolean sealed = new AtomicBoolean(true);


I don't think that would solve anything - it wouldn't prevent
the race condition - would it?



Which one do you prefer?


I think we should fix the potential race condition using
limited doPrivileged in 9. IMHO that does exactly what we
want.

best regards,

-- daniel


Regards, Peter



thanks
Mandy

On 12/17/2013 7:29 AM, Jason Mehrens wrote:

Handlers can be subclassed.  Is it a security concern when
doPrivileged is invoking non-final public/protected methods?  For
example,

@Override
public void setOutputStream(OutputStream out) {
 LogManager.getLogManager().reset();
}

@Override
public void setLevel(Level l) {
LogManager.getLogManager().reset();
}

Jason

 Date: Mon, 16 Dec 2013 13:14:03 -0800
 From: mandy.ch...@oracle.com
 To: peter.lev...@gmail.com
 Subject: Re: Theoretical data race on 
java.util.logging.Handler.sealed

 CC: core-libs-dev@openjdk.java.net

 On 12/14/2013 9:38 AM, Peter Levart wrote:
  Hi,
 
  Daniel reminded me of a couple of issues the 4th revision of the
patch
  would have when backporting to 7u. So here's another variant that
  tries to be more backport-friendly:
 
 
http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.05/ 




 This looks good in general.

 SocketHandler line 200 - it looks to me that this is an existing bug
 that should call setOutputStream within doPrivileged.

 I think it'd be simpler if SocketHandler no-arg constructor can 
first

 get the port and host from the logging properties so that it doesn't
 need to differentiate hostAndPortSet is set and ConfigureAction 
no-arg

 constructor can be removed.

 Daniel/Peter - do we have tests to cover these permission check for
 these handlers?

 Mandy

 
  This variant could be backported by simply replacing a limited
variant
  of doPrivileged (introduced in JDK 8) with full variant and still
not
  elevate the privilege of Socket creation in SocketHandler. I also
  removed the need to subclass various ConfigureAction(s) with
  annonymous inner subclasses by introducing overloaded
constructors to
  ConfigureActions(s) that follow the overloaded constructors

Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-18 Thread Peter Levart

On 12/18/2013 12:05 PM, Daniel Fuchs wrote:

But then we have another problem with doPrivileged approach, since it is
even more restrictive than 'sealed' field approach. Currently the
Handler's subclass that overrides a setter and calls super, works:


@Override
public void setOutputStream(OutputStream out) {
 super.setOutputStream(out);
}


With doPrivileged wrapping setOutputStream in the superclass
constructor, it will throw SecurityException if the subclass protection
domain does not have the control permission...

Can this break custom handlers in some environment?


Good question. It may yes - but on the other hand, a subclass of
handler that override such methods and call the super.method would
*need* to have the control permission too - wouldn't it?

Otherwise calling these methods when sealed is back to true would
always fail...


There might be no need to call the overridden setters after the Handler 
instance is constructed. Apart from setLevel, Handler setters are only 
called by Handlers themselves in construction phase and by user code... 
If user code doesn't need to call the overridden setters after handlers 
are constructed, user code doesn't need the control permission.


But than again, user would *need* to have control permission anyway to 
make use of a newly constructed Handler. If all she can do is 
instantiate new Handler instances and not add them to Loggers, what good 
does it make?


Regards, Peter



best regards,

-- daniel 




Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-18 Thread Peter Levart

On 12/17/2013 06:43 PM, Mandy Chung wrote:
Can you check what methods are called by the constructors whose access 
are denied in the current implementation but granted in the patch?  I 
have to take another look to make sure but I believe they only calls 
the methods in the handler classes that calls Handler.checkPermission.


Mandy


Methods that are called by various Handler constructors and would be 
elevated by doPrivileged are:
- Handler's own setters, protected by Handler.checkPermission - 
control permission required,

- LogManager.getLevelProperty - no special permission required
- LogManager.getFilterProperty - loads class configured in properties 
from system class loader and instantiates it. (since this is done by 
system class - LogManager, no special permission required besides those 
that might be imposed by constructor of the Filter (sub)class)

- LogManager.getFormatterProperty - the same as getFilterProperty
- LogManager.getStringProperty,getIntProperty - no special permission 
required


That's about it. So the only methods that are not known and would be 
elevated by doPrivileged are no-args constructors of Filter and 
Formatter subclasses the names of which are obtained from logging 
properties and which must be loadable by system class loader.



Regards, Peter



Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-18 Thread Peter Levart

On 12/17/2013 06:43 PM, Mandy Chung wrote:
Can you check what methods are called by the constructors whose access 
are denied in the current implementation but granted in the patch?  I 
have to take another look to make sure but I believe they only calls 
the methods in the handler classes that calls Handler.checkPermission.


Mandy


Hi Mandy, Daniel,

Here's yet another variant that reduces the doPrivileged code to just 
Handler's setters. This way no LogManager methods are invoked under 
elevated privilege:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.06/

I also factored-out common code into a single package-private 
Handler.configure() method + two package-private getters that provide 
this method with different defaults for different Handler subclasses. 
configure() is in this variant called only in immediate Handler 
subclasses: MemoryHandler  StreamHandler and not in SocketHandler or 
ConsoleHandler. Each property is only set once this way at construction 
time - current code sets each property twice in SocketHandler or 
ConsoleHandler.


SocketHandler's output stream is set with privileged action in both 
cases: whether constructed with configured or specified host/port.



Regards, Peter



Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-19 Thread Peter Levart

On 12/18/2013 11:55 PM, Mandy Chung wrote:


On 12/18/2013 9:03 AM, Peter Levart wrote:

Hi Mandy, Daniel,

Here's yet another variant that reduces the doPrivileged code to just 
Handler's setters. This way no LogManager methods are invoked under 
elevated privilege:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.06/ 





This version looks good.  I like the refactoring to have the subclass 
to call the common code Handler.configure method.  It may be better to 
have the configure method (or a new one) that takes the default Level 
and default Formatter instead of the package-private getters.


I don't see why the handler constructors are designed to call the 
overridden methods rather than the initialization and if a subclass 
has its custom field, it should initialize its custom fields in its 
constructor implementation.Anyway this would be a separate clean 
up task from this one.


Can you also add a sanity test to verify that these handlers can be 
constructed successfully with a security manager installed?




Hi Mandy, Daniel,

I didn't like the package-protected getters either. So here's another 
variant that replaces Handler.configure() method with a 
package-protected constructor which is chained from JDK subclasses:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.07/

I filed another bug that is fixed by this patch:

https://bugs.openjdk.java.net/browse/JDK-8030801

And I created a test (see webrev.07) that almost passes when run against 
unchanged JDK 8 (the failure is just at the end when calling new 
SocketHandler(host, port) - access denied 
(java.util.logging.LoggingPermission control)). If I comment-out the 
System.setSecurityManager() from the test, it passes with unchanged 
code. This is to verify the test itself. When run against the patched 
JDK 8, it passes even when SecurityManager is active - this verifies two 
things:
- the behaviour of patched code is analogous to unpatched code as far as 
defaults and configured handler properties is concerned and it conforms 
to javadoc
- the patched code does not require any new permissions - it actually 
requires less, because it fixes bug 8030801.


All java/util/logging jtreg tests pass with patched code. I hope that 
localhost is a resolvable name on all environments and that new 
ServerSocket(0) creates a server socket bound at least to the IP address 
that localhost resolves to. Is this reasonable to assume?



Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2013-12-21 Thread Peter Levart

Hi David,

Is it possible to get the test output when it fails? It can fail in two 
different ways. I can't look at the bug (not authorized)...



On 12/20/2013 10:54 AM, Chris Hegarty wrote:

On 20 Dec 2013, at 04:33, Mandy Chung mandy.ch...@oracle.com wrote:


Hi Srikalyan,

Maybe you can get add an uncaught handler to see if you can get
any information.

+1. With this, at least the next time we see this failure we should have a 
better idea where the OOM is coming from.

-Chris.


We can try, but I think the VM already prints the stack-trace of the 
exception by default and as far as I remember, OOME thrown by VM is 
preallocated and does not contain a stack trace. So I suspect we'll see 
nothing more with the suggested UEH.


Is it possible to include in test, a modified version of Reference class 
that would be prepended to boot-classpath? For example, containing the 
following ReferenceHandler:



private static class ReferenceHandler extends Thread {

ReferenceHandler(ThreadGroup g, String name) {
super(g, name);
}

private volatile int state;

@Override
public String toString() {
return super.toString() + [state= + state + ];
}

public void run() {
for (;;) {
state = 1;
ReferenceObject r;
state = 2;
synchronized (lock) {
state = 3;
if (pending != null) {
state = 4;
r = pending;
state = 5;
pending = r.discovered;
state = 6;
r.discovered = null;
state = 7;
} else {
state = 8;
// The waiting on the lock may cause an OOME 
because it may try to allocate
// exception objects, so also catch OOME here 
to avoid silent exit of the

// reference handler thread.
//
// Explicitly define the order of the two 
exceptions we catch here

// when waiting for the lock.
//
// We do not want to try to potentially load 
the InterruptedException class
// (which would be done if this was its first 
use, and InterruptedException

// were checked first) in this situation.
//
// This may lead to the VM not ever trying to 
load the InterruptedException

// class again.
try {
state = 9;
try {
state = 10;
lock.wait();
state = 11;
} catch (InterruptedException x) { state = 
12; }

state = 13;
} catch (OutOfMemoryError x) { state = 14; }
state = 15;
continue;
}
state = 16;
}
state = 17;

// Fast path for cleaners
if (r instanceof Cleaner) {
state = 18;
((Cleaner)r).clean();
state = 19;
continue;
}
state = 20;

ReferenceQueueObject q = (ReferenceQueue) r.queue;
state = 21;
if (q != ReferenceQueue.NULL) q.enqueue(r);
state = 22;
}
}
}




...then just include the toString of referenceHandlerThread instance as 
part of the exception message at the end of the test:


...
...
 // wait at most 10 seconds for success or failure
 for (int i = 0; i  20; i++) {
 if (refQueue.poll() != null) {
 // Reference Handler thread still working - success
 return;
 }
 System.gc();
 Thread.sleep(500L); // wait a little to allow GC to do 
it's work before allocating objects

 if (!referenceHandlerThread.isAlive()) {
 // Reference Handler thread died - failure
 throw new Exception(Reference Handler thread died. 
referenceHandlerThread:  + referenceHandlerThread);

 }
 }

 // no sure answer after 10 seconds
 throw new IllegalStateException(Reference Handler thread 
stuck. weakRef.get():  + weakRef.get() +
  , referenceHandlerThread:  
+ referenceHandlerThread);

 }


This might be safer than using UEH since at the time the 
UEH.uncaughtException() is called, the heap might still be full which 
would prevent printing the message. 

Re: Theoretical data race on java.util.logging.Handler.sealed

2013-12-22 Thread Peter Levart

Hi Mandy,

On 12/19/2013 10:38 PM, Mandy Chung wrote:

On 12/19/13 7:49 AM, Peter Levart wrote:

Hi Mandy, Daniel,

I didn't like the package-protected getters either. So here's another 
variant that replaces Handler.configure() method with a 
package-protected constructor which is chained from JDK subclasses:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.07/ 





Looks good.  Thanks for making the change and the new test.  It'd be 
good to close the handlers by the test. The test is running in othervm 
mode and the Cleaner thread will close the handler when VM exits and 
the test is fine as it is.


Well, not really. The Cleaner only closes Handlers that are attached to 
Loggers but the test just instantiates Handlers and doesn't add them to 
any Loggers. It's harmless as it is, othervm will exit nevertheless and 
resources will be freed...


I tried closing Handlers at the end of test, but that requires control 
LoggingPermission and we don't want to run the test with control 
permission since we want to check that instantiating Handlers 
(SocketHandler too) doesn't require control permission.




Digress:  Just notice that the closeable handler classes are not 
AutoCloseable (they don't implement Closeable either).  The close() 
method don't throw IOException but instead throws SecurityException an 
unchecked exception.  Otherwise, we could use try-with-resources.



I filed another bug that is fixed by this patch:

https://bugs.openjdk.java.net/browse/JDK-8030801

And I created a test (see webrev.07) that almost passes when run 
against unchanged JDK 8 (the failure is just at the end when calling 
new SocketHandler(host, port) - access denied 
(java.util.logging.LoggingPermission control)). If I comment-out 
the System.setSecurityManager() from the test, it passes with 
unchanged code. This is to verify the test itself. When run against 
the patched JDK 8, it passes even when SecurityManager is active - 
this verifies two things:
- the behaviour of patched code is analogous to unpatched code as far 
as defaults and configured handler properties is concerned and it 
conforms to javadoc
- the patched code does not require any new permissions - it actually 
requires less, because it fixes bug 8030801.




Yes I agree this is a bug that should get fixed.

All java/util/logging jtreg tests pass with patched code. I hope that 
localhost is a resolvable name on all environments and that new 
ServerSocket(0) creates a server socket bound at least to the IP 
address that localhost resolves to. Is this reasonable to assume?


localhost should be fine and there are other tests depending on it 
be resolvable.


So should anything else be done before pushing this to jdk9/dev ?


Regards, Peter



thanks
Mandy




Re: (reflect) Accessing members of inner annotations types

2014-01-03 Thread Peter Levart
I think the problem is as follows... Annotations are implemented as Java 
dynamic Proxy classes. The generated proxy class for a package-private 
interface is created in the same package as the interface so that it has 
access to the interface. The top level interface can be package private, 
but nested interface (nested inside another interface) is by default 
public (all interface members are by default public). The consequence is 
that proxy class of an interface nested inside the interface is 
generated in com.sun.proxy package:


package pkg;

import java.lang.reflect.Proxy;

public class ProxyTest {
public static void main(String[] args) throws Exception {
Class? iClass = Proxy.getProxyClass(I.class.getClassLoader(), 
new Class[]{I.class});
Class? nClass = Proxy.getProxyClass(I.class.getClassLoader(), 
new Class[]{I.N.class});

System.out.println(iClass:  + iClass);
System.out.println(nClass:  + nClass);
}
}

interface I {
interface N {}
}

prints:

iClass: class pkg.$Proxy0
nClass: class com.sun.proxy.$Proxy1


This is would be all right until such proxy class (com.sun.proxy.$Proxy1 
in our example) has to access some package-private types in some 
specific package. This happens in your Named.List annotation  
implementation class. It implements a member method with the following 
signature:


public Named[] value() {...

...where the return type is an array of a package-private type Named. 
Public class in com.sun.proxy package can not access package-private 
types in other packages!


Your best solution currently is to implement the top-level annotations 
as public, or have all package-private annotations as top-level annotations.


In future, I think the logic to calculate the package of a proxy class 
could be improved. It currently is as follows:


String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

/*
 * Record the package of a non-public proxy interface so 
that the
 * proxy class will be defined in the same package.  Verify 
that

 * all non-public proxy interfaces are in the same package.
 */
for (Class? intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ?  : name.substring(0, n 
+ 1));

if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
non-public interfaces from different 
packages);

}
}
}

if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy 
package

proxyPkg = ReflectUtil.PROXY_PACKAGE + .;
}


...It could be improved to take into account not only all interfaces 
being implemented but also all types that are encountered in interface 
method signatures. If any of those types is non-public than all of them 
should be in the same package and proxy class would be generated in that 
package...


I can file a bug/rfe for this.

Regards, Peter



On 01/03/2014 02:14 PM, Gunnar Morling wrote:

Hi,

In the course of running the Bean Validation TCK on JDK 8, I'm
investigating an issue around reflectively accessing members of annotations
which are declared as inner type of another, package-private annotation
type.

The following shows an example:

 @Retention( RetentionPolicy.RUNTIME )
 /*package-private */ @interface Named {

 @Retention( RetentionPolicy.RUNTIME )
 /*package-private */ @interface List {
 Named[] value();
 }
 }

The @List annotation is used as this on a type in the same package:

 public class Foo {

 @Named.List( @Named )
 public void getBar() {}
 }

I'm then trying to access the @Named annotation using reflection like this:

 Annotation listAnnotation = Foo.class.getMethod( getBar
).getAnnotations()[0];

 Method method = listAnnotation.getClass().getMethod( value );
 method.setAccessible( true );

 //fails
 Annotation namedAnnotation = ( (Annotation[]) method.invoke(
listAnnotation ) )[0];

This is the exception I get:

 IllegalAccessError: tried to access class com.example.Named from class
com.sun.proxy.$Proxy3
   at com.sun.proxy.$Proxy3.value(Unknown Source)

Interestingly, this only occurs when the List annotation is declared as an
inner type within the Named type; it works when the List annotation is a
top-level package-private type (the Named annotation still being
package-private) as well as when it is 

Re: (reflect) Accessing members of inner annotations types

2014-01-03 Thread Peter Levart

On 01/03/2014 03:52 PM, Peter Levart wrote:
This is would be all right until such proxy class 
(com.sun.proxy.$Proxy1 in our example) has to access some 
package-private types in some specific package. This happens in your 
Named.List annotation  implementation class. It implements a member 
method with the following signature:


public Named[] value() {...

...where the return type is an array of a package-private type Named. 
Public class in com.sun.proxy package can not access package-private 
types in other packages! 


Investigating this further, I found that the declaration itself is not 
problematic. It's the code in the implemented proxy method that tries to 
access the package-private Named class. Here's how the bytecode looks 
like for such proxy method:



  public final pkg.Named[] value() throws ;
Signature: ()[Lpkg/Named;
flags: ACC_PUBLIC, ACC_FINAL
Code:
  stack=10, locals=2, args_size=1
 0: aload_0
 1: getfield  #16 // Field 
java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;

 4: aload_0
 5: getstatic #67 // Field 
m3:Ljava/lang/reflect/Method;

 8: aconst_null
 9: invokeinterface #28,  4   // InterfaceMethod 
java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;

*14: checkcast #69 // class [Lpkg/Named;*
17: areturn
18: athrow
19: astore_1
20: new   #42 // class 
java/lang/reflect/UndeclaredThrowableException

23: dup
24: aload_1
25: invokespecial #45 // Method 
java/lang/reflect/UndeclaredThrowableException.init:(Ljava/lang/Throwable;)V

28: athrow
  Exception table:
 fromto  target type
 01818   Class java/lang/Error
 01818   Class java/lang/RuntimeException
 01819   Class java/lang/Throwable


... I think the error is thrown at the checkcast bytecode. The 
improvement suggested still holds. If the proxy class was generated in 
the specific package, error would not be thrown. But the requirement to 
take into account all implemented interfaces and all types encountered 
in the interface method signatures to calculate the package of proxy 
class it too strict. Only implemented interfaces and return types of all 
interface methods need to be taken into consideration. Here's an example 
of bytecode that illustrates how method parameters are passed to 
InvocationHandler:



  public final void doWith(pkg.Named[]) throws ;
Signature: ([Lpkg/Named;)V
flags: ACC_PUBLIC, ACC_FINAL
Code:
  stack=10, locals=3, args_size=2
 0: aload_0
 1: getfield  #16 // Field 
java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;

 4: aload_0
 5: getstatic #57 // Field 
m3:Ljava/lang/reflect/Method;

 8: iconst_1
 9: anewarray #22 // class java/lang/Object
12: dup
13: iconst_0
14: aload_1
15: aastore
16: invokeinterface #28,  4   // InterfaceMethod 
java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;

21: pop
22: return
23: athrow
24: astore_2
25: new   #42 // class 
java/lang/reflect/UndeclaredThrowableException

28: dup
29: aload_2
30: invokespecial #45 // Method 
java/lang/reflect/UndeclaredThrowableException.init:(Ljava/lang/Throwable;)V

33: athrow
  Exception table:
 fromto  target type
 02323   Class java/lang/Error
 02323   Class java/lang/RuntimeException
 02324   Class java/lang/Throwable


... as can be seen, no parameter types are referenced in order to wrap 
the parameters with Object[] array.


Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-07 Thread Peter Levart

On 01/07/2014 03:15 AM, srikalyan chandrashekar wrote:

Sure David will give that a try, we have so far attempted to
1. Print state data(as per the test creator peter.levart's inputs),


Hi Kalyan,

Have you been able to reproduce the OOME in that set-up? What was the 
result?


Regards, Peter


2. Use UEH(uncaught exception handler per Mandy's inputs)

--
Thanks
kalyan

On 1/6/14 4:40 PM, David Holmes wrote:

Back from vacation ...

On 20/12/2013 4:49 PM, David Holmes wrote:

On 20/12/2013 12:57 PM, srikalyan chandrashekar wrote:
Hi David Thanks for your comments, the unguarded part(clean and 
enqueue)
in the Reference Handler thread does not seem to create any new 
objects,
so it is the application(the test in this case) which is adding 
objects

to heap and causing the Reference Handler to die with OOME.


The ReferenceHandler thread can only get OOME if it allocates (directly
or indirectly) - so there has to be something in the unguarded part 
that

causes this. Again it may be an implicit action in the VM - similar to
the class load issue for InterruptedException.


Run a debug VM with -XX:+TraceExceptions to see where the OOME is 
triggered.


David
-


David

I am still

unsure about the side effects of the code change and agree with your
thoughts(on memory exhaustion test's reliability).

PS: hotspot dev alias removed from CC.

--
Thanks
kalyan

On 12/19/13 5:08 PM, David Holmes wrote:

Hi Kalyan,

This is not a hotspot issue so I'm moving this to core-libs, please
drop hotspot from any replies.

On 20/12/2013 6:26 AM, srikalyan wrote:

Hi all,  I have been working on the bug JDK-8022321
https://bugs.openjdk.java.net/browse/JDK-8022321 , this is a 
sporadic

failure and the webrev is available here
http://cr.openjdk.java.net/~srikchan/Regression/JDK-8022321_OOMEInReferenceHandler-webrev/ 






I'm really not sure what to make of this. We have a test that 
triggers

an out-of-memory condition but the OOME can actually turn up in the
ReferenceHandler thread causing it to terminate and the test to fail.
We previously accounted for the non-obvious occurrences of OOME 
due to
the Object.wait and the possible need to load the 
InterruptedException

class - but still the OOME can appear where we don't want it. So
finally you have just placed the whole for(;;) loop in a
try/catch(OOME) that ignores the OOME. I'm certain that makes the 
test

happy, but I'm not sure it is really what we want for the
ReferenceHandler thread. If the OOME occurs while cleaning, or
enqueuing then we will fail to clean and/or enqueue but there 
would be

no indication that has occurred and I think that is a bigger problem
than this test failing.

There may be no way to make this test 100% reliable. In fact I'd
suggest that no memory exhaustion test can be 100% reliable.

David


*
**Root Cause:Still not known*
2 places where there is a possibility for OOME
1) Cleaner.clean()
2) ReferenceQueue.enqueue()

1)  The cleanup code in turn has 2 places where there is 
potential for

throwing OOME,
 a) thunk Thread which is run from clean() method. This 
Runnable is

passed to Cleaner and appears in the following classes
 java/nio/DirectByteBuffer.java
 sun/misc/Perf.java
 sun/nio/fs/NativeBuffer.java
 sun/nio/ch/IOVecWrapper.java
 sun/misc/Cleaner/ExitOnThrow.java
However none of the above overridden implementations ever create an
object in the clean() code.
 b) new PrivilegedAction created in try catch Exception block of
clean() method but for this object to be created and to be held
responsible for OOME an Exception(other than OOME) has to be thrown.

2) No new heap objects are created in the enqueue method nor
anywhere in
the deep call stack (VM.addFinalRefCount() etc) so this cannot be a
potential cause.

*Experimental change to java.lang.Reference.java* :
- Put one more guard (try catch with OOME block) in the Reference
Handler Thread which may give the Reference Handler a chance to
cleanup.
This is fixing the test failure (several 1000 runs with 0 failures)
- Without the above change the test fails atleast 3-5 times for 
every

1000 run.

*PS*: The code change is to a very critical part of JDK and i am 
fully
not aware of the consequences of the change, hence seeking expert 
help

here. Appreciate your time and inputs towards this.









Re: Theoretical data race on java.util.logging.Handler.sealed

2014-01-07 Thread Peter Levart

Hi Mandy, Daniel,

Thanks for reviews. I just pushed this change to jdk9-dev/jdk ...

Regards, Peter

On 12/23/2013 05:50 AM, Mandy Chung wrote:


On 12/22/2013 5:23 AM, Peter Levart wrote:

Hi Mandy,

On 12/19/2013 10:38 PM, Mandy Chung wrote:

On 12/19/13 7:49 AM, Peter Levart wrote:

Hi Mandy, Daniel,

I didn't like the package-protected getters either. So here's 
another variant that replaces Handler.configure() method with a 
package-protected constructor which is chained from JDK subclasses:


http://cr.openjdk.java.net/~plevart/jdk8-tl/jul.Handler.sealed/webrev.07/ 





Looks good.  Thanks for making the change and the new test. It'd be 
good to close the handlers by the test. The test is running in 
othervm mode and the Cleaner thread will close the handler when VM 
exits and the test is fine as it is.


Well, not really. The Cleaner only closes Handlers that are attached 
to Loggers but the test just instantiates Handlers and doesn't add 
them to any Loggers. It's harmless as it is, othervm will exit 
nevertheless and resources will be freed...


I tried closing Handlers at the end of test, but that requires 
control LoggingPermission and we don't want to run the test with 
control permission since we want to check that instantiating 
Handlers (SocketHandler too) doesn't require control permission.


Thanks and the test is fine as it is.



So should anything else be done before pushing this to jdk9/dev ?


Fix looks good and have a regression test.  It's good to go and push 
to jdk9/dev.No other approval needed.


thanks
Mandy




Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-08 Thread Peter Levart

On 01/08/2014 07:30 AM, David Holmes wrote:

On 8/01/2014 4:19 PM, David Holmes wrote:

On 8/01/2014 7:33 AM, srikalyan chandrashekar wrote:

Hi David, TraceExceptions with fastdebug build produced some nice trace
http://cr.openjdk.java.net/%7Esrikchan/OOME_exception_trace.log . The
native method wait(long) is where the OOME if being thrown, the deepest
call is in

src/share/vm/gc_interface/collectedHeap.inline.hpp, line 157


Yes but it is the caller that is of interest:

Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/runtime/objectMonitor.cpp, 


line 1649]
for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
  thrown in interpreter method {method} {0x7f78b4800ae0} 'wait'
'(J)V' in 'java/lang/Object'
  at bci 0 for thread 0x7f78c40d2800

The ReferenceHandler thread gets the OOME trying to allocate the
InterruptedException.


However we already have a catch block around the wait() so how is this 
OOME getting through? A bug in exception handling in the interpreter ??




Might be. And it may have something to do with the fact that the 
Thread.run() method is the 1st call frame on the thread's stack (seems 
like corner case). The last few meaningful TraceExceptions records are:



Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown 
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp, 
line 157]

for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown 
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/runtime/objectMonitor.cpp, 
line 1649]

for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
 thrown in interpreter method {method} {0x7f78b4800ae0} 'wait' 
'(J)V' in 'java/lang/Object'

 at bci 0 for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
 thrown in interpreter method {method} {0x7f78b4800ca8} 'wait' 
'()V' in 'java/lang/Object'

 at *bci 2* for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
 thrown in interpreter method {method} {0x7f78b48d2250} 'run' 
'()V' in 'java/lang/ref/Reference$ReferenceHandler'

 at *bci 36* for thread 0x7f78c40d2800


Here's the relevant bytecodes:


public class java.lang.Object

  public final void wait() throws java.lang.InterruptedException;
descriptor: ()V
flags: ACC_PUBLIC, ACC_FINAL
Code:
  stack=3, locals=1, args_size=1
 0: aload_0
 1: lconst_0
* 2: invokevirtual #73 // Method wait:(J)V*
 5: return
  LineNumberTable:
line 502: 0
line 503: 5
Exceptions:
  throws java.lang.InterruptedException


class java.lang.ref.Reference$ReferenceHandler extends java.lang.Thread

  public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
  stack=2, locals=5, args_size=1
 0: invokestatic  #62 // Method 
java/lang/ref/Reference.access$100:()Ljava/lang/ref/Reference$Lock;

 3: dup
 4: astore_2
 5: monitorenter
 6: invokestatic  #61 // Method 
java/lang/ref/Reference.access$200:()Ljava/lang/ref/Reference;

 9: ifnull33
12: invokestatic  #61 // Method 
java/lang/ref/Reference.access$200:()Ljava/lang/ref/Reference;

15: astore_1
16: aload_1
17: invokestatic  #64 // Method 
java/lang/ref/Reference.access$300:(Ljava/lang/ref/Reference;)Ljava/lang/ref/Reference;
20: invokestatic  #63 // Method 
java/lang/ref/Reference.access$202:(Ljava/lang/ref/Reference;)Ljava/lang/ref/Reference;

23: pop
24: aload_1
25: aconst_null
26: invokestatic  #65 // Method 
java/lang/ref/Reference.access$302:(Ljava/lang/ref/Reference;Ljava/lang/ref/Reference;)Ljava/lang/ref/Reference;

29: pop
30: goto  52
33: invokestatic  #62 // Method 
java/lang/ref/Reference.access$100:()Ljava/lang/ref/Reference$Lock;
*36: invokevirtual #59 // Method 
java/lang/Object.wait:()V*

39: goto  43
42: astore_3
43: goto  47
46: astore_3
47: aload_2
48: monitorexit
49: goto  0
52: aload_2
53: monitorexit
54: goto  64
57: astore4
59: aload_2
60: monitorexit
61: aload 4
63: athrow
64: aload_1
65: instanceof#38 // class sun/misc/Cleaner
68: ifeq  81
71: aload_1
72: checkcast #38 // class sun/misc/Cleaner
75: invokevirtual #67 // Method 

Re: (reflect) Accessing members of inner annotations types

2014-01-08 Thread Peter Levart

On 01/08/2014 01:00 PM, Joel Borggren-Franck wrote:

Hi Peter,

On 2014-01-03, Peter Levart wrote:

On 01/03/2014 03:52 PM, Peter Levart wrote:

This is would be all right until such proxy class
(com.sun.proxy.$Proxy1 in our example) has to access some
package-private types in some specific package. This happens in
your Named.List annotation  implementation class. It implements a
member method with the following signature:

public Named[] value() {...

...where the return type is an array of a package-private type
Named. Public class in com.sun.proxy package can not access
package-private types in other packages!

Investigating this further, I found that the declaration itself is
not problematic. It's the code in the implemented proxy method that
tries to access the package-private Named class. Here's how the
bytecode looks like for such proxy method:
... I think the error is thrown at the checkcast bytecode. The
improvement suggested still holds. If the proxy class was generated
in the specific package, error would not be thrown. But the
requirement to take into account all implemented interfaces and all
types encountered in the interface method signatures to calculate
the package of proxy class it too strict. Only implemented
interfaces and return types of all interface methods need to be
taken into consideration. Here's an example of bytecode that
illustrates how method parameters are passed to InvocationHandler:


Perhaps an alternative would be to check if the interface a proxy is
proxying is nested. In that case use the outermost interface's access
level for the package calculation.

This would probably lead to a few more proxies being generated into the
real package compared to your proposal. I don't know if that is ok or
not.


Hi Joel,

The nested public interface need not be referencing the outer 
class/interface. In this case, proxy class can be generated in 
com.sun.proxy. More importantly, even if the outer interface/class was 
public, the nested interface could be referencing some other 
package-private type. For example:



public class Outer {

@Retention(RUNTIME)
@interface PkgPrivate {}

@Retention(RUNTIME)
public @interface Public {
PkgPrivate value();
}


@Public(@PkgPrivate)
public void m() {}
}


I think the criteria for package selection should be closely tied to 
requirements of the generated proxy class code. And the generated code 
references the return type of the method.


Regards, Peter



cheers
/Joel




Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-10 Thread Peter Levart


On 01/10/2014 12:59 AM, srikalyan chandrashekar wrote:
David/Peter you are right, the logs trace came from passed run, i am 
trying to simulate the failure and get the logs for failed runs(2000+ 
runs done and still no failure), will get back to you once i have the 
data from failed run. Sorry for the confusion.


I doubt the logs will be any different. A simple test that throws an 
exception inside Thread.run() without catching it shows that 
TraceExceptions doesn't report the fact that Thread.run() terminates 
abruptly (as David pointed out, pending exception is reported after 
every bytecode executed and there's no bytecode that invoked Thread.run()).
While you're at it, testing, could you also test the modified 
ReferenceHandler (the one that calls private runImpl() from it's run() 
method) so that we get a proof of incorrect behaviour.


Since we suspect there's something wrong with exception handling in 
interpreter, I devised a hypothetical reproducer that tries to simulate 
ReferenceHandler in many aspects, but doesn't require to be a 
ReferenceHandler:


http://cr.openjdk.java.net/~plevart/misc/OOME/OOMECatchingTest.java

This is designed to run indefinitely and only terminate if/when thread 
dies. Could you run this program in the environment that causes the 
OOMEInReferenceHandler test to fail and see if it terminates?



Regards, Peter



---
Thanks
kalyan

On 01/08/2014 11:22 PM, David Holmes wrote:

Thanks Peter.

Kalyan: Can you confirm, as Peter asked, that the TraceExceptions 
output came from a failed run?


AFAICS the Trace info is printed after each bytecode where there is a 
pending exception - though I'm not 100% sure on the printing within 
the VM runtime. Based on that I think we see the Trace output in 
run() at the point where wait() returns, so it may well be caught 
after that - in which case this was not a failing run.


I also can't reproduce the problem :(

David

On 8/01/2014 10:34 PM, Peter Levart wrote:

On 01/08/2014 07:30 AM, David Holmes wrote:

On 8/01/2014 4:19 PM, David Holmes wrote:

On 8/01/2014 7:33 AM, srikalyan chandrashekar wrote:
Hi David, TraceExceptions with fastdebug build produced some nice 
trace
http://cr.openjdk.java.net/%7Esrikchan/OOME_exception_trace.log 
. The
native method wait(long) is where the OOME if being thrown, the 
deepest

call is in

src/share/vm/gc_interface/collectedHeap.inline.hpp, line 157


Yes but it is the caller that is of interest:

Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/runtime/objectMonitor.cpp, 



line 1649]
for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
  thrown in interpreter method {method} {0x7f78b4800ae0} 'wait'
'(J)V' in 'java/lang/Object'
  at bci 0 for thread 0x7f78c40d2800

The ReferenceHandler thread gets the OOME trying to allocate the
InterruptedException.


However we already have a catch block around the wait() so how is this
OOME getting through? A bug in exception handling in the 
interpreter ??




Might be. And it may have something to do with the fact that the
Thread.run() method is the 1st call frame on the thread's stack (seems
like corner case). The last few meaningful TraceExceptions records are:


Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp, 


line 157]
for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
thrown
[/HUDSON/workspace/8-2-build-linux-amd64/jdk8/1317/hotspot/src/share/vm/runtime/objectMonitor.cpp, 


line 1649]
for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
  thrown in interpreter method {method} {0x7f78b4800ae0} 'wait'
'(J)V' in 'java/lang/Object'
  at bci 0 for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
  thrown in interpreter method {method} {0x7f78b4800ca8} 'wait'
'()V' in 'java/lang/Object'
  at *bci 2* for thread 0x7f78c40d2800
Exception a 'java/lang/OutOfMemoryError' (0xd6a01840)
  thrown in interpreter method {method} {0x7f78b48d2250} 'run'
'()V' in 'java/lang/ref/Reference$ReferenceHandler'
  at *bci 36* for thread 0x7f78c40d2800


Here's the relevant bytecodes:


public class java.lang.Object

   public final void wait() throws java.lang.InterruptedException;
 descriptor: ()V
 flags: ACC_PUBLIC, ACC_FINAL
 Code:
   stack=3, locals=1, args_size=1
  0: aload_0
  1: lconst_0
* 2: invokevirtual #73 // Method wait:(J)V*
  5: return
   LineNumberTable:
 line 502: 0
 line 503: 5
 Exceptions:
   throws java.lang.InterruptedException


class java.lang.ref.Reference$ReferenceHandler extends java.lang.Thread

   public void run();
 descriptor: ()V

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-10 Thread Peter Levart

On 01/10/2014 09:31 AM, Peter Levart wrote:
Since we suspect there's something wrong with exception handling in 
interpreter, I devised a hypothetical reproducer that tries to 
simulate ReferenceHandler in many aspects, but doesn't require to be a 
ReferenceHandler:


http://cr.openjdk.java.net/~plevart/misc/OOME/OOMECatchingTest.java

This is designed to run indefinitely and only terminate if/when thread 
dies. Could you run this program in the environment that causes the 
OOMEInReferenceHandler test to fail and see if it terminates?


I forgot to mention that in order for this long-running program to 
exhibit interpreter behaviour, it should be run with -Xint option. So I 
suggest:


-Xmx24M -XX:-UseTLAB -Xint

Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-11 Thread Peter Levart


On 01/10/2014 10:51 PM, srikalyan chandrashekar wrote:
Hi Peter the version you provided ran indefinitely(i put a 10 minute 
timeout) and the program got interrupted(no error),


Did you run it with or without fastedbug  -XX:+TraceExceptions ? If 
with, it might be that fastdebug and/or -XX:+TraceExceptions changes the 
execution a bit so that we can no longer reproduce the wrong behaviour.


even if there were to be an error you cannot print the string of 
thread to console(these have been attempted earlier).


...it has been attempted to print toString in uncaught exception 
handler. At that time, the heap is still full. I'm printing it after the 
GC has cleared the heap. You can try that it works by commenting out the 
try { and corresponding } catch (OOME x) {} exception handler...


- The test's running on interpreter mode, what i am watching for is 
one error with trace. Without fastdebug build and -XX:+TraceExceptions 
i am able to reproduce failure atleast 5 failures out of 1000 runs but 
with fastdebug+Trace no luck yet(already past few 1000 runs).


It might be interesting to try with fastebug build but without the 
-XX:+TraceExceptions option to see what has an effect on it. It might 
also be interesting to try the modified ReferenceHandler (the one with 
private runImpl() method called from run()) and with normal 
non-fastdebug JDK. This info might be useful when one starts to inspect 
the exception handling code in interpreter...


Regards, Peter



---
Thanks
kalyan

On 01/10/2014 02:57 AM, Peter Levart wrote:

On 01/10/2014 09:31 AM, Peter Levart wrote:
Since we suspect there's something wrong with exception handling in 
interpreter, I devised a hypothetical reproducer that tries to 
simulate ReferenceHandler in many aspects, but doesn't require to be 
a ReferenceHandler:


http://cr.openjdk.java.net/~plevart/misc/OOME/OOMECatchingTest.java

This is designed to run indefinitely and only terminate if/when 
thread dies. Could you run this program in the environment that 
causes the OOMEInReferenceHandler test to fail and see if it 
terminates?


I forgot to mention that in order for this long-running program to 
exhibit interpreter behaviour, it should be run with -Xint option. So 
I suggest:


-Xmx24M -XX:-UseTLAB -Xint

Regards, Peter







Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-17 Thread Peter Levart
 from the above changes, Peter's suggestion to create and
call a
private runImpl() from run() in ReferenceHandler makes sense to me.


Why would we need this?

David
-



---
Thanks
kalyan

On 01/13/2014 03:57 PM, srikalyan wrote:


On 1/11/14, 6:15 AM, Peter Levart wrote:


On 01/10/2014 10:51 PM, srikalyan chandrashekar wrote:

Hi Peter the version you provided ran indefinitely(i put a 10
minute
timeout) and the program got interrupted(no error),


Did you run it with or without fastedbug  -XX:+TraceExceptions 
? If
with, it might be that fastdebug and/or -XX:+TraceExceptions 
changes

the execution a bit so that we can no longer reproduce the wrong
behaviour.

With fastdebug  -XX:TraceExceptions. I will try combination of
possible options(i.e without -XX:TraceEception on debug build etc)
soon.


even if there were to be an error you cannot print the 
string of

thread to console(these have been attempted earlier).


...it has been attempted to print toString in uncaught exception
handler. At that time, the heap is still full. I'm printing it 
after
the GC has cleared the heap. You can try that it works by 
commenting

out the try { and corresponding } catch (OOME x) {} exception
handler...
Since there is a GC call prior to printing string i will give 
that a

shot with non-debug build.


- The test's running on interpreter mode, what i am watching 
for is

one error with trace. Without fastdebug build and
-XX:+TraceExceptions i am able to reproduce failure atleast 5
failures out of 1000 runs but with fastdebug+Trace no luck
yet(already past few 1000 runs).


It might be interesting to try with fastebug build but without the
-XX:+TraceExceptions option to see what has an effect on it. It
might
also be interesting to try the modified ReferenceHandler (the one
with private runImpl() method called from run()) and with normal
non-fastdebug JDK. This info might be useful when one starts to
inspect the exception handling code in interpreter...

Regards, Peter



--
Thanks
kalyan
Ph: (408)-585-8040



---
Thanks
kalyan

On 01/10/2014 02:57 AM, Peter Levart wrote:

On 01/10/2014 09:31 AM, Peter Levart wrote:
Since we suspect there's something wrong with exception 
handling
in interpreter, I devised a hypothetical reproducer that 
tries to
simulate ReferenceHandler in many aspects, but doesn't 
require to

be a ReferenceHandler:

http://cr.openjdk.java.net/~plevart/misc/OOME/OOMECatchingTest.java 




This is designed to run indefinitely and only terminate if/when
thread dies. Could you run this program in the environment that
causes the OOMEInReferenceHandler test to fail and see if it
terminates?


I forgot to mention that in order for this long-running 
program to
exhibit interpreter behaviour, it should be run with -Xint 
option.

So I suggest:

-Xmx24M -XX:-UseTLAB -Xint

Regards, Peter













Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-17 Thread Peter Levart

On 01/17/2014 02:00 PM, Peter Levart wrote:

On 01/17/2014 05:38 AM, David Holmes wrote:

On 17/01/2014 1:31 PM, srikalyan chandrashekar wrote:

Hi David, the disassembled code is also attached to the bug. Per my


Sorry missed that.

analysis the exception was thrown when Reference Handler was on line 
143

as put in the earlier email.


But if the numbers in the dissassembly match the BCI then 65 shows:

  65: instanceof#11 // class sun/misc/Cleaner

which makes more sense, the runtime instanceof check might encounter 
an OOME condition. I wish there was some easy way to trace into the 
full call chain as TraceExceptions doesn't show you any runtime 
frames :(


Still, it is easy enough to check:

// Fast path for cleaners
boolean isCleaner = false;
try {
  isCleaner = r instanceof Cleaner;
} catch (OutofMemoryError oome) {
  continue;
}

if (isCleaner) {
  ((Cleaner)r).clean();
  continue;
}



Hi David, Kalyan,

I've caught-up now. Just thinking: is instanceof Cleaner throwing 
OOME as a result of loading the Cleaner class? Wouldn't the above code 
then throw some error also in ((Cleaner)r) - the checkcast, since 
Cleaner class would not be successfully initialized? 


Well, no. The above code would just skip Cleaner processing in this 
situation. And will never be doing it again after the heap is freed... 
So it might be good to load and initialize Cleaner class as part of 
ReferenceHandler initialization to ensure correct operation...


Peter

Perhaps we should pre-load and initialize the Cleaner class as part of 
ReferenceHandler initialization...


Regards, Peter


Thanks,
David


--
Thanks
kalyan

On 1/16/14 6:16 PM, David Holmes wrote:

On 17/01/2014 4:48 AM, srikalyan wrote:

Hi David

On 1/15/14, 9:04 PM, David Holmes wrote:

On 16/01/2014 10:19 AM, srikalyan chandrashekar wrote:

Hi Peter/David, we could finally get a trace of exception with
fastdebug
build and ReferenceHandler modified (with runImpl() added and 
called

from run()). The logs, disassembled code is available in JIRA
https://bugs.openjdk.java.net/browse/JDK-8022321 as attachments.


All I can see is the log for the OOMECatchingTest program not one 
for

the actual ReferenceHandler ??


Please search for ReferenceHandler in the log.

Observations from the log:

Root Cause:
1) UncaughtException is being dispatched from Reference.java:143
141   ReferenceObject r;
142   synchronized (lock) {
143if (pending != null) {
144r = pending;
145pending = r.discovered;
146r.discovered = null;

pending field in Reference is touched and updated by the 
collector, so
at line 143 when the execution context is in Reference handler 
there

might have been an Exception pending due to allocation done by
collector
which causes ReferenceHandler thread to die.


Sorry but the GC does not trigger asynchronous exceptions so this
explanation does not make any sense to me. What part of the log led
you to this conclusion?

-- Log Excerpt begins --
Exception a 'java/lang/OutOfMemoryError' (0xff7808e8)
thrown
[/home/srikalyc/work/ora2013/infracleanup/jdk8/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp, 



line 168]
for thread 0x7feed80cf800
Exception a 'java/lang/OutOfMemoryError' (0xff7808e8)
  thrown in interpreter method {method} {0x7feeddd3c600} 
'runImpl'

'()V' in 'java/lang/ref/Reference$ReferenceHandler'
  at bci 65 for thread 0x7feed80cf800
Exception a 'java/lang/OutOfMemoryError' (0xff7808e8)
  thrown in interpreter method {method} {0x7feeddd3c478} 'run'
'()V' in 'java/lang/ref/Reference$ReferenceHandler'
  at bci 1 for thread 0x7feed80cf800
Exception a 'java/lang/OutOfMemoryError' (0xff780868)
thrown
[/home/srikalyc/work/ora2013/infracleanup/jdk8/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp, 



line 157]
for thread 0x7feed80cf800
Exception a 'java/lang/OutOfMemoryError' (0xff780868)
  thrown in interpreter method {method} {0x7feeddcaaf90}
'uncaughtException' '(Ljava/lang/Thread;Ljava/lang/Throwable;)V' 
in '

  at bci 48 for thread 0x7feed80cf800
Exception a 'java/lang/OutOfMemoryError' (0xff780868)
  thrown in interpreter method {method} {0x7feeddca7298}
'dispatchUncaughtException' '(Ljava/lang/Throwable;)V' in 
'java/lang/

  at bci 6 for thread 0x7feed80cf800
-- Log Excerpt ends --
Sorry if it is a wrong understanding.


What you are seeing there is an OOME escaping the run() method which
will cause the uncaughtExceptionHandler to be run which then triggers
a second OOME (likely as it tries to report information about the
first OOME). The first exception occurred in runImpl at BCI 65. Can
you disassemble (javap -c) the class you used so we can see what is at
BCI 65.

Thanks,
David




Suggested fix

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-17 Thread Peter Levart

On 01/17/2014 02:13 PM, Peter Levart wrote:

// Fast path for cleaners
boolean isCleaner = false;
try {
  isCleaner = r instanceof Cleaner;
} catch (OutofMemoryError oome) {
  continue;
}

if (isCleaner) {
  ((Cleaner)r).clean();
  continue;
}



Hi David, Kalyan,

I've caught-up now. Just thinking: is instanceof Cleaner throwing 
OOME as a result of loading the Cleaner class? Wouldn't the above 
code then throw some error also in ((Cleaner)r) - the checkcast, 
since Cleaner class would not be successfully initialized? 


Well, no. The above code would just skip Cleaner processing in this 
situation. And will never be doing it again after the heap is freed... 
So it might be good to load and initialize Cleaner class as part of 
ReferenceHandler initialization to ensure correct operation... 


Well, yes and no. Let me try once more:

Above code will skip Cleaner processing if the 1st time instanceof 
Cleaner is executed, OOME is thrown as a consequence of full heap while 
loading and initializing the Cleaner class. The 2nd time the instanceof 
Cleaner is executed after such OOME, the same line would throw 
NoClassDefFoundError as a consequence of referencing a class that failed 
initialization. Am I right?


Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-20 Thread Peter Levart

On 01/20/2014 02:51 AM, David Holmes wrote:

Hi Peter,

On 17/01/2014 11:24 PM, Peter Levart wrote:

On 01/17/2014 02:13 PM, Peter Levart wrote:

// Fast path for cleaners
boolean isCleaner = false;
try {
  isCleaner = r instanceof Cleaner;
} catch (OutofMemoryError oome) {
  continue;
}

if (isCleaner) {
  ((Cleaner)r).clean();
  continue;
}



Hi David, Kalyan,

I've caught-up now. Just thinking: is instanceof Cleaner throwing
OOME as a result of loading the Cleaner class? Wouldn't the above
code then throw some error also in ((Cleaner)r) - the checkcast,
since Cleaner class would not be successfully initialized?


Well, no. The above code would just skip Cleaner processing in this
situation. And will never be doing it again after the heap is freed...
So it might be good to load and initialize Cleaner class as part of
ReferenceHandler initialization to ensure correct operation...


Well, yes and no. Let me try once more:

Above code will skip Cleaner processing if the 1st time instanceof
Cleaner is executed, OOME is thrown as a consequence of full heap while
loading and initializing the Cleaner class.


Yes - I was assuming that this would not fail the very first time and 
so the Cleaner class would already be loaded. Failing to be able to 
load the Cleaner class was one of the potential issues flagged earlier 
with this problem. I was actually assuming that Cleaner would be 
loaded already due to some actual Cleaner subclasses being used, but 
this does not happen as part of the default initialization. :( The 
irony being that if the Cleaner class is not loaded then r can not be 
an instance of Cleaner and so we would fail to load the class in a 
case where we didn't need it anyway.


What I wanted to focus on here was an OOME from the instanceof itself, 
but as you say that might trigger classloading of Cleaner (which is 
not what I was interested in).



The 2nd time the instanceof
Cleaner is executed after such OOME, the same line would throw
NoClassDefFoundError as a consequence of referencing a class that failed
initialization. Am I right?


instanceof is not one of the class initialization triggers, so we 
should not see an OOME generated due to a class initialization 
exception and so the class will not be put into the Erroneous state 
and so subsequent attempts to use the class will not automatically 
trigger NoClassdefFoundError.


If OOME occurs during actual loading/linking of the class Cleaner it 
is unclear what would happen on subsequent attempts. OOME is not a 
LinkageError that must be rethrown on subsequent attempts, and it is 
potentially a transient condition, so I would expect a re-load attempt 
to be allowed. However we are now deep into the details of the VM and 
it may well depend on the exact place from which the OOME originates.


The bottom line with the current problem is that there are multiple 
non-obvious paths by which the ReferenceHandler can encounter an OOME. 
In such cases we do not want the ReferenceHandler to terminate - which 
implies catching the OOME and continuing. However we also do not want 
to silently skip Cleaner processing or reference queue processing - as 
that would lead to hard to diagnoze bugs. But trying to report the 
problem may not be possible due to being out-of-memory. It may be that 
we need to break things up into multiple try/catch blocks, where each 
catch does a System.gc() and then reports that the OOME occurred. Of 
course the reporting must still be in a try/catch for the OOME. Though 
at some point letting the ReferenceHandler die may be the only way to 
report a major memory problem.


David


Hm... If I give -verbose:class option to run a simple test program:

public class Test { public static void main(String... a) {} }

I see Cleaner class being loaded before Test class. I don't see by which 
tread or if it might get loaded after main() starts, but I suspect that 
loading of Cleaner is not a problem here. Initialization of Cleaner 
class is not performed by ReferenceHandler thread as you pointed out. 
The instanceof does not trigger it and if it returns true then Cleaner 
has already been initialized. So there must be some other cause for 
instanceof throwing OOME...


What do you say about this variant of ReferenceHandler.run() method:

public void run() {
for (;;) {
Reference r;
Cleaner c;
synchronized (lock) {
r = pending;
if (r != null) {
// instanceof operator might throw OOME 
sometimes. Just retry after

// yielding - might have better luck next time...
try {
c = r instanceof Cleaner ? (Cleaner) r : null;
} catch (OutOfMemoryError x) {
Thread.yield();
continue;
}
pending = r.discovered

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-20 Thread Peter Levart
 skipped a Reference because of OOME, but 
if we just re-try until we eventually succeed, nothing is lost, nothing 
to report (but a slow response)...




Your suggested approach seems okay though I'm not sure why we 
shouldn't help things along by calling System.gc() ourselves rather 
than just yielding and hoping things will get cleaned up elsewhere. 
But for the present purposes your approach will suffice I think.


Maybe my understanding is wrong but isn't the fact that OOME is rised a 
consequence of that VM has already attempted to clear things up 
(executing a GC round synchronously) but didn't succeed to make enough 
free space to satisfy the allocation request? If this is only how some 
collectors/allocators are implemented and not a general rule, then we 
should put a System.gc() in place of Thread.yield(). Should we also 
combine that with Thread.yield()? I'm concerned of a possibility that we 
spin, consume too much CPU (ReferenceHandler thread has MAX priority) so 
that other threads dont' get enough CPU time to proceed and clean things 
up (we hope other threads will also get OOME and release things as their 
stacks unwind...).



Regards, Peter



Thanks,
David

On 20/01/2014 6:42 PM, Peter Levart wrote:

On 01/20/2014 09:00 AM, Peter Levart wrote:

On 01/20/2014 02:51 AM, David Holmes wrote:

Hi Peter,

On 17/01/2014 11:24 PM, Peter Levart wrote:

On 01/17/2014 02:13 PM, Peter Levart wrote:

// Fast path for cleaners
boolean isCleaner = false;
try {
  isCleaner = r instanceof Cleaner;
} catch (OutofMemoryError oome) {
  continue;
}

if (isCleaner) {
  ((Cleaner)r).clean();
  continue;
}



Hi David, Kalyan,

I've caught-up now. Just thinking: is instanceof Cleaner throwing
OOME as a result of loading the Cleaner class? Wouldn't the above
code then throw some error also in ((Cleaner)r) - the checkcast,
since Cleaner class would not be successfully initialized?


Well, no. The above code would just skip Cleaner processing in this
situation. And will never be doing it again after the heap is 
freed...

So it might be good to load and initialize Cleaner class as part of
ReferenceHandler initialization to ensure correct operation...


Well, yes and no. Let me try once more:

Above code will skip Cleaner processing if the 1st time instanceof
Cleaner is executed, OOME is thrown as a consequence of full heap
while
loading and initializing the Cleaner class.


Yes - I was assuming that this would not fail the very first time and
so the Cleaner class would already be loaded. Failing to be able to
load the Cleaner class was one of the potential issues flagged
earlier with this problem. I was actually assuming that Cleaner would
be loaded already due to some actual Cleaner subclasses being used,
but this does not happen as part of the default initialization. :(
The irony being that if the Cleaner class is not loaded then r can
not be an instance of Cleaner and so we would fail to load the class
in a case where we didn't need it anyway.

What I wanted to focus on here was an OOME from the instanceof
itself, but as you say that might trigger classloading of Cleaner
(which is not what I was interested in).


The 2nd time the instanceof
Cleaner is executed after such OOME, the same line would throw
NoClassDefFoundError as a consequence of referencing a class that
failed
initialization. Am I right?


instanceof is not one of the class initialization triggers, so we
should not see an OOME generated due to a class initialization
exception and so the class will not be put into the Erroneous state
and so subsequent attempts to use the class will not automatically
trigger NoClassdefFoundError.

If OOME occurs during actual loading/linking of the class Cleaner it
is unclear what would happen on subsequent attempts. OOME is not a
LinkageError that must be rethrown on subsequent attempts, and it is
potentially a transient condition, so I would expect a re-load
attempt to be allowed. However we are now deep into the details of
the VM and it may well depend on the exact place from which the OOME
originates.

The bottom line with the current problem is that there are multiple
non-obvious paths by which the ReferenceHandler can encounter an
OOME. In such cases we do not want the ReferenceHandler to terminate
- which implies catching the OOME and continuing. However we also do
not want to silently skip Cleaner processing or reference queue
processing - as that would lead to hard to diagnoze bugs. But trying
to report the problem may not be possible due to being out-of-memory.
It may be that we need to break things up into multiple try/catch
blocks, where each catch does a System.gc() and then reports that the
OOME occurred. Of course the reporting must still be in a try/catch
for the OOME. Though at some point letting the ReferenceHandler die
may be the only way to report a major memory problem.

David


Hm... If I give -verbose:class option to run a simple test program:

public class Test { public static void main(String

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-21 Thread Peter Levart

Hi, David, Kalyan,

Summing up the discussion, I propose the following patch for 
ReferenceHandler:


http://cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/webrev.01/

all 10 java/lang/ref tests pass on my PC (including OOMEInReferenceHandler).

I kindly ask Kalyan to try to re-run the OOMEInReferenceHandler test 
with this code and report any failure.



Thanks, Peter

On 01/21/2014 08:57 AM, David Holmes wrote:

On 21/01/2014 4:54 PM, Peter Levart wrote:


On 01/21/2014 03:22 AM, David Holmes wrote:

Hi Peter,

I do not see Cleaner being loaded prior to the main class on either
Windows or Linux. Which platform are you on? Did you see it loaded
before the main class or as part of executing it?


Before. The main class is empty:

public class Test { public static void main(String... a) {} }

Here's last few lines of -verbose:class:

[Loaded java.util.TimeZone from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfo from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$1 from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInput from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*


Curious. I wonder what the controlling factor is ??



I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it. So perhaps it would be good
to trigger Cleaner loading and initialization as part of
ReferenceHandler initialization to play things safe.



If we do that for Cleaner we may as well do it for 
InterruptedException too.



Also, it is not that I think ReferenceHandler is responsible for
reporting OOME, but that it is responsible for reporting that it was
unable to perform a clean or enqueue because of OOME.


This would be necessary if we skipped a Reference because of OOME, but
if we just re-try until we eventually succeed, nothing is lost, nothing
to report (but a slow response)...


Agreed - just trying to clarify things.



Your suggested approach seems okay though I'm not sure why we
shouldn't help things along by calling System.gc() ourselves rather
than just yielding and hoping things will get cleaned up elsewhere.
But for the present purposes your approach will suffice I think.


Maybe my understanding is wrong but isn't the fact that OOME is rised a
consequence of that VM has already attempted to clear things up
(executing a GC round synchronously) but didn't succeed to make enough
free space to satisfy the allocation request? If this is only how some
collectors/allocators are implemented and not a general rule, then we
should put a System.gc() in place of Thread.yield(). Should we also
combine that with Thread.yield()? I'm concerned of a possibility that we
spin, consume too much CPU (ReferenceHandler thread has MAX priority) so
that other threads dont' get enough CPU time to proceed and clean things
up (we hope other threads will also get OOME and release things as their
stacks unwind...).


You are probably right about the System.gc() - OOME should be thrown 
after GC fails to create space, so it really needs some other thread 
to drop live references to allow further space to be reclaimed.


But note that Thread.yield() can behave badly on some linux systems 
too, so spinning is still a possibility - but either way this would 
only be really bad on a uniprocessor system where yield() is 
unlikely to misbehave.


David
-



Regards, Peter



Thanks,
David

On 20/01/2014 6:42 PM, Peter Levart wrote:

On 01/20/2014 09:00 AM, Peter Levart wrote:

On 01/20/2014 02:51 AM, David Holmes wrote:

Hi Peter,

On 17/01/2014 11:24 PM, Peter Levart wrote:

On 01/17/2014 02:13 PM, Peter Levart wrote:

// Fast path for cleaners
boolean isCleaner = false;
try {
  isCleaner = r instanceof Cleaner;
} catch (OutofMemoryError oome) {
  continue;
}

if (isCleaner) {
  ((Cleaner)r).clean();
  continue;
}



Hi David, Kalyan,

I've caught-up now. Just thinking: is instanceof Cleaner 
throwing

OOME as a result of loading the Cleaner class? Wouldn't the above
code then throw some error also in ((Cleaner)r) - the checkcast,
since Cleaner class would not be successfully initialized?


Well, no. The above code would just skip Cleaner processing in 
this

situation. And will never be doing it again after the heap is
freed...
So it might be good to load and initialize Cleaner class as 
part of

ReferenceHandler initialization to ensure correct operation...


Well, yes and no. Let me try once more:

Above code will skip Cleaner processing if the 1st time instanceof
Cleaner is executed, OOME is thrown as a consequence of full heap
while
loading and initializing the Cleaner class.


Yes - I was assuming

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-21 Thread Peter Levart

On 01/21/2014 08:57 AM, David Holmes wrote:

[Loaded java.util.TimeZone from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfo from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$1 from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInput from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*


Curious. I wonder what the controlling factor is ?? 


The Cleaner is usually loaded by ReferenceHandler in JDK8 in the 1st 
execution of it's loop. It looks like JDK8 system initialization 
produces at least one XXXReference that is cleared before main() method 
is entered (debugging, I found it's a Finalizer for a FileInputStream - 
perhaps of the stream that loads the TimeZone data), so ReferenceHandler 
thread is woken-up, executes the instanceof Cleaner check and this loads 
the class. I put the following printfs in an original ReferenceHandler:


System.out.println(Before using Cleaner...);
// Fast path for cleaners
if (r instanceof Cleaner) {
((Cleaner)r).clean();
continue;
}
System.out.println(After using Cleaner...);


...and the empty main() test with -verbose:class prints:

...
[Loaded java.io.DataInput from 
/home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]
[Loaded java.io.DataInputStream from 
/home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]

*Before using Cleaner...**
**[Loaded sun.misc.Cleaner from out/production/jdk]**
**After using Cleaner...*
[Loaded java.io.ByteArrayInputStream from 
/home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule from 
/home/peter/work/hg/jdk8-tl/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/rt.jar]


...


But sometimes, It seems, the VM is not so quick in clearing the early 
XXXReferences and/or the ReferenceHandler start-up is delayed and the 
1st iteration of the loop is executed after the OOMEInReferenceHandler 
test already fills the heap and consequently loading of Cleaner class 
throws OOME in instanceof check...


My proposed fix is very aggressive. It pre-loads classes, initializes 
them and watches for OOMEs thrown in all ocasions. It might be that 
pre-loading Cleaner class in ReferenceHandler initialization would be 
sufficient to fix this intermittent failure. Or do you think instanceof 
check could throw OOME for some other reason besides loading of the class?



Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-21 Thread Peter Levart

On 01/21/2014 07:54 AM, Peter Levart wrote:
*[Loaded sun.misc.Cleaner from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*
[Loaded java.io.ByteArrayInputStream from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]

...


I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it.


So what changed between JDK 7 and JDK 8?

I suspect the following: 8007572: Replace existing jdk timezone data at 
java.home/lib/zi with JSR310's tzdb



Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-21 Thread Peter Levart


On 01/21/2014 07:17 PM, srikalyan wrote:
Hi Peter/David, catching up after long weekend. Why would there be an 
OOME in object heap due to class loading in perm gen space ?


The perm gen is not a problem her (JDK 8 does not have it and we see 
OOME on JDK8 too). Each time a class is loaded, new java.lang.Class 
object is allocated on heap.


Regards, Peter

Please correct if i am missing something here. Meanwhile i will give 
the version of Reference Handler you both agreed on a try.

--
Thanks
kalyan
Ph: (408)-585-8040

On 1/21/14, 7:24 AM, Peter Levart wrote:

On 01/21/2014 07:54 AM, Peter Levart wrote:
*[Loaded sun.misc.Cleaner from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*
[Loaded java.io.ByteArrayInputStream from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule from 
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]

...


I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it.


So what changed between JDK 7 and JDK 8?

I suspect the following: 8007572: Replace existing jdk timezone data 
at java.home/lib/zi with JSR310's tzdb



Regards, Peter





Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-24 Thread Peter Levart


On 01/24/2014 02:53 AM, srikalyan chandrashekar wrote:
Hi David, yes thats right, only benefit i see is we can avoid 
assignment to 'r' if pending is null.


Hi Kalyan,

Good to hear that test runs without failures so far.

Regarding assignment of 'r'. What I tried to accomplish with the change 
was eliminate double reading of 'pending' field. I have a mental model 
of local variable being a register and field being a memory location. 
This may be important if the field is volatile, but for normal fields, I 
guess the optimizer knows how to compile such code most optimally in 
either case. The old (your) version is better from logical perspective, 
since it guarantees that dereferencing the 'r', wherever it is possible, 
will never throw NPE (dereferencing where 'r' is not assigned is not 
possible because of definitive assignment rules). So I support going 
back to your version...


Regards, Peter



--
Thanks
kalyan

On 1/23/14 4:33 PM, David Holmes wrote:

On 24/01/2014 6:10 AM, srikalyan wrote:

Hi Peter, i have modified your code from

r = pending;
if (r != null) {
  ..
   TO
if (pending != null) {
  r = pending;

This is because the r is used later in the code and must not be 
assigned

pending unless it is not null(this was as is earlier).


If r is null, because pending is null then you perform the wait() and 
then continue - back to the top of the loop. There is no bug in 
Peter's code.


The new webrev is

posted here
http://cr.openjdk.java.net/~srikchan/Regression/JDK-8022321_OOMEInReferenceHandler-webrev-V2/ 

. I ran a 1000 run and no failures so far, however i would like to 
run a

couple more 1000 runs to assert the fix.

PS: The description section of JEP-122
(http://openjdk.java.net/jeps/122) says meta-data would be in native
memory(not heap).


The class_mirror is a Java object not meta-data.

David


--
Thanks
kalyan
Ph: (408)-585-8040


On 1/21/14, 2:31 PM, Peter Levart wrote:


On 01/21/2014 07:17 PM, srikalyan wrote:

Hi Peter/David, catching up after long weekend. Why would there be an
OOME in object heap due to class loading in perm gen space ?


The perm gen is not a problem her (JDK 8 does not have it and we see
OOME on JDK8 too). Each time a class is loaded, new java.lang.Class
object is allocated on heap.

Regards, Peter


Please correct if i am missing something here. Meanwhile i will give
the version of Reference Handler you both agreed on a try.
--
Thanks
kalyan
Ph: (408)-585-8040

On 1/21/14, 7:24 AM, Peter Levart wrote:

On 01/21/2014 07:54 AM, Peter Levart wrote:

*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*
[Loaded java.io.ByteArrayInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule
from /home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
...


I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it.


So what changed between JDK 7 and JDK 8?

I suspect the following: 8007572: Replace existing jdk timezone data
at java.home/lib/zi with JSR310's tzdb


Regards, Peter









Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-24 Thread Peter Levart


On 01/22/2014 03:19 AM, David Holmes wrote:

Hi Peter,

On 22/01/2014 12:00 AM, Peter Levart wrote:

Hi, David, Kalyan,

Summing up the discussion, I propose the following patch for
ReferenceHandler:

http://cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/webrev.01/ 



I can live with it, though it maybe that once Cleaner has been 
preloaded instanceof can no longer throw OOME. Can't be 100% sure. And 
there's some duplication/verbosity in the commentary that could be 
trimmed down :)


Any specific reason to use Unsafe to do the preload rather than 
Class.forName ? Does this force Unsafe to be loaded earlier than it 
otherwise would?


Good question. In systemDictionary.hpp they are both on the preloaded 
list in this order:


  do_klass(Reference_klass, java_lang_ref_Reference,   
Pre ) \

...
  do_klass(misc_Unsafe_klass, 
sun_misc_Unsafe,   Pre ) \



So when Reference is initialized, the Unsafe is already loaded. But I 
don't know if it is already initialized. This should be studied.


I'll try to find out what is the case and get back to you.

Regards, Peter




Thanks,
David



all 10 java/lang/ref tests pass on my PC (including
OOMEInReferenceHandler).

I kindly ask Kalyan to try to re-run the OOMEInReferenceHandler test
with this code and report any failure.


Thanks, Peter

On 01/21/2014 08:57 AM, David Holmes wrote:

On 21/01/2014 4:54 PM, Peter Levart wrote:


On 01/21/2014 03:22 AM, David Holmes wrote:

Hi Peter,

I do not see Cleaner being loaded prior to the main class on either
Windows or Linux. Which platform are you on? Did you see it loaded
before the main class or as part of executing it?


Before. The main class is empty:

public class Test { public static void main(String... a) {} }

Here's last few lines of -verbose:class:

[Loaded java.util.TimeZone from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfo from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$1 from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInput from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded java.io.DataInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*


Curious. I wonder what the controlling factor is ??



I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it. So perhaps it would be 
good

to trigger Cleaner loading and initialization as part of
ReferenceHandler initialization to play things safe.



If we do that for Cleaner we may as well do it for
InterruptedException too.


Also, it is not that I think ReferenceHandler is responsible for
reporting OOME, but that it is responsible for reporting that it was
unable to perform a clean or enqueue because of OOME.


This would be necessary if we skipped a Reference because of OOME, but
if we just re-try until we eventually succeed, nothing is lost, 
nothing

to report (but a slow response)...


Agreed - just trying to clarify things.



Your suggested approach seems okay though I'm not sure why we
shouldn't help things along by calling System.gc() ourselves rather
than just yielding and hoping things will get cleaned up elsewhere.
But for the present purposes your approach will suffice I think.


Maybe my understanding is wrong but isn't the fact that OOME is 
rised a

consequence of that VM has already attempted to clear things up
(executing a GC round synchronously) but didn't succeed to make enough
free space to satisfy the allocation request? If this is only how some
collectors/allocators are implemented and not a general rule, then we
should put a System.gc() in place of Thread.yield(). Should we also
combine that with Thread.yield()? I'm concerned of a possibility 
that we
spin, consume too much CPU (ReferenceHandler thread has MAX 
priority) so
that other threads dont' get enough CPU time to proceed and clean 
things
up (we hope other threads will also get OOME and release things as 
their

stacks unwind...).


You are probably right about the System.gc() - OOME should be thrown
after GC fails to create space, so it really needs some other thread
to drop live references to allow further space to be reclaimed.

But note that Thread.yield() can behave badly on some linux systems
too, so spinning is still a possibility - but either way this would
only be really bad on a uniprocessor system where yield() is
unlikely to misbehave.

David
-



Regards, Peter



Thanks,
David

On 20/01/2014 6:42 PM, Peter Levart wrote:

On 01/20/2014 09:00 AM, Peter Levart wrote:

On 01/20/2014 02:51 AM, David Holmes wrote:

Hi Peter,

On 17/01/2014 11:24 PM, Peter Levart wrote:

On 01/17/2014 02:13 PM, Peter Levart

Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-26 Thread Peter Levart


On 01/25/2014 05:35 AM, srikalyan chandrashekar wrote:
Hi Peter, if you are a committer would you like to take this further 
(OR) perhaps david could sponsor this change.


Hi,

Here's new webrev that takes into account Kaylan's and David's review 
comments:


cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/webrev.02/


I changed into using Class.forName() instead of Unsafe for class 
preloading and initialization just to be on the safe side regarding 
unwanted premature initialization of Unsafe class. I also took the 
liberty of removing an unneeded semicolon (line 114) and fixing a JDK 8 
compile time error in generics (line 189):


incompatible types: java.lang.ref.ReferenceQueuecapture#1 of ? 
super java.lang.Object cannot be converted to 
java.lang.ref.ReferenceQueuejava.lang.Object


I re-ran the java/lang/ref tests and they pass.

Can I count you as a reviewer, Kalyan? If I get a go also from David, 
I'll commit this to jdk9/dev...


Regards, Peter


--
Thanks
kalyan
On 1/24/14 4:05 PM, Peter Levart wrote:


On 01/24/2014 02:53 AM, srikalyan chandrashekar wrote:
Hi David, yes thats right, only benefit i see is we can avoid 
assignment to 'r' if pending is null.


Hi Kalyan,

Good to hear that test runs without failures so far.

Regarding assignment of 'r'. What I tried to accomplish with the 
change was eliminate double reading of 'pending' field. I have a 
mental model of local variable being a register and field being a 
memory location. This may be important if the field is volatile, but 
for normal fields, I guess the optimizer knows how to compile such 
code most optimally in either case. The old (your) version is better 
from logical perspective, since it guarantees that dereferencing the 
'r', wherever it is possible, will never throw NPE (dereferencing 
where 'r' is not assigned is not possible because of definitive 
assignment rules). So I support going back to your version...


Regards, Peter



--
Thanks
kalyan

On 1/23/14 4:33 PM, David Holmes wrote:

On 24/01/2014 6:10 AM, srikalyan wrote:

Hi Peter, i have modified your code from

r = pending;
if (r != null) {
  ..
   TO
if (pending != null) {
  r = pending;

This is because the r is used later in the code and must not be 
assigned

pending unless it is not null(this was as is earlier).


If r is null, because pending is null then you perform the wait() 
and then continue - back to the top of the loop. There is no bug in 
Peter's code.


The new webrev is

posted here
http://cr.openjdk.java.net/~srikchan/Regression/JDK-8022321_OOMEInReferenceHandler-webrev-V2/ 

. I ran a 1000 run and no failures so far, however i would like to 
run a

couple more 1000 runs to assert the fix.

PS: The description section of JEP-122
(http://openjdk.java.net/jeps/122) says meta-data would be in native
memory(not heap).


The class_mirror is a Java object not meta-data.

David


--
Thanks
kalyan
Ph: (408)-585-8040


On 1/21/14, 2:31 PM, Peter Levart wrote:


On 01/21/2014 07:17 PM, srikalyan wrote:
Hi Peter/David, catching up after long weekend. Why would there 
be an

OOME in object heap due to class loading in perm gen space ?


The perm gen is not a problem her (JDK 8 does not have it and we see
OOME on JDK8 too). Each time a class is loaded, new java.lang.Class
object is allocated on heap.

Regards, Peter

Please correct if i am missing something here. Meanwhile i will 
give

the version of Reference Handler you both agreed on a try.
--
Thanks
kalyan
Ph: (408)-585-8040

On 1/21/14, 7:24 AM, Peter Levart wrote:

On 01/21/2014 07:54 AM, Peter Levart wrote:

*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*
[Loaded java.io.ByteArrayInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule
from /home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
...


I'm on linux, 64bit and using official EA build 121 of JDK 8...

But if I try with JDK 7u45, I don't see it.


So what changed between JDK 7 and JDK 8?

I suspect the following: 8007572: Replace existing jdk timezone 
data

at java.home/lib/zi with JSR310's tzdb


Regards, Peter













Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-28 Thread Peter Levart

On 01/28/2014 03:17 AM, David Holmes wrote:

On 27/01/2014 5:07 AM, Peter Levart wrote:


On 01/25/2014 05:35 AM, srikalyan chandrashekar wrote:

Hi Peter, if you are a committer would you like to take this further
(OR) perhaps david could sponsor this change.


Hi,

Here's new webrev that takes into account Kaylan's and David's review
comments:

cr.openjdk.java.net/~plevart/jdk9-dev/OOMEInReferenceHandler/webrev.02/


I changed into using Class.forName() instead of Unsafe for class
preloading and initialization just to be on the safe side regarding
unwanted premature initialization of Unsafe class. I also took the
liberty of removing an unneeded semicolon (line 114) and fixing a JDK 8
compile time error in generics (line 189):

 incompatible types: java.lang.ref.ReferenceQueuecapture#1 of ?
super java.lang.Object cannot be converted to
java.lang.ref.ReferenceQueuejava.lang.Object


Seems somewhat odd given there is no supertype for Object but it is 
consistent with the field declaration:


ReferenceQueue? super T queue;

The generics here is a little odd as we don't really know the type of 
T we just play fast-and-loose by declaring:


ReferenceObject r;

Which only works because of erasure. I guess it wouldn't work to try 
and use a simple wildcard '?' for both 'r' and 'q' as they would be 
different captures to javac.


Yes, I tried that too and it results in even more unsafe casts.

It's odd yes, since the compile-time error is not present when building 
via OpenJDK build system make files (using make images in top 
directory for example) but only if I compile the class from command line 
(using javac directly) or from IDEA. I use JDK 8 ea-b121 in all cases as 
a build JDK. Are there any special options passed to javac for compiling 
those classes in JDK build system that allow such code?


Regards, Peter




I re-ran the java/lang/ref tests and they pass.

Can I count you as a reviewer, Kalyan? If I get a go also from David,
I'll commit this to jdk9/dev...


I can be counted as the Reviewer. Kalyan can be listed as a reviewer.

Thanks Peter.

David
-


Regards, Peter


--
Thanks
kalyan
On 1/24/14 4:05 PM, Peter Levart wrote:


On 01/24/2014 02:53 AM, srikalyan chandrashekar wrote:

Hi David, yes thats right, only benefit i see is we can avoid
assignment to 'r' if pending is null.


Hi Kalyan,

Good to hear that test runs without failures so far.

Regarding assignment of 'r'. What I tried to accomplish with the
change was eliminate double reading of 'pending' field. I have a
mental model of local variable being a register and field being a
memory location. This may be important if the field is volatile, but
for normal fields, I guess the optimizer knows how to compile such
code most optimally in either case. The old (your) version is better
from logical perspective, since it guarantees that dereferencing the
'r', wherever it is possible, will never throw NPE (dereferencing
where 'r' is not assigned is not possible because of definitive
assignment rules). So I support going back to your version...

Regards, Peter



--
Thanks
kalyan

On 1/23/14 4:33 PM, David Holmes wrote:

On 24/01/2014 6:10 AM, srikalyan wrote:

Hi Peter, i have modified your code from

r = pending;
if (r != null) {
  ..
   TO
if (pending != null) {
  r = pending;

This is because the r is used later in the code and must not be
assigned
pending unless it is not null(this was as is earlier).


If r is null, because pending is null then you perform the wait()
and then continue - back to the top of the loop. There is no bug in
Peter's code.

The new webrev is

posted here
http://cr.openjdk.java.net/~srikchan/Regression/JDK-8022321_OOMEInReferenceHandler-webrev-V2/ 



. I ran a 1000 run and no failures so far, however i would like to
run a
couple more 1000 runs to assert the fix.

PS: The description section of JEP-122
(http://openjdk.java.net/jeps/122) says meta-data would be in 
native

memory(not heap).


The class_mirror is a Java object not meta-data.

David


--
Thanks
kalyan
Ph: (408)-585-8040


On 1/21/14, 2:31 PM, Peter Levart wrote:


On 01/21/2014 07:17 PM, srikalyan wrote:

Hi Peter/David, catching up after long weekend. Why would there
be an
OOME in object heap due to class loading in perm gen space ?


The perm gen is not a problem her (JDK 8 does not have it and 
we see
OOME on JDK8 too). Each time a class is loaded, new 
java.lang.Class

object is allocated on heap.

Regards, Peter


Please correct if i am missing something here. Meanwhile i will
give
the version of Reference Handler you both agreed on a try.
--
Thanks
kalyan
Ph: (408)-585-8040

On 1/21/14, 7:24 AM, Peter Levart wrote:

On 01/21/2014 07:54 AM, Peter Levart wrote:

*[Loaded sun.misc.Cleaner from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]*
[Loaded java.io.ByteArrayInputStream from
/home/peter/Apps64/jdk1.8.0-ea-b121/jre/lib/rt.jar]
[Loaded sun.util.calendar.ZoneInfoFile$ZoneOffsetTransitionRule
from /home/peter/Apps64

Re: RFR(s): 8023541 Race condition in rmid initialization

2014-01-29 Thread Peter Levart

Hi Stuart,

My eye was caught by the following new method:

 328 private synchronized void awaitInitialized() {
 329 try {
 330 while (!initialized) {
 331 wait();
 332 }
 333 } catch (InterruptedException ie) {
 334 Thread.currentThread().interrupt();
 335 }
 336 }



...if the thread calling this method is interrupted while waiting, it 
will set the interrupted status of the thread back, but will terminate 
the waiting loop. So the initialization race is still possible. Why not 
wait until initialized like:



boolean interrupted = false;
while (!initialized) {
try {
wait();
} catch (InterruptedException ie) {
interrupted = true;
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}


Regards, Peter


boolean interrupted = false;
On 01/29/2014 07:51 AM, Stuart Marks wrote:

Hi all,

Please review this fix to a race condition in rmid initialization. 
Briefly, rmid subclasses the RMI registry implementation and provides 
special handling for its own stub. Unfortunately the registry is 
exported in the super() call, making remote calls possible before 
rmid's stub initialization is complete. The fix is to ensure that all 
remote calls wait for initialization before proceeding.


Bug:

https://bugs.openjdk.java.net/browse/JDK-8023541

Webrev:

http://cr.openjdk.java.net/~smarks/reviews/8023541/webrev.0/

Thanks,

s'marks




Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-29 Thread Peter Levart

On 01/28/2014 04:46 PM, Alan Bateman wrote:

On 28/01/2014 08:44, Peter Levart wrote:


Yes, I tried that too and it results in even more unsafe casts.

It's odd yes, since the compile-time error is not present when 
building via OpenJDK build system make files (using make images in 
top directory for example) but only if I compile the class from 
command line (using javac directly) or from IDEA. I use JDK 8 ea-b121 
in all cases as a build JDK. Are there any special options passed to 
javac for compiling those classes in JDK build system that allow such 
code?


jdk/make/Setup.gmk has the -Xlint options that are used in the build 
but I suspect it more than that all the classes in java/lang/ref are 
compiled together.


-Alan


That's right. If I add the source for ReferenceQueue.java into a 
directory where Reference.java resides and then compile with:


javac -d /tmp Reference.java

...then Reference as well as ReferenceQueue gets compiled and there's no 
error. If there is sole Reference.java in the directory, a compile time 
error is emitted. I checked the source of ReferenceQueue.java in JDK 8 
ea-b121 (the JDK used for compiling) and it only differs in copyright 
year from the source in jdk9-dev. So there seems to be inconsistency in 
javac's handling of types that are read from .class vs. .java files.


I'll try to create a reproducer example and post it to compiler-dev.

Since I don't know what should be the correct behaviour of javac, I can 
leave the Reference.java changes as proposed since it compiles in both 
cases. Or should I revert the change to declaration of local variable 'q' ?


Regards, Peter



Re: Analysis on JDK-8022321 java/lang/ref/OOMEInReferenceHandler.java fails intermittently

2014-01-30 Thread Peter Levart

On 01/30/2014 03:46 PM, Alan Bateman wrote:

On 29/01/2014 19:10, Mandy Chung wrote:


On 1/29/2014 5:09 AM, Peter Levart wrote:


Since I don't know what should be the correct behaviour of javac, I 
can leave the Reference.java changes as proposed since it compiles 
in both cases. Or should I revert the change to declaration of local 
variable 'q' ? 


I slightly prefer to revert the change to ReferenceQueue? super 
Object for now as there is no supertype for Object and this looks a 
little odd.  We can clean this up as a separate fix after we get 
clarification from compiler-dev.
I see Peter has posted a question to compiler-dev on this and it can 
always be re-visited once it clear why it compiles when both Reference 
and ReferenceQueue are in the same compilation unit.


-Alan


I Just commited the version with no change to ReferenceQueueObject 
line to jdk9/dev. If there is a bug in javac and the code would not 
compile as is, the change to this line should be committed as part of 
javac fix, right?


Regards, Peter



RFR - 6857566 (bf) DirectByteBuffer garbage creation can outpace reclamation

2014-02-05 Thread Peter Levart

Hi,

I'm proposing a patch for the following issue:

https://bugs.openjdk.java.net/browse/JDK-6857566

The patch is basically the same as developed and tested as part of the 
following discussion 3 months ago:


http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-October/021547.html

It's just modified to be applied on top of JDK9 which already changed 
since then. Here's the webrev:


http://cr.openjdk.java.net/~plevart/jdk9-dev/DirectBufferAlloc/webrev.01/


As Alan Bateman pointed out: A related piece of work is the FileChannel 
map implementation where there is a gc + retry if mmap fails. This could 
be changed to have a similar back-off/retry.


I'm planning to examine this code and come up with a similar patch for 
mapped memory.


Regards, Peter



Re: ObjectIn/OutputStream improvements

2014-02-05 Thread Peter Levart

On 02/05/2014 04:11 PM, Chris Hegarty wrote:

Thanks stuart, Mike, and Paul.


- Why not have getClassSignature() return an interned string? (that's if 
interning is actually essential. Are we sure it's not just overhead?)

I didn’t want to change the existing use of interning here, just refactor the 
code a little to make it cleaner.


I think that would be a better way to spend our performance investigation 
budget. Thus, it might be better to remove the StringBuilder field from this 
patch and submit another one focusing on UTF decoding; the other changes in the 
patch look good.

Agreed. This could be looked at separately.

Latest webrev:
   http://cr.openjdk.java.net/~chegar/serial_stupp.01/

Thanks,
-Chris.


Hi Chris,

What about the following even less garbage-producing-and-copying 
ObjectStreamClass.get[Class|Method]Signature combo:


/**
 * Returns JVM type signature for given class.
 */
static String getClassSignature(Class? cl) {
if (cl.isPrimitive())
return getPrimitiveSignature(cl);
else
return appendClassSignature(new StringBuilder(), 
cl).toString();

}

private static StringBuilder appendClassSignature(StringBuilder 
sbuf, Class? cl) {

while (cl.isArray()) {
sbuf.append('[');
cl = cl.getComponentType();
}

if (cl.isPrimitive())
sbuf.append(getPrimitiveSignature(cl));
else
sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');

return sbuf;
}

/**
 * Returns JVM type signature for given list of parameters and 
return type.

 */
private static String getMethodSignature(Class?[] paramTypes,
 Class? retType)
{
StringBuilder sbuf = new StringBuilder();
sbuf.append('(');
for (int i = 0; i  paramTypes.length; i++) {
appendClassSignature(sbuf, paramTypes[i]);
}
sbuf.append(')');
appendClassSignature(sbuf, retType);
return sbuf.toString();
}


Regards, Peter



Re: RFR - 6857566 (bf) DirectByteBuffer garbage creation can outpace reclamation

2014-02-20 Thread Peter Levart


On 02/05/2014 11:21 AM, Alan Bateman wrote:

On 05/02/2014 08:08, Peter Levart wrote:

Hi,

I'm proposing a patch for the following issue:

https://bugs.openjdk.java.net/browse/JDK-6857566

The patch is basically the same as developed and tested as part of 
the following discussion 3 months ago:


http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-October/021547.html 



It's just modified to be applied on top of JDK9 which already changed 
since then. Here's the webrev:


http://cr.openjdk.java.net/~plevart/jdk9-dev/DirectBufferAlloc/webrev.01/ 



Hi Alan,

I made another webrev with minor changes based on your feedback...

http://cr.openjdk.java.net/~plevart/jdk9-dev/DirectBufferAlloc/webrev.03/

Thanks for re-basing the changes and from the previous discussion then 
I think there was agreement on the approach. So I'd say this is ready 
to go into jdk9/dev.


A minor comments on the usages of tryHandlePendingReferences in Bits 
that it might be a bit neater to not split the line. At least when 
looking at the patch then it makes it a bit more obvious what is 
condition vs. statement in the while loop.


I did that by extracting the reference to JavaLangRefAccess into a local 
variable.




Another minor comment is that usually avoid System.exit in tests. It's 
probably okay here as it always runs in othervm mode but in other 
modes a System.exit(0) will be flagged by jtreg and will require it 
spin up another VM.


No System.exit in this webrev any more. The test should still run in 
othervm though, since it uses special VM option 
-XX:MaxDirectMemorySize=128m. Without it there might be to much direct 
memory available by default on some machine (like mine with 16GB of RAM) 
to provoke an error in 5 seconds time...




I completely agree with separating the mapped buffers issue to a 
separate issue.


Thanks again for running with this one (it goes back to original 
implementation in JDK 1.4).


-Alan.


I think I'll need another official review before pushing this.

Regards, Peter




Re: JDK 9 RFR of JDK-8035279: Clean up internal deprecations in BigInteger

2014-02-20 Thread Peter Levart


On 02/20/2014 11:20 AM, David Holmes wrote:

Hi Brian,

On 20/02/2014 7:44 AM, Brian Burkhalter wrote:

This patch concerns cleaning up some ugly internal deprecations.

Issue:https://bugs.openjdk.java.net/browse/JDK-8035279
Webrev:http://cr.openjdk.java.net/~bpb/8035279/webrev.00/

All JTREG BigInteger tests pass, and the serialized form has been 
unaltered as verified by bidirectional read-write testing between 
Java 7 and this version.


I would appreciate scrutiny of the arithmetic to make sure that I've 
made no silly errors. Also I would be interested in opinions as to 
whether the volatile keyword should in fact be used for the 
affected instance variables.


re: volatile

The basic approach being taken with these primitive fields is lazy 
initialization to a value that will always be the same if recomputed. 
If the variables are not volatile then in the worst-case (this is 
theoretical only) they will be recomputed by each thread that accesses 
them. If they are volatile then they will only be recomputed by 
threads that truly race on the initialization logic, but you will 
thereafter pay the price of a volatile read on each access.


Either way you will be functionally correct so it all comes down to 
performance. Practically speaking I would expect you to be better off 
overall without the volatile.


As Paul notes the powerCache array does not need to be volatile as it 
is initialized as part of class initialization.


Cheers,
David


Hi Brian,

I would also be concerned about correctness here. You changed fields to 
be volatile and assigned them with different that default (zero) values 
in field initializers. Take for example the field bitCount:


|  156 private volatile int bitCount = Integer.MIN_VALUE;|


In code you check this initial value and decide whether to lazily 
compute the real value or not based on this check:


3298 public int bitCount() {
3299 // This computation has a known, acceptable non-critical race 
condition.
3300 if (bitCount == Integer.MIN_VALUE) {  // bitCount not initialized 
yet


There has recently been a discussion on concurrency-dev mailing list 
about whether this is safe:


http://cs.oswego.edu/pipermail/concurrency-interest/2013-November/011951.html

...in cases where the instance of such constructed object escapes to 
non-constructing thread via data-race. I think the conclusion was that 
such semantics is desirable and might be guaranteed in a future updated 
JMM, but currently it is not, although most JVMs are implemented in such 
a way that this is safe. Citing Doug Lea:



Right. To summarize:

* Programmers do not expect that even though final fields are specifically
publication-safe, volatile fields are not always so.

* For various implementation reasons, JVMs arrange that
volatile fields are publication safe anyway, at least in
cases we know about.

* Actually updating the JMM/JLS to mandate this is not easy
(no small tweak that I know applies). But now is a good time
to be considering a full revision for JDK9.

* In the mean time, it would make sense to further test
and validate JVMs as meeting this likely future spec.

-Doug


Is there a special reason you changed the uninitialized value from 
default (zero) to non-zero?



Regards, Peter









Re: JDK 9 RFR of JDK-8035279: Clean up internal deprecations in BigInteger

2014-02-21 Thread Peter Levart


On 02/21/2014 10:06 AM, Paul Sandoz wrote:

I think we should try and use zero, as John says (alas @Stable is package 
private to j.l.invoke), and replace 0 with another value such as MIN_VALUE if 
one is unsure of the bounds:

   int lsb;
   if ((lsb = lowestSetBit) == 0) {
 ...
 lowestSetBit = lsb != 0 ? lsb : Integer.MIN_VALUE;
   }
   return lsb != Integer.MIN_VALUE : lsb ? 0;


Hm, would the following be any better or worse?

int lsb = lowestSetBit;
if (lsb = 0) {
if (lsb == Integer.MIN_VALUE) {
lsb = 0;
} else {
...
lowestSetBit = lsb != 0 ? lsb : Integer.MIN_VALUE;
}
}
return lsb;


I wonder if any of the above is better than current code that offsets 
the value space. Current code only contains a single 
compare+conditional-branch on fast-path while both of above variants 
contain more than one. Does eliminating a single add instruction on 
fast-path pay up for that? What do measurements show?



Regards, Peter



Re: [7u backport] RFR: 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations

2014-02-24 Thread Peter Levart

Hi Dmeetry,

On 02/22/2014 01:22 PM, dmeetry degrave wrote:

Hi all,

I would like to ask for a review of combined back port for 
7u-dev/7u80. The main goal is to have a fix for 7122142 in jdk7, it 
also integrates the changes from 8005232, 7185456, 8022721


https://bugs.openjdk.java.net/browse/JDK-7122142
https://bugs.openjdk.java.net/browse/JDK-8005232
https://bugs.openjdk.java.net/browse/JDK-7185456
https://bugs.openjdk.java.net/browse/JDK-8022721

Original jdk8 changes:

7122142: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/e4ce6502eac0
8005232: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/1109bfff4e92
7185456: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/ae03282ba501
8022721: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/2281a7f79738

back port:

http://cr.openjdk.java.net/~dmeetry/7122142.8005232.7185456.8022721/webrev.0/ 



Patches can't be applied cleanly, hence it was a manual back port, 
though the final result is equivalent to applying the patches in 
chronological order (8005232, 7185456, 7122142, 8022721) and applying 
all the relevant rejected parts


It's good to see those patches being back-ported to 7u. By browsing the 
webrev, I don't see any obvious difference between the original patches 
and the backport. Do you happen to remember in what part of code there 
were rejects so that you had to manually apply the changes?


(with one exception, AnnotationTypeRuntimeAssumptionTest.java test was 
not included due to jdk8 API).


Ah, It's the Class.getDeclaredAnnotation(Class) that's new in JDK8. 
Here's the changed test that only uses the JDK7 API so you can include 
this test too:


http://cr.openjdk.java.net/~plevart/jdk7u/7122142/AnnotationTypeRuntimeAssumptionTest.java



All tests in test/java/lang/annotation passed.

thanks,
dmeetry


Regards, Peter



Re: JDK 9 RFR of JDK-8035279: Clean up internal deprecations in BigInteger

2014-02-26 Thread Peter Levart

On 02/25/2014 09:38 PM, Brian Burkhalter wrote:

On Feb 20, 2014, at 1:42 AM, Paul Sandoz wrote:


Not sure the static powerCache field, in the original code, needs to be 
volatile either:

1137 private static volatile BigInteger[][] powerCache;

Is there consensus on whether volatile is necessary here?


I think it has to be volatile. The powerCache implementation was added 
in the following changeset:


http://hg.openjdk.java.net/jdk9/dev/jdk/rev/7546

...and improved later in the following:

http://hg.openjdk.java.net/jdk9/dev/jdk/rev/7586

It uses a copy-on-write technique to extend the cache with new values 
when needed. volatile is mandatory here to safely publish the newly 
constructed array-of-arrays and the newly constructed sub-array to other 
threads. Without volatile, other threads could see null slots where 
BigInteger[] and/or BigInteger objects should be...


Regards, Peter



Thanks,

Brian




Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-02-26 Thread Peter Levart

On 02/26/2014 09:54 PM, Martin Buchholz wrote:

I don't recall having added this particular wart
to test/java/lang/ProcessBuilder/Basic.java, and history suggests that
others did that.

It does seem that being able to tell whether a java object monitor is
currently locked is useful for debugging and monitoring - there should be a
way to do that.


Thread.holdsLock(Object) ?

Regards, Peter




On Wed, Feb 26, 2014 at 7:12 AM, Paul Sandoz paul.san...@oracle.com wrote:


Hi,

Out of all the methods on Unsafe i think the
monitorEnter/monitorExit/tryMonitorEnter are the least used and are very
strong candidates for removal.

99% of use-cases are supported by classes in the
java.util.concurrent.locks package.


Within the JDK itself it is only used in one JDK test file
test/java/lang/ProcessBuilder/Basic.java:

 while (unsafe.tryMonitorEnter(s)) {
 unsafe.monitorExit(s);
 Thread.sleep(1);
 }

for a test verifying an EOF is received on pending reads and it is polling
to check when the process builder acquires the lock before destroying the
process, presumably to avoid some sort of race condition that occasionally
causes the test to fail.

I believe this test as been through a number of rounds, i stared at things
for a bit, but cannot quickly work out a replacement; i lack the knowledge
on this area.


Outside of the JDK i can only find one usage of monitorExit/Enter
(according to grep code) in JBoss modules, and i believe this is only used
on Java 1.6 to work around some limitations in class loading that were
fixed in 1.7.


Given such very limited use i propose to remove these methods after having
worked out a fix for ProcessBuilder/Basic.java test.

Paul.





Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-02-26 Thread Peter Levart

On 02/27/2014 08:29 AM, Peter Levart wrote:

On 02/26/2014 09:54 PM, Martin Buchholz wrote:

I don't recall having added this particular wart
to test/java/lang/ProcessBuilder/Basic.java, and history suggests that
others did that.

It does seem that being able to tell whether a java object monitor is
currently locked is useful for debugging and monitoring - there 
should be a

way to do that.


Thread.holdsLock(Object) ?


Ah, you meant to query from some other thread, right?

Peter



Regards, Peter




On Wed, Feb 26, 2014 at 7:12 AM, Paul Sandoz paul.san...@oracle.com 
wrote:



Hi,

Out of all the methods on Unsafe i think the
monitorEnter/monitorExit/tryMonitorEnter are the least used and are 
very

strong candidates for removal.

99% of use-cases are supported by classes in the
java.util.concurrent.locks package.


Within the JDK itself it is only used in one JDK test file
test/java/lang/ProcessBuilder/Basic.java:

 while (unsafe.tryMonitorEnter(s)) {
 unsafe.monitorExit(s);
 Thread.sleep(1);
 }

for a test verifying an EOF is received on pending reads and it is 
polling
to check when the process builder acquires the lock before 
destroying the
process, presumably to avoid some sort of race condition that 
occasionally

causes the test to fail.

I believe this test as been through a number of rounds, i stared at 
things
for a bit, but cannot quickly work out a replacement; i lack the 
knowledge

on this area.


Outside of the JDK i can only find one usage of monitorExit/Enter
(according to grep code) in JBoss modules, and i believe this is 
only used

on Java 1.6 to work around some limitations in class loading that were
fixed in 1.7.


Given such very limited use i propose to remove these methods after 
having

worked out a fix for ProcessBuilder/Basic.java test.

Paul.







Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-02-27 Thread Peter Levart

On 02/27/2014 08:41 AM, David Holmes wrote:

On 27/02/2014 5:30 PM, Peter Levart wrote:

On 02/27/2014 08:29 AM, Peter Levart wrote:

On 02/26/2014 09:54 PM, Martin Buchholz wrote:

I don't recall having added this particular wart
to test/java/lang/ProcessBuilder/Basic.java, and history suggests that
others did that.

It does seem that being able to tell whether a java object monitor is
currently locked is useful for debugging and monitoring - there
should be a
way to do that.


Thread.holdsLock(Object) ?


Ah, you meant to query from some other thread, right?


Right - that is the usage in Basic.java but I'm still scratching my 
head trying to understand what finding the BufferedInputStream locked 
is supposed to signify.


Here's the relevant code block:

while (unsafe.tryMonitorEnter(s)) {
unsafe.monitorExit(s);
Thread.sleep(1);
}

This code block waits until it finds that some thread has acquired the 
lock on 's' for at least 1 ms (or else it can miss it and will wait 
further) ...


Since this block is executed for s instanceof BufferedInputStream, what 
this block does, is wait until one of synchronized methods on 
BufferedInputStream is called. The thread that does that, calls read() 
or read(byte[]) and blocks while holding a lock, since the child process 
that is spawned and whose stdout the thread is trying to read in this 
situation does a 10 minute sleep. I think the following could be used 
instead for the same purpose:


while (!isLocked(s, 100L)) {
Thread.sleep(1);
}

// using the following utility method:

static boolean isLocked(final Object monitor, long millis) throws 
InterruptedException {

Thread t = new Thread() {
@Override
public void run() {
synchronized (monitor) { }
}
};
t.start();
t.join(millis);
return t.isAlive();
}


Regards, Peter



David
-


Peter



Regards, Peter




On Wed, Feb 26, 2014 at 7:12 AM, Paul Sandoz paul.san...@oracle.com
wrote:


Hi,

Out of all the methods on Unsafe i think the
monitorEnter/monitorExit/tryMonitorEnter are the least used and are
very
strong candidates for removal.

99% of use-cases are supported by classes in the
java.util.concurrent.locks package.


Within the JDK itself it is only used in one JDK test file
test/java/lang/ProcessBuilder/Basic.java:

 while (unsafe.tryMonitorEnter(s)) {
 unsafe.monitorExit(s);
 Thread.sleep(1);
 }

for a test verifying an EOF is received on pending reads and it is
polling
to check when the process builder acquires the lock before
destroying the
process, presumably to avoid some sort of race condition that
occasionally
causes the test to fail.

I believe this test as been through a number of rounds, i stared at
things
for a bit, but cannot quickly work out a replacement; i lack the
knowledge
on this area.


Outside of the JDK i can only find one usage of monitorExit/Enter
(according to grep code) in JBoss modules, and i believe this is
only used
on Java 1.6 to work around some limitations in class loading that 
were

fixed in 1.7.


Given such very limited use i propose to remove these methods after
having
worked out a fix for ProcessBuilder/Basic.java test.

Paul.









Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-02-27 Thread Peter Levart

On 02/27/2014 10:58 AM, David Holmes wrote:

On 27/02/2014 6:38 PM, Peter Levart wrote:

On 02/27/2014 08:41 AM, David Holmes wrote:

On 27/02/2014 5:30 PM, Peter Levart wrote:

On 02/27/2014 08:29 AM, Peter Levart wrote:

On 02/26/2014 09:54 PM, Martin Buchholz wrote:

I don't recall having added this particular wart
to test/java/lang/ProcessBuilder/Basic.java, and history suggests 
that

others did that.

It does seem that being able to tell whether a java object 
monitor is

currently locked is useful for debugging and monitoring - there
should be a
way to do that.


Thread.holdsLock(Object) ?


Ah, you meant to query from some other thread, right?


Right - that is the usage in Basic.java but I'm still scratching my
head trying to understand what finding the BufferedInputStream locked
is supposed to signify.


Here's the relevant code block:

 while (unsafe.tryMonitorEnter(s)) {
 unsafe.monitorExit(s);
 Thread.sleep(1);
 }

This code block waits until it finds that some thread has acquired the
lock on 's' for at least 1 ms (or else it can miss it and will wait
further) ...

Since this block is executed for s instanceof BufferedInputStream, what
this block does, is wait until one of synchronized methods on
BufferedInputStream is called. The thread that does that, calls read()
or read(byte[]) and blocks while holding a lock, since the child process
that is spawned and whose stdout the thread is trying to read in this
situation does a 10 minute sleep.


Ah I see - thanks for the analysis. So this is a classic 'barrier' 
waiting for the other thread to have reached the synchronized method.



I think the following could be used instead for the same purpose:

 while (!isLocked(s, 100L)) {
 Thread.sleep(1);
 }

// using the following utility method:

 static boolean isLocked(final Object monitor, long millis) throws
InterruptedException {
 Thread t = new Thread() {
 @Override
 public void run() {
 synchronized (monitor) { }
 }
 };
 t.start();
 t.join(millis);
 return t.isAlive();
 }


Functionally yes this will only return true if the object is locked 
for 100ms. But it is potentially going to generate a lot of temporary 
threads. And in theory at least the JIT can optimize the run method 
into nothing.


Ok, then what about the following:

static boolean isLocked(final Object monitor, final long millis) 
throws InterruptedException {

return new Thread() {
volatile boolean unlocked;

@Override
public void run() {
synchronized (monitor) { unlocked = true; }
}

boolean isLocked() throws InterruptedException {
start();
join(millis);
return !unlocked;
}
}.isLocked();
}


// and usage it like:

while (!isLocked(s, 100L)) {
Thread.sleep(100L);
}


This will allocate about 10 Thread objects per second until the other 
thread finally reaches the synchronized read() method in 
BufferedInputStream...



Regards, Peter



Still it is a cute trick :)

David



Regards, Peter



David
-


Peter



Regards, Peter




On Wed, Feb 26, 2014 at 7:12 AM, Paul Sandoz 
paul.san...@oracle.com

wrote:


Hi,

Out of all the methods on Unsafe i think the
monitorEnter/monitorExit/tryMonitorEnter are the least used and are
very
strong candidates for removal.

99% of use-cases are supported by classes in the
java.util.concurrent.locks package.


Within the JDK itself it is only used in one JDK test file
test/java/lang/ProcessBuilder/Basic.java:

 while (unsafe.tryMonitorEnter(s)) {
 unsafe.monitorExit(s);
 Thread.sleep(1);
 }

for a test verifying an EOF is received on pending reads and it is
polling
to check when the process builder acquires the lock before
destroying the
process, presumably to avoid some sort of race condition that
occasionally
causes the test to fail.

I believe this test as been through a number of rounds, i stared 
at public static boolean isLocked(final Object monitor, 
final long millis) throws InterruptedException {

return new Thread() {
volatile boolean unlocked;

@Override
public void run() {
synchronized (monitor) { unlocked = true; }
}

boolean isLocked() throws InterruptedException {
start();
join(millis);
return !unlocked;
}
}.isLocked();
}

things
for a bit, but cannot quickly work out a replacement; i lack the
knowledge
on this area.


Outside of the JDK i can only find one usage of monitorExit/Enter
(according to grep code

Re: JDK 9 RFR of JDK-8035279: Clean up internal deprecations in BigInteger

2014-02-27 Thread Peter Levart

On 02/27/2014 09:22 AM, Paul Sandoz wrote:

On Feb 27, 2014, at 12:51 AM, Brian Burkhalter brian.burkhal...@oracle.com 
wrote:


On Feb 26, 2014, at 1:53 PM, Paul Sandoz wrote:


Thanks for the suggestion, Paul. Assuming it is correct, in what way would this 
be a better approach? (I apologize for being obtuse.)


IMHO it is a simpler solution. It's a cache line that requires updating not the 
cache line*s*, as the current approach can potentially knock out cache lines 
for other radixes.


Potentially yes, but not very likely, since the whole powerCache 
reference is re-read again *after* the computation of cacheLine and then 
replaced with a modified clone immediately after that. It should be 
noted what Alan Eliasen already pointed-out in a discussion back in June 
2013:


http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/018375.html

...so I think what could be improved in current implementation is the 
potential and more likely useless computation of the same values for the 
same radix by multiple concurrent threads. Back then I presented an 
alternative solution which solves that:


http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/018457.html

...and as can be seen, does not use volatile read/write to publish 
BigIntegers - that's why it is important that internal implementation of 
such immutable classes like BigInteger is tolerant to unsafe publication...



Regards, Peter



I forgot to mention a slightly more complex variation is to CAS the cache line 
instead of a lazy set, which can ensure a line does not knock another 
containing a higher exponent.

Paul.




Re: rationale for swallowing exceptions in Class#getEnumConstantsShared

2014-02-28 Thread Peter Levart

On 02/28/2014 04:56 PM, Jochen Theodorou wrote:

Hi,

we stumbled here about a strange error involving enums generated from 
our compiler and that did make me see getEnumConstantsShared() in 
java.lang.Class.


Now the implementation more or less says, that if calling values() 
fails in any way, return null and ignore the exception. But why is the 
exception ignored? It could contain valuable information about what 
did go wrong


Hi Jochen,

I agree that the exception should be thrown (possibly an unchecked 
IllegalArgumentException or something like that with the cause from 
reflective operation). If Class.isEnum() returns true then the class 
should be considered an enum and if it is not conformant to 
specification (which may cause one of those exceptions) then this should 
be reported as exception and not as null return. The 
getEnumConstantsShared() is also used as implementation for public method:


/**
 * Returns the elements of this enum class or *null if this**
** * Class object does not represent an enum type*.
 *
 * @return an array containing the values comprising the enum class
 * represented by this Class object in the order they're
 * declared, or null if this Class object does not
 * represent an enum type
 * @since 1.5
 */
public T[] getEnumConstants() {
T[] values = getEnumConstantsShared();
return (values != null) ? values.clone() : null;
}


The behaviour of above method is not consistent with:

/**
 * Returns *true if and only if this class was declared as an enum* 
in the

 * source code.
 *
 * @return true if and only if this class was declared as an enum 
in the

 * source code
 * @since 1.5
 */
public boolean isEnum() {
// An enum must both directly extend java.lang.Enum and have
// the ENUM bit set; classes for specialized enum constants
// don't do the former.
return (this.getModifiers()  ENUM) != 0 
this.getSuperclass() == java.lang.Enum.class;
}


...which can return true at the same time as getEnumConstants() returns 
null for the same class...



I don't believe there's any code out there that relies on this faulty 
behaviour of getEnumConstants() public method. The other use of 
getEnumConstantsShared() is to support the Enum.valueOf(Class, String) 
method which already throws IllegalArgumentException if the 1st 
parameter does not represent an enum class, so there's no compatibility 
concerns about that use.



What do experts say?


Regards, Peter



In my code for example, something obviously goes wrong... sometimes... 
depending on moon-phases or something. and I have not the slightest 
idea what.


bye Jochen






Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-03-03 Thread Peter Levart

On 03/04/2014 05:09 AM, David Holmes wrote:

On 4/03/2014 1:45 PM, David Holmes wrote:

On 3/03/2014 10:56 PM, David M. Lloyd wrote:
Yes, that would necessarily be the contract of a Monitors class, 
just as

it is part of the contract of Lock today.  If your argument is that it
shouldn't be allowed because it might be used wrong, we might as well
just delete most of the JDK, ReentrantLock included, since it suffers
from the exact same potential problem.  The difference is that monitors
have a simple API in the form of synchronized that people were in the
past and would continue to be free (and recommended) to use.


We should not introduce anything that allows something that was
guaranteed to be safe by the language, to become unsafe. So I can
support a call for tryMonitorEnter, but not for explicit enter/exit
actions.


Which of course is not possible at the API level - Doh! Sorry.


Unless the API is made safe by packing it into a lambda-consuming 
method. For example:


public static boolean trySynchronized(Runnable action);

Regards, Peter



David


David
-

I would not call recommending monitors to be a premature 
optimization.

  The memory overhead of ReentrantLock is far too large for many use
cases, especially when it comes to fine-grained locking of large data
sets.  In fact I would *only* recommend Lock if your need for the extra
behavior it provides (i.e., multiple conditions, tryLock, timed 
tryLock,

and/or interruptible locking) or for the extra behavior provided by
ReentrantLock itself (i.e., lock status introspection) outweighs the
cost of its memory consumption, which so far has happened zero times in
any of the many frameworks I maintain.

On the other hand, adding some of the missing functionality to a
Monitors class would be pretty handy, especially if doing so doesn't
create a large divergence from the existing implementation. Given that
tryMonitorEnter already exists, implementing that method on a Monitors
class seems fairly trivial, which already takes care of one out of the
four special use cases for Locks.  Interruptible locking would be my
first choice for a number two, if this idea were actually officially on
the table.  Finally, an isMonitorHeld() method would tie in another
branch of the discussion nicely and seems trivially possible as well.
Any other information would be a purely

It's worth noting that it's already possible for user code to implement
the basic functionality using JNI methods, though in the interest of
full disclosure it's worth noting that the enter/exit monitor JNI
functions are forbidden by spec to interoperate with the corresponding
bytecodes.

FWIW using the word monitor instead of lock may help avoid 
confusion

and scare off those pesky undergrads.

On 03/02/2014 12:48 PM, Dr Heinz M. Kabutz wrote:

Hi Dave,

lighter is subject to the HotSpot Profiler doing the optimizations
that you expect.  Problem is, once you begin manually locking /
unlocking monitors, the byte codes are not recognizable as standard
synchronized(monitor) {} code, thus the optimizations will also not be
as good (or completely absent).  At least that has been my experience
when I tried it out a few years ago.  So the argument that 
synchronized

is faster than ReentrantLock, besides this being IMHO a premature
optimization, cannot be directly applied to when we manually do use 
the

monitorEnter/monitorExit methods.

The reason why I personally think they are more dangerous than
ReentrantLock is that we are used to synchronized() {} taking care of
the unlocking for us.  If we see a thread that is in the BLOCKED state
(which only happens with synchronized) then we would typically assume
that another thread is /currently /holding the monitor.

Take the following example code:

import sun.misc.*;

import java.lang.reflect.*;

public class MonitorMystery {
   public static Unsafe getUnsafe() {
 try {
   for (Field field : Unsafe.class.getDeclaredFields()) {
 if (Modifier.isStatic(field.getModifiers())) {
   if (field.getType() == Unsafe.class) {
 field.setAccessible(true);
 return (Unsafe) field.get(null);
   }
 }
   }
   throw new IllegalStateException(Unsafe field not found);
 } catch (Exception e) {
   throw new IllegalStateException(
   Could not initialize unsafe, e);
 }
   }

   public static void main(String... args) throws 
InterruptedException {

 Thread t = new Thread() {
   public void run() {
 getUnsafe().monitorEnter(MonitorMystery.class);
   }
 };
 t.start();
 Thread.sleep(100);
 System.out.println(Trying to synchronize);
 synchronized (MonitorMystery.class) {
   System.out.println(Managed to synchronized);
 }
   }
}

We now see that we never manage to synchronize in the main thread 
and in

fact if you do a thread dump you will see a deadlock involving only a
single thread :-)

This is why it is so important to use the correct 

Re: Unsafe: removing the monitorEnter/monitorExit/tryMonitorEnter methods

2014-03-03 Thread Peter Levart

On 03/04/2014 08:01 AM, Peter Levart wrote:

On 03/04/2014 05:09 AM, David Holmes wrote:

On 4/03/2014 1:45 PM, David Holmes wrote:

On 3/03/2014 10:56 PM, David M. Lloyd wrote:
Yes, that would necessarily be the contract of a Monitors class, 
just as

it is part of the contract of Lock today.  If your argument is that it
shouldn't be allowed because it might be used wrong, we might as well
just delete most of the JDK, ReentrantLock included, since it suffers
from the exact same potential problem.  The difference is that 
monitors

have a simple API in the form of synchronized that people were in the
past and would continue to be free (and recommended) to use.


We should not introduce anything that allows something that was
guaranteed to be safe by the language, to become unsafe. So I can
support a call for tryMonitorEnter, but not for explicit enter/exit
actions.


Which of course is not possible at the API level - Doh! Sorry.


Unless the API is made safe by packing it into a lambda-consuming 
method. For example:


public static boolean trySynchronized(Runnable action);


Sorry, forgot the monitor:

public static boolean trySynchronized(Object monitor, Runnable action);


I guess new java.lang.Object instance method is out of question?

Regards, Peter



Regards, Peter



David


David
-

I would not call recommending monitors to be a premature 
optimization.

  The memory overhead of ReentrantLock is far too large for many use
cases, especially when it comes to fine-grained locking of large data
sets.  In fact I would *only* recommend Lock if your need for the 
extra
behavior it provides (i.e., multiple conditions, tryLock, timed 
tryLock,

and/or interruptible locking) or for the extra behavior provided by
ReentrantLock itself (i.e., lock status introspection) outweighs the
cost of its memory consumption, which so far has happened zero 
times in

any of the many frameworks I maintain.

On the other hand, adding some of the missing functionality to a
Monitors class would be pretty handy, especially if doing so doesn't
create a large divergence from the existing implementation. Given that
tryMonitorEnter already exists, implementing that method on a Monitors
class seems fairly trivial, which already takes care of one out of the
four special use cases for Locks.  Interruptible locking would be my
first choice for a number two, if this idea were actually 
officially on

the table.  Finally, an isMonitorHeld() method would tie in another
branch of the discussion nicely and seems trivially possible as well.
Any other information would be a purely

It's worth noting that it's already possible for user code to 
implement

the basic functionality using JNI methods, though in the interest of
full disclosure it's worth noting that the enter/exit monitor JNI
functions are forbidden by spec to interoperate with the corresponding
bytecodes.

FWIW using the word monitor instead of lock may help avoid 
confusion

and scare off those pesky undergrads.

On 03/02/2014 12:48 PM, Dr Heinz M. Kabutz wrote:

Hi Dave,

lighter is subject to the HotSpot Profiler doing the optimizations
that you expect.  Problem is, once you begin manually locking /
unlocking monitors, the byte codes are not recognizable as standard
synchronized(monitor) {} code, thus the optimizations will also 
not be

as good (or completely absent).  At least that has been my experience
when I tried it out a few years ago.  So the argument that 
synchronized

is faster than ReentrantLock, besides this being IMHO a premature
optimization, cannot be directly applied to when we manually do 
use the

monitorEnter/monitorExit methods.

The reason why I personally think they are more dangerous than
ReentrantLock is that we are used to synchronized() {} taking care of
the unlocking for us.  If we see a thread that is in the BLOCKED 
state

(which only happens with synchronized) then we would typically assume
that another thread is /currently /holding the monitor.

Take the following example code:

import sun.misc.*;

import java.lang.reflect.*;

public class MonitorMystery {
   public static Unsafe getUnsafe() {
 try {
   for (Field field : Unsafe.class.getDeclaredFields()) {
 if (Modifier.isStatic(field.getModifiers())) {
   if (field.getType() == Unsafe.class) {
 field.setAccessible(true);
 return (Unsafe) field.get(null);
   }
 }
   }
   throw new IllegalStateException(Unsafe field not found);
 } catch (Exception e) {
   throw new IllegalStateException(
   Could not initialize unsafe, e);
 }
   }

   public static void main(String... args) throws 
InterruptedException {

 Thread t = new Thread() {
   public void run() {
 getUnsafe().monitorEnter(MonitorMystery.class);
   }
 };
 t.start();
 Thread.sleep(100);
 System.out.println(Trying to synchronize);
 synchronized (MonitorMystery.class) {
   System.out.println(Managed

Re: How to close a Process and having shutdown hooks called ?

2014-03-04 Thread Peter Levart

On 03/04/2014 02:09 PM, LE PICARD NICOLAS wrote:

I didn't know for jdk8 functions destroy and the new one destroyForcibly...

And Jonathan was right in his previous answer, I was looking for a solution in Java, I 
mean a portable one like  in Process class, like the destroyGracefully.
I am looking to signals because it seems to be a simple way to achieve this 
portable solution, maybe I'm wrong.

It would be useful (as you said) to have a function to kill gracefully 
through Process class, no ?

Nicolas Le Picard


Hi Nicolas,

So you're spawning a Java sub-process from a Java master process using 
java.lang.Process, do I understand correctly?


Are you in control of the code that represents the child sub-process? Is 
this code already using System.in (STDIN) stream for anything? If the 
answers are YES and NO respectively, then you may be able to use the 
System.in in the sub-process (spawn a special monitoring thread) and 
Process.getOutputStream() in the master process to establish a one way 
channel for passing commands in direction: master process - 
sub-process. One of those commands could be shutdown for example, that 
would trigger a System.exit() in the sub-process. This way you could 
make the shut-down hooks in sub-process be executed before exiting...


Regards, Peter



-Message d'origine-
De : Alan Bateman [mailto:alan.bate...@oracle.com]
Envoyé : mardi 4 mars 2014 13:12
À : Krystal Mok
Cc : LE PICARD NICOLAS; core-libs-dev@openjdk.java.net
Objet : Re: How to close a Process and having shutdown hooks called ?

On 04/03/2014 11:51, Krystal Mok wrote:

Hi Nicolas,

Looks like a well discussed question. On Posix systems, SIGTERM should
work for you. That's the default signal sent by the 'kill' command on Linux.
e.g. please take a look here:
http://stackoverflow.com/questions/2541597/how-to-gracefully-handle-th
e-sigkill-signal-in-java

- Kris


I think he's on Windows and is looking for destroy to use something other than 
TerminateProcess.

As background, the destroy method was confusingly specified to kill the 
sub-process forcibly but it wasn't implemented this way everywhere. On 
Unix/Linux then the long standing implementation used SIGTERM and so no 
guarantee that it would cause the sub-process to terminate. This mismatch was 
examined in JDK 8 (you'll need to go through the archives of this mailing list 
to see the discussion) and the javadoc updated to make it clear that it is 
implementation specific as to whether it is done forcibly or not. In addition a 
new destroyForcibly was added to do the SIGKILL or TerminateProcess for cases 
where you really want to kill the child. There isn't a corresponding 
destroyGracefully but clearly this would be useful if were feasible to 
implement everywhere.

-Alan.




Re: JDK 9 RFR of 6375303: Review use of caching in BigDecimal

2014-03-04 Thread Peter Levart

On 03/04/2014 01:14 AM, Brian Burkhalter wrote:

- add AtomicReferenceFieldUpdater-type constant for stringCache initialization


Hi Brian,

By using volatile read and CAS, there's still a chance that multiple 
concurrent threads will be invoking the layoutChars(true) concurrently, 
but you guarantee that only a single instance of String will ever be 
returned as a result of the toString() method. Is that what you were 
pursuing?


Regards, Peter



Re: JEP 193: Enhanced Volatiles

2014-03-05 Thread Peter Levart


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: Review 8035808: Eliminate dependency to GetPropertyAction and other sun.security.action convenient classes

2014-03-07 Thread Peter Levart

On 03/07/2014 12:31 PM, Alan Bateman wrote:

On 06/03/2014 21:10, Mandy Chung wrote:

Webrev:
http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8035808/webrev.00/

This patch converts the use of sun.security.action.GetPropertyAction 
tolambda

   (PrivilegedActionString) () - System.getProperty(key)

Similarly for GetIntegerAction and GetLongAction.

The sun.security.action.* classes are just convenient classes that 
are used not only by the security library but also used by RMI, 
management, a couple other components that cause cross-module 
dependency that are not absolutely necessary.  They can simply be 
replaced to call System.getProperty, Integer.getInteger, or 
Long.getLong at the callsite.
This looks good to me as it reduces the number of inner classes, 
removes a lot of dependencies on sun.* APIs, and updates the code to 
use new language features. The only downside appears to the cast but 
you can't really get away from that here (at least not without 
declaring a PrivilegedAction for each usage).


-Alan.


Maybe, if PrivilegedAction interface could be retrofitted as follows:

public interface PrivilegedExceptionActionT {
T run() throws Exception;
}

public interface PrivilegedActionT extends 
PrivilegedExceptionActionT {

@Override
T run();
}


Then in majority of cases where lambda body did not throw a checked 
exception, the most-specific rule would choose the 
doPrivileged(PrivilegedAction) method automatically... For 
checked-exceptional-cases the cast would still be needed.



Regards, Peter



Re: [9] RFR (S): 8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed)

2014-03-11 Thread Peter Levart

Hi,

Excuse my ignorant question: What is the purpose of @LambdaForm.Hidden 
annotation?


I suspect it has to do with hiding the call frames in stack traces that 
are part of LambdaForm invocation chain. In this case, method:


private static Object[] prepend(Object elem, Object[] array)

in MethodHandleImpl need not be annotated with this annotation, since 
it's call frame is not on stack when one of the target methods is 
executed. It's just a function used to calculate the argument of the 
call. In fact, if prepend() ever throws exception (NPE in case array is 
null?), It would be preferable that it's call frame is visible in the 
stack trace.


Am I right or am I just talking nonsense?

Regards, Peter


On 03/11/2014 12:12 AM, Vladimir Ivanov wrote:

John, Chris, thanks!

Best regards,
Vladimir Ivanov

On 3/11/14 3:08 AM, Christian Thalinger wrote:

Even better.

On Mar 10, 2014, at 3:21 PM, Vladimir Ivanov 
vladimir.x.iva...@oracle.com wrote:



Chris, thanks for the review.

John suggested an elegant way to fix the problem - use asFixedArity.

Updated fix:
http://cr.openjdk.java.net/~vlivanov/8036117/webrev.01/

Best regards,
Vladimir Ivanov

On 3/8/14 4:51 AM, Christian Thalinger wrote:

Seems good to me.  I’d like to have another name for this method:

+ private static Object invokeCustom(MethodHandle target, 
Object... args) throws Throwable {


On Mar 4, 2014, at 12:00 PM, Vladimir Ivanov 
vladimir.x.iva...@oracle.com wrote:



http://cr.openjdk.java.net/~vlivanov/8036117/webrev.00/
https://bugs.openjdk.java.net/browse/JDK-8036117
84 lines changed: 74 ins; 3 del; 7 mod

I have to revert a cleanup I did for 8027827.
MethodHandle.invokeWithArguments (and generic invocation) has 
unpleasant

peculiarity in behavior when used with VarargsCollector. So,
unfortunately, invokeWithArguments is not an option there.

Looking at the API (excerpts from javadoc [1] [2]), the following
condition doesn't hold in that case:
   trailing parameter type of the caller is a reference type 
identical

to or assignable to the trailing parameter type of the adapter.

Example:
   target.invokeWithArguments((Object[])args)
   =
   target.invoke((Object)o1,(Object)o2,(Object)o3)
   =/
   target.invokeExact((Object)o1, (Object)o2, (Object[])o3)

because Object !: Object[].

The fix is to skip unnecessary conversion when invoking a method 
handle

and just do a pairwise type conversion.

Testing: failing test case, nashorn w/ experimental features (octane)

Thanks!

Best regards,
Vladimir Ivanov

[1] MethodHandle.invokeWithArguments
Performs a variable arity invocation, ..., as if via an inexact 
invoke
from a call site which mentions only the type Object, and whose 
arity is

the length of the argument array.

[2] MethodHandle.asVarargsCollector
When called with plain, inexact invoke, if the caller type is the 
same

as the adapter, the adapter invokes the target as with invokeExact.
(This is the normal behavior for invoke when types match.)

Otherwise, if the caller and adapter arity are the same, and the
trailing parameter type of the caller is a reference type 
identical to

or assignable to the trailing parameter type of the adapter, the
arguments and return values are converted pairwise, as if by 
asType on a

fixed arity method handle.

Otherwise, the arities differ, or the adapter's trailing parameter 
type
is not assignable from the corresponding caller type. In this 
case, the

adapter replaces all trailing arguments from the original trailing
argument position onward, by a new array of type arrayType, whose
elements comprise (in order) the replaced arguments.
___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev




Re: JDK 9 RFC on 8029770: Improve user friendliness of preferences storage on Unix systems

2014-03-11 Thread Peter Levart

On 03/10/2014 10:12 PM, Brian Burkhalter wrote:

This issue (https://bugs.openjdk.java.net/browse/JDK-8029770) concerns 
improving preference handling (java.util.prefs.Preferences) on systems other 
than Mac OS X and Windows, essentially Unix systems other than OS X. It would 
be good to obtain some comments on the behavior of the prospective changes 
including whether they are even necessary. For the moment, comments on the 
behavior are of more interest than those on any particular implementation.

For background, on the Unix systems in question, the file system is used to 
store preferences in a tree with nodes mapping to directories. As node names 
can contain characters which may cause confusion when used verbatim in 
directory names, in those cases where such characters are detected, the 
directory name is derived from the node name by encoding the latter using a 
non-standard variant of the Base 64 Alphabet (Table 1 in [1]) which is immune 
to alphabetic character case folding. This can result in some strange and human 
unreadable directory names in the file system preferences tree. The objective 
here would be to change this scheme to something more user friendly.

There are likely numerous approaches to solving this problem, but I think that 
first it needs to be determined whether interoperability with earlier Java 
versions is a requirement and, if so, what the nature of this requirement is. 
There are probably others, but there are at least the following alternatives 
(not all of which might be sensible):

A) No interoperability: Java 9 and subsequent versions would not share 
preferences with earlier versions.
B) Initialization only: Java 9 preferences would be initialized from the state 
of pre-9 preferences at the instant of first use.
C) Unidirectional: Java 9 would detect changes made by earlier versions.
D) Bidirectional: Java 9 and pre-9 preferences would be kept in sync.

For options C and D note that only Java 9+ instances could effect this 
behavior. If for example Java 9 was not run for some time on a particular 
machine, the pre-9 preferences could significantly diverge from the 9 
preferences. These would presumably be brought into sync when a Java 9+ 
instance next invoked the Preferences APIs.

Whichever option were chosen, the changes made could include the definition of 
a system property which could be set to disable the new preferences handling 
variant, i.e., to force pre-9 file system preferences behavior.

Any comments would be appreciated.

Thanks,

Brian

[1] http://tools.ietf.org/rfc/rfc4648.txt

Hi Brian,

What is the purpose of changing the scheme? Is it just to be more 
power-user and developer friendly? To enable users to inspect the 
preferences with filesystem tools? What about a little command-line 
and/or gui jprefs tool in the style of regedit or gconftool or 
similar? Would that be enough to satisfy the goal? Any of the options 
A...D seem a compatibility nightmare for majority of programs that use 
preferences. Most users don't ever inspect directories starting with dot 
'.', so this feature is more or less targeted at developers, right? A 
tool that is standard part of JRE distribution could do the job of 
browsing (and perhaps changing of) the preferences without compatibility 
concerns...


Regards, Peter



Re: [9] RFR (S): 8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed)

2014-03-11 Thread Peter Levart

On 03/11/2014 12:59 PM, Vladimir Ivanov wrote:

Peter,

You raised totally valid question.

I marked MethodHandleImpl.prepend with @Hidden annotation because it 
is internal implementation detail of JSR292.


You are right that normally a callee can't see it on stack. *But it's 
possible to observe it when stack trace is queried from a separate 
thread. *


Is this good or bad? It enables tools to see it (for example sampling 
profilers, etc...).


Regards, Peter



There's not much value in it in this particular case, but I decided to 
reduce possible noise.


Best regards,
Vladimir Ivanov

On 3/11/14 3:35 PM, Peter Levart wrote:

Hi,

Excuse my ignorant question: What is the purpose of @LambdaForm.Hidden
annotation?

I suspect it has to do with hiding the call frames in stack traces that
are part of LambdaForm invocation chain. In this case, method:

 private static Object[] prepend(Object elem, Object[] array)

in MethodHandleImpl need not be annotated with this annotation, since
it's call frame is not on stack when one of the target methods is
executed. It's just a function used to calculate the argument of the
call. In fact, if prepend() ever throws exception (NPE in case array is
null?), It would be preferable that it's call frame is visible in the
stack trace.

Am I right or am I just talking nonsense?

Regards, Peter


On 03/11/2014 12:12 AM, Vladimir Ivanov wrote:

John, Chris, thanks!

Best regards,
Vladimir Ivanov

On 3/11/14 3:08 AM, Christian Thalinger wrote:

Even better.

On Mar 10, 2014, at 3:21 PM, Vladimir Ivanov
vladimir.x.iva...@oracle.com wrote:


Chris, thanks for the review.

John suggested an elegant way to fix the problem - use asFixedArity.

Updated fix:
http://cr.openjdk.java.net/~vlivanov/8036117/webrev.01/

Best regards,
Vladimir Ivanov

On 3/8/14 4:51 AM, Christian Thalinger wrote:

Seems good to me.  I’d like to have another name for this method:

+ private static Object invokeCustom(MethodHandle target,
Object... args) throws Throwable {

On Mar 4, 2014, at 12:00 PM, Vladimir Ivanov
vladimir.x.iva...@oracle.com wrote:


http://cr.openjdk.java.net/~vlivanov/8036117/webrev.00/
https://bugs.openjdk.java.net/browse/JDK-8036117
84 lines changed: 74 ins; 3 del; 7 mod

I have to revert a cleanup I did for 8027827.
MethodHandle.invokeWithArguments (and generic invocation) has
unpleasant
peculiarity in behavior when used with VarargsCollector. So,
unfortunately, invokeWithArguments is not an option there.

Looking at the API (excerpts from javadoc [1] [2]), the following
condition doesn't hold in that case:
   trailing parameter type of the caller is a reference type
identical
to or assignable to the trailing parameter type of the adapter.

Example:
   target.invokeWithArguments((Object[])args)
   =
   target.invoke((Object)o1,(Object)o2,(Object)o3)
   =/
   target.invokeExact((Object)o1, (Object)o2, (Object[])o3)

because Object !: Object[].

The fix is to skip unnecessary conversion when invoking a method
handle
and just do a pairwise type conversion.

Testing: failing test case, nashorn w/ experimental features 
(octane)


Thanks!

Best regards,
Vladimir Ivanov

[1] MethodHandle.invokeWithArguments
Performs a variable arity invocation, ..., as if via an inexact
invoke
from a call site which mentions only the type Object, and whose
arity is
the length of the argument array.

[2] MethodHandle.asVarargsCollector
When called with plain, inexact invoke, if the caller type is the
same
as the adapter, the adapter invokes the target as with invokeExact.
(This is the normal behavior for invoke when types match.)

Otherwise, if the caller and adapter arity are the same, and the
trailing parameter type of the caller is a reference type
identical to
or assignable to the trailing parameter type of the adapter, the
arguments and return values are converted pairwise, as if by
asType on a
fixed arity method handle.

Otherwise, the arities differ, or the adapter's trailing parameter
type
is not assignable from the corresponding caller type. In this
case, the
adapter replaces all trailing arguments from the original trailing
argument position onward, by a new array of type arrayType, whose
elements comprise (in order) the replaced arguments.
___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


___
mlvm-dev mailing list
mlvm-...@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm

Re: [9] RFR (S): 8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed)

2014-03-11 Thread Peter Levart

On 03/11/2014 03:05 PM, Vladimir Ivanov wrote:

You raised totally valid question.

I marked MethodHandleImpl.prepend with @Hidden annotation because it
is internal implementation detail of JSR292.

You are right that normally a callee can't see it on stack. *But it's
possible to observe it when stack trace is queried from a separate
thread. *


Is this good or bad? It enables tools to see it (for example sampling
profilers, etc...).
For the purposes of sampling profilers (and other monitoring tools) 
@Hidden should be completely ignored.  These tools should use 
appropriate API to get the data.


I looked into the code and @Hidden has even less effect than I thought 
initially. It affects very limited set of cases - only users of 
JVM_FillInStackTrace (when filling exception's stack trace, 
Thread.dumpStack()). Calls to Thread.getStackTrace() from a separate 
thread omit stack trace filtering.


So all you're achieving by annotating prepend() method is that any 
exception stack trace, in case it is thrown inside the prepend() method, 
will hide where it was thrown from. In case all LambdaForm frames 
leading to the prepend() method were also hidden, the exception would 
appear to be thrown from the invocation of the MH...


Regards, Peter



Best regards,
Vladimir Ivanov


Regards, Peter



There's not much value in it in this particular case, but I decided to
reduce possible noise.

Best regards,
Vladimir Ivanov

On 3/11/14 3:35 PM, Peter Levart wrote:

Hi,

Excuse my ignorant question: What is the purpose of @LambdaForm.Hidden
annotation?

I suspect it has to do with hiding the call frames in stack traces 
that

are part of LambdaForm invocation chain. In this case, method:

 private static Object[] prepend(Object elem, Object[] array)

in MethodHandleImpl need not be annotated with this annotation, since
it's call frame is not on stack when one of the target methods is
executed. It's just a function used to calculate the argument of the
call. In fact, if prepend() ever throws exception (NPE in case 
array is

null?), It would be preferable that it's call frame is visible in the
stack trace.

Am I right or am I just talking nonsense?

Regards, Peter


On 03/11/2014 12:12 AM, Vladimir Ivanov wrote:

John, Chris, thanks!

Best regards,
Vladimir Ivanov

On 3/11/14 3:08 AM, Christian Thalinger wrote:

Even better.

On Mar 10, 2014, at 3:21 PM, Vladimir Ivanov
vladimir.x.iva...@oracle.com wrote:


Chris, thanks for the review.

John suggested an elegant way to fix the problem - use 
asFixedArity.


Updated fix:
http://cr.openjdk.java.net/~vlivanov/8036117/webrev.01/

Best regards,
Vladimir Ivanov

On 3/8/14 4:51 AM, Christian Thalinger wrote:

Seems good to me.  I’d like to have another name for this method:

+ private static Object invokeCustom(MethodHandle target,
Object... args) throws Throwable {

On Mar 4, 2014, at 12:00 PM, Vladimir Ivanov
vladimir.x.iva...@oracle.com wrote:


http://cr.openjdk.java.net/~vlivanov/8036117/webrev.00/
https://bugs.openjdk.java.net/browse/JDK-8036117
84 lines changed: 74 ins; 3 del; 7 mod

I have to revert a cleanup I did for 8027827.
MethodHandle.invokeWithArguments (and generic invocation) has
unpleasant
peculiarity in behavior when used with VarargsCollector. So,
unfortunately, invokeWithArguments is not an option there.

Looking at the API (excerpts from javadoc [1] [2]), the following
condition doesn't hold in that case:
   trailing parameter type of the caller is a reference type
identical
to or assignable to the trailing parameter type of the adapter.

Example:
   target.invokeWithArguments((Object[])args)
   =
   target.invoke((Object)o1,(Object)o2,(Object)o3)
   =/
   target.invokeExact((Object)o1, (Object)o2, (Object[])o3)

because Object !: Object[].

The fix is to skip unnecessary conversion when invoking a method
handle
and just do a pairwise type conversion.

Testing: failing test case, nashorn w/ experimental features
(octane)

Thanks!

Best regards,
Vladimir Ivanov

[1] MethodHandle.invokeWithArguments
Performs a variable arity invocation, ..., as if via an inexact
invoke
from a call site which mentions only the type Object, and whose
arity is
the length of the argument array.

[2] MethodHandle.asVarargsCollector
When called with plain, inexact invoke, if the caller type is 
the

same
as the adapter, the adapter invokes the target as with 
invokeExact.

(This is the normal behavior for invoke when types match.)

Otherwise, if the caller and adapter arity are the same, and the
trailing parameter type of the caller is a reference type
identical to
or assignable to the trailing parameter type of the adapter, the
arguments and return values are converted pairwise, as if by
asType on a
fixed arity method handle.

Otherwise, the arities differ, or the adapter's trailing 
parameter

type
is not assignable from the corresponding caller type. In this
case, the
adapter replaces all trailing arguments from the original 
trailing

argument position onward

Re: JDK 9 RFR of 6375303: Review use of caching in BigDecimal

2014-03-12 Thread Peter Levart

On 03/11/2014 06:07 PM, Mike Duigou wrote:

You are making stringCache volatile - performance penalty on ARM  PPC.

It is understood that the volatile is not free. For this purpose it was 
believed that the performance cost was a fair trade off to avoid the heap pollution. 
Regardless of the decision in this case the method used would seem to be the best caching 
pattern available. We do need to establish when it is appropriate to use this solution 
and what the tradeoffs are that would make other solutions more appropriate.



Hi,

What would the following cost?


private transient String stringCache;

public String toString() {
String sc = stringCache;
if (sc == null) {
sc = (String) U.getObjectVolatile(this, STRING_CACHE_OFFSET);
if (sc == null) {
sc = layoutChars(true);
if (!U.compareAndSwapObject(this, STRING_CACHE_OFFSET, 
null, sc)) {
sc = (String) U.getObjectVolatile(this, 
STRING_CACHE_OFFSET);

}
}
}
return sc;
}

private static final Unsafe U = Unsafe.getUnsafe();
private static final long STRING_CACHE_OFFSET;
static {
try {
STRING_CACHE_OFFSET = 
U.objectFieldOffset(BigDecimal.class.getDeclaredField(stringCache));

} catch (NoSuchFieldException e) {
throw new Error(e);
}
}



Regards, Peter



  1   2   3   4   5   6   7   8   9   10   >