Commit aa7baa83 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make it easier to get the slowpath addr for a patchpoint

Currently it gets somewhat hidden by the object-caching behavior.
Add an API for fetching it out, and use it to make the "prettified"
IR (which you see on -vv or higher) include the slowpath addresses.
parent 59c009d4
......@@ -1940,28 +1940,6 @@ bool spillFrameArgumentIfNecessary(StackMap::Record::Location& l, uint8_t*& inst
}
}
void* extractSlowpathFunc(uint8_t* pp_addr) {
#ifndef NDEBUG
// mov $imm, %r11:
ASSERT(pp_addr[0] == 0x49, "%x", pp_addr[0]);
assert(pp_addr[1] == 0xbb);
// 8 bytes of the addr
// callq *%r11:
assert(pp_addr[10] == 0x41);
assert(pp_addr[11] == 0xff);
assert(pp_addr[12] == 0xd3);
int i = INITIAL_CALL_SIZE;
while (*(pp_addr + i) == 0x66 || *(pp_addr + i) == 0x0f || *(pp_addr + i) == 0x2e)
i++;
assert(*(pp_addr + i) == 0x90 || *(pp_addr + i) == 0x1f);
#endif
void* call_addr = *(void**)&pp_addr[2];
return call_addr;
}
void setSlowpathFunc(uint8_t* pp_addr, void* func) {
#ifndef NDEBUG
// mov $imm, %r11:
......
......@@ -518,7 +518,6 @@ public:
friend class RewriterVar;
};
void* extractSlowpathFunc(uint8_t* pp_addr);
void setSlowpathFunc(uint8_t* pp_addr, void* func);
struct GRCompare {
......
......@@ -20,10 +20,12 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "codegen/codegen.h"
#include "codegen/patchpoints.h"
#include "core/common.h"
#include "runtime/types.h"
......@@ -158,9 +160,14 @@ llvm::Constant* getConstantDouble(double val) {
class PrettifyingMaterializer : public llvm::ValueMaterializer {
private:
llvm::Module* module;
llvm::ValueToValueMapTy& VMap;
llvm::RemapFlags flags;
llvm::ValueMapTypeRemapper* type_remapper;
public:
PrettifyingMaterializer(llvm::Module* module) : module(module) {}
PrettifyingMaterializer(llvm::Module* module, llvm::ValueToValueMapTy& VMap, llvm::RemapFlags flags,
llvm::ValueMapTypeRemapper* type_remapper)
: module(module), VMap(VMap), flags(flags), type_remapper(type_remapper) {}
virtual llvm::Value* materializeValueFor(llvm::Value* v) {
if (llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(v)) {
......@@ -183,6 +190,46 @@ public:
return module->getOrInsertGlobal(name, pt->getElementType());
}
}
if (llvm::IntrinsicInst* ii = llvm::dyn_cast<llvm::IntrinsicInst>(v)) {
if (ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_i64
|| ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_void
|| ii->getIntrinsicID() == llvm::Intrinsic::experimental_patchpoint_double) {
int pp_id = -1;
for (int i = 0; i < ii->getNumArgOperands(); i++) {
llvm::Value* op = ii->getArgOperand(i);
if (i != 1) {
if (i == 0) {
llvm::ConstantInt* l_pp_id = llvm::cast<llvm::ConstantInt>(op);
pp_id = l_pp_id->getSExtValue();
}
ii->setArgOperand(i, llvm::MapValue(op, VMap, flags, type_remapper, this));
continue;
} else {
assert(pp_id != -1);
void* addr = PatchpointInfo::getSlowpathAddr(pp_id);
bool lookup_success = true;
std::string name;
if (addr == (void*)None) {
name = "None";
} else {
name = g.func_addr_registry.getFuncNameAtAddress(addr, true, &lookup_success);
}
if (!lookup_success) {
llvm::Constant* int_val
= llvm::ConstantInt::get(g.i64, reinterpret_cast<uintptr_t>(addr), false);
llvm::Constant* ptr_val = llvm::ConstantExpr::getIntToPtr(int_val, g.i8_ptr);
ii->setArgOperand(i, ptr_val);
continue;
} else {
ii->setArgOperand(i, module->getOrInsertGlobal(name, g.i8_ptr));
}
}
}
return ii;
}
}
return v;
}
};
......@@ -194,12 +241,14 @@ void dumpPrettyIR(llvm::Function* f) {
llvm::Function* new_f = tmp_module->begin();
llvm::ValueToValueMapTy VMap;
PrettifyingMaterializer materializer(tmp_module.get());
llvm::RemapFlags flags = llvm::RF_None;
llvm::ValueMapTypeRemapper* type_remapper = NULL;
PrettifyingMaterializer materializer(tmp_module.get(), VMap, flags, type_remapper);
for (llvm::Function::iterator I = new_f->begin(), E = new_f->end(); I != E; ++I) {
VMap[I] = I;
}
for (llvm::inst_iterator it = inst_begin(new_f), end = inst_end(new_f); it != end; ++it) {
llvm::RemapInstruction(&*it, VMap, llvm::RF_None, NULL, &materializer);
llvm::RemapInstruction(&*it, VMap, flags, type_remapper, &materializer);
}
tmp_module->begin()->dump();
// tmp_module->dump();
......
......@@ -162,7 +162,7 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
PatchpointInfo* pp = new_patchpoints[r->id].first;
assert(pp);
void* dst_func = new_patchpoints[r->id].second;
void* slowpath_func = PatchpointInfo::getSlowpathAddr(r->id);
if (VERBOSITY() >= 2) {
printf("Processing pp %ld; [%d, %d)\n", reinterpret_cast<int64_t>(pp), r->offset,
r->offset + pp->patchpointSize());
......@@ -179,10 +179,7 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
uint8_t* end_addr = start_addr + pp->patchpointSize();
if (ENABLE_JIT_OBJECT_CACHE)
setSlowpathFunc(start_addr, dst_func);
// TODO shouldn't have to do it this way
void* slowpath_func = extractSlowpathFunc(start_addr);
setSlowpathFunc(start_addr, slowpath_func);
//*start_addr = 0xcc;
// start_addr++;
......@@ -287,6 +284,11 @@ PatchpointInfo* PatchpointInfo::create(CompiledFunction* parent_cf, const ICSetu
return r;
}
void* PatchpointInfo::getSlowpathAddr(unsigned int pp_id) {
RELEASE_ASSERT(pp_id < new_patchpoints.size(), "");
return new_patchpoints[pp_id].second;
}
ICSetupInfo* createGenericIC(TypeRecorder* type_recorder, bool has_return_value, int size) {
return ICSetupInfo::initialize(has_return_value, 1, size, ICSetupInfo::Generic, type_recorder);
}
......
......@@ -97,6 +97,7 @@ public:
static PatchpointInfo* create(CompiledFunction* parent_cf, const ICSetupInfo* icinfo, int num_ic_stackmap_args,
void* func_addr);
static void* getSlowpathAddr(unsigned int pp_id);
};
class ICSetupInfo {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment