stack_alloc.h revision 98913fed6520d8849fb2e246be943e04474aefa4
1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov/* Copyright (C) 2002 Jean-Marc Valin */
2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/**
3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   @file stack_alloc.h
4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   @brief Temporary memory allocation on stack
5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany*/
6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/*
7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   Redistribution and use in source and binary forms, with or without
8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   modification, are permitted provided that the following conditions
9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   are met:
10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   - Redistributions of source code must retain the above copyright
12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   notice, this list of conditions and the following disclaimer.
13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   - Redistributions in binary form must reproduce the above copyright
15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   notice, this list of conditions and the following disclaimer in the
16da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   documentation and/or other materials provided with the distribution.
17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   - Neither the name of the Xiph.org Foundation nor the names of its
19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   contributors may be used to endorse or promote products derived from
20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   this software without specific prior written permission.
21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
26da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany*/
34da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
35da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#ifndef STACK_ALLOC_H
36da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define STACK_ALLOC_H
37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#ifdef USE_ALLOCA
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany# ifdef WIN32
40da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#  include <malloc.h>
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany# else
42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#  ifdef HAVE_ALLOCA_H
43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#   include <alloca.h>
44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#  else
45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#   include <stdlib.h>
46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#  endif
47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany# endif
48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#endif
49da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
50da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/**
51da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @def ALIGN(stack, size)
52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * Aligns the stack to a 'size' boundary
54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param stack Stack
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param size  New size boundary
57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany */
58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/**
60da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @def PUSH(stack, size, type)
61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * Allocates 'size' elements of type 'type' on the stack
63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param stack Stack
65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param size  Number of elements
66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param type  Type of element
67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany */
68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/**
70da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @def VARDECL(var)
71da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
72da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * Declare variable on stack
73da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
74da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param var Variable to declare
75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany */
76da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany/**
78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @def ALLOC(var, size, type)
79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * Allocate 'size' elements of 'type' on stack
81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany *
82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param var  Name of variable to allocate
83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param size Number of elements
84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany * @param type Type of element
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany */
86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
87da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#ifdef ENABLE_VALGRIND
88da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
89da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <valgrind/memcheck.h>
90da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
91da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
92da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
93da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
94da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
95da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#else
96da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
97da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
98da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
99da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
100da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
101da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#endif
102da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
103da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#if defined(VAR_ARRAYS)
104da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define VARDECL(var)
105da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define ALLOC(var, size, type) type var[size]
106da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#elif defined(USE_ALLOCA)
107da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define VARDECL(var) var
108da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size))
109da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#else
110da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define VARDECL(var) var
111da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#define ALLOC(var, size, type) var = PUSH(stack, size, type)
112da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#endif
113da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
114da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
115da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#endif
116da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany