Mercurial > hg > graal-compiler
annotate src/share/vm/prims/unsafe.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | e6b1331a51d2 |
children | 436b4a3231bf |
rev | line source |
---|---|
0 | 1 /* |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
27 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
28 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
29 #endif // SERIALGC |
1972 | 30 #include "memory/allocation.inline.hpp" |
31 #include "prims/jni.h" | |
32 #include "prims/jvm.h" | |
33 #include "runtime/globals.hpp" | |
34 #include "runtime/interfaceSupport.hpp" | |
35 #include "runtime/reflection.hpp" | |
36 #include "runtime/synchronizer.hpp" | |
37 #include "services/threadService.hpp" | |
38 #include "utilities/copy.hpp" | |
39 #include "utilities/dtrace.hpp" | |
40 | |
0 | 41 /* |
42 * Implementation of class sun.misc.Unsafe | |
43 */ | |
44 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
45 HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
46 HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
47 HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
48 |
0 | 49 #define MAX_OBJECT_SIZE \ |
50 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \ | |
51 + ((julong)max_jint * sizeof(double)) ) | |
52 | |
53 | |
54 #define UNSAFE_ENTRY(result_type, header) \ | |
55 JVM_ENTRY(result_type, header) | |
56 | |
57 // Can't use UNSAFE_LEAF because it has the signature of a straight | |
58 // call into the runtime (just like JVM_LEAF, funny that) but it's | |
59 // called like a Java Native and thus the wrapper built for it passes | |
60 // arguments like a JNI call. It expects those arguments to be popped | |
61 // from the stack on Intel like all good JNI args are, and adjusts the | |
62 // stack according. Since the JVM_LEAF call expects no extra | |
63 // arguments the stack isn't popped in the C code, is pushed by the | |
64 // wrapper and we get sick. | |
65 //#define UNSAFE_LEAF(result_type, header) \ | |
66 // JVM_LEAF(result_type, header) | |
67 | |
68 #define UNSAFE_END JVM_END | |
69 | |
70 #define UnsafeWrapper(arg) /*nothing, for the present*/ | |
71 | |
72 | |
73 inline void* addr_from_java(jlong addr) { | |
74 // This assert fails in a variety of ways on 32-bit systems. | |
75 // It is impossible to predict whether native code that converts | |
76 // pointers to longs will sign-extend or zero-extend the addresses. | |
77 //assert(addr == (uintptr_t)addr, "must not be odd high bits"); | |
78 return (void*)(uintptr_t)addr; | |
79 } | |
80 | |
81 inline jlong addr_to_java(void* p) { | |
82 assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); | |
83 return (uintptr_t)p; | |
84 } | |
85 | |
86 | |
87 // Note: The VM's obj_field and related accessors use byte-scaled | |
88 // ("unscaled") offsets, just as the unsafe methods do. | |
89 | |
90 // However, the method Unsafe.fieldOffset explicitly declines to | |
91 // guarantee this. The field offset values manipulated by the Java user | |
92 // through the Unsafe API are opaque cookies that just happen to be byte | |
93 // offsets. We represent this state of affairs by passing the cookies | |
94 // through conversion functions when going between the VM and the Unsafe API. | |
95 // The conversion functions just happen to be no-ops at present. | |
96 | |
97 inline jlong field_offset_to_byte_offset(jlong field_offset) { | |
98 return field_offset; | |
99 } | |
100 | |
101 inline jlong field_offset_from_byte_offset(jlong byte_offset) { | |
102 return byte_offset; | |
103 } | |
104 | |
105 inline jint invocation_key_from_method_slot(jint slot) { | |
106 return slot; | |
107 } | |
108 | |
109 inline jint invocation_key_to_method_slot(jint key) { | |
110 return key; | |
111 } | |
112 | |
113 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) { | |
114 jlong byte_offset = field_offset_to_byte_offset(field_offset); | |
2316
d411927672ed
7012072: CompileTheWorld causes incorrect class initialization
never
parents:
2177
diff
changeset
|
115 // Don't allow unsafe to be used to read or write the header word of oops |
d411927672ed
7012072: CompileTheWorld causes incorrect class initialization
never
parents:
2177
diff
changeset
|
116 assert(p == NULL || field_offset >= oopDesc::header_size(), "offset must be outside of header"); |
0 | 117 #ifdef ASSERT |
118 if (p != NULL) { | |
119 assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); | |
120 if (byte_offset == (jint)byte_offset) { | |
121 void* ptr_plus_disp = (address)p + byte_offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
122 assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp, |
0 | 123 "raw [ptr+disp] must be consistent with oop::field_base"); |
124 } | |
125 } | |
126 #endif | |
127 if (sizeof(char*) == sizeof(jint)) // (this constant folds!) | |
128 return (address)p + (jint) byte_offset; | |
129 else | |
130 return (address)p + byte_offset; | |
131 } | |
132 | |
133 // Externally callable versions: | |
134 // (Use these in compiler intrinsics which emulate unsafe primitives.) | |
135 jlong Unsafe_field_offset_to_byte_offset(jlong field_offset) { | |
136 return field_offset; | |
137 } | |
138 jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) { | |
139 return byte_offset; | |
140 } | |
141 jint Unsafe_invocation_key_from_method_slot(jint slot) { | |
142 return invocation_key_from_method_slot(slot); | |
143 } | |
144 jint Unsafe_invocation_key_to_method_slot(jint key) { | |
145 return invocation_key_to_method_slot(key); | |
146 } | |
147 | |
148 | |
149 ///// Data in the Java heap. | |
150 | |
151 #define GET_FIELD(obj, offset, type_name, v) \ | |
152 oop p = JNIHandles::resolve(obj); \ | |
153 type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) | |
154 | |
155 #define SET_FIELD(obj, offset, type_name, x) \ | |
156 oop p = JNIHandles::resolve(obj); \ | |
157 *(type_name*)index_oop_from_field_offset_long(p, offset) = x | |
158 | |
159 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ | |
160 oop p = JNIHandles::resolve(obj); \ | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
161 volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset)); |
0 | 162 |
163 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ | |
164 oop p = JNIHandles::resolve(obj); \ | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
165 OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x); |
0 | 166 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
167 // Macros for oops that check UseCompressedOops |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
168 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
169 #define GET_OOP_FIELD(obj, offset, v) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
170 oop p = JNIHandles::resolve(obj); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
171 oop v; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
172 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
173 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
174 v = oopDesc::decode_heap_oop(n); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
175 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
176 v = *(oop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
177 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
178 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
179 #define GET_OOP_FIELD_VOLATILE(obj, offset, v) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
180 oop p = JNIHandles::resolve(obj); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
181 volatile oop v; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
182 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
183 volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
184 v = oopDesc::decode_heap_oop(n); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
185 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
186 v = *(volatile oop*)index_oop_from_field_offset_long(p, offset); \ |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
187 } \ |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
188 OrderAccess::acquire(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
189 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
190 |
0 | 191 // Get/SetObject must be special-cased, since it works with handles. |
192 | |
193 // The xxx140 variants for backward compatibility do not allow a full-width offset. | |
194 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) | |
195 UnsafeWrapper("Unsafe_GetObject"); | |
196 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
197 GET_OOP_FIELD(obj, offset, v) |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
198 jobject ret = JNIHandles::make_local(env, v); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
199 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
200 // We could be accessing the referent field in a reference |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
201 // object. If G1 is enabled then we need to register a non-null |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
202 // referent with the SATB barrier. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
203 if (UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
204 bool needs_barrier = false; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
205 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
206 if (ret != NULL) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
207 if (offset == java_lang_ref_Reference::referent_offset) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
208 oop o = JNIHandles::resolve_non_null(obj); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
209 klassOop k = o->klass(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
210 if (instanceKlass::cast(k)->reference_type() != REF_NONE) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
211 assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
212 needs_barrier = true; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
213 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
214 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
215 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
216 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
217 if (needs_barrier) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
218 oop referent = JNIHandles::resolve(ret); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
219 G1SATBCardTableModRefBS::enqueue(referent); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
220 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
221 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
222 #endif // SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
223 return ret; |
0 | 224 UNSAFE_END |
225 | |
226 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) | |
227 UnsafeWrapper("Unsafe_SetObject"); | |
228 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); | |
229 oop x = JNIHandles::resolve(x_h); | |
230 //SET_FIELD(obj, offset, oop, x); | |
231 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
232 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
233 if (x != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
234 // If there is a heap base pointer, we are obliged to emit a store barrier. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
235 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
236 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
237 narrowOop n = oopDesc::encode_heap_oop_not_null(x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
238 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
239 } |
0 | 240 } else { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
241 if (x != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
242 // If there is a heap base pointer, we are obliged to emit a store barrier. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
243 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
244 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
245 *(oop*)index_oop_from_field_offset_long(p, offset) = x; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
246 } |
0 | 247 } |
248 UNSAFE_END | |
249 | |
250 // The normal variants allow a null base pointer with an arbitrary address. | |
251 // But if the base pointer is non-null, the offset should make some sense. | |
252 // That is, it should be in the range [0, MAX_OBJECT_SIZE]. | |
253 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
254 UnsafeWrapper("Unsafe_GetObject"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
255 GET_OOP_FIELD(obj, offset, v) |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
256 jobject ret = JNIHandles::make_local(env, v); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
257 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
258 // We could be accessing the referent field in a reference |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
259 // object. If G1 is enabled then we need to register non-null |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
260 // referent with the SATB barrier. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
261 if (UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
262 bool needs_barrier = false; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
263 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
264 if (ret != NULL) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
265 if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
266 oop o = JNIHandles::resolve(obj); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
267 klassOop k = o->klass(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
268 if (instanceKlass::cast(k)->reference_type() != REF_NONE) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
269 assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
270 needs_barrier = true; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
271 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
272 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
273 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
274 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
275 if (needs_barrier) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
276 oop referent = JNIHandles::resolve(ret); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
277 G1SATBCardTableModRefBS::enqueue(referent); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
278 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
279 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
280 #endif // SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2376
diff
changeset
|
281 return ret; |
0 | 282 UNSAFE_END |
283 | |
284 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
285 UnsafeWrapper("Unsafe_SetObject"); | |
286 oop x = JNIHandles::resolve(x_h); | |
287 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
288 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
289 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
290 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
291 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
292 } |
0 | 293 UNSAFE_END |
294 | |
295 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
296 UnsafeWrapper("Unsafe_GetObjectVolatile"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
297 GET_OOP_FIELD_VOLATILE(obj, offset, v) |
0 | 298 return JNIHandles::make_local(env, v); |
299 UNSAFE_END | |
300 | |
301 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
302 UnsafeWrapper("Unsafe_SetObjectVolatile"); | |
303 oop x = JNIHandles::resolve(x_h); | |
304 oop p = JNIHandles::resolve(obj); | |
3901
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
305 // Catch VolatileCallSite.target stores (via |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
306 // CallSite.setTargetVolatile) and check call site dependencies. |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
307 if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) { |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
308 oop call_site = p; |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
309 oop method_handle = x; |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
310 assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be"); |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
311 assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be"); |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
312 { |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
313 // Walk all nmethods depending on this call site. |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
314 MutexLocker mu(Compile_lock, thread); |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
315 Universe::flush_dependents_on(call_site, method_handle); |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
316 } |
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3895
diff
changeset
|
317 } |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
318 void* addr = index_oop_from_field_offset_long(p, offset); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
319 OrderAccess::release(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
320 if (UseCompressedOops) { |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
321 oop_store((narrowOop*)addr, x); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
322 } else { |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
323 oop_store((oop*)addr, x); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
324 } |
0 | 325 OrderAccess::fence(); |
326 UNSAFE_END | |
327 | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
328 #if defined(SPARC) || defined(X86) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
329 // Sparc and X86 have atomic jlong (8 bytes) instructions |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
330 |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
331 #else |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
332 // Keep old code for platforms which may not have atomic jlong (8 bytes) instructions |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
333 |
0 | 334 // Volatile long versions must use locks if !VM_Version::supports_cx8(). |
335 // support_cx8 is a surrogate for 'supports atomic long memory ops'. | |
336 | |
337 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
338 UnsafeWrapper("Unsafe_GetLongVolatile"); | |
339 { | |
340 if (VM_Version::supports_cx8()) { | |
341 GET_FIELD_VOLATILE(obj, offset, jlong, v); | |
342 return v; | |
343 } | |
344 else { | |
345 Handle p (THREAD, JNIHandles::resolve(obj)); | |
346 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
347 ObjectLocker ol(p, THREAD); | |
348 jlong value = *addr; | |
349 return value; | |
350 } | |
351 } | |
352 UNSAFE_END | |
353 | |
354 UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) | |
355 UnsafeWrapper("Unsafe_SetLongVolatile"); | |
356 { | |
357 if (VM_Version::supports_cx8()) { | |
358 SET_FIELD_VOLATILE(obj, offset, jlong, x); | |
359 } | |
360 else { | |
361 Handle p (THREAD, JNIHandles::resolve(obj)); | |
362 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
363 ObjectLocker ol(p, THREAD); | |
364 *addr = x; | |
365 } | |
366 } | |
367 UNSAFE_END | |
368 | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
369 #endif // not SPARC and not X86 |
0 | 370 |
371 #define DEFINE_GETSETOOP(jboolean, Boolean) \ | |
372 \ | |
373 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) \ | |
374 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
375 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); \ | |
376 GET_FIELD(obj, offset, jboolean, v); \ | |
377 return v; \ | |
378 UNSAFE_END \ | |
379 \ | |
380 UNSAFE_ENTRY(void, Unsafe_Set##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jboolean x)) \ | |
381 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
382 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); \ | |
383 SET_FIELD(obj, offset, jboolean, x); \ | |
384 UNSAFE_END \ | |
385 \ | |
386 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \ | |
387 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
388 GET_FIELD(obj, offset, jboolean, v); \ | |
389 return v; \ | |
390 UNSAFE_END \ | |
391 \ | |
392 UNSAFE_ENTRY(void, Unsafe_Set##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \ | |
393 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
394 SET_FIELD(obj, offset, jboolean, x); \ | |
395 UNSAFE_END \ | |
396 \ | |
397 // END DEFINE_GETSETOOP. | |
398 | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
399 DEFINE_GETSETOOP(jboolean, Boolean) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
400 DEFINE_GETSETOOP(jbyte, Byte) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
401 DEFINE_GETSETOOP(jshort, Short); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
402 DEFINE_GETSETOOP(jchar, Char); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
403 DEFINE_GETSETOOP(jint, Int); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
404 DEFINE_GETSETOOP(jlong, Long); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
405 DEFINE_GETSETOOP(jfloat, Float); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
406 DEFINE_GETSETOOP(jdouble, Double); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
407 |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
408 #undef DEFINE_GETSETOOP |
0 | 409 |
410 #define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \ | |
411 \ | |
412 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \ | |
413 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
414 GET_FIELD_VOLATILE(obj, offset, jboolean, v); \ | |
415 return v; \ | |
416 UNSAFE_END \ | |
417 \ | |
418 UNSAFE_ENTRY(void, Unsafe_Set##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \ | |
419 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
420 SET_FIELD_VOLATILE(obj, offset, jboolean, x); \ | |
421 UNSAFE_END \ | |
422 \ | |
423 // END DEFINE_GETSETOOP_VOLATILE. | |
424 | |
425 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) | |
426 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte) | |
427 DEFINE_GETSETOOP_VOLATILE(jshort, Short); | |
428 DEFINE_GETSETOOP_VOLATILE(jchar, Char); | |
429 DEFINE_GETSETOOP_VOLATILE(jint, Int); | |
430 DEFINE_GETSETOOP_VOLATILE(jfloat, Float); | |
431 DEFINE_GETSETOOP_VOLATILE(jdouble, Double); | |
432 | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
433 #if defined(SPARC) || defined(X86) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
434 // Sparc and X86 have atomic jlong (8 bytes) instructions |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
435 DEFINE_GETSETOOP_VOLATILE(jlong, Long); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
436 #endif |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
437 |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
438 #undef DEFINE_GETSETOOP_VOLATILE |
0 | 439 |
440 // The non-intrinsified versions of setOrdered just use setVolatile | |
441 | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
442 UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
443 UnsafeWrapper("Unsafe_SetOrderedInt"); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
444 SET_FIELD_VOLATILE(obj, offset, jint, x); |
0 | 445 UNSAFE_END |
446 | |
447 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
448 UnsafeWrapper("Unsafe_SetOrderedObject"); | |
449 oop x = JNIHandles::resolve(x_h); | |
450 oop p = JNIHandles::resolve(obj); | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
451 void* addr = index_oop_from_field_offset_long(p, offset); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
452 OrderAccess::release(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
453 if (UseCompressedOops) { |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
454 oop_store((narrowOop*)addr, x); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
455 } else { |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
456 oop_store((oop*)addr, x); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
457 } |
0 | 458 OrderAccess::fence(); |
459 UNSAFE_END | |
460 | |
461 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) | |
462 UnsafeWrapper("Unsafe_SetOrderedLong"); | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
463 #if defined(SPARC) || defined(X86) |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
464 // Sparc and X86 have atomic jlong (8 bytes) instructions |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
465 SET_FIELD_VOLATILE(obj, offset, jlong, x); |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
466 #else |
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
467 // Keep old code for platforms which may not have atomic long (8 bytes) instructions |
0 | 468 { |
469 if (VM_Version::supports_cx8()) { | |
470 SET_FIELD_VOLATILE(obj, offset, jlong, x); | |
471 } | |
472 else { | |
473 Handle p (THREAD, JNIHandles::resolve(obj)); | |
474 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
475 ObjectLocker ol(p, THREAD); | |
476 *addr = x; | |
477 } | |
478 } | |
2114
4fc084dac61e
7009756: volatile variables could be broken throw reflection API
kvn
parents:
1972
diff
changeset
|
479 #endif |
0 | 480 UNSAFE_END |
481 | |
482 ////// Data in the C heap. | |
483 | |
484 // Note: These do not throw NullPointerException for bad pointers. | |
485 // They just crash. Only a oop base pointer can generate a NullPointerException. | |
486 // | |
487 #define DEFINE_GETSETNATIVE(java_type, Type, native_type) \ | |
488 \ | |
489 UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) \ | |
490 UnsafeWrapper("Unsafe_GetNative"#Type); \ | |
491 void* p = addr_from_java(addr); \ | |
492 JavaThread* t = JavaThread::current(); \ | |
493 t->set_doing_unsafe_access(true); \ | |
494 java_type x = *(volatile native_type*)p; \ | |
495 t->set_doing_unsafe_access(false); \ | |
496 return x; \ | |
497 UNSAFE_END \ | |
498 \ | |
499 UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) \ | |
500 UnsafeWrapper("Unsafe_SetNative"#Type); \ | |
501 JavaThread* t = JavaThread::current(); \ | |
502 t->set_doing_unsafe_access(true); \ | |
503 void* p = addr_from_java(addr); \ | |
504 *(volatile native_type*)p = x; \ | |
505 t->set_doing_unsafe_access(false); \ | |
506 UNSAFE_END \ | |
507 \ | |
508 // END DEFINE_GETSETNATIVE. | |
509 | |
510 DEFINE_GETSETNATIVE(jbyte, Byte, signed char) | |
511 DEFINE_GETSETNATIVE(jshort, Short, signed short); | |
512 DEFINE_GETSETNATIVE(jchar, Char, unsigned short); | |
513 DEFINE_GETSETNATIVE(jint, Int, jint); | |
514 // no long -- handled specially | |
515 DEFINE_GETSETNATIVE(jfloat, Float, float); | |
516 DEFINE_GETSETNATIVE(jdouble, Double, double); | |
517 | |
518 #undef DEFINE_GETSETNATIVE | |
519 | |
520 UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) | |
521 UnsafeWrapper("Unsafe_GetNativeLong"); | |
522 JavaThread* t = JavaThread::current(); | |
523 // We do it this way to avoid problems with access to heap using 64 | |
524 // bit loads, as jlong in heap could be not 64-bit aligned, and on | |
525 // some CPUs (SPARC) it leads to SIGBUS. | |
526 t->set_doing_unsafe_access(true); | |
527 void* p = addr_from_java(addr); | |
528 jlong x; | |
529 if (((intptr_t)p & 7) == 0) { | |
530 // jlong is aligned, do a volatile access | |
531 x = *(volatile jlong*)p; | |
532 } else { | |
533 jlong_accessor acc; | |
534 acc.words[0] = ((volatile jint*)p)[0]; | |
535 acc.words[1] = ((volatile jint*)p)[1]; | |
536 x = acc.long_value; | |
537 } | |
538 t->set_doing_unsafe_access(false); | |
539 return x; | |
540 UNSAFE_END | |
541 | |
542 UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) | |
543 UnsafeWrapper("Unsafe_SetNativeLong"); | |
544 JavaThread* t = JavaThread::current(); | |
545 // see comment for Unsafe_GetNativeLong | |
546 t->set_doing_unsafe_access(true); | |
547 void* p = addr_from_java(addr); | |
548 if (((intptr_t)p & 7) == 0) { | |
549 // jlong is aligned, do a volatile access | |
550 *(volatile jlong*)p = x; | |
551 } else { | |
552 jlong_accessor acc; | |
553 acc.long_value = x; | |
554 ((volatile jint*)p)[0] = acc.words[0]; | |
555 ((volatile jint*)p)[1] = acc.words[1]; | |
556 } | |
557 t->set_doing_unsafe_access(false); | |
558 UNSAFE_END | |
559 | |
560 | |
561 UNSAFE_ENTRY(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) | |
562 UnsafeWrapper("Unsafe_GetNativeAddress"); | |
563 void* p = addr_from_java(addr); | |
564 return addr_to_java(*(void**)p); | |
565 UNSAFE_END | |
566 | |
567 UNSAFE_ENTRY(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) | |
568 UnsafeWrapper("Unsafe_SetNativeAddress"); | |
569 void* p = addr_from_java(addr); | |
570 *(void**)p = addr_from_java(x); | |
571 UNSAFE_END | |
572 | |
573 | |
574 ////// Allocation requests | |
575 | |
576 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) | |
577 UnsafeWrapper("Unsafe_AllocateInstance"); | |
578 { | |
579 ThreadToNativeFromVM ttnfv(thread); | |
580 return env->AllocObject(cls); | |
581 } | |
582 UNSAFE_END | |
583 | |
584 UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory(JNIEnv *env, jobject unsafe, jlong size)) | |
585 UnsafeWrapper("Unsafe_AllocateMemory"); | |
586 size_t sz = (size_t)size; | |
587 if (sz != (julong)size || size < 0) { | |
588 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
589 } | |
590 if (sz == 0) { | |
591 return 0; | |
592 } | |
593 sz = round_to(sz, HeapWordSize); | |
594 void* x = os::malloc(sz); | |
595 if (x == NULL) { | |
596 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); | |
597 } | |
598 //Copy::fill_to_words((HeapWord*)x, sz / HeapWordSize); | |
599 return addr_to_java(x); | |
600 UNSAFE_END | |
601 | |
602 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) | |
603 UnsafeWrapper("Unsafe_ReallocateMemory"); | |
604 void* p = addr_from_java(addr); | |
605 size_t sz = (size_t)size; | |
606 if (sz != (julong)size || size < 0) { | |
607 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
608 } | |
609 if (sz == 0) { | |
610 os::free(p); | |
611 return 0; | |
612 } | |
613 sz = round_to(sz, HeapWordSize); | |
614 void* x = (p == NULL) ? os::malloc(sz) : os::realloc(p, sz); | |
615 if (x == NULL) { | |
616 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); | |
617 } | |
618 return addr_to_java(x); | |
619 UNSAFE_END | |
620 | |
621 UNSAFE_ENTRY(void, Unsafe_FreeMemory(JNIEnv *env, jobject unsafe, jlong addr)) | |
622 UnsafeWrapper("Unsafe_FreeMemory"); | |
623 void* p = addr_from_java(addr); | |
624 if (p == NULL) { | |
625 return; | |
626 } | |
627 os::free(p); | |
628 UNSAFE_END | |
629 | |
630 UNSAFE_ENTRY(void, Unsafe_SetMemory(JNIEnv *env, jobject unsafe, jlong addr, jlong size, jbyte value)) | |
631 UnsafeWrapper("Unsafe_SetMemory"); | |
632 size_t sz = (size_t)size; | |
633 if (sz != (julong)size || size < 0) { | |
634 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
635 } | |
636 char* p = (char*) addr_from_java(addr); | |
637 Copy::fill_to_memory_atomic(p, sz, value); | |
638 UNSAFE_END | |
639 | |
640 UNSAFE_ENTRY(void, Unsafe_SetMemory2(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) | |
641 UnsafeWrapper("Unsafe_SetMemory"); | |
642 size_t sz = (size_t)size; | |
643 if (sz != (julong)size || size < 0) { | |
644 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
645 } | |
646 oop base = JNIHandles::resolve(obj); | |
647 void* p = index_oop_from_field_offset_long(base, offset); | |
648 Copy::fill_to_memory_atomic(p, sz, value); | |
649 UNSAFE_END | |
650 | |
651 UNSAFE_ENTRY(void, Unsafe_CopyMemory(JNIEnv *env, jobject unsafe, jlong srcAddr, jlong dstAddr, jlong size)) | |
652 UnsafeWrapper("Unsafe_CopyMemory"); | |
653 if (size == 0) { | |
654 return; | |
655 } | |
656 size_t sz = (size_t)size; | |
657 if (sz != (julong)size || size < 0) { | |
658 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
659 } | |
660 void* src = addr_from_java(srcAddr); | |
661 void* dst = addr_from_java(dstAddr); | |
662 Copy::conjoint_memory_atomic(src, dst, sz); | |
663 UNSAFE_END | |
664 | |
665 UNSAFE_ENTRY(void, Unsafe_CopyMemory2(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) | |
666 UnsafeWrapper("Unsafe_CopyMemory"); | |
667 if (size == 0) { | |
668 return; | |
669 } | |
670 size_t sz = (size_t)size; | |
671 if (sz != (julong)size || size < 0) { | |
672 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
673 } | |
674 oop srcp = JNIHandles::resolve(srcObj); | |
675 oop dstp = JNIHandles::resolve(dstObj); | |
676 if (dstp != NULL && !dstp->is_typeArray()) { | |
677 // NYI: This works only for non-oop arrays at present. | |
678 // Generalizing it would be reasonable, but requires card marking. | |
679 // Also, autoboxing a Long from 0L in copyMemory(x,y, 0L,z, n) would be bad. | |
680 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
681 } | |
682 void* src = index_oop_from_field_offset_long(srcp, srcOffset); | |
683 void* dst = index_oop_from_field_offset_long(dstp, dstOffset); | |
684 Copy::conjoint_memory_atomic(src, dst, sz); | |
685 UNSAFE_END | |
686 | |
687 | |
688 ////// Random queries | |
689 | |
690 // See comment at file start about UNSAFE_LEAF | |
691 //UNSAFE_LEAF(jint, Unsafe_AddressSize()) | |
692 UNSAFE_ENTRY(jint, Unsafe_AddressSize(JNIEnv *env, jobject unsafe)) | |
693 UnsafeWrapper("Unsafe_AddressSize"); | |
694 return sizeof(void*); | |
695 UNSAFE_END | |
696 | |
697 // See comment at file start about UNSAFE_LEAF | |
698 //UNSAFE_LEAF(jint, Unsafe_PageSize()) | |
699 UNSAFE_ENTRY(jint, Unsafe_PageSize(JNIEnv *env, jobject unsafe)) | |
700 UnsafeWrapper("Unsafe_PageSize"); | |
701 return os::vm_page_size(); | |
702 UNSAFE_END | |
703 | |
704 jint find_field_offset(jobject field, int must_be_static, TRAPS) { | |
705 if (field == NULL) { | |
706 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
707 } | |
708 | |
709 oop reflected = JNIHandles::resolve_non_null(field); | |
710 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
711 klassOop k = java_lang_Class::as_klassOop(mirror); | |
712 int slot = java_lang_reflect_Field::slot(reflected); | |
713 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
714 | |
715 if (must_be_static >= 0) { | |
716 int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0); | |
717 if (must_be_static != really_is_static) { | |
718 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
719 } | |
720 } | |
721 | |
3938 | 722 int offset = instanceKlass::cast(k)->field_offset(slot); |
0 | 723 return field_offset_from_byte_offset(offset); |
724 } | |
725 | |
726 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
727 UnsafeWrapper("Unsafe_ObjectFieldOffset"); | |
728 return find_field_offset(field, 0, THREAD); | |
729 UNSAFE_END | |
730 | |
731 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
732 UnsafeWrapper("Unsafe_StaticFieldOffset"); | |
733 return find_field_offset(field, 1, THREAD); | |
734 UNSAFE_END | |
735 | |
736 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromField(JNIEnv *env, jobject unsafe, jobject field)) | |
737 UnsafeWrapper("Unsafe_StaticFieldBase"); | |
738 // Note: In this VM implementation, a field address is always a short | |
739 // offset from the base of a a klass metaobject. Thus, the full dynamic | |
740 // range of the return type is never used. However, some implementations | |
741 // might put the static field inside an array shared by many classes, | |
742 // or even at a fixed address, in which case the address could be quite | |
743 // large. In that last case, this function would return NULL, since | |
744 // the address would operate alone, without any base pointer. | |
745 | |
746 if (field == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); | |
747 | |
748 oop reflected = JNIHandles::resolve_non_null(field); | |
749 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
750 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
751 | |
752 if ((modifiers & JVM_ACC_STATIC) == 0) { | |
753 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
754 } | |
755 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2316
diff
changeset
|
756 return JNIHandles::make_local(env, mirror); |
0 | 757 UNSAFE_END |
758 | |
759 //@deprecated | |
760 UNSAFE_ENTRY(jint, Unsafe_FieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
761 UnsafeWrapper("Unsafe_FieldOffset"); | |
762 // tries (but fails) to be polymorphic between static and non-static: | |
763 jlong offset = find_field_offset(field, -1, THREAD); | |
764 guarantee(offset == (jint)offset, "offset fits in 32 bits"); | |
765 return (jint)offset; | |
766 UNSAFE_END | |
767 | |
768 //@deprecated | |
769 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromClass(JNIEnv *env, jobject unsafe, jobject clazz)) | |
770 UnsafeWrapper("Unsafe_StaticFieldBase"); | |
771 if (clazz == NULL) { | |
772 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
773 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2316
diff
changeset
|
774 return JNIHandles::make_local(env, JNIHandles::resolve_non_null(clazz)); |
0 | 775 UNSAFE_END |
776 | |
777 UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz)) | |
778 UnsafeWrapper("Unsafe_EnsureClassInitialized"); | |
779 if (clazz == NULL) { | |
780 THROW(vmSymbols::java_lang_NullPointerException()); | |
781 } | |
782 oop mirror = JNIHandles::resolve_non_null(clazz); | |
783 instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(mirror)); | |
784 if (k != NULL) { | |
785 k->initialize(CHECK); | |
786 } | |
787 UNSAFE_END | |
788 | |
789 static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) { | |
790 if (acls == NULL) { | |
791 THROW(vmSymbols::java_lang_NullPointerException()); | |
792 } | |
793 oop mirror = JNIHandles::resolve_non_null(acls); | |
794 klassOop k = java_lang_Class::as_klassOop(mirror); | |
795 if (k == NULL || !k->klass_part()->oop_is_array()) { | |
796 THROW(vmSymbols::java_lang_InvalidClassException()); | |
797 } else if (k->klass_part()->oop_is_objArray()) { | |
798 base = arrayOopDesc::base_offset_in_bytes(T_OBJECT); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
799 scale = heapOopSize; |
0 | 800 } else if (k->klass_part()->oop_is_typeArray()) { |
801 typeArrayKlass* tak = typeArrayKlass::cast(k); | |
802 base = tak->array_header_in_bytes(); | |
803 assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok"); | |
804 scale = (1 << tak->log2_element_size()); | |
805 } else { | |
806 ShouldNotReachHere(); | |
807 } | |
808 } | |
809 | |
810 UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls)) | |
811 UnsafeWrapper("Unsafe_ArrayBaseOffset"); | |
812 int base, scale; | |
813 getBaseAndScale(base, scale, acls, CHECK_0); | |
814 return field_offset_from_byte_offset(base); | |
815 UNSAFE_END | |
816 | |
817 | |
818 UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls)) | |
819 UnsafeWrapper("Unsafe_ArrayIndexScale"); | |
820 int base, scale; | |
821 getBaseAndScale(base, scale, acls, CHECK_0); | |
822 // This VM packs both fields and array elements down to the byte. | |
823 // But watch out: If this changes, so that array references for | |
824 // a given primitive type (say, T_BOOLEAN) use different memory units | |
825 // than fields, this method MUST return zero for such arrays. | |
826 // For example, the VM used to store sub-word sized fields in full | |
827 // words in the object layout, so that accessors like getByte(Object,int) | |
828 // did not really do what one might expect for arrays. Therefore, | |
829 // this function used to report a zero scale factor, so that the user | |
830 // would know not to attempt to access sub-word array elements. | |
831 // // Code for unpacked fields: | |
832 // if (scale < wordSize) return 0; | |
833 | |
834 // The following allows for a pretty general fieldOffset cookie scheme, | |
835 // but requires it to be linear in byte offset. | |
836 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); | |
837 UNSAFE_END | |
838 | |
839 | |
840 static inline void throw_new(JNIEnv *env, const char *ename) { | |
841 char buf[100]; | |
842 strcpy(buf, "java/lang/"); | |
843 strcat(buf, ename); | |
844 jclass cls = env->FindClass(buf); | |
845 char* msg = NULL; | |
846 env->ThrowNew(cls, msg); | |
847 } | |
848 | |
849 static jclass Unsafe_DefineClass(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) { | |
850 { | |
851 // Code lifted from JDK 1.3 ClassLoader.c | |
852 | |
853 jbyte *body; | |
854 char *utfName; | |
855 jclass result = 0; | |
856 char buf[128]; | |
857 | |
858 if (UsePerfData) { | |
859 ClassLoader::unsafe_defineClassCallCounter()->inc(); | |
860 } | |
861 | |
862 if (data == NULL) { | |
863 throw_new(env, "NullPointerException"); | |
864 return 0; | |
865 } | |
866 | |
867 /* Work around 4153825. malloc crashes on Solaris when passed a | |
868 * negative size. | |
869 */ | |
870 if (length < 0) { | |
871 throw_new(env, "ArrayIndexOutOfBoundsException"); | |
872 return 0; | |
873 } | |
874 | |
875 body = NEW_C_HEAP_ARRAY(jbyte, length); | |
876 | |
877 if (body == 0) { | |
878 throw_new(env, "OutOfMemoryError"); | |
879 return 0; | |
880 } | |
881 | |
882 env->GetByteArrayRegion(data, offset, length, body); | |
883 | |
884 if (env->ExceptionOccurred()) | |
885 goto free_body; | |
886 | |
887 if (name != NULL) { | |
888 uint len = env->GetStringUTFLength(name); | |
889 int unicode_len = env->GetStringLength(name); | |
890 if (len >= sizeof(buf)) { | |
891 utfName = NEW_C_HEAP_ARRAY(char, len + 1); | |
892 if (utfName == NULL) { | |
893 throw_new(env, "OutOfMemoryError"); | |
894 goto free_body; | |
895 } | |
896 } else { | |
897 utfName = buf; | |
898 } | |
899 env->GetStringUTFRegion(name, 0, unicode_len, utfName); | |
900 //VerifyFixClassname(utfName); | |
901 for (uint i = 0; i < len; i++) { | |
902 if (utfName[i] == '.') utfName[i] = '/'; | |
903 } | |
904 } else { | |
905 utfName = NULL; | |
906 } | |
907 | |
908 result = JVM_DefineClass(env, utfName, loader, body, length, pd); | |
909 | |
910 if (utfName && utfName != buf) | |
911 FREE_C_HEAP_ARRAY(char, utfName); | |
912 | |
913 free_body: | |
914 FREE_C_HEAP_ARRAY(jbyte, body); | |
915 return result; | |
916 } | |
917 } | |
918 | |
919 | |
920 UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length)) | |
921 UnsafeWrapper("Unsafe_DefineClass"); | |
922 { | |
923 ThreadToNativeFromVM ttnfv(thread); | |
924 | |
925 int depthFromDefineClass0 = 1; | |
926 jclass caller = JVM_GetCallerClass(env, depthFromDefineClass0); | |
927 jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller); | |
928 jobject pd = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller); | |
929 | |
930 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd); | |
931 } | |
932 UNSAFE_END | |
933 | |
934 | |
935 UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd)) | |
936 UnsafeWrapper("Unsafe_DefineClass"); | |
937 { | |
938 ThreadToNativeFromVM ttnfv(thread); | |
939 | |
940 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd); | |
941 } | |
942 UNSAFE_END | |
943 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
944 #define DAC_Args CLS"[B["OBJ |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
945 // define a class but do not make it known to the class loader or system dictionary |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
946 // - host_class: supplies context for linkage, access control, protection domain, and class loader |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
947 // - data: bytes of a class file, a raw memory address (length gives the number of bytes) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
948 // - cp_patches: where non-null entries exist, they replace corresponding CP entries in data |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
949 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
950 // When you load an anonymous class U, it works as if you changed its name just before loading, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
951 // to a name that you will never use again. Since the name is lost, no other class can directly |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
952 // link to any member of U. Just after U is loaded, the only way to use it is reflectively, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
953 // through java.lang.Class methods like Class.newInstance. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
954 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
955 // Access checks for linkage sites within U continue to follow the same rules as for named classes. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
956 // The package of an anonymous class is given by the package qualifier on the name under which it was loaded. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
957 // An anonymous class also has special privileges to access any member of its host class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
958 // This is the main reason why this loading operation is unsafe. The purpose of this is to |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
959 // allow language implementations to simulate "open classes"; a host class in effect gets |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
960 // new code when an anonymous class is loaded alongside it. A less convenient but more |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
961 // standard way to do this is with reflection, which can also be set to ignore access |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
962 // restrictions. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
963 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
964 // Access into an anonymous class is possible only through reflection. Therefore, there |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
965 // are no special access rules for calling into an anonymous class. The relaxed access |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
966 // rule for the host class is applied in the opposite direction: A host class reflectively |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
967 // access one of its anonymous classes. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
968 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
969 // If you load the same bytecodes twice, you get two different classes. You can reload |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
970 // the same bytecodes with or without varying CP patches. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
971 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
972 // By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
973 // The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is). |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
974 // The CONSTANT_Class entry for that name can be patched to refer directly to U1. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
975 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
976 // This allows, for example, U2 to use U1 as a superclass or super-interface, or as |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
977 // an outer class (so that U2 is an anonymous inner class of anonymous U1). |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
978 // It is not possible for a named class, or an older anonymous class, to refer by |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
979 // name (via its CP) to a newer anonymous class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
980 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
981 // CP patching may also be used to modify (i.e., hack) the names of methods, classes, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
982 // or type descriptors used in the loaded anonymous class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
983 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
984 // Finally, CP patching may be used to introduce "live" objects into the constant pool, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
985 // instead of "dead" strings. A compiled statement like println((Object)"hello") can |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
986 // be changed to println(greeting), where greeting is an arbitrary object created before |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
987 // the anonymous class is loaded. This is useful in dynamic languages, in which |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
988 // various kinds of metaobjects must be introduced as constants into bytecode. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
989 // Note the cast (Object), which tells the verifier to expect an arbitrary object, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
990 // not just a literal string. For such ldc instructions, the verifier uses the |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
991 // type Object instead of String, if the loaded constant is not in fact a String. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
992 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
993 static oop |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
994 Unsafe_DefineAnonymousClass_impl(JNIEnv *env, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
995 jclass host_class, jbyteArray data, jobjectArray cp_patches_jh, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
996 HeapWord* *temp_alloc, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
997 TRAPS) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
998 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
999 if (UsePerfData) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1000 ClassLoader::unsafe_defineClassCallCounter()->inc(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1001 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1002 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1003 if (data == NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1004 THROW_0(vmSymbols::java_lang_NullPointerException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1005 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1006 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1007 jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1008 jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1009 HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1010 if (body == NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1011 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1012 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1013 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1014 // caller responsible to free it: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1015 (*temp_alloc) = body; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1016 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1017 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1018 jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1019 Copy::conjoint_words((HeapWord*) array_base, body, word_length); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1020 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1021 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1022 u1* class_bytes = (u1*) body; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1023 int class_bytes_length = (int) length; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1024 if (class_bytes_length < 0) class_bytes_length = 0; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1025 if (class_bytes == NULL |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1026 || host_class == NULL |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1027 || length != class_bytes_length) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1028 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1029 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1030 objArrayHandle cp_patches_h; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1031 if (cp_patches_jh != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1032 oop p = JNIHandles::resolve_non_null(cp_patches_jh); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1033 if (!p->is_objArray()) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1034 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1035 cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1036 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1037 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1038 KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class))); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1039 const char* host_source = host_klass->external_name(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1040 Handle host_loader(THREAD, host_klass->class_loader()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1041 Handle host_domain(THREAD, host_klass->protection_domain()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1042 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1043 GrowableArray<Handle>* cp_patches = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1044 if (cp_patches_h.not_null()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1045 int alen = cp_patches_h->length(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1046 for (int i = alen-1; i >= 0; i--) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1047 oop p = cp_patches_h->obj_at(i); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1048 if (p != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1049 Handle patch(THREAD, p); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1050 if (cp_patches == NULL) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1051 cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1052 cp_patches->at_put(i, patch); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1053 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1054 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1055 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1056 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1057 ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1058 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1059 instanceKlassHandle anon_klass; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1060 { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2114
diff
changeset
|
1061 Symbol* no_class_name = NULL; |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1062 klassOop anonk = SystemDictionary::parse_stream(no_class_name, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1063 host_loader, host_domain, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1064 &st, host_klass, cp_patches, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1065 CHECK_NULL); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1066 if (anonk == NULL) return NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1067 anon_klass = instanceKlassHandle(THREAD, anonk); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1068 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1069 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1070 // let caller initialize it as needed... |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1071 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1072 return anon_klass->java_mirror(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1073 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1074 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1075 UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh)) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1076 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1077 UnsafeWrapper("Unsafe_DefineAnonymousClass"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1078 ResourceMark rm(THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1079 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1080 HeapWord* temp_alloc = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1081 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1082 jobject res_jh = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1083 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1084 { oop res_oop = Unsafe_DefineAnonymousClass_impl(env, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1085 host_class, data, cp_patches_jh, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1086 &temp_alloc, THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1087 if (res_oop != NULL) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1088 res_jh = JNIHandles::make_local(env, res_oop); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1089 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1090 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1091 // try/finally clause: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1092 if (temp_alloc != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1093 FREE_C_HEAP_ARRAY(HeapWord, temp_alloc); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1094 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1095 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1096 return (jclass) res_jh; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1097 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1098 UNSAFE_END |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1099 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1100 |
0 | 1101 |
1102 UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1103 UnsafeWrapper("Unsafe_MonitorEnter"); | |
1104 { | |
1105 if (jobj == NULL) { | |
1106 THROW(vmSymbols::java_lang_NullPointerException()); | |
1107 } | |
1108 Handle obj(thread, JNIHandles::resolve_non_null(jobj)); | |
1109 ObjectSynchronizer::jni_enter(obj, CHECK); | |
1110 } | |
1111 UNSAFE_END | |
1112 | |
1113 | |
1114 UNSAFE_ENTRY(jboolean, Unsafe_TryMonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1115 UnsafeWrapper("Unsafe_TryMonitorEnter"); | |
1116 { | |
1117 if (jobj == NULL) { | |
1118 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); | |
1119 } | |
1120 Handle obj(thread, JNIHandles::resolve_non_null(jobj)); | |
1121 bool res = ObjectSynchronizer::jni_try_enter(obj, CHECK_0); | |
1122 return (res ? JNI_TRUE : JNI_FALSE); | |
1123 } | |
1124 UNSAFE_END | |
1125 | |
1126 | |
1127 UNSAFE_ENTRY(void, Unsafe_MonitorExit(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1128 UnsafeWrapper("Unsafe_MonitorExit"); | |
1129 { | |
1130 if (jobj == NULL) { | |
1131 THROW(vmSymbols::java_lang_NullPointerException()); | |
1132 } | |
1133 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj)); | |
1134 ObjectSynchronizer::jni_exit(obj(), CHECK); | |
1135 } | |
1136 UNSAFE_END | |
1137 | |
1138 | |
1139 UNSAFE_ENTRY(void, Unsafe_ThrowException(JNIEnv *env, jobject unsafe, jthrowable thr)) | |
1140 UnsafeWrapper("Unsafe_ThrowException"); | |
1141 { | |
1142 ThreadToNativeFromVM ttnfv(thread); | |
1143 env->Throw(thr); | |
1144 } | |
1145 UNSAFE_END | |
1146 | |
1147 // JSR166 ------------------------------------------------------------------ | |
1148 | |
1149 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) | |
1150 UnsafeWrapper("Unsafe_CompareAndSwapObject"); | |
1151 oop x = JNIHandles::resolve(x_h); | |
1152 oop e = JNIHandles::resolve(e_h); | |
1153 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1154 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1155 if (UseCompressedOops) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1156 update_barrier_set_pre((narrowOop*)addr, e); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1157 } else { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1158 update_barrier_set_pre((oop*)addr, e); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1159 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1160 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1161 jboolean success = (res == e); |
0 | 1162 if (success) |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1163 update_barrier_set((void*)addr, x); |
0 | 1164 return success; |
1165 UNSAFE_END | |
1166 | |
1167 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) | |
1168 UnsafeWrapper("Unsafe_CompareAndSwapInt"); | |
1169 oop p = JNIHandles::resolve(obj); | |
1170 jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); | |
1171 return (jint)(Atomic::cmpxchg(x, addr, e)) == e; | |
1172 UNSAFE_END | |
1173 | |
1174 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) | |
1175 UnsafeWrapper("Unsafe_CompareAndSwapLong"); | |
1176 Handle p (THREAD, JNIHandles::resolve(obj)); | |
1177 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
1178 if (VM_Version::supports_cx8()) | |
1179 return (jlong)(Atomic::cmpxchg(x, addr, e)) == e; | |
1180 else { | |
1181 jboolean success = false; | |
1182 ObjectLocker ol(p, THREAD); | |
1183 if (*addr == e) { *addr = x; success = true; } | |
1184 return success; | |
1185 } | |
1186 UNSAFE_END | |
1187 | |
1188 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) | |
1189 UnsafeWrapper("Unsafe_Park"); | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1190 HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time); |
0 | 1191 JavaThreadParkedState jtps(thread, time != 0); |
1192 thread->parker()->park(isAbsolute != 0, time); | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1193 HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker()); |
0 | 1194 UNSAFE_END |
1195 | |
1196 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) | |
1197 UnsafeWrapper("Unsafe_Unpark"); | |
1198 Parker* p = NULL; | |
1199 if (jthread != NULL) { | |
1200 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
1201 if (java_thread != NULL) { | |
1202 jlong lp = java_lang_Thread::park_event(java_thread); | |
1203 if (lp != 0) { | |
1204 // This cast is OK even though the jlong might have been read | |
1205 // non-atomically on 32bit systems, since there, one word will | |
1206 // always be zero anyway and the value set is always the same | |
1207 p = (Parker*)addr_from_java(lp); | |
1208 } else { | |
1209 // Grab lock if apparently null or using older version of library | |
1210 MutexLocker mu(Threads_lock); | |
1211 java_thread = JNIHandles::resolve_non_null(jthread); | |
1212 if (java_thread != NULL) { | |
1213 JavaThread* thr = java_lang_Thread::thread(java_thread); | |
1214 if (thr != NULL) { | |
1215 p = thr->parker(); | |
1216 if (p != NULL) { // Bind to Java thread for next time. | |
1217 java_lang_Thread::set_park_event(java_thread, addr_to_java(p)); | |
1218 } | |
1219 } | |
1220 } | |
1221 } | |
1222 } | |
1223 } | |
1224 if (p != NULL) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1225 HS_DTRACE_PROBE1(hotspot, thread__unpark, p); |
0 | 1226 p->unpark(); |
1227 } | |
1228 UNSAFE_END | |
1229 | |
1230 UNSAFE_ENTRY(jint, Unsafe_Loadavg(JNIEnv *env, jobject unsafe, jdoubleArray loadavg, jint nelem)) | |
1231 UnsafeWrapper("Unsafe_Loadavg"); | |
1232 const int max_nelem = 3; | |
1233 double la[max_nelem]; | |
1234 jint ret; | |
1235 | |
1236 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(loadavg)); | |
1237 assert(a->is_typeArray(), "must be type array"); | |
1238 | |
1239 if (nelem < 0 || nelem > max_nelem || a->length() < nelem) { | |
1240 ThreadToNativeFromVM ttnfv(thread); | |
1241 throw_new(env, "ArrayIndexOutOfBoundsException"); | |
1242 return -1; | |
1243 } | |
1244 | |
1245 ret = os::loadavg(la, nelem); | |
1246 if (ret == -1) return -1; | |
1247 | |
1248 // if successful, ret is the number of samples actually retrieved. | |
1249 assert(ret >= 0 && ret <= max_nelem, "Unexpected loadavg return value"); | |
1250 switch(ret) { | |
1251 case 3: a->double_at_put(2, (jdouble)la[2]); // fall through | |
1252 case 2: a->double_at_put(1, (jdouble)la[1]); // fall through | |
1253 case 1: a->double_at_put(0, (jdouble)la[0]); break; | |
1254 } | |
1255 return ret; | |
1256 UNSAFE_END | |
1257 | |
1258 UNSAFE_ENTRY(void, Unsafe_PrefetchRead(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) | |
1259 UnsafeWrapper("Unsafe_PrefetchRead"); | |
1260 oop p = JNIHandles::resolve(obj); | |
1261 void* addr = index_oop_from_field_offset_long(p, 0); | |
1262 Prefetch::read(addr, (intx)offset); | |
1263 UNSAFE_END | |
1264 | |
1265 UNSAFE_ENTRY(void, Unsafe_PrefetchWrite(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) | |
1266 UnsafeWrapper("Unsafe_PrefetchWrite"); | |
1267 oop p = JNIHandles::resolve(obj); | |
1268 void* addr = index_oop_from_field_offset_long(p, 0); | |
1269 Prefetch::write(addr, (intx)offset); | |
1270 UNSAFE_END | |
1271 | |
1272 | |
1273 /// JVM_RegisterUnsafeMethods | |
1274 | |
1275 #define ADR "J" | |
1276 | |
1277 #define LANG "Ljava/lang/" | |
1278 | |
1279 #define OBJ LANG"Object;" | |
1280 #define CLS LANG"Class;" | |
1281 #define CTR LANG"reflect/Constructor;" | |
1282 #define FLD LANG"reflect/Field;" | |
1283 #define MTH LANG"reflect/Method;" | |
1284 #define THR LANG"Throwable;" | |
1285 | |
1286 #define DC0_Args LANG"String;[BII" | |
1287 #define DC1_Args DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;" | |
1288 | |
1289 #define CC (char*) /*cast a literal from (const char*)*/ | |
1290 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) | |
1291 | |
1292 // define deprecated accessors for compabitility with 1.4.0 | |
1293 #define DECLARE_GETSETOOP_140(Boolean, Z) \ | |
1294 {CC"get"#Boolean, CC"("OBJ"I)"#Z, FN_PTR(Unsafe_Get##Boolean##140)}, \ | |
1295 {CC"put"#Boolean, CC"("OBJ"I"#Z")V", FN_PTR(Unsafe_Set##Boolean##140)} | |
1296 | |
1297 // Note: In 1.4.1, getObject and kin take both int and long offsets. | |
1298 #define DECLARE_GETSETOOP_141(Boolean, Z) \ | |
1299 {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ | |
1300 {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)} | |
1301 | |
1302 // Note: In 1.5.0, there are volatile versions too | |
1303 #define DECLARE_GETSETOOP(Boolean, Z) \ | |
1304 {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ | |
1305 {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)}, \ | |
1306 {CC"get"#Boolean"Volatile", CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean##Volatile)}, \ | |
1307 {CC"put"#Boolean"Volatile", CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean##Volatile)} | |
1308 | |
1309 | |
1310 #define DECLARE_GETSETNATIVE(Byte, B) \ | |
1311 {CC"get"#Byte, CC"("ADR")"#B, FN_PTR(Unsafe_GetNative##Byte)}, \ | |
1312 {CC"put"#Byte, CC"("ADR#B")V", FN_PTR(Unsafe_SetNative##Byte)} | |
1313 | |
1314 | |
1315 | |
1316 // %%% These are temporarily supported until the SDK sources | |
1317 // contain the necessarily updated Unsafe.java. | |
1318 static JNINativeMethod methods_140[] = { | |
1319 | |
1320 {CC"getObject", CC"("OBJ"I)"OBJ"", FN_PTR(Unsafe_GetObject140)}, | |
1321 {CC"putObject", CC"("OBJ"I"OBJ")V", FN_PTR(Unsafe_SetObject140)}, | |
1322 | |
1323 DECLARE_GETSETOOP_140(Boolean, Z), | |
1324 DECLARE_GETSETOOP_140(Byte, B), | |
1325 DECLARE_GETSETOOP_140(Short, S), | |
1326 DECLARE_GETSETOOP_140(Char, C), | |
1327 DECLARE_GETSETOOP_140(Int, I), | |
1328 DECLARE_GETSETOOP_140(Long, J), | |
1329 DECLARE_GETSETOOP_140(Float, F), | |
1330 DECLARE_GETSETOOP_140(Double, D), | |
1331 | |
1332 DECLARE_GETSETNATIVE(Byte, B), | |
1333 DECLARE_GETSETNATIVE(Short, S), | |
1334 DECLARE_GETSETNATIVE(Char, C), | |
1335 DECLARE_GETSETNATIVE(Int, I), | |
1336 DECLARE_GETSETNATIVE(Long, J), | |
1337 DECLARE_GETSETNATIVE(Float, F), | |
1338 DECLARE_GETSETNATIVE(Double, D), | |
1339 | |
1340 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1341 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1342 | |
1343 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1344 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1345 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1346 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1347 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1348 | |
1349 {CC"fieldOffset", CC"("FLD")I", FN_PTR(Unsafe_FieldOffset)}, //deprecated | |
1350 {CC"staticFieldBase", CC"("CLS")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromClass)}, //deprecated | |
1351 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1352 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1353 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1354 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1355 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1356 | |
1357 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1358 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1359 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1360 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1361 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1362 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} | |
1363 }; | |
1364 | |
1365 // These are the old methods prior to the JSR 166 changes in 1.5.0 | |
1366 static JNINativeMethod methods_141[] = { | |
1367 | |
1368 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1369 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1370 | |
1371 DECLARE_GETSETOOP_141(Boolean, Z), | |
1372 DECLARE_GETSETOOP_141(Byte, B), | |
1373 DECLARE_GETSETOOP_141(Short, S), | |
1374 DECLARE_GETSETOOP_141(Char, C), | |
1375 DECLARE_GETSETOOP_141(Int, I), | |
1376 DECLARE_GETSETOOP_141(Long, J), | |
1377 DECLARE_GETSETOOP_141(Float, F), | |
1378 DECLARE_GETSETOOP_141(Double, D), | |
1379 | |
1380 DECLARE_GETSETNATIVE(Byte, B), | |
1381 DECLARE_GETSETNATIVE(Short, S), | |
1382 DECLARE_GETSETNATIVE(Char, C), | |
1383 DECLARE_GETSETNATIVE(Int, I), | |
1384 DECLARE_GETSETNATIVE(Long, J), | |
1385 DECLARE_GETSETNATIVE(Float, F), | |
1386 DECLARE_GETSETNATIVE(Double, D), | |
1387 | |
1388 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1389 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1390 | |
1391 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1392 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1393 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1394 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1395 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1396 | |
1397 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1398 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1399 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1400 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1401 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1402 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1403 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1404 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1405 | |
1406 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1407 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1408 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1409 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1410 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1411 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} | |
1412 | |
1413 }; | |
1414 | |
1415 // These are the old methods prior to the JSR 166 changes in 1.6.0 | |
1416 static JNINativeMethod methods_15[] = { | |
1417 | |
1418 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1419 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1420 {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, | |
1421 {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, | |
1422 | |
1423 | |
1424 DECLARE_GETSETOOP(Boolean, Z), | |
1425 DECLARE_GETSETOOP(Byte, B), | |
1426 DECLARE_GETSETOOP(Short, S), | |
1427 DECLARE_GETSETOOP(Char, C), | |
1428 DECLARE_GETSETOOP(Int, I), | |
1429 DECLARE_GETSETOOP(Long, J), | |
1430 DECLARE_GETSETOOP(Float, F), | |
1431 DECLARE_GETSETOOP(Double, D), | |
1432 | |
1433 DECLARE_GETSETNATIVE(Byte, B), | |
1434 DECLARE_GETSETNATIVE(Short, S), | |
1435 DECLARE_GETSETNATIVE(Char, C), | |
1436 DECLARE_GETSETNATIVE(Int, I), | |
1437 DECLARE_GETSETNATIVE(Long, J), | |
1438 DECLARE_GETSETNATIVE(Float, F), | |
1439 DECLARE_GETSETNATIVE(Double, D), | |
1440 | |
1441 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1442 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1443 | |
1444 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1445 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1446 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1447 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1448 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1449 | |
1450 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1451 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1452 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1453 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1454 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1455 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1456 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1457 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1458 | |
1459 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1460 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1461 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1462 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1463 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1464 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, | |
1465 {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, | |
1466 {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, | |
1467 {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, | |
1468 {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, | |
1469 {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} | |
1470 | |
1471 }; | |
1472 | |
1473 // These are the correct methods, moving forward: | |
1474 static JNINativeMethod methods[] = { | |
1475 | |
1476 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1477 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1478 {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, | |
1479 {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, | |
1480 | |
1481 | |
1482 DECLARE_GETSETOOP(Boolean, Z), | |
1483 DECLARE_GETSETOOP(Byte, B), | |
1484 DECLARE_GETSETOOP(Short, S), | |
1485 DECLARE_GETSETOOP(Char, C), | |
1486 DECLARE_GETSETOOP(Int, I), | |
1487 DECLARE_GETSETOOP(Long, J), | |
1488 DECLARE_GETSETOOP(Float, F), | |
1489 DECLARE_GETSETOOP(Double, D), | |
1490 | |
1491 DECLARE_GETSETNATIVE(Byte, B), | |
1492 DECLARE_GETSETNATIVE(Short, S), | |
1493 DECLARE_GETSETNATIVE(Char, C), | |
1494 DECLARE_GETSETNATIVE(Int, I), | |
1495 DECLARE_GETSETNATIVE(Long, J), | |
1496 DECLARE_GETSETNATIVE(Float, F), | |
1497 DECLARE_GETSETNATIVE(Double, D), | |
1498 | |
1499 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1500 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1501 | |
1502 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1503 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1504 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1505 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1506 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1507 | |
1508 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1509 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1510 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1511 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1512 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1513 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1514 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1515 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1516 | |
1517 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1518 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1519 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1520 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1521 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1522 {CC"tryMonitorEnter", CC"("OBJ")Z", FN_PTR(Unsafe_TryMonitorEnter)}, | |
1523 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, | |
1524 {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, | |
1525 {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, | |
1526 {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, | |
1527 {CC"putOrderedObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetOrderedObject)}, | |
1528 {CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)}, | |
1529 {CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, | |
1530 {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, | |
1531 {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} | |
1532 | |
1533 // {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)}, | |
1534 | |
1535 // {CC"prefetchRead", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1536 // {CC"prefetchWrite", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1537 // {CC"prefetchReadStatic", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1538 // {CC"prefetchWriteStatic",CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1539 | |
1540 }; | |
1541 | |
1542 JNINativeMethod loadavg_method[] = { | |
1543 {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)} | |
1544 }; | |
1545 | |
1546 JNINativeMethod prefetch_methods[] = { | |
1547 {CC"prefetchRead", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1548 {CC"prefetchWrite", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)}, | |
1549 {CC"prefetchReadStatic", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1550 {CC"prefetchWriteStatic",CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1551 }; | |
1552 | |
1553 JNINativeMethod memcopy_methods[] = { | |
1554 {CC"copyMemory", CC"("OBJ"J"OBJ"JJ)V", FN_PTR(Unsafe_CopyMemory2)}, | |
1555 {CC"setMemory", CC"("OBJ"JJB)V", FN_PTR(Unsafe_SetMemory2)} | |
1556 }; | |
1557 | |
1558 JNINativeMethod memcopy_methods_15[] = { | |
1559 {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1560 {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)} | |
1561 }; | |
1562 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1563 JNINativeMethod anonk_methods[] = { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1564 {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)}, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1565 }; |
0 | 1566 |
1567 #undef CC | |
1568 #undef FN_PTR | |
1569 | |
1570 #undef ADR | |
1571 #undef LANG | |
1572 #undef OBJ | |
1573 #undef CLS | |
1574 #undef CTR | |
1575 #undef FLD | |
1576 #undef MTH | |
1577 #undef THR | |
1578 #undef DC0_Args | |
1579 #undef DC1_Args | |
1580 | |
1581 #undef DECLARE_GETSETOOP | |
1582 #undef DECLARE_GETSETNATIVE | |
1583 | |
1584 | |
1585 // This one function is exported, used by NativeLookup. | |
1586 // The Unsafe_xxx functions above are called only from the interpreter. | |
1587 // The optimizer looks at names and signatures to recognize | |
1588 // individual functions. | |
1589 | |
1590 JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls)) | |
1591 UnsafeWrapper("JVM_RegisterUnsafeMethods"); | |
1592 { | |
1593 ThreadToNativeFromVM ttnfv(thread); | |
1594 { | |
1595 env->RegisterNatives(unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod)); | |
1596 if (env->ExceptionOccurred()) { | |
1597 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1598 tty->print_cr("Warning: SDK 1.6 Unsafe.loadavg not found."); | |
1599 } | |
1600 env->ExceptionClear(); | |
1601 } | |
1602 } | |
1603 { | |
1604 env->RegisterNatives(unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod)); | |
1605 if (env->ExceptionOccurred()) { | |
1606 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1607 tty->print_cr("Warning: SDK 1.6 Unsafe.prefetchRead/Write not found."); | |
1608 } | |
1609 env->ExceptionClear(); | |
1610 } | |
1611 } | |
1612 { | |
1613 env->RegisterNatives(unsafecls, memcopy_methods, sizeof(memcopy_methods)/sizeof(JNINativeMethod)); | |
1614 if (env->ExceptionOccurred()) { | |
1615 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1616 tty->print_cr("Warning: SDK 1.7 Unsafe.copyMemory not found."); | |
1617 } | |
1618 env->ExceptionClear(); | |
1619 env->RegisterNatives(unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod)); | |
1620 if (env->ExceptionOccurred()) { | |
1621 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1622 tty->print_cr("Warning: SDK 1.5 Unsafe.copyMemory not found."); | |
1623 } | |
1624 env->ExceptionClear(); | |
1625 } | |
1626 } | |
1627 } | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2376
diff
changeset
|
1628 if (EnableInvokeDynamic) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1629 env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1630 if (env->ExceptionOccurred()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1631 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1632 tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found."); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1633 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1634 env->ExceptionClear(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1635 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1636 } |
0 | 1637 int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod)); |
1638 if (env->ExceptionOccurred()) { | |
1639 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1640 tty->print_cr("Warning: SDK 1.6 version of Unsafe not found."); | |
1641 } | |
1642 env->ExceptionClear(); | |
1643 // %%% For now, be backward compatible with an older class: | |
1644 status = env->RegisterNatives(unsafecls, methods_15, sizeof(methods_15)/sizeof(JNINativeMethod)); | |
1645 } | |
1646 if (env->ExceptionOccurred()) { | |
1647 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1648 tty->print_cr("Warning: SDK 1.5 version of Unsafe not found."); | |
1649 } | |
1650 env->ExceptionClear(); | |
1651 // %%% For now, be backward compatible with an older class: | |
1652 status = env->RegisterNatives(unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod)); | |
1653 } | |
1654 if (env->ExceptionOccurred()) { | |
1655 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1656 tty->print_cr("Warning: SDK 1.4.1 version of Unsafe not found."); | |
1657 } | |
1658 env->ExceptionClear(); | |
1659 // %%% For now, be backward compatible with an older class: | |
1660 status = env->RegisterNatives(unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod)); | |
1661 } | |
1662 guarantee(status == 0, "register unsafe natives"); | |
1663 } | |
1664 JVM_END |