void asys::DebugInfo::pushCallInfo(int index) { CallInfo* pCallInfo = new CallInfo; pCallInfo->init(m_pMachine, index); m_callStack.push_back(pCallInfo); m_pLocalVariables = &pCallInfo->m_variables; }
CallInfo Call::getInfo() const throw(Error) { pjsua_call_info pj_ci; CallInfo ci; PJSUA2_CHECK_EXPR( pjsua_call_get_info(id, &pj_ci) ); ci.fromPj(pj_ci); return ci; }
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); //signature-> // Invoke the method printf("%s[%d] [tid: %lu]: 开始调用Java中的静态方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), klass->external_name(), name->as_C_string(), signature->as_C_string()); JavaCalls::call(result, method, args, CHECK); }
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkResolver::resolve_special_call(callinfo, link_info, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
CallInfo* CallList::find(const CallEndpoint* call) { ObjList* l = m_calls.skipNull(); for (; l; l = l->skipNext()) { CallInfo* info = static_cast<CallInfo*>(l->get()); if (info->call() == call) return info; } return 0; }
bool MultiRouter::msgDisconnected(Message& msg, CallInfo& info) { info.copyParams(msg,true,"reason","error",0); Message* m = buildExecute(info,msg.getBoolValue("reroute")); if (m) { m->userData(info.call()); Engine::enqueue(m); return true; } return false; }
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); LinkInfo link_info(spec_klass, name, signature); LinkResolver::resolve_virtual_call( callinfo, receiver, recvrKlass, link_info, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
void SourceAssembler::define_call_info() { #if ENABLE_EMBEDDED_CALLINFO // Only the interpreter defined call info in the source assembler CallInfo ci = CallInfo::interpreter(); emit_comment("call info"); if (!GenerateGNUCode) if (!GenerateInlineAsm) emit("\ttest eax, %d\n", ci.raw()); else emit("\t__asm test eax, %d\n", ci.raw()); else emit("\ttest $%d, %%eax\n", ci.raw()); #endif // ENABLE_EMBEDDED_CALLINFO }
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass()); LinkResolver::resolve_virtual_call( callinfo, receiver, recvrKlass, spec_klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); printf("%s[%d] [tid: %lu]: 开始调用Java中的方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), spec_klass->external_name(), name->as_C_string(), signature->as_C_string()); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool, Bytecodes::Code invoke_code, const CallInfo &call_info) { // NOTE: This CPCE can be the subject of data races. // There are three words to update: flags, refs[f2], f1 (in that order). // Writers must store all other values before f1. // Readers must test f1 first for non-null before reading other fields. // Competing writers must acquire exclusive access via a lock. // A losing writer waits on the lock until the winner writes f1 and leaves // the lock, so that when the losing writer returns, he can use the linked // cache entry. MonitorLockerEx ml(cpool->lock()); if (!is_f1_null()) { return; } const methodHandle adapter = call_info.resolved_method(); const Handle appendix = call_info.resolved_appendix(); const Handle method_type = call_info.resolved_method_type(); const bool has_appendix = appendix.not_null(); const bool has_method_type = method_type.not_null(); // Write the flags. set_method_flags(as_TosState(adapter->result_type()), ((has_appendix ? 1 : 0) << has_appendix_shift ) | ((has_method_type ? 1 : 0) << has_method_type_shift) | ( 1 << is_final_shift ), adapter->size_of_parameters()); if (TraceInvokeDynamic) { tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ", invoke_code, (void *)appendix(), (has_appendix ? "" : " (unused)"), (void *)method_type(), (has_method_type ? "" : " (unused)"), (intptr_t)adapter()); adapter->print(); if (has_appendix) appendix()->print(); } // Method handle invokes and invokedynamic sites use both cp cache words. // refs[f2], if not null, contains a value passed as a trailing argument to the adapter. // In the general case, this could be the call site's MethodType, // for use with java.lang.Invokers.checkExactType, or else a CallSite object. // f1 contains the adapter method which manages the actual call. // In the general case, this is a compiled LambdaForm. // (The Java code is free to optimize these calls by binding other // sorts of methods and appendices to call sites.) // JVM-level linking is via f1, as if for invokespecial, and signatures are erased. // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits. // Even with the appendix, the method will never take more than 255 parameter slots. // // This means that given a call site like (List)mh.invoke("foo"), // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;', // not '(Ljava/lang/String;)Ljava/util/List;'. // The fact that String and List are involved is encoded in the MethodType in refs[f2]. // This allows us to create fewer method oops, while keeping type safety. // objArrayHandle resolved_references = cpool->resolved_references(); // Store appendix, if any. if (has_appendix) { const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset; assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob"); assert(resolved_references->obj_at(appendix_index) == NULL, "init just once"); resolved_references->obj_at_put(appendix_index, appendix()); } // Store MethodType, if any. if (has_method_type) { const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset; assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob"); assert(resolved_references->obj_at(method_type_index) == NULL, "init just once"); resolved_references->obj_at_put(method_type_index, method_type()); } release_set_f1(adapter()); // This must be the last one to set (see NOTE above)! // The interpreter assembly code does not check byte_2, // but it is used by is_resolved, method_if_resolved, etc. set_bytecode_1(invoke_code); NOT_PRODUCT(verify(tty)); if (TraceInvokeDynamic) { this->print(tty, 0); } }
void SourceAssembler::define_call_info() { #if ENABLE_EMBEDDED_CALLINFO CallInfo ci = CallInfo::interpreter(); define_long(ci.raw()); #endif }
bool MultiRouter::received(Message& msg, int id) { CallEndpoint* call = static_cast<CallEndpoint*>(msg.userObject(YATOM("CallEndpoint"))); bool first = false; CallInfo* info = 0; String chanid(msg.getValue("id")); Lock lock(this); if (call) info = m_list.find(call); if (info) { if (*info != chanid) { Debug(DebugGoOn,"Channel mismatch! call=%p id='%s' stored='%s'", call,chanid.c_str(),info->c_str()); return false; } } else info = m_list.find(chanid); if (info) { if (!call) call = info->call(); else if (!info->call()) info->setCall(call); else if (info->call() != call) { Debug(DebugGoOn,"Channel mismatch! id='%s' call=%p stored=%p", chanid.c_str(),call,info->call()); return false; } } else if ((id == Route) || (id == Execute)) { info = new CallInfo(chanid,call); info->copyParams(msg,false,"module","address","billid","caller","called","callername",0); m_list.append(info); first = true; DDebug(DebugInfo,"MultiRouter built '%s' @ %p for %p", chanid.c_str(),info,call); } else return false; DDebug(DebugAll,"MultiRouter::received '%s' for '%s' info=%p call=%p", msg.c_str(),chanid.c_str(),info,call); switch (id) { case Route: return msgRoute(msg,*info,first); case Execute: if (!call) return false; return msgExecute(msg,*info,first); case Disconnected: return msgDisconnected(msg,*info); case Hangup: info->clearCall(); msgHangup(msg,*info); m_list.remove(info); DDebug(DebugInfo,"MultiRouter destroyed '%s' @ %p",info->c_str(),info); info->destruct(); break; default: Debug(DebugFail,"Invalid id %d in MultiRouter::received()",id); } return false; }