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