1// PR rtl-optimization/56999 2// { dg-do run } 3// { dg-options "-O2" } 4// { dg-additional-options "-fpic" { target fpic } } 5// { dg-additional-options "-march=i686 -mtune=atom" { target ia32 } } 6// { dg-require-visibility "" } 7 8extern "C" void abort (void); 9extern "C" void exit (int); 10volatile bool do_exit = true; 11struct JSScript; 12struct JITScript { int i; }; 13#pragma GCC visibility push(hidden) 14typedef struct JSCompartment JSCompartment; 15typedef struct JSContext JSContext; 16namespace js 17{ 18 struct ContextFriendFields 19 { 20 JSCompartment *compartment; 21 }; 22 struct TempAllocPolicy 23 { 24 }; 25 template <class T> 26 struct Vector 27 { 28 T *mBegin; 29 T *begin () { return mBegin; } 30 T & operator[] (unsigned i) { return begin ()[i]; } 31 template <class U> 32 __attribute__((noinline, noclone)) 33 bool append (U) { asm volatile ("" : : : "memory"); if (do_exit) abort (); return false; } 34 }; 35 namespace types 36 { 37 struct TypeCompartment; 38 } 39 namespace mjit 40 { 41 } 42 namespace ion 43 { 44 struct IonScript; 45 } 46 namespace types 47 { 48 struct CompilerOutput 49 { 50 enum Kind { MethodJIT, ParallelIon }; 51 JSScript *script; 52 unsigned kindInt : 2; 53 bool constructing : 1; 54 bool barriers : 1; 55 bool pendingRecompilation : 1; 56 Kind kind () const { return static_cast <Kind> (kindInt); } 57 bool isValid () const; 58 }; 59 struct RecompileInfo 60 { 61 unsigned outputIndex; 62 CompilerOutput *compilerOutput (TypeCompartment & types) const; 63 CompilerOutput *compilerOutput (JSContext *cx) const; 64 }; 65 struct TypeCompartment 66 { 67 Vector <CompilerOutput> *constrainedOutputs; 68 Vector <RecompileInfo> *pendingRecompiles; 69 void addPendingRecompile (JSContext *cx, const RecompileInfo & info); 70 }; 71 } 72} 73struct JSScript 74{ 75 struct JITScriptHandle 76 { 77 static volatile JITScript *UNJITTABLE __attribute__((visibility ("default"))); 78 JITScript *value; 79 bool isValid () { return value != UNJITTABLE; } 80 JITScript *getValid () { return value; } 81 }; 82 struct JITScriptSet 83 { 84 JITScriptHandle jitHandleNormal, jitHandleNormalBarriered; 85 JITScriptHandle jitHandleCtor, jitHandleCtorBarriered; 86 JITScriptHandle jitNull1, jitNull2; 87 }; 88 JITScriptSet *mJITInfo; 89 void *ion; 90 JITScriptHandle *jitHandle (bool constructing, bool barriers) 91 { 92 return constructing ? (barriers ? &mJITInfo->jitHandleCtorBarriered 93 : &mJITInfo->jitHandleCtor) 94 : (barriers ? &mJITInfo->jitHandleNormalBarriered 95 : &mJITInfo->jitHandleNormal); 96 } 97 JITScript *getJIT (bool constructing, bool barriers) 98 { 99 JITScriptHandle *jith = jitHandle (constructing, barriers); 100 return jith->isValid () ? jith->getValid () : __null; 101 } 102}; 103struct JSContext : js::ContextFriendFields 104{ 105}; 106namespace js 107{ 108 __attribute__((noinline, noclone)) 109 void CancelOffThreadIonCompile (JSCompartment *, JSScript *) 110 { 111 if (do_exit) 112 exit (0); 113 } 114} 115struct JSCompartment 116{ 117 js::types::TypeCompartment types; 118}; 119namespace js 120{ 121 namespace types 122 { 123 inline bool CompilerOutput::isValid () const 124 { 125 if (!script) 126 return false; 127 switch (kind ()) 128 { 129 case MethodJIT: 130 { 131 JITScript *jit = script->getJIT (constructing, barriers); 132 if (!jit) 133 return false; 134 } 135 case ParallelIon: 136 return true; 137 } 138 return false; 139 } 140 inline CompilerOutput *RecompileInfo::compilerOutput (TypeCompartment & types) const 141 { 142 return &(*types.constrainedOutputs)[outputIndex]; 143 } 144 inline CompilerOutput *RecompileInfo::compilerOutput (JSContext *cx) const 145 { 146 return compilerOutput (cx->compartment->types); 147 } 148 } 149} 150using namespace js::types; 151__attribute__((noinline, noclone)) void 152TypeCompartment::addPendingRecompile (JSContext *cx, const RecompileInfo & info) 153{ 154 CompilerOutput *co = info.compilerOutput (cx); 155 if (co->pendingRecompilation) 156 if (co->isValid ()) 157 CancelOffThreadIonCompile (cx->compartment, co->script); 158 if (co->isValid ()) 159 pendingRecompiles->append (info); 160} 161volatile JITScript *JSScript::JITScriptHandle::UNJITTABLE; 162#pragma GCC visibility pop 163int 164main () 165{ 166 JSContext cx; 167 JSCompartment com; 168 RecompileInfo info; 169 cx.compartment = &com; 170 info.outputIndex = 0; 171 js::Vector<CompilerOutput> v; 172 JITScript js; 173 JSScript::JITScriptSet set; 174 __builtin_memset (&set, 0, sizeof set); 175 set.jitHandleCtor.value = &js; 176 JSScript s; 177 s.mJITInfo = &set; 178 CompilerOutput co; 179 co.kindInt = 0; 180 co.constructing = true; 181 co.barriers = false; 182 co.pendingRecompilation = true; 183 co.script = &s; 184 v.mBegin = &co; 185 com.types.constrainedOutputs = &v; 186 com.types.pendingRecompiles = __null; 187 com.types.addPendingRecompile (&cx, info); 188 abort (); 189} 190