diff options
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/erl_message.c | 25 | ||||
-rw-r--r-- | erts/emulator/beam/erl_message.h | 1 | ||||
-rw-r--r-- | erts/emulator/beam/io.c | 6 |
3 files changed, 23 insertions, 9 deletions
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 13e084ce10..f806d2c498 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -93,9 +93,6 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size, #endif ErlHeapFragment* nbp; - /* ToDo: Make use of 'used_size' to avoid realloc - when shrinking just a few words */ - #ifdef DEBUG { Uint off_sz = size < bp->used_size ? size : bp->used_size; @@ -110,8 +107,10 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size, } #endif - if (size == bp->used_size) + if (size >= (bp->used_size - bp->used_size / 16)) { + bp->used_size = size; return bp; + } #ifdef HARD_DEBUG dbg_brefs = erts_alloc(ERTS_ALC_T_UNDEF, sizeof(Eterm *)*brefs_size); @@ -1288,6 +1287,24 @@ void erts_factory_close(ErtsHeapFactory* factory) factory->mode = FACTORY_CLOSED; } +void erts_factory_trim_and_close(ErtsHeapFactory* factory, + Eterm *brefs, Uint brefs_size) +{ + if (factory->mode == FACTORY_HEAP_FRAGS) { + ErlHeapFragment* bp = factory->heap_frags; + if (bp->next == NULL) { + Uint used_sz = factory->hp - bp->mem; + ASSERT(used_sz <= bp->alloc_size); + factory->heap_frags = erts_resize_message_buffer(bp, used_sz, + brefs, brefs_size); + factory->mode = FACTORY_CLOSED; + return; + } + /*else we don't trim multi fragmented messages for now */ + } + erts_factory_close(factory); +} + void erts_factory_undo(ErtsHeapFactory* factory) { ErlHeapFragment* bp; diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h index 39946f2a14..705ba5e506 100644 --- a/erts/emulator/beam/erl_message.h +++ b/erts/emulator/beam/erl_message.h @@ -79,6 +79,7 @@ void erts_factory_dummy_init(ErtsHeapFactory*); Eterm* erts_produce_heap(ErtsHeapFactory*, Uint need, Uint xtra); Eterm* erts_reserve_heap(ErtsHeapFactory*, Uint need); void erts_factory_close(ErtsHeapFactory*); +void erts_factory_trim_and_close(ErtsHeapFactory*,Eterm *brefs, Uint brefs_size); void erts_factory_undo(ErtsHeapFactory*); #ifdef CHECK_FOR_HOLES diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index fb030d61f9..23f208c2eb 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -1407,12 +1407,8 @@ queue_port_sched_op_reply(Process *rp, hp += REF_THING_SIZE; msg = TUPLE2(hp, ref, msg); - hp += 3; - /* SVERK: We used to call erts_resize_message_buffer here - * to maybe realloc message. - */ - erts_factory_close(factory); + erts_factory_trim_and_close(factory, &msg, 1); erts_queue_message(rp, rp_locksp, factory->heap_frags, msg, NIL); } |