diff --git a/vvp/Makefile.in b/vvp/Makefile.in index a0da8a9de..a53c062df 100644 --- a/vvp/Makefile.in +++ b/vvp/Makefile.in @@ -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 diff --git a/vvp/main.cc b/vvp/main.cc index d0cca4e40..c0847abfb 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -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); diff --git a/vvp/permaheap.cc b/vvp/permaheap.cc new file mode 100644 index 000000000..81c3ab3db --- /dev/null +++ b/vvp/permaheap.cc @@ -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 + +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; +} diff --git a/vvp/permaheap.h b/vvp/permaheap.h new file mode 100644 index 000000000..c93db237f --- /dev/null +++ b/vvp/permaheap.h @@ -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 + +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 diff --git a/vvp/statistics.cc b/vvp/statistics.cc index 7f03e98ec..79a8f3fd4 100644 --- a/vvp/statistics.cc +++ b/vvp/statistics.cc @@ -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; diff --git a/vvp/statistics.h b/vvp/statistics.h index aa7bf0386..a9b342c89 100644 --- a/vvp/statistics.h +++ b/vvp/statistics.h @@ -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; diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 151a5a283..d773843eb 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -35,6 +35,9 @@ # include #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); diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index c14ef404b..0b8e979e5 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -22,6 +22,7 @@ # include "config.h" # include "vpi_user.h" # include "vvp_vpi_callback.h" +# include "permaheap.h" # include # include # include @@ -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&); diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index 44dcc32a8..43e983902 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -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*) diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index 7ed785362..50dab4a4f 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -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: