2 * Runtime data structures for loaded program.
8 #include "specialsignatures.h"
9 #include "specialclasses.h"
14 #include "configure.h"
15 #include "interpreter.h"
16 #include "exceptions.h"
18 #include "platform_hooks.h"
21 #define get_stack_object(MREC_) ((Object *) get_ref_at ((MREC_)->numParameters - 1))
26 void *installedBinary;
30 // (Gotta be careful with these; a lot of stuff
31 // is not reentrant because of globals like these).
33 static ClassRecord *tempClassRecord;
34 static MethodRecord *tempMethodRecord;
38 byte get_class_index (Object *obj)
43 if (f & IS_ARRAY_MASK)
44 return JAVA_LANG_OBJECT;
45 return (f & CLASS_MASK);
49 * @return Method record or null.
51 MethodRecord *find_method (ClassRecord *classRecord, TWOBYTES methodSignature)
53 tempByte = classRecord->numMethods;
56 tempMethodRecord = get_method_record (classRecord, tempByte);
57 if (tempMethodRecord->signatureId == methodSignature)
58 return tempMethodRecord;
63 boolean dispatch_static_initializer (ClassRecord *aRec, byte *retAddr)
65 if (is_initialized (aRec))
67 set_initialized (aRec);
68 if (!has_clinit (aRec))
71 printf ("dispatch_static_initializer: has clinit: %d, %d\n",
72 (int) aRec, (int) retAddr);
74 dispatch_special (find_method (aRec, _6clinit_7_4_5V), retAddr);
78 void dispatch_virtual (Object *ref, TWOBYTES signature, byte *retAddr)
80 MethodRecord *auxMethodRecord;
84 printf("dispatch_virtual %d\n", signature);
88 throw_exception (nullPointerException);
92 auxByte = get_class_index(ref);
94 tempClassRecord = get_class_record (auxByte);
95 auxMethodRecord = find_method (tempClassRecord, signature);
96 if (auxMethodRecord == null)
99 if (auxByte == JAVA_LANG_OBJECT)
101 throw_exception (noSuchMethodError);
105 auxByte = tempClassRecord->parentClass;
106 goto LABEL_METHODLOOKUP;
109 if (dispatch_special (auxMethodRecord, retAddr))
111 if (is_synchronized(auxMethodRecord))
113 current_stackframe()->monitor = ref;
114 enter_monitor (currentThread, ref);
120 * Calls static initializer if necessary before
121 * dispatching with dispatch_special().
122 * @param retAddr Return bytecode address.
123 * @param btAddr Backtrack bytecode address (in case
124 * static initializer is executed).
126 void dispatch_special_checked (byte classIndex, byte methodIndex,
127 byte *retAddr, byte *btAddr)
129 ClassRecord *classRecord;
132 printf ("dispatch_special_checked: %d, %d, %d, %d\n",
133 classIndex, methodIndex, (int) retAddr, (int) btAddr);
136 classRecord = get_class_record (classIndex);
137 if (dispatch_static_initializer (classRecord, btAddr))
139 dispatch_special (get_method_record (classRecord, methodIndex), retAddr);
143 * @param classRecord Record for method class.
144 * @param methodRecord Calle's method record.
145 * @param retAddr What the PC should be upon return.
146 * @return true iff the stack frame was pushed.
148 boolean dispatch_special (MethodRecord *methodRecord, byte *retAddr)
154 StackFrame *stackFrame;
155 byte newStackFrameIndex;
158 printf ("\n------ dispatch special - %d ------------------\n\n",
159 methodRecord->signatureId);
163 printf ("dispatch_special: %d, %d\n",
164 (int) methodRecord, (int) retAddr);
165 printf ("-- signature id = %d\n", methodRecord->signatureId);
166 printf ("-- code offset = %d\n", methodRecord->codeOffset);
167 printf ("-- flags = %d\n", methodRecord->mflags);
168 printf ("-- num params = %d\n", methodRecord->numParameters);
169 printf ("-- stack ptr = %d\n", (int) get_stack_ptr());
170 printf ("-- max stack ptr= %d\n", (int) (currentThread->stackArray + (get_array_size(currentThread->stackArray))*2));
173 pop_words (methodRecord->numParameters);
176 if (is_native (methodRecord))
179 printf ("-- native\n");
181 dispatch_native (methodRecord->signatureId, get_stack_ptr() + 1);
182 // Stack frame not pushed
186 newStackFrameIndex = currentThread->stackFrameArraySize;
188 if (newStackFrameIndex >= get_array_length((Object *) word2ptr (currentThread->stackFrameArray)))
190 #if !FIXED_STACK_SIZE
191 // int len = get_array_length((Object *) word2ptr (currentThread->stackFrameArray));
192 int newlen = get_array_length((Object *) word2ptr (currentThread->stackFrameArray)) * 3 / 2;
193 JINT newStackFrameArray = JNULL;
195 // Stack frames are indexed by a byte value so limit the size.
198 // increase the stack frame size
199 newStackFrameArray = ptr2word(reallocate_array(word2ptr(currentThread->stackFrameArray), newlen));
202 // If can't allocate new stack, give in!
203 if (newStackFrameArray == JNULL)
206 throw_exception (stackOverflowError);
208 #if !FIXED_STACK_SIZE
212 currentThread->stackFrameArray = newStackFrameArray;
216 if (newStackFrameIndex == 0)
218 // Assign NEW stack frame
219 stackFrame = stackframe_array();
224 for (debug_ctr = 0; debug_ctr < methodRecord->numParameters; debug_ctr++)
225 printf ("-- param[%d] = %ld\n", debug_ctr, (long) get_stack_ptr()[debug_ctr+1]);
228 // Save OLD stackFrame state
229 stackFrame = stackframe_array() + (newStackFrameIndex - 1);
230 update_stack_frame (stackFrame);
231 // Push NEW stack frame
234 // Increment size of stack frame array
235 currentThread->stackFrameArraySize++;
236 // Initialize rest of new stack frame
237 stackFrame->methodRecord = methodRecord;
238 stackFrame->monitor = null;
239 stackFrame->localsBase = get_stack_ptr() + 1;
240 // Initialize auxiliary global variables (registers)
241 pc = get_code_ptr(methodRecord);
244 printf ("pc set to 0x%X\n", (int) pc);
247 init_sp (stackFrame, methodRecord);
248 update_constant_registers (stackFrame);
250 //printf ("m %d stack = %d\n", (int) methodRecord->signatureId, (int) (localsBase - stack_array()));
252 // Check for stack overflow
253 // (stackTop + methodRecord->maxOperands) >= (stack_array() + STACK_SIZE);
254 if (is_stack_overflow (methodRecord))
256 #if !FIXED_STACK_SIZE
257 StackFrame *stackBase;
260 // Need at least this many bytes
261 // int len = (int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE;
263 // Need to compute new array size (as distinct from number of bytes in array).
264 int newlen = (((int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE + 1) / 4) * 3 / 2;
265 JINT newStackArray = ptr2word(reallocate_array(word2ptr(currentThread->stackArray), newlen));
267 // If can't allocate new stack, give in!
268 if (newStackArray == JNULL)
271 throw_exception (stackOverflowError);
273 #if !FIXED_STACK_SIZE
277 newlen = newStackArray - currentThread->stackArray;
278 stackBase = stackframe_array();
279 stackTop = word2ptr(ptr2word(stackTop) + newlen);
280 localsBase = word2ptr(ptr2word(localsBase) + newlen);
282 printf("thread=%d, stackTop(%d), localsBase(%d)=%d\n", currentThread->threadId, (int)stackTop, (int)localsBase, (int)(*localsBase));
284 for (i=currentThread->stackFrameArraySize-1;
288 stackBase[i].localsBase = word2ptr(ptr2word(stackBase[i].localsBase) + newlen);
289 stackBase[i].stackTop = word2ptr(ptr2word(stackBase[i].stackTop) + newlen);
291 printf("stackBase[%d].localsBase(%d) = %d\n", i, (int)stackBase[i].localsBase, (int)(*stackBase[i].localsBase));
296 currentThread->stackArray = newStackArray;
304 void do_return (byte numWords)
306 StackFrame *stackFrame;
307 STACKWORD *fromStackPtr;
309 stackFrame = current_stackframe();
312 printf ("\n------ return ----- %d ------------------\n\n",
313 stackFrame->methodRecord->signatureId);
317 printf ("do_return: method: %d # num. words: %d\n",
318 stackFrame->methodRecord->signatureId, numWords);
322 assert (stackFrame != null, LANGUAGE3);
324 if (stackFrame->monitor != null)
325 exit_monitor (currentThread, stackFrame->monitor);
327 #if DEBUG_THREADS || DEBUG_METHODS
328 printf ("do_return: stack frame array size: %d\n", currentThread->stackFrameArraySize);
331 if (currentThread->stackFrameArraySize == 1)
334 printf ("do_return: thread is done: %d\n", (int) currentThread);
336 currentThread->state = DEAD;
337 schedule_request (REQUEST_SWITCH_THREAD);
341 // Place source ptr below data to be copied up the stack
342 fromStackPtr = get_stack_ptr_at (numWords);
344 currentThread->stackFrameArraySize--;
347 update_registers (stackFrame);
350 printf ("do_return: stack reset to:\n");
351 printf ("-- stack ptr = %d\n", (int) get_stack_ptr());
356 push_word (*(++fromStackPtr));
363 STACKWORD instance_of (Object *obj, byte classIndex)
369 rtType = get_class_index(obj);
370 // TBD: support for interfaces
371 if (is_interface (get_class_record(classIndex)))
374 if (rtType == classIndex)
376 if (rtType == JAVA_LANG_OBJECT)
378 rtType = get_class_record(rtType)->parentClass;