nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CodeStore.java
author lagergren
Fri, 26 Sep 2014 18:47:20 +0200
changeset 26886 18c744ab4df2
parent 26768 751b0f427090
child 27366 c0fdaac978ea
permissions -rw-r--r--
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     1
/*
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     2
 * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     4
 *
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    10
 *
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    15
 * accompanied this code).
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    16
 *
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    20
 *
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    23
 * questions.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    24
 */
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    25
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    27
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    28
import java.io.BufferedInputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    29
import java.io.BufferedOutputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    30
import java.io.File;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    31
import java.io.FileInputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    32
import java.io.FileOutputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    33
import java.io.IOException;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    34
import java.io.ObjectInputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    35
import java.io.ObjectOutputStream;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    36
import java.io.Serializable;
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    37
import java.security.AccessControlException;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    38
import java.security.AccessController;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    39
import java.security.PrivilegedActionException;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    40
import java.security.PrivilegedExceptionAction;
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    41
import java.util.Iterator;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    42
import java.util.Map;
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    43
import java.util.ServiceLoader;
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
    44
import jdk.nashorn.internal.codegen.types.Type;
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
    45
import jdk.nashorn.internal.runtime.logging.DebugLogger;
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
    46
import jdk.nashorn.internal.runtime.logging.Loggable;
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
    47
