< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java

Print this page

        

*** 26,35 **** --- 26,37 ---- package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.lookup.Lookup.MH; import java.io.IOException; + import java.io.ObjectOutputStream; + import java.io.Serializable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.ref.Reference; import java.lang.ref.SoftReference;
*** 98,108 **** /** * Cached form of the AST. Either a {@code SerializedAst} object used by split functions as they can't be * reparsed from source, or a soft reference to a {@code FunctionNode} for other functions (it is safe * to be cleared as they can be reparsed). */ ! private volatile Object cachedAst; /** Token of this function within the source. */ private final long token; /** --- 100,110 ---- /** * Cached form of the AST. Either a {@code SerializedAst} object used by split functions as they can't be * reparsed from source, or a soft reference to a {@code FunctionNode} for other functions (it is safe * to be cleared as they can be reparsed). */ ! private volatile transient Object cachedAst; /** Token of this function within the source. */ private final long token; /**
*** 287,296 **** --- 289,301 ---- */ public void initTransients(final Source src, final CodeInstaller inst) { if (this.source == null && this.installer == null) { this.source = src; this.installer = inst; + for (final RecompilableScriptFunctionData nested : nestedFunctions.values()) { + nested.initTransients(src, inst); + } } else if (this.source != src || !this.installer.isCompatibleWith(inst)) { // Existing values must be same as those passed as parameters throw new IllegalArgumentException(); } }
*** 422,432 **** } // Are we strongly caching a serialized AST (for split functions only)? } else if (lCachedAst instanceof SerializedAst) { final SerializedAst serializedAst = (SerializedAst)lCachedAst; // Even so, are we also softly caching the AST? ! final FunctionNode cachedFn = serializedAst.cachedAst.get(); if (cachedFn != null) { // Yes we are - this is fast return cloneSymbols(cachedFn); } final FunctionNode deserializedFn = deserialize(serializedAst.serializedAst); --- 427,437 ---- } // Are we strongly caching a serialized AST (for split functions only)? } else if (lCachedAst instanceof SerializedAst) { final SerializedAst serializedAst = (SerializedAst)lCachedAst; // Even so, are we also softly caching the AST? ! final FunctionNode cachedFn = serializedAst.cachedAst == null ? null : serializedAst.cachedAst.get(); if (cachedFn != null) { // Yes we are - this is fast return cloneSymbols(cachedFn); } final FunctionNode deserializedFn = deserialize(serializedAst.serializedAst);
*** 490,502 **** * functions. Since split functions are altered from their source form, they can't be reparsed from * source. While we could just use the {@code byte[]} representation in {@link RecompilableScriptFunctionData#cachedAst} * we're using this tuple instead to also keep a deserialized AST around in memory to cut down on * deserialization costs. */ ! private static class SerializedAst { private final byte[] serializedAst; ! private volatile Reference<FunctionNode> cachedAst; SerializedAst(final FunctionNode fn, final Reference<FunctionNode> cachedAst) { this.serializedAst = AstSerializer.serialize(fn); this.cachedAst = cachedAst; } --- 495,509 ---- * functions. Since split functions are altered from their source form, they can't be reparsed from * source. While we could just use the {@code byte[]} representation in {@link RecompilableScriptFunctionData#cachedAst} * we're using this tuple instead to also keep a deserialized AST around in memory to cut down on * deserialization costs. */ ! private static class SerializedAst implements Serializable { private final byte[] serializedAst; ! private volatile transient Reference<FunctionNode> cachedAst; ! ! private static final long serialVersionUID = 1L; SerializedAst(final FunctionNode fn, final Reference<FunctionNode> cachedAst) { this.serializedAst = AstSerializer.serialize(fn); this.cachedAst = cachedAst; }
*** 1036,1047 **** --- 1043,1066 ---- } } return true; } + private void writeObject(final ObjectOutputStream out) throws IOException { + final Object localCachedAst = cachedAst; + out.defaultWriteObject(); + // We need to persist SerializedAst for split functions as they can't reparse the source code. + if (localCachedAst instanceof SerializedAst) { + out.writeObject(localCachedAst); + } else { + out.writeObject(null); + } + } + private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); + cachedAst = in.readObject(); createLogger(); } private void createLogger() { log = initLogger(Context.getContextTrusted());
< prev index next >