< prev index next >

src/hotspot/share/memory/allocation.cpp

Print this page
rev 52793 : imported patch fix
rev 52794 : imported patch assign_assert


 169     ResourceObj* resobj = (ResourceObj *)res;
 170     resobj->_allocation_t[0] = ~(allocation + type);
 171     if (type != STACK_OR_EMBEDDED) {
 172       // Called from operator new() and CollectionSetChooser(),
 173       // set verification value.
 174       resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type;
 175     }
 176 }
 177 
 178 ResourceObj::allocation_type ResourceObj::get_allocation_type() const {
 179     assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object");
 180     return (allocation_type)((~_allocation_t[0]) & allocation_mask);
 181 }
 182 
 183 bool ResourceObj::is_type_set() const {
 184     allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask);
 185     return get_allocation_type()  == type &&
 186            (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]);
 187 }
 188 
 189 ResourceObj::ResourceObj() { // default constructor





 190     if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) {
 191       // Operator new() is not called for allocations
 192       // on stack and for embedded objects.
 193       set_allocation_type((address)this, STACK_OR_EMBEDDED);
 194     } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED
 195       // For some reason we got a value which resembles
 196       // an embedded or stack object (operator new() does not
 197       // set such type). Keep it since it is valid value
 198       // (even if it was garbage).
 199       // Ignore garbage in other fields.
 200     } else if (is_type_set()) {
 201       // Operator new() was called and type was set.
 202       assert(!allocated_on_stack(),
 203              "not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
 204              p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
 205     } else {
 206       // Operator new() was not called.
 207       // Assume that it is embedded or stack object.
 208       set_allocation_type((address)this, STACK_OR_EMBEDDED);
 209     }
 210     _allocation_t[1] = 0; // Zap verification value
 211 }
 212 
 213 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor
 214     // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream.
 215     // Note: garbage may resembles valid value.
 216     assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(),
 217            "embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
 218            p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
 219     set_allocation_type((address)this, STACK_OR_EMBEDDED);
 220     _allocation_t[1] = 0; // Zap verification value
 221 }
 222 
 223 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment
 224     // Used in InlineTree::ok_to_inline() for WarmCallInfo.
 225     assert(allocated_on_stack(),
 226            "copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
 227            p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
 228     // Keep current _allocation_t value;
 229     return *this;
 230 }
 231 
 232 ResourceObj::~ResourceObj() {
 233     // allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
 234     if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap.
 235       _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type
 236     }
 237 }
 238 #endif // ASSERT
 239 
 240 //--------------------------------------------------------------------------------------
 241 // Non-product code
 242 
 243 #ifndef PRODUCT
 244 void AllocatedObj::print() const       { print_on(tty); }




 169     ResourceObj* resobj = (ResourceObj *)res;
 170     resobj->_allocation_t[0] = ~(allocation + type);
 171     if (type != STACK_OR_EMBEDDED) {
 172       // Called from operator new() and CollectionSetChooser(),
 173       // set verification value.
 174       resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type;
 175     }
 176 }
 177 
 178 ResourceObj::allocation_type ResourceObj::get_allocation_type() const {
 179     assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object");
 180     return (allocation_type)((~_allocation_t[0]) & allocation_mask);
 181 }
 182 
 183 bool ResourceObj::is_type_set() const {
 184     allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask);
 185     return get_allocation_type()  == type &&
 186            (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]);
 187 }
 188 
 189 // This whole business of passing information from ResourceObj::operator new
 190 // to the ResourceObj constructor via fields in the "object" is technically UB.
 191 // But it seems to work within the limitations of HotSpot usage (such as no
 192 // multiple inheritance) with the compilers and compiler options we're using.
 193 // And it gives some possibly useful checking for misuse of ResourceObj.
 194 void ResourceObj::initialize_allocation_info() {
 195     if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) {
 196       // Operator new() is not called for allocations
 197       // on stack and for embedded objects.
 198       set_allocation_type((address)this, STACK_OR_EMBEDDED);
 199     } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED
 200       // For some reason we got a value which resembles
 201       // an embedded or stack object (operator new() does not
 202       // set such type). Keep it since it is valid value
 203       // (even if it was garbage).
 204       // Ignore garbage in other fields.
 205     } else if (is_type_set()) {
 206       // Operator new() was called and type was set.
 207       assert(!allocated_on_stack(),
 208              "not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
 209              p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
 210     } else {
 211       // Operator new() was not called.
 212       // Assume that it is embedded or stack object.
 213       set_allocation_type((address)this, STACK_OR_EMBEDDED);
 214     }
 215     _allocation_t[1] = 0; // Zap verification value
 216 }
 217 
 218 ResourceObj::ResourceObj() {
 219     initialize_allocation_info();
 220 }
 221 
 222 ResourceObj::ResourceObj(const ResourceObj&) {
 223     // Initialize _allocation_t as a new object, ignoring object being copied.
 224     initialize_allocation_info();

 225 }
 226 
 227 ResourceObj& ResourceObj::operator=(const ResourceObj& r) {

 228     assert(allocated_on_stack(),
 229            "copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
 230            p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]);
 231     // Keep current _allocation_t value;
 232     return *this;
 233 }
 234 
 235 ResourceObj::~ResourceObj() {
 236     // allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
 237     if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap.
 238       _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type
 239     }
 240 }
 241 #endif // ASSERT
 242 
 243 //--------------------------------------------------------------------------------------
 244 // Non-product code
 245 
 246 #ifndef PRODUCT
 247 void AllocatedObj::print() const       { print_on(tty); }


< prev index next >