import jdk.nashorn.internal.runtime.logging.Logger;
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    48
import jdk.nashorn.internal.runtime.options.Options;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    49
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    50
/**
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    51
 * A code cache for persistent caching of compiled scripts.
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    52
 */
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    53
@Logger(name="codestore")
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    54
public abstract class CodeStore implements Loggable {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    55
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    56
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    57
     * Permission needed to provide a CodeStore instance via ServiceLoader.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    58
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    59
    public final static String NASHORN_PROVIDE_CODE_STORE = "nashorn.provideCodeStore";
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    60
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    61
    private DebugLogger log;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    62
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    63
    /**
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    64
     * Constructor
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    65
     */
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    66
    protected CodeStore() {
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    67
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    68
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    69
    @Override
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26055
diff changeset
    70
    public DebugLogger initLogger(final Context context) {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    71
        log = context.getLogger(getClass());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    72
        return log;
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    73
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    74
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    75
    @Override
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    76
    public DebugLogger getLogger() {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
    77
        return log;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    78
    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    79
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    80
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    81
     * Returns a new code store instance.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    82
     *
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    83
     * @param context the current context
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    84
     * @return The instance
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    85
     * @throws IOException If an error occurs
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    86
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    87
    public static CodeStore newCodeStore(final Context context) throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    88
        final Class<CodeStore> baseClass = CodeStore.class;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
    89
        try {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    90
            // security check first
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    91
            final SecurityManager sm = System.getSecurityManager();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    92
            if (sm != null) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    93
                sm.checkPermission(new RuntimePermission(NASHORN_PROVIDE_CODE_STORE));
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    94
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    95
            final ServiceLoader<CodeStore> services = ServiceLoader.load(baseClass);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    96
            final Iterator<CodeStore> iterator = services.iterator();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    97
            if (iterator.hasNext()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    98
                final CodeStore store = iterator.next();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
    99
                store.initLogger(context).info("using code store provider ", store.getClass().getCanonicalName());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   100
                return store;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   101
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   102
        } catch (final AccessControlException e) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   103
            context.getLogger(CodeStore.class).warning("failed to load code store provider ", e);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   104
        }
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   105
        final CodeStore store = new DirectoryCodeStore();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   106
        store.initLogger(context);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   107
        return store;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   108
    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   109
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   110
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   111
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   112
     * Store a compiled script in the cache.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   113
     *
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   114
     * @param functionKey   the function key
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   115
     * @param source        the source
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   116
     * @param mainClassName the main class name
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   117
     * @param classBytes    a map of class bytes
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   118
     * @param initializers  the function initializers
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   119
     * @param constants     the constants array
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   120
     * @param compilationId the compilation id
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   121
     *
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   122
     * @return stored script
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   123
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   124
    public StoredScript store(final String functionKey,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   125
                              final Source source,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   126
                              final String mainClassName,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   127
                              final Map<String, byte[]> classBytes,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   128
                              final Map<Integer, FunctionInitializer> initializers,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   129
                              final Object[] constants,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   130
                              final int compilationId) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   131
        return store(functionKey, source, storedScriptFor(source, mainClassName, classBytes, initializers, constants, compilationId));
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   132
    }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   133
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   134
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   135
     * Stores a compiled script.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   136
     *
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   137
     * @param functionKey the function key
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   138
     * @param source the source
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   139
     * @param script The compiled script
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   140
     * @return The compiled script or {@code null} if not stored
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   141
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   142
    public abstract StoredScript store(final String functionKey,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   143
                                       final Source source,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   144
                                       final StoredScript script);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   145
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   146
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   147
     * Return a compiled script from the cache, or null if it isn't found.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   148
     *
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   149
     * @param source      the source
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   150
     * @param functionKey the function key
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   151
     * @return the stored script or null
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   152
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   153
    public abstract StoredScript load(final Source source, final String functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   154
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   155
    /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   156
     * Returns a new StoredScript instance.
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   157
     *
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   158
     * @param source the source
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   159
     * @param mainClassName the main class name
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   160
     * @param classBytes a map of class bytes
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   161
     * @param initializers function initializers
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   162
     * @param constants the constants array
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   163
     * @param compilationId the compilation id
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   164
     *
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   165
     * @return The compiled script
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   166
     */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   167
    public StoredScript storedScriptFor(final Source source, final String mainClassName,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   168
                                        final Map<String, byte[]> classBytes,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   169
                                        final Map<Integer, FunctionInitializer> initializers,
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   170
                                        final Object[] constants, final int compilationId) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   171
        for (final Object constant : constants) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   172
            // Make sure all constant data is serializable
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   173
            if (!(constant instanceof Serializable)) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   174
                getLogger().warning("cannot store ", source, " non serializable constant ", constant);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   175
                return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   176
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   177
        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   178
        return new StoredScript(compilationId, mainClassName, classBytes, initializers, constants);
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   179
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   180
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   181
    /**
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   182
     * Generate a string representing the function with {@code functionId} and {@code paramTypes}.
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   183
     * @param functionId function id
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   184
     * @param paramTypes parameter types
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   185
     * @return a string representing the function
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   186
     */
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   187
    public static String getCacheKey(final int functionId, final Type[] paramTypes) {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   188
        final StringBuilder b = new StringBuilder().append(functionId);
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   189
        if(paramTypes != null && paramTypes.length > 0) {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   190
            b.append('-');
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   191
            for(final Type t: paramTypes) {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   192
                b.append(Type.getShortSignatureDescriptor(t));
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   193
            }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   194
        }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   195
        return b.toString();
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   196
    }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25255
diff changeset
   197
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   198
    /**
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   199
     * A store using a file system directory.
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   200
     */
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   201
    public static class DirectoryCodeStore extends CodeStore {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   202
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   203
        // Default minimum size for storing a compiled script class
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   204
        private final static int DEFAULT_MIN_SIZE = 1000;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   205
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   206
        private final File dir;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   207
        private final boolean readOnly;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   208
        private final int minSize;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   209
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   210
        /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   211
         * Constructor
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   212
         *
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   213
         * @throws IOException if there are read/write problems with the cache and cache directory
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   214
         */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   215
        public DirectoryCodeStore() throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   216
            this(Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache"), false, DEFAULT_MIN_SIZE);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   217
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   218
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   219
        /**
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   220
         * Constructor
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   221
         *
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   222
         * @param path    directory to store code in
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   223
         * @param readOnly is this a read only code store
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   224
         * @param minSize minimum file size for caching scripts
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   225
         * @throws IOException if there are read/write problems with the cache and cache directory
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   226
         */
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   227
        public DirectoryCodeStore(final String path, final boolean readOnly, final int minSize) throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   228
            this.dir = checkDirectory(path, readOnly);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   229
            this.readOnly = readOnly;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   230
            this.minSize = minSize;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   231
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   232
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   233
        private static File checkDirectory(final String path, final boolean readOnly) throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   234
            try {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   235
                return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   236
                    @Override
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   237
                    public File run() throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   238
                        final File dir = new File(path).getAbsoluteFile();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   239
                        if (readOnly) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   240
                            if (!dir.exists() || !dir.isDirectory()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   241
                                throw new IOException("Not a directory: " + dir.getPath());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   242
                            } else if (!dir.canRead()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   243
                                throw new IOException("Directory not readable: " + dir.getPath());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   244
                            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   245
                        } else if (!dir.exists() && !dir.mkdirs()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   246
                            throw new IOException("Could not create directory: " + dir.getPath());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   247
                        } else if (!dir.isDirectory()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   248
                            throw new IOException("Not a directory: " + dir.getPath());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   249
                        } else if (!dir.canRead() || !dir.canWrite()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   250
                            throw new IOException("Directory not readable or writable: " + dir.getPath());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   251
                        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   252
                        return dir;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   253
                    }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   254
                });
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   255
            } catch (final PrivilegedActionException e) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   256
                throw (IOException) e.getException();
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   257
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   258
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   259
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   260
        @Override
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   261
        public StoredScript load(final Source source, final String functionKey) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   262
            if (source.getLength() < minSize) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   263
                return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   264
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   265
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   266
            final File file = getCacheFile(source, functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   267
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   268
            try {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   269
                return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   270
                    @Override
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   271
                    public StoredScript run() throws IOException, ClassNotFoundException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   272
                        if (!file.exists()) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   273
                            return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   274
                        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   275
                        try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   276
                            final StoredScript storedScript = (StoredScript) in.readObject();
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   277
                            getLogger().info("loaded ", source, "-", functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   278
                            return storedScript;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   279
                        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   280
                    }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   281
                });
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   282
            } catch (final PrivilegedActionException e) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   283
                getLogger().warning("failed to load ", source, "-", functionKey, ": ", e.getException());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   284
                return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   285
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   286
        }
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   287
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   288
        @Override
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   289
        public StoredScript store(final String functionKey, final Source source, final StoredScript script) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   290
            if (readOnly || script == null || belowThreshold(source)) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   291
                return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   292
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   293
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   294
            final File file = getCacheFile(source, functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   295
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   296
            try {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   297
                return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   298
                    @Override
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   299
                    public StoredScript run() throws IOException {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   300
                        try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   301
                            out.writeObject(script);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   302
                        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   303
                        getLogger().info("stored ", source, "-", functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   304
                        return script;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   305
                    }
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   306
                });
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   307
            } catch (final PrivilegedActionException e) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   308
                getLogger().warning("failed to store ", script, "-", functionKey, ": ", e.getException());
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   309
                return null;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   310
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   311
        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   312
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   313
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   314
        private File getCacheFile(final Source source, final String functionKey) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   315
            return new File(dir, source.getDigest() + '-' + functionKey);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   316
        }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   317
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   318
        private boolean belowThreshold(final Source source) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   319
            if (source.getLength() < minSize) {
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   320
                getLogger().info("below size threshold ", source);
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   321
                return true;
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   322
            }
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26068
diff changeset
   323
            return false;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   324
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   325
    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   326
}
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents:
diff changeset
   327