CXXR (C++ R)
RAllocStack.h
Go to the documentation of this file.
1 /*CXXR $Id: RAllocStack.h 1348 2013-02-25 17:49:03Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-13 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation; either version 2.1 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, a copy is available at
32  * http://www.r-project.org/Licenses/
33  */
34 
42 #ifndef RALLOCSTACK_H
43 #define RALLOCSTACK_H 1
44 
45 #include <stddef.h>
46 
47 #ifdef __cplusplus
48 
49 #include <stack>
50 #include <vector>
51 #include "CXXR/config.hpp"
52 #include "CXXR/SchwarzCounter.hpp"
53 
54 namespace CXXR {
60  class RAllocStack {
61  public:
70  class Scope {
71  public:
72  Scope()
73 #ifndef NDEBUG
74  : m_next_scope(RAllocStack::s_innermost_scope),
75  m_saved_size(RAllocStack::size())
76 #else
77  : m_saved_size(RAllocStack::size())
78 #endif
79  {
80 #ifndef NDEBUG
81  RAllocStack::s_innermost_scope = this;
82 #endif
83  }
84 
85  ~Scope()
86  {
87  if (RAllocStack::size() != m_saved_size)
88  RAllocStack::trim(m_saved_size);
89 #ifndef NDEBUG
90  RAllocStack::s_innermost_scope = m_next_scope;
91 #endif
92  }
93 
100  size_t startSize() const
101  {
102  return m_saved_size;
103  }
104  private:
105 #ifndef NDEBUG
106  Scope* m_next_scope;
107 #endif
108  size_t m_saved_size;
109  };
110 
119  static void* allocate(size_t sz);
120 
134  static void restoreSize(size_t new_size);
135 
143  static size_t size()
144  {
145  return s_stack->size();
146  }
147  private:
148  typedef std::pair<size_t, void*> Pair;
149  typedef std::stack<Pair, std::vector<Pair> > Stack;
150  static Stack* s_stack;
151 #ifndef NDEBUG
152  static Scope* s_innermost_scope;
153 #endif
154 
155  // Not implemented. Declared to stop the compiler generating
156  // a constructor.
157  RAllocStack();
158 
159  // Clean up static data members:
160  static void cleanup();
161 
162  // Initialize the static data members:
163  static void initialize();
164 
165  // Pop entries off the stack to reduce its size to new_size,
166  // which must be no greater than the current size.
167  static void trim(size_t new_size);
168 
169  friend class SchwarzCounter<RAllocStack>;
170  };
171 } // namespace CXXR
172 
173 namespace {
174  CXXR::SchwarzCounter<CXXR::RAllocStack> rallocstack_schwarz_ctr;
175 }
176 
177 extern "C" {
178 #endif /* __cplusplus */
179 
180  /* ***** C interface ***** */
181 
201  char* R_alloc(size_t num_elts, int elt_size);
202 
203 #ifdef __cplusplus
204 
225  inline void* CXXR_alloc(size_t num_elts, int elt_size)
226  {
227  return static_cast<void*>(R_alloc(num_elts, elt_size));
228  }
229 #endif
230 
243  char* S_alloc(long num_elts, int elt_size);
244 
265  char* S_realloc(char *prev_block, long new_sz, long old_sz, int elt_size);
266 
278 #ifndef __cplusplus
279  void* vmaxget(void);
280 #else
281  inline void* vmaxget(void)
282  {
283  return static_cast<char*>(0) + CXXR::RAllocStack::size();
284  }
285 #endif
286 
299 #ifndef __cplusplus
300  void vmaxset(const void* stack_sizep);
301 #else
302  inline void vmaxset(const void* stack_sizep)
303  {
304  size_t stack_size = static_cast<const char*>(stack_sizep)
305  - static_cast<const char*>(0);
306  CXXR::RAllocStack::restoreSize(stack_size);
307  }
308 #endif
309 
310 #ifdef __cplusplus
311 } /* extern "C" */
312 #endif
313 
314 #endif // RALLOCSTACK_H