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 \
|
O = main.o parse.o parse_misc.o lexor.o arith.o array.o bufif.o compile.o \
|
||||||
concat.o \
|
concat.o \
|
||||||
dff.o extend.o npmos.o part.o reduce.o resolv.o sfunc.o stop.o symbols.o \
|
dff.o extend.o npmos.o part.o permaheap.o reduce.o resolv.o sfunc.o stop.o \
|
||||||
ufunc.o codes.o \
|
symbols.o ufunc.o codes.o \
|
||||||
vthread.o schedule.o statistics.o tables.o udp.o vvp_island.o vvp_net.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
|
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) {
|
if (verbose_flag) {
|
||||||
vpi_mcd_printf(1, " ... %8lu functors (net_fun pool=%zu bytes)\n",
|
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 logic\n", count_functors_logic);
|
||||||
vpi_mcd_printf(1, " %8lu bufif\n", count_functors_bufif);
|
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 resolv\n",count_functors_resolv);
|
||||||
vpi_mcd_printf(1, " %8lu signals\n", count_functors_sig);
|
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",
|
vpi_mcd_printf(1, " ... %8lu opcodes (%zu bytes)\n",
|
||||||
count_opcodes, size_opcodes);
|
count_opcodes, size_opcodes);
|
||||||
vpi_mcd_printf(1, " ... %8lu nets\n", count_vpi_nets);
|
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_resolv= 0;
|
||||||
unsigned long count_functors_sig = 0;
|
unsigned long count_functors_sig = 0;
|
||||||
|
|
||||||
|
unsigned long count_filters = 0;
|
||||||
unsigned long count_vpi_nets = 0;
|
unsigned long count_vpi_nets = 0;
|
||||||
|
|
||||||
unsigned long count_vpi_scopes = 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_bufif;
|
||||||
extern unsigned long count_functors_resolv;
|
extern unsigned long count_functors_resolv;
|
||||||
extern unsigned long count_functors_sig;
|
extern unsigned long count_functors_sig;
|
||||||
|
extern unsigned long count_filters;
|
||||||
extern unsigned long count_vvp_nets;
|
extern unsigned long count_vvp_nets;
|
||||||
extern unsigned long count_vpi_nets;
|
extern unsigned long count_vpi_nets;
|
||||||
extern unsigned long count_vpi_scopes;
|
extern unsigned long count_vpi_scopes;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@
|
||||||
# include <map>
|
# include <map>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
permaheap vvp_net_fun_t::heap_;
|
||||||
|
permaheap vvp_net_fil_t::heap_;
|
||||||
|
|
||||||
// Allocate around 1Megbytes/chunk.
|
// Allocate around 1Megbytes/chunk.
|
||||||
static const size_t VVP_NET_CHUNK = 1024*1024/sizeof(vvp_net_t);
|
static const size_t VVP_NET_CHUNK = 1024*1024/sizeof(vvp_net_t);
|
||||||
static vvp_net_t*vvp_net_alloc_table = 0;
|
static vvp_net_t*vvp_net_alloc_table = 0;
|
||||||
|
|
@ -47,7 +50,6 @@ static size_t vvp_net_alloc_remaining = 0;
|
||||||
// chunks allocated.
|
// chunks allocated.
|
||||||
unsigned long count_vvp_nets = 0;
|
unsigned long count_vvp_nets = 0;
|
||||||
size_t size_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)
|
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);
|
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*)
|
void vvp_net_fun_t::operator delete(void*)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -199,6 +168,7 @@ vvp_net_fil_t::vvp_net_fil_t()
|
||||||
{
|
{
|
||||||
force_link_ = 0;
|
force_link_ = 0;
|
||||||
force_propagate_ = false;
|
force_propagate_ = false;
|
||||||
|
count_filters += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_net_fil_t::~vvp_net_fil_t()
|
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);
|
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*)
|
void vvp_net_fil_t::operator delete(void*)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include "vpi_user.h"
|
# include "vpi_user.h"
|
||||||
# include "vvp_vpi_callback.h"
|
# include "vvp_vpi_callback.h"
|
||||||
|
# include "permaheap.h"
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
|
|
@ -1093,10 +1094,13 @@ class vvp_net_fun_t {
|
||||||
unsigned base, unsigned wid);
|
unsigned base, unsigned wid);
|
||||||
|
|
||||||
public: // These objects are only permallocated.
|
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 void operator delete(void*); // not implemented
|
||||||
|
|
||||||
|
static std::size_t heap_total() { return heap_.heap_total(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void* permalloc(std::size_t size);
|
static permaheap heap_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
vvp_net_fun_t(const vvp_net_fun_t&);
|
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;
|
virtual void force_fil_real(double val, vvp_vector2_t mask) =0;
|
||||||
|
|
||||||
public: // These objects are only permallocated.
|
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 void operator delete(void*); // not implemented
|
||||||
|
|
||||||
|
static size_t heap_total() { return heap_.heap_total(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static permaheap heap_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
vvp_net_fil_t(const vvp_net_fil_t&);
|
vvp_net_fil_t(const vvp_net_fil_t&);
|
||||||
vvp_net_fil_t& operator= (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)
|
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*)
|
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;
|
vvp_vector4_t vec4_unfiltered_value() const;
|
||||||
|
|
||||||
public: // These objects are only permallocated.
|
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);
|
static void operator delete(void*obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue