KNIEXPORT jlong KNI_GetParameterAsLong(jint index) { GUARANTEE(!_in_kvm_native_method, "sanity"); jint AA = *(jint*)parameter_address(index); jint BB = *(jint*)parameter_address(index+1); if (JavaStackDirection < 0) { GUARANTEE(parameter_address(index+1) < parameter_address(index), "Sanity"); return jlong_from_low_high(BB, AA); } else { GUARANTEE(parameter_address(index+1) > parameter_address(index), "Sanity"); return jlong_from_low_high(AA, BB); } }
void popLongToAddress(void* ptr) { GUARANTEE(_in_kvm_native_method, "sanity"); int BB = *_kvm_stack_top; _kvm_stack_top -= JavaStackDirection; int AA = *_kvm_stack_top; _kvm_stack_top -= JavaStackDirection; jlong value; if (JavaStackDirection < 0) { value = jlong_from_low_high(BB, AA); } else { value = jlong_from_low_high(AA, BB); } *((jlong*)ptr) = value; }
jlong ObjectReferenceImpl::invoke_return(Oop *o, Oop *exc, Oop *transport, int id, int options, int return_type, OopDesc **obj_ret_val) { UsingFastOops fastoops; Oop::Fast ret_obj; Transport *t = (Transport *)transport; PacketOutputStream out(t); out.init_reply(id); if (!exc->is_null()) { // have an exception condition, return the exception object out.write_byte(JDWP_Tag_OBJECT); out.write_object(exc); } else { if (o->is_null()) { out.write_byte(JDWP_Tag_VOID); } else if (o->is_obj_array()) { ObjArray::Raw oa = o->obj(); ret_obj = oa().obj_at(0); jbyte tag = JavaDebugger::get_jdwp_tag(&ret_obj); out.write_byte(tag); out.write_object(&ret_obj); } else { GUARANTEE(o->is_type_array(), "Invalid return array type"); TypeArray::Raw ta = o->obj(); switch(return_type) { case T_BOOLEAN: out.write_byte(JDWP_Tag_BOOLEAN); out.write_boolean((jboolean)ta().int_at(0)); break; case T_BYTE: out.write_byte(JDWP_Tag_BYTE); out.write_byte((jboolean)ta().int_at(0)); break; case T_SHORT: out.write_byte(JDWP_Tag_SHORT); out.write_short((jshort)ta().int_at(0)); break; case T_CHAR: out.write_byte(JDWP_Tag_CHAR); out.write_char((jchar)ta().int_at(0)); break; case T_INT: out.write_byte(JDWP_Tag_INT); out.write_int(ta().int_at(0)); break; case T_LONG: out.write_byte(JDWP_Tag_LONG); out.write_long((jlong)ta().long_at(0)); break; case T_DOUBLE: out.write_byte(JDWP_Tag_DOUBLE); out.write_double(ta().double_at(0)); break; case T_FLOAT: out.write_byte(JDWP_Tag_FLOAT); out.write_float(ta().float_at(0)); break; } } out.write_byte(JDWP_Tag_OBJECT); out.write_int(0); } if (options & JDWP_InvokeOptions_INVOKE_SINGLE_THREADED) { ThreadReferenceImpl::suspend_specific_thread(Thread::current(), -1, true); } else { ThreadReferenceImpl::suspend_all_threads(-1, true); } out.send_packet(); // At this point the stack looks like: // [ 0] com/sun/cldchi/jvm/JVM.debuggerInvokeReturn // [ 1] com/sun/cldchi/jvm/JVM.debuggerInvoke // [ 2] EntryFrame // [ 3] test/Testx.main // Need to remove the two JavaFrames and the entry frame. // The stack will look like it did before we did the invoke Thread *thread = Thread::current(); Frame fr(thread); GUARANTEE(fr.is_java_frame(), "Frame must be java frame"); fr.as_JavaFrame().caller_is(fr); GUARANTEE(fr.is_java_frame(), "Frame must be java frame"); fr.as_JavaFrame().caller_is(fr); GUARANTEE(fr.is_entry_frame(), "Frame must be entry frame"); // We want to pass the original return value from the call VM (that got // saved in the EntryFrame) back to call_vm so it looks like this // invoke never happened. jlong ret_val = 0; if (obj_ret_val != NULL) { *obj_ret_val = fr.as_EntryFrame().stored_obj_value(); } else { ret_val = jlong_from_low_high(fr.as_EntryFrame().stored_int_value2(), fr.as_EntryFrame().stored_int_value1()); } fr.as_EntryFrame().caller_is(fr); GUARANTEE(fr.is_java_frame(), "Frame must be java frame"); // point to just after pc_addr address empty_stack = fr.sp() + (JavaStackDirection * BytesPerStackElement); // place to store original fp and return into call_vm code address *two_word_stack = (address *)(empty_stack + JavaStackDirection * BytesPerStackElement * 2); address* stack_pointer = (address*)thread->stack_pointer(); // original return address address ret_addr = stack_pointer[-1 * JavaStackDirection]; two_word_stack[-1*JavaStackDirection] = ret_addr; two_word_stack[0] = fr.fp(); thread->set_last_java_fp(fr.fp()); thread->set_last_java_sp(fr.sp()); thread->set_stack_pointer((jint)two_word_stack); return ret_val; }