Home | History | Annotate | Download | only in Reactor
      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 "LLVMRoutineManager.hpp"
     16 
     17 #include "LLVMRoutine.hpp"
     18 #include "llvm/Function.h"
     19 #include "../Common/Memory.hpp"
     20 #include "../Common/Thread.hpp"
     21 #include "../Common/Debug.hpp"
     22 
     23 namespace sw
     24 {
     25 	using namespace llvm;
     26 
     27 	volatile int LLVMRoutineManager::averageInstructionSize = 4;
     28 
     29 	LLVMRoutineManager::LLVMRoutineManager()
     30 	{
     31 		routine = nullptr;
     32 	}
     33 
     34 	LLVMRoutineManager::~LLVMRoutineManager()
     35 	{
     36 		delete routine;
     37 	}
     38 
     39 	void LLVMRoutineManager::AllocateGOT()
     40 	{
     41 		UNIMPLEMENTED();
     42 	}
     43 
     44 	uint8_t *LLVMRoutineManager::allocateStub(const GlobalValue *function, unsigned stubSize, unsigned alignment)
     45 	{
     46 		UNIMPLEMENTED();
     47 		return nullptr;
     48 	}
     49 
     50 	uint8_t *LLVMRoutineManager::startFunctionBody(const llvm::Function *function, uintptr_t &actualSize)
     51 	{
     52 		if(actualSize == 0)   // Estimate size
     53 		{
     54 			size_t instructionCount = 0;
     55 			for(llvm::Function::const_iterator basicBlock = function->begin(); basicBlock != function->end(); basicBlock++)
     56 			{
     57 				instructionCount += basicBlock->size();
     58 			}
     59 
     60 			actualSize = instructionCount * averageInstructionSize;
     61 		}
     62 		else   // Estimate was too low
     63 		{
     64 			sw::atomicIncrement(&averageInstructionSize);
     65 		}
     66 
     67 		// Round up to the next page size
     68 		size_t pageSize = memoryPageSize();
     69 		actualSize = (actualSize + pageSize - 1) & ~(pageSize - 1);
     70 
     71 		delete routine;
     72 		routine = new LLVMRoutine(static_cast<int>(actualSize));
     73 
     74 		return (uint8_t*)routine->buffer;
     75 	}
     76 
     77 	void LLVMRoutineManager::endFunctionBody(const llvm::Function *function, uint8_t *functionStart, uint8_t *functionEnd)
     78 	{
     79 		routine->functionSize = static_cast<int>(static_cast<ptrdiff_t>(functionEnd - functionStart));
     80 	}
     81 
     82 	uint8_t *LLVMRoutineManager::startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
     83 	{
     84 		UNIMPLEMENTED();
     85 		return nullptr;
     86 	}
     87 
     88 	void LLVMRoutineManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart, uint8_t *TableEnd, uint8_t* FrameRegister)
     89 	{
     90 		UNIMPLEMENTED();
     91 	}
     92 
     93 	uint8_t *LLVMRoutineManager::getGOTBase() const
     94 	{
     95 		ASSERT(!HasGOT);
     96 		return nullptr;
     97 	}
     98 
     99 	uint8_t *LLVMRoutineManager::allocateSpace(intptr_t Size, unsigned Alignment)
    100 	{
    101 		UNIMPLEMENTED();
    102 		return nullptr;
    103 	}
    104 
    105 	uint8_t *LLVMRoutineManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
    106 	{
    107 		UNIMPLEMENTED();
    108 		return nullptr;
    109 	}
    110 
    111 	void LLVMRoutineManager::deallocateFunctionBody(void *Body)
    112 	{
    113 		delete routine;
    114 		routine = nullptr;
    115 	}
    116 
    117 	void LLVMRoutineManager::deallocateExceptionTable(void *ET)
    118 	{
    119 		if(ET)
    120 		{
    121 			UNIMPLEMENTED();
    122 		}
    123 	}
    124 
    125 	void LLVMRoutineManager::setMemoryWritable()
    126 	{
    127 	}
    128 
    129 	void LLVMRoutineManager::setMemoryExecutable()
    130 	{
    131 		markExecutable(routine->buffer, routine->bufferSize);
    132 	}
    133 
    134 	void LLVMRoutineManager::setPoisonMemory(bool poison)
    135 	{
    136 		UNIMPLEMENTED();
    137 	}
    138 
    139 	LLVMRoutine *LLVMRoutineManager::acquireRoutine(void *entry)
    140 	{
    141 		routine->entry = entry;
    142 
    143 		LLVMRoutine *result = routine;
    144 		routine = nullptr;
    145 
    146 		return result;
    147 	}
    148 }
    149