diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine')
12 files changed, 312 insertions, 124 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs index 5f00f86..27fde5b 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs | |||
@@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
69 | 69 | ||
70 | public static readonly string OBJECT_CODE_MAGIC = "YObjectCode"; | 70 | public static readonly string OBJECT_CODE_MAGIC = "YObjectCode"; |
71 | // reserve positive version values for original xmr | 71 | // reserve positive version values for original xmr |
72 | public static int COMPILED_VERSION_VALUE = -1; // decremented when compiler or object file changes | 72 | public static int COMPILED_VERSION_VALUE = -2; // decremented when compiler or object file changes |
73 | 73 | ||
74 | public static readonly int CALL_FRAME_MEMUSE = 64; | 74 | public static readonly int CALL_FRAME_MEMUSE = 64; |
75 | public static readonly int STRING_LEN_TO_MEMUSE = 2; | 75 | public static readonly int STRING_LEN_TO_MEMUSE = 2; |
@@ -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/XMREngine.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs index 6acc293..e1f8c4c 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs | |||
@@ -1535,15 +1535,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
1535 | */ | 1535 | */ |
1536 | public void QueueToStart(XMRInstance inst) | 1536 | public void QueueToStart(XMRInstance inst) |
1537 | { | 1537 | { |
1538 | if(inst.m_IState != XMRInstState.ONSTARTQ) | 1538 | if (inst.m_IState != XMRInstState.ONSTARTQ) |
1539 | throw new Exception("bad state"); | 1539 | throw new Exception("bad state"); |
1540 | 1540 | ||
1541 | lock(m_StartQueue) | 1541 | lock (m_StartQueue) |
1542 | m_StartQueue.InsertTail(inst); | 1542 | m_StartQueue.InsertTail(inst); |
1543 | 1543 | ||
1544 | WakeUpOne(); | 1544 | WakeUpOne(); |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | public void QueueToYield(XMRInstance inst) | ||
1548 | { | ||
1549 | if (inst.m_IState != XMRInstState.ONYIELDQ) | ||
1550 | throw new Exception("bad state"); | ||
1551 | |||
1552 | lock (m_YieldQueue) | ||
1553 | m_YieldQueue.InsertTail(inst); | ||
1554 | |||
1555 | WakeUpOne(); | ||
1556 | } | ||
1557 | |||
1558 | public void RemoveFromSleep(XMRInstance inst) | ||
1559 | { | ||
1560 | lock (m_SleepQueue) | ||
1561 | { | ||
1562 | if (inst.m_IState != XMRInstState.ONSLEEPQ) | ||
1563 | return; | ||
1564 | |||
1565 | m_SleepQueue.Remove(inst); | ||
1566 | inst.m_IState = XMRInstState.REMDFROMSLPQ; | ||
1567 | } | ||
1568 | } | ||
1569 | |||
1547 | /** | 1570 | /** |
1548 | * @brief A script may be sleeping, in which case we wake it. | 1571 | * @brief A script may be sleeping, in which case we wake it. |
1549 | */ | 1572 | */ |
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..dec775f 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs | |||
@@ -60,7 +60,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
60 | public Delegate[][] iarSDTIntfObjs; | 60 | public Delegate[][] iarSDTIntfObjs; |
61 | 61 | ||
62 | private XMRInstAbstract instance; | 62 | private XMRInstAbstract instance; |
63 | private int heapUse; | 63 | private int arraysHeapUse; |
64 | 64 | ||
65 | private static readonly XMR_Array[] noArrays = new XMR_Array[0]; | 65 | private static readonly XMR_Array[] noArrays = new XMR_Array[0]; |
66 | private static readonly char[] noChars = new char[0]; | 66 | private static readonly char[] noChars = new char[0]; |
@@ -81,20 +81,49 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
81 | 81 | ||
82 | ~XMRInstArrays() | 82 | ~XMRInstArrays() |
83 | { | 83 | { |
84 | heapUse = instance.UpdateHeapUse(heapUse, 0); | 84 | arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, 0); |
85 | } | 85 | } |
86 | 86 | ||
87 | public void AllocVarArrays(XMRInstArSizes ars) | 87 | public void Clear() |
88 | { | ||
89 | int newheapUse = 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 | if (iarFloats != null) | ||
104 | newheapUse += iarFloats.Length * HeapTrackerObject.HT_DOUB; | ||
105 | if (iarIntegers != null) | ||
106 | newheapUse += iarIntegers.Length * HeapTrackerObject.HT_INT; | ||
107 | if (iarRotations != null) | ||
108 | newheapUse += iarRotations.Length * HeapTrackerObject.HT_ROT; | ||
109 | if (iarVectors != null) | ||
110 | newheapUse += iarVectors.Length * HeapTrackerObject.HT_VEC; | ||
111 | |||
112 | arraysHeapUse = instance.UpdateHeapUse(0, newheapUse); | ||
113 | } | ||
114 | |||
115 | public void AllocVarArrays(XMRInstArSizes ars) | ||
88 | { | 116 | { |
89 | ClearOldArrays(); | 117 | ClearOldArrays(); |
118 | int newuse = arraysHeapUse + | ||
119 | ars.iasChars* HeapTrackerObject.HT_CHAR + | ||
120 | ars.iasFloats * HeapTrackerObject.HT_SFLT + | ||
121 | ars.iasIntegers * HeapTrackerObject.HT_INT + | ||
122 | ars.iasRotations * HeapTrackerObject.HT_ROT + | ||
123 | ars.iasVectors * HeapTrackerObject.HT_VEC + | ||
124 | ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE; | ||
90 | 125 | ||
91 | heapUse = instance.UpdateHeapUse(heapUse, | 126 | arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, 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 | 127 | ||
99 | iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays; | 128 | iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays; |
100 | iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars; | 129 | iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars; |
@@ -114,9 +143,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
114 | */ | 143 | */ |
115 | public void PopList(int index, LSL_List lis) | 144 | public void PopList(int index, LSL_List lis) |
116 | { | 145 | { |
117 | LSL_List old = iarLists[index]; | 146 | int delta = HeapTrackerObject.Size(lis) - HeapTrackerObject.Size(iarLists[index]); |
118 | int newheapuse = heapUse + HeapTrackerList.Size(lis) - HeapTrackerList.Size(old); | 147 | instance.UpdateHeapUse(0, delta); |
119 | heapUse = instance.UpdateHeapUse(heapUse, newheapuse); | 148 | Interlocked.Add(ref arraysHeapUse, delta); |
120 | iarLists[index] = lis; | 149 | iarLists[index] = lis; |
121 | } | 150 | } |
122 | 151 | ||
@@ -125,9 +154,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
125 | */ | 154 | */ |
126 | public void PopObject(int index, object obj) | 155 | public void PopObject(int index, object obj) |
127 | { | 156 | { |
128 | object old = iarObjects[index]; | 157 | int delta = HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(iarObjects[index]); |
129 | int newheapuse = heapUse + HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(old); | 158 | instance.UpdateHeapUse(0, delta); |
130 | heapUse = instance.UpdateHeapUse(heapUse, newheapuse); | 159 | Interlocked.Add(ref arraysHeapUse, delta); |
131 | iarObjects[index] = obj; | 160 | iarObjects[index] = obj; |
132 | } | 161 | } |
133 | 162 | ||
@@ -136,9 +165,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
136 | */ | 165 | */ |
137 | public void PopString(int index, string str) | 166 | public void PopString(int index, string str) |
138 | { | 167 | { |
139 | string old = iarStrings[index]; | 168 | int delta = HeapTrackerString.Size(str) - HeapTrackerString.Size(iarStrings[index]); |
140 | int newheapuse = heapUse + HeapTrackerString.Size(str) - HeapTrackerString.Size(old); | 169 | instance.UpdateHeapUse(0, delta); |
141 | heapUse = instance.UpdateHeapUse(heapUse, newheapuse); | 170 | Interlocked.Add(ref arraysHeapUse, delta); |
142 | iarStrings[index] = str; | 171 | iarStrings[index] = str; |
143 | } | 172 | } |
144 | 173 | ||
@@ -181,11 +210,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
181 | iarSDTClObjs = (XMRSDTypeClObj[])recver(); | 210 | iarSDTClObjs = (XMRSDTypeClObj[])recver(); |
182 | Delegate[][] dels = (Delegate[][])recver(); | 211 | Delegate[][] dels = (Delegate[][])recver(); |
183 | 212 | ||
184 | int newheapuse = heapUse; | 213 | int newheapuse = arraysHeapUse; |
185 | 214 | ||
186 | // value types simply are the size of the value * number of values | 215 | // value types simply are the size of the value * number of values |
187 | newheapuse += chrs.Length * HeapTrackerObject.HT_CHAR; | 216 | newheapuse += chrs.Length * HeapTrackerObject.HT_CHAR; |
188 | newheapuse += flts.Length * HeapTrackerObject.HT_SFLT; | 217 | newheapuse += flts.Length * HeapTrackerObject.HT_DOUB; |
189 | newheapuse += ints.Length * HeapTrackerObject.HT_INT; | 218 | newheapuse += ints.Length * HeapTrackerObject.HT_INT; |
190 | newheapuse += rots.Length * HeapTrackerObject.HT_ROT; | 219 | newheapuse += rots.Length * HeapTrackerObject.HT_ROT; |
191 | newheapuse += vecs.Length * HeapTrackerObject.HT_VEC; | 220 | newheapuse += vecs.Length * HeapTrackerObject.HT_VEC; |
@@ -204,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
204 | // others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage | 233 | // others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage |
205 | 234 | ||
206 | // update script heap usage, throwing an exception before finalizing changes | 235 | // update script heap usage, throwing an exception before finalizing changes |
207 | heapUse = instance.UpdateHeapUse(heapUse, newheapuse); | 236 | arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, newheapuse); |
208 | 237 | ||
209 | iarChars = chrs; | 238 | iarChars = chrs; |
210 | iarFloats = flts; | 239 | iarFloats = flts; |
@@ -219,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
219 | 248 | ||
220 | private void ClearOldArrays() | 249 | private void ClearOldArrays() |
221 | { | 250 | { |
222 | int newheapuse = heapUse; | 251 | int newheapuse = arraysHeapUse; |
223 | 252 | ||
224 | iarArrays = null; | 253 | iarArrays = null; |
225 | if(iarChars != null) | 254 | if(iarChars != null) |
@@ -272,7 +301,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
272 | iarSDTIntfObjs = null; | 301 | iarSDTIntfObjs = null; |
273 | } | 302 | } |
274 | 303 | ||
275 | heapUse = instance.UpdateHeapUse(heapUse, newheapuse); | 304 | arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, newheapuse); |
276 | } | 305 | } |
277 | } | 306 | } |
278 | 307 | ||
@@ -424,31 +453,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
424 | \**************************************************/ | 453 | \**************************************************/ |
425 | 454 | ||
426 | protected int heapLimit; | 455 | protected int heapLimit; |
427 | private int heapUsed; | 456 | protected int heapUsed; |
428 | 457 | ||
429 | public virtual int UpdateHeapUse(int olduse, int newuse) | 458 | public virtual int UpdateHeapUse(int olduse, int newuse) |
430 | { | 459 | { |
431 | if(newuse <= olduse) | 460 | int newtotal = Interlocked.Add(ref heapUsed, newuse - olduse); |
432 | Interlocked.Add(ref heapUsed, newuse - olduse); | 461 | if(newtotal > heapLimit) |
433 | else | 462 | 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; | 463 | return newuse; |
453 | } | 464 | } |
454 | 465 | ||
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs index 7fc97e9..7ef1b9f 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs | |||
@@ -218,7 +218,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
218 | // do not do llResetScript on entry | 218 | // do not do llResetScript on entry |
219 | if(eventCode == ScriptEventCode.state_entry && stateCode == 0) | 219 | if(eventCode == ScriptEventCode.state_entry && stateCode == 0) |
220 | return; | 220 | return; |
221 | ClearQueueExceptLinkMessages(); | 221 | // do clear the events queue on reset |
222 | ClearQueue(); | ||
223 | //ClearQueueExceptLinkMessages(); | ||
222 | throw new ScriptResetException(); | 224 | throw new ScriptResetException(); |
223 | } | 225 | } |
224 | 226 | ||
@@ -583,6 +585,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
583 | * Tell outer layers to cancel any event triggers, like llListen(), | 585 | * Tell outer layers to cancel any event triggers, like llListen(), |
584 | * then tell outer layers which events the new state has handlers for. | 586 | * then tell outer layers which events the new state has handlers for. |
585 | * We also clear the event queue as per http://wiki.secondlife.com/wiki/State | 587 | * We also clear the event queue as per http://wiki.secondlife.com/wiki/State |
588 | * old scripts may want linked messages, but that is not as SL does now | ||
586 | */ | 589 | */ |
587 | public override void StateChange() | 590 | public override void StateChange() |
588 | { | 591 | { |
@@ -595,7 +598,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
595 | // Tell whoever cares which event handlers the new state has. | 598 | // Tell whoever cares which event handlers the new state has. |
596 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); | 599 | m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); |
597 | 600 | ||
598 | // Clear out any old events from the queue. | 601 | // keep link messages |
602 | //ClearQueueExceptLinkMessages(); | ||
603 | // or Clear out all old events from the queue. | ||
599 | lock(m_QueueLock) | 604 | lock(m_QueueLock) |
600 | { | 605 | { |
601 | m_EventQueue.Clear(); | 606 | m_EventQueue.Clear(); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs index 12feb7b..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. |
@@ -363,8 +370,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
363 | lock(m_QueueLock) | 370 | lock(m_QueueLock) |
364 | { | 371 | { |
365 | m_Running = value; | 372 | m_Running = value; |
366 | if(!value) | 373 | if(value) |
374 | { | ||
375 | if (m_IState == XMRInstState.SUSPENDED && m_SuspendCount == 0) | ||
376 | { | ||
377 | if(eventCode != ScriptEventCode.None) | ||
378 | { | ||
379 | m_IState = XMRInstState.ONYIELDQ; | ||
380 | m_Engine.QueueToYield(this); | ||
381 | } | ||
382 | else if ((m_EventQueue != null) && (m_EventQueue.First != null)) | ||
383 | { | ||
384 | m_IState = XMRInstState.ONSTARTQ; | ||
385 | m_Engine.QueueToStart(this); | ||
386 | } | ||
387 | else | ||
388 | m_IState = XMRInstState.IDLE; | ||
389 | } | ||
390 | else if(m_SuspendCount != 0) | ||
391 | m_IState = XMRInstState.IDLE; | ||
392 | } | ||
393 | else | ||
367 | { | 394 | { |
395 | if(m_IState == XMRInstState.ONSLEEPQ) | ||
396 | { | ||
397 | m_Engine.RemoveFromSleep(this); | ||
398 | m_IState = XMRInstState.SUSPENDED; | ||
399 | } | ||
368 | EmptyEventQueues(); | 400 | EmptyEventQueues(); |
369 | } | 401 | } |
370 | } | 402 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs index 1b735e3..987e22c 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs | |||
@@ -80,10 +80,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
80 | !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state | 80 | !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state |
81 | return; | 81 | return; |
82 | 82 | ||
83 | // Not running means we ignore any incoming events. | 83 | // Not running means we ignore any incoming events. |
84 | // But queue if still constructing because m_Running is not yet valid. | 84 | // But queue if still constructing because m_Running is not yet valid. |
85 | |||
85 | if(!m_Running && !construct) | 86 | if(!m_Running && !construct) |
87 | { | ||
88 | if(m_IState == XMRInstState.SUSPENDED) | ||
89 | { | ||
90 | if(evc == ScriptEventCode.state_entry && m_EventQueue.Count == 0) | ||
91 | { | ||
92 | LinkedListNode<EventParams> llns = new LinkedListNode<EventParams>(evt); | ||
93 | m_EventQueue.AddFirst(llns); | ||
94 | } | ||
95 | } | ||
86 | return; | 96 | return; |
97 | } | ||
87 | 98 | ||
88 | if(m_minEventDelay != 0) | 99 | if(m_minEventDelay != 0) |
89 | { | 100 | { |
@@ -250,13 +261,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
250 | return XMRInstState.SUSPENDED; | 261 | return XMRInstState.SUSPENDED; |
251 | } | 262 | } |
252 | 263 | ||
253 | // Make sure we aren't being migrated in or out and prevent that | 264 | // Make sure we aren't being migrated in or out and prevent that |
254 | // whilst we are in here. If migration has it locked, don't call | 265 | // whilst we are in here. If migration has it locked, don't call |
255 | // back right away, delay a bit so we don't get in infinite loop. | 266 | // back right away, delay a bit so we don't get in infinite loop. |
256 | m_RunOnePhase = "lock m_RunLock"; | 267 | m_RunOnePhase = "lock m_RunLock"; |
257 | if(!Monitor.TryEnter(m_RunLock)) | 268 | if(!Monitor.TryEnter(m_RunLock)) |
258 | { | 269 | { |
259 | m_SleepUntil = now.AddMilliseconds(3); | 270 | m_SleepUntil = now.AddMilliseconds(15); |
260 | m_RunOnePhase = "return was locked"; | 271 | m_RunOnePhase = "return was locked"; |
261 | return XMRInstState.ONSLEEPQ; | 272 | return XMRInstState.ONSLEEPQ; |
262 | } | 273 | } |
@@ -273,6 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
273 | return XMRInstState.DISPOSED; | 284 | return XMRInstState.DISPOSED; |
274 | } | 285 | } |
275 | 286 | ||
287 | if(!m_Running) | ||
288 | { | ||
289 | m_RunOnePhase = "return is not running"; | ||
290 | return XMRInstState.SUSPENDED; | ||
291 | } | ||
292 | |||
276 | // Do some more of the last event if it didn't finish. | 293 | // Do some more of the last event if it didn't finish. |
277 | if(this.eventCode != ScriptEventCode.None) | 294 | if(this.eventCode != ScriptEventCode.None) |
278 | { | 295 | { |
@@ -325,10 +342,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
325 | if(m_EventQueue.First != null) | 342 | if(m_EventQueue.First != null) |
326 | { | 343 | { |
327 | evt = m_EventQueue.First.Value; | 344 | evt = m_EventQueue.First.Value; |
328 | if(m_DetachQuantum > 0) | 345 | evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName); |
346 | if (m_DetachQuantum > 0) | ||
329 | { | 347 | { |
330 | evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), | ||
331 | evt.EventName); | ||
332 | if(evc != ScriptEventCode.attach) | 348 | if(evc != ScriptEventCode.attach) |
333 | { | 349 | { |
334 | // This is the case where the attach event | 350 | // This is the case where the attach event |
@@ -343,8 +359,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
343 | } | 359 | } |
344 | } | 360 | } |
345 | m_EventQueue.RemoveFirst(); | 361 | m_EventQueue.RemoveFirst(); |
346 | evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), | ||
347 | evt.EventName); | ||
348 | if((int)evc >= 0) | 362 | if((int)evc >= 0) |
349 | m_EventCounts[(int)evc]--; | 363 | m_EventCounts[(int)evc]--; |
350 | } | 364 | } |
@@ -730,11 +744,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
730 | case XMRInstState.DISPOSED: | 744 | case XMRInstState.DISPOSED: |
731 | return; | 745 | return; |
732 | 746 | ||
733 | // Some other thread is already resetting it, let it finish. | 747 | // Some other thread is already resetting it, let it finish. |
734 | 748 | ||
735 | case XMRInstState.RESETTING: | 749 | case XMRInstState.RESETTING: |
736 | return; | 750 | return; |
737 | 751 | ||
752 | case XMRInstState.SUSPENDED: | ||
753 | break; | ||
754 | |||
738 | default: | 755 | default: |
739 | throw new Exception("bad state"); | 756 | throw new Exception("bad state"); |
740 | } | 757 | } |
@@ -744,17 +761,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
744 | { | 761 | { |
745 | CheckRunLockInvariants(true); | 762 | CheckRunLockInvariants(true); |
746 | 763 | ||
747 | // No other thread should have transitioned it from RESETTING. | 764 | // No other thread should have transitioned it from RESETTING. |
748 | if(m_IState != XMRInstState.RESETTING) | 765 | if (m_IState != XMRInstState.SUSPENDED) |
749 | throw new Exception("bad state"); | 766 | { |
767 | if (m_IState != XMRInstState.RESETTING) | ||
768 | throw new Exception("bad state"); | ||
750 | 769 | ||
751 | // Mark it idle now so it can get queued to process new stuff. | 770 | m_IState = XMRInstState.IDLE; |
752 | m_IState = XMRInstState.IDLE; | 771 | } |
753 | 772 | ||
754 | // Reset everything and queue up default's start_entry() event. | 773 | // Reset everything and queue up default's start_entry() event. |
755 | ClearQueue(); | 774 | ClearQueue(); |
756 | ResetLocked("external Reset"); | 775 | ResetLocked("external Reset"); |
757 | 776 | ||
777 | // Mark it idle now so it can get queued to process new stuff. | ||
778 | |||
758 | CheckRunLockInvariants(true); | 779 | CheckRunLockInvariants(true); |
759 | } | 780 | } |
760 | } | 781 | } |
@@ -820,6 +841,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
820 | m_SleepUntil = DateTime.MinValue; // not doing llSleep() | 841 | m_SleepUntil = DateTime.MinValue; // not doing llSleep() |
821 | m_ResetCount++; // has been reset once more | 842 | m_ResetCount++; // has been reset once more |
822 | 843 | ||
844 | heapUsed = 0; | ||
845 | glblVars.Clear(); | ||
846 | |||
823 | // Tell next call to 'default state_entry()' to reset all global | 847 | // Tell next call to 'default state_entry()' to reset all global |
824 | // vars to their initial values. | 848 | // vars to their initial values. |
825 | doGblInit = true; | 849 | doGblInit = true; |
@@ -827,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
827 | // Throw away all its stack frames. | 851 | // Throw away all its stack frames. |
828 | // 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. |
829 | // 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. |
830 | stackFrames = null; | 854 | stackFrames = null; |
831 | 855 | ||
832 | // Set script to 'default' state and queue call to its | 856 | // Set script to 'default' state and queue call to its |
833 | // 'state_entry()' event handler. | 857 | // 'state_entry()' event handler. |
@@ -937,7 +961,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
937 | lock(m_QueueLock) | 961 | lock(m_QueueLock) |
938 | { | 962 | { |
939 | m_Suspended = false; | 963 | m_Suspended = false; |
940 | if((m_EventQueue != null) && | 964 | m_DetachQuantum = 0; |
965 | m_DetachReady.Set(); | ||
966 | if ((m_EventQueue != null) && | ||
941 | (m_EventQueue.First != null) && | 967 | (m_EventQueue.First != null) && |
942 | (m_IState == XMRInstState.IDLE)) | 968 | (m_IState == XMRInstState.IDLE)) |
943 | { | 969 | { |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs index 08c7e80..f68fd51 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs | |||
@@ -166,7 +166,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
166 | 166 | ||
167 | if(inst == null) | 167 | if(inst == null) |
168 | break; | 168 | break; |
169 | if(inst.m_IState != XMRInstState.ONSTARTQ) | 169 | if (inst.m_IState == XMRInstState.SUSPENDED) |
170 | continue; | ||
171 | if (inst.m_IState != XMRInstState.ONSTARTQ) | ||
170 | throw new Exception("bad state"); | 172 | throw new Exception("bad state"); |
171 | RunInstance(inst, tid); | 173 | RunInstance(inst, tid); |
172 | if(m_SuspendScriptThreadFlag || m_Exiting) | 174 | if(m_SuspendScriptThreadFlag || m_Exiting) |
@@ -187,7 +189,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
187 | 189 | ||
188 | if(inst != null) | 190 | if(inst != null) |
189 | { | 191 | { |
190 | if(inst.m_IState != XMRInstState.ONYIELDQ) | 192 | if (inst.m_IState == XMRInstState.SUSPENDED) |
193 | continue; | ||
194 | if (inst.m_IState != XMRInstState.ONYIELDQ) | ||
191 | throw new Exception("bad state"); | 195 | throw new Exception("bad state"); |
192 | RunInstance(inst, tid); | 196 | RunInstance(inst, tid); |
193 | continue; | 197 | continue; |