--- old/src/hotspot/share/memory/allocation.cpp 2018-11-18 18:52:44.204965658 -0500 +++ new/src/hotspot/share/memory/allocation.cpp 2018-11-18 18:52:43.936951602 -0500 @@ -186,7 +186,12 @@ (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]); } -ResourceObj::ResourceObj() { // default constructor +// This whole business of passing information from ResourceObj::operator new +// to the ResourceObj constructor via fields in the "object" is technically UB. +// But it seems to work within the limitations of HotSpot usage (such as no +// multiple inheritance) with the compilers and compiler options we're using. +// And it gives some possibly useful checking for misuse of ResourceObj. +void ResourceObj::initialize_allocation_info() { if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) { // Operator new() is not called for allocations // on stack and for embedded objects. @@ -210,21 +215,16 @@ _allocation_t[1] = 0; // Zap verification value } -ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor - // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream. - // Note: garbage may resembles valid value. - assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(), - "embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]); - set_allocation_type((address)this, STACK_OR_EMBEDDED); - _allocation_t[1] = 0; // Zap verification value +ResourceObj::ResourceObj() { + initialize_allocation_info(); +} + +ResourceObj::ResourceObj(const ResourceObj&) { + // Initialize _allocation_t as a new object, ignoring object being copied. + initialize_allocation_info(); } -ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment - // Used in InlineTree::ok_to_inline() for WarmCallInfo. - assert(allocated_on_stack(), - "copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")", - p2i(this), get_allocation_type(), _allocation_t[0], _allocation_t[1]); +ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // Keep current _allocation_t value; return *this; }