diff options
author | UbitUmarov | 2019-04-15 23:32:22 +0100 |
---|---|---|
committer | UbitUmarov | 2019-04-15 23:32:22 +0100 |
commit | a83b7a292bc3c18c9c6a1aa17cfc2622b99804c4 (patch) | |
tree | 335491b0008480e334331b9e38ccb453a189bc46 /OpenSim/Region | |
parent | update warp3d.dll (diff) | |
download | opensim-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 '')
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. |