Skip to content

Commit

Permalink
Add matched user-defined placement delete operator
Browse files Browse the repository at this point in the history
When memory is allocated for an object with operator new, the object's
constructor is called. If the constructor throws an exception, any
memory that was allocated for the object should be deallocated. This
cannot take place unless an operator `delete` function exists that matches
the operator `new`.

The compiler code generates a lot of **C4291** warnings because no placement
form of operator `delete` has been defined that matches the placement form
of operator `new`.

The detailes are described on MSDN:
https://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx

The commit adds missed placement forms of operator `delete` to the
compiler code.

For the optimizator files bellow:

 * `OMROptimization.hpp`
 * `DataFlowAnalysis.hpp`
 * `UseDefInfo.hpp`
 * `SinkStores.hpp`
 * `ValueNumberInfo.hpp`
 * `OptimizationPolicy.hpp`
 * `OptimizationUtil.hpp`
 * `OMROptimizationManager.hpp`

the placement `delete` operator

`static void  operator delete(void *ptr, TR::Allocator a)`

does nothing: @dsouzai has confirmed these objects exist only during
a compilation. If there is an exception thrown during construction,
the compilation will be aborted, and all memory associated with that
compilation will get freed (when `TR::SegmentAllocator &scratchSegmentProvider`
goes out of scope).

Signed-off-by: Pavel Samolysov <[email protected]>
  • Loading branch information
samolisov committed Jul 31, 2018
1 parent b97f34e commit f76d2c5
Show file tree
Hide file tree
Showing 19 changed files with 110 additions and 20 deletions.
17 changes: 11 additions & 6 deletions compiler/env/TRMemory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,14 @@ TR_HeapMemory::allocate(size_t size, TR_MemoryBase::ObjectType ot)
static void jitPersistentFree(void *mem) {TR_Memory::jitPersistentFree(mem); }

#define TR_PERSISTENT_NEW(a) \
void * operator new (size_t s, PERSISTENT_NEW_DECLARE) throw() {return TR_Memory::jitPersistentAlloc(s, a);} \
void * operator new[] (size_t s, PERSISTENT_NEW_DECLARE) throw() {return TR_Memory::jitPersistentAlloc(s, a);} \
void * operator new (size_t s, TR_PersistentMemory * m) throw() {return m->allocatePersistentMemory(s, a);} \
void * operator new[] (size_t s, TR_PersistentMemory * m) throw() {return m->allocatePersistentMemory(s, a);} \
void * operator new (size_t s, PERSISTENT_NEW_DECLARE) throw() { return TR_Memory::jitPersistentAlloc(s, a); } \
void operator delete (void *p, PERSISTENT_NEW_DECLARE) throw() { TR_Memory::jitPersistentFree(p); } \
void * operator new[] (size_t s, PERSISTENT_NEW_DECLARE) throw() { return TR_Memory::jitPersistentAlloc(s, a); } \
void operator delete[] (void *p, PERSISTENT_NEW_DECLARE) throw() { TR_Memory::jitPersistentFree(p); } \
void * operator new (size_t s, TR_PersistentMemory * m) throw() { return m->allocatePersistentMemory(s, a); } \
void operator delete (void *p, TR_PersistentMemory *m) throw() { m->freePersistentMemory(p); } \
void * operator new[] (size_t s, TR_PersistentMemory * m) throw() { return m->allocatePersistentMemory(s, a); } \
void operator delete[] (void *p, TR_PersistentMemory *m) throw() { m->freePersistentMemory(p); } \
void operator delete (void *p, size_t s) throw() { TR_ASSERT(false, "Invalid use of operator delete"); }

