Skip to content

Commit

Permalink
Enable flags for setting release code with debug symbols (#473)
Browse files Browse the repository at this point in the history
* Enable flags for setting release code with debug symbols

* Return back state when setting config and test for behaviour

* update release notes
  • Loading branch information
tonybaloney authored Jan 12, 2022
1 parent 658e106 commit b4c5a4f
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 47 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release notes

## 1.2.5

* Changed the `pyjion.config(debug=)` setting to allow True or False (as before), or 0 (Release), 1 (Debug), 2 (ReleaseWithDebugInfo)

## 1.2.4

* Updated to rich 11.0
Expand Down
2 changes: 1 addition & 1 deletion Tests/Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ int main(int argc, char* const argv[]) {
JitInit(L"libclrjit.so");
#endif
g_pyjionSettings.graph = true;
g_pyjionSettings.debug = true;
g_pyjionSettings.debug = DebugMode::Debug;
g_pyjionSettings.codeObjectSizeLimit = 1000000;
g_pyjionSettings.exceptionHandling = true;
setOptimizationLevel(2);
Expand Down
25 changes: 25 additions & 0 deletions Tests/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@ def _f(x):
assert len(offsets) > 7


def test_offsets_in_release():
def _f(x):
return x / 2

pyjion.config(debug=0)

assert _f(4) == 2.0

offsets = pyjion.offsets(_f)
assert len(offsets) == 0
pyjion.config(debug=1)


def test_offsets_in_release_with_debinfo():
def _f(x):
return x / 2

pyjion.config(debug=2)
assert _f(4) == 2.0

offsets = pyjion.offsets(_f)
assert len(offsets) > 7
pyjion.config(debug=1)


def test_dis(capsys):
def test_f():
numbers = (1, 2, 3, 4)
Expand Down
28 changes: 14 additions & 14 deletions Tests/test_ilgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ TEST_CASE("Test numerics") {
std::vector<Parameter>{});
gen->ld_i4(value);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -71,7 +71,7 @@ TEST_CASE("Test numerics") {
std::vector<Parameter>{});
gen->ld_u4(value);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
uint32_t result = ((Returns_uint32) method.getAddr())();
Expand All @@ -87,7 +87,7 @@ TEST_CASE("Test numerics") {
std::vector<Parameter>{});
gen->ld_i8(value);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int64_t result = ((Returns_int64) method.getAddr())();
Expand All @@ -103,7 +103,7 @@ TEST_CASE("Test numerics") {
std::vector<Parameter>{});
gen->ld_r8(value);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
double result = ((Returns_double) method.getAddr())();
Expand All @@ -125,7 +125,7 @@ TEST_CASE("Test locals") {
gen->st_loc(l);
gen->ld_loc(l);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -151,7 +151,7 @@ TEST_CASE("Test locals") {
gen->branch(BranchLessThan, another);
gen->ld_loc(l);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -174,7 +174,7 @@ TEST_CASE("Test branch true of floats") {
gen->ld_i4(3);
gen->mark_label(end);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -195,7 +195,7 @@ TEST_CASE("Test branch true of floats") {
gen->ld_i4(3);
gen->mark_label(end);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -217,7 +217,7 @@ TEST_CASE("Test branch true of floats") {
gen->ld_i4(3);
gen->mark_label(end);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -236,7 +236,7 @@ TEST_CASE("Test call") {
gen->ld_i8(5);
gen->emit_call(METHOD_INT_TRUE_DIVIDE);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
double result = ((Returns_double) method.getAddr())();
Expand All @@ -257,7 +257,7 @@ TEST_CASE("Test intrinsics") {
gen->ld_i8(5);
gen->emit_call(INTRINSIC_TEST);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
double result = ((Returns_double) method.getAddr())();
Expand All @@ -277,7 +277,7 @@ TEST_CASE("Test valuetype"){
gen->define_local(Parameter(CORINFO_TYPE_VALUECLASS));
gen->ld_r8(2.0);
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_call", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
double result = ((Returns_double) method.getAddr())();
Expand All @@ -299,7 +299,7 @@ TEST_CASE("Test binary operations") {
gen->ld_i4(value2);
gen->lshift();
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand All @@ -317,7 +317,7 @@ TEST_CASE("Test binary operations") {
gen->ld_i4(value2);
gen->rshift();
gen->ret();
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, true);
auto* jitInfo = new CorJitInfo("test_module", "test_32_int", test_module, DebugMode::Debug);
JITMethod method = gen->compile(jitInfo, g_jit, 100);
REQUIRE(method.m_addr != nullptr);
int32_t result = ((Returns_int32) method.getAddr())();
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

setup(
name='pyjion',
version='1.2.4',
version='1.2.5',
description='A JIT compiler wrapper for CPython',
author='Anthony Shaw',
author_email='[email protected]',
Expand Down
8 changes: 7 additions & 1 deletion src/pyjion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from enum import IntFlag, IntEnum
from dataclasses import dataclass

__version__ = '1.2.4'
__version__ = '1.2.5'


def _no_dotnet(path):
Expand Down Expand Up @@ -152,6 +152,12 @@ class PgcStatus(IntEnum):
Optimized = 2


class CompileMode(IntEnum):
Release = 0
Debug = 1
ReleaseWithDebugInfo = 2


@dataclass()
class JitInfo:
failed: bool
Expand Down
6 changes: 3 additions & 3 deletions src/pyjion/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, Any, Callable, Optional
from typing import Dict, Any, Callable, Optional, Union

from pyjion import JitInfo
from pyjion import JitInfo, CompileMode


def enable() -> bool:
Expand Down Expand Up @@ -40,7 +40,7 @@ def info(f: Callable) -> JitInfo:
"""
...

def config(pgc: Optional[bool], level: Optional[int], debug: Optional[bool], graph: Optional[bool], threshold: Optional[int], ) -> Dict[str, Any]:
def config(pgc: Optional[bool], level: Optional[int], debug: Optional[Union[bool, CompileMode]], graph: Optional[bool], threshold: Optional[int], ) -> Dict[str, Any]:
...

def offsets(f: Callable) -> tuple[tuple[int, int, int, int]]:
Expand Down
16 changes: 6 additions & 10 deletions src/pyjion/ipycomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@
#include "instructions.h"
#include "frame.h"

#ifdef WINDOWS
typedef SIZE_T size_t;
typedef SSIZE_T ssize_t;
#endif

#ifdef WINDOWS
typedef SIZE_T size_t;
typedef SSIZE_T ssize_t;
#endif

class InvalidLocalException : public std::exception {
public:
InvalidLocalException() : std::exception(){};
Expand Down Expand Up @@ -106,6 +96,12 @@ enum BranchType {
BranchLessThanUnsigned
};

enum DebugMode {
Release,
Debug,
ReleaseWithDebugInfo
};

class JittedCode {
public:
virtual ~JittedCode() = default;
Expand Down
25 changes: 16 additions & 9 deletions src/pyjion/jitinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class CorJitInfo : public ICorJitInfo, public JittedCode {
uint32_t m_nativeSize;
vector<SequencePoint> m_sequencePoints;
vector<CallPoint> m_callPoints;
bool m_compileDebug;
DebugMode m_compileDebug;

volatile const GSCookie s_gsCookie = 0x1234;

Expand All @@ -83,7 +83,7 @@ class CorJitInfo : public ICorJitInfo, public JittedCode {
#endif

public:
CorJitInfo(const char* moduleName, const char* methodName, UserModule* module, bool compileDebug) {
CorJitInfo(const char* moduleName, const char* methodName, UserModule* module, DebugMode compileDebug) {
m_codeAddr = m_dataAddr = nullptr;
m_methodName = methodName;
m_moduleName = moduleName;
Expand Down Expand Up @@ -1514,13 +1514,20 @@ class CorJitInfo : public ICorJitInfo, public JittedCode {
#ifdef FEATURE_SIMD
flags->Add(flags->CORJIT_FLAG_FEATURE_SIMD);
#endif
if (m_compileDebug) {
flags->Add(flags->CORJIT_FLAG_DEBUG_INFO);
flags->Add(flags->CORJIT_FLAG_DEBUG_CODE);
flags->Add(flags->CORJIT_FLAG_NO_INLINING);
flags->Add(flags->CORJIT_FLAG_MIN_OPT);
} else {
flags->Add(flags->CORJIT_FLAG_SPEED_OPT);
switch (m_compileDebug) {
case DebugMode::Debug:
flags->Add(flags->CORJIT_FLAG_DEBUG_CODE);
flags->Add(flags->CORJIT_FLAG_DEBUG_INFO);
flags->Add(flags->CORJIT_FLAG_NO_INLINING);
flags->Add(flags->CORJIT_FLAG_MIN_OPT);
break;
case DebugMode::ReleaseWithDebugInfo:
flags->Add(flags->CORJIT_FLAG_DEBUG_INFO);
case DebugMode::Release:
flags->Add(flags->CORJIT_FLAG_SPEED_OPT);
break;
default:
break;
}

#ifdef DOTNET_PGO
Expand Down
3 changes: 1 addition & 2 deletions src/pyjion/pycomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#ifndef PYJION_PYCOMP_H
#define PYJION_PYCOMP_H


#include <windows.h>

#include <share.h>
Expand Down Expand Up @@ -281,7 +280,7 @@ class PythonCompiler : public IPythonCompiler {
// This is the ADDRESS of the int f_lasti inside the PyFrameObject
Local m_lasti;
Local m_instrCount;
bool m_compileDebug;
DebugMode m_compileDebug;

public:
explicit PythonCompiler(PyCodeObject* code);
Expand Down
30 changes: 26 additions & 4 deletions src/pyjion/pyjit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,11 +659,23 @@ pyjion_config(PyObject* self, PyObject* args, PyObject* kwargs) {
debug = PyDict_GetItemString(kwargs, "debug");
if (debug != nullptr) {
// debug
if (!PyBool_Check(debug)) {
PyErr_SetString(PyExc_TypeError, "Expected bool for debug flag");
if (PyBool_Check(debug)) {
g_pyjionSettings.debug = debug == Py_True ? DebugMode::Debug : DebugMode::Release;
}
else if (PyLong_Check(debug)){
auto debugEnum = PyLong_AsLong(debug);
switch (debugEnum){
case 0: g_pyjionSettings.debug = DebugMode::Release; break;
case 1: g_pyjionSettings.debug = DebugMode::Debug; break;
case 2: g_pyjionSettings.debug = DebugMode::ReleaseWithDebugInfo; break;
default:
PyErr_SetString(PyExc_ValueError, "Debug mode not in range of 0-2");
return nullptr;
}
} else {
PyErr_SetString(PyExc_TypeError, "Expected bool or int for debug flag");
return nullptr;
}
g_pyjionSettings.debug = debug == Py_True ? true : false;
}
graph = PyDict_GetItemString(kwargs, "graph");
if (graph) {
Expand Down Expand Up @@ -699,7 +711,17 @@ pyjion_config(PyObject* self, PyObject* args, PyObject* kwargs) {
PyDict_SetItemString(res, "clrjitpath", PyUnicode_FromWideChar(g_pyjionSettings.clrjitpath, -1));
PyDict_SetItemString(res, "pgc", g_pyjionSettings.pgc ? Py_True : Py_False);
PyDict_SetItemString(res, "graph", g_pyjionSettings.graph ? Py_True : Py_False);
PyDict_SetItemString(res, "debug", g_pyjionSettings.debug ? Py_True : Py_False);
switch (g_pyjionSettings.debug){
case DebugMode::Release:
PyDict_SetItemString(res, "debug", PyLong_FromLong(0));
break;
case DebugMode::Debug:
PyDict_SetItemString(res, "debug", PyLong_FromLong(1));
break;
case DebugMode::ReleaseWithDebugInfo:
PyDict_SetItemString(res, "debug", PyLong_FromLong(2));
break;
}
PyDict_SetItemString(res, "level", PyLong_FromLong(g_pyjionSettings.optimizationLevel));
PyDict_SetItemString(res, "threshold", PyLong_FromLong(g_pyjionSettings.threshold));

Expand Down
5 changes: 3 additions & 2 deletions src/pyjion/pyjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

#include <Python.h>
#include <frameobject.h>
#include "ipycomp.h"

#include "codemodel.h"
#include "absvalue.h"
Expand Down Expand Up @@ -112,9 +113,9 @@ typedef struct PyjionSettings {
uint32_t recursionLimit = DEFAULT_RECURSION_LIMIT;
uint32_t codeObjectSizeLimit = DEFAULT_CODEOBJECT_SIZE_LIMIT;
#ifdef DEBUG
bool debug = true;
DebugMode debug = DebugMode::Debug;
#else
bool debug = false;
DebugMode debug = DebugMode::Release;
#endif
bool exceptionHandling = false;
const wchar_t* clrjitpath = L"";
Expand Down

0 comments on commit b4c5a4f

Please sign in to comment.