Xengine: try to reduce memory pressure of scripts compile. Still ugly code, possible mistakes, but i need to share it before i loose it :) )

LSLKeyTest
UbitUmarov 2016-08-31 09:15:08 +01:00
parent 4e1784d069
commit 5afc5fe343
5 changed files with 338 additions and 357 deletions

View File

@ -81,8 +81,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
// private object m_syncy = new object(); // private object m_syncy = new object();
private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); // private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); // private static VBCodeProvider VBcodeProvider = new VBCodeProvider();
// private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files
private static UInt64 scriptCompileCounter = 0; // And a counter private static UInt64 scriptCompileCounter = 0; // And a counter
@ -356,14 +356,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
throw new Exception(errtext); throw new Exception(errtext);
} }
string compileScript = source; string compileScript = string.Empty;
if (language == enumCompileType.lsl) if (language == enumCompileType.lsl)
{ {
// Its LSL, convert it to C# // Its LSL, convert it to C#
LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls);
compileScript = LSL_Converter.Convert(source);
StringBuilder sb = new StringBuilder(16394);
LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls);
AddCSScriptHeader(
m_scriptEngine.ScriptClassName,
m_scriptEngine.ScriptBaseClassName,
m_scriptEngine.ScriptBaseClassParameters,
sb);
LSL_Converter.Convert(source,sb);
AddCSScriptTail(sb);
compileScript = sb.ToString();
// copy converter warnings into our warnings. // copy converter warnings into our warnings.
foreach (string warning in LSL_Converter.GetWarnings()) foreach (string warning in LSL_Converter.GetWarnings())
{ {
@ -374,22 +384,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
// Write the linemap to a file and save it in our dictionary for next time. // Write the linemap to a file and save it in our dictionary for next time.
m_lineMaps[assembly] = linemap; m_lineMaps[assembly] = linemap;
WriteMapFile(assembly + ".map", linemap); WriteMapFile(assembly + ".map", linemap);
LSL_Converter.Clear();
} }
else
switch (language)
{ {
case enumCompileType.cs: switch (language)
case enumCompileType.lsl: {
compileScript = CreateCSCompilerScript( case enumCompileType.cs:
compileScript, compileScript = CreateCSCompilerScript(
m_scriptEngine.ScriptClassName, compileScript,
m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptClassName,
m_scriptEngine.ScriptBaseClassParameters); m_scriptEngine.ScriptBaseClassName,
break; m_scriptEngine.ScriptBaseClassParameters);
case enumCompileType.vb: break;
compileScript = CreateVBCompilerScript( case enumCompileType.vb:
compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); compileScript = CreateVBCompilerScript(
break; compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName);
break;
}
} }
assembly = CompileFromDotNetText(compileScript, language, asset, assembly); assembly = CompileFromDotNetText(compileScript, language, asset, assembly);
@ -419,6 +431,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
// return compileScript; // return compileScript;
// } // }
public static void AddCSScriptHeader(string className, string baseClassName, ParameterInfo[] constructorParameters, StringBuilder sb)
{
sb.Append(string.Format(
@"using OpenSim.Region.ScriptEngine.Shared;
using System.Collections.Generic;
namespace SecondLife
{{
public class {0} : {1}
{{
public {0}({2}) : base({3}) {{}}
",
className,
baseClassName,
constructorParameters != null
? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString()))
: "",
constructorParameters != null
? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name))
: ""
));
}
public static void AddCSScriptTail(StringBuilder sb)
{
sb.Append(string.Format("\n }}\n}}\n"));
}
public static string CreateCSCompilerScript( public static string CreateCSCompilerScript(
string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters)
{ {
@ -511,8 +551,6 @@ namespace SecondLife
// Do actual compile // Do actual compile
CompilerParameters parameters = new CompilerParameters(); CompilerParameters parameters = new CompilerParameters();
parameters.IncludeDebugInformation = true;
string rootPath = AppDomain.CurrentDomain.BaseDirectory; string rootPath = AppDomain.CurrentDomain.BaseDirectory;
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
@ -532,26 +570,44 @@ namespace SecondLife
parameters.IncludeDebugInformation = CompileWithDebugInformation; parameters.IncludeDebugInformation = CompileWithDebugInformation;
//parameters.WarningLevel = 1; // Should be 4? //parameters.WarningLevel = 1; // Should be 4?
parameters.TreatWarningsAsErrors = false; parameters.TreatWarningsAsErrors = false;
parameters.GenerateInMemory = false;
CompilerResults results; CompilerResults results;
CodeDomProvider provider;
switch (lang) switch (lang)
{ {
case enumCompileType.vb: case enumCompileType.vb:
results = VBcodeProvider.CompileAssemblyFromSource( // results = VBcodeProvider.CompileAssemblyFromSource(
parameters, Script); // parameters, Script);
provider = CodeDomProvider.CreateProvider("VisualBasic");
break; break;
case enumCompileType.cs: case enumCompileType.cs:
case enumCompileType.lsl: case enumCompileType.lsl:
provider = CodeDomProvider.CreateProvider("CSharp");
break;
default:
throw new Exception("Compiler is not able to recongnize " +
"language type \"" + lang.ToString() + "\"");
}
if(provider == null)
throw new Exception("Compiler failed to load ");
bool complete = false; bool complete = false;
bool retried = false; bool retried = false;
do do
{ {
lock (CScodeProvider) // lock (CScodeProvider)
{ // {
results = CScodeProvider.CompileAssemblyFromSource( // results = CScodeProvider.CompileAssemblyFromSource(
parameters, Script); // parameters, Script);
} // }
results = provider.CompileAssemblyFromSource(
parameters, Script);
// Deal with an occasional segv in the compiler. // Deal with an occasional segv in the compiler.
// Rarely, if ever, occurs twice in succession. // Rarely, if ever, occurs twice in succession.
// Line # == 0 and no file name are indications that // Line # == 0 and no file name are indications that
@ -575,11 +631,11 @@ namespace SecondLife
complete = true; complete = true;
} }
} while (!complete); } while (!complete);
break; // break;
default: // default:
throw new Exception("Compiler is not able to recongnize " + // throw new Exception("Compiler is not able to recongnize " +
"language type \"" + lang.ToString() + "\""); // "language type \"" + lang.ToString() + "\"");
} // }
// foreach (Type type in results.CompiledAssembly.GetTypes()) // foreach (Type type in results.CompiledAssembly.GetTypes())
// { // {
@ -628,6 +684,8 @@ namespace SecondLife
} }
} }
provider.Dispose();
if (hadErrors) if (hadErrors)
{ {
throw new Exception(errtext); throw new Exception(errtext);
@ -785,15 +843,16 @@ namespace SecondLife
private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap)
{ {
string mapstring = String.Empty; StringBuilder mapbuilder = new StringBuilder(1024);
foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap) foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap)
{ {
KeyValuePair<int, int> k = kvp.Key; KeyValuePair<int, int> k = kvp.Key;
KeyValuePair<int, int> v = kvp.Value; KeyValuePair<int, int> v = kvp.Value;
mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value); mapbuilder.Append(String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value));
} }
Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); Byte[] mapbytes = Encoding.ASCII.GetBytes(mapbuilder.ToString());
using (FileStream mfs = File.Create(filename)) using (FileStream mfs = File.Create(filename))
mfs.Write(mapbytes, 0, mapbytes.Length); mfs.Write(mapbytes, 0, mapbytes.Length);

