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.cs271
1 files changed, 271 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs b/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
new file mode 100644
index 0000000..0e7d303
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs
@@ -0,0 +1,271 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Reflection.Emit;
31
32using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
33using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
34using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
35using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
36using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
37using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
38using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
39
40namespace OpenSim.Region.ScriptEngine.XMREngine
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 */
51 public class HeapTrackerBase {
52 protected int usage; // num bytes used by object
53 protected XMRInstAbstract instance; // what script it is in
54
55 public HeapTrackerBase (XMRInstAbstract inst)
56 {
57 if (inst == null) throw new ArgumentNullException ("inst");
58 instance = inst;
59 }
60
61 ~HeapTrackerBase ()
62 {
63 usage = instance.UpdateHeapUse (usage, 0);
64 }
65 }
66
67 /**
68 * Wrapper around lists to keep track of how much memory they use.
69 */
70 public class HeapTrackerList : HeapTrackerBase {
71 private static FieldInfo listValueField = typeof (HeapTrackerList).GetField ("value");
72 private static MethodInfo listSaveMethod = typeof (HeapTrackerList).GetMethod ("Save");
73
74 public LSL_List value;
75
76 public HeapTrackerList (XMRInstAbstract inst) : base (inst) { }
77
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)
87 {
88 ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod);
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);
102 }
103
104 public void Save (LSL_List lis)
105 {
106 int newuse = Size (lis);
107 usage = instance.UpdateHeapUse (usage, newuse);
108 value = lis;
109 }
110
111 //private static int counter = 5;
112 public static int Size (LSL_List lis)
113 {
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
123 try {
124 return lis.Size;
125 } catch {
126 return 0;
127 }
128 }
129 }
130
131 /**
132 * Wrapper around objects to keep track of how much memory they use.
133 */
134 public class HeapTrackerObject : HeapTrackerBase {
135 private static FieldInfo objectValueField = typeof (HeapTrackerObject).GetField ("value");
136 private static MethodInfo objectSaveMethod = typeof (HeapTrackerObject).GetMethod ("Save");
137
138 public const int HT_CHAR = 2;
139 public const int HT_DELE = 8;
140 public const int HT_DOUB = 8;
141 public const int HT_SING = 4;
142 public const int HT_SFLT = 4;
143 public const int HT_INT = 4;
144 public const int HT_VEC = HT_DOUB * 3;
145 public const int HT_ROT = HT_DOUB * 4;
146
147 public object value;
148
149 public HeapTrackerObject (XMRInstAbstract inst) : base (inst) { }
150
151 // generate CIL code to pop the value from the CIL stack
152 // input:
153 // 'this' pointer already pushed on CIL stack
154 // new value pushed on CIL stack
155 // output:
156 // 'this' pointer popped from stack
157 // new value popped from CIL stack
158 // heap usage updated
159 public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
160 {
161 ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod);
162 }
163
164 // generate CIL code to push the value on the CIL stack
165 // input:
166 // 'this' pointer already pushed on CIL stack
167 // output:
168 // 'this' pointer popped from stack
169 // value pushed on CIL stack replacing 'this' pointer
170 // returns typeof value pushed on stack
171 public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
172 {
173 ilGen.Emit (errorAt, OpCodes.Ldfld, objectValueField);
174 return typeof (object);
175 }
176
177 public void Save (object obj)
178 {
179 int newuse = Size (obj);
180 usage = instance.UpdateHeapUse (usage, newuse);
181 value = obj;
182 }
183
184 // public so it can be used by XMRArray
185 public static int Size (object obj)
186 {
187 if (obj == null) return 0;
188
189 if (obj is char) return HT_CHAR;
190 if (obj is Delegate) return HT_DELE;
191 if (obj is double) return HT_DOUB;
192 if (obj is float) return HT_SING;
193 if (obj is int) return HT_INT;
194 if (obj is LSL_Float) return HT_SFLT;
195 if (obj is LSL_Integer) return HT_INT;
196 if (obj is LSL_List) return ((LSL_List)obj).Size;
197 if (obj is LSL_Rotation) return HT_ROT;
198 if (obj is LSL_String) return ((LSL_String)obj).m_string.Length * HT_CHAR;
199 if (obj is LSL_Vector) return HT_VEC;
200 if (obj is string) return ((string)obj).Length * HT_CHAR;
201 if (obj is XMR_Array) return 0;
202 if (obj is XMRArrayListKey) return ((XMRArrayListKey)obj).Size;
203 if (obj is XMRSDTypeClObj) return 0;
204
205 if (obj is Array) {
206 Array ar = (Array)obj;
207 int len = ar.Length;
208 if (len == 0) return 0;
209 Type et = ar.GetType ().GetElementType ();
210 if (et.IsValueType) return Size (ar.GetValue (0)) * len;
211 int size = 0;
212 for (int i = 0; i < len; i ++) {
213 size += Size (ar.GetValue (i));
214 }
215 return size;
216 }
217
218 throw new Exception ("unknown size of type " + obj.GetType ().Name);
219 }
220 }
221
222 /**
223 * Wrapper around strings to keep track of how much memory they use.
224 */
225 public class HeapTrackerString : HeapTrackerBase {
226 private static FieldInfo stringValueField = typeof (HeapTrackerString).GetField ("value");
227 private static MethodInfo stringSaveMethod = typeof (HeapTrackerString).GetMethod ("Save");
228
229 public string value;
230
231 public HeapTrackerString (XMRInstAbstract inst) : base (inst) { }
232
233 // generate CIL code to pop the value from the CIL stack
234 // input:
235 // 'this' pointer already pushed on CIL stack
236 // new value pushed on CIL stack
237 // output:
238 // 'this' pointer popped from stack
239 // new value popped from CIL stack
240 // heap usage updated
241 public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
242 {
243 ilGen.Emit (errorAt, OpCodes.Call, stringSaveMethod);
244 }
245
246 // generate CIL code to push the value on the CIL stack
247 // input:
248 // 'this' pointer already pushed on CIL stack
249 // output:
250 // 'this' pointer popped from stack
251 // value pushed on CIL stack replacing 'this' pointer
252 // returns typeof value pushed on stack
253 public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
254 {
255 ilGen.Emit (errorAt, OpCodes.Ldfld, stringValueField);
256 return typeof (string);
257 }
258
259 public void Save (string str)
260 {
261 int newuse = Size (str);
262 usage = instance.UpdateHeapUse (usage, newuse);
263 value = str;
264 }
265
266 public static int Size (string str)
267 {
268 return (str == null) ? 0 : str.Length * HeapTrackerObject.HT_CHAR;
269 }
270 }
271}