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:
parent
187399b1fd
commit
af27b4200d
nashorn
src/jdk/nashorn/internal
objects
runtime
test/script
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user