diff --git a/uppsrc/Core/Other.h b/uppsrc/Core/Other.h index 01d90b113..5e317fdf5 100644 --- a/uppsrc/Core/Other.h +++ b/uppsrc/Core/Other.h @@ -119,6 +119,8 @@ class Bits : Moveable { dword *bp; void Expand(int q); + void Realloc(int nalloc); + void Free(); public: void Clear(); @@ -127,9 +129,16 @@ public: bool Get(int i) const { ASSERT(i >= 0 && alloc >= 0); int q = i >> 5; return q < alloc ? bp[q] & (1 << (i & 31)) : false; } bool operator[](int i) const { return Get(i); } + + void Reserve(int nbits); + void Shrink(); + + dword *CreateRaw(int n_dwords); + const dword *Raw(int& n_dwords) const { n_dwords = alloc; return bp; } + dword *Raw(int& n_dwords) { n_dwords = alloc; return bp; } Bits() { bp = NULL; alloc = 0; } - ~Bits() { Clear(); } + ~Bits() { Free(); } Bits(Bits&& b) { alloc = b.alloc; bp = b.bp; b.bp = NULL; } void operator=(Bits&& b) { if(this != &b) { Clear(); alloc = b.alloc; bp = b.bp; b.bp = NULL; } } diff --git a/uppsrc/Core/Vcont.cpp b/uppsrc/Core/Vcont.cpp index 634af60e6..45af62f6a 100644 --- a/uppsrc/Core/Vcont.cpp +++ b/uppsrc/Core/Vcont.cpp @@ -83,26 +83,60 @@ thread__ int invector_cache_blki_; thread__ int invector_cache_offset_; thread__ int invector_cache_end_; +void Bits::Free() +{ + if(bp) + MemoryFree(bp); +} void Bits::Clear() { - if(bp) - delete[] bp; alloc = 0; bp = NULL; } -void Bits::Expand(int q) +void Bits::Realloc(int nalloc) { - int nalloc = 4 * q / 3 + 1; - dword *nbp = new dword[nalloc]; + size_t sz = sizeof(dword) * nalloc; + dword *nbp = (dword *)MemoryAllocSz(sz); + nalloc = sz / sizeof(dword); if(bp) { - Copy(nbp, bp, bp + alloc); - delete[] bp; + Copy(nbp, bp, bp + min(alloc, nalloc)); + Free(); } - Fill(nbp + alloc, nbp + nalloc, (dword)0); + if(nalloc > alloc) + Fill(nbp + alloc, nbp + nalloc, (dword)0); bp = nbp; alloc = nalloc; } +void Bits::Expand(int q) +{ + Realloc(3 * q / 2 + 1); +} + +void Bits::Reserve(int nbits) +{ + int n = (nbits + 31) >> 5; + if(n > alloc) + Realloc(n); +} + +void Bits::Shrink() +{ + int lasti = alloc - 1; + while(lasti > 0 && bp[lasti] == 0) + lasti--; + int nalloc = lasti + 1; + if(nalloc != alloc) + Realloc(nalloc); +} + +dword *Bits::CreateRaw(int n_dwords) +{ + Clear(); + Realloc(n_dwords); + return bp; +} + } diff --git a/uppsrc/Core/src.tpp/Bits$en-us.tpp b/uppsrc/Core/src.tpp/Bits$en-us.tpp index a74f971d9..6bd51e27f 100644 --- a/uppsrc/Core/src.tpp/Bits$en-us.tpp +++ b/uppsrc/Core/src.tpp/Bits$en-us.tpp @@ -35,4 +35,28 @@ onst]&] [s5;:Bits`:`:operator`[`]`(int`)const: [@(0.0.255) bool]_[* operator`[`]]([@(0.0.255) int]_ [*@3 i])_[@(0.0.255) const]&] [s2;%% Returns the value of bool [%-*@3 i].&] +[s4; &] +[s5;:Upp`:`:Bits`:`:Reserve`(int`): [@(0.0.255) void]_[* Reserve]([@(0.0.255) int]_[*@3 nbits +])&] +[s2;%% Preallocates internal storage for [%-*@3 nbits] bits, avoiding +further reallocations during Set (as long as only nbits are used).&] +[s3;%% &] +[s4; &] +[s5;:Upp`:`:Bits`:`:Shrink`(`): [@(0.0.255) void]_[* Shrink]()&] +[s2;%% Tries to reduce internal storage.&] +[s3; &] +[s4; &] +[s5;:Upp`:`:Bits`:`:CreateRaw`(int`): [_^Upp`:`:dword^ dword]_`*[* CreateRaw]([@(0.0.255) i +nt]_[*@3 n`_dwords])&] +[s2;%% Creates a new internal storage for [%-*@3 n`_dwords] dwords +(sizeof(dword) `* [%-*@3 n`_dwords] bits) and returns a pointer +to it. Bits are numbered from LSB.&] +[s3;%% &] +[s4; &] +[s5;:Upp`:`:Bits`:`:Raw`(int`&`)const: [@(0.0.255) const]_[_^Upp`:`:dword^ dword]_`*[* Raw]( +[@(0.0.255) int`&]_[*@3 n`_dwords])_[@(0.0.255) const]&] +[s5;:Upp`:`:Bits`:`:Raw`(int`&`): [_^Upp`:`:dword^ dword]_`*[* Raw]([@(0.0.255) int`&]_[*@3 n +`_dwords])&] +[s2;%% Returns a pointer to internal storage and the size of internal +storage.&] [s0;%% ]] \ No newline at end of file