8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that

Reviewed-by: attila, lagergren
This commit is contained in:
Matherey Nunez 2014-04-18 21:24:34 +02:00 committed by Marcus Lagergren
parent 187399b1fd
commit af27b4200d
17 changed files with 91 additions and 17 deletions

@ -712,7 +712,6 @@ public final class NativeArray extends ScriptObject {
return new NativeArray(list.toArray()); return new NativeArray(list.toArray());
} }
@SuppressWarnings("null")
private static void concatToList(final ArrayList<Object> list, final Object obj) { private static void concatToList(final ArrayList<Object> list, final Object obj) {
final boolean isScriptArray = isArray(obj); final boolean isScriptArray = isArray(obj);
final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject; final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;

@ -39,9 +39,9 @@ import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyListeners; import jdk.nashorn.internal.runtime.PropertyListeners;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.RuntimeEvent;
import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
import jdk.nashorn.internal.runtime.linker.LinkerCallSite; import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
/** /**

@ -41,6 +41,7 @@ import java.util.logging.Level;
import jdk.nashorn.internal.codegen.types.ArrayType; import jdk.nashorn.internal.codegen.types.ArrayType;
import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.runtime.events.RecompilationEvent;
import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.Bootstrap;
/** /**
@ -576,7 +577,7 @@ final class CompiledFunction {
final FunctionNode fn = oldOptimismInfo.recompile(callSiteType, re); final FunctionNode fn = oldOptimismInfo.recompile(callSiteType, re);
if (LOG.isEnabled()) { if (LOG.isEnabled()) {
LOG.info(new RuntimeEvent<>(Level.INFO, re), "\tRewriteException ", re.getMessageShort()); LOG.info(new RecompilationEvent(Level.INFO, re, re.getReturnValueNonDestructive()), "\tRewriteException ", re.getMessageShort());
} }
// It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already // It didn't necessarily recompile, e.g. for an outer invocation of a recursive function if we already

@ -64,6 +64,7 @@ import jdk.nashorn.internal.ir.debug.ASTWriter;
import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.ir.debug.PrintVisitor;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
import jdk.nashorn.internal.runtime.options.Options; import jdk.nashorn.internal.runtime.options.Options;
/** /**

@ -30,7 +30,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.RuntimeEvent; import jdk.nashorn.internal.runtime.events.RuntimeEvent;
import jdk.nashorn.internal.runtime.options.Options; import jdk.nashorn.internal.runtime.options.Options;
/** /**

@ -100,6 +100,7 @@ public abstract class Property {
/** Property field number or spill slot. */ /** Property field number or spill slot. */
private final int slot; private final int slot;
/** SwitchPoint that is invalidated when property is changed, optional */
protected SwitchPoint changeCallback; protected SwitchPoint changeCallback;
/** /**
@ -173,6 +174,12 @@ public abstract class Property {
return propFlags; return propFlags;
} }
/**
* Set the change callback for this property, i.e. a SwitchPoint
* that will be invalidated when the value of the property is
* changed
* @param sp SwitchPoint to use for change callback
*/
public final void setChangeCallback(final SwitchPoint sp) { public final void setChangeCallback(final SwitchPoint sp) {
this.changeCallback = sp; this.changeCallback = sp;
} }

@ -167,7 +167,7 @@ public class RewriteException extends Exception {
return getUOE().getReturnValueDestructive(); return getUOE().getReturnValueDestructive();
} }
private Object getReturnValueNonDestructive() { Object getReturnValueNonDestructive() {
return getUOE().getReturnValueNonDestructive(); return getUOE().getReturnValueNonDestructive();
} }

@ -2246,7 +2246,6 @@ public abstract class ScriptObject implements PropertyAccess {
* @param request the link request * @param request the link request
* @return GuardedInvocation to be invoked at call site. * @return GuardedInvocation to be invoked at call site.
*/ */
@SuppressWarnings("null")
public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) { public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true); final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);

@ -0,0 +1,67 @@
/*
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime.events;
import java.util.logging.Level;
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
import jdk.nashorn.internal.runtime.RewriteException;
/**
* Subclass of runtime event for {@link RewriteException}. In order not
* to leak memory, RewriteExceptions get their return value destroyed
* and nulled out during recompilation. If we are running with event
* logging enabled, we need to retain the returnValue, hence the extra
* field
*/
public final class RecompilationEvent extends RuntimeEvent<RewriteException> {
private final Object returnValue;
/**
* Constructor
*
* @param level logging level
* @param rewriteException rewriteException wrapped by this RuntimEvent
* @param returnValue rewriteException return value - as we don't want to make
* {@link RewriteException#getReturnValueNonDestructive()} public, we pass it as
* an extra parameter, rather than querying the getter from another package.
*/
public RecompilationEvent(final Level level, final RewriteException rewriteException, final Object returnValue) {
super(level, rewriteException);
assert RecompilableScriptFunctionData.getLogger().isEnabled() :
"Unit test/instrumentation purpose only: RecompilationEvent instances should not be created without '--log=recompile', or we will leak memory in the general case";
this.returnValue = returnValue;
}
/**
* Get the preserved return value for the RewriteException
* @return return value
*/
public Object getReturnValue() {
return returnValue;
}
}

