Unify some duplicated heap management.
Create the permaheap class to hold common code from the vvp_net_fun_t and vvp_net_fil_t classes.
This commit is contained in:
parent
5a96b397e4
commit
d64b1f0275
|
|
@ -73,8 +73,8 @@ vpip_to_dec.o vpip_format.o vvp_vpi.o
|
|||
|
||||
O = main.o parse.o parse_misc.o lexor.o arith.o array.o bufif.o compile.o \
|
||||
concat.o \
|
||||
dff.o extend.o npmos.o part.o reduce.o resolv.o sfunc.o stop.o symbols.o \
|
||||
ufunc.o codes.o \
|
||||
dff.o extend.o npmos.o part.o permaheap.o reduce.o resolv.o sfunc.o stop.o \
|
||||
symbols.o ufunc.o codes.o \
|
||||
vthread.o schedule.o statistics.o tables.o udp.o vvp_island.o vvp_net.o \
|
||||
vvp_net_sig.o event.o logic.o delay.o words.o island_tran.o $V
|
||||
|
||||
|
|
|
|||
|
|
@ -373,11 +373,13 @@ int main(int argc, char*argv[])
|
|||
|
||||
if (verbose_flag) {
|
||||
vpi_mcd_printf(1, " ... %8lu functors (net_fun pool=%zu bytes)\n",
|
||||
count_functors, size_vvp_net_funs);
|
||||
count_functors, vvp_net_fun_t::heap_total());
|
||||
vpi_mcd_printf(1, " %8lu logic\n", count_functors_logic);
|
||||
vpi_mcd_printf(1, " %8lu bufif\n", count_functors_bufif);
|
||||
vpi_mcd_printf(1, " %8lu resolv\n",count_functors_resolv);
|
||||
vpi_mcd_printf(1, " %8lu signals\n", count_functors_sig);
|
||||
vpi_mcd_printf(1, " ... %8lu filters (net_fil pool=%zu bytes)\n",
|
||||
count_filters, vvp_net_fil_t::heap_total());
|
||||
vpi_mcd_printf(1, " ... %8lu opcodes (%zu bytes)\n",
|
||||
count_opcodes, size_opcodes);
|
||||
vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "permaheap.h"
|
||||
# include <assert.h>
|
||||
|
||||
permaheap::permaheap()
|
||||
{
|
||||
chunk_ptr_ = initial_chunk_.bytes;
|
||||
chunk_remaining_ = sizeof(initial_chunk_);
|
||||
heap_total_ = chunk_remaining_;
|
||||
}
|
||||
|
||||
permaheap::~permaheap()
|
||||
{
|
||||
}
|
||||
|
||||
void* permaheap::alloc(size_t size)
|
||||
{
|
||||
assert(size <= CHUNK_SIZE);
|
||||
|
||||
if (size > chunk_remaining_) {
|
||||
chunk_ptr_ = ::new char[CHUNK_SIZE];
|
||||
chunk_remaining_ = CHUNK_SIZE;
|
||||
heap_total_ += CHUNK_SIZE;
|
||||
}
|
||||
|
||||
assert( (size%sizeof(void*)) == 0 );
|
||||
|
||||
void*res = chunk_ptr_;
|
||||
chunk_ptr_ += size;
|
||||
chunk_remaining_ -= size;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef __permaheap_H
|
||||
#define __permaheap_H
|
||||
/*
|
||||
* Copyright (c) 2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include <stdlib.h>
|
||||
|
||||
class permaheap {
|
||||
|
||||
public:
|
||||
explicit permaheap();
|
||||
~permaheap();
|
||||
|
||||
void* alloc(size_t size);
|
||||
|
||||
size_t heap_total() const { return heap_total_; }
|
||||
|
||||
private:
|
||||
enum { INITIAL_CHUNK_SIZE = 512*1024, CHUNK_SIZE=256*1024 };
|
||||
|
||||
union {
|
||||
void*align;
|
||||
char bytes[INITIAL_CHUNK_SIZE];
|
||||
} initial_chunk_;
|
||||
|
||||
char*chunk_ptr_;
|
||||
size_t chunk_remaining_;
|
||||
size_t heap_total_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -30,6 +30,7 @@ unsigned long count_functors_bufif = 0;
|
|||
unsigned long count_functors_resolv= 0;
|
||||
unsigned long count_functors_sig = 0;
|
||||
|
||||
unsigned long count_filters = 0;
|
||||
unsigned long count_vpi_nets = 0;
|
||||
|
||||
unsigned long count_vpi_scopes = 0;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ extern unsigned long count_functors_logic;
|
|||
extern unsigned long count_functors_bufif;
|
||||
extern unsigned long count_functors_resolv;
|
||||
extern unsigned long count_functors_sig;
|
||||
extern unsigned long count_filters;
|
||||
extern unsigned long count_vvp_nets;
|
||||
extern unsigned long count_vpi_nets;
|
||||
extern unsigned long count_vpi_scopes;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
# include <map>
|
||||
#endif
|
||||
|
||||
permaheap vvp_net_fun_t::heap_;
|
||||
permaheap vvp_net_fil_t::heap_;
|
||||
|
||||
// Allocate around 1Megbytes/chunk.
|
||||
static const size_t VVP_NET_CHUNK = 1024*1024/sizeof(vvp_net_t);
|
||||
static vvp_net_t*vvp_net_alloc_table = 0;
|
||||
|
|
@ -47,7 +50,6 @@ static size_t vvp_net_alloc_remaining = 0;
|
|||
// chunks allocated.
|
||||
unsigned long count_vvp_nets = 0;
|
||||
size_t size_vvp_nets = 0;
|
||||
size_t size_vvp_net_funs = 0;
|
||||
|
||||
void* vvp_net_t::operator new (size_t size)
|
||||
{
|
||||
|
|
@ -156,39 +158,6 @@ void vvp_net_t::unlink(vvp_net_ptr_t dst_ptr)
|
|||
net->port[net_port] = vvp_net_ptr_t(0,0);
|
||||
}
|
||||
|
||||
void* vvp_net_fun_t::permalloc(size_t size)
|
||||
{
|
||||
// Link in an initial chunk of space for net_fun_t
|
||||
// objects. This chunk doesn't need to be the same size as the
|
||||
// subsequent chunks, but we do need to make sure it is
|
||||
// aligned with pointer alignment. (Hence the union with "align".)
|
||||
static union { void*align; char bytes[512*1024]; } initial_chunk;
|
||||
|
||||
// Initialize the pointer to the initial chunk.
|
||||
static char*chunk_ptr = initial_chunk.bytes;
|
||||
static size_t chunk_remaining = sizeof(initial_chunk);
|
||||
|
||||
// Once the initial chunk fills up, allocate new chunks in
|
||||
// fairly large blocks to reduce the system allocator
|
||||
// overhead, but not such big chunks that we create our own
|
||||
// waste. (Expect the typical waste to be CHUNK_BYTES/2.)
|
||||
const size_t CHUNK_BYTES = 256*1024;
|
||||
|
||||
if (size > chunk_remaining) {
|
||||
chunk_ptr = ::new char[CHUNK_BYTES];
|
||||
chunk_remaining = CHUNK_BYTES;
|
||||
size_vvp_net_funs += CHUNK_BYTES;
|
||||
}
|
||||
|
||||
assert( (size%sizeof(void*)) == 0 );
|
||||
|
||||
void*res = chunk_ptr;
|
||||
chunk_ptr += size;
|
||||
chunk_remaining -= size;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void vvp_net_fun_t::operator delete(void*)
|
||||
{
|
||||
assert(0);
|
||||
|
|
@ -199,6 +168,7 @@ vvp_net_fil_t::vvp_net_fil_t()
|
|||
{
|
||||
force_link_ = 0;
|
||||
force_propagate_ = false;
|
||||
count_filters += 1;
|
||||
}
|
||||
|
||||
vvp_net_fil_t::~vvp_net_fil_t()
|
||||
|
|
@ -291,38 +261,6 @@ void vvp_net_fil_t::force_link(vvp_net_t*dst, vvp_net_t*src)
|
|||
src->link(dst_ptr);
|
||||
}
|
||||
|
||||
void*vvp_net_fil_t::operator new(size_t size)
|
||||
{
|
||||
// Link in an initial chunk of space for net_fun_t
|
||||
// objects. This chunk doesn't need to be the same size as the
|
||||
// subsequent chunks, but we do need to make sure it is
|
||||
// aligned with pointer alignment. (Hence the union with "align".)
|
||||
static union { void*align; char bytes[512*1024]; } initial_chunk;
|
||||
|
||||
// Initialize the pointer to the initial chunk.
|
||||
static char*chunk_ptr = initial_chunk.bytes;
|
||||
static size_t chunk_remaining = sizeof(initial_chunk);
|
||||
|
||||
// Once the initial chunk fills up, allocate new chunks in
|
||||
// fairly large blocks to reduce the system allocator
|
||||
// overhead, but not such big chunks that we create our own
|
||||
// waste. (Expect the typical waste to be CHUNK_BYTES/2.)
|
||||
const size_t CHUNK_BYTES = 256*1024;
|
||||
|
||||
if (size > chunk_remaining) {
|
||||
chunk_ptr = ::new char[CHUNK_BYTES];
|
||||
chunk_remaining = CHUNK_BYTES;
|
||||
}
|
||||
|
||||
assert( (size%sizeof(void*)) == 0 );
|
||||
|
||||
void*res = chunk_ptr;
|
||||
chunk_ptr += size;
|
||||
chunk_remaining -= size;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void vvp_net_fil_t::operator delete(void*)
|
||||
{
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
# include "config.h"
|
||||
# include "vpi_user.h"
|
||||
# include "vvp_vpi_callback.h"
|
||||
# include "permaheap.h"
|
||||
# include <stddef.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
|
|
@ -1093,10 +1094,13 @@ class vvp_net_fun_t {
|
|||
unsigned base, unsigned wid);
|
||||
|
||||
public: // These objects are only permallocated.
|
||||
static void* operator new(std::size_t size) { return permalloc(size); }
|
||||
static void* operator new(std::size_t size) { return heap_.alloc(size); }
|
||||
static void operator delete(void*); // not implemented
|
||||
|
||||
static std::size_t heap_total() { return heap_.heap_total(); }
|
||||
|
||||
protected:
|
||||
static void* permalloc(std::size_t size);
|
||||
static permaheap heap_;
|
||||
|
||||
private: // not implemented
|
||||
vvp_net_fun_t(const vvp_net_fun_t&);
|
||||
|
|
@ -1157,8 +1161,14 @@ class vvp_net_fil_t : public vvp_vpi_callback {
|
|||
virtual void force_fil_real(double val, vvp_vector2_t mask) =0;
|
||||
|
||||
public: // These objects are only permallocated.
|
||||
static void* operator new(std::size_t size);
|
||||
static void* operator new(std::size_t size) { return heap_.alloc(size); }
|
||||
static void operator delete(void*); // not implemented
|
||||
|
||||
static size_t heap_total() { return heap_.heap_total(); }
|
||||
|
||||
private:
|
||||
static permaheap heap_;
|
||||
|
||||
private: // not implemented
|
||||
vvp_net_fil_t(const vvp_net_fil_t&);
|
||||
vvp_net_fil_t& operator= (const vvp_net_fil_t&);
|
||||
|
|
|
|||
|
|
@ -604,7 +604,7 @@ vvp_vector4_t vvp_fun_signal_real_aa::vec4_value() const
|
|||
|
||||
void* vvp_fun_signal_real_aa::operator new(std::size_t size)
|
||||
{
|
||||
return vvp_net_fun_t::permalloc(size);
|
||||
return vvp_net_fun_t::heap_.alloc(size);
|
||||
}
|
||||
|
||||
void vvp_fun_signal_real_aa::operator delete(void*)
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_ba
|
|||
vvp_vector4_t vec4_unfiltered_value() const;
|
||||
|
||||
public: // These objects are only permallocated.
|
||||
static void* operator new(std::size_t size) { return permalloc(size); }
|
||||
static void* operator new(std::size_t size) { return vvp_net_fun_t::heap_.alloc(size); }
|
||||
static void operator delete(void*obj);
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in New Issue