aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/global.h48
-rw-r--r--erts/emulator/beam/utils.c20
2 files changed, 54 insertions, 14 deletions
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 1fb069232a..dcba8bbba8 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -372,7 +372,7 @@ extern int stackdump_on_exit;
* DESTROY_ESTACK(Stack)
*/
-typedef struct {
+typedef struct ErtsEStack_ {
Eterm* start;
Eterm* sp;
Eterm* end;
@@ -381,7 +381,7 @@ typedef struct {
#define DEF_ESTACK_SIZE (16)
-void erl_grow_estack(ErtsEStack*, Eterm* def_stack);
+void erl_grow_estack(ErtsEStack*, Eterm* def_stack, Uint need);
#define ESTK_CONCAT(a,b) a##b
#define ESTK_DEF_STACK(s) ESTK_CONCAT(s,_default_estack)
@@ -457,7 +457,7 @@ do { \
#define ESTACK_PUSH(s, x) \
do { \
if (s.sp == s.end) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
+ erl_grow_estack(&s, ESTK_DEF_STACK(s), 1); \
} \
*s.sp++ = (x); \
} while(0)
@@ -465,7 +465,7 @@ do { \
#define ESTACK_PUSH2(s, x, y) \
do { \
if (s.sp > s.end - 2) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
+ erl_grow_estack(&s, ESTK_DEF_STACK(s), 2); \
} \
*s.sp++ = (x); \
*s.sp++ = (y); \
@@ -474,7 +474,7 @@ do { \
#define ESTACK_PUSH3(s, x, y, z) \
do { \
if (s.sp > s.end - 3) { \
- erl_grow_estack(&s, ESTK_DEF_STACK(s)); \
+ erl_grow_estack(&s, ESTK_DEF_STACK(s), 3); \
} \
*s.sp++ = (x); \
*s.sp++ = (y); \
@@ -492,6 +492,20 @@ do { \
*s.sp++ = (E4); \
} while(0)
+#define ESTACK_RESERVE(s, push_cnt) \
+do { \
+ if (s.sp > s.end - (push_cnt)) { \
+ erl_grow_estack(&s, ESTK_DEF_STACK(s), (push_cnt)); \
+ } \
+} while(0)
+
+/* Must be preceded by ESTACK_RESERVE */
+#define ESTACK_FAST_PUSH(s, x) \
+do { \
+ ASSERT(s.sp < s.end); \
+ *s.sp++ = (x); \
+} while(0)
+
#define ESTACK_COUNT(s) (s.sp - s.start)
#define ESTACK_ISEMPTY(s) (s.sp == s.start)
#define ESTACK_POP(s) (*(--s.sp))
@@ -501,7 +515,7 @@ do { \
* WSTACK: same as ESTACK but with UWord instead of Eterm
*/
-typedef struct {
+typedef struct ErtsWStack_ {
UWord* wstart;
UWord* wsp;
UWord* wend;
@@ -510,7 +524,7 @@ typedef struct {
#define DEF_WSTACK_SIZE (16)
-void erl_grow_wstack(ErtsWStack*, UWord* def_stack);
+void erl_grow_wstack(ErtsWStack*, UWord* def_stack, Uint need);
#define WSTK_CONCAT(a,b) a##b
#define WSTK_DEF_STACK(s) WSTK_CONCAT(s,_default_wstack)
@@ -592,7 +606,7 @@ do { \
#define WSTACK_PUSH(s, x) \
do { \
if (s.wsp == s.wend) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ erl_grow_wstack(&s, WSTK_DEF_STACK(s), 1); \
} \
*s.wsp++ = (x); \
} while(0)
@@ -600,7 +614,7 @@ do { \
#define WSTACK_PUSH2(s, x, y) \
do { \
if (s.wsp > s.wend - 2) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ erl_grow_wstack(&s, WSTK_DEF_STACK(s), 2); \
} \
*s.wsp++ = (x); \
*s.wsp++ = (y); \
@@ -609,7 +623,7 @@ do { \
#define WSTACK_PUSH3(s, x, y, z) \
do { \
if (s.wsp > s.wend - 3) { \
- erl_grow_wstack(&s, WSTK_DEF_STACK(s)); \
+ erl_grow_wstack(&s, WSTK_DEF_STACK(s), 3); \
} \
*s.wsp++ = (x); \
*s.wsp++ = (y); \
@@ -652,6 +666,20 @@ do { \
*s.wsp++ = (A6); \
} while(0)
+#define WSTACK_RESERVE(s, push_cnt) \
+do { \
+ if (s.wsp > s.wend - (push_cnt)) { \
+ erl_grow_wstack(&s, WSTK_DEF_STACK(s), (push_cnt)); \
+ } \
+} while(0)
+
+/* Must be preceded by WSTACK_RESERVE */
+#define WSTACK_FAST_PUSH(s, x) \
+do { \
+ ASSERT(s.wsp < s.wend); \
+ *s.wsp++ = (x); \
+} while(0)
+
#define WSTACK_COUNT(s) (s.wsp - s.wstart)
#define WSTACK_ISEMPTY(s) (s.wsp == s.wstart)
#define WSTACK_POP(s) ((ASSERT(s.wsp > s.wstart)),*(--s.wsp))
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index cea20a6002..bd90ec2fba 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -190,11 +190,17 @@ erts_set_hole_marker(Eterm* ptr, Uint sz)
* Helper function for the ESTACK macros defined in global.h.
*/
void
-erl_grow_estack(ErtsEStack* s, Eterm* default_estack)
+erl_grow_estack(ErtsEStack* s, Eterm* default_estack, Uint need)
{
Uint old_size = (s->end - s->start);
- Uint new_size = old_size * 2;
+ Uint new_size;
Uint sp_offs = s->sp - s->start;
+
+ if (need < old_size)
+ new_size = 2*old_size;
+ else
+ new_size = ((need / old_size) + 2) * old_size;
+
if (s->start != default_estack) {
s->start = erts_realloc(s->alloc_type, s->start,
new_size*sizeof(Eterm));
@@ -210,11 +216,17 @@ erl_grow_estack(ErtsEStack* s, Eterm* default_estack)
* Helper function for the WSTACK macros defined in global.h.
*/
void
-erl_grow_wstack(ErtsWStack* s, UWord* default_wstack)
+erl_grow_wstack(ErtsWStack* s, UWord* default_wstack, Uint need)
{
Uint old_size = (s->wend - s->wstart);
- Uint new_size = old_size * 2;
+ Uint new_size;
Uint sp_offs = s->wsp - s->wstart;
+
+ if (need < old_size)
+ new_size = 2 * old_size;
+ else
+ new_size = ((need / old_size) + 2) * old_size;
+
if (s->wstart != default_wstack) {
s->wstart = erts_realloc(s->alloc_type, s->wstart,
new_size*sizeof(UWord));