[pypy-svn] r55327 - in pypy/branch/oo-jit/pypy: jit/codegen/cli jit/codegen/cli/test translator/cli/src
antocuni at codespeak.net
antocuni at codespeak.net
Wed May 28 10:32:59 CEST 2008
Author: antocuni
Date: Wed May 28 10:32:56 2008
New Revision: 55327
Added:
pypy/branch/oo-jit/pypy/jit/codegen/cli/methodbuilder.py (contents, props changed)
Removed:
pypy/branch/oo-jit/pypy/jit/codegen/cli/dumpgenerator.py
Modified:
pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_interpreter.py
pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py
pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs
Log:
add a way to dump the generated methods into an assembly if PYPYJITLOG
is set
Added: pypy/branch/oo-jit/pypy/jit/codegen/cli/methodbuilder.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/methodbuilder.py Wed May 28 10:32:56 2008
@@ -0,0 +1,80 @@
+import os
+from pypy.translator.cli.dotnet import CLR
+from pypy.translator.cli import dotnet
+System = CLR.System
+Utils = CLR.pypy.runtime.Utils
+AutoSaveAssembly = CLR.pypy.runtime.AutoSaveAssembly
+MethodAttributes = System.Reflection.MethodAttributes
+TypeAttributes = System.Reflection.TypeAttributes
+
+class AbstractMethodBuilder:
+
+ def get_il_generator(self):
+ raise NotImplementedError
+
+ def create_delegate(self, delegatetype, consts):
+ raise NotImplementedError
+
+class DynamicMethodBuilder(AbstractMethodBuilder):
+
+ def __init__(self, name, res, args):
+ self.dynmeth = Utils.CreateDynamicMethod(name, res, args)
+
+ def get_il_generator(self):
+ return self.dynmeth.GetILGenerator()
+
+ def create_delegate(self, delegatetype, consts):
+ return self.dynmeth.CreateDelegate(delegatetype, consts)
+
+
+# the assemblyData singleton contains the informations about the
+# assembly we are currently writing to
+class AssemblyData:
+ assembly = None
+ name = None
+
+ def is_enabled(self):
+ if self.name is None:
+ name = os.environ.get('PYPYJITLOG')
+ if name is None:
+ name = ''
+ self.name = name
+ return bool(self.name)
+
+ def create(self):
+ assert self.is_enabled()
+ if self.assembly is None:
+ name = self.name
+ self.auto_save_assembly = AutoSaveAssembly.Create(name)
+ self.assembly = self.auto_save_assembly.GetAssemblyBuilder()
+ self.module = self.assembly.DefineDynamicModule(name)
+
+assemblyData = AssemblyData()
+
+
+class AssemblyMethodBuilder(AbstractMethodBuilder):
+
+ def __init__(self, name, res, args):
+ module = assemblyData.module
+ self.typeBuilder = AutoSaveAssembly.DefineType(module, name)
+ self.meth = AutoSaveAssembly.DefineMethod(self.typeBuilder,
+ "invoke", res, args)
+
+
+ def get_il_generator(self):
+ return self.meth.GetILGenerator()
+
+ def create_delegate(self, delegatetype, consts):
+ t = self.typeBuilder.CreateType()
+ methinfo = t.GetMethod("invoke")
+ return System.Delegate.CreateDelegate(delegatetype,
+ consts,
+ methinfo)
+
+def get_methodbuilder(name, res, args):
+ if assemblyData.is_enabled():
+ assemblyData.create()
+ return AssemblyMethodBuilder(name, res, args)
+ else:
+ return DynamicMethodBuilder(name, res, args)
+
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Wed May 28 10:32:56 2008
@@ -6,16 +6,13 @@
from pypy.jit.codegen.model import AbstractRGenOp, GenBuilder, GenLabel
from pypy.jit.codegen.model import GenVarOrConst, GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.cli import operation as ops
-from pypy.jit.codegen.cli.dumpgenerator import DumpGenerator
+from pypy.jit.codegen.cli.methodbuilder import get_methodbuilder
from pypy.translator.cli.dotnet import CLR, typeof, new_array, box, unbox, clidowncast, classof
from pypy.translator.cli import dotnet
System = CLR.System
-Utils = CLR.pypy.runtime.Utils
DelegateHolder = CLR.pypy.runtime.DelegateHolder
OpCodes = System.Reflection.Emit.OpCodes
-DUMP_IL = False
-
cVoid = ootype.nullruntimeclass
cInt32 = classof(System.Int32)
cBoolean = classof(System.Boolean)
@@ -325,10 +322,8 @@
def __init__(self, rgenop, name, res, args, sigtoken):
self.rgenop = rgenop
- self.meth = Utils.CreateDynamicMethod(name, res, args)
- self.il = self.meth.GetILGenerator()
- if DUMP_IL:
- self.il = DumpGenerator(self.il)
+ self.meth = get_methodbuilder(name, res, args)
+ self.il = self.meth.get_il_generator()
self.inputargs_gv = []
# we start from 1 because the 1st arg is an Object[] containing the genconsts
for i in range(1, len(args)):
@@ -416,7 +411,7 @@
for gv_const, i in self.genconsts.iteritems():
consts[i] = gv_const.getobj()
# build the delegate
- myfunc = self.meth.CreateDelegate(self.delegatetype, consts)
+ myfunc = self.meth.create_delegate(self.delegatetype, consts)
self.gv_entrypoint.holder.SetFunc(myfunc)
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_interpreter.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_interpreter.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_interpreter.py Wed May 28 10:32:56 2008
@@ -7,7 +7,6 @@
RGenOp = RCliGenOp
def _invoke(self, generated, residualargs):
-
# mono sucks; if we call the generated function directly,
# sometimes the result is wrong (e.g. test_simple_fixed
# fails). If we call it by DynamicInvoke, the result is
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Wed May 28 10:32:56 2008
@@ -103,6 +103,28 @@
annotatorpolicy=annotatorpolicy,
nowrap=False)
+ def test_dump_assembly(self):
+ import os
+ from pypy.jit.codegen.cli import methodbuilder
+
+ # clear the global state, setup env
+ methodbuilder.assemblyData = methodbuilder.AssemblyData()
+ oldenv = os.environ.get('PYPYJITLOG')
+ os.environ['PYPYJITLOG'] = 'generated.dll'
+ try:
+ self.test_adder_compile()
+ finally:
+ # reset the global state, clear env
+ methodbuilder.assemblyData = methodbuilder.AssemblyData()
+ if oldenv:
+ os.environ['PYPYJITLOG'] = oldenv
+ else:
+ del os.environ['PYPYJITLOG']
+
+ f = py.path.local('generated.dll')
+ assert f.check()
+ f.remove()
+
def test_largedummy_compile(self):
py.test.skip('it works only if we increase .maxstack')
Modified: pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original)
+++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Wed May 28 10:32:56 2008
@@ -3,6 +3,7 @@
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
+using System.Reflection;
using System.Reflection.Emit;
using pypy.runtime;
@@ -118,6 +119,54 @@
}
}
+ public class AutoSaveAssembly
+ {
+ private AssemblyBuilder assembly;
+ private string name;
+
+ public static AutoSaveAssembly Create(string name)
+ {
+ return new AutoSaveAssembly(name);
+ }
+
+ public AutoSaveAssembly(string name)
+ {
+ this.name = name;
+ AssemblyName assemblyName = new AssemblyName();
+ assemblyName.Name = name;
+ this.assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
+ }
+
+ ~AutoSaveAssembly()
+ {
+ this.assembly.Save(this.name);
+ }
+
+ public AssemblyBuilder GetAssemblyBuilder()
+ {
+ return this.assembly;
+ }
+
+ public static TypeBuilder DefineType(ModuleBuilder module, string name)
+ {
+ return module.DefineType(name,
+ TypeAttributes.Public |
+ TypeAttributes.Class);
+ }
+
+ public static MethodBuilder DefineMethod(TypeBuilder typeBuilder, string name, Type res, Type[] args)
+ {
+ return typeBuilder.DefineMethod("invoke",
+ MethodAttributes.HideBySig |
+ MethodAttributes.Static |
+ MethodAttributes.Public,
+ res,
+ args);
+ }
+
+
+ }
+
public class Utils
{
public static DynamicMethod CreateDynamicMethod(string name, Type res, Type[] args)
More information about the Pypy-commit
mailing list