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