author | hannesw |
Sat, 19 Sep 2015 16:04:28 +0200 | |
changeset 32781 | d8f34ffbbc7a |
parent 32697 | d8416054e691 |
child 32786 | dedf2b6ea495 |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
28 |
import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; |
23767 | 29 |
import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS; |
24719 | 30 |
import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION; |
23767 | 31 |
import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE; |
16147 | 32 |
import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; |
26764
c777787a937d
8046202: Make persistent code store more flexible
hannesw
parents:
26508
diff
changeset
|
33 |
import static jdk.nashorn.internal.runtime.CodeStore.newCodeStore; |
16147 | 34 |
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; |
35 |
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
36 |
import static jdk.nashorn.internal.runtime.Source.sourceFor; |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
37 |
|
16147 | 38 |
import java.io.File; |
39 |
import java.io.IOException; |
|
40 |
import java.io.PrintWriter; |
|
41 |
import java.lang.invoke.MethodHandle; |
|
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
42 |
import java.lang.invoke.MethodHandles; |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
43 |
import java.lang.invoke.MethodType; |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
44 |
import java.lang.invoke.SwitchPoint; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
45 |
import java.lang.ref.Reference; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
46 |
import java.lang.ref.ReferenceQueue; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
47 |
import java.lang.ref.SoftReference; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
48 |
import java.lang.ref.WeakReference; |
23767 | 49 |
import java.lang.reflect.Field; |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
50 |
import java.lang.reflect.Modifier; |
16254 | 51 |
import java.net.MalformedURLException; |
16147 | 52 |
import java.net.URL; |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
53 |
import java.security.AccessControlContext; |
16147 | 54 |
import java.security.AccessController; |
55 |
import java.security.CodeSigner; |
|
56 |
import java.security.CodeSource; |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
57 |
import java.security.Permissions; |
16147 | 58 |
import java.security.PrivilegedAction; |
23767 | 59 |
import java.security.PrivilegedActionException; |
60 |
import java.security.PrivilegedExceptionAction; |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
61 |
import java.security.ProtectionDomain; |
24769 | 62 |
import java.util.Collection; |
23767 | 63 |
import java.util.HashMap; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
64 |
import java.util.LinkedHashMap; |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
65 |
import java.util.Map; |
28785
a503c972d4bd
8072595: nashorn should not use obj.getClass() for null checks
sundar
parents:
28441
diff
changeset
|
66 |
import java.util.Objects; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
67 |
import java.util.concurrent.ConcurrentHashMap; |
22669 | 68 |
import java.util.concurrent.atomic.AtomicLong; |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
69 |
import java.util.concurrent.atomic.AtomicReference; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
70 |
import java.util.concurrent.atomic.LongAdder; |
24769 | 71 |
import java.util.function.Consumer; |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
72 |
import java.util.function.Supplier; |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24727
diff
changeset
|
73 |
import java.util.logging.Level; |
30975
a71c56056f02
8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents:
30513
diff
changeset
|
74 |
import javax.script.ScriptContext; |
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
75 |
import javax.script.ScriptEngine; |
16147 | 76 |
import jdk.internal.org.objectweb.asm.ClassReader; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
77 |
import jdk.internal.org.objectweb.asm.ClassWriter; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
78 |
import jdk.internal.org.objectweb.asm.Opcodes; |
16147 | 79 |
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; |
26071 | 80 |
import jdk.nashorn.api.scripting.ClassFilter; |
17979
adae4d39ee07
8015945: loadWithNewGlobal return value has to be properly wrapped
sundar
parents:
17976
diff
changeset
|
81 |
import jdk.nashorn.api.scripting.ScriptObjectMirror; |
16147 | 82 |
import jdk.nashorn.internal.codegen.Compiler; |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24745
diff
changeset
|
83 |
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
84 |
import jdk.nashorn.internal.codegen.ObjectClassGenerator; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
85 |
import jdk.nashorn.internal.ir.FunctionNode; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
86 |
import jdk.nashorn.internal.ir.debug.ASTWriter; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
87 |
import jdk.nashorn.internal.ir.debug.PrintVisitor; |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
88 |
import jdk.nashorn.internal.lookup.MethodHandleFactory; |
18851
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18618
diff
changeset
|
89 |
import jdk.nashorn.internal.objects.Global; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
90 |
import jdk.nashorn.internal.parser.Parser; |
24742
a9afb384e654
8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents:
24733
diff
changeset
|
91 |
import jdk.nashorn.internal.runtime.events.RuntimeEvent; |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
92 |
import jdk.nashorn.internal.runtime.logging.DebugLogger; |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
93 |
import jdk.nashorn.internal.runtime.logging.Loggable; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
94 |
import jdk.nashorn.internal.runtime.logging.Logger; |
24769 | 95 |
import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo; |
16147 | 96 |
import jdk.nashorn.internal.runtime.options.Options; |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
97 |
import sun.misc.Unsafe; |
16147 | 98 |
|
99 |
/** |
|
100 |
* This class manages the global state of execution. Context is immutable. |
|
101 |
*/ |
|
102 |
public final class Context { |
|
19459 | 103 |
// nashorn specific security runtime access permission names |
104 |
/** |
|
105 |
* Permission needed to pass arbitrary nashorn command line options when creating Context. |
|
106 |
*/ |
|
107 |
public static final String NASHORN_SET_CONFIG = "nashorn.setConfig"; |
|
108 |
||
109 |
/** |
|
110 |
* Permission needed to create Nashorn Context instance. |
|
111 |
*/ |
|
112 |
public static final String NASHORN_CREATE_CONTEXT = "nashorn.createContext"; |
|
113 |
||
114 |
/** |
|
115 |
* Permission needed to create Nashorn Global instance. |
|
116 |
*/ |
|
117 |
public static final String NASHORN_CREATE_GLOBAL = "nashorn.createGlobal"; |
|
118 |
||
119 |
/** |
|
120 |
* Permission to get current Nashorn Context from thread local storage. |
|
121 |
*/ |
|
122 |
public static final String NASHORN_GET_CONTEXT = "nashorn.getContext"; |
|
123 |
||
124 |
/** |
|
125 |
* Permission to use Java reflection/jsr292 from script code. |
|
126 |
*/ |
|
127 |
public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection"; |
|
16147 | 128 |
|
22389
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
129 |
/** |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
130 |
* Permission to enable nashorn debug mode. |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
131 |
*/ |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
132 |
public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode"; |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
133 |
|
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
134 |
// nashorn load psuedo URL prefixes |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
135 |
private static final String LOAD_CLASSPATH = "classpath:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
136 |
private static final String LOAD_FX = "fx:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
137 |
private static final String LOAD_NASHORN = "nashorn:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
138 |
|
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
139 |
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
140 |
private static final MethodType CREATE_PROGRAM_FUNCTION_TYPE = MethodType.methodType(ScriptFunction.class, ScriptObject.class); |
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
141 |
|
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
142 |
private static final LongAdder NAMED_INSTALLED_SCRIPT_COUNT = new LongAdder(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
143 |
private static final LongAdder ANONYMOUS_INSTALLED_SCRIPT_COUNT = new LongAdder(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
144 |
private static final boolean DISABLE_VM_ANONYMOUS_CLASSES = Options.getBooleanProperty("nashorn.disableVmAnonymousClasses"); |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
145 |
/** |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
146 |
* Should scripts use only object slots for fields, or dual long/object slots? The default |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
147 |
* behaviour is to couple this to optimistic types, using dual representation if optimistic types are enabled |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
148 |
* and single field representation otherwise. This can be overridden by setting either the "nashorn.fields.objects" |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
149 |
* or "nashorn.fields.dual" system property. |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
150 |
*/ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
151 |
private final FieldMode fieldMode; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
152 |
|
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
153 |
private static enum FieldMode { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
154 |
/** Value for automatic field representation depending on optimistic types setting */ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
155 |
AUTO, |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
156 |
/** Value for object field representation regardless of optimistic types setting */ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
157 |
OBJECTS, |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
158 |
/** Value for dual primitive/object field representation regardless of optimistic types setting */ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
159 |
DUAL |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
160 |
} |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
161 |
|
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
162 |
/** |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
163 |
* Keeps track of which builtin prototypes and properties have been relinked |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
164 |
* Currently we are conservative and associate the name of a builtin class with all |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
165 |
* its properties, so it's enough to invalidate a property to break all assumptions |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
166 |
* about a prototype. This can be changed to a more fine grained approach, but no one |
32534
b3ec7f3b3c2a
8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents:
32530
diff
changeset
|
167 |
* ever needs this, given the very rare occurrence of swapping out only parts of |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
168 |
* a builtin v.s. the entire builtin object |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
169 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
170 |
private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>(); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
171 |
|
19622
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
172 |
/* Force DebuggerSupport to be loaded. */ |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
173 |
static { |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
174 |
DebuggerSupport.FORCELOAD = true; |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
175 |
} |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
176 |
|
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
177 |
static long getNamedInstalledScriptCount() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
178 |
return NAMED_INSTALLED_SCRIPT_COUNT.sum(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
179 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
180 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
181 |
static long getAnonymousInstalledScriptCount() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
182 |
return ANONYMOUS_INSTALLED_SCRIPT_COUNT.sum(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
183 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
184 |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
185 |
/** |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
186 |
* ContextCodeInstaller that has the privilege of installing classes in the Context. |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
187 |
* Can only be instantiated from inside the context and is opaque to other classes |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
188 |
*/ |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
189 |
private abstract static class ContextCodeInstaller implements CodeInstaller { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
190 |
final Context context; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
191 |
final CodeSource codeSource; |
27207
1f26a24d639a
8060724: ant test262parallel in Nashorn spends a significant amount of time after almost all the tests are run
hannesw
parents:
27102
diff
changeset
|
192 |
|
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
193 |
ContextCodeInstaller(final Context context, final CodeSource codeSource) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
194 |
this.context = context; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
195 |
this.codeSource = codeSource; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
196 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
197 |
|
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
198 |
@Override |
32530 | 199 |
public Context getContext() { |
200 |
return context; |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
201 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
202 |
|
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
203 |
@Override |
24769 | 204 |
public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants) { |
26248 | 205 |
try { |
206 |
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { |
|
23767 | 207 |
@Override |
26248 | 208 |
public Void run() throws Exception { |
209 |
for (final Class<?> clazz : classes) { |
|
210 |
//use reflection to write source and constants table to installed classes |
|
211 |
final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName()); |
|
212 |
sourceField.setAccessible(true); |
|
213 |
sourceField.set(null, source); |
|
24769 | 214 |
|
26248 | 215 |
final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName()); |
216 |
constantsField.setAccessible(true); |
|
217 |
constantsField.set(null, constants); |
|
24769 | 218 |
} |
26248 | 219 |
return null; |
23767 | 220 |
} |
221 |
}); |
|
26248 | 222 |
} catch (final PrivilegedActionException e) { |
223 |
throw new RuntimeException(e); |
|
224 |
} |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
225 |
} |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
226 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
227 |
@Override |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
228 |
public void verify(final byte[] code) { |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
229 |
context.verify(code); |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
230 |
} |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
231 |
|
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
232 |
@Override |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
233 |
public long getUniqueScriptId() { |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
234 |
return context.getUniqueScriptId(); |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
235 |
} |
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
236 |
|
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
237 |
@Override |
26508
b40ef4386b01
8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents:
26504
diff
changeset
|
238 |
public void storeScript(final String cacheKey, final Source source, final String mainClassName, |
26067
b32ccc3a76c9
8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents:
26065
diff
changeset
|
239 |
final Map<String,byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers, |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
240 |
final Object[] constants, final int compilationId) { |
23767 | 241 |
if (context.codeStore != null) { |
26764
c777787a937d
8046202: Make persistent code store more flexible
hannesw
parents:
26508
diff
changeset
|
242 |
context.codeStore.store(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId); |
23767 | 243 |
} |
244 |
} |
|
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
245 |
|
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
246 |
@Override |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
247 |
public StoredScript loadScript(final Source source, final String functionKey) { |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
248 |
if (context.codeStore != null) { |
26764
c777787a937d
8046202: Make persistent code store more flexible
hannesw
parents:
26508
diff
changeset
|
249 |
return context.codeStore.load(source, functionKey); |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
250 |
} |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
251 |
return null; |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
252 |
} |
26891
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
253 |
|
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
254 |
@Override |
32530 | 255 |
public boolean isCompatibleWith(final CodeInstaller other) { |
26891
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
256 |
if (other instanceof ContextCodeInstaller) { |
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
257 |
final ContextCodeInstaller cci = (ContextCodeInstaller)other; |
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
258 |
return cci.context == context && cci.codeSource == codeSource; |
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
259 |
} |
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
260 |
return false; |
aee38d04254a
8059346: Single class loader is used to load compiled bytecode
attila
parents:
26886
diff
changeset
|
261 |
} |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
262 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
263 |
|
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
264 |
private static class NamedContextCodeInstaller extends ContextCodeInstaller { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
265 |
private final ScriptLoader loader; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
266 |
private int usageCount = 0; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
267 |
private int bytesDefined = 0; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
268 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
269 |
// We reuse this installer for 10 compilations or 200000 defined bytes. Usually the first condition |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
270 |
// will occur much earlier, the second is a safety measure for very large scripts/functions. |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
271 |
private final static int MAX_USAGES = 10; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
272 |
private final static int MAX_BYTES_DEFINED = 200_000; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
273 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
274 |
private NamedContextCodeInstaller(final Context context, final CodeSource codeSource, final ScriptLoader loader) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
275 |
super(context, codeSource); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
276 |
this.loader = loader; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
277 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
278 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
279 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
280 |
public Class<?> install(final String className, final byte[] bytecode) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
281 |
usageCount++; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
282 |
bytesDefined += bytecode.length; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
283 |
NAMED_INSTALLED_SCRIPT_COUNT.increment(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
284 |
return loader.installClass(Compiler.binaryName(className), bytecode, codeSource); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
285 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
286 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
287 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
288 |
public CodeInstaller getOnDemandCompilationInstaller() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
289 |
// Reuse this installer if we're within our limits. |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
290 |
if (usageCount < MAX_USAGES && bytesDefined < MAX_BYTES_DEFINED) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
291 |
return this; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
292 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
293 |
return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader()); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
294 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
295 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
296 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
297 |
public CodeInstaller getMultiClassCodeInstaller() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
298 |
// This installer is perfectly suitable for installing multiple classes that reference each other |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
299 |
// as it produces classes with resolvable names, all defined in a single class loader. |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
300 |
return this; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
301 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
302 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
303 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
304 |
private final Map<CodeSource, Reference<Class<?>>> anonymousHostClasses = new ConcurrentHashMap<>(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
305 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
306 |
private static final class AnonymousContextCodeInstaller extends ContextCodeInstaller { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
307 |
private static final Unsafe UNSAFE = getUnsafe(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
308 |
private static final String ANONYMOUS_HOST_CLASS_NAME = Compiler.SCRIPTS_PACKAGE.replace('/', '.') + ".AnonymousHost"; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
309 |
private static final byte[] ANONYMOUS_HOST_CLASS_BYTES = getAnonymousHostClassBytes(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
310 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
311 |
private final Class<?> hostClass; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
312 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
313 |
private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
314 |
super(context, codeSource); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
315 |
hostClass = getAnonymousHostClass(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
316 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
317 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
318 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
319 |
public Class<?> install(final String className, final byte[] bytecode) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
320 |
ANONYMOUS_INSTALLED_SCRIPT_COUNT.increment(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
321 |
return UNSAFE.defineAnonymousClass(hostClass, bytecode, null); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
322 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
323 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
324 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
325 |
public CodeInstaller getOnDemandCompilationInstaller() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
326 |
// This code loader can be indefinitely reused for on-demand recompilations for the same code source. |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
327 |
return this; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
328 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
329 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
330 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
331 |
public CodeInstaller getMultiClassCodeInstaller() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
332 |
// This code loader can not be used to install multiple classes that reference each other, as they |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
333 |
// would have no resolvable names. Therefore, in such situation we must revert to an installer that |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
334 |
// produces named classes. |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
335 |
return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader()); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
336 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
337 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
338 |
private Class<?> getAnonymousHostClass() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
339 |
final Reference<Class<?>> ref = context.anonymousHostClasses.get(codeSource); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
340 |
if (ref != null) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
341 |
final Class<?> existingHostClass = ref.get(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
342 |
if (existingHostClass != null) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
343 |
return existingHostClass; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
344 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
345 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
346 |
final Class<?> newHostClass = context.createNewLoader().installClass(ANONYMOUS_HOST_CLASS_NAME, ANONYMOUS_HOST_CLASS_BYTES, codeSource); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
347 |
context.anonymousHostClasses.put(codeSource, new WeakReference<>(newHostClass)); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
348 |
return newHostClass; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
349 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
350 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
351 |
private static final byte[] getAnonymousHostClassBytes() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
352 |
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
353 |
cw.visit(V1_7, Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, ANONYMOUS_HOST_CLASS_NAME.replace('.', '/'), null, "java/lang/Object", null); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
354 |
cw.visitEnd(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
355 |
return cw.toByteArray(); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
356 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
357 |
|
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
358 |
private static Unsafe getUnsafe() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
359 |
return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
360 |
@Override |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
361 |
public Unsafe run() { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
362 |
try { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
363 |
final Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
364 |
theUnsafeField.setAccessible(true); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
365 |
return (Unsafe)theUnsafeField.get(null); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
366 |
} catch (final ReflectiveOperationException e) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
367 |
throw new RuntimeException(e); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
368 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
369 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
370 |
}); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
371 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
372 |
} |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
373 |
|
16147 | 374 |
/** Is Context global debug mode enabled ? */ |
375 |
public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug"); |
|
376 |
||
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
377 |
private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>(); |
16147 | 378 |
|
23767 | 379 |
// in-memory cache for loaded classes |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
380 |
private ClassCache classCache; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
381 |
|
23767 | 382 |
// persistent code store |
383 |
private CodeStore codeStore; |
|
384 |
||
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
385 |
// A factory for linking global properties as constant method handles. It is created when the first Global |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
386 |
// is created, and invalidated forever once the second global is created. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
387 |
private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
388 |
|
16147 | 389 |
/** |
16188 | 390 |
* Get the current global scope |
391 |
* @return the current global scope |
|
16147 | 392 |
*/ |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
393 |
public static Global getGlobal() { |
17231 | 394 |
// This class in a package.access protected package. |
395 |
// Trusted code only can call this method. |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
396 |
return currentGlobal.get(); |
16147 | 397 |
} |
398 |
||
399 |
/** |
|
400 |
* Set the current global scope |
|
401 |
* @param global the global scope |
|
402 |
*/ |
|
403 |
public static void setGlobal(final ScriptObject global) { |
|
18851
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18618
diff
changeset
|
404 |
if (global != null && !(global instanceof Global)) { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
405 |
throw new IllegalArgumentException("not a global!"); |
16147 | 406 |
} |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
407 |
setGlobal((Global)global); |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
408 |
} |
16147 | 409 |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
410 |
/** |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
411 |
* Set the current global scope |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
412 |
* @param global the global scope |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
413 |
*/ |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
414 |
public static void setGlobal(final Global global) { |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
415 |
// This class in a package.access protected package. |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
416 |
// Trusted code only can call this method. |
24733
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
417 |
assert getGlobal() != global; |
1e825be55fd1
8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents:
24731
diff
changeset
|
418 |
//same code can be cached between globals, then we need to invalidate method handle constants |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
419 |
if (global != null) { |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
420 |
final GlobalConstants globalConstants = getContext(global).getGlobalConstants(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
421 |
if (globalConstants != null) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
422 |
globalConstants.invalidateAll(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
423 |
} |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
424 |
} |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
425 |
currentGlobal.set(global); |
16147 | 426 |
} |
427 |
||
428 |
/** |
|
429 |
* Get context of the current global |
|
430 |
* @return current global scope's context. |
|
431 |
*/ |
|
432 |
public static Context getContext() { |
|
16185 | 433 |
final SecurityManager sm = System.getSecurityManager(); |
434 |
if (sm != null) { |
|
19459 | 435 |
sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT)); |
16185 | 436 |
} |
437 |
return getContextTrusted(); |
|
438 |
} |
|
439 |
||
440 |
/** |
|
441 |
* Get current context's error writer |
|
442 |
* |
|
443 |
* @return error writer of the current context |
|
444 |
*/ |
|
445 |
public static PrintWriter getCurrentErr() { |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
446 |
final ScriptObject global = getGlobal(); |
16185 | 447 |
return (global != null)? global.getContext().getErr() : new PrintWriter(System.err); |
16147 | 448 |
} |
449 |
||
450 |
/** |
|
451 |
* Output text to this Context's error stream |
|
452 |
* @param str text to write |
|
453 |
*/ |
|
454 |
public static void err(final String str) { |
|
455 |
err(str, true); |
|
456 |
} |
|
457 |
||
458 |
/** |
|
459 |
* Output text to this Context's error stream, optionally with |
|
460 |
* a newline afterwards |
|
461 |
* |
|
462 |
* @param str text to write |
|
463 |
* @param crlf write a carriage return/new line after text |
|
464 |
*/ |
|
465 |
public static void err(final String str, final boolean crlf) { |
|
16185 | 466 |
final PrintWriter err = Context.getCurrentErr(); |
16155
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
467 |
if (err != null) { |
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
468 |
if (crlf) { |
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
469 |
err.println(str); |
16147 | 470 |
} else { |
16155
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
471 |
err.print(str); |
16147 | 472 |
} |
473 |
} |
|
474 |
} |
|
475 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
476 |
/** Current environment. */ |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
477 |
private final ScriptEnvironment env; |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
478 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
479 |
/** is this context in strict mode? Cached from env. as this is used heavily. */ |
18328
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18321
diff
changeset
|
480 |
final boolean _strict; |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
481 |
|
16185 | 482 |
/** class loader to resolve classes from script. */ |
483 |
private final ClassLoader appLoader; |
|
484 |
||
16147 | 485 |
/** Class loader to load classes from -classpath option, if set. */ |
486 |
private final ClassLoader classPathLoader; |
|
487 |
||
488 |
/** Class loader to load classes compiled from scripts. */ |
|
489 |
private final ScriptLoader scriptLoader; |
|
490 |
||
491 |
/** Current error manager. */ |
|
492 |
private final ErrorManager errors; |
|
493 |
||
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
494 |
/** Unique id for script. Used only when --loader-per-compile=false */ |
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
495 |
private final AtomicLong uniqueScriptId; |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
496 |
|
26071 | 497 |
/** Optional class filter to use for Java classes. Can be null. */ |
498 |
private final ClassFilter classFilter; |
|
499 |
||
16185 | 500 |
private static final ClassLoader myLoader = Context.class.getClassLoader(); |
16147 | 501 |
private static final StructureLoader sharedLoader; |
19459 | 502 |
|
20933
89748612fd1d
8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents:
20929
diff
changeset
|
503 |
/*package-private*/ @SuppressWarnings("static-method") |
89748612fd1d
8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents:
20929
diff
changeset
|
504 |
ClassLoader getSharedLoader() { |
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
505 |
return sharedLoader; |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
506 |
} |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
507 |
|
19459 | 508 |
private static AccessControlContext createNoPermAccCtxt() { |
509 |
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); |
|
510 |
} |
|
511 |
||
512 |
private static AccessControlContext createPermAccCtxt(final String permName) { |
|
513 |
final Permissions perms = new Permissions(); |
|
514 |
perms.add(new RuntimePermission(permName)); |
|
515 |
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) }); |
|
516 |
} |
|
517 |
||
518 |
private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt(); |
|
519 |
private static final AccessControlContext CREATE_LOADER_ACC_CTXT = createPermAccCtxt("createClassLoader"); |
|
520 |
private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(NASHORN_CREATE_GLOBAL); |
|
16147 | 521 |
|
522 |
static { |
|
523 |
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() { |
|
524 |
@Override |
|
525 |
public StructureLoader run() { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
526 |
return new StructureLoader(myLoader); |
16147 | 527 |
} |
19459 | 528 |
}, CREATE_LOADER_ACC_CTXT); |
16147 | 529 |
} |
530 |
||
531 |
/** |
|
532 |
* ThrowErrorManager that throws ParserException upon error conditions. |
|
533 |
*/ |
|
534 |
public static class ThrowErrorManager extends ErrorManager { |
|
535 |
@Override |
|
536 |
public void error(final String message) { |
|
537 |
throw new ParserException(message); |
|
538 |
} |
|
539 |
||
540 |
@Override |
|
541 |
public void error(final ParserException e) { |
|
542 |
throw e; |
|
543 |
} |
|
544 |
} |
|
545 |
||
546 |
/** |
|
547 |
* Constructor |
|
548 |
* |
|
549 |
* @param options options from command line or Context creator |
|
550 |
* @param errors error manger |
|
16185 | 551 |
* @param appLoader application class loader |
16147 | 552 |
*/ |
16185 | 553 |
public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) { |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
554 |
this(options, errors, appLoader, null); |
26071 | 555 |
} |
556 |
||
557 |
/** |
|
558 |
* Constructor |
|
559 |
* |
|
560 |
* @param options options from command line or Context creator |
|
561 |
* @param errors error manger |
|
562 |
* @param appLoader application class loader |
|
563 |
* @param classFilter class filter to use |
|
564 |
*/ |
|
565 |
public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) { |
|
566 |
this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader, classFilter); |
|
16147 | 567 |
} |
568 |
||
569 |
/** |
|
570 |
* Constructor |
|
571 |
* |
|
572 |
* @param options options from command line or Context creator |
|
573 |
* @param errors error manger |
|
574 |
* @param out output writer for this Context |
|
575 |
* @param err error writer for this Context |
|
16185 | 576 |
* @param appLoader application class loader |
16147 | 577 |
*/ |
16185 | 578 |
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) { |
26071 | 579 |
this(options, errors, out, err, appLoader, (ClassFilter)null); |
580 |
} |
|
581 |
||
582 |
/** |
|
583 |
* Constructor |
|
584 |
* |
|
585 |
* @param options options from command line or Context creator |
|
586 |
* @param errors error manger |
|
587 |
* @param out output writer for this Context |
|
588 |
* @param err error writer for this Context |
|
589 |
* @param appLoader application class loader |
|
590 |
* @param classFilter class filter to use |
|
591 |
*/ |
|
592 |
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader, final ClassFilter classFilter) { |
|
16147 | 593 |
final SecurityManager sm = System.getSecurityManager(); |
594 |
if (sm != null) { |
|
19459 | 595 |
sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT)); |
16147 | 596 |
} |
597 |
||
26071 | 598 |
this.classFilter = classFilter; |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
599 |
this.env = new ScriptEnvironment(options, out, err); |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
600 |
this._strict = env._strict; |
16185 | 601 |
this.appLoader = appLoader; |
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
602 |
if (env._loader_per_compile) { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
603 |
this.scriptLoader = null; |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
604 |
this.uniqueScriptId = null; |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
605 |
} else { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
606 |
this.scriptLoader = createNewLoader(); |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
607 |
this.uniqueScriptId = new AtomicLong(); |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
608 |
} |
16147 | 609 |
this.errors = errors; |
610 |
||
611 |
// if user passed -classpath option, make a class loader with that and set it as |
|
612 |
// thread context class loader so that script can access classes from that path. |
|
613 |
final String classPath = options.getString("classpath"); |
|
24719 | 614 |
if (!env._compile_only && classPath != null && !classPath.isEmpty()) { |
16147 | 615 |
// make sure that caller can create a class loader. |
616 |
if (sm != null) { |
|
617 |
sm.checkPermission(new RuntimePermission("createClassLoader")); |
|
618 |
} |
|
619 |
this.classPathLoader = NashornLoader.createClassLoader(classPath); |
|
620 |
} else { |
|
621 |
this.classPathLoader = null; |
|
622 |
} |
|
623 |
||
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
624 |
final int cacheSize = env._class_cache_size; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
625 |
if (cacheSize > 0) { |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
626 |
classCache = new ClassCache(this, cacheSize); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
627 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
628 |
|
23767 | 629 |
if (env._persistent_cache) { |
27530
518b8ae2dbb9
8064789: Nashorn should just warn on code store instantiation error
hannesw
parents:
27369
diff
changeset
|
630 |
codeStore = newCodeStore(this); |
23767 | 631 |
} |
632 |
||
16147 | 633 |
// print version info if asked. |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
634 |
if (env._version) { |
16147 | 635 |
getErr().println("nashorn " + Version.version()); |
636 |
} |
|
637 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
638 |
if (env._fullversion) { |
16147 | 639 |
getErr().println("nashorn full version " + Version.fullVersion()); |
640 |
} |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
641 |
|
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
642 |
if (Options.getBooleanProperty("nashorn.fields.dual")) { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
643 |
fieldMode = FieldMode.DUAL; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
644 |
} else if (Options.getBooleanProperty("nashorn.fields.objects")) { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
645 |
fieldMode = FieldMode.OBJECTS; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
646 |
} else { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
647 |
fieldMode = FieldMode.AUTO; |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
648 |
} |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
649 |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
650 |
initLoggers(); |
16147 | 651 |
} |
652 |
||
26071 | 653 |
|
654 |
/** |
|
655 |
* Get the class filter for this context |
|
656 |
* @return class filter |
|
657 |
*/ |
|
658 |
public ClassFilter getClassFilter() { |
|
659 |
return classFilter; |
|
660 |
} |
|
661 |
||
16147 | 662 |
/** |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
663 |
* Returns the factory for constant method handles for global properties. The returned factory can be |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
664 |
* invalidated if this Context has more than one Global. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
665 |
* @return the factory for constant method handles for global properties. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
666 |
*/ |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
667 |
GlobalConstants getGlobalConstants() { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
668 |
return globalConstantsRef.get(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
669 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
670 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
671 |
/** |
16147 | 672 |
* Get the error manager for this context |
673 |
* @return error manger |
|
674 |
*/ |
|
16185 | 675 |
public ErrorManager getErrorManager() { |
16147 | 676 |
return errors; |
677 |
} |
|
678 |
||
679 |
/** |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
680 |
* Get the script environment for this context |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
681 |
* @return script environment |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
682 |
*/ |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
683 |
public ScriptEnvironment getEnv() { |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
684 |
return env; |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
685 |
} |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
686 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
687 |
/** |
16147 | 688 |
* Get the output stream for this context |
689 |
* @return output print writer |
|
690 |
*/ |
|
691 |
public PrintWriter getOut() { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
692 |
return env.getOut(); |
16147 | 693 |
} |
694 |
||
695 |
/** |
|
696 |
* Get the error stream for this context |
|
697 |
* @return error print writer |
|
698 |
*/ |
|
699 |
public PrintWriter getErr() { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
700 |
return env.getErr(); |
16147 | 701 |
} |
702 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16196
diff
changeset
|
703 |
/** |
29834
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
704 |
* Should scripts compiled by this context use dual field representation? |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
705 |
* @return true if using dual fields, false for object-only fields |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
706 |
*/ |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
707 |
public boolean useDualFields() { |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
708 |
return fieldMode == FieldMode.DUAL || (fieldMode == FieldMode.AUTO && env._optimistic_types); |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
709 |
} |
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
710 |
|
f678f348c947
8067215: Disable dual fields when not using optimistic types
hannesw
parents:
28785
diff
changeset
|
711 |
/** |
16188 | 712 |
* Get the PropertyMap of the current global scope |
713 |
* @return the property map of the current global scope |
|
714 |
*/ |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16196
diff
changeset
|
715 |
public static PropertyMap getGlobalMap() { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
716 |
return Context.getGlobal().getMap(); |
16188 | 717 |
} |
718 |
||
16147 | 719 |
/** |
720 |
* Compile a top level script. |
|
721 |
* |
|
722 |
* @param source the source |
|
723 |
* @param scope the scope |
|
724 |
* |
|
725 |
* @return top level function for script |
|
726 |
*/ |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
727 |
public ScriptFunction compileScript(final Source source, final ScriptObject scope) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
728 |
return compileScript(source, scope, this.errors); |
16147 | 729 |
} |
730 |
||
731 |
/** |
|
24282
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
732 |
* Interface to represent compiled code that can be re-used across many |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
733 |
* global scope instances |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
734 |
*/ |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
735 |
public static interface MultiGlobalCompiledScript { |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
736 |
/** |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
737 |
* Obtain script function object for a specific global scope object. |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
738 |
* |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
739 |
* @param newGlobal global scope for which function object is obtained |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
740 |
* @return script function for script level expressions |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
741 |
*/ |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
742 |
public ScriptFunction getFunction(final Global newGlobal); |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
743 |
} |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
744 |
|
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
745 |
/** |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
746 |
* Compile a top level script. |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
747 |
* |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
748 |
* @param source the script source |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
749 |
* @return reusable compiled script across many global scopes. |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
750 |
*/ |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
751 |
public MultiGlobalCompiledScript compileScript(final Source source) { |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
752 |
final Class<?> clazz = compile(source, this.errors, this._strict); |
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
753 |
final MethodHandle createProgramFunctionHandle = getCreateProgramFunctionHandle(clazz); |
24282
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
754 |
|
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
755 |
return new MultiGlobalCompiledScript() { |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
756 |
@Override |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
757 |
public ScriptFunction getFunction(final Global newGlobal) { |
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
758 |
return invokeCreateProgramFunctionHandle(createProgramFunctionHandle, newGlobal); |
24282
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
759 |
} |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
760 |
}; |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
761 |
} |
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
762 |
|
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
763 |
/** |
16147 | 764 |
* Entry point for {@code eval} |
765 |
* |
|
766 |
* @param initialScope The scope of this eval call |
|
767 |
* @param string Evaluated code as a String |
|
768 |
* @param callThis "this" to be passed to the evaluated code |
|
769 |
* @param location location of the eval call |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
770 |
* @return the return value of the {@code eval} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
771 |
*/ |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
772 |
public Object eval(final ScriptObject initialScope, final String string, |
31192
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
773 |
final Object callThis, final Object location) { |
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
774 |
return eval(initialScope, string, callThis, location, false, false); |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
775 |
} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
776 |
|
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
777 |
/** |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
778 |
* Entry point for {@code eval} |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
779 |
* |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
780 |
* @param initialScope The scope of this eval call |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
781 |
* @param string Evaluated code as a String |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
782 |
* @param callThis "this" to be passed to the evaluated code |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
783 |
* @param location location of the eval call |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
784 |
* @param strict is this {@code eval} call from a strict mode code? |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
785 |
* @param evalCall is this called from "eval" builtin? |
16147 | 786 |
* |
787 |
* @return the return value of the {@code eval} |
|
788 |
*/ |
|
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
789 |
public Object eval(final ScriptObject initialScope, final String string, |
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
790 |
final Object callThis, final Object location, final boolean strict, final boolean evalCall) { |
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
791 |
final String file = location == UNDEFINED || location == null ? "<eval>" : location.toString(); |
25240
f92c14b1ca11
8047959: bindings created for declarations in eval code are not mutable
sundar
parents:
24993
diff
changeset
|
792 |
final Source source = sourceFor(file, string, evalCall); |
31192
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
793 |
// is this direct 'eval' builtin call? |
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
794 |
final boolean directEval = evalCall && (location != UNDEFINED); |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
795 |
final Global global = Context.getGlobal(); |
16147 | 796 |
ScriptObject scope = initialScope; |
797 |
||
798 |
// ECMA section 10.1.1 point 2 says eval code is strict if it begins |
|
799 |
// with "use strict" directive or eval direct call itself is made |
|
800 |
// from from strict mode code. We are passed with caller's strict mode. |
|
31192
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
801 |
// Nashorn extension: any 'eval' is unconditionally strict when -strict is specified. |
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
802 |
boolean strictFlag = strict || this._strict; |
16147 | 803 |
|
804 |
Class<?> clazz = null; |
|
805 |
try { |
|
806 |
clazz = compile(source, new ThrowErrorManager(), strictFlag); |
|
807 |
} catch (final ParserException e) { |
|
808 |
e.throwAsEcmaException(global); |
|
809 |
return null; |
|
810 |
} |
|
811 |
||
812 |
if (!strictFlag) { |
|
813 |
// We need to get strict mode flag from compiled class. This is |
|
814 |
// because eval code may start with "use strict" directive. |
|
815 |
try { |
|
17233 | 816 |
strictFlag = clazz.getField(STRICT_MODE.symbolName()).getBoolean(null); |
16147 | 817 |
} catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { |
818 |
//ignored |
|
819 |
strictFlag = false; |
|
820 |
} |
|
821 |
} |
|
822 |
||
823 |
// In strict mode, eval does not instantiate variables and functions |
|
824 |
// in the caller's environment. A new environment is created! |
|
825 |
if (strictFlag) { |
|
31195
4ff0587b9ed1
8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents:
31192
diff
changeset
|
826 |
// Create a new scope object with given scope as its prototype |
4ff0587b9ed1
8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents:
31192
diff
changeset
|
827 |
scope = newScope(scope); |
16147 | 828 |
} |
829 |
||
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
830 |
final ScriptFunction func = getProgramFunction(clazz, scope); |
16147 | 831 |
Object evalThis; |
832 |
if (directEval) { |
|
28441
beb75d5da248
8068985: Wrong 'this' bound to eval call within a function when caller's 'this' is a Java object
sundar
parents:
27530
diff
changeset
|
833 |
evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global; |
16147 | 834 |
} else { |
31192
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
835 |
// either indirect evalCall or non-eval (Function, engine.eval, ScriptObjectMirror.eval..) |
1e019aeea9b5
8087211: Indirect evals should be strict with -strict option
sundar
parents:
30975
diff
changeset
|
836 |
evalThis = callThis; |
16147 | 837 |
} |
838 |
||
839 |
return ScriptRuntime.apply(func, evalThis); |
|
840 |
} |
|
841 |
||
31195
4ff0587b9ed1
8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents:
31192
diff
changeset
|
842 |
private static ScriptObject newScope(final ScriptObject callerScope) { |
31199 | 843 |
return new Scope(callerScope, PropertyMap.newMap(Scope.class)); |
31195
4ff0587b9ed1
8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents:
31192
diff
changeset
|
844 |
} |
4ff0587b9ed1
8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents:
31192
diff
changeset
|
845 |
|
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17513
diff
changeset
|
846 |
private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) { |
17244 | 847 |
if (srcStr.startsWith(prefix)) { |
848 |
final String resource = resourcePath + srcStr.substring(prefix.length()); |
|
849 |
// NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme |
|
850 |
// These scripts are always available and are loaded from nashorn.jar's resources. |
|
851 |
return AccessController.doPrivileged( |
|
852 |
new PrivilegedAction<Source>() { |
|
853 |
@Override |
|
854 |
public Source run() { |
|
855 |
try { |
|
856 |
final URL resURL = Context.class.getResource(resource); |
|
24769 | 857 |
return resURL != null ? sourceFor(srcStr, resURL) : null; |
17244 | 858 |
} catch (final IOException exp) { |
859 |
return null; |
|
860 |
} |
|
861 |
} |
|
862 |
}); |
|
863 |
} |
|
864 |
||
865 |
return null; |
|
866 |
} |
|
867 |
||
16147 | 868 |
/** |
869 |
* Implementation of {@code load} Nashorn extension. Load a script file from a source |
|
870 |
* expression |
|
871 |
* |
|
872 |
* @param scope the scope |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
873 |
* @param from source expression for script |
16147 | 874 |
* |
875 |
* @return return value for load call (undefined) |
|
876 |
* |
|
877 |
* @throws IOException if source cannot be found or loaded |
|
878 |
*/ |
|
31196
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
879 |
public Object load(final Object scope, final Object from) throws IOException { |
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
880 |
final Object src = from instanceof ConsString ? from.toString() : from; |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
881 |
Source source = null; |
16147 | 882 |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
883 |
// load accepts a String (which could be a URL or a file name), a File, a URL |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
884 |
// or a ScriptObject that has "name" and "source" (string valued) properties. |
16147 | 885 |
if (src instanceof String) { |
16251
4a5d15b2f168
8008166: URL handling was broken on windows, causing "load" to malfunction
lagergren
parents:
16245
diff
changeset
|
886 |
final String srcStr = (String)src; |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
887 |
if (srcStr.startsWith(LOAD_CLASSPATH)) { |
24725
7bb1f687a852
8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents:
24719
diff
changeset
|
888 |
final URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length())); |
24769 | 889 |
source = url != null ? sourceFor(url.toString(), url) : null; |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
890 |
} else { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
891 |
final File file = new File(srcStr); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
892 |
if (srcStr.indexOf(':') != -1) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
893 |
if ((source = loadInternal(srcStr, LOAD_NASHORN, "resources/")) == null && |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
894 |
(source = loadInternal(srcStr, LOAD_FX, "resources/fx/")) == null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
895 |
URL url; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
896 |
try { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
897 |
//check for malformed url. if malformed, it may still be a valid file |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
898 |
url = new URL(srcStr); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
899 |
} catch (final MalformedURLException e) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
900 |
url = file.toURI().toURL(); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
901 |
} |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
902 |
source = sourceFor(url.toString(), url); |
16254 | 903 |
} |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
904 |
} else if (file.isFile()) { |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
905 |
source = sourceFor(srcStr, file); |
16147 | 906 |
} |
907 |
} |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
908 |
} else if (src instanceof File && ((File)src).isFile()) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
909 |
final File file = (File)src; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
910 |
source = sourceFor(file.getName(), file); |
16147 | 911 |
} else if (src instanceof URL) { |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
912 |
final URL url = (URL)src; |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
913 |
source = sourceFor(url.toString(), url); |
16147 | 914 |
} else if (src instanceof ScriptObject) { |
915 |
final ScriptObject sobj = (ScriptObject)src; |
|
916 |
if (sobj.has("script") && sobj.has("name")) { |
|
917 |
final String script = JSType.toString(sobj.get("script")); |
|
918 |
final String name = JSType.toString(sobj.get("name")); |
|
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
919 |
source = sourceFor(name, script); |
16147 | 920 |
} |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
921 |
} else if (src instanceof Map) { |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
922 |
final Map<?,?> map = (Map<?,?>)src; |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
923 |
if (map.containsKey("script") && map.containsKey("name")) { |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
924 |
final String script = JSType.toString(map.get("script")); |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
925 |
final String name = JSType.toString(map.get("name")); |
24206
40c6d45af73f
8040078: Avoid repeated reading of source for cached loads
hannesw
parents:
23767
diff
changeset
|
926 |
source = sourceFor(name, script); |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
927 |
} |
16147 | 928 |
} |
929 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
930 |
if (source != null) { |
31196
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
931 |
if (scope instanceof ScriptObject && ((ScriptObject)scope).isScope()) { |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
932 |
final ScriptObject sobj = (ScriptObject)scope; |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
933 |
// passed object is a script object |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
934 |
// Global is the only user accessible scope ScriptObject |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
935 |
assert sobj.isGlobal() : "non-Global scope object!!"; |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
936 |
return evaluateSource(source, sobj, sobj); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
937 |
} else if (scope == null || scope == UNDEFINED) { |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
938 |
// undefined or null scope. Use current global instance. |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
939 |
final Global global = getGlobal(); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
940 |
return evaluateSource(source, global, global); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
941 |
} else { |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
942 |
/* |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
943 |
* Arbitrary object passed for scope. |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
944 |
* Indirect load that is equivalent to: |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
945 |
* |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
946 |
* (function(scope, source) { |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
947 |
* with (scope) { |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
948 |
* eval(<script_from_source>); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
949 |
* } |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
950 |
* })(scope, source); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
951 |
*/ |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
952 |
final Global global = getGlobal(); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
953 |
// Create a new object. This is where all declarations |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
954 |
// (var, function) from the evaluated code go. |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
955 |
// make global to be its __proto__ so that global |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
956 |
// definitions are accessible to the evaluated code. |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
957 |
final ScriptObject evalScope = newScope(global); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
958 |
|
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
959 |
// finally, make a WithObject around user supplied scope object |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
960 |
// so that it's properties are accessible as variables. |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
961 |
final ScriptObject withObj = ScriptRuntime.openWith(evalScope, scope); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
962 |
|
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
963 |
// evaluate given source with 'withObj' as scope |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
964 |
// but use global object as "this". |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
965 |
return evaluateSource(source, withObj, global); |
2ab121636a13
8098578: Global scope is not accessible with indirect load call
sundar
parents:
31195
diff
changeset
|
966 |
} |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
967 |
} |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
968 |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16254
diff
changeset
|
969 |
throw typeError("cant.load.script", ScriptRuntime.safeToString(from)); |
16147 | 970 |
} |
971 |
||
972 |
/** |
|
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
973 |
* Implementation of {@code loadWithNewGlobal} Nashorn extension. Load a script file from a source |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
974 |
* expression, after creating a new global scope. |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
975 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
976 |
* @param from source expression for script |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
977 |
* @param args (optional) arguments to be passed to the loaded script |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
978 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
979 |
* @return return value for load call (undefined) |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
980 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
981 |
* @throws IOException if source cannot be found or loaded |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
982 |
*/ |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
983 |
public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
984 |
final Global oldGlobal = getGlobal(); |
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
985 |
final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() { |
17976
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
986 |
@Override |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
987 |
public Global run() { |
17976
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
988 |
try { |
19459 | 989 |
return newGlobal(); |
17976
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
990 |
} catch (final RuntimeException e) { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
991 |
if (Context.DEBUG) { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
992 |
e.printStackTrace(); |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
993 |
} |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
994 |
throw e; |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
995 |
} |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
996 |
} |
19459 | 997 |
}, CREATE_GLOBAL_ACC_CTXT); |
998 |
// initialize newly created Global instance |
|
999 |
initGlobal(newGlobal); |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1000 |
setGlobal(newGlobal); |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1001 |
|
18874
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
1002 |
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal); |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1003 |
newGlobal.put("arguments", newGlobal.wrapAsObject(wrapped), env._strict); |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
1004 |
|
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1005 |
try { |
18874
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
1006 |
// wrap objects from newGlobal's world as mirrors - but if result |
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
1007 |
// is from oldGlobal's world, unwrap it! |
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
1008 |
return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal); |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1009 |
} finally { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1010 |
setGlobal(oldGlobal); |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1011 |
} |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1012 |
} |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1013 |
|
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
1014 |
/** |
16147 | 1015 |
* Load or get a structure class. Structure class names are based on the number of parameter fields |
1016 |
* and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects |
|
1017 |
* |
|
1018 |
* @see ObjectClassGenerator |
|
1019 |
* @see AccessorProperty |
|
1020 |
* @see ScriptObject |
|
1021 |
* |
|
16275 | 1022 |
* @param fullName full name of class, e.g. jdk.nashorn.internal.objects.JO2P1 contains 2 fields and 1 parameter. |
16147 | 1023 |
* |
16272 | 1024 |
* @return the {@code Class<?>} for this structure |
16147 | 1025 |
* |
1026 |
* @throws ClassNotFoundException if structure class cannot be resolved |
|
1027 |
*/ |
|
24719 | 1028 |
@SuppressWarnings("unchecked") |
1029 |
public static Class<? extends ScriptObject> forStructureClass(final String fullName) throws ClassNotFoundException { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
1030 |
if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
1031 |
throw new ClassNotFoundException(fullName); |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
1032 |
} |
24719 | 1033 |
return (Class<? extends ScriptObject>)Class.forName(fullName, true, sharedLoader); |
16147 | 1034 |
} |
1035 |
||
1036 |
/** |
|
32781
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1037 |
* Is {@code className} the name of a structure class? |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1038 |
* |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1039 |
* @param className a class name |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1040 |
* @return true if className is a structure class name |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1041 |
*/ |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1042 |
public static boolean isStructureClass(final String className) { |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1043 |
return StructureLoader.isStructureClass(className); |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1044 |
} |
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1045 |
|
d8f34ffbbc7a
8135190: Method code too large in Babel browser.js script
hannesw
parents:
32697
diff
changeset
|
1046 |
/** |
20567 | 1047 |
* Checks that the given Class can be accessed from no permissions context. |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1048 |
* |
20567 | 1049 |
* @param clazz Class object |
23374 | 1050 |
* @throws SecurityException if not accessible |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1051 |
*/ |
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
1052 |
public static void checkPackageAccess(final Class<?> clazz) { |
20567 | 1053 |
final SecurityManager sm = System.getSecurityManager(); |
1054 |
if (sm != null) { |
|
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
1055 |
Class<?> bottomClazz = clazz; |
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
1056 |
while (bottomClazz.isArray()) { |
20567 | 1057 |
bottomClazz = bottomClazz.getComponentType(); |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1058 |
} |
20567 | 1059 |
checkPackageAccess(sm, bottomClazz.getName()); |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1060 |
} |
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1061 |
} |
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1062 |
|
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
1063 |
/** |
22669 | 1064 |
* Checks that the given package name can be accessed from no permissions context. |
1065 |
* |
|
1066 |
* @param pkgName package name |
|
23374 | 1067 |
* @throws SecurityException if not accessible |
22669 | 1068 |
*/ |
1069 |
public static void checkPackageAccess(final String pkgName) { |
|
1070 |
final SecurityManager sm = System.getSecurityManager(); |
|
1071 |
if (sm != null) { |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1072 |
checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + "."); |
22669 | 1073 |
} |
1074 |
} |
|
1075 |
||
1076 |
/** |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
1077 |
* Checks that the given package can be accessed from no permissions context. |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1078 |
* |
20567 | 1079 |
* @param sm current security manager instance |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1080 |
* @param fullName fully qualified package name |
20567 | 1081 |
* @throw SecurityException if not accessible |
1082 |
*/ |
|
1083 |
private static void checkPackageAccess(final SecurityManager sm, final String fullName) { |
|
28785
a503c972d4bd
8072595: nashorn should not use obj.getClass() for null checks
sundar
parents:
28441
diff
changeset
|
1084 |
Objects.requireNonNull(sm); |
20567 | 1085 |
final int index = fullName.lastIndexOf('.'); |
1086 |
if (index != -1) { |
|
1087 |
final String pkgName = fullName.substring(0, index); |
|
1088 |
AccessController.doPrivileged(new PrivilegedAction<Void>() { |
|
1089 |
@Override |
|
1090 |
public Void run() { |
|
1091 |
sm.checkPackageAccess(pkgName); |
|
1092 |
return null; |
|
1093 |
} |
|
1094 |
}, NO_PERMISSIONS_ACC_CTXT); |
|
1095 |
} |
|
1096 |
} |
|
1097 |
||
1098 |
/** |
|
1099 |
* Checks that the given Class can be accessed from no permissions context. |
|
1100 |
* |
|
1101 |
* @param clazz Class object |
|
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1102 |
* @return true if package is accessible, false otherwise |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1103 |
*/ |
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
1104 |
private static boolean isAccessiblePackage(final Class<?> clazz) { |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1105 |
try { |
20567 | 1106 |
checkPackageAccess(clazz); |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1107 |
return true; |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1108 |
} catch (final SecurityException se) { |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1109 |
return false; |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1110 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1111 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1112 |
|
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1113 |
/** |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
1114 |
* Checks that the given Class is public and it can be accessed from no permissions context. |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1115 |
* |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1116 |
* @param clazz Class object to check |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1117 |
* @return true if Class is accessible, false otherwise |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1118 |
*/ |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1119 |
public static boolean isAccessibleClass(final Class<?> clazz) { |
20567 | 1120 |
return Modifier.isPublic(clazz.getModifiers()) && Context.isAccessiblePackage(clazz); |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1121 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1122 |
|
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
1123 |
/** |
16147 | 1124 |
* Lookup a Java class. This is used for JSR-223 stuff linking in from |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17519
diff
changeset
|
1125 |
* {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage} |
16147 | 1126 |
* |
1127 |
* @param fullName full name of class to load |
|
1128 |
* |
|
16272 | 1129 |
* @return the {@code Class<?>} for the name |
16147 | 1130 |
* |
1131 |
* @throws ClassNotFoundException if class cannot be resolved |
|
1132 |
*/ |
|
1133 |
public Class<?> findClass(final String fullName) throws ClassNotFoundException { |
|
20567 | 1134 |
if (fullName.indexOf('[') != -1 || fullName.indexOf('/') != -1) { |
1135 |
// don't allow array class names or internal names. |
|
1136 |
throw new ClassNotFoundException(fullName); |
|
1137 |
} |
|
1138 |
||
26071 | 1139 |
// give chance to ClassFilter to filter out, if present |
1140 |
if (classFilter != null && !classFilter.exposeToScripts(fullName)) { |
|
1141 |
throw new ClassNotFoundException(fullName); |
|
1142 |
} |
|
1143 |
||
16147 | 1144 |
// check package access as soon as possible! |
20567 | 1145 |
final SecurityManager sm = System.getSecurityManager(); |
1146 |
if (sm != null) { |
|
1147 |
checkPackageAccess(sm, fullName); |
|
1148 |
} |
|
16147 | 1149 |
|
16185 | 1150 |
// try the script -classpath loader, if that is set |
16147 | 1151 |
if (classPathLoader != null) { |
1152 |
try { |
|
1153 |
return Class.forName(fullName, true, classPathLoader); |
|
16185 | 1154 |
} catch (final ClassNotFoundException ignored) { |
16147 | 1155 |
// ignore, continue search |
1156 |
} |
|
1157 |
} |
|
1158 |
||
16185 | 1159 |
// Try finding using the "app" loader. |
1160 |
return Class.forName(fullName, true, appLoader); |
|
16147 | 1161 |
} |
1162 |
||
1163 |
/** |
|
1164 |
* Hook to print stack trace for a {@link Throwable} that occurred during |
|
1165 |
* execution |
|
1166 |
* |
|
1167 |
* @param t throwable for which to dump stack |
|
1168 |
*/ |
|
1169 |
public static void printStackTrace(final Throwable t) { |
|
1170 |
if (Context.DEBUG) { |
|
16185 | 1171 |
t.printStackTrace(Context.getCurrentErr()); |
16147 | 1172 |
} |
1173 |
} |
|
1174 |
||
1175 |
/** |
|
1176 |
* Verify generated bytecode before emission. This is called back from the |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
1177 |
* {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter |
16147 | 1178 |
* hasn't been given, this is a nop |
1179 |
* |
|
1180 |
* Note that verification may load classes -- we don't want to do that unless |
|
1181 |
* user specified verify option. We check it here even though caller |
|
1182 |
* may have already checked that flag |
|
1183 |
* |
|
1184 |
* @param bytecode bytecode to verify |
|
1185 |
*/ |
|
1186 |
public void verify(final byte[] bytecode) { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
1187 |
if (env._verify_code) { |
16147 | 1188 |
// No verification when security manager is around as verifier |
1189 |
// may load further classes - which should be avoided. |
|
1190 |
if (System.getSecurityManager() == null) { |
|
19098
473dfe87bb7b
8021294: --verify-code option results in AnalyzerException
sundar
parents:
19097
diff
changeset
|
1191 |
CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true)); |
16147 | 1192 |
} |
1193 |
} |
|
1194 |
} |
|
1195 |
||
1196 |
/** |
|
16211 | 1197 |
* Create and initialize a new global scope object. |
1198 |
* |
|
1199 |
* @return the initialized global scope object. |
|
1200 |
*/ |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1201 |
public Global createGlobal() { |
16211 | 1202 |
return initGlobal(newGlobal()); |
1203 |
} |
|
1204 |
||
1205 |
/** |
|
1206 |
* Create a new uninitialized global scope object |
|
16147 | 1207 |
* @return the global script object |
1208 |
*/ |
|
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1209 |
public Global newGlobal() { |
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1210 |
createOrInvalidateGlobalConstants(); |
19085
066c9e5afd79
8020731: Revisit checkPermission calls in Context class
sundar
parents:
18874
diff
changeset
|
1211 |
return new Global(this); |
16211 | 1212 |
} |
1213 |
||
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1214 |
private void createOrInvalidateGlobalConstants() { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1215 |
for (;;) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1216 |
final GlobalConstants currentGlobalConstants = getGlobalConstants(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1217 |
if (currentGlobalConstants != null) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1218 |
// Subsequent invocation; we're creating our second or later Global. GlobalConstants is not safe to use |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1219 |
// with more than one Global, as the constant method handle linkages it creates create a coupling |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1220 |
// between the Global and the call sites in the compiled code. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1221 |
currentGlobalConstants.invalidateForever(); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1222 |
return; |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1223 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1224 |
final GlobalConstants newGlobalConstants = new GlobalConstants(getLogger(GlobalConstants.class)); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1225 |
if (globalConstantsRef.compareAndSet(null, newGlobalConstants)) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1226 |
// First invocation; we're creating the first Global in this Context. Create the GlobalConstants object |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1227 |
// for this Context. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1228 |
return; |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1229 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1230 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1231 |
// If we reach here, then we started out as the first invocation, but another concurrent invocation won the |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1232 |
// CAS race. We'll just let the loop repeat and invalidate the CAS race winner. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1233 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1234 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1235 |
|
16211 | 1236 |
/** |
1237 |
* Initialize given global scope object. |
|
1238 |
* |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1239 |
* @param global the global |
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1240 |
* @param engine the associated ScriptEngine instance, can be null |
30975
a71c56056f02
8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents:
30513
diff
changeset
|
1241 |
* @param ctxt the initial ScriptContext, can be null |
16211 | 1242 |
* @return the initialized global scope object. |
1243 |
*/ |
|
30975
a71c56056f02
8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents:
30513
diff
changeset
|
1244 |
public Global initGlobal(final Global global, final ScriptEngine engine, final ScriptContext ctxt) { |
16147 | 1245 |
// Need only minimal global object, if we are just compiling. |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
1246 |
if (!env._compile_only) { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1247 |
final Global oldGlobal = Context.getGlobal(); |
16185 | 1248 |
try { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1249 |
Context.setGlobal(global); |
16185 | 1250 |
// initialize global scope with builtin global objects |
30975
a71c56056f02
8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents:
30513
diff
changeset
|
1251 |
global.initBuiltinObjects(engine, ctxt); |
16185 | 1252 |
} finally { |
23375
a1110f2cbe75
8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents:
23374
diff
changeset
|
1253 |
Context.setGlobal(oldGlobal); |
16185 | 1254 |
} |
16147 | 1255 |
} |
1256 |
||
1257 |
return global; |
|
1258 |
} |
|
1259 |
||
1260 |
/** |
|
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1261 |
* Initialize given global scope object. |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1262 |
* |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1263 |
* @param global the global |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1264 |
* @return the initialized global scope object. |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1265 |
*/ |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1266 |
public Global initGlobal(final Global global) { |
30975
a71c56056f02
8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents:
30513
diff
changeset
|
1267 |
return initGlobal(global, null, null); |
25422
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1268 |
} |
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1269 |
|
199a23bee487
8049524: Global object initialization via javax.script API should be minimal
sundar
parents:
25243
diff
changeset
|
1270 |
/** |
16188 | 1271 |
* Return the current global's context |
1272 |
* @return current global's context |
|
16185 | 1273 |
*/ |
1274 |
static Context getContextTrusted() { |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1275 |
return getContext(getGlobal()); |
16185 | 1276 |
} |
1277 |
||
24769 | 1278 |
static Context getContextTrustedOrNull() { |
1279 |
final Global global = Context.getGlobal(); |
|
27369
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1280 |
return global == null ? null : getContext(global); |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1281 |
} |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1282 |
|
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1283 |
private static Context getContext(final Global global) { |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1284 |
// We can't invoke Global.getContext() directly, as it's a protected override, and Global isn't in our package. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1285 |
// In order to access the method, we must cast it to ScriptObject first (which is in our package) and then let |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1286 |
// virtual invocation do its thing. |
5a251d0063d1
8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents:
27366
diff
changeset
|
1287 |
return ((ScriptObject)global).getContext(); |
24769 | 1288 |
} |
1289 |
||
16185 | 1290 |
/** |
16147 | 1291 |
* Try to infer Context instance from the Class. If we cannot, |
1292 |
* then get it from the thread local variable. |
|
1293 |
* |
|
1294 |
* @param clazz the class |
|
1295 |
* @return context |
|
1296 |
*/ |
|
1297 |
static Context fromClass(final Class<?> clazz) { |
|
1298 |
final ClassLoader loader = clazz.getClassLoader(); |
|
1299 |
||
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
1300 |
if (loader instanceof ScriptLoader) { |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
1301 |
return ((ScriptLoader)loader).getContext(); |
16147 | 1302 |
} |
1303 |
||
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
1304 |
return Context.getContextTrusted(); |
16147 | 1305 |
} |
1306 |
||
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
1307 |
private URL getResourceURL(final String resName) { |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1308 |
// try the classPathLoader if we have and then |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1309 |
// try the appLoader if non-null. |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1310 |
if (classPathLoader != null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1311 |
return classPathLoader.getResource(resName); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1312 |
} else if (appLoader != null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1313 |
return appLoader.getResource(resName); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1314 |
} |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1315 |
|
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1316 |
return null; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1317 |
} |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
1318 |
|
16147 | 1319 |
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { |
1320 |
ScriptFunction script = null; |
|
1321 |
||
1322 |
try { |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
1323 |
script = compileScript(source, scope, new Context.ThrowErrorManager()); |
16147 | 1324 |
} catch (final ParserException e) { |
16188 | 1325 |
e.throwAsEcmaException(); |
16147 | 1326 |
} |
1327 |
||
1328 |
return ScriptRuntime.apply(script, thiz); |
|
1329 |
} |
|
1330 |
||
24719 | 1331 |
private static ScriptFunction getProgramFunction(final Class<?> script, final ScriptObject scope) { |
24879
d316854e4249
8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents:
24783
diff
changeset
|
1332 |
if (script == null) { |
d316854e4249
8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents:
24783
diff
changeset
|
1333 |
return null; |
d316854e4249
8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents:
24783
diff
changeset
|
1334 |
} |
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1335 |
return invokeCreateProgramFunctionHandle(getCreateProgramFunctionHandle(script), scope); |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1336 |
} |
24282
2e3bd98c5664
8041697: CompiledScript slower when eval with binding
sundar
parents:
24206
diff
changeset
|
1337 |
|
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1338 |
private static MethodHandle getCreateProgramFunctionHandle(final Class<?> script) { |
16147 | 1339 |
try { |
24783
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1340 |
return LOOKUP.findStatic(script, CREATE_PROGRAM_FUNCTION.symbolName(), CREATE_PROGRAM_FUNCTION_TYPE); |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1341 |
} catch (NoSuchMethodException | IllegalAccessException e) { |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1342 |
throw new AssertionError("Failed to retrieve a handle for the program function for " + script.getName(), e); |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1343 |
} |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1344 |
} |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1345 |
|
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1346 |
private static ScriptFunction invokeCreateProgramFunctionHandle(final MethodHandle createProgramFunctionHandle, final ScriptObject scope) { |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1347 |
try { |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1348 |
return (ScriptFunction)createProgramFunctionHandle.invokeExact(scope); |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1349 |
} catch (final RuntimeException|Error e) { |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1350 |
throw e; |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1351 |
} catch (final Throwable t) { |
b5c31bfe1496
8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents:
24779
diff
changeset
|
1352 |
throw new AssertionError("Failed to create a program function", t); |
16147 | 1353 |
} |
1354 |
} |
|
1355 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
1356 |
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) { |
24719 | 1357 |
return getProgramFunction(compile(source, errMan, this._strict), scope); |
16147 | 1358 |
} |
1359 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
1360 |
private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) { |
16147 | 1361 |
// start with no errors, no warnings. |
1362 |
errMan.reset(); |
|
1363 |
||
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1364 |
Class<?> script = findCachedClass(source); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1365 |
if (script != null) { |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1366 |
final DebugLogger log = getLogger(Compiler.class); |
24744
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
1367 |
if (log.isEnabled()) { |
5290da85fc3d
8038426: Move all loggers from process wide scope into Global scope
lagergren
parents:
24742
diff
changeset
|
1368 |
log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile."); |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24727
diff
changeset
|
1369 |
} |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1370 |
return script; |
16147 | 1371 |
} |
1372 |
||
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1373 |
StoredScript storedScript = null; |
23767 | 1374 |
FunctionNode functionNode = null; |
30389
35e1a33f3d12
8078612: Persistent code cache should support more configurations
hannesw
parents:
30056
diff
changeset
|
1375 |
// Don't use code store if optimistic types is enabled but lazy compilation is not. |
35e1a33f3d12
8078612: Persistent code cache should support more configurations
hannesw
parents:
30056
diff
changeset
|
1376 |
// This would store a full script compilation with many wrong optimistic assumptions that would |
35e1a33f3d12
8078612: Persistent code cache should support more configurations
hannesw
parents:
30056
diff
changeset
|
1377 |
// do more harm than good on later runs with both optimistic types and lazy compilation enabled. |
35e1a33f3d12
8078612: Persistent code cache should support more configurations
hannesw
parents:
30056
diff
changeset
|
1378 |
final boolean useCodeStore = codeStore != null && !env._parse_only && (!env._optimistic_types || env._lazy_compilation); |
35e1a33f3d12
8078612: Persistent code cache should support more configurations
hannesw
parents:
30056
diff
changeset
|
1379 |
final String cacheKey = useCodeStore ? CodeStore.getCacheKey("script", null) : null; |
23767 | 1380 |
|
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1381 |
if (useCodeStore) { |
26764
c777787a937d
8046202: Make persistent code store more flexible
hannesw
parents:
26508
diff
changeset
|
1382 |
storedScript = codeStore.load(source, cacheKey); |
16147 | 1383 |
} |
1384 |
||
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1385 |
if (storedScript == null) { |
30513
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
30389
diff
changeset
|
1386 |
if (env._dest_dir != null) { |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
30389
diff
changeset
|
1387 |
source.dump(env._dest_dir); |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
30389
diff
changeset
|
1388 |
} |
14cefab8350f
8080090: -d option should dump script source as well
sundar
parents:
30389
diff
changeset
|
1389 |
|
24769 | 1390 |
functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse(); |
23767 | 1391 |
|
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26248
diff
changeset
|
1392 |
if (errMan.hasErrors()) { |
23767 | 1393 |
return null; |
1394 |
} |
|
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
1395 |
|
26065
d15adb218527
8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents:
26055
diff
changeset
|
1396 |
if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) { |
23767 | 1397 |
getErr().println(new ASTWriter(functionNode)); |
1398 |
} |
|
1399 |
||
26065
d15adb218527
8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents:
26055
diff
changeset
|
1400 |
if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) { |
24769 | 1401 |
getErr().println(new PrintVisitor(functionNode, true, false)); |
23767 | 1402 |
} |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1403 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1404 |
|
17233 | 1405 |
if (env._parse_only) { |
1406 |
return null; |
|
1407 |
} |
|
1408 |
||
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1409 |
final URL url = source.getURL(); |
23076
8660ebaaa2f2
8033924: Default permissions are not given for eval code
sundar
parents:
22669
diff
changeset
|
1410 |
final CodeSource cs = new CodeSource(url, (CodeSigner[])null); |
32696
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1411 |
final CodeInstaller installer; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1412 |
if (DISABLE_VM_ANONYMOUS_CLASSES || env._persistent_cache || !env._lazy_compilation) { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1413 |
// Persistent code cache and eager compilation preclude use of VM anonymous classes |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1414 |
final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader; |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1415 |
installer = new NamedContextCodeInstaller(this, cs, loader); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1416 |
} else { |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1417 |
installer = new AnonymousContextCodeInstaller(this, cs); |
05c6d9c5eb07
8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents:
32534
diff
changeset
|
1418 |
} |
16147 | 1419 |
|
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1420 |
if (storedScript == null) { |
24769 | 1421 |
final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL; |
24759
31aed7d9c02a
8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents:
24745
diff
changeset
|
1422 |
|
32530 | 1423 |
final Compiler compiler = Compiler.forInitialCompilation( |
24769 | 1424 |
installer, |
1425 |
source, |
|
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26248
diff
changeset
|
1426 |
errMan, |
24769 | 1427 |
strict | functionNode.isStrict()); |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1428 |
|
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1429 |
final FunctionNode compiledFunction = compiler.compile(functionNode, phases); |
26377
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26248
diff
changeset
|
1430 |
if (errMan.hasErrors()) { |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26248
diff
changeset
|
1431 |
return null; |
028dad61662f
8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents:
26248
diff
changeset
|
1432 |
} |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1433 |
script = compiledFunction.getRootClass(); |
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1434 |
compiler.persistClassInfo(cacheKey, compiledFunction); |
23767 | 1435 |
} else { |
26055
fe8be844ba50
8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents:
25422
diff
changeset
|
1436 |
Compiler.updateCompilationId(storedScript.getCompilationId()); |
30056
06d201382b55
8053905: Eager code generation fails for earley boyer with split threshold set to 1000
hannesw
parents:
29834
diff
changeset
|
1437 |
script = storedScript.installScript(source, installer); |
23767 | 1438 |
} |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
1439 |
|
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1440 |
cacheClass(source, script); |
16147 | 1441 |
return script; |
1442 |
} |
|
1443 |
||
1444 |
private ScriptLoader createNewLoader() { |
|
1445 |
return AccessController.doPrivileged( |
|
1446 |
new PrivilegedAction<ScriptLoader>() { |
|
1447 |
@Override |
|
1448 |
public ScriptLoader run() { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
1449 |
return new ScriptLoader(appLoader, Context.this); |
16147 | 1450 |
} |
19459 | 1451 |
}, CREATE_LOADER_ACC_CTXT); |
16147 | 1452 |
} |
1453 |
||
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
1454 |
private long getUniqueScriptId() { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
1455 |
return uniqueScriptId.getAndIncrement(); |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
1456 |
} |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1457 |
|
23767 | 1458 |
/** |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1459 |
* Cache for compiled script classes. |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1460 |
*/ |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1461 |
@SuppressWarnings("serial") |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1462 |
@Logger(name="classcache") |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1463 |
private static class ClassCache extends LinkedHashMap<Source, ClassReference> implements Loggable { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1464 |
private final int size; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1465 |
private final ReferenceQueue<Class<?>> queue; |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1466 |
private final DebugLogger log; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1467 |
|
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1468 |
ClassCache(final Context context, final int size) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1469 |
super(size, 0.75f, true); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1470 |
this.size = size; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1471 |
this.queue = new ReferenceQueue<>(); |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1472 |
this.log = initLogger(context); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1473 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1474 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1475 |
void cache(final Source source, final Class<?> clazz) { |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1476 |
if (log.isEnabled()) { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1477 |
log.info("Caching ", source, " in class cache"); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1478 |
} |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1479 |
put(source, new ClassReference(clazz, queue, source)); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1480 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1481 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1482 |
@Override |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1483 |
protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1484 |
return size() > size; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1485 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1486 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1487 |
@Override |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24727
diff
changeset
|
1488 |
public ClassReference get(final Object key) { |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1489 |
for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) { |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1490 |
final Source source = ref.source; |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1491 |
if (log.isEnabled()) { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1492 |
log.info("Evicting ", source, " from class cache."); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1493 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1494 |
remove(source); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1495 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1496 |
|
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1497 |
final ClassReference ref = super.get(key); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1498 |
if (ref != null && log.isEnabled()) { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1499 |
log.info("Retrieved class reference for ", ref.source, " from class cache"); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1500 |
} |
27102
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1501 |
return ref; |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1502 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1503 |
|
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1504 |
@Override |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1505 |
public DebugLogger initLogger(final Context context) { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1506 |
return context.getLogger(getClass()); |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1507 |
} |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1508 |
|
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1509 |
@Override |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1510 |
public DebugLogger getLogger() { |
c64b3468d51d
8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents:
26982
diff
changeset
|
1511 |
return log; |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1512 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1513 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1514 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1515 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1516 |
private static class ClassReference extends SoftReference<Class<?>> { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1517 |
private final Source source; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1518 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1519 |
ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1520 |
super(clazz, queue); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1521 |
this.source = source; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1522 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1523 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1524 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1525 |
// Class cache management |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1526 |
private Class<?> findCachedClass(final Source source) { |
24731
ab0c8fc915ae
8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents:
24727
diff
changeset
|
1527 |
final ClassReference ref = classCache == null ? null : classCache.get(source); |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1528 |
return ref != null ? ref.get() : null; |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1529 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1530 |
|
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1531 |
private void cacheClass(final Source source, final Class<?> clazz) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1532 |
if (classCache != null) { |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1533 |
classCache.cache(source, clazz); |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1534 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1535 |
} |
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1536 |
|
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1537 |
// logging |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1538 |
private final Map<String, DebugLogger> loggers = new HashMap<>(); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1539 |
|
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1540 |
private void initLoggers() { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1541 |
((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1542 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1543 |
|
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1544 |
/** |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1545 |
* Get a logger, given a loggable class |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1546 |
* @param clazz a Loggable class |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1547 |
* @return debuglogger associated with that class |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1548 |
*/ |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1549 |
public DebugLogger getLogger(final Class<? extends Loggable> clazz) { |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1550 |
return getLogger(clazz, null); |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1551 |
} |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1552 |
|
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1553 |
/** |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1554 |
* Get a logger, given a loggable class |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1555 |
* @param clazz a Loggable class |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1556 |
* @param initHook an init hook - if this is the first time the logger is created in the context, run the init hook |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1557 |
* @return debuglogger associated with that class |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1558 |
*/ |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1559 |
public DebugLogger getLogger(final Class<? extends Loggable> clazz, final Consumer<DebugLogger> initHook) { |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1560 |
final String name = getLoggerName(clazz); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1561 |
DebugLogger logger = loggers.get(name); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1562 |
if (logger == null) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1563 |
if (!env.hasLogger(name)) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1564 |
return DebugLogger.DISABLED_LOGGER; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1565 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1566 |
final LoggerInfo info = env._loggers.get(name); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1567 |
logger = new DebugLogger(name, info.getLevel(), info.isQuiet()); |
24993
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1568 |
if (initHook != null) { |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1569 |
initHook.accept(logger); |
b707d46bae40
8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents:
24879
diff
changeset
|
1570 |
} |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1571 |
loggers.put(name, logger); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1572 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1573 |
return logger; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1574 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1575 |
|
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1576 |
/** |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1577 |
* Given a Loggable class, weave debug info info a method handle for that logger. |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1578 |
* Level.INFO is used |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1579 |
* |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1580 |
* @param clazz loggable |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1581 |
* @param mh method handle |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1582 |
* @param text debug printout to add |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1583 |
* |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1584 |
* @return instrumented method handle, or null if logger not enabled |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1585 |
*/ |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1586 |
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final MethodHandle mh, final Supplier<String> text) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1587 |
return addLoggingToHandle(clazz, Level.INFO, mh, Integer.MAX_VALUE, false, text); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1588 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1589 |
|
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1590 |
/** |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1591 |
* Given a Loggable class, weave debug info info a method handle for that logger. |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1592 |
* |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1593 |
* @param clazz loggable |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1594 |
* @param level log level |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1595 |
* @param mh method handle |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1596 |
* @param paramStart first parameter to print |
32534
b3ec7f3b3c2a
8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents:
32530
diff
changeset
|
1597 |
* @param printReturnValue should we print the return value? |
24745
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1598 |
* @param text debug printout to add |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1599 |
* |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1600 |
* @return instrumented method handle, or null if logger not enabled |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1601 |
*/ |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1602 |
public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Supplier<String> text) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1603 |
final DebugLogger log = getLogger(clazz); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1604 |
if (log.isEnabled()) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1605 |
return MethodHandleFactory.addDebugPrintout(log, level, mh, paramStart, printReturnValue, text.get()); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1606 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1607 |
return mh; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1608 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1609 |
|
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1610 |
private static String getLoggerName(final Class<?> clazz) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1611 |
Class<?> current = clazz; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1612 |
while (current != null) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1613 |
final Logger log = current.getAnnotation(Logger.class); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1614 |
if (log != null) { |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1615 |
assert !"".equals(log.name()); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1616 |
return log.name(); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1617 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1618 |
current = current.getSuperclass(); |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1619 |
} |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1620 |
assert false; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1621 |
return null; |
3a6e1477362b
8041434: Add synchronization to the common global constants structure
lagergren
parents:
24744
diff
changeset
|
1622 |
} |
23372
09707b3e5fb0
8021350: Share script classes between threads/globals within context
hannesw
parents:
23076
diff
changeset
|
1623 |
|
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1624 |
/** |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1625 |
* This is a special kind of switchpoint used to guard builtin |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1626 |
* properties and prototypes. In the future it might contain |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1627 |
* logic to e.g. multiple switchpoint classes. |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1628 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1629 |
public static final class BuiltinSwitchPoint extends SwitchPoint { |
26886
18c744ab4df2
8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents:
26768
diff
changeset
|
1630 |
//empty |
26768
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1631 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1632 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1633 |
/** |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1634 |
* Create a new builtin switchpoint and return it |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1635 |
* @param name key name |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1636 |
* @return new builtin switchpoint |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1637 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1638 |
public SwitchPoint newBuiltinSwitchPoint(final String name) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1639 |
assert builtinSwitchPoints.get(name) == null; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1640 |
final SwitchPoint sp = new BuiltinSwitchPoint(); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1641 |
builtinSwitchPoints.put(name, sp); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1642 |
return sp; |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1643 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1644 |
|
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1645 |
/** |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1646 |
* Return the builtin switchpoint for a particular key name |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1647 |
* @param name key name |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1648 |
* @return builtin switchpoint or null if none |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1649 |
*/ |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1650 |
public SwitchPoint getBuiltinSwitchPoint(final String name) { |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1651 |
return builtinSwitchPoints.get(name); |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1652 |
} |
751b0f427090
8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents:
26764
diff
changeset
|
1653 |
|
16147 | 1654 |
} |