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