hotspot/src/share/vm/prims/unsafe.cpp
changeset 13728 882756847a04
parent 13391 30245956af37
child 13952 e3cf184080bc
equal deleted inserted replaced
13727:caf5eb7dd4a7 13728:882756847a04
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   195     bool needs_barrier = false;
   195     bool needs_barrier = false;
   196 
   196 
   197     if (ret != NULL) {
   197     if (ret != NULL) {
   198       if (offset == java_lang_ref_Reference::referent_offset) {
   198       if (offset == java_lang_ref_Reference::referent_offset) {
   199         oop o = JNIHandles::resolve_non_null(obj);
   199         oop o = JNIHandles::resolve_non_null(obj);
   200         klassOop k = o->klass();
   200         Klass* k = o->klass();
   201         if (instanceKlass::cast(k)->reference_type() != REF_NONE) {
   201         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
   202           assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
   202           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
   203           needs_barrier = true;
   203           needs_barrier = true;
   204         }
   204         }
   205       }
   205       }
   206     }
   206     }
   207 
   207 
   253     bool needs_barrier = false;
   253     bool needs_barrier = false;
   254 
   254 
   255     if (ret != NULL) {
   255     if (ret != NULL) {
   256       if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
   256       if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
   257         oop o = JNIHandles::resolve(obj);
   257         oop o = JNIHandles::resolve(obj);
   258         klassOop k = o->klass();
   258         Klass* k = o->klass();
   259         if (instanceKlass::cast(k)->reference_type() != REF_NONE) {
   259         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
   260           assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
   260           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
   261           needs_barrier = true;
   261           needs_barrier = true;
   262         }
   262         }
   263       }
   263       }
   264     }
   264     }
   265 
   265 
   693     THROW_0(vmSymbols::java_lang_NullPointerException());
   693     THROW_0(vmSymbols::java_lang_NullPointerException());
   694   }
   694   }
   695 
   695 
   696   oop reflected   = JNIHandles::resolve_non_null(field);
   696   oop reflected   = JNIHandles::resolve_non_null(field);
   697   oop mirror      = java_lang_reflect_Field::clazz(reflected);
   697   oop mirror      = java_lang_reflect_Field::clazz(reflected);
   698   klassOop k      = java_lang_Class::as_klassOop(mirror);
   698   Klass* k      = java_lang_Class::as_Klass(mirror);
   699   int slot        = java_lang_reflect_Field::slot(reflected);
   699   int slot        = java_lang_reflect_Field::slot(reflected);
   700   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
   700   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
   701 
   701 
   702   if (must_be_static >= 0) {
   702   if (must_be_static >= 0) {
   703     int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
   703     int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
   704     if (must_be_static != really_is_static) {
   704     if (must_be_static != really_is_static) {
   705       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
   705       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
   706     }
   706     }
   707   }
   707   }
   708 
   708 
   709   int offset = instanceKlass::cast(k)->field_offset(slot);
   709   int offset = InstanceKlass::cast(k)->field_offset(slot);
   710   return field_offset_from_byte_offset(offset);
   710   return field_offset_from_byte_offset(offset);
   711 }
   711 }
   712 
   712 
   713 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
   713 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
   714   UnsafeWrapper("Unsafe_ObjectFieldOffset");
   714   UnsafeWrapper("Unsafe_ObjectFieldOffset");
   766   if (clazz == NULL) {
   766   if (clazz == NULL) {
   767     THROW(vmSymbols::java_lang_NullPointerException());
   767     THROW(vmSymbols::java_lang_NullPointerException());
   768   }
   768   }
   769   oop mirror = JNIHandles::resolve_non_null(clazz);
   769   oop mirror = JNIHandles::resolve_non_null(clazz);
   770 
   770 
   771   klassOop klass = java_lang_Class::as_klassOop(mirror);
   771   Klass* klass = java_lang_Class::as_Klass(mirror);
   772   if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
   772   if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
   773     instanceKlass* k = instanceKlass::cast(klass);
   773     InstanceKlass* k = InstanceKlass::cast(klass);
   774     k->initialize(CHECK);
   774     k->initialize(CHECK);
   775   }
   775   }
   776 }
   776 }
   777 UNSAFE_END
   777 UNSAFE_END
   778 
   778 
   780   UnsafeWrapper("Unsafe_ShouldBeInitialized");
   780   UnsafeWrapper("Unsafe_ShouldBeInitialized");
   781   if (clazz == NULL) {
   781   if (clazz == NULL) {
   782     THROW_(vmSymbols::java_lang_NullPointerException(), false);
   782     THROW_(vmSymbols::java_lang_NullPointerException(), false);
   783   }
   783   }
   784   oop mirror = JNIHandles::resolve_non_null(clazz);
   784   oop mirror = JNIHandles::resolve_non_null(clazz);
   785   klassOop klass = java_lang_Class::as_klassOop(mirror);
   785   Klass* klass = java_lang_Class::as_Klass(mirror);
   786   if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
   786   if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
   787     return true;
   787     return true;
   788   }
   788   }
   789   return false;
   789   return false;
   790 }
   790 }
   793 static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) {
   793 static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) {
   794   if (acls == NULL) {
   794   if (acls == NULL) {
   795     THROW(vmSymbols::java_lang_NullPointerException());
   795     THROW(vmSymbols::java_lang_NullPointerException());
   796   }
   796   }
   797   oop      mirror = JNIHandles::resolve_non_null(acls);
   797   oop      mirror = JNIHandles::resolve_non_null(acls);
   798   klassOop k      = java_lang_Class::as_klassOop(mirror);
   798   Klass* k      = java_lang_Class::as_Klass(mirror);
   799   if (k == NULL || !k->klass_part()->oop_is_array()) {
   799   if (k == NULL || !k->oop_is_array()) {
   800     THROW(vmSymbols::java_lang_InvalidClassException());
   800     THROW(vmSymbols::java_lang_InvalidClassException());
   801   } else if (k->klass_part()->oop_is_objArray()) {
   801   } else if (k->oop_is_objArray()) {
   802     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
   802     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
   803     scale = heapOopSize;
   803     scale = heapOopSize;
   804   } else if (k->klass_part()->oop_is_typeArray()) {
   804   } else if (k->oop_is_typeArray()) {
   805     typeArrayKlass* tak = typeArrayKlass::cast(k);
   805     typeArrayKlass* tak = typeArrayKlass::cast(k);
   806     base  = tak->array_header_in_bytes();
   806     base  = tak->array_header_in_bytes();
   807     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
   807     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
   808     scale = (1 << tak->log2_element_size());
   808     scale = (1 << tak->log2_element_size());
   809   } else {
   809   } else {
  1037     if (!p->is_objArray())
  1037     if (!p->is_objArray())
  1038       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
  1038       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
  1039     cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
  1039     cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
  1040   }
  1040   }
  1041 
  1041 
  1042   KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
  1042   KlassHandle host_klass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(host_class)));
  1043   const char* host_source = host_klass->external_name();
  1043   const char* host_source = host_klass->external_name();
  1044   Handle      host_loader(THREAD, host_klass->class_loader());
  1044   Handle      host_loader(THREAD, host_klass->class_loader());
  1045   Handle      host_domain(THREAD, host_klass->protection_domain());
  1045   Handle      host_domain(THREAD, host_klass->protection_domain());
  1046 
  1046 
  1047   GrowableArray<Handle>* cp_patches = NULL;
  1047   GrowableArray<Handle>* cp_patches = NULL;
  1061   ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
  1061   ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
  1062 
  1062 
  1063   instanceKlassHandle anon_klass;
  1063   instanceKlassHandle anon_klass;
  1064   {
  1064   {
  1065     Symbol* no_class_name = NULL;
  1065     Symbol* no_class_name = NULL;
  1066     klassOop anonk = SystemDictionary::parse_stream(no_class_name,
  1066     Klass* anonk = SystemDictionary::parse_stream(no_class_name,
  1067                                                     host_loader, host_domain,
  1067                                                     host_loader, host_domain,
  1068                                                     &st, host_klass, cp_patches,
  1068                                                     &st, host_klass, cp_patches,
  1069                                                     CHECK_NULL);
  1069                                                     CHECK_NULL);
  1070     if (anonk == NULL)  return NULL;
  1070     if (anonk == NULL)  return NULL;
  1071     anon_klass = instanceKlassHandle(THREAD, anonk);
  1071     anon_klass = instanceKlassHandle(THREAD, anonk);
  1154   UnsafeWrapper("Unsafe_CompareAndSwapObject");
  1154   UnsafeWrapper("Unsafe_CompareAndSwapObject");
  1155   oop x = JNIHandles::resolve(x_h);
  1155   oop x = JNIHandles::resolve(x_h);
  1156   oop e = JNIHandles::resolve(e_h);
  1156   oop e = JNIHandles::resolve(e_h);
  1157   oop p = JNIHandles::resolve(obj);
  1157   oop p = JNIHandles::resolve(obj);
  1158   HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
  1158   HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
  1159   if (UseCompressedOops) {
  1159   oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);
  1160     update_barrier_set_pre((narrowOop*)addr, e);
       
  1161   } else {
       
  1162     update_barrier_set_pre((oop*)addr, e);
       
  1163   }
       
  1164   oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
       
  1165   jboolean success  = (res == e);
  1160   jboolean success  = (res == e);
  1166   if (success)
  1161   if (success)
  1167     update_barrier_set((void*)addr, x);
  1162     update_barrier_set((void*)addr, x);
  1168   return success;
  1163   return success;
  1169 UNSAFE_END
  1164 UNSAFE_END