Permalink
Browse files

Implement workaround for DefineInitializedData/dynamic assembly/sgen …

…incompatibility
  • Loading branch information...
1 parent e41e2cf commit 3cbbfcd4f37ab7f0600518718c27a162edb51173 @sorear committed May 29, 2011
Showing with 73 additions and 31 deletions.
  1. +16 −3 lib/CLRBackend.cs
  2. +36 −22 lib/Kernel.cs
  3. +10 −0 perf/perf.TODO
  4. +11 −6 perf/std-20110528.pl6
View
@@ -1141,6 +1141,8 @@ class CgContext {
public void EmitDataArray(Type ty, int ct, byte[] vec) {
EmitInt(ct);
+ if (CLRBackend.Current.dynamic)
+ throw new Exception("cannot EmitDataArray with dynamic assembly");
// the mono JIT checks for this exact sequence
il.Emit(OpCodes.Newarr, ty);
if (vec.Length != 0) {
@@ -4253,6 +4255,7 @@ public class CLRBackend {
internal AssemblyBuilder ab;
internal ModuleBuilder mob;
internal TypeBuilder tb;
+ internal bool dynamic;
[ThreadStatic] internal static CLRBackend Current;
@@ -4270,6 +4273,7 @@ public class CLRBackend {
Environment.GetEnvironmentVariable("NIECZA_CODEGEN_UNVERIFIABLE") != null ? false : true;
CLRBackend(string dir, string mobname, string filename) {
+ dynamic = (filename == null);
AssemblyName an = new AssemblyName(mobname);
this.dir = dir;
ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
@@ -4525,14 +4529,23 @@ public class CLRBackend {
unit_load.Add(unit.EmitVarConsts());
unit_load.Add(unit.EmitStringListConsts());
+ CpsOp mkheap;
+ // https://bugzilla.novell.com/show_bug.cgi?id=696817
+ if (CLRBackend.Current.dynamic) {
+ mkheap = CpsOp.Null(typeof(byte[]));
+ RuntimeUnit.RegisterHeap(unit.name, unit.thaw_heap.ToArray());
+ } else {
+ mkheap = CpsOp.NewByteArray(typeof(byte), unit.thaw_heap.ToArray());
+ }
+
unit_load[0] = CpsOp.SetSField(unit.rtunit, CpsOp.ConstructorCall(
- Tokens.RuntimeUnit.GetConstructor(new Type[] { typeof(Type), typeof(byte[]), typeof(RuntimeUnit[]), typeof(int) }),
+ Tokens.RuntimeUnit.GetConstructor(new Type[] { typeof(string), typeof(Type), typeof(byte[]), typeof(RuntimeUnit[]), typeof(int) }),
+ CpsOp.StringLiteral(unit.name),
CpsOp.TypeLiteral(tb),
- CpsOp.NewByteArray(typeof(byte), unit.thaw_heap.ToArray()),
+ mkheap,
CpsOp.NewArray(Tokens.RuntimeUnit, tdep_rtu.ToArray()),
CpsOp.IntLiteral(unit.xref.Length)));
-
thaw[unit_slot] = CpsOp.Sequence(unit_load.ToArray());
CpsBuilder boot = new CpsBuilder(this, "BOOT", true);
View
@@ -188,6 +188,9 @@ public sealed class BValue {
}
public sealed class RuntimeUnit {
+ static Dictionary<string, byte[]> heapreg;
+
+ public string name;
public Type type;
public byte[] heap;
public RuntimeUnit[] depends;
@@ -196,36 +199,47 @@ public sealed class RuntimeUnit {
public object[] xref;
public static bool TraceLoad = Environment.GetEnvironmentVariable("NIECZA_TRACE_LOAD") != null;
- public RuntimeUnit(Type type, byte[] heap, RuntimeUnit[] depends,
- int nx) {
+ public static void HexDump(byte[] heap) {
+ for (int offs = 0; offs < heap.Length; offs += 16) {
+ Console.Write("{0:X6} ", offs);
+ int len = heap.Length - offs;
+ if (len > 16) len = 16;
+ for (int col = 0; col < 16; col++) {
+ if (col >= len)
+ Console.Write(" ");
+ else
+ Console.Write("{0:X2} ", heap[offs+col]);
+ if (col == 7)
+ Console.Write(" ");
+ }
+ Console.Write(" |");
+ for (int col = 0; col < len; col++)
+ Console.Write(
+ (heap[offs+col] < 32 || heap[offs+col] > 126)
+ ? '.' : (char)heap[offs+col]);
+ Console.WriteLine("|");
+ }
+ }
+
+ public static void RegisterHeap(string name, byte[] heap) {
+ if (heapreg == null)
+ heapreg = new Dictionary<string, byte[]>();
+ heapreg[name] = heap;
+ }
+
+ public RuntimeUnit(string name, Type type, byte[] heap,
+ RuntimeUnit[] depends, int nx) {
+ this.name = name;
this.type = type;
- this.heap = heap;
+ this.heap = (heap == null ? heapreg[name] : heap);
this.depends = depends;
this.xref = new object[nx];
this.methods = new DynBlockDelegate[nx];
this.meta_fields = new FieldInfo[nx*2];
if (TraceLoad) {
Console.WriteLine("Setting up unit {0}", type.Name);
- for (int offs = 0; offs < heap.Length; offs += 16) {
- Console.Write("{0:X6} ", offs);
- int len = heap.Length - offs;
- if (len > 16) len = 16;
- for (int col = 0; col < 16; col++) {
- if (col >= len)
- Console.Write(" ");
- else
- Console.Write("{0:X2} ", heap[offs+col]);
- if (col == 7)
- Console.Write(" ");
- }
- Console.Write(" |");
- for (int col = 0; col < len; col++)
- Console.Write(
- (heap[offs+col] < 32 || heap[offs+col] > 126)
- ? '.' : (char)heap[offs+col]);
- Console.WriteLine("|");
- }
+ HexDump(heap);
}
uint d = 0;
View
@@ -10,3 +10,13 @@ Experiment with making P6any: Variable
Make LISTSTORE off-loop?
push, shift, etc off-loop?
+
+Avoid calling a function for trivial attribute (or parameter) defaults
+
+Improve isa, somehow.
+
+Subquadratic nibbling.
+
+81537 Mu.new attr: 14093 RxOp.zyg,
+
+Missing accelerators: Bool.Numeric, Hash.delete-key, Any.delete-key
View
@@ -25,13 +25,18 @@ bench "nulling test", 1000000, sub () {};
bench "iterate empty list", 1000000, sub () { for @l { } };
}
-my ($x, $y);
-bench "Parcel.LISTSTORE", 1000000, sub () { ($x,$y) = ($y,$x) };
-{
- "foo" ~~ /f(.)/;
- bench '$<x>', 1000000, sub () { $0 };
-}
+my %h; my $x;
+bench "Hash.delete-key", 1000000, sub () { %h<foo>:delete };
+bench "Any.delete-key", 1000000, sub () { $x<foo>:delete };
+bench "Bool.Numeric", 1000000, sub () { +True };
+# my ($x, $y);
+# bench "Parcel.LISTSTORE", 1000000, sub () { ($x,$y) = ($y,$x) };
+# {
+# "foo" ~~ /f(.)/;
+# bench '$<x>', 1000000, sub () { $0 };
+# }
+#
# my $str = "0";
# $str ~= $str for ^18;
# say $str.chars;

0 comments on commit 3cbbfcd

Please sign in to comment.