1.1 --- a/src/share/vm/oops/oopsHierarchy.hpp Wed Sep 25 17:47:51 2013 +0200 1.2 +++ b/src/share/vm/oops/oopsHierarchy.hpp Thu Sep 26 10:25:02 2013 -0400 1.3 @@ -55,11 +55,16 @@ 1.4 // to and from the underlying oopDesc pointer type. 1.5 // 1.6 // Because oop and its subclasses <type>Oop are class types, arbitrary 1.7 -// conversions are not accepted by the compiler, and you may get a message 1.8 -// about overloading ambiguity (between long and int is common when converting 1.9 -// from a constant in 64 bit mode), or unable to convert from type to 'oop'. 1.10 -// Applying a cast to one of these conversion operators first will get to the 1.11 -// underlying oopDesc* type if appropriate. 1.12 +// conversions are not accepted by the compiler. Applying a cast to 1.13 +// an oop will cause the best matched conversion operator to be 1.14 +// invoked returning the underlying oopDesc* type if appropriate. 1.15 +// No copy constructors, explicit user conversions or operators of 1.16 +// numerical type should be defined within the oop class. Most C++ 1.17 +// compilers will issue a compile time error concerning the overloading 1.18 +// ambiguity between operators of numerical and pointer types. If 1.19 +// a conversion to or from an oop to a numerical type is needed, 1.20 +// use the inline template methods, cast_*_oop, defined below. 1.21 +// 1.22 // Converting NULL to oop to Handle implicit is no longer accepted by the 1.23 // compiler because there are too many steps in the conversion. Use Handle() 1.24 // instead, which generates less code anyway. 1.25 @@ -83,12 +88,9 @@ 1.26 void raw_set_obj(const void* p) { _o = (oopDesc*)p; } 1.27 1.28 oop() { set_obj(NULL); } 1.29 + oop(const oop& o) { set_obj(o.obj()); } 1.30 oop(const volatile oop& o) { set_obj(o.obj()); } 1.31 oop(const void* p) { set_obj(p); } 1.32 - oop(intptr_t i) { set_obj((void *)i); } 1.33 -#ifdef _LP64 1.34 - oop(int i) { set_obj((void *)i); } 1.35 -#endif 1.36 ~oop() { 1.37 if (CheckUnhandledOops) unregister_oop(); 1.38 } 1.39 @@ -101,8 +103,6 @@ 1.40 bool operator==(void *p) const { return obj() == p; } 1.41 bool operator!=(const volatile oop o) const { return obj() != o.obj(); } 1.42 bool operator!=(void *p) const { return obj() != p; } 1.43 - bool operator==(intptr_t p) const { return obj() == (oopDesc*)p; } 1.44 - bool operator!=(intptr_t p) const { return obj() != (oopDesc*)p; } 1.45 1.46 bool operator<(oop o) const { return obj() < o.obj(); } 1.47 bool operator>(oop o) const { return obj() > o.obj(); } 1.48 @@ -110,8 +110,18 @@ 1.49 bool operator>=(oop o) const { return obj() >= o.obj(); } 1.50 bool operator!() const { return !obj(); } 1.51 1.52 - // Cast 1.53 + // Assignment 1.54 + oop& operator=(const oop& o) { _o = o.obj(); return *this; } 1.55 +#ifndef SOLARIS 1.56 + volatile oop& operator=(const oop& o) volatile { _o = o.obj(); return *this; } 1.57 +#endif 1.58 + volatile oop& operator=(const volatile oop& o) volatile { _o = o.obj(); return *this; } 1.59 + 1.60 + // Explict user conversions 1.61 operator void* () const { return (void *)obj(); } 1.62 +#ifndef SOLARIS 1.63 + operator void* () const volatile { return (void *)obj(); } 1.64 +#endif 1.65 operator HeapWord* () const { return (HeapWord*)obj(); } 1.66 operator oopDesc* () const { return obj(); } 1.67 operator intptr_t* () const { return (intptr_t*)obj(); } 1.68 @@ -119,7 +129,6 @@ 1.69 operator markOop () const { return markOop(obj()); } 1.70 1.71 operator address () const { return (address)obj(); } 1.72 - operator intptr_t () const volatile { return (intptr_t)obj(); } 1.73 1.74 // from javaCalls.cpp 1.75 operator jobject () const { return (jobject)obj(); } 1.76 @@ -141,12 +150,26 @@ 1.77 class type##Oop : public oop { \ 1.78 public: \ 1.79 type##Oop() : oop() {} \ 1.80 + type##Oop(const oop& o) : oop(o) {} \ 1.81 type##Oop(const volatile oop& o) : oop(o) {} \ 1.82 type##Oop(const void* p) : oop(p) {} \ 1.83 operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ 1.84 type##OopDesc* operator->() const { \ 1.85 return (type##OopDesc*)obj(); \ 1.86 } \ 1.87 + type##Oop& operator=(const type##Oop& o) { \ 1.88 + oop::operator=(o); \ 1.89 + return *this; \ 1.90 + } \ 1.91 + NOT_SOLARIS( \ 1.92 + volatile type##Oop& operator=(const type##Oop& o) volatile { \ 1.93 + (void)const_cast<oop&>(oop::operator=(o)); \ 1.94 + return *this; \ 1.95 + }) \ 1.96 + volatile type##Oop& operator=(const volatile type##Oop& o) volatile {\ 1.97 + (void)const_cast<oop&>(oop::operator=(o)); \ 1.98 + return *this; \ 1.99 + } \ 1.100 }; 1.101 1.102 DEF_OOP(instance); 1.103 @@ -156,6 +179,16 @@ 1.104 1.105 #endif // CHECK_UNHANDLED_OOPS 1.106 1.107 +// For CHECK_UNHANDLED_OOPS, it is ambiguous C++ behavior to have the oop 1.108 +// structure contain explicit user defined conversions of both numerical 1.109 +// and pointer type. Define inline methods to provide the numerical conversions. 1.110 +template <class T> inline oop cast_to_oop(T value) { 1.111 + return (oop)(CHECK_UNHANDLED_OOPS_ONLY((void *))(value)); 1.112 +} 1.113 +template <class T> inline T cast_from_oop(oop o) { 1.114 + return (T)(CHECK_UNHANDLED_OOPS_ONLY((void*))o); 1.115 +} 1.116 + 1.117 // The metadata hierarchy is separate from the oop hierarchy 1.118 1.119 // class MetaspaceObj