From 92fe0e0fc7a10d8b6ef6fa35574782a7a6a309ce Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 29 Sep 2009 21:17:08 -0700 Subject: [PATCH] vvp_net_fil_t objects are permallocated. --- vvp/vvp_net.cc | 39 ++++++++++++++++++++++++++++++++++++++- vvp/vvp_net.h | 14 +++++++++++++- vvp/vvp_net_sig.cc | 25 +++++++++++++++++++++++++ vvp/vvp_net_sig.h | 10 ++++++++++ 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 159b5f390..151a5a283 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -156,7 +156,7 @@ 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::operator new(size_t size) +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 @@ -291,6 +291,43 @@ 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); +} + void vvp_net_fil_t::force_unlink(void) { if (force_link_ == 0) return; diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index a22b8fd07..c14ef404b 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -1093,8 +1093,11 @@ class vvp_net_fun_t { unsigned base, unsigned wid); public: // These objects are only permallocated. - static void* operator new(std::size_t size); + static void* operator new(std::size_t size) { return permalloc(size); } static void operator delete(void*); // not implemented + protected: + static void* permalloc(std::size_t size); + private: // not implemented vvp_net_fun_t(const vvp_net_fun_t&); vvp_net_fun_t& operator= (const vvp_net_fun_t&); @@ -1153,6 +1156,15 @@ class vvp_net_fil_t : public vvp_vpi_callback { virtual void force_fil_vec8(const vvp_vector8_t&val, vvp_vector2_t mask) =0; 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 delete(void*); // not implemented + private: // not implemented + vvp_net_fil_t(const vvp_net_fil_t&); + vvp_net_fil_t& operator= (const vvp_net_fil_t&); + static void* operator new[](std::size_t size); + static void operator delete[](void*); + protected: // Set bits of the filter force mask void force_mask(vvp_vector2_t mask); diff --git a/vvp/vvp_net_sig.cc b/vvp/vvp_net_sig.cc index 50a5edb79..44dcc32a8 100644 --- a/vvp/vvp_net_sig.cc +++ b/vvp/vvp_net_sig.cc @@ -294,6 +294,11 @@ vvp_fun_signal4_aa::vvp_fun_signal4_aa(unsigned wid, vvp_bit4_t init) size_ = wid; } +vvp_fun_signal4_aa::~vvp_fun_signal4_aa() +{ + assert(0); +} + void vvp_fun_signal4_aa::alloc_instance(vvp_context_t context) { vvp_set_context_item(context, context_idx_, new vvp_vector4_t(size_)); @@ -388,6 +393,11 @@ vvp_vector4_t vvp_fun_signal4_aa::vec4_unfiltered_value() const return vec4_value(); } +void vvp_fun_signal4_aa::operator delete(void*) +{ + assert(0); +} + vvp_fun_signal8::vvp_fun_signal8(unsigned wid) : bits8_(wid) { @@ -513,6 +523,11 @@ vvp_fun_signal_real_aa::vvp_fun_signal_real_aa() context_idx_ = vpip_add_item_to_context(this, vpip_peek_context_scope()); } +vvp_fun_signal_real_aa::~vvp_fun_signal_real_aa() +{ + assert(0); +} + void vvp_fun_signal_real_aa::alloc_instance(vvp_context_t context) { double*bits = new double; @@ -587,6 +602,16 @@ vvp_vector4_t vvp_fun_signal_real_aa::vec4_value() const assert(0); } +void* vvp_fun_signal_real_aa::operator new(std::size_t size) +{ + return vvp_net_fun_t::permalloc(size); +} + +void vvp_fun_signal_real_aa::operator delete(void*) +{ + assert(0); +} + vvp_fun_force::vvp_fun_force() { } diff --git a/vvp/vvp_net_sig.h b/vvp/vvp_net_sig.h index 3739df303..7ed785362 100644 --- a/vvp/vvp_net_sig.h +++ b/vvp/vvp_net_sig.h @@ -162,6 +162,7 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_ba public: explicit vvp_fun_signal4_aa(unsigned wid, vvp_bit4_t init=BIT4_X); + ~vvp_fun_signal4_aa(); void alloc_instance(vvp_context_t context); void reset_instance(vvp_context_t context); @@ -184,6 +185,10 @@ class vvp_fun_signal4_aa : public vvp_fun_signal_vec, public automatic_signal_ba vvp_vector4_t vec4_value() const; 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 delete(void*obj); + private: unsigned context_idx_; unsigned size_; @@ -245,6 +250,7 @@ class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_sign public: explicit vvp_fun_signal_real_aa(); + ~vvp_fun_signal_real_aa(); void alloc_instance(vvp_context_t context); void reset_instance(vvp_context_t context); @@ -266,6 +272,10 @@ class vvp_fun_signal_real_aa : public vvp_fun_signal_real, public automatic_sign double real_value() const; void get_signal_value(struct t_vpi_value*vp); + public: // These objects are only permallocated. + static void* operator new(std::size_t size); + static void operator delete(void*obj); + private: unsigned context_idx_; };