71 } |
71 } |
72 |
72 |
73 void ResourceObj::operator delete(void* p) { |
73 void ResourceObj::operator delete(void* p) { |
74 assert(((ResourceObj *)p)->allocated_on_C_heap(), |
74 assert(((ResourceObj *)p)->allocated_on_C_heap(), |
75 "delete only allowed for C_HEAP objects"); |
75 "delete only allowed for C_HEAP objects"); |
76 DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;) |
76 DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;) |
77 FreeHeap(p); |
77 FreeHeap(p); |
78 } |
78 } |
79 |
79 |
80 #ifdef ASSERT |
80 #ifdef ASSERT |
81 void ResourceObj::set_allocation_type(address res, allocation_type type) { |
81 void ResourceObj::set_allocation_type(address res, allocation_type type) { |
82 // Set allocation type in the resource object |
82 // Set allocation type in the resource object |
83 uintptr_t allocation = (uintptr_t)res; |
83 uintptr_t allocation = (uintptr_t)res; |
84 assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); |
84 assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least"); |
85 assert(type <= allocation_mask, "incorrect allocation type"); |
85 assert(type <= allocation_mask, "incorrect allocation type"); |
86 ((ResourceObj *)res)->_allocation = ~(allocation + type); |
86 ResourceObj* resobj = (ResourceObj *)res; |
|
87 resobj->_allocation_t[0] = ~(allocation + type); |
|
88 if (type != STACK_OR_EMBEDDED) { |
|
89 // Called from operator new() and CollectionSetChooser(), |
|
90 // set verification value. |
|
91 resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type; |
|
92 } |
87 } |
93 } |
88 |
94 |
89 ResourceObj::allocation_type ResourceObj::get_allocation_type() const { |
95 ResourceObj::allocation_type ResourceObj::get_allocation_type() const { |
90 assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object"); |
96 assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object"); |
91 return (allocation_type)((~_allocation) & allocation_mask); |
97 return (allocation_type)((~_allocation_t[0]) & allocation_mask); |
|
98 } |
|
99 |
|
100 bool ResourceObj::is_type_set() const { |
|
101 allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask); |
|
102 return get_allocation_type() == type && |
|
103 (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]); |
92 } |
104 } |
93 |
105 |
94 ResourceObj::ResourceObj() { // default constructor |
106 ResourceObj::ResourceObj() { // default constructor |
95 if (~(_allocation | allocation_mask) != (uintptr_t)this) { |
107 if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) { |
|
108 // Operator new() is not called for allocations |
|
109 // on stack and for embedded objects. |
96 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
110 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
97 } else if (allocated_on_stack()) { |
111 } else if (allocated_on_stack()) { // STACK_OR_EMBEDDED |
98 // For some reason we got a value which looks like an allocation on stack. |
112 // For some reason we got a value which resembles |
99 // Pass if it is really allocated on stack. |
113 // an embedded or stack object (operator new() does not |
100 assert(Thread::current()->on_local_stack((address)this),"should be on stack"); |
114 // set such type). Keep it since it is valid value |
|
115 // (even if it was garbage). |
|
116 // Ignore garbage in other fields. |
|
117 } else if (is_type_set()) { |
|
118 // Operator new() was called and type was set. |
|
119 assert(!allocated_on_stack(), |
|
120 err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
|
121 this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
101 } else { |
122 } else { |
102 assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(), |
123 // Operator new() was not called. |
103 "allocation_type should be set by operator new()"); |
124 // Assume that it is embedded or stack object. |
104 } |
125 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
|
126 } |
|
127 _allocation_t[1] = 0; // Zap verification value |
105 } |
128 } |
106 |
129 |
107 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor |
130 ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor |
108 // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. |
131 // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. |
|
132 // Note: garbage may resembles valid value. |
|
133 assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), |
|
134 err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
|
135 this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
109 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
136 set_allocation_type((address)this, STACK_OR_EMBEDDED); |
|
137 _allocation_t[1] = 0; // Zap verification value |
110 } |
138 } |
111 |
139 |
112 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment |
140 ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment |
113 // Used in InlineTree::ok_to_inline() for WarmCallInfo. |
141 // Used in InlineTree::ok_to_inline() for WarmCallInfo. |
114 assert(allocated_on_stack(), "copy only into local"); |
142 assert(allocated_on_stack(), |
115 // Keep current _allocation value; |
143 err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", |
|
144 this, get_allocation_type(), _allocation_t[0], _allocation_t[1])); |
|
145 // Keep current _allocation_t value; |
116 return *this; |
146 return *this; |
117 } |
147 } |
118 |
148 |
119 ResourceObj::~ResourceObj() { |
149 ResourceObj::~ResourceObj() { |
120 // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. |
150 // allocated_on_C_heap() also checks that encoded (in _allocation) address == this. |
121 if (!allocated_on_C_heap()) { // ResourceObj::delete() zaps _allocation for C_heap. |
151 if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap. |
122 _allocation = (uintptr_t)badHeapOopVal; // zap type |
152 _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type |
123 } |
153 } |
124 } |
154 } |
125 #endif // ASSERT |
155 #endif // ASSERT |
126 |
156 |
127 |
157 |