/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_RUNTIME_HANDLES_HPP
#define SHARE_VM_RUNTIME_HANDLES_HPP
#include "oops/klassOop.hpp"
//------------------------------------------------------------------------------------------------------------------------
// In order to preserve oops during garbage collection, they should be
// allocated and passed around via Handles within the VM. A handle is
// simply an extra indirection allocated in a thread local handle area.
//
// A handle is a ValueObj, so it can be passed around as a value, can
// be used as a parameter w/o using &-passing, and can be returned as a
// return value.
//
// oop parameters and return types should be Handles whenever feasible.
//
// Handles are declared in a straight-forward manner, e.g.
//
// oop obj = ...;
// Handle h1(obj); // allocate new handle
// Handle h2(thread, obj); // faster allocation when current thread is known
// Handle h3; // declare handle only, no allocation occurs
// ...
// h3 = h1; // make h3 refer to same indirection as h1
// oop obj2 = h2(); // get handle value
// h1->print(); // invoking operation on oop
//
// Handles are specialized for different oop types to provide extra type
// information and avoid unnecessary casting. For each oop type xxxOop
// there is a corresponding handle called xxxHandle, e.g.
//
// oop Handle
// methodOop methodHandle
// instanceOop instanceHandle
//
// For klassOops, it is often useful to model the Klass hierarchy in order
// to get access to the klass_part without casting. For each xxxKlass there
// is a corresponding handle called xxxKlassHandle, e.g.
//
// klassOop Klass KlassHandle
// klassOop methodKlass methodKlassHandle
// klassOop instanceKlass instanceKlassHandle
//
//------------------------------------------------------------------------------------------------------------------------
// Base class for all handles. Provides overloading of frequently
// used operators for ease of use.
private:
protected:
public:
// Constructors
#ifndef ASSERT
#else
// Don't inline body with assert for current thread
#endif // ASSERT
// General access
oop operator -> () const { return non_null_obj(); }
// Null checks
// Debugging
// Direct interface, use very sparingly.
// Used by JavaCalls to quickly convert handles and to create handles static data structures.
// Constructor takes a dummy argument to prevent unintentional type conversion in C++.
// Raw handle access. Allows easy duplication of Handles. This can be very unsafe
// since duplicates is only valid as long as original handle is alive.
};
//------------------------------------------------------------------------------------------------------------------------
// Base class for Handles containing klassOops. Provides overloading of frequently
// used operators for ease of use and typed access to the Klass part.
protected:
public:
// Constructors
}
}
// Faster versions passing Thread
}
}
// Direct interface, use very sparingly.
// Used by SystemDictionaryHandles to create handles on existing WKKs.
// The obj of such a klass handle may be null, because the handle is formed
// during system bootstrapping.
}
// General access
};
//------------------------------------------------------------------------------------------------------------------------
// Specific Handles for different oop types
protected: \
\
public: \
/* Constructors */ \
"illegal type"); \
} \
} \
\
/* Special constructor, use sparingly */ \
\
/* Operators for ease of use */ \
};
//------------------------------------------------------------------------------------------------------------------------
// Specific KlassHandles for different Klass types
public: \
/* Constructors */ \
"illegal type"); \
} \
"illegal type"); \
} \
\
/* Access to klass part */ \
\
\
};
//------------------------------------------------------------------------------------------------------------------------
// Thread local handle area
friend class HandleMark;
friend class NoHandleMark;
friend class ResetNoHandleMark;
#ifdef ASSERT
int _handle_mark_nesting;
#endif
public:
// Constructor
}
// Handle allocation
private:
#ifdef ASSERT
#else
#endif
return handle;
}
public:
#ifdef ASSERT
#else
#endif
// Garbage collection support
void oops_do(OopClosure* f);
// Number of handles in use
};
//------------------------------------------------------------------------------------------------------------------------
// Handles are allocated in a (growable) thread local handle area. Deallocation
// is managed using a HandleMark. It should normally not be necessary to use
// HandleMarks manually.
//
// A HandleMark constructor will record the current handle area top, and the
// desctructor will reset the top, destroying all handles allocated in between.
// The following code will therefore NOT work:
//
// Handle h;
// {
// HandleMark hm;
// h = Handle(obj);
// }
// h()->print(); // WRONG, h destroyed by HandleMark destructor.
//
// If h has to be preserved, it can be converted to an oop or a local JNI handle
// across the HandleMark boundary.
// The base class of HandleMark should have been StackObj but we also heap allocate
// a HandleMark when a thread is created.
class HandleMark {
private:
// Link to previous active HandleMark in thread
public:
HandleMark(); // see handles_inline.hpp
~HandleMark();
// Functions used by HandleMarkCleaner
// called in the constructor of HandleMarkCleaner
void push();
// called in the destructor of HandleMarkCleaner
void pop_and_restore();
};
//------------------------------------------------------------------------------------------------------------------------
// A NoHandleMark stack object will verify that no handles are allocated
// in its scope. Enabled in debug mode only.
public:
#ifdef ASSERT
NoHandleMark();
~NoHandleMark();
#else
NoHandleMark() {}
~NoHandleMark() {}
#endif
};
public:
#ifdef ASSERT
#else
ResetNoHandleMark() {}
~ResetNoHandleMark() {}
#endif
};
#endif // SHARE_VM_RUNTIME_HANDLES_HPP