< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page

        

@@ -278,10 +278,44 @@
   }
   return found;
 }
 #endif // ASSERT
 
+static void assert_and_log_unsafe_value_type_access(oop p, jlong offset, ValueKlass* vk) {
+  Klass* k = p->klass();
+
+#ifdef ASSERT
+  if (k->is_instance_klass()) {
+    assert_field_offset_sane(p, offset);
+    fieldDescriptor fd;
+    bool found = get_field_descriptor(p, offset, &fd);
+    assert(found, "value field not found");
+    assert(fd.is_flattened(), "field not flat");
+  } else if (k->is_valueArray_klass()) {
+    ValueArrayKlass* vak = ValueArrayKlass::cast(k);
+    int index = (offset - vak->array_header_in_bytes()) / vak->element_byte_size();
+    address dest = (address)((valueArrayOop)p)->value_at_addr(index, vak->layout_helper());
+    assert(dest == ((address)p) + offset, "invalid offset");
+  } else {
+    ShouldNotReachHere();
+  }
+#endif // ASSERT
+
+  if (log_is_enabled(Trace, valuetypes)) {
+    if (k->is_valueArray_klass()) {
+      ValueArrayKlass* vak = ValueArrayKlass::cast(k);
+      int index = (offset - vak->array_header_in_bytes()) / vak->element_byte_size();
+      address dest = (address)((valueArrayOop)p)->value_at_addr(index, vak->layout_helper());
+      log_trace(valuetypes)("array type %s index %d element size %d offset " SIZE_FORMAT_HEX " at " INTPTR_FORMAT,
+                            vak->external_name(), index, vak->element_byte_size(), offset, p2i(dest));
+    } else {
+      log_trace(valuetypes)("field type %s at offset " SIZE_FORMAT_HEX,
+                            vk->external_name(), offset);
+    }
+  }
+}
+
 // These functions allow a null base pointer with an arbitrary address.
 // But if the base pointer is non-null, the offset should make some sense.
 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   oop p = JNIHandles::resolve(obj);

@@ -295,28 +329,20 @@
   oop p = JNIHandles::resolve(obj);
   assert_field_offset_sane(p, offset);
   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 } UNSAFE_END
 
+UNSAFE_ENTRY(jboolean, Unsafe_IsFlattenedArray(JNIEnv *env, jobject unsafe, jclass c)) {
+  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c));
+  return k->is_valueArray_klass();
+} UNSAFE_END
+
 UNSAFE_ENTRY(jobject, Unsafe_GetValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jclass c)) {
   oop p = JNIHandles::resolve(obj);
   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c));
   ValueKlass* vk = ValueKlass::cast(k);
-
-#ifdef ASSERT
-  assert_field_offset_sane(p, offset);
-  fieldDescriptor fd;
-  bool found = get_field_descriptor(p, offset, &fd);
-  assert(found, "value field not found");
-  assert(fd.is_flattened(), "field not flat");
-#endif // ASSERT
-
-  if (log_is_enabled(Trace, valuetypes)) {
-    log_trace(valuetypes)("getValue: field type %s at offset " SIZE_FORMAT_HEX,
-                          vk->external_name(), offset);
-  }
-
+  assert_and_log_unsafe_value_type_access(p, offset, vk);
   Handle p_h(THREAD, p);
   bool in_heap;
   oop v = vk->allocate_buffered_or_heap_instance(&in_heap, CHECK_NULL); // allocate instance
   vk->initialize(CHECK_NULL); // If field is a default value, value class might not be initialized yet
   vk->value_store(((char*)(oopDesc*)p_h()) + offset,

@@ -328,23 +354,11 @@
 UNSAFE_ENTRY(void, Unsafe_PutValue(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jclass c, jobject value)) {
   oop v = JNIHandles::resolve(value);
   oop p = JNIHandles::resolve(obj);
   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c));
   ValueKlass* vk = ValueKlass::cast(k);
-
-#ifdef ASSERT
-  assert_field_offset_sane(p, offset);
-  fieldDescriptor fd;
-  bool found = get_field_descriptor(p, offset, &fd);
-  assert(found, "value field not found");
-  assert(fd.is_flattened(), "field not flat");
-#endif  // ASSERT
-
-  if (log_is_enabled(Trace, valuetypes)) {
-    log_trace(valuetypes)("putValue: field type %s at offset " SIZE_FORMAT_HEX,
-                          vk->external_name(), offset);
-  }
+  assert_and_log_unsafe_value_type_access(p, offset, vk);
   vk->value_store(vk->data_for_oop(v),
                  ((char*)(oopDesc*)p) + offset, true, true);
 } UNSAFE_END
 
 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {

@@ -646,10 +660,15 @@
   } else if (k->is_typeArray_klass()) {
     TypeArrayKlass* tak = TypeArrayKlass::cast(k);
     base  = tak->array_header_in_bytes();
     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
     scale = (1 << tak->log2_element_size());
+  } else if (k->is_valueArray_klass()) {
+    ValueArrayKlass* vak = ValueArrayKlass::cast(k);
+    ValueKlass* vklass = vak->element_klass();
+    base = vak->array_header_in_bytes();
+    scale = vak->element_byte_size();
   } else {
     ShouldNotReachHere();
   }
 }
 

@@ -1113,10 +1132,11 @@
     {CC "getObject",        CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObject)},
     {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObject)},
     {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObjectVolatile)},
     {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObjectVolatile)},
 
+    {CC "isFlattenedArray", CC "(" CLS ")Z",               FN_PTR(Unsafe_IsFlattenedArray)},
     {CC "getValue",         CC "(" OBJ "J" CLS ")" OBJ "", FN_PTR(Unsafe_GetValue)},
     {CC "putValue",         CC "(" OBJ "J" CLS OBJ ")V",   FN_PTR(Unsafe_PutValue)},
 
     {CC "getUncompressedObject", CC "(" ADR ")" OBJ,  FN_PTR(Unsafe_GetUncompressedObject)},
 
< prev index next >