aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs158
1 files changed, 128 insertions, 30 deletions
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)