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) });
|
new Type[] { typeof (LSL_Vector) });
|
||||||
private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod (typeof (ScriptRestoreCatchException), "Unwrap", new Type[] { typeof (Exception) });
|
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 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),
|
private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod (typeof (ScriptCodeGen),
|
||||||
"CatchExcToStr",
|
"CatchExcToStr",
|
||||||
|
@ -1510,16 +1507,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Ldloc, lcl);
|
ilGen.Emit (curDeclFunc, OpCodes.Ldloc, lcl);
|
||||||
Type t = lcl.type;
|
Type t = lcl.type;
|
||||||
if (t == typeof (HeapTrackerList)) {
|
if (t == typeof (HeapTrackerList)) {
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerListPush);
|
t = HeapTrackerList.GenPush (curDeclFunc, ilGen);
|
||||||
t = typeof (LSL_List);
|
|
||||||
}
|
}
|
||||||
if (t == typeof (HeapTrackerObject)) {
|
if (t == typeof (HeapTrackerObject)) {
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerObjectPush);
|
t = HeapTrackerObject.GenPush (curDeclFunc, ilGen);
|
||||||
t = typeof (object);
|
|
||||||
}
|
}
|
||||||
if (t == typeof (HeapTrackerString)) {
|
if (t == typeof(HeapTrackerString)) {
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Call, heapTrackerStringPush);
|
t = HeapTrackerString.GenPush (curDeclFunc, ilGen);
|
||||||
t = typeof (string);
|
|
||||||
}
|
}
|
||||||
if (t.IsValueType) {
|
if (t.IsValueType) {
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Box, t);
|
ilGen.Emit (curDeclFunc, OpCodes.Box, t);
|
||||||
|
@ -1615,7 +1609,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Castclass, u);
|
ilGen.Emit (curDeclFunc, OpCodes.Castclass, u);
|
||||||
}
|
}
|
||||||
if (u != t) {
|
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 {
|
} else {
|
||||||
ilGen.Emit (curDeclFunc, OpCodes.Stloc, lcl);
|
ilGen.Emit (curDeclFunc, OpCodes.Stloc, lcl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1313,7 +1313,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
||||||
if (type.ToHeapTrackerType () != null) {
|
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)
|
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)
|
public override void PopPost (ScriptCodeGen scg, Token errorAt)
|
||||||
{
|
{
|
||||||
if (type.ToHeapTrackerType () != null) {
|
if (type.ToHeapTrackerType () != null) {
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ());
|
type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
|
||||||
} else {
|
} else {
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Stloc, localBuilder);
|
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.Stloc, htpop);
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, localBuilder);
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, htpop);
|
scg.ilGen.Emit (errorAt, OpCodes.Ldloc, htpop);
|
||||||
scg.ilGen.Emit (errorAt, OpCodes.Call, type.GetHeapTrackerPopMeth ());
|
type.CallHeapTrackerPopMeth (errorAt, scg.ilGen);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1504,6 +1504,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get heap tracking type.
|
* @brief Get heap tracking type.
|
||||||
|
* null indicates there is no heap tracker for the type.
|
||||||
*/
|
*/
|
||||||
public virtual Type ToHeapTrackerType ()
|
public virtual Type ToHeapTrackerType ()
|
||||||
{
|
{
|
||||||
|
@ -1511,15 +1512,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
}
|
}
|
||||||
public virtual ConstructorInfo GetHeapTrackerCtor ()
|
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 {
|
public class TokenTypeList : TokenType {
|
||||||
private static readonly FieldInfo iarListsFieldInfo = typeof (XMRInstArrays).GetField ("iarLists");
|
private static readonly FieldInfo iarListsFieldInfo = typeof (XMRInstArrays).GetField ("iarLists");
|
||||||
private static readonly ConstructorInfo htListCtor = typeof (HeapTrackerList).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
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 (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||||
public TokenTypeList (Token original) : base (original) { }
|
public TokenTypeList (Token original) : base (original) { }
|
||||||
|
@ -1624,14 +1623,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
}
|
}
|
||||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerList); }
|
public override Type ToHeapTrackerType () { return typeof (HeapTrackerList); }
|
||||||
public override ConstructorInfo GetHeapTrackerCtor () { return htListCtor; }
|
public override ConstructorInfo GetHeapTrackerCtor () { return htListCtor; }
|
||||||
public override MethodInfo GetHeapTrackerPopMeth () { return htListPopMeth; }
|
public override void CallHeapTrackerPopMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPop(errorAt, ilGen); }
|
||||||
public override MethodInfo GetHeapTrackerPushMeth () { return htListPushMeth; }
|
public override void CallHeapTrackerPushMeth (Token errorAt, ScriptMyILGen ilGen) { HeapTrackerList.GenPush(errorAt, ilGen); }
|
||||||
}
|
}
|
||||||
public class TokenTypeObject : TokenType {
|
public class TokenTypeObject : TokenType {
|
||||||
private static readonly FieldInfo iarObjectsFieldInfo = typeof (XMRInstArrays).GetField ("iarObjects");
|
private static readonly FieldInfo iarObjectsFieldInfo = typeof (XMRInstArrays).GetField ("iarObjects");
|
||||||
private static readonly ConstructorInfo htObjectCtor = typeof (HeapTrackerObject).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
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 (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||||
public TokenTypeObject (Token original) : base (original) { }
|
public TokenTypeObject (Token original) : base (original) { }
|
||||||
|
@ -1644,8 +1641,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
}
|
}
|
||||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerObject); }
|
public override Type ToHeapTrackerType () { return typeof (HeapTrackerObject); }
|
||||||
public override ConstructorInfo GetHeapTrackerCtor () { return htObjectCtor; }
|
public override ConstructorInfo GetHeapTrackerCtor () { return htObjectCtor; }
|
||||||
public override MethodInfo GetHeapTrackerPopMeth () { return htObjectPopMeth; }
|
public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPop (errorAt, ilGen); }
|
||||||
public override MethodInfo GetHeapTrackerPushMeth () { return htObjectPushMeth; }
|
public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerObject.GenPush(errorAt, ilGen); }
|
||||||
}
|
}
|
||||||
public class TokenTypeRot : TokenType {
|
public class TokenTypeRot : TokenType {
|
||||||
private static readonly FieldInfo iarRotationsFieldInfo = typeof (XMRInstArrays).GetField ("iarRotations");
|
private static readonly FieldInfo iarRotationsFieldInfo = typeof (XMRInstArrays).GetField ("iarRotations");
|
||||||
|
@ -1663,8 +1660,6 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
public class TokenTypeStr : TokenType {
|
public class TokenTypeStr : TokenType {
|
||||||
private static readonly FieldInfo iarStringsFieldInfo = typeof (XMRInstArrays).GetField ("iarStrings");
|
private static readonly FieldInfo iarStringsFieldInfo = typeof (XMRInstArrays).GetField ("iarStrings");
|
||||||
private static readonly ConstructorInfo htStringCtor = typeof (HeapTrackerString).GetConstructor (new Type [] { typeof (XMRInstAbstract) });
|
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 (TokenErrorMessage emsg, string file, int line, int posn) : base (emsg, file, line, posn) { }
|
||||||
public TokenTypeStr (Token original) : base (original) { }
|
public TokenTypeStr (Token original) : base (original) { }
|
||||||
|
@ -1677,8 +1672,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine {
|
||||||
}
|
}
|
||||||
public override Type ToHeapTrackerType () { return typeof (HeapTrackerString); }
|
public override Type ToHeapTrackerType () { return typeof (HeapTrackerString); }
|
||||||
public override ConstructorInfo GetHeapTrackerCtor () { return htStringCtor; }
|
public override ConstructorInfo GetHeapTrackerCtor () { return htStringCtor; }
|
||||||
public override MethodInfo GetHeapTrackerPopMeth () { return htStringPopMeth; }
|
public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) { HeapTrackerString.GenPop(errorAt, ilGen); }
|
||||||
public override MethodInfo GetHeapTrackerPushMeth () { return htStringPushMeth; }
|
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 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) { }
|
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";
|
bool https = uri.Scheme == "https";
|
||||||
if (!https && (uri.Scheme != "http")) {
|
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;
|
string host = uri.Host;
|
||||||
int port = uri.Port;
|
int port = uri.Port;
|
||||||
|
|
|
@ -25,11 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
|
|
||||||
|
@ -43,9 +39,18 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.XMREngine
|
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 {
|
public class HeapTrackerBase {
|
||||||
private int usage;
|
protected int usage; // num bytes used by object
|
||||||
private XMRInstAbstract instance;
|
protected XMRInstAbstract instance; // what script it is in
|
||||||
|
|
||||||
public HeapTrackerBase (XMRInstAbstract inst)
|
public HeapTrackerBase (XMRInstAbstract inst)
|
||||||
{
|
{
|
||||||
|
@ -57,36 +62,78 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
|
||||||
{
|
{
|
||||||
usage = instance.UpdateHeapUse (usage, 0);
|
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 {
|
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 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;
|
value = lis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_List Push ()
|
//private static int counter = 5;
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Size (LSL_List lis)
|
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 {
|
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_CHAR = 2;
|
||||||
public const int HT_DELE = 8;
|
public const int HT_DELE = 8;
|
||||||
public const int HT_DOUB = 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_VEC = HT_DOUB * 3;
|
||||||
public const int HT_ROT = HT_DOUB * 4;
|
public const int HT_ROT = HT_DOUB * 4;
|
||||||
|
|
||||||
private object value;
|
public object value;
|
||||||
|
|
||||||
public HeapTrackerObject (XMRInstAbstract inst) : base (inst) { }
|
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;
|
value = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Push ()
|
// public so it can be used by XMRArray
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Size (object obj)
|
public static int Size (object obj)
|
||||||
{
|
{
|
||||||
if (obj == null) return 0;
|
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 {
|
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 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));
|
ilGen.Emit (errorAt, OpCodes.Call, stringSaveMethod);
|
||||||
value = str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static int Size (string str)
|
||||||
|
|
Loading…
Reference in New Issue