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); }
|