aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/dist.h1
-rw-r--r--erts/emulator/beam/external.c39
2 files changed, 36 insertions, 4 deletions
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index 93a651b24d..3e17645997 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -53,7 +53,6 @@
| DFLAG_EXPORT_PTR_TAG \
| DFLAG_BIT_BINARIES \
| DFLAG_MAP_TAG \
- | DFLAG_UTF8_ATOMS \
| DFLAG_BIG_CREATION)
/* opcodes used in distribution messages */
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 1190d90b8e..06213daa67 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -2090,6 +2090,7 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
{
int iix;
int len;
+ int utf8_atoms = (int) (dflags & DFLAG_UTF8_ATOMS);
ASSERT(is_atom(atom));
@@ -2118,8 +2119,8 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
if (iix < 0) {
Atom *a = atom_tab(atom_val(atom));
len = a->len;
- {
- if (len > 255) {
+ if (utf8_atoms || a->latin1_chars < 0) {
+ if (len > 255) {
*ep++ = ATOM_UTF8_EXT;
put_int16(len, ep);
ep += 2;
@@ -2131,6 +2132,32 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
}
sys_memcpy((char *) ep, (char *) a->name, len);
}
+ else {
+ if (a->latin1_chars <= 255 && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
+ *ep++ = SMALL_ATOM_EXT;
+ if (len == a->latin1_chars) {
+ sys_memcpy(ep+1, a->name, len);
+ }
+ else {
+ len = erts_utf8_to_latin1(ep+1, a->name, len);
+ ASSERT(len == a->latin1_chars);
+ }
+ put_int8(len, ep);
+ ep++;
+ }
+ else {
+ *ep++ = ATOM_EXT;
+ if (len == a->latin1_chars) {
+ sys_memcpy(ep+2, a->name, len);
+ }
+ else {
+ len = erts_utf8_to_latin1(ep+2, a->name, len);
+ ASSERT(len == a->latin1_chars);
+ }
+ put_int16(len, ep);
+ ep += 2;
+ }
+ }
ep += len;
return ep;
}
@@ -4053,13 +4080,19 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
else {
Atom *a = atom_tab(atom_val(obj));
int alen;
- {
+ if ((dflags & DFLAG_UTF8_ATOMS) || a->latin1_chars < 0) {
alen = a->len;
result += 1 + 1 + alen;
if (alen > 255) {
result++; /* ATOM_UTF8_EXT (not small) */
}
}
+ else {
+ alen = a->latin1_chars;
+ result += 1 + 1 + alen;
+ if (alen > 255 || !(dflags & DFLAG_SMALL_ATOM_TAGS))
+ result++; /* ATOM_EXT (not small) */
+ }
insert_acache_map(acmp, obj, dflags);
}
break;