aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorUbitUmarov2019-04-15 23:32:22 +0100
committerUbitUmarov2019-04-15 23:32:22 +0100
commita83b7a292bc3c18c9c6a1aa17cfc2622b99804c4 (patch)
tree335491b0008480e334331b9e38ccb453a189bc46 /OpenSim/Region
parentupdate warp3d.dll (diff)
downloadopensim-SC-a83b7a292bc3c18c9c6a1aa17cfc2622b99804c4.zip
opensim-SC-a83b7a292bc3c18c9c6a1aa17cfc2622b99804c4.tar.gz
opensim-SC-a83b7a292bc3c18c9c6a1aa17cfc2622b99804c4.tar.bz2
opensim-SC-a83b7a292bc3c18c9c6a1aa17cfc2622b99804c4.tar.xz
mantis 8518: Yengine; we can't wait for GC (worse finalizers) to count released memory of some local variables, so add a pseudo free; fix memory account on timeslice rentry; change the folder for the debug IL files; fix memory usage on reset. This changes will only take effect on new compiles
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs48
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs112
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs59
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs5
9 files changed, 178 insertions, 80 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
index 5f00f86..e6a4224 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
@@ -197,7 +197,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
197 public CallLabel openCallLabel = null; // only one call label can be open at a time 197 public CallLabel openCallLabel = null; // only one call label can be open at a time
198 // - the call label is open from the time of CallPre() until corresponding CallPost() 198 // - the call label is open from the time of CallPre() until corresponding CallPost()
199 // - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost() 199 // - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost()
200 200 public List<ScriptMyLocal> HeapLocals = new List<ScriptMyLocal>();
201 private ScriptMyILGen _ilGen; 201 private ScriptMyILGen _ilGen;
202 public ScriptMyILGen ilGen 202 public ScriptMyILGen ilGen
203 { 203 {
@@ -1258,6 +1258,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1258 // resume at the correct spot. 1258 // resume at the correct spot.
1259 actCallLabels.Clear(); 1259 actCallLabels.Clear();
1260 allCallLabels.Clear(); 1260 allCallLabels.Clear();
1261 HeapLocals.Clear();
1261 openCallLabel = null; 1262 openCallLabel = null;
1262 1263
1263 // Alloc stack space for local vars. 1264 // Alloc stack space for local vars.
@@ -1398,19 +1399,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1398 _ilGen = collector.WriteOutAll(); 1399 _ilGen = collector.WriteOutAll();
1399 collector = null; 1400 collector = null;
1400 1401
1401 // Output code to restore stack frame from stream.
1402 // It jumps back to the call labels within the function body.
1403 List<ScriptMyLocal> activeTemps = null; 1402 List<ScriptMyLocal> activeTemps = null;
1404 if(!isTrivial) 1403 if (!isTrivial)
1405 { 1404 {
1406 // Build list of locals and temps active at all the call labels. 1405 // Build list of locals and temps active at all the call labels.
1407 activeTemps = new List<ScriptMyLocal>(); 1406 activeTemps = new List<ScriptMyLocal>();
1408 foreach(CallLabel cl in allCallLabels) 1407 foreach (CallLabel cl in allCallLabels)
1409 {
1410 foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten)
1411 { 1408 {
1412 if(!activeTemps.Contains(lcl)) 1409 foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten)
1413 { 1410 {
1411 if(!activeTemps.Contains(lcl))
1412 {
1414 activeTemps.Add(lcl); 1413 activeTemps.Add(lcl);
1415 } 1414 }
1416 } 1415 }
@@ -1452,11 +1451,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1452 } 1451 }
1453 1452
1454 // Output the 'real' return opcode. 1453 // Output the 'real' return opcode.
1454 // push return value
1455 ilGen.MarkLabel(retLabel); 1455 ilGen.MarkLabel(retLabel);
1456 if(!(curDeclFunc.retType is TokenTypeVoid)) 1456 if (!(curDeclFunc.retType is TokenTypeVoid))
1457 { 1457 {
1458 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue); 1458 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue);
1459 } 1459 }
1460
1461 // pseudo free memory usage
1462 foreach (ScriptMyLocal sml in HeapLocals)
1463 {
1464 Type t = sml.type;
1465 if (t == typeof(HeapTrackerList))
1466 {
1467 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1468 HeapTrackerList.GenFree(curDeclFunc, ilGen);
1469 }
1470 else if (t == typeof(HeapTrackerString))
1471 {
1472 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1473 HeapTrackerString.GenFree(curDeclFunc, ilGen);
1474 }
1475 else if (t == typeof(HeapTrackerObject))
1476 {
1477 ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
1478 HeapTrackerObject.GenFree(curDeclFunc, ilGen);
1479 }
1480 }
1481
1460 ilGen.Emit(curDeclFunc, OpCodes.Ret); 1482 ilGen.Emit(curDeclFunc, OpCodes.Ret);
1461 retLabel = null; 1483 retLabel = null;
1462 retValue = null; 1484 retValue = null;
@@ -1675,11 +1697,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1675 if(u != t) 1697 if(u != t)
1676 { 1698 {
1677 if(t == typeof(HeapTrackerList)) 1699 if(t == typeof(HeapTrackerList))
1678 HeapTrackerList.GenPop(curDeclFunc, ilGen); 1700 HeapTrackerList.GenRestore(curDeclFunc, ilGen);
1679 if(t == typeof(HeapTrackerObject)) 1701 if(t == typeof(HeapTrackerObject))
1680 HeapTrackerObject.GenPop(curDeclFunc, ilGen); 1702 HeapTrackerObject.GenRestore(curDeclFunc, ilGen);
1681 if(t == typeof(HeapTrackerString)) 1703 if(t == typeof(HeapTrackerString))
1682 HeapTrackerString.GenPop(curDeclFunc, ilGen); 1704 HeapTrackerString.GenRestore(curDeclFunc, ilGen);
1683 } 1705 }
1684 else 1706 else
1685 { 1707 {
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
index 75eae53..e92f429 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
@@ -2611,10 +2611,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2611 // everything required by any blocks it can branch to. 2611 // everything required by any blocks it can branch to.
2612 do 2612 do
2613 { 2613 {
2614 this.resolvedSomething = false; 2614 resolvedSomething = false;
2615 this.resolveSequence++; 2615 resolveSequence++;
2616 this.ResolveBlock((GraphNodeBlock)firstLin); 2616 ResolveBlock((GraphNodeBlock)firstLin);
2617 } while(this.resolvedSomething); 2617 } while(resolvedSomething);
2618 2618
2619 // Repeat the cutting loops as long as we keep finding stuff. 2619 // Repeat the cutting loops as long as we keep finding stuff.
2620 bool didSomething; 2620 bool didSomething;
@@ -2939,7 +2939,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2939 return; 2939 return;
2940 2940
2941 // So we don't recurse forever on a backward branch. 2941 // So we don't recurse forever on a backward branch.
2942 currentBlock.hasBeenResolved = this.resolveSequence; 2942 currentBlock.hasBeenResolved = resolveSequence;
2943 2943
2944 // Assume we haven't written any locals yet. 2944 // Assume we haven't written any locals yet.
2945 List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); 2945 List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>();
@@ -2975,7 +2975,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2975 !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) 2975 !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock))
2976 { 2976 {
2977 currentBlock.localsReadBeforeWritten.Add(readByNextBlock); 2977 currentBlock.localsReadBeforeWritten.Add(readByNextBlock);
2978 this.resolvedSomething = true; 2978 resolvedSomething = true;
2979 } 2979 }
2980 } 2980 }
2981 } 2981 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
index 675ab9a..486d822 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
@@ -1483,7 +1483,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1483 { 1483 {
1484 if(type.ToHeapTrackerType() != null) 1484 if(type.ToHeapTrackerType() != null)
1485 { 1485 {
1486 this.localBuilder = scg.ilGen.DeclareLocal(type.ToHeapTrackerType(), name); 1486 localBuilder = scg.ilGen.DeclareLocal(type.ToHeapTrackerType(), name);
1487 scg.HeapLocals.Add(localBuilder);
1487 scg.PushXMRInst(); 1488 scg.PushXMRInst();
1488 scg.ilGen.Emit(type, OpCodes.Newobj, type.GetHeapTrackerCtor()); 1489 scg.ilGen.Emit(type, OpCodes.Newobj, type.GetHeapTrackerCtor());
1489 scg.ilGen.Emit(type, OpCodes.Stloc, localBuilder); 1490 scg.ilGen.Emit(type, OpCodes.Stloc, localBuilder);
@@ -1547,6 +1548,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1547 scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder); 1548 scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder);
1548 scg.ilGen.Emit(errorAt, OpCodes.Ldloc, htpop); 1549 scg.ilGen.Emit(errorAt, OpCodes.Ldloc, htpop);
1549 type.CallHeapTrackerPopMeth(errorAt, scg.ilGen); 1550 type.CallHeapTrackerPopMeth(errorAt, scg.ilGen);
1551 scg.HeapLocals.Add(htpop);
1550 } 1552 }
1551 else 1553 else
1552 { 1554 {
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs
index f37efd4..8e15402 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs
@@ -130,7 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
130 // Since we just wrote the .xmrobj file, maybe save disassembly. 130 // Since we just wrote the .xmrobj file, maybe save disassembly.
131 if (m_Engine.m_ScriptDebugSaveIL) 131 if (m_Engine.m_ScriptDebugSaveIL)
132 { 132 {
133 string asmFileName = GetScriptFileName (m_ScriptObjCodeKey + ".yasm"); 133 string asmFileName = GetScriptILFileName(m_ScriptObjCodeKey + ".yasm");
134// m_log.Debug ("[YEngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName); 134// m_log.Debug ("[YEngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName);
135 asmFileWriter = File.CreateText (asmFileName); 135 asmFileWriter = File.CreateText (asmFileName);
136 } 136 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
index 3d0525b..930a8d6 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
@@ -125,7 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
125 125
126 // Save new value in array, replacing one of same key if there. 126 // Save new value in array, replacing one of same key if there.
127 // null means remove the value, ie, script did array[key] = undef. 127 // null means remove the value, ie, script did array[key] = undef.
128 if(value != null) 128 if (value != null)
129 { 129 {
130 dnary[key] = value; 130 dnary[key] = value;
131 } 131 }
@@ -285,10 +285,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
285 public void RecvArrayObj(RecvArrayObjDelegate recvObj) 285 public void RecvArrayObj(RecvArrayObjDelegate recvObj)
286 { 286 {
287 heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); 287 heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP);
288 288 // Cause any enumeration to refill the array from the sorted dictionary.
289 // Cause any enumeration to refill the array from the sorted dictionary. 289 // Since it is a sorted dictionary, any enumerations will be in the same
290 // Since it is a sorted dictionary, any enumerations will be in the same 290 // order as on the sending side.
291 // order as on the sending side.
292 arrayValid = 0; 291 arrayValid = 0;
293 enumrValid = false; 292 enumrValid = false;
294 293
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs
index 33eb8bf..8b67349 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs
@@ -58,11 +58,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
58 if(inst == null) 58 if(inst == null)
59 throw new ArgumentNullException("inst"); 59 throw new ArgumentNullException("inst");
60 instance = inst; 60 instance = inst;
61 } 61 usage = 0;
62
63 ~HeapTrackerBase()
64 {
65 usage = instance.UpdateHeapUse(usage, 0);
66 } 62 }
67 } 63 }
68 64
@@ -73,24 +69,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
73 { 69 {
74 private static FieldInfo listValueField = typeof(HeapTrackerList).GetField("value"); 70 private static FieldInfo listValueField = typeof(HeapTrackerList).GetField("value");
75 private static MethodInfo listSaveMethod = typeof(HeapTrackerList).GetMethod("Save"); 71 private static MethodInfo listSaveMethod = typeof(HeapTrackerList).GetMethod("Save");
72 private static MethodInfo listRestoreMethod = typeof(HeapTrackerList).GetMethod("Restore");
73 private static MethodInfo listFreeMethod = typeof(HeapTrackerList).GetMethod("Free");
76 74
77 public LSL_List value; 75 public LSL_List value;
78 76
79 public HeapTrackerList(XMRInstAbstract inst) : base(inst) { } 77 public HeapTrackerList(XMRInstAbstract inst) : base(inst) {}
80 78
81 // generate CIL code to pop the value from the CIL stack 79 // generate CIL code to pop the value ie store in value
82 // input: 80 // input:
83 // 'this' pointer already pushed on CIL stack 81 // 'this' pointer already pushed on CIL stack
84 // new value pushed on CIL stack 82 // new value
85 // output: 83 // output:
86 // 'this' pointer popped from stack
87 // new value popped from CIL stack
88 // heap usage updated
89 public static void GenPop(Token errorAt, ScriptMyILGen ilGen) 84 public static void GenPop(Token errorAt, ScriptMyILGen ilGen)
90 { 85 {
91 ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod); 86 ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod);
92 } 87 }
93 88
89 public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
90 {
91 ilGen.Emit(errorAt, OpCodes.Call, listRestoreMethod);
92 }
93
94 public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
95 {
96 ilGen.Emit(errorAt, OpCodes.Call, listFreeMethod);
97 }
98
94 // generate CIL code to push the value on the CIL stack 99 // generate CIL code to push the value on the CIL stack
95 // input: 100 // input:
96 // 'this' pointer already pushed on CIL stack 101 // 'this' pointer already pushed on CIL stack
@@ -106,23 +111,32 @@ namespace OpenSim.Region.ScriptEngine.Yengine
106 111
107 public void Save(LSL_List lis) 112 public void Save(LSL_List lis)
108 { 113 {
109 int newuse = Size(lis); 114 if (lis == null)
110 usage = instance.UpdateHeapUse(usage, newuse); 115 usage = instance.UpdateHeapUse(usage, 0);
116 else
117 usage = instance.UpdateHeapUse(usage, Size(lis));
111 value = lis; 118 value = lis;
112 } 119 }
113 120
114 //private static int counter = 5; 121 public void Restore(LSL_List lis)
115 public static int Size(LSL_List lis)
116 { 122 {
117 // VS2017 in debug mode seems to have a problem running this statement quickly: 123 value = lis;
118 //SLOW: return (!typeof(LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size; 124 if (lis != null)
119 125 usage = Size(lis);
120 //FAST: return 33; 126 else
121 //SLOW: return (lis == null) ? 0 : 99; 127 usage = 0;
122 //FAST: return ++ counter; 128 }
123 129
124 // VS2017 in debug mode seems content to run this quickly though: 130 public void Free()
131 {
132 usage = instance.UpdateHeapUse(usage, 0);
133 value = null;
134 instance = null;
135 }
125 136
137 //private static int counter = 5;
138 public static int Size(LSL_List lis)
139 {
126 try 140 try
127 { 141 {
128 return lis.Size; 142 return lis.Size;
@@ -141,6 +155,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
141 { 155 {
142 private static FieldInfo objectValueField = typeof(HeapTrackerObject).GetField("value"); 156 private static FieldInfo objectValueField = typeof(HeapTrackerObject).GetField("value");
143 private static MethodInfo objectSaveMethod = typeof(HeapTrackerObject).GetMethod("Save"); 157 private static MethodInfo objectSaveMethod = typeof(HeapTrackerObject).GetMethod("Save");
158 private static MethodInfo objectRestoreMethod = typeof(HeapTrackerObject).GetMethod("Restore");
159 private static MethodInfo objectFreeMethod = typeof(HeapTrackerObject).GetMethod("Free");
144 160
145 public const int HT_CHAR = 2; 161 public const int HT_CHAR = 2;
146 public const int HT_DELE = 8; 162 public const int HT_DELE = 8;
@@ -168,6 +184,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
168 ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod); 184 ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod);
169 } 185 }
170 186
187 public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
188 {
189 ilGen.Emit(errorAt, OpCodes.Call, objectRestoreMethod);
190 }
191
192 public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
193 {
194 ilGen.Emit(errorAt, OpCodes.Call, objectFreeMethod);
195 }
196
171 // generate CIL code to push the value on the CIL stack 197 // generate CIL code to push the value on the CIL stack
172 // input: 198 // input:
173 // 'this' pointer already pushed on CIL stack 199 // 'this' pointer already pushed on CIL stack
@@ -188,6 +214,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
188 value = obj; 214 value = obj;
189 } 215 }
190 216
217 public void Restore(object obj)
218 {
219 value = obj;
220 usage = Size(obj);
221 }
222
223 public void Free()
224 {
225 usage = instance.UpdateHeapUse(usage, 0);
226 value = null;
227 instance = null;
228 }
229
191 // public so it can be used by XMRArray 230 // public so it can be used by XMRArray
192 public static int Size(object obj) 231 public static int Size(object obj)
193 { 232 {
@@ -204,8 +243,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
204 return HT_SING; 243 return HT_SING;
205 if(obj is int) 244 if(obj is int)
206 return HT_INT; 245 return HT_INT;
207 if(obj is LSL_Float) 246 if(obj is LSL_Float) // lsl floats are stupid doubles
208 return HT_SFLT; 247 return HT_DOUB;
209 if(obj is LSL_Integer) 248 if(obj is LSL_Integer)
210 return HT_INT; 249 return HT_INT;
211 if(obj is LSL_List) 250 if(obj is LSL_List)
@@ -252,7 +291,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
252 public class HeapTrackerString: HeapTrackerBase 291 public class HeapTrackerString: HeapTrackerBase
253 { 292 {
254 private static FieldInfo stringValueField = typeof(HeapTrackerString).GetField("value"); 293 private static FieldInfo stringValueField = typeof(HeapTrackerString).GetField("value");
294 private static MethodInfo stringRestoreMethod = typeof(HeapTrackerString).GetMethod("Restore");
255 private static MethodInfo stringSaveMethod = typeof(HeapTrackerString).GetMethod("Save"); 295 private static MethodInfo stringSaveMethod = typeof(HeapTrackerString).GetMethod("Save");
296 private static MethodInfo stringFreeMethod = typeof(HeapTrackerString).GetMethod("Free");
256 297
257 public string value; 298 public string value;
258 299
@@ -271,6 +312,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
271 ilGen.Emit(errorAt, OpCodes.Call, stringSaveMethod); 312 ilGen.Emit(errorAt, OpCodes.Call, stringSaveMethod);
272 } 313 }
273 314
315 public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
316 {
317 ilGen.Emit(errorAt, OpCodes.Call, stringRestoreMethod);
318 }
319
320 public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
321 {
322 ilGen.Emit(errorAt, OpCodes.Call, stringFreeMethod);
323 }
324
274 // generate CIL code to push the value on the CIL stack 325 // generate CIL code to push the value on the CIL stack
275 // input: 326 // input:
276 // 'this' pointer already pushed on CIL stack 327 // 'this' pointer already pushed on CIL stack
@@ -291,6 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
291 value = str; 342 value = str;
292 } 343 }
293 344
345 public void Restore(string str)
346 {
347 value = str;
348 usage = Size(str);
349 }
350
351 public void Free()
352 {
353 usage = instance.UpdateHeapUse(usage, 0);
354 value = null;
355 instance = null;
356 }
357
294 public static int Size(string str) 358 public static int Size(string str)
295 { 359 {
296 return (str == null) ? 0 : str.Length * HeapTrackerObject.HT_CHAR; 360 return (str == null) ? 0 : str.Length * HeapTrackerObject.HT_CHAR;
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
index a440cf3..f21116e 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
@@ -84,17 +84,36 @@ namespace OpenSim.Region.ScriptEngine.Yengine
84 heapUse = instance.UpdateHeapUse(heapUse, 0); 84 heapUse = instance.UpdateHeapUse(heapUse, 0);
85 } 85 }
86 86
87 public void Clear()
88 {
89 heapUse = 0;
90 if(iarArrays != null)
91 {
92 foreach(XMR_Array xa in iarArrays)
93 xa.__pub_clear();
94 }
95 if(iarChars != null)
96 iarChars = new char[iarChars.Length];
97 if (iarLists != null)
98 iarLists = new LSL_List[iarLists.Length];
99 if (iarObjects != null)
100 iarObjects = new object[iarObjects.Length];
101 if(iarStrings != null)
102 iarStrings = new string[iarStrings.Length];
103 }
104
87 public void AllocVarArrays(XMRInstArSizes ars) 105 public void AllocVarArrays(XMRInstArSizes ars)
88 { 106 {
89 ClearOldArrays(); 107 ClearOldArrays();
108 int newuse = heapUse +
109 ars.iasChars* HeapTrackerObject.HT_CHAR +
110 ars.iasFloats * HeapTrackerObject.HT_SFLT +
111 ars.iasIntegers * HeapTrackerObject.HT_INT +
112 ars.iasRotations * HeapTrackerObject.HT_ROT +
113 ars.iasVectors * HeapTrackerObject.HT_VEC +
114 ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE;
90 115
91 heapUse = instance.UpdateHeapUse(heapUse, 116 heapUse = instance.UpdateHeapUse(heapUse, newuse);
92 ars.iasChars * HeapTrackerObject.HT_CHAR +
93 ars.iasFloats * HeapTrackerObject.HT_SFLT +
94 ars.iasIntegers * HeapTrackerObject.HT_INT +
95 ars.iasRotations * HeapTrackerObject.HT_ROT +
96 ars.iasVectors * HeapTrackerObject.HT_VEC +
97 ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE);
98 117
99 iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays; 118 iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays;
100 iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars; 119 iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars;
@@ -424,31 +443,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
424 \**************************************************/ 443 \**************************************************/
425 444
426 protected int heapLimit; 445 protected int heapLimit;
427 private int heapUsed; 446 protected int heapUsed;
428 447
429 public virtual int UpdateHeapUse(int olduse, int newuse) 448 public virtual int UpdateHeapUse(int olduse, int newuse)
430 { 449 {
431 if(newuse <= olduse) 450 int newtotal = Interlocked.Add(ref heapUsed, newuse - olduse);
432 Interlocked.Add(ref heapUsed, newuse - olduse); 451 if(newtotal > heapLimit)
433 else 452 throw new OutOfHeapException(newtotal + olduse - newuse, newtotal, heapLimit);
434 {
435 int newtotal, oldtotal;
436 do
437 {
438 oldtotal = Interlocked.Add(ref heapUsed, 0);
439 newtotal = oldtotal + newuse - olduse;
440 if(newtotal > heapLimit)
441 {
442 // System.GC.Collect ();
443 // System.GC.WaitForPendingFinalizers ();
444 oldtotal = Interlocked.Add(ref heapUsed, 0);
445 newtotal = oldtotal + newuse - olduse;
446 if(newtotal > heapLimit)
447 throw new OutOfHeapException(oldtotal, newtotal, heapLimit);
448 }
449 } while(Interlocked.CompareExchange(ref heapUsed, newtotal, oldtotal) != oldtotal);
450 }
451
452 return newuse; 453 return newuse;
453 } 454 }
454 455
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
index ff8dae5..e97c71e 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
@@ -236,6 +236,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
236 return GetScriptFileName(m_ScriptBasePath, filename); 236 return GetScriptFileName(m_ScriptBasePath, filename);
237 } 237 }
238 238
239 public string GetScriptILFileName(string filename)
240 {
241 string path = Path.Combine(m_ScriptBasePath, "DebugIL");
242 Directory.CreateDirectory(path);
243 return Path.Combine(path, filename);
244 }
245
239 public static string GetScriptFileName(string scriptBasePath, string filename) 246 public static string GetScriptFileName(string scriptBasePath, string filename)
240 { 247 {
241 // Get old path, ie, all files lumped in a single huge directory. 248 // Get old path, ie, all files lumped in a single huge directory.
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
index 4f94c23..987e22c 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
@@ -841,6 +841,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
841 m_SleepUntil = DateTime.MinValue; // not doing llSleep() 841 m_SleepUntil = DateTime.MinValue; // not doing llSleep()
842 m_ResetCount++; // has been reset once more 842 m_ResetCount++; // has been reset once more
843 843
844 heapUsed = 0;
845 glblVars.Clear();
846
844 // Tell next call to 'default state_entry()' to reset all global 847 // Tell next call to 'default state_entry()' to reset all global
845 // vars to their initial values. 848 // vars to their initial values.
846 doGblInit = true; 849 doGblInit = true;
@@ -848,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
848 // Throw away all its stack frames. 851 // Throw away all its stack frames.
849 // If the script is resetting itself, there shouldn't be any stack frames. 852 // If the script is resetting itself, there shouldn't be any stack frames.
850 // If the script is being reset by something else, we throw them away cuz we want to start from the beginning of an event handler. 853 // If the script is being reset by something else, we throw them away cuz we want to start from the beginning of an event handler.
851 stackFrames = null; 854 stackFrames = null;
852 855
853 // Set script to 'default' state and queue call to its 856 // Set script to 'default' state and queue call to its
854 // 'state_entry()' event handler. 857 // 'state_entry()' event handler.