aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XMREngine
diff options
context:
space:
mode:
authorUbitUmarov2018-02-05 12:48:07 +0000
committerUbitUmarov2018-02-05 12:48:07 +0000
commit38cd12b3cf00ac137fb474e76fa762f01dfe1283 (patch)
treec7414257d9eca01685d5918a7617085a9964745f /OpenSim/Region/ScriptEngine/XMREngine
parentfix log4net for .net4.6 (diff)
downloadopensim-SC-38cd12b3cf00ac137fb474e76fa762f01dfe1283.zip
opensim-SC-38cd12b3cf00ac137fb474e76fa762f01dfe1283.tar.gz
opensim-SC-38cd12b3cf00ac137fb474e76fa762f01dfe1283.tar.bz2
opensim-SC-38cd12b3cf00ac137fb474e76fa762f01dfe1283.tar.xz
add mrieker fresh optimization on heap tracker
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCodeGen.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCompValu.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/MMRScriptTokenize.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/MMRWebRequest.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs158
5 files changed, 151 insertions, 62 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCodeGen.cs
index 5219fa8..3b0ba66 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCodeGen.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCodeGen.cs
@@ -141,9 +141,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
141 new Type[] { typeof (LSL_Vector) }); 141 new Type[] { typeof (LSL_Vector) });
142 private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod (typeof (ScriptRestoreCatchException), "Unwrap", new Type[] { typeof (Exception) }); 142 private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod (typeof (ScriptRestoreCatchException), "Unwrap", new Type[] { typeof (Exception) });
143 private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod (typeof (ScriptThrownException), "Wrap", new Type[] { typeof (object) }); 143 private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod (typeof (ScriptThrownException), "Wrap", new Type[] { typeof (object) });
144 private static MethodInfo heapTrackerListPush = typeof (HeapTrackerList). GetMethod ("Push", new Type[0]);
145 private static MethodInfo heapTrackerObjectPush = typeof (HeapTrackerObject).GetMethod ("Push", new Type[0]);
146 private static MethodInfo heapTrackerStringPush = typeof (HeapTrackerString).GetMethod ("Push", new Type[0]);
147 144
148 private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod (typeof (ScriptCodeGen), 145 private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod (typeof (ScriptCodeGen),
149 "CatchExcToStr", 146 "CatchExcToStr",
@@ -1510,16 +1507,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1510 ilGen.Emit (curDeclFunc, OpCodes.Ldloc, lcl); 1507 ilGen.Emit (curDeclFunc, OpCodes.Ldloc, lcl);
1511 Type t = lcl.type; 1508 Type t = lcl.type;
1512 if (t == typeof (HeapTrackerList)) { 1509 if (t == typeof (HeapTrackerList)) {
1513 ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerListPush); 1510 t = HeapTrackerList.GenPush (curDeclFunc, ilGen);
1514 t = typeof (LSL_List);
1515 } 1511 }
1516 if (t == typeof (HeapTrackerObject)) { 1512 if (t == typeof (HeapTrackerObject)) {
1517 ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerObjectPush); 1513 t = HeapTrackerObject.GenPush (curDeclFunc, ilGen);
1518 t = typeof (object);
1519 } 1514 }
1520 if (t == typeof (HeapTrackerString)) { 1515 if (t == typeof(HeapTrackerString)) {
1521 ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerStringPush); 1516 t = HeapTrackerString.GenPush (curDeclFunc, ilGen);
1522 t = typeof (string);
1523 } 1517 }
1524 if (t.IsValueType) { 1518 if (t.IsValueType) {
1525 ilGen.Emit (curDeclFunc, OpCodes.Box, t); 1519 ilGen.Emit (curDeclFunc, OpCodes.Box, t);
@@ -1615,7 +1609,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1615 ilGen.Emit (curDeclFunc, OpCodes.Castclass, u); 1609 ilGen.Emit (curDeclFunc, OpCodes.Castclass, u);
1616 } 1610 }
1617 if (u != t) { 1611 if (u != t) {
1618 ilGen.Emit (curDeclFunc, OpCodes.Call, t.GetMethod ("Pop", new Type[] { u })); 1612 if (t == typeof (HeapTrackerList)) HeapTrackerList.GenPop (curDeclFunc, ilGen);
1613 if (t == typeof (HeapTrackerObject)) HeapTrackerObject.GenPop (curDeclFunc, ilGen);
1614 if (t == typeof (HeapTrackerString)) HeapTrackerString.GenPop (curDeclFunc, ilGen);
1619 } else { 1615 } else {
1620 ilGen.Emit (curDeclFunc, OpCodes.Stloc, lcl); 1616 ilGen.Emit (curDeclFunc, OpCodes.Stloc, lcl);
1621 } 1617 }
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCompValu.cs b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCompValu.cs
index fd3174d..7263274 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCompValu.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptCompValu.cs
@@ -1313,7 +1313,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1313 { 1313 {
1314 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder); 1314 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
1315 if (type.ToHeapTrackerType () != null) { 1315 if (type.ToHeapTrackerType () != null) {
1316 scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPushMeth ()); 1316 type.CallHeapTrackerPushMeth (errorAt, scg.ilGen);
1317 } 1317 }
1318 } 1318 }
1319 public override void PushRef (ScriptCodeGen scg, Token errorAt) 1319 public override void PushRef (ScriptCodeGen scg, Token errorAt)
@@ -1335,7 +1335,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1335 public override void PopPost (ScriptCodeGen scg, Token errorAt) 1335 public override void PopPost (ScriptCodeGen scg, Token errorAt)
1336 { 1336 {
1337 if (type.ToHeapTrackerType () != null) { 1337 if (type.ToHeapTrackerType () != null) {
1338 scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ()); 1338 type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
1339 } else { 1339 } else {
1340 scg.ilGen.Emit (errorAt, OpCodes.Stloc, localBuilder); 1340 scg.ilGen.Emit (errorAt, OpCodes.Stloc, localBuilder);
1341 } 1341 }
@@ -1352,7 +1352,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1352 scg.ilGen.Emit (errorAt, OpCodes.Stloc, htpop); 1352 scg.ilGen.Emit (errorAt, OpCodes.Stloc, htpop);
1353 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder); 1353 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
1354 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, htpop); 1354 scg.ilGen.Emit (errorAt, OpCodes.Ldloc, htpop);
1355 scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ()); 1355 type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
1356 } else { 1356 } else {
1357 1357
1358 /* 1358 /*
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptTokenize.cs b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptTokenize.cs
index a767dcf..1bdcc27 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptTokenize.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/MMRScriptTokenize.cs
@@ -1504,6 +1504,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1504 1504
1505 /** 1505 /**
1506 * @brief Get heap tracking type. 1506 * @brief Get heap tracking type.
1507 * null indicates there is no heap tracker for the type.
1507 */ 1508 */
1508 public virtual Type ToHeapTrackerType () 1509 public virtual Type ToHeapTrackerType ()
1509 { 1510 {
@@ -1511,15 +1512,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1511 } 1512 }
1512 public virtual ConstructorInfo GetHeapTrackerCtor () 1513 public virtual ConstructorInfo GetHeapTrackerCtor ()
1513 { 1514 {
1514 return null; 1515 throw new ApplicationException("no GetHeapTrackerCtor for " + this.GetType());
1515 } 1516 }
1516 public virtual MethodInfo GetHeapTrackerPopMeth () 1517 public virtual void CallHeapTrackerPopMeth (Token errorAt, ScriptMyILGen ilGen)
1517 { 1518 {
1518 return null; 1519 throw new ApplicationException("no CallHeapTrackerPopMeth for " + this.GetType());
1519 } 1520 }
1520 public virtual MethodInfo GetHeapTrackerPushMeth () 1521 public virtual void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen)
1521 { 1522 {
1522 return null; 1523 throw new ApplicationException("no CallHeapTrackerPushMeth for " + this.GetType());
1523 } 1524 }
1524 } 1525 }
1525 1526
@@ -1610,8 +1611,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1610 public class TokenTypeList : TokenType { 1611 public class TokenTypeList : TokenType {
1611 private static readonly FieldInfo iarListsFieldInfo = typeof (XMRInstArrays).GetField ("iarLists"); 1612 private static readonly FieldInfo iarListsFieldInfo = typeof (XMRInstArrays).GetField ("iarLists");
1612 private static readonly ConstructorInfo htListCtor = typeof (HeapTrackerList).GetConstructor (new Type [] { typeof (XMRInstAbstract) }); 1613 private static readonly ConstructorInfo htListCtor = typeof (HeapTrackerList).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
1613 private static readonly MethodInfo htListPopMeth = typeof (HeapTrackerList).GetMethod ("Pop", new Type[] { typeof (LSL_List) });
1614 private static readonly MethodInfo htListPushMeth = typeof (HeapTrackerList).GetMethod ("Push", new Type[0]);
1615 1614
1616 public TokenTypeList (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { } 1615 public TokenTypeList (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
1617 public TokenTypeList (Token original) : base (original) { } 1616 public TokenTypeList (Token original) : base (original) { }
@@ -1624,14 +1623,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1624 } 1623 }
1625 public override Type ToHeapTrackerType () { return typeof (HeapTrackerList); } 1624 public override Type ToHeapTrackerType () { return typeof (HeapTrackerList); }
1626 public override ConstructorInfo GetHeapTrackerCtor () { return htListCtor; } 1625 public override ConstructorInfo GetHeapTrackerCtor () { return htListCtor; }
1627 public override MethodInfo GetHeapTrackerPopMeth () { return htListPopMeth; } 1626 public override void CallHeapTrackerPopMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPop(errorAt, ilGen); }
1628 public override MethodInfo GetHeapTrackerPushMeth () { return htListPushMeth; } 1627 public override void CallHeapTrackerPushMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPush(errorAt, ilGen); }
1629 } 1628 }
1630 public class TokenTypeObject : TokenType { 1629 public class TokenTypeObject : TokenType {
1631 private static readonly FieldInfo iarObjectsFieldInfo = typeof (XMRInstArrays).GetField ("iarObjects"); 1630 private static readonly FieldInfo iarObjectsFieldInfo = typeof (XMRInstArrays).GetField ("iarObjects");
1632 private static readonly ConstructorInfo htObjectCtor = typeof (HeapTrackerObject).GetConstructor (new Type [] { typeof (XMRInstAbstract) }); 1631 private static readonly ConstructorInfo htObjectCtor = typeof (HeapTrackerObject).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
1633 private static readonly MethodInfo htObjectPopMeth = typeof (HeapTrackerObject).GetMethod ("Pop", new Type[] { typeof (object) });
1634 private static readonly MethodInfo htObjectPushMeth = typeof (HeapTrackerObject).GetMethod ("Push", new Type[0]);
1635 1632
1636 public TokenTypeObject (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { } 1633 public TokenTypeObject (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
1637 public TokenTypeObject (Token original) : base (original) { } 1634 public TokenTypeObject (Token original) : base (original) { }
@@ -1644,8 +1641,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1644 } 1641 }
1645 public override Type ToHeapTrackerType () { return typeof (HeapTrackerObject); } 1642 public override Type ToHeapTrackerType () { return typeof (HeapTrackerObject); }
1646 public override ConstructorInfo GetHeapTrackerCtor () { return htObjectCtor; } 1643 public override ConstructorInfo GetHeapTrackerCtor () { return htObjectCtor; }
1647 public override MethodInfo GetHeapTrackerPopMeth () { return htObjectPopMeth; } 1644 public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPop (errorAt, ilGen); }
1648 public override MethodInfo GetHeapTrackerPushMeth () { return htObjectPushMeth; } 1645 public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPush(errorAt, ilGen); }
1649 } 1646 }
1650 public class TokenTypeRot : TokenType { 1647 public class TokenTypeRot : TokenType {
1651 private static readonly FieldInfo iarRotationsFieldInfo = typeof (XMRInstArrays).GetField ("iarRotations"); 1648 private static readonly FieldInfo iarRotationsFieldInfo = typeof (XMRInstArrays).GetField ("iarRotations");
@@ -1663,8 +1660,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1663 public class TokenTypeStr : TokenType { 1660 public class TokenTypeStr : TokenType {
1664 private static readonly FieldInfo iarStringsFieldInfo = typeof (XMRInstArrays).GetField ("iarStrings"); 1661 private static readonly FieldInfo iarStringsFieldInfo = typeof (XMRInstArrays).GetField ("iarStrings");
1665 private static readonly ConstructorInfo htStringCtor = typeof (HeapTrackerString).GetConstructor (new Type [] { typeof (XMRInstAbstract) }); 1662 private static readonly ConstructorInfo htStringCtor = typeof (HeapTrackerString).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
1666 private static readonly MethodInfo htStringPopMeth = typeof (HeapTrackerString).GetMethod ("Pop", new Type[] { typeof (string) });
1667 private static readonly MethodInfo htStringPushMeth = typeof (HeapTrackerString).GetMethod ("Push", new Type[0]);
1668 1663
1669 public TokenTypeStr (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { } 1664 public TokenTypeStr (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
1670 public TokenTypeStr (Token original) : base (original) { } 1665 public TokenTypeStr (Token original) : base (original) { }
@@ -1677,8 +1672,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
1677 } 1672 }
1678 public override Type ToHeapTrackerType () { return typeof (HeapTrackerString); } 1673 public override Type ToHeapTrackerType () { return typeof (HeapTrackerString); }
1679 public override ConstructorInfo GetHeapTrackerCtor () { return htStringCtor; } 1674 public override ConstructorInfo GetHeapTrackerCtor () { return htStringCtor; }
1680 public override MethodInfo GetHeapTrackerPopMeth () { return htStringPopMeth; } 1675 public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerString.GenPop(errorAt, ilGen); }
1681 public override MethodInfo GetHeapTrackerPushMeth () { return htStringPushMeth; } 1676 public override void CallHeapTrackerPushMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerString.GenPush(errorAt, ilGen); }
1682 } 1677 }
1683 public class TokenTypeUndef : TokenType { // for the 'undef' constant, ie, null object pointer 1678 public class TokenTypeUndef : TokenType { // for the 'undef' constant, ie, null object pointer
1684 public TokenTypeUndef (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { } 1679 public TokenTypeUndef (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/MMRWebRequest.cs b/OpenSim/Region/ScriptEngine/XMREngine/MMRWebRequest.cs
index 3579332..4286586 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/MMRWebRequest.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/MMRWebRequest.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
54 } 54 }
55 bool https = uri.Scheme == "https"; 55 bool https = uri.Scheme == "https";
56 if (!https && (uri.Scheme != "http")) { 56 if (!https && (uri.Scheme != "http")) {
57 throw new WebException ("only support " + supported + ", not " + uri.Scheme); 57 throw new WebException ("only support " + supported + ", not " + uri.Scheme + " in " + requestUrl);
58 } 58 }
59 string host = uri.Host; 59 string host = uri.Host;
60 int port = uri.Port; 60 int port = uri.Port;
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
index c906f21..fdf65cf 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
+++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
@@ -25,11 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
29using OpenSim.Region.ScriptEngine.XMREngine;
30using System; 28using System;
31using System.Collections.Generic;
32using System.IO;
33using System.Reflection; 29using System.Reflection;
34using System.Reflection.Emit; 30using System.Reflection.Emit;
35 31
@@ -43,9 +39,18 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
43 39
44namespace OpenSim.Region.ScriptEngine.XMREngine 40namespace OpenSim.Region.ScriptEngine.XMREngine
45{ 41{
42 /**
43 * One instance of this class for lsl base objects that take a variable
44 * amount of memory. They are what the script-visible list,object,string
45 * variables are declared as at the CIL level. Generally, temp vars used
46 * by the compiler get their basic type (list,object,string).
47 *
48 * Note that the xmr arrays and script-defined objects have their own
49 * heap tracking built in so do not need any of this stuff.
50 */
46 public class HeapTrackerBase { 51 public class HeapTrackerBase {
47 private int usage; 52 protected int usage; // num bytes used by object
48 private XMRInstAbstract instance; 53 protected XMRInstAbstract instance; // what script it is in
49 54
50 public HeapTrackerBase (XMRInstAbstract inst) 55 public HeapTrackerBase (XMRInstAbstract inst)
51 { 56 {
@@ -57,36 +62,78 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
57 { 62 {
58 usage = instance.UpdateHeapUse (usage, 0); 63 usage = instance.UpdateHeapUse (usage, 0);
59 } 64 }
60
61 protected void NewUse (int newuse)
62 {
63 usage = instance.UpdateHeapUse (usage, newuse);
64 }
65 } 65 }
66 66
67 /**
68 * Wrapper around lists to keep track of how much memory they use.
69 */
67 public class HeapTrackerList : HeapTrackerBase { 70 public class HeapTrackerList : HeapTrackerBase {
68 private LSL_List value; 71 private static FieldInfo listValueField = typeof (HeapTrackerList).GetField ("value");
72 private static MethodInfo listSaveMethod = typeof (HeapTrackerList).GetMethod ("Save");
73
74 public LSL_List value;
69 75
70 public HeapTrackerList (XMRInstAbstract inst) : base (inst) { } 76 public HeapTrackerList (XMRInstAbstract inst) : base (inst) { }
71 77
72 public void Pop (LSL_List lis) 78 // generate CIL code to pop the value from the CIL stack
79 // input:
80 // 'this' pointer already pushed on CIL stack
81 // new value pushed on CIL stack
82 // output:
83 // 'this' pointer popped from stack
84 // new value popped from CIL stack
85 // heap usage updated
86 public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
73 { 87 {
74 NewUse (Size (lis)); 88 ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod);
75 value = lis; 89 }
90
91 // generate CIL code to push the value on the CIL stack
92 // input:
93 // 'this' pointer already pushed on CIL stack
94 // output:
95 // 'this' pointer popped from stack
96 // value pushed on CIL stack replacing 'this' pointer
97 // returns typeof value pushed on stack
98 public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
99 {
100 ilGen.Emit (errorAt, OpCodes.Ldfld, listValueField);
101 return typeof (LSL_List);
76 } 102 }
77 103
78 public LSL_List Push () 104 public void Save (LSL_List lis)
79 { 105 {
80 return value; 106 int newuse = Size (lis);
107 usage = instance.UpdateHeapUse (usage, newuse);
108 value = lis;
81 } 109 }
82 110
111 //private static int counter = 5;
83 public static int Size (LSL_List lis) 112 public static int Size (LSL_List lis)
84 { 113 {
85 return (!typeof (LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size; 114 // VS2017 in debug mode seems to have a problem running this statement quickly:
115 //SLOW: return (!typeof(LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size;
116
117 //FAST: return 33;
118 //SLOW: return (lis == null) ? 0 : 99;
119 //FAST: return ++ counter;
120
121 // VS2017 in debug mode seems content to run this quickly though:
122 try {
123 return lis.Size;
124 } catch {
125 return 0;
126 }
86 } 127 }
87 } 128 }
88 129
130 /**
131 * Wrapper around objects to keep track of how much memory they use.
132 */
89 public class HeapTrackerObject : HeapTrackerBase { 133 public class HeapTrackerObject : HeapTrackerBase {
134 private static FieldInfo objectValueField = typeof (HeapTrackerObject).GetField ("value");
135 private static MethodInfo objectSaveMethod = typeof (HeapTrackerObject).GetMethod ("Save");
136
90 public const int HT_CHAR = 2; 137 public const int HT_CHAR = 2;
91 public const int HT_DELE = 8; 138 public const int HT_DELE = 8;
92 public const int HT_DOUB = 8; 139 public const int HT_DOUB = 8;
@@ -96,21 +143,44 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
96 public const int HT_VEC = HT_DOUB * 3; 143 public const int HT_VEC = HT_DOUB * 3;
97 public const int HT_ROT = HT_DOUB * 4; 144 public const int HT_ROT = HT_DOUB * 4;
98 145
99 private object value; 146 public object value;
100 147
101 public HeapTrackerObject (XMRInstAbstract inst) : base (inst) { } 148 public HeapTrackerObject (XMRInstAbstract inst) : base (inst) { }
102 149
103 public void Pop (object obj) 150 // generate CIL code to pop the value from the CIL stack
151 // input:
152 // 'this' pointer already pushed on CIL stack
153 // new value pushed on CIL stack
154 // output:
155 // 'this' pointer popped from stack
156 // new value popped from CIL stack
157 // heap usage updated
158 public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
104 { 159 {
105 NewUse (Size (obj)); 160 ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod);
106 value = obj;
107 } 161 }
108 162
109 public object Push () 163 // generate CIL code to push the value on the CIL stack
164 // input:
165 // 'this' pointer already pushed on CIL stack
166 // output:
167 // 'this' pointer popped from stack
168 // value pushed on CIL stack replacing 'this' pointer
169 // returns typeof value pushed on stack
170 public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
110 { 171 {
111 return value; 172 ilGen.Emit (errorAt, OpCodes.Ldfld, objectValueField);
173 return typeof (object);
174 }
175
176 public void Save (object obj)
177 {
178 int newuse = Size (obj);
179 usage = instance.UpdateHeapUse (usage, newuse);
180 value = obj;
112 } 181 }
113 182
183 // public so it can be used by XMRArray
114 public static int Size (object obj) 184 public static int Size (object obj)
115 { 185 {
116 if (obj == null) return 0; 186 if (obj == null) return 0;
@@ -148,20 +218,48 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
148 } 218 }
149 } 219 }
150 220
221 /**
222 * Wrapper around strings to keep track of how much memory they use.
223 */
151 public class HeapTrackerString : HeapTrackerBase { 224 public class HeapTrackerString : HeapTrackerBase {
152 private string value; 225 private static FieldInfo stringValueField = typeof (HeapTrackerString).GetField ("value");
226 private static MethodInfo stringSaveMethod = typeof (HeapTrackerString).GetMethod ("Save");
227
228 public string value;
153 229
154 public HeapTrackerString (XMRInstAbstract inst) : base (inst) { } 230 public HeapTrackerString (XMRInstAbstract inst) : base (inst) { }
155 231
156 public void Pop (string str) 232 // generate CIL code to pop the value from the CIL stack
233 // input:
234 // 'this' pointer already pushed on CIL stack
235 // new value pushed on CIL stack
236 // output:
237 // 'this' pointer popped from stack
238 // new value popped from CIL stack
239 // heap usage updated
240 public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
157 { 241 {
158 NewUse (Size (str)); 242 ilGen.Emit (errorAt, OpCodes.Call, stringSaveMethod);
159 value = str;
160 } 243 }
161 244
162 public string Push () 245 // generate CIL code to push the value on the CIL stack
246 // input:
247 // 'this' pointer already pushed on CIL stack
248 // output:
249 // 'this' pointer popped from stack
250 // value pushed on CIL stack replacing 'this' pointer
251 // returns typeof value pushed on stack
252 public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
163 { 253 {
164 return value; 254 ilGen.Emit (errorAt, OpCodes.Ldfld, stringValueField);
255 return typeof (string);
256 }
257
258 public void Save (string str)
259 {
260 int newuse = Size (str);
261 usage = instance.UpdateHeapUse (usage, newuse);
262 value = str;
165 } 263 }
166 264
167 public static int Size (string str) 265 public static int Size (string str)