From fc500ad68ed5dc9718f9312a089cc3c809f5e0ae Mon Sep 17 00:00:00 2001 From: CristinaCristescu Date: Fri, 8 Apr 2016 15:07:46 +0200 Subject: [PATCH] Reduce I/O operations caused by the check of address validity. --- include/cling/Utils/Validation.h | 40 +---------- .../NullDerefProtectionTransformer.cpp | 6 ++ lib/Utils/CMakeLists.txt | 1 + lib/Utils/Validation.cpp | 69 +++++++++++++++++++ 4 files changed, 77 insertions(+), 39 deletions(-) create mode 100644 lib/Utils/Validation.cpp diff --git a/include/cling/Utils/Validation.h b/include/cling/Utils/Validation.h index 1d374a33..c95a5e4d 100644 --- a/include/cling/Utils/Validation.h +++ b/include/cling/Utils/Validation.h @@ -10,50 +10,12 @@ #ifndef CLING_UTILS_VALIDATION_H #define CLING_UTILS_VALIDATION_H -#include "llvm/Config/config.h" // for LLVM_ON_WIN32 - -#include -#include -#ifdef LLVM_ON_WIN32 -# define WIN32_LEAN_AND_MEAN -# define NOGDI -# include -#else -# include -#endif - namespace cling { namespace utils{ // Checking whether the pointer points to a valid memory location // Used for checking of void* output // Should be moved to earlier stages (ex. IR) in the future - static bool isAddressValid(const void *P) { - if (!P || P == (void *) -1) - return false; - -#ifdef LLVM_ON_WIN32 - MEMORY_BASIC_INFORMATION MBI; - if (!VirtualQuery(P, &MBI, sizeof(MBI))) - return false; - if (MBI.State != MEM_COMMIT) - return false; - return true; -#else - // There is a POSIX way of finding whether an address can be accessed for - // reading: write() will return EFAULT if not. - int FD[2]; - if (pipe(FD)) - return false; // error in pipe()? Be conservative... - int NBytes = write(FD[1], P, 1/*byte*/); - close(FD[0]); - close(FD[1]); - if (NBytes != 1) { - assert(errno == EFAULT && "unexpected pipe write error"); - return false; - } - return true; -#endif - } + bool isAddressValid(const void *P); } } diff --git a/lib/Interpreter/NullDerefProtectionTransformer.cpp b/lib/Interpreter/NullDerefProtectionTransformer.cpp index 179f0ebd..0622ddc7 100644 --- a/lib/Interpreter/NullDerefProtectionTransformer.cpp +++ b/lib/Interpreter/NullDerefProtectionTransformer.cpp @@ -92,6 +92,12 @@ namespace cling { return true; } + bool VisitDecl (Decl* D) + { + printf("%ld\n", *(long*)D); + return true; + } + bool VisitFunctionDecl(FunctionDecl* FD) { if (!FD->isConstexpr()) { CompoundStmt* CS = dyn_cast_or_null(FD->getBody()); diff --git a/lib/Utils/CMakeLists.txt b/lib/Utils/CMakeLists.txt index ec988064..578e9bb7 100644 --- a/lib/Utils/CMakeLists.txt +++ b/lib/Utils/CMakeLists.txt @@ -8,6 +8,7 @@ add_cling_library(clingUtils AST.cpp + Validation.cpp LINK_LIBS clangCodeGen diff --git a/lib/Utils/Validation.cpp b/lib/Utils/Validation.cpp new file mode 100644 index 00000000..bd9e02b5 --- /dev/null +++ b/lib/Utils/Validation.cpp @@ -0,0 +1,69 @@ +//--------------------------------------------------------------------*- C++ -*- +// CLING - the C++ LLVM-based InterpreterG :) +// author: Vassil Vassilev +// +// This file is dual-licensed: you can choose to license it under the University +// of Illinois Open Source License or the GNU Lesser General Public License. See +// LICENSE.TXT for details. +//------------------------------------------------------------------------------ + +#include "cling/Utils/Validation.h" + +#include +#include +#ifdef LLVM_ON_WIN32 +# include +#else +#include +# include +#endif + + + +namespace cling { + namespace utils { + + static int getNullDevFileDescriptor() { +#ifdef LLVM_ON_WIN32 + return 0; +#else + struct FileDescriptor { + int FD; + const char* file = "/dev/null"; + FileDescriptor() { FD = open(file, O_WRONLY); } + ~FileDescriptor() { + close(FD); + } + }; + static FileDescriptor nullDev; + return nullDev.FD; +#endif + } + + // Checking whether the pointer points to a valid memory location + // Used for checking of void* output + // Should be moved to earlier stages (ex. IR) in the future + bool isAddressValid(const void *P) { + if (!P || P == (void *) -1) + return false; + +#ifdef LLVM_ON_WIN32 + MEMORY_BASIC_INFORMATION MBI; + if (!VirtualQuery(P, &MBI, sizeof(MBI))) + return false; + if (MBI.State != MEM_COMMIT) + return false; + return true; +#else + // There is a POSIX way of finding whether an address can be accessed for + // reading: write() will return EFAULT if not. + int NBytes = write(getNullDevFileDescriptor(), P, 1/*byte*/); + if (NBytes != 1) { + assert(errno == EFAULT && "unexpected pipe write error"); + return false; + } + return true; +#endif + } + } +}