src/share/vm/oops/oopsHierarchy.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2658
c7f3d0b4570f
child 4037
da91efe96a93
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1997, 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  */
    25 #ifndef SHARE_VM_OOPS_OOPSHIERARCHY_HPP
    26 #define SHARE_VM_OOPS_OOPSHIERARCHY_HPP
    28 #include "runtime/globals.hpp"
    29 #include "utilities/globalDefinitions.hpp"
    31 // OBJECT hierarchy
    32 // This hierarchy is a representation hierarchy, i.e. if A is a superclass
    33 // of B, A's representation is a prefix of B's representation.
    35 typedef juint narrowOop; // Offset instead of address for an oop within a java object
    36 typedef class klassOopDesc* wideKlassOop; // to keep SA happy and unhandled oop
    37                                           // detector happy.
    38 typedef void* OopOrNarrowOopStar;
    40 #ifndef CHECK_UNHANDLED_OOPS
    42 typedef class oopDesc*                            oop;
    43 typedef class   instanceOopDesc*            instanceOop;
    44 typedef class   methodOopDesc*                    methodOop;
    45 typedef class   constMethodOopDesc*            constMethodOop;
    46 typedef class   methodDataOopDesc*            methodDataOop;
    47 typedef class   arrayOopDesc*                    arrayOop;
    48 typedef class     objArrayOopDesc*            objArrayOop;
    49 typedef class     typeArrayOopDesc*            typeArrayOop;
    50 typedef class   constantPoolOopDesc*            constantPoolOop;
    51 typedef class   constantPoolCacheOopDesc*   constantPoolCacheOop;
    52 typedef class   klassOopDesc*                    klassOop;
    53 typedef class   markOopDesc*                    markOop;
    54 typedef class   compiledICHolderOopDesc*    compiledICHolderOop;
    56 #else
    59 // When CHECK_UNHANDLED_OOPS is defined, an "oop" is a class with a
    60 // carefully chosen set of constructors and conversion operators to go
    61 // to and from the underlying oopDesc pointer type.
    62 //
    63 // Because oop and its subclasses <type>Oop are class types, arbitrary
    64 // conversions are not accepted by the compiler, and you may get a message
    65 // about overloading ambiguity (between long and int is common when converting
    66 // from a constant in 64 bit mode), or unable to convert from type to 'oop'.
    67 // Applying a cast to one of these conversion operators first will get to the
    68 // underlying oopDesc* type if appropriate.
    69 // Converting NULL to oop to Handle implicit is no longer accepted by the
    70 // compiler because there are too many steps in the conversion.  Use Handle()
    71 // instead, which generates less code anyway.
    73 class Thread;
    74 typedef class   markOopDesc*                markOop;
    75 class PromotedObject;
    78 class oop {
    79   oopDesc* _o;
    81   void register_oop();
    82   void unregister_oop();
    84   // friend class markOop;
    85 public:
    86   void set_obj(const void* p)         {
    87     raw_set_obj(p);
    88     if (CheckUnhandledOops) register_oop();
    89   }
    90   void raw_set_obj(const void* p)     { _o = (oopDesc*)p; }
    92   oop()                               { set_obj(NULL); }
    93   oop(const volatile oop& o)          { set_obj(o.obj()); }
    94   oop(const void* p)                  { set_obj(p); }
    95   oop(intptr_t i)                     { set_obj((void *)i); }
    96 #ifdef _LP64
    97   oop(int i)                          { set_obj((void *)i); }
    98 #endif
    99   ~oop()                              {
   100     if (CheckUnhandledOops) unregister_oop();
   101   }
   103   oopDesc* obj()  const volatile      { return _o; }
   105   // General access
   106   oopDesc*  operator->() const        { return obj(); }
   107   bool operator==(const oop o) const  { return obj() == o.obj(); }
   108   bool operator==(void *p) const      { return obj() == p; }
   109   bool operator!=(const oop o) const  { return obj() != o.obj(); }
   110   bool operator!=(void *p) const      { return obj() != p; }
   111   bool operator==(intptr_t p) const   { return obj() == (oopDesc*)p; }
   112   bool operator!=(intptr_t p) const   { return obj() != (oopDesc*)p; }
   114   bool operator<(oop o) const         { return obj() < o.obj(); }
   115   bool operator>(oop o) const         { return obj() > o.obj(); }
   116   bool operator<=(oop o) const        { return obj() <= o.obj(); }
   117   bool operator>=(oop o) const        { return obj() >= o.obj(); }
   118   bool operator!() const              { return !obj(); }
   120   // Cast
   121   operator void* () const             { return (void *)obj(); }
   122   operator HeapWord* () const         { return (HeapWord*)obj(); }
   123   operator oopDesc* () const          { return obj(); }
   124   operator intptr_t* () const         { return (intptr_t*)obj(); }
   125   operator PromotedObject* () const   { return (PromotedObject*)obj(); }
   126   operator markOop () const           { return markOop(obj()); }
   128   operator address   () const         { return (address)obj(); }
   129   operator intptr_t () const          { return (intptr_t)obj(); }
   131   // from javaCalls.cpp
   132   operator jobject () const           { return (jobject)obj(); }
   133   // from javaClasses.cpp
   134   operator JavaThread* () const       { return (JavaThread*)obj(); }
   136 #ifndef _LP64
   137   // from jvm.cpp
   138   operator jlong* () const            { return (jlong*)obj(); }
   139 #endif
   141   // from parNewGeneration and other things that want to get to the end of
   142   // an oop for stuff (like constMethodKlass.cpp, objArrayKlass.cpp)
   143   operator oop* () const              { return (oop *)obj(); }
   144 };
   146 #define DEF_OOP(type)                                                      \
   147    class type##OopDesc;                                                    \
   148    class type##Oop : public oop {                                          \
   149      public:                                                               \
   150        type##Oop() : oop() {}                                              \
   151        type##Oop(const volatile oop& o) : oop(o) {}                        \
   152        type##Oop(const void* p) : oop(p) {}                                \
   153        operator type##OopDesc* () const { return (type##OopDesc*)obj(); }  \
   154        type##OopDesc* operator->() const {                                 \
   155             return (type##OopDesc*)obj();                                  \
   156        }                                                                   \
   157    };                                                                      \
   159 DEF_OOP(instance);
   160 DEF_OOP(method);
   161 DEF_OOP(methodData);
   162 DEF_OOP(array);
   163 DEF_OOP(constMethod);
   164 DEF_OOP(constantPool);
   165 DEF_OOP(constantPoolCache);
   166 DEF_OOP(objArray);
   167 DEF_OOP(typeArray);
   168 DEF_OOP(klass);
   169 DEF_OOP(compiledICHolder);
   171 #endif // CHECK_UNHANDLED_OOPS
   173 // The klass hierarchy is separate from the oop hierarchy.
   175 class Klass;
   176 class   instanceKlass;
   177 class     instanceMirrorKlass;
   178 class     instanceRefKlass;
   179 class   methodKlass;
   180 class   constMethodKlass;
   181 class   methodDataKlass;
   182 class   klassKlass;
   183 class     instanceKlassKlass;
   184 class     arrayKlassKlass;
   185 class       objArrayKlassKlass;
   186 class       typeArrayKlassKlass;
   187 class   arrayKlass;
   188 class     objArrayKlass;
   189 class     typeArrayKlass;
   190 class   constantPoolKlass;
   191 class   constantPoolCacheKlass;
   192 class   compiledICHolderKlass;
   194 #endif // SHARE_VM_OOPS_OOPSHIERARCHY_HPP

mercurial