Home | History | Annotate | Download | only in Common
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "Memory.hpp"
     16 
     17 #include "Types.hpp"
     18 #include "Debug.hpp"
     19 
     20 #if defined(_WIN32)
     21 	#ifndef WIN32_LEAN_AND_MEAN
     22 		#define WIN32_LEAN_AND_MEAN
     23 	#endif
     24 	#include <windows.h>
     25 	#include <intrin.h>
     26 #else
     27 	#include <sys/mman.h>
     28 	#include <unistd.h>
     29 #endif
     30 
     31 #include <memory.h>
     32 
     33 #undef allocate
     34 #undef deallocate
     35 
     36 #if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined (_M_X64)) && !defined(__x86__)
     37 #define __x86__
     38 #endif
     39 
     40 namespace sw
     41 {
     42 size_t memoryPageSize()
     43 {
     44 	static int pageSize = 0;
     45 
     46 	if(pageSize == 0)
     47 	{
     48 		#if defined(_WIN32)
     49 			SYSTEM_INFO systemInfo;
     50 			GetSystemInfo(&systemInfo);
     51 			pageSize = systemInfo.dwPageSize;
     52 		#else
     53 			pageSize = sysconf(_SC_PAGESIZE);
     54 		#endif
     55 	}
     56 
     57 	return pageSize;
     58 }
     59 
     60 struct Allocation
     61 {
     62 //	size_t bytes;
     63 	unsigned char *block;
     64 };
     65 
     66 inline void *allocateRaw(size_t bytes, size_t alignment)
     67 {
     68 	unsigned char *block = new unsigned char[bytes + sizeof(Allocation) + alignment];
     69 	unsigned char *aligned = nullptr;
     70 
     71 	if(block)
     72 	{
     73 		aligned = (unsigned char*)((uintptr_t)(block + sizeof(Allocation) + alignment - 1) & -(intptr_t)alignment);
     74 		Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
     75 
     76 	//	allocation->bytes = bytes;
     77 		allocation->block = block;
     78 	}
     79 
     80 	return aligned;
     81 }
     82 
     83 void *allocate(size_t bytes, size_t alignment)
     84 {
     85 	void *memory = allocateRaw(bytes, alignment);
     86 
     87 	if(memory)
     88 	{
     89 		memset(memory, 0, bytes);
     90 	}
     91 
     92 	return memory;
     93 }
     94 
     95 void deallocate(void *memory)
     96 {
     97 	if(memory)
     98 	{
     99 		unsigned char *aligned = (unsigned char*)memory;
    100 		Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
    101 
    102 		delete[] allocation->block;
    103 	}
    104 }
    105 
    106 void *allocateExecutable(size_t bytes)
    107 {
    108 	size_t pageSize = memoryPageSize();
    109 
    110 	return allocate((bytes + pageSize - 1) & ~(pageSize - 1), pageSize);
    111 }
    112 
    113 void markExecutable(void *memory, size_t bytes)
    114 {
    115 	#if defined(_WIN32)
    116 		unsigned long oldProtection;
    117 		VirtualProtect(memory, bytes, PAGE_EXECUTE_READ, &oldProtection);
    118 	#else
    119 		mprotect(memory, bytes, PROT_READ | PROT_EXEC);
    120 	#endif
    121 }
    122 
    123 void deallocateExecutable(void *memory, size_t bytes)
    124 {
    125 	#if defined(_WIN32)
    126 		unsigned long oldProtection;
    127 		VirtualProtect(memory, bytes, PAGE_READWRITE, &oldProtection);
    128 	#else
    129 		mprotect(memory, bytes, PROT_READ | PROT_WRITE);
    130 	#endif
    131 
    132 	deallocate(memory);
    133 }
    134 
    135 void clear(uint16_t *memory, uint16_t element, size_t count)
    136 {
    137 	#if defined(_MSC_VER) && defined(__x86__)
    138 		__stosw(memory, element, count);
    139 	#elif defined(__GNUC__) && defined(__x86__)
    140 		__asm__("rep stosw" : : "D"(memory), "a"(element), "c"(count));
    141 	#else
    142 		for(size_t i = 0; i < count; i++)
    143 		{
    144 			memory[i] = element;
    145 		}
    146 	#endif
    147 }
    148 
    149 void clear(uint32_t *memory, uint32_t element, size_t count)
    150 {
    151 	#if defined(_MSC_VER) && defined(__x86__)
    152 		__stosd((unsigned long*)memory, element, count);
    153 	#elif defined(__GNUC__) && defined(__x86__)
    154 		__asm__("rep stosl" : : "D"(memory), "a"(element), "c"(count));
    155 	#else
    156 		for(size_t i = 0; i < count; i++)
    157 		{
    158 			memory[i] = element;
    159 		}
    160 	#endif
    161 }
    162 }
    163