add mrieker fresh optimization on heap tracker
parent
a7e2978db9
commit
38cd12b3cf
|
@ -141,9 +141,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
new Type[] { typeof (LSL_Vector) });
|
||||
private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod (typeof (ScriptRestoreCatchException), "Unwrap", new Type[] { typeof (Exception) });
|
||||
private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod (typeof (ScriptThrownException), "Wrap", new Type[] { typeof (object) });
|
||||
private static MethodInfo heapTrackerListPush = typeof (HeapTrackerList). GetMethod ("Push", new Type[0]);
|
||||
private static MethodInfo heapTrackerObjectPush = typeof (HeapTrackerObject).GetMethod ("Push", new Type[0]);
|
||||
private static MethodInfo heapTrackerStringPush = typeof (HeapTrackerString).GetMethod ("Push", new Type[0]);
|
||||
|
||||
private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod (typeof (ScriptCodeGen),
|
||||
"CatchExcToStr",
|
||||
|
@ -1510,16 +1507,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
ilGen.Emit (curDeclFunc, OpCodes.Ldloc, lcl);
|
||||
Type t = lcl.type;
|
||||
if (t == typeof (HeapTrackerList)) {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerListPush);
|
||||
t = typeof (LSL_List);
|
||||
t = HeapTrackerList.GenPush (curDeclFunc, ilGen);
|
||||
}
|
||||
if (t == typeof (HeapTrackerObject)) {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerObjectPush);
|
||||
t = typeof (object);
|
||||
t = HeapTrackerObject.GenPush (curDeclFunc, ilGen);
|
||||
}
|
||||
if (t == typeof (HeapTrackerString)) {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerStringPush);
|
||||
t = typeof (string);
|
||||
if (t == typeof(HeapTrackerString)) {
|
||||
t = HeapTrackerString.GenPush (curDeclFunc, ilGen);
|
||||
}
|
||||
if (t.IsValueType) {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Box, t);
|
||||
|
@ -1615,7 +1609,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
ilGen.Emit (curDeclFunc, OpCodes.Castclass, u);
|
||||
}
|
||||
if (u != t) {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Call, t.GetMethod ("Pop", new Type[] { u }));
|
||||
if (t == typeof (HeapTrackerList)) HeapTrackerList.GenPop (curDeclFunc, ilGen);
|
||||
if (t == typeof (HeapTrackerObject)) HeapTrackerObject.GenPop (curDeclFunc, ilGen);
|
||||
if (t == typeof (HeapTrackerString)) HeapTrackerString.GenPop (curDeclFunc, ilGen);
|
||||
} else {
|
||||
ilGen.Emit (curDeclFunc, OpCodes.Stloc, lcl);
|
||||
}
|
||||
|
|
|
@ -1313,7 +1313,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
{
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
||||
if (type.ToHeapTrackerType () != null) {
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPushMeth ());
|
||||
type.CallHeapTrackerPushMeth (errorAt, scg.ilGen);
|
||||
}
|
||||
}
|
||||
public override void PushRef (ScriptCodeGen scg, Token errorAt)
|
||||
|
@ -1335,7 +1335,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
public override void PopPost (ScriptCodeGen scg, Token errorAt)
|
||||
{
|
||||
if (type.ToHeapTrackerType () != null) {
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ());
|
||||
type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
|
||||
} else {
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Stloc, localBuilder);
|
||||
}
|
||||
|
@ -1352,7 +1352,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
scg.ilGen.Emit (errorAt, OpCodes.Stloc, htpop);
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, htpop);
|
||||
scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ());
|
||||
type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
|
||||
} else {
|
||||
|
||||
/*
|
||||
|
|
|
@ -1504,6 +1504,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
|
||||
/**
|
||||
* @brief Get heap tracking type.
|
||||
* null indicates there is no heap tracker for the type.
|
||||
*/
|
||||
public virtual Type ToHeapTrackerType ()
|
||||
{
|
||||
|
@ -1511,15 +1512,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
}
|
||||
public virtual ConstructorInfo GetHeapTrackerCtor ()
|
||||
{
|
||||
return null;
|
||||
throw new ApplicationException("no GetHeapTrackerCtor for " + this.GetType());
|
||||
}
|
||||
public virtual MethodInfo GetHeapTrackerPopMeth ()
|
||||
public virtual void CallHeapTrackerPopMeth (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
return null;
|
||||
throw new ApplicationException("no CallHeapTrackerPopMeth for " + this.GetType());
|
||||
}
|
||||
public virtual MethodInfo GetHeapTrackerPushMeth ()
|
||||
public virtual void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
return null;
|
||||
throw new ApplicationException("no CallHeapTrackerPushMeth for " + this.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1610,8 +1611,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
public class TokenTypeList : TokenType {
|
||||
private static readonly FieldInfo iarListsFieldInfo = typeof (XMRInstArrays).GetField ("iarLists");
|
||||
private static readonly ConstructorInfo htListCtor = typeof (HeapTrackerList).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
||||
private static readonly MethodInfo htListPopMeth = typeof (HeapTrackerList).GetMethod ("Pop", new Type[] { typeof (LSL_List) });
|
||||
private static readonly MethodInfo htListPushMeth = typeof (HeapTrackerList).GetMethod ("Push", new Type[0]);
|
||||
|
||||
public TokenTypeList (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||
public TokenTypeList (Token original) : base (original) { }
|
||||
|
@ -1624,14 +1623,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
}
|
||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerList); }
|
||||
public override ConstructorInfo GetHeapTrackerCtor () { return htListCtor; }
|
||||
public override MethodInfo GetHeapTrackerPopMeth () { return htListPopMeth; }
|
||||
public override MethodInfo GetHeapTrackerPushMeth () { return htListPushMeth; }
|
||||
public override void CallHeapTrackerPopMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPop(errorAt, ilGen); }
|
||||
public override void CallHeapTrackerPushMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPush(errorAt, ilGen); }
|
||||
}
|
||||
public class TokenTypeObject : TokenType {
|
||||
private static readonly FieldInfo iarObjectsFieldInfo = typeof (XMRInstArrays).GetField ("iarObjects");
|
||||
private static readonly ConstructorInfo htObjectCtor = typeof (HeapTrackerObject).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
||||
private static readonly MethodInfo htObjectPopMeth = typeof (HeapTrackerObject).GetMethod ("Pop", new Type[] { typeof (object) });
|
||||
private static readonly MethodInfo htObjectPushMeth = typeof (HeapTrackerObject).GetMethod ("Push", new Type[0]);
|
||||
|
||||
public TokenTypeObject (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||
public TokenTypeObject (Token original) : base (original) { }
|
||||
|
@ -1644,8 +1641,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
}
|
||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerObject); }
|
||||
public override ConstructorInfo GetHeapTrackerCtor () { return htObjectCtor; }
|
||||
public override MethodInfo GetHeapTrackerPopMeth () { return htObjectPopMeth; }
|
||||
public override MethodInfo GetHeapTrackerPushMeth () { return htObjectPushMeth; }
|
||||
public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPop (errorAt, ilGen); }
|
||||
public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPush(errorAt, ilGen); }
|
||||
}
|
||||
public class TokenTypeRot : TokenType {
|
||||
private static readonly FieldInfo iarRotationsFieldInfo = typeof (XMRInstArrays).GetField ("iarRotations");
|
||||
|
@ -1663,8 +1660,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
public class TokenTypeStr : TokenType {
|
||||
private static readonly FieldInfo iarStringsFieldInfo = typeof (XMRInstArrays).GetField ("iarStrings");
|
||||
private static readonly ConstructorInfo htStringCtor = typeof (HeapTrackerString).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
||||
private static readonly MethodInfo htStringPopMeth = typeof (HeapTrackerString).GetMethod ("Pop", new Type[] { typeof (string) });
|
||||
private static readonly MethodInfo htStringPushMeth = typeof (HeapTrackerString).GetMethod ("Push", new Type[0]);
|
||||
|
||||
public TokenTypeStr (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||
public TokenTypeStr (Token original) : base (original) { }
|
||||
|
@ -1677,8 +1672,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
}
|
||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerString); }
|
||||
public override ConstructorInfo GetHeapTrackerCtor () { return htStringCtor; }
|
||||
public override MethodInfo GetHeapTrackerPopMeth () { return htStringPopMeth; }
|
||||
public override MethodInfo GetHeapTrackerPushMeth () { return htStringPushMeth; }
|
||||
public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerString.GenPop(errorAt, ilGen); }
|
||||
public override void CallHeapTrackerPushMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerString.GenPush(errorAt, ilGen); }
|
||||
}
|
||||
public class TokenTypeUndef : TokenType { // for the 'undef' constant, ie, null object pointer
|
||||
public TokenTypeUndef (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
|||
}
|
||||
bool https = uri.Scheme == "https";
|
||||
if (!https && (uri.Scheme != "http")) {
|
||||
throw new WebException ("only support " + supported + ", not " + uri.Scheme);
|
||||
throw new WebException ("only support " + supported + ", not " + uri.Scheme + " in " + requestUrl);
|
||||
}
|
||||
string host = uri.Host;
|
||||
int port = uri.Port;
|
||||
|
|
|
@ -25,11 +25,7 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
||||
using OpenSim.Region.ScriptEngine.XMREngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
|
@ -43,9 +39,18 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
|||
|
||||
namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||
{
|
||||
/**
|
||||
* One instance of this class for lsl base objects that take a variable
|
||||
* amount of memory. They are what the script-visible list,object,string
|
||||
* variables are declared as at the CIL level. Generally, temp vars used
|
||||
* by the compiler get their basic type (list,object,string).
|
||||
*
|
||||
* Note that the xmr arrays and script-defined objects have their own
|
||||
* heap tracking built in so do not need any of this stuff.
|
||||
*/
|
||||
public class HeapTrackerBase {
|
||||
private int usage;
|
||||
private XMRInstAbstract instance;
|
||||
protected int usage; // num bytes used by object
|
||||
protected XMRInstAbstract instance; // what script it is in
|
||||
|
||||
public HeapTrackerBase (XMRInstAbstract inst)
|
||||
{
|
||||
|
@ -57,36 +62,78 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
{
|
||||
usage = instance.UpdateHeapUse (usage, 0);
|
||||
}
|
||||
|
||||
protected void NewUse (int newuse)
|
||||
{
|
||||
usage = instance.UpdateHeapUse (usage, newuse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around lists to keep track of how much memory they use.
|
||||
*/
|
||||
public class HeapTrackerList : HeapTrackerBase {
|
||||
private LSL_List value;
|
||||
private static FieldInfo listValueField = typeof (HeapTrackerList).GetField ("value");
|
||||
private static MethodInfo listSaveMethod = typeof (HeapTrackerList).GetMethod ("Save");
|
||||
|
||||
public LSL_List value;
|
||||
|
||||
public HeapTrackerList (XMRInstAbstract inst) : base (inst) { }
|
||||
|
||||
public void Pop (LSL_List lis)
|
||||
// generate CIL code to pop the value from the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// new value pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// new value popped from CIL stack
|
||||
// heap usage updated
|
||||
public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
NewUse (Size (lis));
|
||||
ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod);
|
||||
}
|
||||
|
||||
// generate CIL code to push the value on the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// value pushed on CIL stack replacing 'this' pointer
|
||||
// returns typeof value pushed on stack
|
||||
public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
ilGen.Emit (errorAt, OpCodes.Ldfld, listValueField);
|
||||
return typeof (LSL_List);
|
||||
}
|
||||
|
||||
public void Save (LSL_List lis)
|
||||
{
|
||||
int newuse = Size (lis);
|
||||
usage = instance.UpdateHeapUse (usage, newuse);
|
||||
value = lis;
|
||||
}
|
||||
|
||||
public LSL_List Push ()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
//private static int counter = 5;
|
||||
public static int Size (LSL_List lis)
|
||||
{
|
||||
return (!typeof (LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size;
|
||||
// VS2017 in debug mode seems to have a problem running this statement quickly:
|
||||
//SLOW: return (!typeof(LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size;
|
||||
|
||||
//FAST: return 33;
|
||||
//SLOW: return (lis == null) ? 0 : 99;
|
||||
//FAST: return ++ counter;
|
||||
|
||||
// VS2017 in debug mode seems content to run this quickly though:
|
||||
try {
|
||||
return lis.Size;
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around objects to keep track of how much memory they use.
|
||||
*/
|
||||
public class HeapTrackerObject : HeapTrackerBase {
|
||||
private static FieldInfo objectValueField = typeof (HeapTrackerObject).GetField ("value");
|
||||
private static MethodInfo objectSaveMethod = typeof (HeapTrackerObject).GetMethod ("Save");
|
||||
|
||||
public const int HT_CHAR = 2;
|
||||
public const int HT_DELE = 8;
|
||||
public const int HT_DOUB = 8;
|
||||
|
@ -96,21 +143,44 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
public const int HT_VEC = HT_DOUB * 3;
|
||||
public const int HT_ROT = HT_DOUB * 4;
|
||||
|
||||
private object value;
|
||||
public object value;
|
||||
|
||||
public HeapTrackerObject (XMRInstAbstract inst) : base (inst) { }
|
||||
|
||||
public void Pop (object obj)
|
||||
// generate CIL code to pop the value from the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// new value pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// new value popped from CIL stack
|
||||
// heap usage updated
|
||||
public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
NewUse (Size (obj));
|
||||
ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod);
|
||||
}
|
||||
|
||||
// generate CIL code to push the value on the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// value pushed on CIL stack replacing 'this' pointer
|
||||
// returns typeof value pushed on stack
|
||||
public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
ilGen.Emit (errorAt, OpCodes.Ldfld, objectValueField);
|
||||
return typeof (object);
|
||||
}
|
||||
|
||||
public void Save (object obj)
|
||||
{
|
||||
int newuse = Size (obj);
|
||||
usage = instance.UpdateHeapUse (usage, newuse);
|
||||
value = obj;
|
||||
}
|
||||
|
||||
public object Push ()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// public so it can be used by XMRArray
|
||||
public static int Size (object obj)
|
||||
{
|
||||
if (obj == null) return 0;
|
||||
|
@ -148,20 +218,48 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around strings to keep track of how much memory they use.
|
||||
*/
|
||||
public class HeapTrackerString : HeapTrackerBase {
|
||||
private string value;
|
||||
private static FieldInfo stringValueField = typeof (HeapTrackerString).GetField ("value");
|
||||
private static MethodInfo stringSaveMethod = typeof (HeapTrackerString).GetMethod ("Save");
|
||||
|
||||
public string value;
|
||||
|
||||
public HeapTrackerString (XMRInstAbstract inst) : base (inst) { }
|
||||
|
||||
public void Pop (string str)
|
||||
// generate CIL code to pop the value from the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// new value pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// new value popped from CIL stack
|
||||
// heap usage updated
|
||||
public static void GenPop (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
NewUse (Size (str));
|
||||
value = str;
|
||||
ilGen.Emit (errorAt, OpCodes.Call, stringSaveMethod);
|
||||
}
|
||||
|
||||
public string Push ()
|
||||
// generate CIL code to push the value on the CIL stack
|
||||
// input:
|
||||
// 'this' pointer already pushed on CIL stack
|
||||
// output:
|
||||
// 'this' pointer popped from stack
|
||||
// value pushed on CIL stack replacing 'this' pointer
|
||||
// returns typeof value pushed on stack
|
||||
public static Type GenPush (Token errorAt, ScriptMyILGen ilGen)
|
||||
{
|
||||
return value;
|
||||
ilGen.Emit (errorAt, OpCodes.Ldfld, stringValueField);
|
||||
return typeof (string);
|
||||
}
|
||||
|
||||
public void Save (string str)
|
||||
{
|
||||
int newuse = Size (str);
|
||||
usage = instance.UpdateHeapUse (usage, newuse);
|
||||
value = str;
|
||||
}
|
||||
|
||||
public static int Size (string str)
|
||||
|
|
Loading…
Reference in New Issue