1.1 --- a/src/share/vm/memory/allocation.cpp Tue Aug 03 08:13:38 2010 -0400 1.2 +++ b/src/share/vm/memory/allocation.cpp Mon Aug 09 17:51:56 2010 -0700 1.3 @@ -43,24 +43,73 @@ 1.4 switch (type) { 1.5 case C_HEAP: 1.6 res = (address)AllocateHeap(size, "C_Heap: ResourceOBJ"); 1.7 + DEBUG_ONLY(set_allocation_type(res, C_HEAP);) 1.8 break; 1.9 case RESOURCE_AREA: 1.10 + // new(size) sets allocation type RESOURCE_AREA. 1.11 res = (address)operator new(size); 1.12 break; 1.13 default: 1.14 ShouldNotReachHere(); 1.15 } 1.16 - // Set allocation type in the resource object for assertion checks. 1.17 - DEBUG_ONLY(((ResourceObj *)res)->_allocation = type;) 1.18 return res; 1.19 } 1.20 1.21 void ResourceObj::operator delete(void* p) { 1.22 assert(((ResourceObj *)p)->allocated_on_C_heap(), 1.23 "delete only allowed for C_HEAP objects"); 1.24 + DEBUG_ONLY(((ResourceObj *)p)->_allocation = badHeapOopVal;) 1.25 FreeHeap(p); 1.26 } 1.27 1.28 +#ifdef ASSERT 1.29 +void ResourceObj::set_allocation_type(address res, allocation_type type) { 1.30 + // Set allocation type in the resource object 1.31 + uintptr_t allocation = (uintptr_t)res; 1.32 + assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); 1.33 + assert(type <= allocation_mask, "incorrect allocation type"); 1.34 + ((ResourceObj *)res)->_allocation = ~(allocation + type); 1.35 +} 1.36 + 1.37 +ResourceObj::allocation_type ResourceObj::get_allocation_type() const { 1.38 + assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object"); 1.39 + return (allocation_type)((~_allocation) & allocation_mask); 1.40 +} 1.41 + 1.42 +ResourceObj::ResourceObj() { // default constructor 1.43 + if (~(_allocation | allocation_mask) != (uintptr_t)this) { 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 { 1.50 + assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(), 1.51 + "allocation_type should be set by operator new()"); 1.52 + } 1.53 +} 1.54 + 1.55 +ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor 1.56 + // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. 1.57 + set_allocation_type((address)this, STACK_OR_EMBEDDED); 1.58 +} 1.59 + 1.60 +ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment 1.61 + // Used in InlineTree::ok_to_inline() for WarmCallInfo. 1.62 + assert(allocated_on_stack(), "copy only into local"); 1.63 + // Keep current _allocation value; 1.64 + return *this; 1.65 +} 1.66 + 1.67 +ResourceObj::~ResourceObj() { 1.68 + // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. 1.69 + if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap. 1.70 + _allocation = badHeapOopVal; // zap type 1.71 + } 1.72 +} 1.73 +#endif // ASSERT 1.74 + 1.75 + 1.76 void trace_heap_malloc(size_t size, const char* name, void* p) { 1.77 // A lock is not needed here - tty uses a lock internally 1.78 tty->print_cr("Heap malloc " INTPTR_FORMAT " %7d %s", p, size, name == NULL ? "" : name);