2013-08-01 14:27:40 +04:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Vassil Vassilev <vvasilev@cern.ch>
2014-01-07 14:08:37 +04:00
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
2013-08-01 14:27:40 +04:00
//------------------------------------------------------------------------------
# ifndef CLING_TRANSACTION_POOL_H
# define CLING_TRANSACTION_POOL_H
# include "cling/Interpreter/Transaction.h"
# include "llvm/ADT/SmallVector.h"
2013-08-04 20:31:52 +04:00
namespace clang {
2014-03-28 17:53:34 +04:00
class Sema ;
2013-08-04 20:31:52 +04:00
}
2013-08-01 14:27:40 +04:00
namespace cling {
class TransactionPool {
# define TRANSACTIONS_IN_BLOCK 8
2013-10-29 22:06:52 +04:00
# define POOL_SIZE 2 * TRANSACTIONS_IN_BLOCK
2013-08-01 14:27:40 +04:00
private :
// It is twice the size of the block because there might be easily around 8
// transactions in flight which can be empty, which might lead to refill of
// the smallvector and then the return for reuse will exceed the capacity
// of the smallvector causing redundant copy of the elements.
//
2013-10-29 22:06:52 +04:00
llvm : : SmallVector < Transaction * , POOL_SIZE > m_Transactions ;
2013-08-01 14:27:40 +04:00
public :
2016-06-27 02:43:40 +03:00
TransactionPool ( ) { }
2013-08-01 14:27:40 +04:00
~ TransactionPool ( ) {
2016-06-27 02:43:40 +03:00
// Only free the memory as anything put in m_Transactions will have
// already been destructed in releaseTransaction
for ( Transaction * T : m_Transactions )
: : operator delete ( T ) ;
2013-08-01 14:27:40 +04:00
}
2016-06-27 02:43:40 +03:00
Transaction * takeTransaction ( clang : : Sema & S ) {
Transaction * T ;
if ( kDebugMode | | m_Transactions . empty ( ) ) {
T = ( Transaction * ) : : operator new ( sizeof ( Transaction ) ) ;
new ( T ) Transaction ( S ) ;
} else
T = new ( m_Transactions . pop_back_val ( ) ) Transaction ( S ) ;
2014-04-15 19:26:44 +04:00
2013-08-04 20:38:42 +04:00
return T ;
2013-08-01 14:27:40 +04:00
}
2016-06-27 02:43:40 +03:00
void releaseTransaction ( Transaction * T , bool reuse = true ) {
if ( reuse ) {
assert ( ( T - > getState ( ) = = Transaction : : kCompleted | |
T - > getState ( ) = = Transaction : : kRolledBack )
& & " Transaction must completed! " ) ;
}
2014-04-14 18:53:39 +04:00
2015-06-08 15:50:58 +03:00
// Tell the parent that T is gone.
if ( T - > getParent ( ) )
T - > getParent ( ) - > removeNestedTransaction ( T ) ;
2014-04-14 18:53:39 +04:00
2015-06-08 15:50:58 +03:00
T - > ~ Transaction ( ) ;
2016-06-27 02:43:40 +03:00
// don't overflow the pool
if ( reuse & & ( m_Transactions . size ( ) < POOL_SIZE ) ) {
T - > m_State = Transaction : : kNumStates ;
m_Transactions . push_back ( T ) ;
}
else
: : operator delete ( T ) ;
2013-08-01 14:27:40 +04:00
}
2016-06-27 02:43:40 +03:00
2013-10-29 22:06:52 +04:00
# undef POOL_SIZE
2013-08-01 14:27:40 +04:00
# undef TRANSACTIONS_IN_BLOCK
} ;
} // end namespace cling
# endif // CLING_TRANSACTION_POOL_H