CACAO
recompiler.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/recompiler.cpp - recompilation system
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <assert.h>
29 
30 #include "threads/condition.hpp"
31 #include "threads/mutex.hpp"
32 #include "threads/thread.hpp"
33 
34 #include "vm/classcache.hpp"
35 #include "vm/exceptions.hpp"
36 #include "vm/options.hpp"
37 
38 #include "vm/jit/builtin.hpp"
39 #include "vm/jit/code.hpp"
40 #include "vm/jit/jit.hpp"
41 
43 
44 
45 /**
46  * Stop the worker thread.
47  */
49 {
50  // Set the running flag to false.
51  _run = false;
52 
53  // Now signal the worker thread.
54  _cond.signal();
55 
56  // TODO We should wait here until the thread exits.
57 }
58 
59 
60 /* recompile_replace_vftbl *****************************************************
61 
62  XXX
63 
64 *******************************************************************************/
65 
67 {
68  codeinfo *code;
69  codeinfo *pcode;
70  u4 slot;
73  classinfo *c;
74  vftbl_t *vftbl;
75  s4 i;
76 
77  /* get current and previous codeinfo structure */
78 
79  code = m->code;
80  pcode = code->prev;
81 
82  assert(pcode);
83 
84  /* iterate over all classes */
85 
86  for (slot = 0; slot < hashtable_classcache.size; slot++) {
88 
89  for (; nmen; nmen = nmen->hashlink) {
90  /* iterate over all class entries */
91 
92  for (clsen = nmen->classes; clsen; clsen = clsen->next) {
93  c = clsen->classobj;
94 
95  if (c == NULL)
96  continue;
97 
98  /* Search for entrypoint of the previous codeinfo in
99  the vftbl and replace it with the current one. */
100 
101  vftbl = c->vftbl;
102 
103  /* Is the class linked? Means, is the vftbl finished? */
104 
105  if (!(c->state & CLASS_LINKED))
106  continue;
107 
108  /* Does the class have a vftbl? Some internal classes
109  (e.g. $NEW$) are linked, but do not have a
110  vftbl. */
111 
112  if (vftbl == NULL)
113  continue;
114 
115  for (i = 0; i < vftbl->vftbllength; i++) {
116  if (vftbl->table[i] == pcode->entrypoint) {
117 #if !defined(NDEBUG)
118  printf("replacing vftbl in: ");
119  class_println(c);
120 #endif
121  vftbl->table[i] = code->entrypoint;
122  }
123  }
124  }
125  }
126  }
127 }
128 
129 
130 /**
131  * The actual recompilation thread.
132  */
134 {
135  // FIXME This just works for one recompiler.
137 
138  while (r._run == true) {
139  // Enter the recompile mutex, so we can call wait.
140  r._mutex.lock();
141 
142  // Wait forever on that condition until we are signaled.
143  r._cond.wait(r._mutex);
144 
145  // Leave the mutex.
146  r._mutex.unlock();
147 
148  // FIXME Move this into the for loop.
149  if (r._run == false)
150  break;
151 
152  // Get the next method form the queue and recompile it.
153  while (r._methods.empty() == false) {
154  methodinfo* m = r._methods.front();
155 
156  // Recompile this method.
157  if (jit_recompile(m) != NULL) {
158  // Replace in vftbl's.
160  }
161  else {
162  // XXX What is the right-thing(tm) to do here?
164  }
165 
166  // Remove the method from the queue.
167  r._methods.pop();
168  }
169  }
170 }
171 
172 
173 /**
174  * Start the recompilation thread.
175  *
176  * @return true on success, false otherwise.
177  */
179 {
180  Utf8String name = Utf8String::from_utf8("Recompiler");
181 
183  return false;
184 
185  return true;
186 }
187 
188 
189 /**
190  * Add a method to the recompilation queue and signal the
191  * recompilation thread that there is some work to do.
192  *
193  * @param m Method to recompile.
194  */
196 {
197  // Add the method to the queue.
198  _methods.push(m);
199 
200  // Enter the recompile mutex, so we can call notify.
201  _mutex.lock();
202 
203  // Signal the recompiler thread.
204  _cond.signal();
205 
206  // Leave the mutex.
207  _mutex.unlock();
208 }
209 
210 
211 
212 // Legacy C interface.
214 
215 /*
216  * These are local overrides for various environment variables in Emacs.
217  * Please do not remove this and leave it at the end of the file, where
218  * Emacs will automagically detect them.
219  * ---------------------------------------------------------------------
220  * Local variables:
221  * mode: c++
222  * indent-tabs-mode: t
223  * c-basic-offset: 4
224  * tab-width: 4
225  * End:
226  * vim:noexpandtab:sw=4:ts=4:
227  */
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
void signal()
Restarts one of the threads that are waiting on this condition variable.
classcache_class_entry * next
Definition: classcache.hpp:103
s4 state
Definition: class.hpp:115
Recompiler & get_recompiler()
Definition: vm.hpp:116
bool threads_thread_start_internal(Utf8String name, functionptr f)
Definition: thread.cpp:402
std::queue< methodinfo * > _methods
Definition: recompiler.hpp:43
hashtable hashtable_classcache
Definition: classcache.cpp:223
void queue_method(methodinfo *m)
Queue a method for recompilation.
Definition: recompiler.cpp:195
Mutex _mutex
Definition: recompiler.hpp:41
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
Condition _cond
Definition: recompiler.hpp:42
void(* functionptr)(void)
Definition: global.hpp:39
classcache_class_entry * classes
Definition: classcache.hpp:95
void exceptions_print_current_exception(void)
s4 vftbllength
Definition: vftbl.hpp:102
Thread for JIT recompilations.
Definition: recompiler.hpp:39
void class_println(classinfo *c)
Definition: class.cpp:2276
u1 * jit_recompile(methodinfo *m)
Definition: jit.cpp:453
void ** ptr
Definition: hashtable.hpp:781
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
MIIterator i
int32_t s4
Definition: types.hpp:45
codeinfo * code
Definition: method.hpp:103
~Recompiler()
Stop the worker thread.
Definition: recompiler.cpp:48
codeinfo * prev
Definition: code.hpp:76
uint32_t u4
Definition: types.hpp:46
static void thread()
Worker thread.
Definition: recompiler.cpp:133
vftbl_t * vftbl
Definition: class.hpp:121
bool _run
Flag to stop worker thread.
Definition: recompiler.hpp:44
Definition: classcache.hpp:98
void unlock()
Unlocks the given mutex object and checks for errors.
Definition: mutex-none.hpp:36
methodptr table[1]
Definition: vftbl.hpp:116
classcache_name_entry * hashlink
Definition: classcache.hpp:94
void Recompiler_queue_method(methodinfo *m)
Definition: recompiler.cpp:213
classinfo * classobj
Definition: classcache.hpp:100
Definition: classcache.hpp:91
#define printf(...)
Definition: ssa2.cpp:40
void wait(Mutex *mutex)
Waits for the condition variable.
void lock()
Locks the given mutex object and checks for errors.
Definition: mutex-none.hpp:35
static VM * get_current()
Definition: vm.hpp:99
u1 * entrypoint
Definition: code.hpp:84
bool start()
Start the worker thread.
Definition: recompiler.cpp:178
static void recompile_replace_vftbl(methodinfo *m)
Definition: recompiler.cpp:66