From c10e3e1fc83cbccd1c8c3b377e2309ea8fa27572 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 1 Mar 2018 12:27:48 +0100 Subject: erts: Optimize dist transcoding toward erl_/jinterface to only transcode if output buffer actually contains unsupported BIT_BINARY_EXT or EXPORT_EXT. --- erts/emulator/beam/dist.c | 2 ++ erts/emulator/beam/dist.h | 6 +++--- erts/emulator/beam/erl_node_tables.h | 1 + erts/emulator/beam/external.c | 23 ++++++++++++++++------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index c08a8ec832..132a0b9fba 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -2000,6 +2000,7 @@ erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx) break; } ctx->u.ec.flags = ctx->flags; + ctx->u.ec.hopefull_flags = 0; ctx->u.ec.level = 0; ctx->u.ec.wstack.wstart = NULL; ctx->obuf->msg_start = ctx->obuf->ext_endp; @@ -2023,6 +2024,7 @@ erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx) ctx->data_size = ctx->obuf->ext_endp - ctx->obuf->extp; + ctx->obuf->hopefull_flags = ctx->u.ec.hopefull_flags; /* * Signal encoded; now verify that the connection still exists, * and if so enqueue the signal and schedule it for send. diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index e8dcdb669d..000c66a00f 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -55,9 +55,8 @@ /* * Additional optimistic flags when encoding toward pending connection. - * If remote node does not supporting these (erl_interface) - * then we will need to transcode all messages enqueued before - * connection setup was finished. + * If remote node (erl_interface) does not supporting these then we may need + * to transcode messages enqueued before connection setup was finished. */ #define DFLAG_DIST_HOPEFULLY (DFLAG_EXPORT_PTR_TAG \ | DFLAG_BIT_BINARIES \ @@ -355,6 +354,7 @@ typedef struct TTBSizeContext_ { typedef struct TTBEncodeContext_ { Uint flags; + Uint hopefull_flags; int level; byte* ep; Eterm obj; diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index 8d29c83e15..5822f97f55 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -86,6 +86,7 @@ struct ErtsDistOutputBuf_ { byte *alloc_endp; #endif ErtsDistOutputBuf *next; + Uint hopefull_flags; byte *extp; byte *ext_endp; byte *msg_start; diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index b12a021e41..b358685cc0 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2873,6 +2873,8 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, ep[j] = 0; /* Zero unused bits at end of binary */ data_dst = ep; ep += j + 1; + if (ctx) + ctx->hopefull_flags |= DFLAG_BIT_BINARIES; } else { /* * Bit-level binary, but the receiver doesn't support it. @@ -2908,6 +2910,8 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, ep = enc_atom(acmp, exp->info.mfa.function, ep, dflags); ep = enc_term(acmp, make_small(exp->info.mfa.arity), ep, dflags, off_heap); + if (ctx) + ctx->hopefull_flags |= DFLAG_EXPORT_PTR_TAG; } else { /* Tag, arity */ *ep++ = SMALL_TUPLE_EXT; @@ -4729,11 +4733,13 @@ Sint transcode_dist_obuf(ErtsDistOutputBuf* ob, struct transcode_context* ctx = dep->transcode_ctx; if (!ctx) { /* first call for 'ob' */ - - if (~dflags & (DFLAG_BIT_BINARIES | DFLAG_EXPORT_PTR_TAG)) { + ASSERT(!(ob->hopefull_flags & ~(Uint)(DFLAG_BIT_BINARIES | + DFLAG_EXPORT_PTR_TAG))); + if (~dflags & ob->hopefull_flags) { /* - * Receiver does not support bitstrings and/or export funs. - * We need to transcode control and message terms to use tuple fallbacks. + * Receiver does not support bitstrings and/or export funs + * and output buffer contains such message tags (hopefull_flags). + * Must transcode control and message terms to use tuple fallbacks. */ ctx = erts_alloc(ERTS_ALC_T_DIST_TRANSCODE, sizeof(struct transcode_context)); dep->transcode_ctx = ctx; @@ -4760,7 +4766,7 @@ Sint transcode_dist_obuf(ErtsDistOutputBuf* ob, ctx->state = TRANSCODE_ENC_CTL; } } - else { + else if (!(dflags & DFLAG_DIST_HDR_ATOM_CACHE)) { /* * No need for full transcoding, but primitive receiver (erl_/jinterface) * expects VERSION_MAGIC before both control and message terms. @@ -4777,8 +4783,10 @@ Sint transcode_dist_obuf(ErtsDistOutputBuf* ob, *--(ob->extp) = VERSION_MAGIC; goto done; } + else + goto done; } - else { + else { /* continue after yield */ ASSERT(ctx->dbg_ob == ob); } ctx->b2t.reds = reds * B2T_BYTES_PER_REDUCTION; @@ -4831,6 +4839,7 @@ Sint transcode_dist_obuf(ErtsDistOutputBuf* ob, ob->msg_start = ob->ext_endp; ctx->ttb.wstack.wstart = NULL; ctx->ttb.flags = dflags; + ctx->ttb.hopefull_flags = 0; ctx->ttb.level = 0; ctx->state = TRANSCODE_ENC_MSG; @@ -4843,7 +4852,7 @@ Sint transcode_dist_obuf(ErtsDistOutputBuf* ob, reds /= TERM_TO_BINARY_LOOP_FACTOR; ASSERT(ob->ext_endp <= ob->alloc_endp); - + ASSERT(!ctx->ttb.hopefull_flags); } transcode_free_ctx(dep); -- cgit v1.2.3