Commit 53862fa5 authored by Marius Wachtler's avatar Marius Wachtler

Add more runtime ICs and make the EH frame generation code ready for the new JIT tier

IC sizes are guessed...
parent 5281aab8
...@@ -64,7 +64,7 @@ namespace pyston { ...@@ -64,7 +64,7 @@ namespace pyston {
// readelf -w test // readelf -w test
// //
#if RUNTIMEICS_OMIT_FRAME_PTR
// clang++ test.cpp -o test -O3 -fomit-frame-pointer -c -DN=40 // clang++ test.cpp -o test -O3 -fomit-frame-pointer -c -DN=40
// The generated assembly is: // The generated assembly is:
// //
...@@ -77,7 +77,7 @@ namespace pyston { ...@@ -77,7 +77,7 @@ namespace pyston {
// //
// (I believe the push/pop are for stack alignment) // (I believe the push/pop are for stack alignment)
// //
static const char _eh_frame_template[] = static const char _eh_frame_template_ofp[] =
// CIE // CIE
"\x14\x00\x00\x00" // size of the CIE "\x14\x00\x00\x00" // size of the CIE
"\x00\x00\x00\x00" // specifies this is an CIE "\x00\x00\x00\x00" // specifies this is an CIE
...@@ -105,7 +105,7 @@ static const char _eh_frame_template[] = ...@@ -105,7 +105,7 @@ static const char _eh_frame_template[] =
"\x00\x00\x00\x00" // terminator "\x00\x00\x00\x00" // terminator
; ;
#else
// clang++ test.cpp -o test -O3 -fno-omit-frame-pointer -c -DN=40 // clang++ test.cpp -o test -O3 -fno-omit-frame-pointer -c -DN=40
// The generated assembly is: // The generated assembly is:
// 0: 55 push %rbp // 0: 55 push %rbp
...@@ -118,7 +118,7 @@ static const char _eh_frame_template[] = ...@@ -118,7 +118,7 @@ static const char _eh_frame_template[] =
// 1a: 5d pop %rbp // 1a: 5d pop %rbp
// 1b: c3 retq // 1b: c3 retq
// //
static const char _eh_frame_template[] = static const char _eh_frame_template_fp[] =
// CIE // CIE
"\x14\x00\x00\x00" // size of the CIE "\x14\x00\x00\x00" // size of the CIE
"\x00\x00\x00\x00" // specifies this is an CIE "\x00\x00\x00\x00" // specifies this is an CIE
...@@ -150,13 +150,19 @@ static const char _eh_frame_template[] = ...@@ -150,13 +150,19 @@ static const char _eh_frame_template[] =
"\x00\x00\x00\x00" // terminator "\x00\x00\x00\x00" // terminator
; ;
#endif
static constexpr int _eh_frame_template_ofp_size = sizeof(_eh_frame_template_ofp) - 1;
static constexpr int _eh_frame_template_fp_size = sizeof(_eh_frame_template_fp) - 1;
#define EH_FRAME_SIZE (sizeof(_eh_frame_template) - 1) // omit string-terminating null byte #define EH_FRAME_SIZE (sizeof(_eh_frame_template) - 1) // omit string-terminating null byte
static_assert(sizeof("") == 1, "strings are null-terminated"); static_assert(sizeof("") == 1, "strings are null-terminated");
static void writeTrivialEhFrame(void* eh_frame_addr, void* func_addr, uint64_t func_size) { static void writeTrivialEhFrame(void* eh_frame_addr, void* func_addr, uint64_t func_size, bool omit_frame_pointer) {
memcpy(eh_frame_addr, _eh_frame_template, EH_FRAME_SIZE); if (omit_frame_pointer)
memcpy(eh_frame_addr, _eh_frame_template_ofp, _eh_frame_template_ofp_size);
else
memcpy(eh_frame_addr, _eh_frame_template_fp, _eh_frame_template_fp_size);
int32_t* offset_ptr = (int32_t*)((uint8_t*)eh_frame_addr + 0x20); int32_t* offset_ptr = (int32_t*)((uint8_t*)eh_frame_addr + 0x20);
int32_t* size_ptr = (int32_t*)((uint8_t*)eh_frame_addr + 0x24); int32_t* size_ptr = (int32_t*)((uint8_t*)eh_frame_addr + 0x24);
...@@ -171,27 +177,29 @@ static void writeTrivialEhFrame(void* eh_frame_addr, void* func_addr, uint64_t f ...@@ -171,27 +177,29 @@ static void writeTrivialEhFrame(void* eh_frame_addr, void* func_addr, uint64_t f
void EHFrameManager::writeAndRegister(void* func_addr, uint64_t func_size) { void EHFrameManager::writeAndRegister(void* func_addr, uint64_t func_size) {
assert(eh_frame_addr == NULL); assert(eh_frame_addr == NULL);
const int size = omit_frame_pointer ? _eh_frame_template_ofp_size : _eh_frame_template_fp_size;
#ifdef NVALGRIND #ifdef NVALGRIND
eh_frame_addr = malloc(EH_FRAME_SIZE); eh_frame_addr = malloc(size);
#else #else
eh_frame_addr = mmap(NULL, (EH_FRAME_SIZE + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1), PROT_READ | PROT_WRITE, eh_frame_addr = mmap(NULL, (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1), PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
RELEASE_ASSERT(eh_frame_addr != MAP_FAILED, ""); RELEASE_ASSERT(eh_frame_addr != MAP_FAILED, "");
#endif #endif
writeTrivialEhFrame(eh_frame_addr, func_addr, func_size); writeTrivialEhFrame(eh_frame_addr, func_addr, func_size, omit_frame_pointer);
// (EH_FRAME_SIZE - 4) to omit the 4-byte null terminator, otherwise we trip an assert in parseEhFrame. // (EH_FRAME_SIZE - 4) to omit the 4-byte null terminator, otherwise we trip an assert in parseEhFrame.
// TODO: can we omit the terminator in general? // TODO: can we omit the terminator in general?
registerDynamicEhFrame((uint64_t)func_addr, func_size, (uint64_t)eh_frame_addr, EH_FRAME_SIZE - 4); registerDynamicEhFrame((uint64_t)func_addr, func_size, (uint64_t)eh_frame_addr, size - 4);
registerEHFrames((uint8_t*)eh_frame_addr, (uint64_t)eh_frame_addr, EH_FRAME_SIZE); registerEHFrames((uint8_t*)eh_frame_addr, (uint64_t)eh_frame_addr, size);
} }
EHFrameManager::~EHFrameManager() { EHFrameManager::~EHFrameManager() {
if (eh_frame_addr) { if (eh_frame_addr) {
deregisterEHFrames((uint8_t*)eh_frame_addr, (uint64_t)eh_frame_addr, EH_FRAME_SIZE); const int size = omit_frame_pointer ? _eh_frame_template_ofp_size : _eh_frame_template_fp_size;
deregisterEHFrames((uint8_t*)eh_frame_addr, (uint64_t)eh_frame_addr, size);
#ifdef NVALGRIND #ifdef NVALGRIND
free(eh_frame_addr); free(eh_frame_addr);
#else #else
munmap(eh_frame_addr, (EH_FRAME_SIZE + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)); munmap(eh_frame_addr, (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1));
#endif #endif
} }
} }
...@@ -204,7 +212,7 @@ EHFrameManager::~EHFrameManager() { ...@@ -204,7 +212,7 @@ EHFrameManager::~EHFrameManager() {
#define SCRATCH_BYTES 0x30 #define SCRATCH_BYTES 0x30
#endif #endif
RuntimeIC::RuntimeIC(void* func_addr, int num_slots, int slot_size) { RuntimeIC::RuntimeIC(void* func_addr, int num_slots, int slot_size) : eh_frame(RUNTIMEICS_OMIT_FRAME_PTR) {
static StatCounter sc("runtime_ics_num"); static StatCounter sc("runtime_ics_num");
sc.log(); sc.log();
......
...@@ -25,9 +25,10 @@ class ICInfo; ...@@ -25,9 +25,10 @@ class ICInfo;
class EHFrameManager { class EHFrameManager {
private: private:
void* eh_frame_addr; void* eh_frame_addr;
bool omit_frame_pointer;
public: public:
EHFrameManager() : eh_frame_addr(NULL) {} EHFrameManager(bool omit_frame_pointer) : eh_frame_addr(NULL), omit_frame_pointer(omit_frame_pointer) {}
~EHFrameManager(); ~EHFrameManager();
void writeAndRegister(void* func_addr, uint64_t func_size); void writeAndRegister(void* func_addr, uint64_t func_size);
}; };
...@@ -76,6 +77,29 @@ public: ...@@ -76,6 +77,29 @@ public:
} }
}; };
class RuntimeCallIC : public RuntimeIC {
public:
RuntimeCallIC() : RuntimeIC((void*)runtimeCall, 2, 320) {}
Box* call(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args) {
return (Box*)call_ptr(obj, argspec, arg1, arg2, arg3, args);
}
};
class UnaryopIC : public RuntimeIC {
public:
UnaryopIC() : RuntimeIC((void*)unaryop, 2, 160) {}
Box* call(Box* obj, int op_type) { return (Box*)call_ptr(obj, op_type); }
};
class AugBinopIC : public RuntimeIC {
public:
AugBinopIC() : RuntimeIC((void*)augbinop, 2, 240) {}
Box* call(Box* lhs, Box* rhs, int op_type) { return (Box*)call_ptr(lhs, rhs, op_type); }
};
class BinopIC : public RuntimeIC { class BinopIC : public RuntimeIC {
public: public:
BinopIC() : RuntimeIC((void*)binop, 2, 240) {} BinopIC() : RuntimeIC((void*)binop, 2, 240) {}
...@@ -83,6 +107,55 @@ public: ...@@ -83,6 +107,55 @@ public:
Box* call(Box* lhs, Box* rhs, int op_type) { return (Box*)call_ptr(lhs, rhs, op_type); } Box* call(Box* lhs, Box* rhs, int op_type) { return (Box*)call_ptr(lhs, rhs, op_type); }
}; };
class CompareIC : public RuntimeIC {
public:
CompareIC() : RuntimeIC((void*)compare, 2, 240) {}
Box* call(Box* lhs, Box* rhs, int op_type) { return (Box*)call_ptr(lhs, rhs, op_type); }
};
class GetItemIC : public RuntimeIC {
public:
GetItemIC() : RuntimeIC((void*)getitem, 2, 512) {}
Box* call(Box* obj, Box* attr) { return (Box*)call_ptr(obj, attr); }
};
class SetItemIC : public RuntimeIC {
public:
SetItemIC() : RuntimeIC((void*)setitem, 2, 512) {}
Box* call(Box* obj, Box* attr, Box* v) { return (Box*)call_ptr(obj, attr, v); }
};
class GetAttrIC : public RuntimeIC {
public:
GetAttrIC() : RuntimeIC((void*)getattr, 2, 512) {}
Box* call(Box* obj, BoxedString* attr) { return (Box*)call_ptr(obj, attr); }
};
class SetAttrIC : public RuntimeIC {
public:
SetAttrIC() : RuntimeIC((void*)setattr, 2, 512) {}
Box* call(Box* obj, BoxedString* attr, Box* v) { return (Box*)call_ptr(obj, attr, v); }
};
class GetGlobalIC : public RuntimeIC {
public:
GetGlobalIC() : RuntimeIC((void*)getGlobal, 2, 512) {}
Box* call(Box* obj, BoxedString* s) { return (Box*)call_ptr(obj, s); }
};
class SetGlobalIC : public RuntimeIC {
public:
SetGlobalIC() : RuntimeIC((void*)setGlobal, 2, 512) {}
Box* call(Box* obj, BoxedString* s, Box* v) { return (Box*)call_ptr(obj, s, v); }
};
class NonzeroIC : public RuntimeIC { class NonzeroIC : public RuntimeIC {
public: public:
NonzeroIC() : RuntimeIC((void*)nonzero, 1, 40) {} NonzeroIC() : RuntimeIC((void*)nonzero, 1, 40) {}
......
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