fint sendDesc::ntargets() { char *addr= jump_addr(); if (addr == lookupRoutine()) return 0; if (Memory->code->contains(addr)) return 1; assert(Memory->code->stubs->contains(addr), "what is it?"); NCodeBase *n= findStub(addr); return n->isCountStub() ? 1 : ((CacheStub*)n)->arity(); }
// NB: get_method() is not quite equivalent to target(): the former returns // an nmethod even when it is called via a count stub, the latter returns // NULL in this case. // It can also be called on dummy sendDescs representing glue code nmethod* sendDesc::get_method() { char *addr= jump_addr(); if (Memory->code->contains(addr)) return nmethod_from_insts(addr); if (!Memory->code->stubs->contains(addr)) return NULL; NCodeBase *n= findStub(addr); assert(n->isCountStub(), "shouldn't call on PICs"); return ((CountStub*)n)->target(); }
NCodeBase* findThing(void* addr) { if (Memory->code->stubs->contains(addr)) { return findStub(addr); } else if (Memory->code->contains(addr)) { nmethod* n= nmethod_from_insts((char*)addr); assert(isNMethod(n), "not a method"); return n; } else { return NULL; } }
CacheStub* sendDesc::pic() { char* addr = jump_addr(); if (Memory->code->contains(addr)) { // linked to a nmethod return NULL; } else if (Memory->code->stubs->contains(addr)) { NCodeBase* stub = findStub(addr); return stub->isCacheStub() ? (CacheStub*)stub : NULL; } else { return NULL; } }
CountStub* sendDesc::countStub() { char* addr= jump_addr(); if (Memory->code->contains(addr)) { // linked to a nmethod assert(!Memory->code->stubs->contains(addr), "zones overlap"); return NULL; } else if (Memory->code->stubs->contains(addr)) { NCodeBase* stub = findStub(addr); return stub->isCountStub() ? (CountStub*)stub : NULL; } else { return NULL; } }