1/*
2    Title:  osomem.h - Interface to OS memory management
3
4    Copyright (c) 2006, 2017-18, 2020 David C.J. Matthews
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License version 2.1 as published by the Free Software Foundation.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19*/
20
21#ifndef OS_MEM_H_INCLUDED
22#define OS_MEM_H_INCLUDED
23
24
25// We need size_t so include these two here.
26#ifdef HAVE_STRING_H
27#include <string.h>
28#endif
29
30#ifdef HAVE_STDLIB_H
31#include <stdlib.h>
32#endif
33
34#ifdef POLYML32IN64
35#include "bitmap.h"
36#endif
37
38#include "locking.h"
39
40
41// This class provides access to the memory management provided by the
42// operating system.  It would be nice if we could always use malloc and
43// free for this but we need to have execute permission on the code
44// objects.
45
46class OSMem {
47
48public:
49    OSMem();
50    virtual ~OSMem();
51
52    enum _MemUsage {
53        UsageData,          // Data or code in the interpreted version
54        UsageStack,         // Stack
55        UsageExecutableCode // Code in the native code versions.
56    };
57
58    bool Initialise(enum _MemUsage usage, size_t space = 0, void** pBase = 0);
59
60    // Allocate space and return a pointer to it.  The size is the minimum
61    // size requested in bytes and it is updated with the actual space allocated.
62    // Returns NULL if it cannot allocate the space.
63    void *AllocateDataArea(size_t& bytes);
64
65    // Release the space previously allocated.  This must free the whole of
66    // the segment.  The space must be the size actually allocated.
67    bool FreeDataArea(void* p, size_t space);
68
69    // Enable/disable writing.  This must apply to the whole of a segment.
70    // Only for data areas.
71    bool EnableWrite(bool enable, void* p, size_t space);
72
73    // Allocate code area.  Some systems will not allow both write and execute permissions
74    // on the same page.  On those systems we have to allocate two regions of shared memory,
75    // one with read+execute permission and the other with read+write.
76    void *AllocateCodeArea(size_t& bytes, void*& shadowArea);
77
78    // Free the allocated areas.
79    bool FreeCodeArea(void* codeAddr, void* dataAddr, size_t space);
80
81    // Remove write access.  This is used after the permanent code area has been created
82    // either from importing a portable export file or copying the area in 32-in-64.
83    bool DisableWriteForCode(void* codeAddr, void* dataAddr, size_t space);
84
85protected:
86    size_t pageSize;
87    enum _MemUsage memUsage;
88
89#ifndef _WIN32
90    // If we need to use dual areas because WRITE+EXECUTE permission is not allowed.
91    int shadowFd;
92    PLock allocLock;
93    size_t allocPtr;
94#endif
95
96#ifdef POLYML32IN64
97    Bitmap pageMap;
98    uintptr_t lastAllocated;
99    char* memBase, *shadowBase;
100    PLock bitmapLock;
101#endif
102
103};
104
105#endif
106