Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / nanojit / VMPI.cpp
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1 (the
7  * "License"); you may not use this file except in compliance with the License. You may obtain
8  * a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
11  * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
12  * language governing rights and limitations under the License.
13  *
14  * The Original Code is [Open Source Virtual Machine.]
15  *
16  * The Initial Developer of the Original Code is Adobe System Incorporated.  Portions created
17  * by the Initial Developer are Copyright (C)[ 2004-2006 ] Adobe Systems Incorporated. All Rights
18  * Reserved.
19  *
20  * Contributor(s): Adobe AS3 Team
21  *                 Andreas Gal <gal@mozilla.com>
22  *
23  * Alternatively, the contents of this file may be used under the terms of either the GNU
24  * General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public
25  * License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the
26  * LGPL are applicable instead of those above. If you wish to allow use of your version of this
27  * file only under the terms of either the GPL or the LGPL, and not to allow others to use your
28  * version of this file under the terms of the MPL, indicate your decision by deleting provisions
29  * above and replace them with the notice and other provisions required by the GPL or the
30  * LGPL. If you do not delete the provisions above, a recipient may use your version of this file
31  * under the terms of any one of the MPL, the GPL or the LGPL.
32  *
33  ***** END LICENSE BLOCK ***** */
34
35 #include "nanojit.h"
36
37 #ifdef SOLARIS
38     typedef caddr_t maddr_ptr;
39 #else
40     typedef void *maddr_ptr;
41 #endif
42
43 using namespace avmplus;
44
45 size_t
46 VMPI_getVMPageSize()
47 {
48     return 4096;
49 }
50
51 #ifdef WIN32
52 void
53 VMPI_setPageProtection(void *address,
54                        size_t size,
55                        bool executableFlag,
56                        bool writeableFlag)
57 {
58     DWORD oldProtectFlags = 0;
59     DWORD newProtectFlags = 0;
60     if ( executableFlag && writeableFlag ) {
61         newProtectFlags = PAGE_EXECUTE_READWRITE;
62     } else if ( executableFlag ) {
63         newProtectFlags = PAGE_EXECUTE_READ;
64     } else if ( writeableFlag ) {
65         newProtectFlags = PAGE_READWRITE;
66     } else {
67         newProtectFlags = PAGE_READONLY;
68     }
69
70     BOOL retval;
71     MEMORY_BASIC_INFORMATION mbi;
72     do {
73         VirtualQuery(address, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
74         size_t markSize = size > mbi.RegionSize ? mbi.RegionSize : size;
75
76         retval = VirtualProtect(address, markSize, newProtectFlags, &oldProtectFlags);
77         NanoAssert(retval);
78
79         address = (char*) address + markSize;
80         size -= markSize;
81     } while(size > 0 && retval);
82
83     // We should not be clobbering PAGE_GUARD protections
84     NanoAssert((oldProtectFlags & PAGE_GUARD) == 0);
85 }
86
87 #elif defined(AVMPLUS_OS2)
88
89 void
90 VMPI_setPageProtection(void *address,
91                        size_t size,
92                        bool executableFlag,
93                        bool writeableFlag)
94 {
95     ULONG flags = PAG_READ;
96     if (executableFlag) {
97         flags |= PAG_EXECUTE;
98     }
99     if (writeableFlag) {
100         flags |= PAG_WRITE;
101     }
102     address = (void*)((size_t)address & ~(0xfff));
103     size = (size + 0xfff) & ~(0xfff);
104
105     ULONG attribFlags = PAG_FREE;
106     while (size) {
107         ULONG attrib;
108         ULONG range = size;
109         ULONG retval = DosQueryMem(address, &range, &attrib);
110         NanoAssert(retval == 0);
111
112         // exit if this is the start of the next memory object
113         if (attrib & attribFlags) {
114             break;
115         }
116         attribFlags |= PAG_BASE;
117
118         range = size > range ? range : size;
119         retval = DosSetMem(address, range, flags);
120         NanoAssert(retval == 0);
121
122         address = (char*)address + range;
123         size -= range;
124     }
125 }
126
127 #else // !WIN32 && !AVMPLUS_OS2
128
129 void VMPI_setPageProtection(void *address,
130                             size_t size,
131                             bool executableFlag,
132                             bool writeableFlag)
133 {
134   int bitmask = sysconf(_SC_PAGESIZE) - 1;
135   // mprotect requires that the addresses be aligned on page boundaries
136   void *endAddress = (void*) ((char*)address + size);
137   void *beginPage = (void*) ((size_t)address & ~bitmask);
138   void *endPage   = (void*) (((size_t)endAddress + bitmask) & ~bitmask);
139   size_t sizePaged = (size_t)endPage - (size_t)beginPage;
140
141   int flags = PROT_READ;
142   if (executableFlag) {
143     flags |= PROT_EXEC;
144   }
145   if (writeableFlag) {
146     flags |= PROT_WRITE;
147   }
148   int retval = mprotect((maddr_ptr)beginPage, (unsigned int)sizePaged, flags);
149   NanoAssert(retval == 0);
150   (void)retval;
151 }
152
153 #endif // WIN32