src/share/vm/memory/allocation.cpp

changeset 2357
79d8657be916
parent 2314
f95d63e2154a
child 2557
f7de3327c683
     1.1 --- a/src/share/vm/memory/allocation.cpp	Wed Dec 08 17:50:49 2010 -0800
     1.2 +++ b/src/share/vm/memory/allocation.cpp	Fri Dec 10 14:14:02 2010 -0800
     1.3 @@ -73,7 +73,7 @@
     1.4  void ResourceObj::operator delete(void* p) {
     1.5    assert(((ResourceObj *)p)->allocated_on_C_heap(),
     1.6           "delete only allowed for C_HEAP objects");
     1.7 -  DEBUG_ONLY(((ResourceObj *)p)->_allocation = (uintptr_t)badHeapOopVal;)
     1.8 +  DEBUG_ONLY(((ResourceObj *)p)->_allocation_t[0] = (uintptr_t)badHeapOopVal;)
     1.9    FreeHeap(p);
    1.10  }
    1.11  
    1.12 @@ -83,43 +83,73 @@
    1.13      uintptr_t allocation = (uintptr_t)res;
    1.14      assert((allocation & allocation_mask) == 0, "address should be aligned to 4 bytes at least");
    1.15      assert(type <= allocation_mask, "incorrect allocation type");
    1.16 -    ((ResourceObj *)res)->_allocation = ~(allocation + type);
    1.17 +    ResourceObj* resobj = (ResourceObj *)res;
    1.18 +    resobj->_allocation_t[0] = ~(allocation + type);
    1.19 +    if (type != STACK_OR_EMBEDDED) {
    1.20 +      // Called from operator new() and CollectionSetChooser(),
    1.21 +      // set verification value.
    1.22 +      resobj->_allocation_t[1] = (uintptr_t)&(resobj->_allocation_t[1]) + type;
    1.23 +    }
    1.24  }
    1.25  
    1.26  ResourceObj::allocation_type ResourceObj::get_allocation_type() const {
    1.27 -    assert(~(_allocation | allocation_mask) == (uintptr_t)this, "lost resource object");
    1.28 -    return (allocation_type)((~_allocation) & allocation_mask);
    1.29 +    assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this, "lost resource object");
    1.30 +    return (allocation_type)((~_allocation_t[0]) & allocation_mask);
    1.31 +}
    1.32 +
    1.33 +bool ResourceObj::is_type_set() const {
    1.34 +    allocation_type type = (allocation_type)(_allocation_t[1] & allocation_mask);
    1.35 +    return get_allocation_type()  == type &&
    1.36 +           (_allocation_t[1] - type) == (uintptr_t)(&_allocation_t[1]);
    1.37  }
    1.38  
    1.39  ResourceObj::ResourceObj() { // default constructor
    1.40 -    if (~(_allocation | allocation_mask) != (uintptr_t)this) {
    1.41 +    if (~(_allocation_t[0] | allocation_mask) != (uintptr_t)this) {
    1.42 +      // Operator new() is not called for allocations
    1.43 +      // on stack and for embedded objects.
    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 if (allocated_on_stack()) { // STACK_OR_EMBEDDED
    1.50 +      // For some reason we got a value which resembles
    1.51 +      // an embedded or stack object (operator new() does not
    1.52 +      // set such type). Keep it since it is valid value
    1.53 +      // (even if it was garbage).
    1.54 +      // Ignore garbage in other fields.
    1.55 +    } else if (is_type_set()) {
    1.56 +      // Operator new() was called and type was set.
    1.57 +      assert(!allocated_on_stack(),
    1.58 +             err_msg("not embedded or stack, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
    1.59 +                     this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
    1.60      } else {
    1.61 -      assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena(),
    1.62 -             "allocation_type should be set by operator new()");
    1.63 +      // Operator new() was not called.
    1.64 +      // Assume that it is embedded or stack object.
    1.65 +      set_allocation_type((address)this, STACK_OR_EMBEDDED);
    1.66      }
    1.67 +    _allocation_t[1] = 0; // Zap verification value
    1.68  }
    1.69  
    1.70  ResourceObj::ResourceObj(const ResourceObj& r) { // default copy constructor
    1.71      // Used in ClassFileParser::parse_constant_pool_entries() for ClassFileStream.
    1.72 +    // Note: garbage may resembles valid value.
    1.73 +    assert(~(_allocation_t[0] | allocation_mask) != (uintptr_t)this || !is_type_set(),
    1.74 +           err_msg("embedded or stack only, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
    1.75 +                   this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
    1.76      set_allocation_type((address)this, STACK_OR_EMBEDDED);
    1.77 +    _allocation_t[1] = 0; // Zap verification value
    1.78  }
    1.79  
    1.80  ResourceObj& ResourceObj::operator=(const ResourceObj& r) { // default copy assignment
    1.81      // Used in InlineTree::ok_to_inline() for WarmCallInfo.
    1.82 -    assert(allocated_on_stack(), "copy only into local");
    1.83 -    // Keep current _allocation value;
    1.84 +    assert(allocated_on_stack(),
    1.85 +           err_msg("copy only into local, this(" PTR_FORMAT ") type %d a[0]=(" PTR_FORMAT ") a[1]=(" PTR_FORMAT ")",
    1.86 +                   this, get_allocation_type(), _allocation_t[0], _allocation_t[1]));
    1.87 +    // Keep current _allocation_t value;
    1.88      return *this;
    1.89  }
    1.90  
    1.91  ResourceObj::~ResourceObj() {
    1.92      // allocated_on_C_heap() also checks that encoded (in _allocation) address == this.
    1.93 -    if (!allocated_on_C_heap()) {  // ResourceObj::delete() zaps _allocation for C_heap.
    1.94 -      _allocation = (uintptr_t)badHeapOopVal; // zap type
    1.95 +    if (!allocated_on_C_heap()) { // ResourceObj::delete() will zap _allocation for C_heap.
    1.96 +      _allocation_t[0] = (uintptr_t)badHeapOopVal; // zap type
    1.97      }
    1.98  }
    1.99  #endif // ASSERT

mercurial