/* Sun-$Revision: 23.3 $ */
/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
See the LICENSE file for license information. */
# pragma interface
// "Foreign" oops (below) are killable objects containing an arbitrary
// machine pointer. foreignOopClass is an abstract class.
// Warning: do not attempt to store an oop where the C pointer is supposed to
// be. This will not work, since the pointer is not scavenged!
class C_pointer {
// In general C pointer requires 32 bits precision, but we also have to
// tag it. We therefore store it as two smiOop's, one holding the upper
// 16 bits, the other holding the lower 16 bits.
// When converting to/from a pointer, a long is used as an intermediate
// step, since this is the only integer C type, that is guaranteed to
// hold any pointer value.
// NB: Actual numbers may not be 16 and 32 bits.
//
// Promised to write here that Urs' thinks this is an unnecessary
// precaution to take; we should just put in an assertion checking that
// the pointer can fit in a smiOop. Anyway, localizing the concept to this
// class, will make it easy to change.
// He made the point that either we do it everywhere in the VM (i.e. use
// instances of this class everywhere we store a pointer), or we never
// care about it.
// Ole Agesen, 10/18/91.
private:
smiOop hi, lo;
static const smi shifts;
static const long low_mask;
public:
void set(const void *ptr) {
assert(BitsPerByte * sizeof(ptr) <=
2 * (BitsPerByte * sizeof(smiOop) - Tag_Size), "Really?");
hi = as_smiOop(long(ptr) >> shifts);
lo = as_smiOop(long(ptr) & low_mask);
}
void *get() {
return (void *)( (long(hi->value()) << shifts) | long(lo->value()) );
}
bool verify();
};
class foreignOopClass: public slotsOopClass { // Abstract class.
private:
C_pointer cObject; // object in C heap pointed to by me.
protected:
foreignOopClass* addr() {
return (foreignOopClass*)slotsOopClass::addr();
}
// Default implementation of kill/is_live. May be overridden.
void kill_foreign() {
set_pointer(NULL);
}
bool is_live_foreign() {
return get_pointer() != NULL;
}
public:
void *get_pointer() {
return addr()->cObject.get();
}
void set_pointer(const void *ptr) {
addr()->cObject.set(ptr);
}
bool is_null() {
return get_pointer() == NULL;
}
foreignOop clone(bool mustAllocate) {
return (foreignOop) slotsOopClass::clone(mustAllocate);
}
smi foreign_hash() {
return smi(get_pointer()) >> Tag_Size;
}
bool same_pointer_as(foreignOop x) {
return get_pointer() == x->get_pointer();
}
bool verify();
friend class foreignMap;
};