aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs50
-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/XMREngine.cs27
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs112
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs103
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs34
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs66
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs8
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;