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