diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XMREngine/XMRHeapTracker.cs | 158 |
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 | ||
28 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
29 | using OpenSim.Region.ScriptEngine.XMREngine; | ||
30 | using System; | 28 | using System; |
31 | using System.Collections.Generic; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | 29 | using System.Reflection; |
34 | using System.Reflection.Emit; | 30 | using System.Reflection.Emit; |
35 | 31 | ||
@@ -43,9 +39,18 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | |||
43 | 39 | ||
44 | namespace OpenSim.Region.ScriptEngine.XMREngine | 40 | namespace 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) |