View File

@ -27,12 +27,15 @@
*/ */
using System; using System;
using System.Text;
namespace OpenSim.Region.ScriptEngine.Shared.CodeTools namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
{ {
public interface ICodeConverter public interface ICodeConverter
{ {
string Convert(string script); string Convert(string script);
void Convert(string script, StringBuilder sb);
string[] GetWarnings(); string[] GetWarnings();
void Clear();
} }
} }

View File

@ -416,7 +416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
PostEvent(new EventParams("on_rez", PostEvent(new EventParams("on_rez",
new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0])); new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
} }
if (m_stateSource == StateSource.AttachedRez) if (m_stateSource == StateSource.AttachedRez)
{ {
PostEvent(new EventParams("attach", PostEvent(new EventParams("attach",
@ -457,7 +456,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
PostEvent(new EventParams("attach", PostEvent(new EventParams("attach",
new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
} }
} }
} }

View File

@ -1278,6 +1278,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
} }
} }
// do not load a assembly on top of a lot of to release memory
// also yield a bit
GC.Collect(2);
ScriptInstance instance = null; ScriptInstance instance = null;
lock (m_Scripts) lock (m_Scripts)
{ {
@ -1501,11 +1505,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_PrimObjects[localID].Add(itemID); m_PrimObjects[localID].Add(itemID);
} }
if (!m_Assemblies.ContainsKey(assetID))
m_Assemblies[assetID] = assemblyPath;
lock (m_AddingAssemblies) lock (m_AddingAssemblies)
{ {
if (!m_Assemblies.ContainsKey(assetID))
m_Assemblies[assetID] = assemblyPath;
m_AddingAssemblies[assemblyPath]--; m_AddingAssemblies[assemblyPath]--;
} }