1.1 --- a/src/share/vm/memory/allocation.cpp Wed Dec 08 17:50:49 2010 -0800 1.2 +++ b/src/share/vm/memory/allocation.cpp Fri Dec 10 14:14:02 2010 -0800 1.3 @@ -73,7 +73,7 @@ 1.4 void ResourceObj::operator delete(void* p) { 1.5 assert(((ResourceObj *)p)->allocated_on_C_heap(), 1.6 "delete only allowed for C_HEAP objects"); 1.7 - DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;) 1.8 + DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;) 1.9 FreeHeap(p); 1.10 } 1.11 1.12 @@ -83,43 +83,73 @@ 1.13 uintptr_t allocation = (uintptr_t)res; 1.14 assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); 1.15 assert(type <= allocation_mask, "incorrect allocation type"); 1.16 - ((ResourceObj *)res)->_allocation = ~(allocation + type); 1.17 + ResourceObj* resobj = (ResourceObj *)res; 1.18 + resobj->_allocation_t[0] = ~(allocation + type); 1.19 + if (type != STACK_OR_EMBEDDED) { 1.20 + // Called from operator new() and CollectionSetChooser(), 1.21 + // set verification value. 1.22 + resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type; 1.23 + } 1.24 } 1.25 1.26 ResourceObj::allocation_type ResourceObj::get_allocation_type() const { 1.27 - assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object"); 1.28 - return (allocation_type)((~_allocation) & allocation_mask); 1.29 + assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object"); 1.30 + return (allocation_type)((~_allocation_t[0]) & allocation_mask); 1.31 +} 1.32 + 1.33 +bool ResourceObj::is_type_set() const { 1.34 + allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask); 1.35 + return get_allocation_type() == type && 1.36 + (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]); 1.37 } 1.38 1.39 ResourceObj::ResourceObj() { // default constructor 1.40 - if (~(_allocation | allocation_mask) != (uintptr_t)this) { 1.41 + if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) { 1.42 + // Operator new() is not called for allocations 1.43 + // on stack and for embedded objects. 1.44 set_allocation_type((address)this, STACK_OR_EMBEDDED); 1.45 - } else if (allocated_on_stack()) { 1.46 - // For some reason we got a value which looks like an allocation on stack. 1.47 - // Pass if it is really allocated on stack. 1.48 - assert(Thread::current()->on_local_stack((address)this),"should be on stack"); 1.49 + } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED 1.50 + // For some reason we got a value which resembles 1.51 + // an embedded or stack object (operator new() does not 1.52 + // set such type). Keep it since it is valid value 1.53 + // (even if it was garbage). 1.54 + // Ignore garbage in other fields. 1.55 + } else if (is_type_set()) { 1.56 + // Operator new() was called and type was set. 1.57 + assert(!allocated_on_stack(), 1.58 + err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 1.59 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 1.60 } else { 1.61 - assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(), 1.62 - "allocation_type should be set by operator new()"); 1.63 + // Operator new() was not called. 1.64 + // Assume that it is embedded or stack object. 1.65 + set_allocation_type((address)this, STACK_OR_EMBEDDED); 1.66 } 1.67 + _allocation_t[1] = 0; // Zap verification value 1.68 } 1.69 1.70 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor 1.71 // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. 1.72 + // Note: garbage may resembles valid value. 1.73 + assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), 1.74 + err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 1.75 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 1.76 set_allocation_type((address)this, STACK_OR_EMBEDDED); 1.77 + _allocation_t[1] = 0; // Zap verification value 1.78 } 1.79 1.80 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment 1.81 // Used in InlineTree::ok_to_inline() for WarmCallInfo. 1.82 - assert(allocated_on_stack(), "copy only into local"); 1.83 - // Keep current _allocation value; 1.84 + assert(allocated_on_stack(), 1.85 + err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", 1.86 + this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); 1.87 + // Keep current _allocation_t value; 1.88 return *this; 1.89 } 1.90 1.91 ResourceObj::~ResourceObj() { 1.92 // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. 1.93 - if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap. 1.94 - _allocation = (uintptr_t)badHeapOopVal; // zap type 1.95 + if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap. 1.96 + _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type 1.97 } 1.98 } 1.99 #endif // ASSERT