hotspot/src/share/vm/memory/allocation.cpp
changeset 7440 eabaf35910a1
parent 7397 5b173b4ca846
child 8320 544210b4dd48
equal deleted inserted replaced
7439:572e3f624901 7440:eabaf35910a1
    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