--- Log opened Wed Jun 03 00:00:57 2009 00:15 < tgrabiec> that's weird. making lib/ compile was as simple as replacing StringBuffer with CPStringBuffer, but now _some_ regression tests segfault. after hours of investigation i discovered that it's because _some_ inner classes cannot be resolved (resolveClass returns NULL), for example jvm/TrampolineBackpatchingTest$B. This is weird... 00:16 <@ahuillet> why can't they be resolved ?! 00:16 < tgrabiec> ahuillet, dunno 00:16 < tgrabiec> i'll digg deeper 00:17 < tgrabiec> but some classes can be resolved, which is weird 00:33 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has quit [Remote closed the connection] 00:45 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has joined #jato 02:45 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has quit [Remote closed the connection] 08:28 <@penberg> vegard: I don't see the #include problem 08:28 <@penberg> vegard: because we have specific subdirectories ("namespaces") for the headers 08:28 <@penberg> vegard: jit/compiler.h, etc. 08:28 <@penberg> vegard: so I don't see why they would collide. 09:33 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has joined #jato 09:34 <@penberg> tgrabiec: hey 09:34 < tgrabiec> hey. i can see you've applied the patches ? 09:34 <@penberg> yes! 09:34 <@penberg> tgrabiec: I wonder how the current exception tests are going work with safepoints. 09:34 <@penberg> and if we can somehow generalize the two 09:35 < tgrabiec> penberg: i think that safepoints won't need a per-thread guard page will they ? 09:36 < tgrabiec> or per-thread pointer to guard page 09:36 < tgrabiec> penberg: i think the safepoint test would be as simple as: test (0x612365123),%eax 09:36 <@penberg> tgrabiec: yes, correct. 09:37 <@penberg> and I suspect we need to add safepoint tests in different places anyway 09:37 <@penberg> like backwards loops 09:37 <@penberg> and method _entry_ 09:37 <@penberg> i mean 09:37 <@penberg> before a call insn 09:38 <@penberg> tgrabiec: and btw, you added exception test everywhere now 09:38 <@penberg> tgrabiec: which is correct 09:38 <@penberg> tgrabiec: but we can probably optimize things 09:38 <@penberg> tgrabiec: that never throw exception. 09:39 <@penberg> although 09:39 < tgrabiec> penberg: sure. but i need to place "signal_exception" to plenty method first. for example every function that allocates something might throw OutOfMemoryError 09:39 <@penberg> most of them can. 09:39 <@penberg> true. 09:39 <@penberg> yeah, I just realized that OOM can trigger almost anywhere. 09:39 <@penberg> well 09:39 <@penberg> except that 09:40 <@penberg> malloc() probably never fails in practice. 09:40 <@penberg> in user-space 09:40 <@penberg> so OutOfMemoryError is mostly for the garbage collector 09:40 <@penberg> when we reach maximum heap size 09:41 <@penberg> tgrabiec: so 09:41 <@penberg> tgrabiec: how come we need mov + test? 09:43 <@penberg> tgrabiec: test doesn't support gs segment override prefix? 09:47 < tgrabiec> penberg: hmm, we first need to load the pointer value (that's one memory access) and we need to access the memory pointed by that pointer. AFAIK there is no double-indirect memory addressing ? 09:49 < tgrabiec> penberg: that's the reason i was thinking about per-thread guard pages, so that the test won't need to allocate register and will require only one instruction 09:52 < tgrabiec> and I would use mprotect to hide when exception occures. It's slower when exception occures but quite faster in normal flow. 09:55 <@penberg> tgrabiec: yeah, I think we should do per-thread guard pages then. 09:55 <@penberg> tgrabiec: the problem with the current approach is that it generates register pressure 09:55 <@penberg> tgrabiec: so we end up with spill + mov + test + reload 09:56 < tgrabiec> penberg: right. so i think, that we should allocate guard page in some thread-initialization and store the pointer to it in execution environemnt. what do you think ? 09:57 <@penberg> tgrabiec: something like that, yes. 10:51 -!- ahuillet_ [n=user@dra38-3-82-236-188-250.fbx.proxad.net] has joined #jato 11:54 < ahuillet_> tgrabiec : how's CP .98 going ? can I help ? 11:55 < tgrabiec> ahuillet_: i'm stuck with the "unresolved class" problem. i'll prepare a patch for what i've done and you'll see 11:56 < ahuillet_> so jato's gonna break when everybody updates CP ? 11:57 < tgrabiec> ahuillet_, yes it will, but i don't know exactly why 11:58 < tgrabiec> perhaps it's jamvm classes' fault 11:58 < tgrabiec> or some sneaky memory corruption 11:59 < vegard> in my tree, lib/ is completely gone :-P 12:00 < ahuillet_> sounds good ! 12:04 <@penberg> we should merge that then ;) 12:08 < tgrabiec> ahuillet, here's the patch: http://pastebin.com/m6febfd07 it makes jato compile, but _some_ regression tests segfault because: "new" byteocde wants to allocate some class -> the class fails to resolve -> converter returns -EINV -> no objcode -> add_cu_mapping segfaults (to be fixed soon) 12:09 < tgrabiec> generally it's always inner class that cannot be resolved, no idea why 12:58 < tgrabiec> i'm giving up on this one since vegard will replace jamvm anyway 13:22 < ahuillet_> sounds good 13:22 < ahuillet_> vegard : merge your code ;) 13:43 < vegard> yes, we're working on it! 13:44 < vegard> there are a few things to sort out first, though 13:51 -!- ahuillet_ [n=user@dra38-3-82-236-188-250.fbx.proxad.net] has quit ["Leaving"] 16:31 < tgrabiec> penberg: the patches were inspired by my experience with class resolvation failure. In this case method compilation fails, but we should throw exception that has been set by jamvm (or jatovm) 17:11 <@penberg> tgrabiec: ok 17:12 <@penberg> tgrabiec: so what about per-thread guard pages to clean up the generated machine code? 17:13 <@penberg> tgrabiec: so hmm 17:13 <@penberg> tgrabiec: so we can throw exceptions from the trampoline now? 17:13 <@penberg> tgrabiec: because jamvm can throw exceptions? 17:14 <@penberg> tgrabiec, vegard: is this still something we want to do when we switch to cafebabe? 17:14 <@penberg> tgrabiec: I know that we need to throw AbstractMethodError etc from the _parsing_ code at some point for failure cases. 17:21 < vegard> is what something we want to do? 17:32 < tgrabiec> penberg: i'm pretty sure we will want to throw exceptions when we get rid of jamvm too, for example we'll want to throw NoClassDefFoundError anyway 17:33 < tgrabiec> penberg: many bad things can happen while compiling method, and we should throw java.lang.Error when something goes wrong rather than killing a thread or whole VM 17:37 < tgrabiec> yes, we can throw exceptions from trampoline now. 17:37 < tgrabiec> About per-thread guard pages - i'm willing to do it, but it's not that simple (at least to me). Becasue if we want to benefit from this, we should somehow make all per-thread guard pages have the same memory address 17:38 < vegard> yes, we need to be able to throw exceptions 17:38 < tgrabiec> we can't declare them statically with __thread because we can't make assumptions about the size of memroy page. 17:40 < vegard> pthread keys? 17:40 < vegard> (dynamically) 17:40 < tgrabiec> vegard: yes, it will work, but it's not faster than the current solution 17:40 < vegard> wait -- that defeats the purpose, doesn't it? 17:40 < tgrabiec> vegard: the point is to perform a test with a single instruction 17:41 < vegard> oh. test for what? 17:43 < tgrabiec> vegard: from JIT-compiled method we poll a memory page to check whether exception occured. We hold the pointer to that page in void *exception_guard. When exception is signalled from jato functions, the (thread-specific) exception_guard is set to point to a page "hidden" with mprotect() 17:43 < tgrabiec> and sigsegv takes care of throwing 17:43 < vegard> hm. 17:44 < tgrabiec> currently we need at least 2-instructions for this and a register allocated so possibly spill/reload instructions are inserted around 17:44 < vegard> isn't it possible to change the return address from the sigsegv handler? 17:44 < vegard> so that you don't need to poll at all? 17:45 < tgrabiec> vegard: the sigsegv handler is triggered by polling code 17:46 < vegard> ah 17:46 < vegard> sorry :) 17:46 < tgrabiec> we need to poll after jato function returns 17:46 < vegard> jato function = C code, right? 17:48 < tgrabiec> vegard: yes 17:48 < vegard> so then, couldn't throw_exception() or whatever we call it, instead of signalling an exception by writing to this special per-thread page, just modify its return address so that we jump directly to the exception handler? 17:49 <@penberg> tgrabiec: what if you allocate an array of PAGE_SIZE ? 17:49 <@penberg> tgrabiec: with __thread? 17:51 < tgrabiec> penberg: but PAGE_SIZE is some constant defined in headres, isn't it ? If so, than jato wouldn't be binary portable 17:52 < vegard> it's not constant 17:53 <@penberg> we can always define it at compile time. 17:53 <@penberg> well 17:53 <@penberg> actually nto hmm 17:53 <@penberg> oh well 17:53 <@penberg> I'll just go home now ;) 17:53 < vegard> does it have to actually be exactly a page? 17:53 < tgrabiec> vegard: if it's not constant, then i can't write: __thread char guard_page[PAGE_SIZE]; 17:55 < tgrabiec> vegard: that is a damn good question 17:55 < tgrabiec> does mprotect work with len < PAGE_SIZE ? 17:56 < tgrabiec> but even if, we have to align guard_page on a page boundary for sure 18:03 < vegard> by the way 18:04 < vegard> what are the instructions needed now? 18:04 < tgrabiec> vegard: for exception polling ? 18:04 < vegard> yes 18:05 < tgrabiec> mov gs:(0xAAAAA), %reg 18:05 < tgrabiec> test (%reg), %reg 18:05 < tgrabiec> where 0xAAAAAA is displacement of exception_guard pointer relative to the start of TLS (gs:0x0) 18:07 < tgrabiec> so, what would be perfect is that we could allocate at run-time a memory region with posix_memalign() and then somehow make that page not shared between threads. is it possible in linux ? 18:11 < vegard> could you do something like dec gs:(0xaaaaa) ? 18:11 < vegard> that would set zero flag if the number goes to zero 18:11 < vegard> and you could skip the "test" 18:11 < vegard> ? 18:12 < tgrabiec> vegard: the point is that we need to trigger SIGSEGV. we don't want any branches 18:13 < vegard> aha, so the "test" instruction above is the one triggering sigsegv? 18:13 < tgrabiec> yes 18:14 < tgrabiec> when no exception is set, the exception_guard points to good memory (it self), when exeption is set, it points to bad page 18:15 < vegard> hm, maybe I am stupid 18:16 < vegard> I think my question from above still applies, though. instead of switching this good/bad pointer, why not modify the return address so that exception handler code gets called at once? 18:17 < vegard> instead of: 1. switching the pointer to point at the bad page, 2. returning, 3. accessing the page, 4. getting segmentation fault and signal from kernel 18:25 < tgrabiec> vegard: hmm 18:27 < tgrabiec> it could work 18:29 < tgrabiec> vegard: no it can't 18:31 < tgrabiec> vegard: the problem is that yes, we could change the return address, but we can't push the exception object on stack 18:32 < tgrabiec> hmm 18:34 < tgrabiec> we could change the convetion, so that exception object is obtained from execution environment instead from stack 18:34 < tgrabiec> need to think about it 18:36 < vegard> well 18:36 < vegard> a temporary solution could be to use a trampoline, no? 18:36 < vegard> return to trampoline, trampoline pushes exception object and jumps to the right place 18:37 < vegard> I don't know :) 18:38 < tgrabiec> vegard: it's not only about trampoline, regular code calls things like lockObject or allocObject() 18:39 < tgrabiec> i mean JIT methods call that function directly. of course we will have to write stubs, but that's not the problem 18:39 < tgrabiec> i'm actually getting convinced to the idea 18:39 < tgrabiec> (by stubs i meant proxies) 18:41 < tgrabiec> we need proxies, because we can perform return address substitution in functions that were directly called from JIT methods because of register consistency 18:42 < tgrabiec> **in function that were directly called _only_ 18:47 < tgrabiec> penberg: i think you can merge patches 1/6 to 4/6 anyway, because they're not related to throwing mechanism directly 19:53 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has quit ["Leaving"] 20:08 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has joined #jato 22:12 -!- tgrabiec [n=tomekg@rev-189-107.ramtel.pl] has quit ["Leaving"] --- Log closed Thu Jun 04 00:00:03 2009