@ -23,7 +23,7 @@
* questions. * questions.
*/ */
package jdk.nashorn.internal.runtime; package jdk.nashorn.internal.runtime.events;
import java.util.logging.Level; import java.util.logging.Level;
@ -46,6 +46,7 @@ public class RuntimeEvent<T> {
/** /**
* Constructor * Constructor
*
* @param level log level for runtime event to create * @param level log level for runtime event to create
* @param object object to wrap * @param object object to wrap
*/ */
@ -58,7 +59,7 @@ public class RuntimeEvent<T> {
* Return the value wrapped in this runtime event * Return the value wrapped in this runtime event
* @return value * @return value
*/ */
public T getValue() { public final T getValue() {
return value; return value;
} }

@ -39,14 +39,13 @@ import jdk.internal.dynalink.beans.StaticClass;
* "class loader", it does not, in fact, extend {@code ClassLoader}, but rather uses them internally. Instances of this * "class loader", it does not, in fact, extend {@code ClassLoader}, but rather uses them internally. Instances of this
* class are normally created by {@link JavaAdapterBytecodeGenerator}. * class are normally created by {@link JavaAdapterBytecodeGenerator}.
*/ */
@SuppressWarnings("javadoc")
final class JavaAdapterClassLoader { final class JavaAdapterClassLoader {
private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader"); private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
private final String className; private final String className;
private final byte[] classBytes; private final byte[] classBytes;
JavaAdapterClassLoader(String className, byte[] classBytes) { JavaAdapterClassLoader(final String className, final byte[] classBytes) {
this.className = className.replace('/', '.'); this.className = className.replace('/', '.');
this.classBytes = classBytes; this.classBytes = classBytes;
} }

@ -22,7 +22,7 @@
*/ */
/** /**
* relinkIndexGetter: after call site was linked for array, make sure it * relink_index_getter: after call site was linked for array, make sure it
* gets correctly relinked for boolean. * gets correctly relinked for boolean.
* *
* @test * @test

@ -35,7 +35,7 @@ print(Debug);
print(); print();
var forName = java.lang.Class["forName(String)"]; var forName = java.lang.Class["forName(String)"];
var RuntimeEvent = forName("jdk.nashorn.internal.runtime.RuntimeEvent").static; var RuntimeEvent = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static;
var getValue = RuntimeEvent.class.getMethod("getValue"); var getValue = RuntimeEvent.class.getMethod("getValue");
var getValueClass = RuntimeEvent.class.getMethod("getValueClass"); var getValueClass = RuntimeEvent.class.getMethod("getValueClass");

@ -1,6 +1,6 @@
[object Debug] [object Debug]
[JavaClass jdk.nashorn.internal.runtime.RuntimeEvent] [JavaClass jdk.nashorn.internal.runtime.events.RuntimeEvent]
[JavaClass jdk.nashorn.internal.runtime.RewriteException] [JavaClass jdk.nashorn.internal.runtime.RewriteException]
4.840000000000001 4.840000000000001
@ -10,24 +10,24 @@ Done with 2 in the event queue
events = true events = true
events.length = 2 events.length = 2
event #0 event #0
event class=class jdk.nashorn.internal.runtime.RuntimeEvent event class=class jdk.nashorn.internal.runtime.events.RecompilationEvent
valueClass in event=class jdk.nashorn.internal.runtime.RewriteException valueClass in event=class jdk.nashorn.internal.runtime.RewriteException
class of value=class jdk.nashorn.internal.runtime.RewriteException class of value=class jdk.nashorn.internal.runtime.RewriteException
return type=double return type=double
event #1 event #1
event class=class jdk.nashorn.internal.runtime.RuntimeEvent event class=class jdk.nashorn.internal.runtime.events.RecompilationEvent
valueClass in event=class jdk.nashorn.internal.runtime.RewriteException valueClass in event=class jdk.nashorn.internal.runtime.RewriteException
class of value=class jdk.nashorn.internal.runtime.RewriteException class of value=class jdk.nashorn.internal.runtime.RewriteException
return type=double return type=double
in loop last class = class jdk.nashorn.internal.runtime.RuntimeEvent in loop last class = class jdk.nashorn.internal.runtime.events.RecompilationEvent
in loop last value class = class jdk.nashorn.internal.runtime.RewriteException in loop last value class = class jdk.nashorn.internal.runtime.RewriteException
in loop rex class = class jdk.nashorn.internal.runtime.RewriteException in loop rex class = class jdk.nashorn.internal.runtime.RewriteException
in loop rex return type = double in loop rex return type = double
true true
last class = class jdk.nashorn.internal.runtime.RuntimeEvent last class = class jdk.nashorn.internal.runtime.events.RecompilationEvent
last value class = class jdk.nashorn.internal.runtime.RewriteException last value class = class jdk.nashorn.internal.runtime.RewriteException
rex class = class jdk.nashorn.internal.runtime.RewriteException rex class = class jdk.nashorn.internal.runtime.RewriteException
rex return type = object rex return type = object