From 0b09ffabadd38bd2d0fa9cfa735542defc380efc Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 22 Dec 2010 15:14:39 +0100 Subject: HALFWORD ETS 32-bit arch fixes and other cleanups --- erts/emulator/beam/erl_db.c | 3 +- erts/emulator/beam/erl_db_tree.c | 4 +- erts/emulator/beam/erl_db_util.c | 10 +++-- erts/emulator/beam/erl_lock_check.c | 2 +- erts/emulator/beam/erl_term.h | 69 +++++++++++++++---------------- erts/emulator/beam/sys.h | 6 +-- erts/emulator/sys/common/erl_mseg.c | 81 ++++++++++++++++++++++--------------- lib/stdlib/test/ets_SUITE.erl | 4 +- 8 files changed, 95 insertions(+), 84 deletions(-) diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 914eedce0c..02f16899ae 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2010. All Rights Reserved. + * Copyright Ericsson AB 1996-2011. 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 @@ -3501,7 +3501,6 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data) /* Make a dummy 1-tuple around data to use DbTerm */ wrap_tpl = TUPLE1(tmp,heir_data); size = size_object(wrap_tpl); - /* SVERK: Must be low memory due to erts_send_message */ dbterm = erts_db_alloc(ERTS_ALC_T_DB_HEIR_DATA, (DbTable *)tb, (sizeof(DbTerm) + sizeof(Eterm)*(size-1))); dbterm->size = size; diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index d9330a3bbf..d4f02f9117 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * Copyright Ericsson AB 1998-2011. 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 @@ -2753,7 +2753,7 @@ static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key, Eterm* bk_ erts_fprintf(stderr," > "); else erts_fprintf(stderr," == "); - erts_fprintf(stderr,"%T\n",bound_key); // SVERK: printing rterm + erts_fprintf(stderr,"%T\n",bound_key); // HALFWORD BUG: printing rterm #endif return ret; } diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 3883ff69fa..7a6a811a60 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * Copyright Ericsson AB 1998-2011. 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 @@ -1915,11 +1915,13 @@ restart: *esp++ = hp[n]; break; case matchPushExpr: - ASSERT(is_tuple_rel(term,base)); #if HALFWORD_HEAP if (base) { - Uint sz = size_object_rel(term, base); - Eterm* top = HAlloc(psp, sz); + Uint sz; + Eterm* top; + ASSERT(is_tuple_rel(term,base)); /* assume ETS */ + sz = size_object_rel(term, base); + top = HAlloc(psp, sz); *esp++ = copy_shallow_rel(tuple_val_rel(term,base), sz, &top, &MSO(psp), base); break; diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 0185baee6b..7cd379d2c8 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -155,7 +155,7 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "alcu_allocator", "index" }, { "alcu_delayed_free", "index" }, { "mseg", NULL }, -#ifdef HALFWORD_HEAP +#if HALFWORD_HEAP { "pmmap", NULL }, #endif #ifdef ERTS_SMP diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 1225b6a944..161093434f 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2010. All Rights Reserved. + * Copyright Ericsson AB 2000-2011. 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 @@ -359,7 +359,6 @@ _ET_DECLARE_CHECKED(Eterm*,binary_val,Wterm) #define is_fun_header(x) ((x) == HEADER_FUN) #define make_fun(x) make_boxed((Eterm*)(x)) #define is_fun(x) (is_boxed((x)) && is_fun_header(*boxed_val((x)))) -#define is_fun_rel(x,Base) (is_boxed((x)) && is_fun_header(*boxed_val_rel((x),Base))) #define is_not_fun(x) (!is_fun((x))) #define _unchecked_fun_val(x) _unchecked_boxed_val((x)) _ET_DECLARE_CHECKED(Eterm*,fun_val,Wterm) @@ -368,7 +367,6 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Wterm) /* export access methods */ #define make_export(x) make_boxed((x)) #define is_export(x) (is_boxed((x)) && is_export_header(*boxed_val((x)))) -#define is_export_rel(x,Base) (is_boxed((x)) && is_export_header(*boxed_val_rel((x),Base))) #define is_not_export(x) (!is_export((x))) #define _unchecked_export_val(x) _unchecked_boxed_val(x) _ET_DECLARE_CHECKED(Eterm*,export_val,Wterm) @@ -396,7 +394,6 @@ _ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm) #define BIG_ARITY_MAX ((1 << 19)-1) #define make_big(x) make_boxed((x)) #define is_big(x) (is_boxed((x)) && _is_bignum_header(*boxed_val((x)))) -#define is_big_rel(x,Base) (is_boxed((x)) && _is_bignum_header(*boxed_val_rel((x),Base))) #define is_not_big(x) (!is_big((x))) #define _unchecked_big_val(x) _unchecked_boxed_val((x)) _ET_DECLARE_CHECKED(Eterm*,big_val,Wterm) @@ -410,7 +407,6 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Wterm) #endif #define make_float(x) make_boxed((x)) #define is_float(x) (is_boxed((x)) && *boxed_val((x)) == HEADER_FLONUM) -#define is_float_rel(x,Base) (is_boxed((x)) && *boxed_val_rel((x),Base) == HEADER_FLONUM) #define is_not_float(x) (!is_float(x)) #define _unchecked_float_val(x) _unchecked_boxed_val((x)) _ET_DECLARE_CHECKED(Eterm*,float_val,Wterm) @@ -451,8 +447,7 @@ typedef union float_def *(((Uint *) (p))+1) = (f).fw[1] #endif -#define GET_DOUBLE(x, f) FLOAT_VAL_GET_DOUBLE(float_val(x),f) -#define GET_DOUBLE_REL(x, f, Base) FLOAT_VAL_GET_DOUBLE(float_val_rel(x,Base),f) +#define GET_DOUBLE(x, f) FLOAT_VAL_GET_DOUBLE(float_val(x), f) #define DOUBLE_DATA_WORDS (sizeof(ieee754_8)/sizeof(Eterm)) #define FLOAT_SIZE_OBJECT (DOUBLE_DATA_WORDS+1) @@ -460,7 +455,6 @@ typedef union float_def /* tuple access methods */ #define make_tuple(x) make_boxed((x)) #define is_tuple(x) (is_boxed((x)) && is_arity_value(*boxed_val((x)))) -#define is_tuple_rel(x,Base) (is_boxed((x)) && is_arity_value(*boxed_val_rel((x),Base))) #define is_not_tuple(x) (!is_tuple((x))) #define is_tuple_arity(x, a) \ (is_boxed((x)) && *boxed_val((x)) == make_arityval((a))) @@ -803,14 +797,10 @@ do { \ ((RefThing*) _unchecked_internal_ref_val(x)) #define ref_thing_ptr(x) \ ((RefThing*) internal_ref_val(x)) -#define ref_thing_ptr_rel(x,Base) \ - ((RefThing*) internal_ref_val_rel(x,Base)) - #define is_internal_ref(x) \ - (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x)))) -#define is_internal_ref_rel(x,Base) \ - (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val_rel((x),Base))) + (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x)))) + #define is_not_internal_ref(x) \ (!is_internal_ref((x))) @@ -911,20 +901,14 @@ typedef struct external_thing_ { #define is_external_header(x) \ (((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID) -#define is_external(x) \ - (is_boxed((x)) && is_external_header(*boxed_val((x)))) -#define is_external_rel(x,Base) \ - (is_boxed((x)) && is_external_header(*boxed_val_rel((x),Base))) +#define is_external(x) (is_boxed((x)) && is_external_header(*boxed_val((x)))) + #define is_external_pid(x) \ (is_boxed((x)) && is_external_pid_header(*boxed_val((x)))) #define is_external_port(x) \ - (is_boxed((x)) && is_external_port_header(*boxed_val((x)))) -#define is_external_port_rel(x,Base) \ - (is_boxed((x)) && is_external_port_header(*boxed_val_rel((x),Base))) -#define is_external_ref(x) \ - (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x)))) -#define is_external_ref_rel(x,Base) \ - (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val_rel((x),Base))) + (is_boxed((x)) && is_external_port_header(*boxed_val((x)))) + +#define is_external_ref(x) (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x)))) #define _unchecked_is_external(x) \ (_unchecked_is_boxed((x)) && is_external_header(*_unchecked_boxed_val((x)))) @@ -958,15 +942,12 @@ _ET_DECLARE_CHECKED(Uint,external_thing_data_words,ExternalThing*) _unchecked_external_thing_data_words(_unchecked_external_thing_ptr((x))) _ET_DECLARE_CHECKED(Uint,external_data_words,Wterm) #define external_data_words(x) _ET_APPLY(external_data_words,(x)) -#define external_data_words_rel(x,Base) \ - external_thing_data_words(external_thing_ptr_rel((x),Base)) #define _unchecked_external_data(x) (_unchecked_external_thing_ptr((x))->data.ui) #define _unchecked_external_node(x) (_unchecked_external_thing_ptr((x))->node) #define external_data(x) (external_thing_ptr((x))->data.ui) #define external_node(x) (external_thing_ptr((x))->node) -#define external_node_rel(x,Base) (external_thing_ptr_rel((x),Base)->node) #define _unchecked_external_pid_data_words(x) \ _unchecked_external_data_words((x)) @@ -1141,13 +1122,11 @@ extern unsigned tag_val_def(Wterm); #if HALFWORD_HEAP #define ptr2rel(PTR,BASE) ((Eterm*)((char*)(PTR) - (char*)(BASE))) -#define rel2ptr(REL,BASE) ((typeof(REL)) ((UWord)(REL) + (char*)(BASE))) #define rterm2wterm(REL,BASE) ((Wterm)(REL) + (Wterm)(BASE)) #else /* HALFWORD_HEAP */ #define ptr2rel(PTR,BASE) (PTR) -#define rel2ptr(REL,BASE) (REL) #define rterm2wterm(REL,BASE) (REL) #endif /* !HALFWORD_HEAP */ @@ -1170,6 +1149,8 @@ extern unsigned tag_val_def(Wterm); #define internal_ref_val_rel(RTERM,BASE) internal_ref_val(rterm2wterm(RTERM,BASE)) #define external_thing_ptr_rel(RTERM, BASE) external_thing_ptr(rterm2wterm(RTERM, BASE)) +#define external_data_words_rel(RTERM,BASE) external_data_words(rterm2wterm(RTERM,BASE)) + #define external_port_node_rel(RTERM,BASE) external_port_node(rterm2wterm(RTERM,BASE)) #define external_port_data_rel(RTERM,BASE) external_port_data(rterm2wterm(RTERM,BASE)) @@ -1178,6 +1159,22 @@ extern unsigned tag_val_def(Wterm); #define external_pid_data_rel(RTERM,BASE) external_pid_data(rterm2wterm(RTERM,BASE)) #define is_binary_rel(RTERM,BASE) is_binary(rterm2wterm(RTERM,BASE)) +#define is_float_rel(RTERM,BASE) is_float(rterm2wterm(RTERM,BASE)) +#define is_fun_rel(RTERM,BASE) is_fun(rterm2wterm(RTERM,BASE)) +#define is_big_rel(RTERM,BASE) is_big(rterm2wterm(RTERM,BASE)) +#define is_export_rel(RTERM,BASE) is_export(rterm2wterm(RTERM,BASE)) +#define is_tuple_rel(RTERM,BASE) is_tuple(rterm2wterm(RTERM,BASE)) + +#define GET_DOUBLE_REL(RTERM, f, BASE) GET_DOUBLE(rterm2wterm(RTERM,BASE), f) + +#define ref_thing_ptr_rel(RTERM,BASE) ref_thing_ptr(rterm2wterm(RTERM,BASE)) +#define is_internal_ref_rel(RTERM,BASE) is_internal_ref(rterm2wterm(RTERM,BASE)) +#define is_external_rel(RTERM,BASE) is_external(rterm2wterm(RTERM,BASE)) +#define is_external_port_rel(RTERM,BASE) is_external_port(rterm2wterm(RTERM,BASE)) +#define is_external_ref_rel(RTERM,BASE) is_external_ref(rterm2wterm(RTERM,BASE)) + +#define external_node_rel(RTERM,BASE) external_node(rterm2wterm(RTERM,BASE)) + #if HALFWORD_HEAP ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base); @@ -1185,12 +1182,12 @@ ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base); #if ERTS_GLB_INLINE_INCL_FUNC_DEF ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base) { - if (a_base == b_base) { - return a == b; - } - /* Assume a and b are on different "heaps", ie can only be same if immed */ - ASSERT(is_immed(a) || is_immed(b) || rterm2wterm(a,a_base) != rterm2wterm(b,b_base)); - return is_immed(a) && a == b; + /* If bases differ, assume a and b are on different "heaps", + ie can only be same if immed */ + ASSERT(a_base == b_base || is_immed(a) || is_immed(b) + || rterm2wterm(a,a_base) != rterm2wterm(b,b_base)); + + return a == b && (a_base == b_base || is_immed(a)); } #endif diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index e36f7cf8cf..d480229999 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -225,16 +225,14 @@ int real_printf(const char *fmt, ...); #else #error Neither 32 nor 64 bit architecture #endif -#ifdef ARCH_64 -# ifdef HALFWORD_HEAP_EMULATOR +#if defined(ARCH_64) && defined(HALFWORD_HEAP_EMULATOR) # define HALFWORD_HEAP 1 # define HALFWORD_ASSERT 0 # define ASSERT_HALFWORD(COND) ASSERT(COND) -# else +#else # define HALFWORD_HEAP 0 # define HALFWORD_ASSERT 0 # define ASSERT_HALFWORD(COND) -# endif #endif #if SIZEOF_VOID_P != SIZEOF_SIZE_T diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index 00da31332a..68c62ca8e1 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2010. All Rights Reserved. + * Copyright Ericsson AB 2002-2011. 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 @@ -362,20 +362,23 @@ mseg_create(MemKind* mk, Uint size) } static ERTS_INLINE void -mseg_destroy(void *seg, Uint size) +mseg_destroy(MemKind* mk, void *seg, Uint size) { #if defined(ERTS_MSEG_FAKE_SEGMENTS) erts_sys_free(ERTS_ALC_N_INVALID, NULL, seg); #elif HAVE_MMAP + int res; -#ifdef DEBUG - int res = -#endif #if HALFWORD_HEAP - pmunmap((void *) seg, size); -#else - munmap((void *) seg, size); + if (mk == &low_mem) { + res = pmunmap((void *) seg, size); + } + else #endif + { + res = munmap((void *) seg, size); + } + ASSERT(size % page_size == 0); ASSERT(res == 0); #else @@ -389,7 +392,7 @@ mseg_destroy(void *seg, Uint size) #if HAVE_MSEG_RECREATE static ERTS_INLINE void * -mseg_recreate(void *old_seg, Uint old_size, Uint new_size) +mseg_recreate(MemKind* mk, void *old_seg, Uint old_size, Uint new_size) { void *new_seg; @@ -400,25 +403,29 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size) new_seg = erts_sys_realloc(ERTS_ALC_N_INVALID, NULL, old_seg, new_size); #elif HAVE_MREMAP #if HALFWORD_HEAP - new_seg = (void *) pmremap((void *) old_seg, - (size_t) old_size, - (size_t) new_size); -#elif defined(__NetBSD__) - new_seg = (void *) mremap((void *) old_seg, - (size_t) old_size, - NULL, - (size_t) new_size, - 0); - if (new_seg == (void *) MAP_FAILED) - new_seg = NULL; -#else - new_seg = (void *) mremap((void *) old_seg, - (size_t) old_size, - (size_t) new_size, - MREMAP_MAYMOVE); - if (new_seg == (void *) MAP_FAILED) - new_seg = NULL; + if (mk == &low_mem) { + new_seg = (void *) pmremap((void *) old_seg, + (size_t) old_size, + (size_t) new_size); + } + else #endif + { + #if defined(__NetBSD__) + new_seg = (void *) mremap((void *) old_seg, + (size_t) old_size, + NULL, + (size_t) new_size, + 0); + #else + new_seg = (void *) mremap((void *) old_seg, + (size_t) old_size, + (size_t) new_size, + MREMAP_MAYMOVE); + #endif + if (new_seg == (void *) MAP_FAILED) + new_seg = NULL; + } #else #error "Missing mseg_recreate() implementation" #endif @@ -538,7 +545,7 @@ adjust_cache_size(MemKind* mk, int force_check_limits) } if (erts_mtrace_enabled) erts_mtrace_crr_free(SEGTYPE, SEGTYPE, cd->seg); - mseg_destroy(cd->seg, cd->size); + mseg_destroy(mk, cd->seg, cd->size); unlink_cd(mk,cd); free_cd(mk,cd); } @@ -593,7 +600,14 @@ mseg_clear_cache(MemKind* mk) static ERTS_INLINE MemKind* type2mk(ErtsAlcType_t atype) { #if HALFWORD_HEAP - return (atype == ERTS_ALC_A_ETS) ? &hi_mem : &low_mem; + switch (atype) { + case ERTS_ALC_A_ETS: + //case ERTS_ALC_A_BINARY: + //case ERTS_ALC_A_FIXED_SIZE: + return &hi_mem; + default: + return &low_mem; + } #else return &the_mem; #endif @@ -726,7 +740,7 @@ mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size, if (!opt->cache || max_cache_size == 0) { if (erts_mtrace_enabled) erts_mtrace_crr_free(atype, SEGTYPE, seg); - mseg_destroy(seg, size); + mseg_destroy(mk, seg, size); } else { int check_limits = 0; @@ -744,7 +758,7 @@ mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size, } if (erts_mtrace_enabled) erts_mtrace_crr_free(SEGTYPE, SEGTYPE, cd->seg); - mseg_destroy(cd->seg, cd->size); + mseg_destroy(mk, cd->seg, cd->size); unlink_cd(mk,cd); free_cd(mk,cd); } @@ -841,7 +855,7 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p, SEGTYPE, seg, new_size); - mseg_destroy(((char *) seg) + new_size, shrink_sz); + mseg_destroy(mk, ((char *) seg) + new_size, shrink_sz); } #elif HAVE_MSEG_RECREATE @@ -875,7 +889,7 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p, #if !CAN_PARTLY_DESTROY do_recreate: #endif - new_seg = mseg_recreate((void *) seg, old_size, new_size); + new_seg = mseg_recreate(mk, (void *) seg, old_size, new_size); if (erts_mtrace_enabled) erts_mtrace_crr_realloc(new_seg, atype, SEGTYPE, seg, new_size); if (!new_seg) @@ -1828,6 +1842,7 @@ static int pmunmap(void *p, size_t size) FreeBlock *last; FreeBlock *nb = (FreeBlock *) p; + ASSERT(((unsigned long)p & CHECK_POINTER_MASK)==0); if (real_size > pagsz) { if (do_unmap(((char *) p) + pagsz,real_size - pagsz)) { return 1; diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index a2c19fa10f..691b1189be 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2011. 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 @@ -4056,7 +4056,7 @@ do_lookup_element(Tab, N, M) -> end. -heavy_concurrent(_Config) -> +heavy_concurrent(Config) when is_list(Config) -> repeat_for_opts(do_heavy_concurrent). do_heavy_concurrent(Opts) -> -- cgit v1.2.3