#define TR_ALLOC_WITHOUT_NEW(a) \
Expand All @@ -773,7 +777,8 @@ TR_HeapMemory::allocate(size_t size, TR_MemoryBase::ObjectType ot)
#define TR_ALLOC_IMPL(a) \
TR_ALLOC_WITHOUT_NEW(a) \
TR_PERSISTENT_NEW(a) \
void * operator new (size_t s, TR_ArenaAllocator *m) {return m->allocate(s);} \
void * operator new (size_t s, TR_ArenaAllocator *m) { return m->allocate(s); } \
void operator delete(void *p, TR_ArenaAllocator *m) { /* TR_ArenaAllocator contains an empty deallocator */ } \
void * operator new (size_t s, TR_HeapMemory m, TR_MemoryBase::ObjectType ot = a) { return m.allocate(s,ot); } \
void operator delete(void *p, TR_HeapMemory m, TR_MemoryBase::ObjectType ot) { return m.deallocate(p); } \
void * operator new[] (size_t s, TR_HeapMemory m, TR_MemoryBase::ObjectType ot = a) { return m.allocate(s,ot); } \
Expand All @@ -792,7 +797,7 @@ TR_HeapMemory::allocate(size_t size, TR_MemoryBase::ObjectType ot)
void operator delete(void * p, TR::Region &region) { region.deallocate(p); } \
void * operator new[](size_t size, TR::Region &region) { return region.allocate(size); } \
void operator delete[](void * p, TR::Region &region) { region.deallocate(p); } \
static TrackedPersistentAllocator getPersistentAllocator() { return TrackedPersistentAllocator(); } \
static TrackedPersistentAllocator getPersistentAllocator() { return TrackedPersistentAllocator(); }

#define TR_ALLOC(a) \
typedef TR_TypedPersistentAllocatorBase TrackedPersistentAllocator; \
Expand Down
10 changes: 8 additions & 2 deletions compiler/il/NodeExtension.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -49,10 +49,16 @@ class NodeExtension

void * operator new (size_t s, uint16_t arrayElems, TR_NodeExtAllocator & m)
{
s+= (arrayElems-NUM_DEFAULT_ELEMS) * sizeof(uintptr_t);
s += (arrayElems - NUM_DEFAULT_ELEMS) * sizeof(uintptr_t);
return m.allocate(s);
}

void operator delete(void * ptr, uint16_t arrayElems, TR_NodeExtAllocator & m)
{
size_t size = sizeof(NodeExtension) + (arrayElems - NUM_DEFAULT_ELEMS) * sizeof(uintptr_t);
return m.deallocate(ptr, size);
}

void operator delete(void * ptr, size_t s, TR_NodeExtAllocator & m)
{
m.deallocate(ptr,s);
Expand Down
12 changes: 12 additions & 0 deletions compiler/il/OMRNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,24 @@ OMR::Node::operator new(size_t s, TR::NodePool& nodes)
return (void *) nodes.allocate();
}

void
OMR::Node::operator delete(void *node, TR::NodePool& nodes)
{
nodes.deallocate((TR::Node *) node);
}

void *
OMR::Node::operator new(size_t s, void *ptr) throw()
{
return ::operator new(s, ptr);
}

void
OMR::Node::operator delete(void *node, void *ptr) throw()
{
::operator delete(node, ptr);
}

OMR::Node::Node()
: _opCode(TR::BadILOp),
_numChildren(0),
Expand Down
2 changes: 2 additions & 0 deletions compiler/il/OMRNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ class OMR_EXTENSIBLE Node
~Node();

void * operator new(size_t s, TR::NodePool & nodePool);
void operator delete(void *node, TR::NodePool& nodes);
void * operator new(size_t s, void *ptr) throw();
void operator delete(void *node, void *ptr) throw();

static TR::Node *copy(TR::Node *);
static TR::Node *copy(TR::Node *, int32_t numChildren);
Expand Down
8 changes: 7 additions & 1 deletion compiler/il/OMRTreeTop.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -219,6 +219,12 @@ OMR::TreeTop::operator new(size_t s, bool trace, TR_Memory * m)
return tt;
}

void
OMR::TreeTop::operator delete(void *p, bool trace, TR_Memory *m)
{
m->freeMemory(p, TR_AllocationKind::heapAlloc);
}

OMR::TreeTop::TreeTop(TR::TreeTop *precedingTreeTop, TR::Node *node, TR::Compilation * c) :
_pNode(node)
{
Expand Down
3 changes: 2 additions & 1 deletion compiler/il/OMRTreeTop.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -71,6 +71,7 @@ class OMR_EXTENSIBLE TreeTop
static void removeDeadTrees(TR::Compilation * comp, TR::TreeTop* first, TR::TreeTop* last);

void * operator new(size_t s, bool trace, TR_Memory *m);
void operator delete(void *ptr, bool trace, TR_Memory *m);

explicit TreeTop(
TR::Node *node = NULL,
Expand Down
7 changes: 7 additions & 0 deletions compiler/infra/List.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ template <class T> class ListElement
}
return rc;
}

void operator delete(void *ptr, List<T>& freeList)
{
// the freeList was modified during the new operator invocation
operator delete(ptr, freeList.getRegion());
}

