diff options
Diffstat (limited to 'erts/emulator/beam/external.h')
-rw-r--r-- | erts/emulator/beam/external.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h new file mode 100644 index 0000000000..f308680f89 --- /dev/null +++ b/erts/emulator/beam/external.h @@ -0,0 +1,211 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* Same order as the ordering of terms in erlang */ + +/* Since there are 255 different External tag values to choose from + There is no reason to not be extravagant. + Hence, the different tags for large/small tuple e.t.c +*/ + + +#ifdef ERTS_WANT_EXTERNAL_TAGS +#ifndef ERTS_EXTERNAL_TAGS +#define ERTS_EXTERNAL_TAGS + +#define SMALL_INTEGER_EXT 'a' +#define INTEGER_EXT 'b' +#define FLOAT_EXT 'c' +#define ATOM_EXT 'd' +#define SMALL_ATOM_EXT 's' +#define REFERENCE_EXT 'e' +#define NEW_REFERENCE_EXT 'r' +#define PORT_EXT 'f' +#define NEW_FLOAT_EXT 'F' +#define PID_EXT 'g' +#define SMALL_TUPLE_EXT 'h' +#define LARGE_TUPLE_EXT 'i' +#define NIL_EXT 'j' +#define STRING_EXT 'k' +#define LIST_EXT 'l' +#define BINARY_EXT 'm' +#define BIT_BINARY_EXT 'M' +#define SMALL_BIG_EXT 'n' +#define LARGE_BIG_EXT 'o' +#define NEW_FUN_EXT 'p' +#define EXPORT_EXT 'q' +#define FUN_EXT 'u' + +#define DIST_HEADER 'D' +#define ATOM_CACHE_REF 'R' +#define COMPRESSED 'P' + +#if 0 +/* Not used anymore */ +#define CACHED_ATOM 'C' +#define NEW_CACHE 'N' +#endif + + +#define VERSION_MAGIC 131 /* 130 in erlang 4.2 */ + /* Increment this when changing the external format. */ + /* ON the other hand, don't change the external format */ + /* since that breaks other people's code! */ + +#endif /* ERTS_EXTERNAL_TAGS */ +#endif /* ERTS_WANT_EXTERNAL_TAGS */ + +#ifndef ERL_EXTERNAL_H__ +#define ERL_EXTERNAL_H__ + +#include "erl_node_tables.h" + +#define ERTS_ATOM_CACHE_SIZE 2048 + +typedef struct cache { + Eterm in_arr[ERTS_ATOM_CACHE_SIZE]; + Eterm out_arr[ERTS_ATOM_CACHE_SIZE]; +} ErtsAtomCache; + +typedef struct { + int hdr_sz; + int sz; + int cix[ERTS_ATOM_CACHE_SIZE]; + struct { + Eterm atom; + int iix; + } cache[ERTS_ATOM_CACHE_SIZE]; +} ErtsAtomCacheMap; + +typedef struct { + Uint32 size; + Eterm atom[ERTS_ATOM_CACHE_SIZE]; +} ErtsAtomTranslationTable; + +#define ERTS_DIST_EXT_DFLAG_HDR (((Uint32) 1) << 31) +#define ERTS_DIST_EXT_ATOM_TRANS_TAB (((Uint32) 1) << 30) +#define ERTS_DIST_EXT_CON_ID_MASK ((Uint32) 0x3fffffff) + +#define ERTS_DIST_EXT_CON_ID(DIST_EXTP) \ + ((DIST_EXTP)->flags & ERTS_DIST_EXT_CON_ID_MASK) +typedef struct { + DistEntry *dep; + byte *extp; + byte *ext_endp; + Sint heap_size; + Uint32 flags; + ErtsAtomTranslationTable attab; +} ErtsDistExternal; + +typedef struct { + int have_header; + int cache_entries; +} ErtsDistHeaderPeek; + +#define ERTS_DIST_EXT_SIZE(EDEP) \ + (sizeof(ErtsDistExternal) \ + - (((EDEP)->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB) \ + ? (ASSERT_EXPR(0 <= (EDEP)->attab.size \ + && (EDEP)->attab.size <= ERTS_ATOM_CACHE_SIZE), \ + sizeof(Eterm)*(ERTS_ATOM_CACHE_SIZE - (EDEP)->attab.size)) \ + : sizeof(ErtsAtomTranslationTable))) + +typedef struct { + byte *extp; + int exttmp; +} ErtsBinary2TermState; + +/* -------------------------------------------------------------------------- */ + +void erts_init_atom_cache_map(ErtsAtomCacheMap *); +void erts_reset_atom_cache_map(ErtsAtomCacheMap *); +void erts_destroy_atom_cache_map(ErtsAtomCacheMap *); +void erts_finalize_atom_cache_map(ErtsAtomCacheMap *); +Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *); + +Uint erts_encode_ext_dist_header_size(ErtsAtomCacheMap *); +byte *erts_encode_ext_dist_header_setup(byte *, ErtsAtomCacheMap *); +byte *erts_encode_ext_dist_header_finalize(byte *, ErtsAtomCache *); +Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *); +void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *); + +Uint erts_encode_ext_size(Eterm); +void erts_encode_ext(Eterm, byte **); + +#ifdef ERTS_WANT_EXTERNAL_TAGS +ERTS_GLB_INLINE void erts_peek_dist_header(ErtsDistHeaderPeek *, byte *, Uint); +#endif +ERTS_GLB_INLINE void erts_free_dist_ext_copy(ErtsDistExternal *); +ERTS_GLB_INLINE void *erts_dist_ext_trailer(ErtsDistExternal *); +ErtsDistExternal *erts_make_dist_ext_copy(ErtsDistExternal *, Uint); +void *erts_dist_ext_trailer(ErtsDistExternal *); +void erts_destroy_dist_ext_copy(ErtsDistExternal *); +int erts_prepare_dist_ext(ErtsDistExternal *, byte *, Uint, + DistEntry *, ErtsAtomCache *); +Sint erts_decode_dist_ext_size(ErtsDistExternal *, int); +Eterm erts_decode_dist_ext(Eterm **, ErlOffHeap *, ErtsDistExternal *); + +Sint erts_decode_ext_size(byte*, Uint, int); +Eterm erts_decode_ext(Eterm **, ErlOffHeap *, byte**); + +Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags); + +Sint erts_binary2term_prepare(ErtsBinary2TermState *, byte *, Sint); +void erts_binary2term_abort(ErtsBinary2TermState *); +Eterm erts_binary2term_create(ErtsBinary2TermState *, Eterm **hpp, ErlOffHeap *); +int erts_debug_max_atom_out_cache_index(void); +int erts_debug_atom_to_out_cache_index(Eterm); + + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF +#ifdef ERTS_WANT_EXTERNAL_TAGS +ERTS_GLB_INLINE void +erts_peek_dist_header(ErtsDistHeaderPeek *dhpp, byte *ext, Uint sz) +{ + if (ext[0] == VERSION_MAGIC + || ext[1] != DIST_HEADER + || sz < (1+1+1)) + dhpp->have_header = 0; + else { + dhpp->have_header = 1; + dhpp->cache_entries = (int) get_int8(&ext[2]); + } +} +#endif + +ERTS_GLB_INLINE void +erts_free_dist_ext_copy(ErtsDistExternal *edep) +{ + if (edep->dep) + erts_deref_dist_entry(edep->dep); + erts_free(ERTS_ALC_T_EXT_TERM_DATA, edep); +} + +ERTS_GLB_INLINE void * +erts_dist_ext_trailer(ErtsDistExternal *edep) +{ + void *res = (void *) (edep->ext_endp + + ERTS_WORD_ALIGN_PAD_SZ(edep->ext_endp)); + ASSERT((((Uint) res) % sizeof(Uint)) == 0); + return res; +} + +#endif + +#endif /* ERL_EXTERNAL_H__ */ |