aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2013-01-28 14:32:54 +0100
committerSverker Eriksson <[email protected]>2013-01-28 14:32:54 +0100
commit58482ed3f2b2f90f8be35b85d5d16f3f40f80fa3 (patch)
treea22f36b6de5d54769d2392b79edf1366964a8a5c
parentd4fd0da2e1fc541bae7ed2de362f8a5f69357e27 (diff)
parent6c61689ae326587dfc9bcebd0fc6d6fa40dfd1fb (diff)
downloadotp-58482ed3f2b2f90f8be35b85d5d16f3f40f80fa3.tar.gz
otp-58482ed3f2b2f90f8be35b85d5d16f3f40f80fa3.tar.bz2
otp-58482ed3f2b2f90f8be35b85d5d16f3f40f80fa3.zip
Merge branch 'sverk/enc_atom-opt'
* sverk/enc_atom-opt: erts: Optimize atom encoding to use memcpy for pure ascii erts: Refactor erts_atom_get to use ErtsAtomEncoding
-rw-r--r--erts/emulator/beam/atom.c4
-rw-r--r--erts/emulator/beam/atom.h2
-rw-r--r--erts/emulator/beam/bif.c2
-rw-r--r--erts/emulator/beam/erl_nif.c6
-rw-r--r--erts/emulator/beam/erl_unicode.c4
-rw-r--r--erts/emulator/beam/external.c60
6 files changed, 40 insertions, 38 deletions
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index 259b5e49c1..b69f979397 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -367,7 +367,7 @@ int atom_table_sz(void)
}
int
-erts_atom_get(const char *name, int len, Eterm* ap, int is_latin1)
+erts_atom_get(const char *name, int len, Eterm* ap, ErtsAtomEncoding enc)
{
byte utf8_copy[MAX_ATOM_SZ_FROM_LATIN1];
Atom a;
@@ -376,7 +376,7 @@ erts_atom_get(const char *name, int len, Eterm* ap, int is_latin1)
a.len = (Sint16) len;
a.name = (byte *)name;
- if (is_latin1) {
+ if (enc == ERTS_ATOM_ENC_LATIN1) {
latin1_to_utf8(utf8_copy, (const byte**)&a.name, &len);
a.len = (Sint16) len;
}
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index 1d3c4cb922..5904ae0f7e 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -139,7 +139,7 @@ int atom_static_put(byte*, int);
void init_atom_table(void);
void atom_info(int, void *);
void dump_atoms(int, void *);
-int erts_atom_get(const char* name, int len, Eterm* ap, int is_latin1);
+int erts_atom_get(const char* name, int len, Eterm* ap, ErtsAtomEncoding enc);
void erts_atom_get_text_space_sizes(Uint *reserved, Uint *used);
#endif
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 16df37a0fb..46f76624a5 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -2670,7 +2670,7 @@ BIF_RETTYPE list_to_existing_atom_1(BIF_ALIST_1)
} else {
Eterm a;
- if (erts_atom_get(buf, i, &a, 1)) {
+ if (erts_atom_get(buf, i, &a, ERTS_ATOM_ENC_LATIN1)) {
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_RET(a);
} else {
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index fb612d8f19..068f904b76 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -984,7 +984,7 @@ int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)
{
ASSERT(encoding == ERL_NIF_LATIN1);
- return erts_atom_get(name, len, atom, 1);
+ return erts_atom_get(name, len, atom, ERTS_ATOM_ENC_LATIN1);
}
ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
@@ -1653,7 +1653,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
BeamInstr** code_pp;
ErlNifFunc* f = &entry->funcs[i];
- if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom, 1)
+ if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom, ERTS_ATOM_ENC_LATIN1)
|| (code_pp = get_func_pp(mod->curr.code, f_atom, f->arity))==NULL) {
ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u",
mod_atom, f->name, f->arity);
@@ -1756,7 +1756,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs; i++)
{
BeamInstr* code_ptr;
- erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom, 1);
+ erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom, ERTS_ATOM_ENC_LATIN1);
code_ptr = *get_func_pp(mod->curr.code, f_atom, entry->funcs[i].arity);
if (code_ptr[1] == 0) {
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 58202976cf..99108af937 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -1905,7 +1905,7 @@ binary_to_atom(Process* proc, Eterm bin, Eterm enc, int must_exist)
if (is_non_value(a))
goto badarg;
BIF_RET(a);
- } else if (erts_atom_get((char *)bytes, bin_size, &a, 1)) {
+ } else if (erts_atom_get((char *)bytes, bin_size, &a, ERTS_ATOM_ENC_LATIN1)) {
erts_free_aligned_binary_bytes(temp_alloc);
BIF_RET(a);
} else {
@@ -1940,7 +1940,7 @@ binary_to_atom(Process* proc, Eterm bin, Eterm enc, int must_exist)
ERTS_ATOM_ENC_UTF8,
0);
}
- else if (!erts_atom_get((char*)bytes, bin_size, &res, 0)) {
+ else if (!erts_atom_get((char*)bytes, bin_size, &res, ERTS_ATOM_ENC_UTF8)) {
goto badarg;
}
erts_free_aligned_binary_bytes(temp_alloc);
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 546e5d6ce0..5ce0d97c74 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1455,8 +1455,8 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
iix = get_iix_acache_map(acmp, atom, dflags);
if (iix < 0) {
Atom *a = atom_tab(atom_val(atom));
+ len = a->len;
if (utf8_atoms || a->latin1_chars < 0) {
- len = a->len;
if (len > 255) {
*ep++ = ATOM_UTF8_EXT;
put_int16(len, ep);
@@ -1472,15 +1472,25 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
else {
if (a->latin1_chars <= 255 && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
*ep++ = SMALL_ATOM_EXT;
- len = erts_utf8_to_latin1(ep+1, a->name, a->len);
- ASSERT(len == a->latin1_chars);
+ 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;
- len = erts_utf8_to_latin1(ep+2, a->name, a->len);
- ASSERT(len == a->latin1_chars);
+ 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;
}
@@ -1524,7 +1534,8 @@ static byte*
dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
{
Uint len;
- int n, is_latin1;
+ int n;
+ ErtsAtomEncoding char_enc;
switch (*ep++) {
case ATOM_CACHE_REF:
@@ -1540,34 +1551,29 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
case ATOM_EXT:
len = get_int16(ep),
ep += 2;
- is_latin1 = 1;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
goto dec_atom_common;
case SMALL_ATOM_EXT:
len = get_int8(ep);
ep++;
- is_latin1 = 1;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
goto dec_atom_common;
case ATOM_UTF8_EXT:
len = get_int16(ep),
ep += 2;
- is_latin1 = 0;
+ char_enc = ERTS_ATOM_ENC_UTF8;
goto dec_atom_common;
case SMALL_ATOM_UTF8_EXT:
len = get_int8(ep),
ep++;
- is_latin1 = 0;
+ char_enc = ERTS_ATOM_ENC_UTF8;
dec_atom_common:
if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
- if (!erts_atom_get((char*)ep, len, objp, is_latin1)) {
+ if (!erts_atom_get((char*)ep, len, objp, char_enc)) {
goto error;
}
} else {
- Eterm atom = erts_atom_put(ep,
- len,
- (is_latin1
- ? ERTS_ATOM_ENC_LATIN1
- : ERTS_ATOM_ENC_UTF8),
- 0);
+ Eterm atom = erts_atom_put(ep, len, char_enc, 0);
if (is_non_value(atom))
goto error;
*objp = atom;
@@ -2175,7 +2181,8 @@ static byte*
dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp)
{
Eterm* hp_saved = *hpp;
- int n, is_latin1;
+ int n;
+ ErtsAtomEncoding char_enc;
register Eterm* hp = *hpp; /* Please don't take the address of hp */
Eterm* next = objp;
@@ -2261,34 +2268,29 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
case ATOM_EXT:
n = get_int16(ep);
ep += 2;
- is_latin1 = 1;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
goto dec_term_atom_common;
case SMALL_ATOM_EXT:
n = get_int8(ep);
ep++;
- is_latin1 = 1;
+ char_enc = ERTS_ATOM_ENC_LATIN1;
goto dec_term_atom_common;
case ATOM_UTF8_EXT:
n = get_int16(ep);
ep += 2;
- is_latin1 = 0;
+ char_enc = ERTS_ATOM_ENC_UTF8;
goto dec_term_atom_common;
case SMALL_ATOM_UTF8_EXT:
n = get_int8(ep);
ep++;
- is_latin1 = 0;
+ char_enc = ERTS_ATOM_ENC_UTF8;
dec_term_atom_common:
if (edep && (edep->flags & ERTS_DIST_EXT_BTT_SAFE)) {
- if (!erts_atom_get((char*)ep, n, objp, is_latin1)) {
+ if (!erts_atom_get((char*)ep, n, objp, char_enc)) {
goto error;
}
} else {
- Eterm atom = erts_atom_put(ep,
- n,
- (is_latin1
- ? ERTS_ATOM_ENC_LATIN1
- : ERTS_ATOM_ENC_UTF8),
- 0);
+ Eterm atom = erts_atom_put(ep, n, char_enc, 0);
if (is_non_value(atom))
goto error;
*objp = atom;