ListElement(T *p, ListElement<T> *q = NULL) : _pNext(q), _pDatum(p) {}

T *getData() {return _pDatum;}
Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/DataFlowAnalysis.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -109,6 +109,11 @@ class TR_DataFlowAnalysis

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((TR_DataFlowAnalysis*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() better return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/OMROptimization.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -59,6 +59,11 @@ class OMR_EXTENSIBLE Optimization: public TR_HasRandomGenerator

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((Optimization*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() better return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/OMROptimizationManager.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -64,6 +64,11 @@ class OMR_EXTENSIBLE OptimizationManager

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((OptimizationManager*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() must return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/OptimizationPolicy.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -33,6 +33,11 @@ class OptimizationPolicy
public:
static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((OptimizationPolicy*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() must return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/OptimizationUtil.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -33,6 +33,11 @@ class OptimizationUtil
public:
static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((OptimizationUtil*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() must return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/SinkStores.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -55,6 +55,11 @@ class TR_LiveOnNotAllPaths

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((TR_LiveOnNotAllPaths*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() must return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/UseDefInfo.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -66,6 +66,11 @@ class TR_UseDefInfo

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((TR_UseDefInfo*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() better return the same allocator as used for new */

Expand Down
7 changes: 6 additions & 1 deletion compiler/optimizer/ValueNumberInfo.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -41,6 +41,11 @@ class TR_ValueNumberInfo

static void *operator new(size_t size, TR::Allocator a)
{ return a.allocate(size); }
static void operator delete(void *ptr, TR::Allocator a)
{
// If there is an exception thrown during construction, the compilation
// will be aborted, and all memory associated with that compilation will get freed.
}
static void operator delete(void *ptr, size_t size)
{ ((TR_ValueNumberInfo*)ptr)->allocator().deallocate(ptr, size); } /* t->allocator() must return the same allocator as used for new */

Expand Down
5 changes: 4 additions & 1 deletion compiler/runtime/CodeCacheTypes.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -76,6 +76,8 @@ class CodeCacheHashEntrySlab

void *operator new(size_t s, CodeCacheHashEntrySlab *slab) { return slab; }

void operator delete(void *ptr, CodeCacheHashEntrySlab *slab) { /* do nothing */ }

static CodeCacheHashEntrySlab *allocate(TR::CodeCacheManager *manager, size_t slabSize);
void free(TR::CodeCacheManager *manager);

Expand Down Expand Up @@ -112,6 +114,7 @@ class CodeCacheHashTable
CodeCacheHashTable() { }

void *operator new(size_t s, CodeCacheHashTable *table) { return table; }
void operator delete(void *p, CodeCacheHashTable *table) { /* do nothing */ }

static CodeCacheHashTable *allocate(TR::CodeCacheManager *codeCacheManager);
static size_t hashUnresolvedMethod(void *constPool, int32_t constPoolIndex);
Expand Down
1 change: 1 addition & 0 deletions compiler/runtime/OMRCodeCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class OMR_EXTENSIBLE CodeCache : public CodeCacheBase
CodeCache() { }

void *operator new(size_t s, TR::CodeCache *cache) { return cache; }
void operator delete(void *p, TR::CodeCache *cache) { /* do nothing */ }


class CacheCriticalSection : public CriticalSection
Expand Down
2 changes: 2 additions & 0 deletions compiler/runtime/OMRCodeCacheMemorySegment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class OMR_EXTENSIBLE CodeCacheMemorySegment

void *operator new(size_t size, TR::CodeCacheMemorySegment *segment) { return segment; }

void operator delete(void *pmem, TR::CodeCacheMemorySegment *segment) { /* do nothing */ }

uint8_t *segmentBase() const { return _base; }
uint8_t *segmentAlloc() const { return _alloc; }
uint8_t *segmentTop() const { return _top; }
Expand Down
7 changes: 6 additions & 1 deletion compiler/x/codegen/OMRRegisterDependency.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -76,6 +76,11 @@ class TR_X86RegisterDependencyGroup
return m->allocateHeapMemory(s);
}

void operator delete(void *p, int32_t numDependencies, TR_Memory * m)
{
m->freeMemory(p, TR_AllocationKind::heapAlloc);
}

public:

TR_X86RegisterDependencyGroup() {_mayNeedToPopFPRegisters = false; _needToClearFPStack = false;}
Expand Down

0 comments on commit f76d2c5

Please sign in to comment.