1 //===- JITTest.cpp - Unit tests for the JIT -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
11 #include "llvm/ADT/OwningPtr.h"
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/Assembly/Parser.h"
14 #include "llvm/BasicBlock.h"
15 #include "llvm/Constant.h"
16 #include "llvm/Constants.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/ExecutionEngine/JIT.h"
19 #include "llvm/ExecutionEngine/JITMemoryManager.h"
20 #include "llvm/Function.h"
21 #include "llvm/GlobalValue.h"
22 #include "llvm/GlobalVariable.h"
23 #include "llvm/LLVMContext.h"
24 #include "llvm/Module.h"
25 #include "llvm/ModuleProvider.h"
26 #include "llvm/Support/IRBuilder.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/TypeBuilder.h"
29 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/Target/TargetSelect.h"
31 #include "llvm/Type.h"
42 #if _POSIX_MAPPED_FILES > 0
50 Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
51 std::vector<const Type*> params;
52 const FunctionType *FTy = FunctionType::get(G->getType()->getElementType(),
54 Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
55 BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F);
56 IRBuilder<> builder(Entry);
57 Value *Load = builder.CreateLoad(G);
58 const Type *GTy = G->getType()->getElementType();
59 Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL));
60 builder.CreateStore(Add, G);
61 builder.CreateRet(Add);
65 std::string DumpFunction(const Function *F) {
67 raw_string_ostream(Result) << "" << *F;
71 class RecordingJITMemoryManager : public JITMemoryManager {
72 const OwningPtr<JITMemoryManager> Base;
74 RecordingJITMemoryManager()
75 : Base(JITMemoryManager::CreateDefaultMemManager()) {
79 virtual void setMemoryWritable() { Base->setMemoryWritable(); }
80 virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
81 virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
82 virtual void AllocateGOT() { Base->AllocateGOT(); }
83 virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); }
84 struct StartFunctionBodyCall {
85 StartFunctionBodyCall(uint8_t *Result, const Function *F,
86 uintptr_t ActualSize, uintptr_t ActualSizeResult)
87 : Result(Result), F(F), F_dump(DumpFunction(F)),
88 ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
93 uintptr_t ActualSizeResult;
95 std::vector<StartFunctionBodyCall> startFunctionBodyCalls;
96 virtual uint8_t *startFunctionBody(const Function *F,
97 uintptr_t &ActualSize) {
98 uintptr_t InitialActualSize = ActualSize;
99 uint8_t *Result = Base->startFunctionBody(F, ActualSize);
100 startFunctionBodyCalls.push_back(
101 StartFunctionBodyCall(Result, F, InitialActualSize, ActualSize));
105 virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
106 unsigned Alignment) {
108 return Base->allocateStub(F, StubSize, Alignment);
110 struct EndFunctionBodyCall {
111 EndFunctionBodyCall(const Function *F, uint8_t *FunctionStart,
112 uint8_t *FunctionEnd)
113 : F(F), F_dump(DumpFunction(F)),
114 FunctionStart(FunctionStart), FunctionEnd(FunctionEnd) {}
117 uint8_t *FunctionStart;
118 uint8_t *FunctionEnd;
120 std::vector<EndFunctionBodyCall> endFunctionBodyCalls;
121 virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
122 uint8_t *FunctionEnd) {
123 endFunctionBodyCalls.push_back(
124 EndFunctionBodyCall(F, FunctionStart, FunctionEnd));
125 Base->endFunctionBody(F, FunctionStart, FunctionEnd);
127 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
128 return Base->allocateSpace(Size, Alignment);
130 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
131 return Base->allocateGlobal(Size, Alignment);
133 struct DeallocateFunctionBodyCall {
134 DeallocateFunctionBodyCall(const void *Body) : Body(Body) {}
137 std::vector<DeallocateFunctionBodyCall> deallocateFunctionBodyCalls;
138 virtual void deallocateFunctionBody(void *Body) {
139 deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body));
140 Base->deallocateFunctionBody(Body);
142 struct DeallocateExceptionTableCall {
143 DeallocateExceptionTableCall(const void *ET) : ET(ET) {}
146 std::vector<DeallocateExceptionTableCall> deallocateExceptionTableCalls;
147 virtual void deallocateExceptionTable(void *ET) {
148 deallocateExceptionTableCalls.push_back(DeallocateExceptionTableCall(ET));
149 Base->deallocateExceptionTable(ET);
151 struct StartExceptionTableCall {
152 StartExceptionTableCall(uint8_t *Result, const Function *F,
153 uintptr_t ActualSize, uintptr_t ActualSizeResult)
154 : Result(Result), F(F), F_dump(DumpFunction(F)),
155 ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
159 uintptr_t ActualSize;
160 uintptr_t ActualSizeResult;
162 std::vector<StartExceptionTableCall> startExceptionTableCalls;
163 virtual uint8_t* startExceptionTable(const Function* F,
164 uintptr_t &ActualSize) {
165 uintptr_t InitialActualSize = ActualSize;
166 uint8_t *Result = Base->startExceptionTable(F, ActualSize);
167 startExceptionTableCalls.push_back(
168 StartExceptionTableCall(Result, F, InitialActualSize, ActualSize));
171 struct EndExceptionTableCall {
172 EndExceptionTableCall(const Function *F, uint8_t *TableStart,
173 uint8_t *TableEnd, uint8_t* FrameRegister)
174 : F(F), F_dump(DumpFunction(F)),
175 TableStart(TableStart), TableEnd(TableEnd),
176 FrameRegister(FrameRegister) {}
181 uint8_t *FrameRegister;
183 std::vector<EndExceptionTableCall> endExceptionTableCalls;
184 virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
185 uint8_t *TableEnd, uint8_t* FrameRegister) {
186 endExceptionTableCalls.push_back(
187 EndExceptionTableCall(F, TableStart, TableEnd, FrameRegister));
188 return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
192 void LoadAssemblyInto(Module *M, const char *assembly) {
194 bool success = NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
196 raw_string_ostream os(errMsg);
198 ASSERT_TRUE(success) << os.str();
201 class JITTest : public testing::Test {
203 virtual void SetUp() {
204 M = new Module("<main>", Context);
205 MP = new ExistingModuleProvider(M);
206 RJMM = new RecordingJITMemoryManager;
208 TheJIT.reset(EngineBuilder(MP).setEngineKind(EngineKind::JIT)
209 .setJITMemoryManager(RJMM)
210 .setErrorStr(&Error).create());
211 ASSERT_TRUE(TheJIT.get() != NULL) << Error;
214 void LoadAssembly(const char *assembly) {
215 LoadAssemblyInto(M, assembly);
219 Module *M; // Owned by MP.
220 ModuleProvider *MP; // Owned by ExecutionEngine.
221 RecordingJITMemoryManager *RJMM;
222 OwningPtr<ExecutionEngine> TheJIT;
225 // Regression test for a bug. The JIT used to allocate globals inside the same
226 // memory block used for the function, and when the function code was freed,
227 // the global was left in the same place. This test allocates a function
228 // that uses and global, deallocates it, and then makes sure that the global
229 // stays alive after that.
230 TEST(JIT, GlobalInFunction) {
232 Module *M = new Module("<main>", context);
233 ExistingModuleProvider *MP = new ExistingModuleProvider(M);
235 JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
236 // Tell the memory manager to poison freed memory so that accessing freed
237 // memory is more easily tested.
238 MemMgr->setPoisonMemory(true);
240 OwningPtr<ExecutionEngine> JIT(EngineBuilder(MP)
241 .setEngineKind(EngineKind::JIT)
243 .setJITMemoryManager(MemMgr)
244 // The next line enables the fix:
245 .setAllocateGVsWithCode(false)
247 ASSERT_EQ(Error, "");
249 // Create a global variable.
250 const Type *GTy = Type::getInt32Ty(context);
251 GlobalVariable *G = new GlobalVariable(
254 false, // Not constant.
255 GlobalValue::InternalLinkage,
256 Constant::getNullValue(GTy),
259 // Make a function that points to a global.
260 Function *F1 = makeReturnGlobal("F1", G, M);
262 // Get the pointer to the native code to force it to JIT the function and
263 // allocate space for the global.
265 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F1));
267 // Since F1 was codegen'd, a pointer to G should be available.
268 int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G);
269 ASSERT_NE((int32_t*)NULL, GPtr);
272 // F1() should increment G.
276 // Make a second function identical to the first, referring to the same
278 Function *F2 = makeReturnGlobal("F2", G, M);
280 reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F2));
282 // F2() should increment G.
287 JIT->freeMachineCodeForFunction(F1);
289 // F2() should *still* increment G.
294 int PlusOne(int arg) {
298 TEST_F(JITTest, FarCallToKnownFunction) {
299 // x86-64 can only make direct calls to functions within 32 bits of
300 // the current PC. To call anything farther away, we have to load
301 // the address into a register and call through the register. The
302 // current JIT does this by allocating a stub for any far call.
303 // There was a bug in which the JIT tried to emit a direct call when
304 // the target was already in the JIT's global mappings and lazy
305 // compilation was disabled.
307 Function *KnownFunction = Function::Create(
308 TypeBuilder<int(int), false>::get(Context),
309 GlobalValue::ExternalLinkage, "known", M);
310 TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne);
312 // int test() { return known(7); }
313 Function *TestFunction = Function::Create(
314 TypeBuilder<int(), false>::get(Context),
315 GlobalValue::ExternalLinkage, "test", M);
316 BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction);
317 IRBuilder<> Builder(Entry);
318 Value *result = Builder.CreateCall(
320 ConstantInt::get(TypeBuilder<int, false>::get(Context), 7));
321 Builder.CreateRet(result);
323 TheJIT->DisableLazyCompilation(true);
324 int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>(
325 (intptr_t)TheJIT->getPointerToFunction(TestFunction));
326 // This used to crash in trying to call PlusOne().
327 EXPECT_EQ(8, TestFunctionPtr());
330 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__)
331 // Test a function C which calls A and B which call each other.
332 TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
333 TheJIT->DisableLazyCompilation(true);
335 const FunctionType *Func1Ty =
336 cast<FunctionType>(TypeBuilder<void(void), false>::get(Context));
337 std::vector<const Type*> arg_types;
338 arg_types.push_back(Type::getInt1Ty(Context));
339 const FunctionType *FuncTy = FunctionType::get(
340 Type::getVoidTy(Context), arg_types, false);
341 Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage,
343 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
345 Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage,
347 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
348 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
349 BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2);
350 BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2);
351 BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3);
352 BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3);
353 BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3);
355 // Make Func1 call Func2(0) and Func3(0).
356 IRBuilder<> Builder(Block1);
357 Builder.CreateCall(Func2, ConstantInt::getTrue(Context));
358 Builder.CreateCall(Func3, ConstantInt::getTrue(Context));
359 Builder.CreateRetVoid();
361 // void Func2(bool b) { if (b) { Func3(false); return; } return; }
362 Builder.SetInsertPoint(Block2);
363 Builder.CreateCondBr(Func2->arg_begin(), True2, False2);
364 Builder.SetInsertPoint(True2);
365 Builder.CreateCall(Func3, ConstantInt::getFalse(Context));
366 Builder.CreateRetVoid();
367 Builder.SetInsertPoint(False2);
368 Builder.CreateRetVoid();
370 // void Func3(bool b) { if (b) { Func2(false); return; } return; }
371 Builder.SetInsertPoint(Block3);
372 Builder.CreateCondBr(Func3->arg_begin(), True3, False3);
373 Builder.SetInsertPoint(True3);
374 Builder.CreateCall(Func2, ConstantInt::getFalse(Context));
375 Builder.CreateRetVoid();
376 Builder.SetInsertPoint(False3);
377 Builder.CreateRetVoid();
379 // Compile the function to native code
381 reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1));
386 // Regression test for PR5162. This used to trigger an AssertingVH inside the
387 // JIT's Function to stub mapping.
388 TEST_F(JITTest, NonLazyLeaksNoStubs) {
389 TheJIT->DisableLazyCompilation(true);
391 // Create two functions with a single basic block each.
392 const FunctionType *FuncTy =
393 cast<FunctionType>(TypeBuilder<int(), false>::get(Context));
394 Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage,
396 Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
398 BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
399 BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
401 // The first function calls the second and returns the result
402 IRBuilder<> Builder(Block1);
403 Value *Result = Builder.CreateCall(Func2);
404 Builder.CreateRet(Result);
406 // The second function just returns a constant
407 Builder.SetInsertPoint(Block2);
408 Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42));
410 // Compile the function to native code
411 (void)TheJIT->getPointerToFunction(Func1);
413 // Free the JIT state for the functions
414 TheJIT->freeMachineCodeForFunction(Func1);
415 TheJIT->freeMachineCodeForFunction(Func2);
417 // Delete the first function (and show that is has no users)
418 EXPECT_EQ(Func1->getNumUses(), 0u);
419 Func1->eraseFromParent();
421 // Delete the second function (and show that it has no users - it had one,
422 // func1 but that's gone now)
423 EXPECT_EQ(Func2->getNumUses(), 0u);
424 Func2->eraseFromParent();
428 TEST_F(JITTest, ModuleDeletion) {
429 TheJIT->DisableLazyCompilation(false);
430 LoadAssembly("define void @main() { "
431 " call i32 @computeVal() "
435 "define internal i32 @computeVal() { "
438 Function *func = M->getFunction("main");
439 TheJIT->getPointerToFunction(func);
440 TheJIT->deleteModuleProvider(MP);
442 SmallPtrSet<const void*, 2> FunctionsDeallocated;
443 for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size();
445 FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body);
447 for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) {
448 EXPECT_TRUE(FunctionsDeallocated.count(
449 RJMM->startFunctionBodyCalls[i].Result))
450 << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump;
452 EXPECT_EQ(RJMM->startFunctionBodyCalls.size(),
453 RJMM->deallocateFunctionBodyCalls.size());
455 SmallPtrSet<const void*, 2> ExceptionTablesDeallocated;
456 unsigned NumTablesDeallocated = 0;
457 for (unsigned i = 0, e = RJMM->deallocateExceptionTableCalls.size();
459 ExceptionTablesDeallocated.insert(
460 RJMM->deallocateExceptionTableCalls[i].ET);
461 if (RJMM->deallocateExceptionTableCalls[i].ET != NULL) {
462 // If JITEmitDebugInfo is off, we'll "deallocate" NULL, which doesn't
463 // appear in startExceptionTableCalls.
464 NumTablesDeallocated++;
467 for (unsigned i = 0, e = RJMM->startExceptionTableCalls.size(); i != e; ++i) {
468 EXPECT_TRUE(ExceptionTablesDeallocated.count(
469 RJMM->startExceptionTableCalls[i].Result))
470 << "Function's exception table leaked: \n"
471 << RJMM->startExceptionTableCalls[i].F_dump;
473 EXPECT_EQ(RJMM->startExceptionTableCalls.size(),
474 NumTablesDeallocated);
477 #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__)
478 typedef int (*FooPtr) ();
480 TEST_F(JITTest, NoStubs) {
481 LoadAssembly("define void @bar() {"
486 "define i32 @foo() {"
492 "define i32 @main() {"
494 "%0 = call i32 @foo()"
498 Function *foo = M->getFunction("foo");
499 uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo));
500 FooPtr ptr = (FooPtr)(tmp);
504 // We should now allocate no more stubs, we have the code to foo
505 // and the existing stub for bar.
506 int stubsBefore = RJMM->stubsAllocated;
507 Function *func = M->getFunction("main");
508 TheJIT->getPointerToFunction(func);
510 Function *bar = M->getFunction("bar");
511 TheJIT->getPointerToFunction(bar);
513 ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
517 #if _POSIX_MAPPED_FILES > 0 && (defined (__x86_64__) || defined (_M_AMD64) || defined (_M_X64))
518 class FarCallMemMgr : public RecordingJITMemoryManager {
522 uint8_t *NextFunction;
526 : MmapSize(16ULL << 30) { // 16GB
527 MmapRegion = mmap(NULL, MmapSize, PROT_READ | PROT_WRITE | PROT_EXEC,
528 MAP_PRIVATE | MAP_ANON, -1, 0);
529 if (MmapRegion == MAP_FAILED) {
530 ADD_FAILURE() << "mmap failed: " << strerror(errno);
532 // Set up the 16GB mapped region in several chunks:
533 // Stubs / ~5GB empty space / Function 1 / ~5GB empty space / Function 2
534 // This way no two entities can use a 32-bit relative call to reach each other.
535 NextStub = static_cast<uint8_t*>(MmapRegion);
536 NextFunction = NextStub + (5ULL << 30);
538 // Next, poison some of the memory so a wild call will eventually crash,
539 // even if memory was initialized by the OS to 0. We can't poison all of
540 // the memory because we want to be able to run on systems with less than
541 // 16GB of physical ram.
542 int TrapInstr = 0xCC; // INT 3
543 memset(NextStub, TrapInstr, 1<<10);
544 for (size_t Offset = 1<<30; Offset < MmapSize; Offset += 1<<30) {
545 // Fill the 2KB around each GB boundary with trap instructions. This
546 // should ensure that we can't run into emitted functions without hitting
548 memset(NextStub + Offset - (1<<10), TrapInstr, 2<<10);
553 EXPECT_EQ(0, munmap(MmapRegion, MmapSize));
556 virtual void setMemoryWritable() {}
557 virtual void setMemoryExecutable() {}
558 virtual uint8_t *startFunctionBody(const Function *F,
559 uintptr_t &ActualSize) {
560 ActualSize = 1 << 30;
561 uint8_t *Result = NextFunction;
562 NextFunction += 5ULL << 30;
565 virtual void endFunctionBody(const Function*, uint8_t*, uint8_t*) {}
566 virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
567 unsigned Alignment) {
568 NextStub = reinterpret_cast<uint8_t*>(
569 uintptr_t(NextStub + Alignment - 1) &~ uintptr_t(Alignment - 1));
570 uint8_t *Result = NextStub;
571 NextStub += StubSize;
576 class FarTargetTest : public ::testing::TestWithParam<CodeGenOpt::Level> {
578 FarTargetTest() : SavedCodeModel(TargetMachine::getCodeModel()) {}
580 TargetMachine::setCodeModel(SavedCodeModel);
583 const CodeModel::Model SavedCodeModel;
585 INSTANTIATE_TEST_CASE_P(CodeGenOpt,
587 ::testing::Values(CodeGenOpt::None,
588 CodeGenOpt::Default));
590 TEST_P(FarTargetTest, CallToFarTarget) {
591 // x86-64 can only make direct calls to functions within 32 bits of
592 // the current PC. To call anything farther away, we have to load
593 // the address into a register and call through the register. The
594 // old JIT did this by allocating a stub for any far call. However,
595 // that stub needed to be within 32 bits of the callsite. Here we
596 // test that the JIT correctly deals with stubs and calls more than
597 // 32 bits away from the callsite.
599 // Make sure the code generator is assuming code might be far away.
600 //TargetMachine::setCodeModel(CodeModel::Large);
603 Module *M = new Module("<main>", Context);
604 ExistingModuleProvider *MP = new ExistingModuleProvider(M);
606 JITMemoryManager *MemMgr = new FarCallMemMgr();
608 OwningPtr<ExecutionEngine> JIT(EngineBuilder(MP)
609 .setEngineKind(EngineKind::JIT)
611 .setJITMemoryManager(MemMgr)
612 .setOptLevel(GetParam())
614 ASSERT_EQ(Error, "");
615 TargetMachine::setCodeModel(CodeModel::Large);
618 "define i32 @test() { "
622 "define i32 @test_far() { "
623 " %result = call i32 @test() "
626 // First, lay out a function early in memory.
627 Function *TestFunction = M->getFunction("test");
628 int32_t (*TestFunctionPtr)() = reinterpret_cast<int32_t(*)()>(
629 (intptr_t)JIT->getPointerToFunction(TestFunction));
630 ASSERT_EQ(7, TestFunctionPtr());
632 // We now lay out the far-away function. This should land >4GB away from test().
633 Function *FarFunction = M->getFunction("test_far");
634 int32_t (*FarFunctionPtr)() = reinterpret_cast<int32_t(*)()>(
635 (intptr_t)JIT->getPointerToFunction(FarFunction));
637 EXPECT_LT(1LL << 32, llabs(intptr_t(FarFunctionPtr) - intptr_t(TestFunctionPtr)))
638 << "Functions must be >32 bits apart or the test is meaningless.";
640 // This used to result in a segfault in FarFunction, when its call instruction
641 // jumped to the wrong address.
642 EXPECT_EQ(7, FarFunctionPtr());
644 #endif // Platform has far-call problem.
646 // This code is copied from JITEventListenerTest, but it only runs once for all
647 // the tests in this directory. Everything seems fine, but that's strange
649 class JITEnvironment : public testing::Environment {
650 virtual void SetUp() {
651 // Required to create a JIT.
652 InitializeNativeTarget();
655 testing::Environment* const jit_env =
656 testing::AddGlobalTestEnvironment(new JITEnvironment);