changeset 39695:946f1321c075

8158946: btree009 fails with assert(s > 0) failed: Bad size calculated Summary: Set oop_size before setting _klass Reviewed-by: coleenp, dholmes, kbarrett, tschatzl
author drwhite
date Tue, 05 Jul 2016 15:34:06 -0400
parents e8e42da000c5
children 1f34864a0347
files hotspot/src/share/vm/classfile/javaClasses.cpp hotspot/src/share/vm/classfile/javaClasses.hpp hotspot/src/share/vm/gc/shared/collectedHeap.hpp hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp hotspot/src/share/vm/oops/instanceMirrorKlass.cpp hotspot/src/share/vm/oops/oop.inline.hpp
diffstat 6 files changed, 43 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Jul 05 15:34:06 2016 -0400
@@ -871,12 +871,17 @@
 
 int  java_lang_Class::oop_size(oop java_class) {
   assert(_oop_size_offset != 0, "must be set");
-  return java_class->int_field(_oop_size_offset);
-}
+  int size = java_class->int_field(_oop_size_offset);
+  assert(size > 0, "Oop size must be greater than zero, not %d", size);
+  return size;
+}
+
 void java_lang_Class::set_oop_size(oop java_class, int size) {
   assert(_oop_size_offset != 0, "must be set");
+  assert(size > 0, "Oop size must be greater than zero, not %d", size);
   java_class->int_field_put(_oop_size_offset, size);
 }
+
 int  java_lang_Class::static_oop_field_count(oop java_class) {
   assert(_static_oop_field_count_offset != 0, "must be set");
   return java_class->int_field(_static_oop_field_count_offset);
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Tue Jul 05 15:34:06 2016 -0400
@@ -275,7 +275,6 @@
   static int static_oop_field_count(oop java_class);
   static void set_static_oop_field_count(oop java_class, int size);
 
-
   static GrowableArray<Klass*>* fixup_mirror_list() {
     return _fixup_mirror_list;
   }
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Tue Jul 05 15:34:06 2016 -0400
@@ -159,6 +159,8 @@
   inline static void post_allocation_setup_array(KlassHandle klass,
                                                  HeapWord* obj, int length);
 
+  inline static void post_allocation_setup_class(KlassHandle klass, HeapWord* obj, int size);
+
   // Clears an allocated object.
   inline static void init_obj(HeapWord* obj, size_t size);
 
@@ -300,6 +302,7 @@
   inline static oop obj_allocate(KlassHandle klass, int size, TRAPS);
   inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS);
   inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
+  inline static oop class_allocate(KlassHandle klass, int size, TRAPS);
 
   inline static void post_allocation_install_obj_klass(KlassHandle klass,
                                                        oop obj);
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Tue Jul 05 15:34:06 2016 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_SHARED_COLLECTEDHEAP_INLINE_HPP
 #define SHARE_VM_GC_SHARED_COLLECTEDHEAP_INLINE_HPP
 
+#include "classfile/javaClasses.hpp"
 #include "gc/shared/allocTracer.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/threadLocalAllocBuffer.inline.hpp"
@@ -96,6 +97,22 @@
   post_allocation_notify(klass, (oop)obj, size);
 }
 
+void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
+                                                HeapWord* obj,
+                                                int size) {
+  // Set oop_size field before setting the _klass field
+  // in post_allocation_setup_common() because the klass field
+  // indicates that the object is parsable by concurrent GC.
+  oop new_cls = (oop)obj;
+  assert(size > 0, "oop_size must be positive.");
+  java_lang_Class::set_oop_size(new_cls, size);
+  post_allocation_setup_common(klass, obj);
+  assert(Universe::is_bootstrapping() ||
+         !new_cls->is_array(), "must not be an array");
+  // notify jvmti and dtrace
+  post_allocation_notify(klass, new_cls, size);
+}
+
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
                                                 HeapWord* obj,
                                                 int length) {
@@ -207,6 +224,16 @@
   return (oop)obj;
 }
 
+oop CollectedHeap::class_allocate(KlassHandle klass, int size, TRAPS) {
+  debug_only(check_for_valid_allocation_state());
+  assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
+  assert(size >= 0, "int won't convert to size_t");
+  HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
+  post_allocation_setup_class(klass, obj, size); // set oop_size
+  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
+  return (oop)obj;
+}
+
 oop CollectedHeap::array_allocate(KlassHandle klass,
                                   int size,
                                   int length,
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Tue Jul 05 15:34:06 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,13 +50,12 @@
   // Query before forming handle.
   int size = instance_size(k);
   KlassHandle h_k(THREAD, this);
-  instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
+
+  assert(size > 0, "total object size must be positive: %d", size);
 
   // Since mirrors can be variable sized because of the static fields, store
   // the size in the mirror itself.
-  java_lang_Class::set_oop_size(i, size);
-
-  return i;
+  return (instanceOop)CollectedHeap::class_allocate(h_k, size, CHECK_NULL);
 }
 
 int InstanceMirrorKlass::oop_size(oop obj) const {
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Tue Jul 05 20:09:21 2016 +0200
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Tue Jul 05 15:34:06 2016 -0400
@@ -258,8 +258,8 @@
     }
   }
 
-  assert(s % MinObjAlignment == 0, "alignment check");
-  assert(s > 0, "Bad size calculated");
+  assert(s % MinObjAlignment == 0, "Oop size is not properly aligned: %d", s);
+  assert(s > 0, "Oop size must be greater than zero, not %d", s);
   return s;
 }