From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- erts/emulator/hipe/hipe_stack.h | 128 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 erts/emulator/hipe/hipe_stack.h (limited to 'erts/emulator/hipe/hipe_stack.h') diff --git a/erts/emulator/hipe/hipe_stack.h b/erts/emulator/hipe/hipe_stack.h new file mode 100644 index 0000000000..354ac81b4c --- /dev/null +++ b/erts/emulator/hipe/hipe_stack.h @@ -0,0 +1,128 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2001-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% + */ +/* $Id$ + */ +#ifndef HIPE_STACK_H +#define HIPE_STACK_H + +#include "hipe_arch.h" + +/* + * Stack descriptors. + */ + +#include /* offsetof() */ + +struct sdesc { + struct { + unsigned long hvalue; /* return address */ + struct sdesc *next; /* hash collision chain */ + } bucket; + unsigned int summary; /* frame size, exn handler presence flag, arity */ + unsigned int livebits[1]; /* size depends on arch & data in summary field */ +}; + +struct sdesc_with_exnra { + unsigned long exnra; + struct sdesc sdesc; +}; + +static __inline__ unsigned int sdesc_fsize(const struct sdesc *sdesc) +{ + return sdesc->summary >> 9; +} + +static __inline__ unsigned int sdesc_arity(const struct sdesc *sdesc) +{ + return sdesc->summary & 0xFF; +} + +static __inline__ unsigned long sdesc_exnra(const struct sdesc *sdesc) +{ + if ((sdesc->summary & (1<<8))) { + const char *tmp; + tmp = (const char*)sdesc - offsetof(struct sdesc_with_exnra, sdesc); + return ((const struct sdesc_with_exnra*)tmp)->exnra; + } + return 0; +} + +struct hipe_sdesc_table { + unsigned int log2size; + unsigned int mask; /* INV: mask == (1 << log2size)-1 */ + unsigned int used; + struct sdesc **bucket; +}; +extern struct hipe_sdesc_table hipe_sdesc_table; + +extern struct sdesc *hipe_put_sdesc(struct sdesc*); +extern void hipe_init_sdesc_table(struct sdesc*); +extern struct sdesc *hipe_decode_sdesc(Eterm); + +#if !defined(__GNUC__) || (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +#define __builtin_expect(x, expected_value) (x) +#endif +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + +static __inline__ const struct sdesc *hipe_find_sdesc(unsigned long ra) +{ + unsigned int i = (ra >> HIPE_RA_LSR_COUNT) & hipe_sdesc_table.mask; + const struct sdesc *sdesc = hipe_sdesc_table.bucket[i]; + if (likely(sdesc->bucket.hvalue == ra)) + return sdesc; + do { + sdesc = sdesc->bucket.next; + } while (sdesc->bucket.hvalue != ra); + return sdesc; +} + +AEXTERN(void,nbif_stack_trap_ra,(void)); + +extern void hipe_print_nstack(Process*); +extern void hipe_find_handler(Process*); +extern void (*hipe_handle_stack_trap(Process*))(void); +extern void hipe_update_stack_trap(Process*, const struct sdesc*); +extern int hipe_fill_stacktrace(Process*, int, Eterm**); + +#if 0 && defined(HIPE_NSTACK_GROWS_UP) +#define hipe_nstack_start(p) ((p)->hipe.nstack) +#define hipe_nstack_used(p) ((p)->hipe.nsp - (p)->hipe.nstack) +#endif +#if defined(HIPE_NSTACK_GROWS_DOWN) +#define hipe_nstack_start(p) ((p)->hipe.nsp) +#define hipe_nstack_used(p) ((p)->hipe.nstend - (p)->hipe.nsp) +#endif + +/* + * GC support procedures + */ +extern Eterm *fullsweep_nstack(Process *p, Eterm *n_htop); +extern void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop); + +#ifdef HYBRID +#ifdef INCREMENTAL +extern Eterm *ma_fullsweep_nstack(Process *p, Eterm *n_htop, Eterm *n_hend); +#else +extern Eterm *ma_fullsweep_nstack(Process *p, Eterm *n_htop); +#endif +extern void ma_gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop); +#endif /* HYBRID */ + +#endif /* HIPE_STACK_H */ -- cgit v1.2.3