Selaa lähdekoodia

Revert back to MruPropertyCache2 with _set field (#478)

Marko Lahma 7 vuotta sitten
vanhempi
commit
c59b15f9ff

+ 1 - 14
Jint/Native/Array/ArrayExecutionContext.cs

@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.Text;
+using System.Text;
 using System.Threading;
 
 namespace Jint.Native.Array
@@ -12,24 +11,12 @@ namespace Jint.Native.Array
         // cache key container for array iteration for less allocations
         private static readonly ThreadLocal<ArrayExecutionContext> _executionContext = new ThreadLocal<ArrayExecutionContext>(() => new ArrayExecutionContext());
 
-        private List<uint> _keyCache;
-        private JsValue[] _callArray1;
-        private JsValue[] _callArray2;
-        private JsValue[] _callArray3;
-        private JsValue[] _callArray4;
         private StringBuilder _stringBuilder;
 
         private ArrayExecutionContext()
         {
         }
 
-        public List<uint> KeyCache => _keyCache = _keyCache ?? new List<uint>();
-
-        public JsValue[] CallArray1 => _callArray1 = _callArray1 ?? new JsValue[1];
-        public JsValue[] CallArray2 => _callArray2 = _callArray2 ?? new JsValue[2];
-        public JsValue[] CallArray3 => _callArray3 = _callArray3 ?? new JsValue[3];
-        public JsValue[] CallArray4 => _callArray4 = _callArray4 ?? new JsValue[4];
-
         public StringBuilder StringBuilder => _stringBuilder = _stringBuilder ?? new StringBuilder();
 
         public static ArrayExecutionContext Current => _executionContext.Value;

+ 1 - 4
Jint/Native/Array/ArrayInstance.cs

@@ -183,10 +183,7 @@ namespace Jint.Native.Array
                     {
                         // in the case of sparse arrays, treat each concrete element instead of
                         // iterating over all indexes
-
-                        var keys = ArrayExecutionContext.Current.KeyCache;
-                        keys.Clear();
-                        keys.AddRange(_sparse.Keys);
+                        var keys = new List<uint>(_sparse.Keys);
                         foreach (var keyIndex in keys)
                         {
                             // is it the index of the array

+ 28 - 34
Jint/Native/Array/ArrayPrototype.cs

@@ -143,8 +143,7 @@ namespace Jint.Native.Array
                 }
             }
 
-
-            var args = ArrayExecutionContext.Current.CallArray4;
+            var args = new JsValue[4];
             while (k < len)
             {
                 var i = (uint) k;
@@ -176,15 +175,15 @@ namespace Jint.Native.Array
             var a = (ArrayInstance) Engine.Array.Construct(Arguments.Empty);
 
             uint to = 0;
-            var jsValues = ArrayExecutionContext.Current.CallArray3;
+            var args = new JsValue[3];
             for (uint k = 0; k < len; k++)
             {
                 if (o.TryGetValue(k, out var kvalue))
                 {
-                    jsValues[0] = kvalue;
-                    jsValues[1] = k;
-                    jsValues[2] = o.Target;
-                    var selected = callable.Call(thisArg, jsValues);
+                    args[0] = kvalue;
+                    args[1] = k;
+                    args[2] = o.Target;
+                    var selected = callable.Call(thisArg, args);
                     if (TypeConverter.ToBoolean(selected))
                     {
                         a.SetIndexValue(to, kvalue, throwOnError: false);
@@ -206,18 +205,16 @@ namespace Jint.Native.Array
 
             var callable = callbackfn.TryCast<ICallable>(x => throw new JavaScriptException(Engine.TypeError, "Argument must be callable"));
 
-            var args = ArrayExecutionContext.Current.CallArray1;
-            args[0] = len;
-            var a = Engine.Array.Construct(args, len);
-            var jsValues =ArrayExecutionContext.Current.CallArray3;
+            var a = Engine.Array.Construct(new JsValue[] {len}, len);
+            var args = new JsValue[3];
             for (uint k = 0; k < len; k++)
             {
                 if (o.TryGetValue(k, out var kvalue))
                 {
-                    jsValues[0] = kvalue;
-                    jsValues[1] = k;
-                    jsValues[2] = o.Target;
-                    var mappedValue = callable.Call(thisArg, jsValues);
+                    args[0] = kvalue;
+                    args[1] = k;
+                    args[2] = o.Target;
+                    var mappedValue = callable.Call(thisArg, args);
                     a.SetIndexValue(k, mappedValue, throwOnError: false);
                 }
             }
@@ -235,15 +232,15 @@ namespace Jint.Native.Array
 
             var callable = callbackfn.TryCast<ICallable>(x => throw new JavaScriptException(Engine.TypeError, "Argument must be callable"));
 
-            var jsValues = ArrayExecutionContext.Current.CallArray3;
+            var args = new JsValue[3];
             for (uint k = 0; k < len; k++)
             {
                 if (o.TryGetValue(k, out var kvalue))
                 {
-                    jsValues[0] = kvalue;
-                    jsValues[1] = k;
-                    jsValues[2] = o.Target;
-                    callable.Call(thisArg, jsValues);
+                    args[0] = kvalue;
+                    args[1] = k;
+                    args[2] = o.Target;
+                    callable.Call(thisArg, args);
                 }
             }
 
@@ -260,15 +257,15 @@ namespace Jint.Native.Array
 
             var callable = callbackfn.TryCast<ICallable>(x => throw new JavaScriptException(Engine.TypeError, "Argument must be callable"));
 
-            var jsValues = ArrayExecutionContext.Current.CallArray3;
+            var args = new JsValue[3];
             for (uint k = 0; k < len; k++)
             {
                 if (o.TryGetValue(k, out var kvalue))
                 {
-                    jsValues[0] = kvalue;
-                    jsValues[1] = k;
-                    jsValues[2] = o.Target;
-                    var testResult = callable.Call(thisArg, jsValues);
+                    args[0] = kvalue;
+                    args[1] = k;
+                    args[2] = o.Target;
+                    var testResult = callable.Call(thisArg, args);
                     if (TypeConverter.ToBoolean(testResult))
                     {
                         return true;
@@ -289,15 +286,15 @@ namespace Jint.Native.Array
 
             var callable = callbackfn.TryCast<ICallable>(x => throw new JavaScriptException(Engine.TypeError, "Argument must be callable"));
 
-            var jsValues = ArrayExecutionContext.Current.CallArray3;
+            var args = new JsValue[3];
             for (uint k = 0; k < len; k++)
             {
                 if (o.TryGetValue(k, out var kvalue))
                 {
-                    jsValues[0] = kvalue;
-                    jsValues[1] = k;
-                    jsValues[2] = o.Target;
-                    var testResult = callable.Call(thisArg, jsValues);
+                    args[0] = kvalue;
+                    args[1] = k;
+                    args[2] = o.Target;
+                    var testResult = callable.Call(thisArg, args);
                     if (false == TypeConverter.ToBoolean(testResult))
                     {
                         return JsBoolean.False;
@@ -524,10 +521,7 @@ namespace Jint.Native.Array
 
                 if (compareFn != null)
                 {
-                    var args = ArrayExecutionContext.Current.CallArray2;
-                    args[0] = x;
-                    args[1] = y;
-                    var s = TypeConverter.ToNumber(compareFn.Call(Undefined, args));
+                    var s = TypeConverter.ToNumber(compareFn.Call(Undefined, new[] {x, y}));
                     if (s < 0)
                     {
                         return -1;

+ 0 - 2
Jint/Native/String/StringExecutionContext.cs

@@ -14,7 +14,6 @@ namespace Jint.Native.String
         private StringBuilder _stringBuilder;
         private List<string> _splitSegmentList;
         private string[] _splitArray1;
-        private JsValue[] _callArray3;
 
         private StringExecutionContext()
         {
@@ -36,7 +35,6 @@ namespace Jint.Native.String
 
         public List<string> SplitSegmentList => _splitSegmentList = _splitSegmentList ?? new List<string>();
         public string[] SplitArray1 => _splitArray1 = _splitArray1 ?? new string[1];
-        public JsValue[] CallArray3 => _callArray3 = _callArray3 ?? new JsValue[3];
 
         public static StringExecutionContext Current => _executionContext.Value;
     }

+ 1 - 1
Jint/Native/String/StringPrototype.cs

@@ -580,7 +580,7 @@ namespace Jint.Native.String
                     return thisString;
                 int end = start + substr.Length;
 
-                var args = StringExecutionContext.Current.CallArray3;
+                var args = new JsValue[3];
                 args[0] = substr;
                 args[1] = start;
                 args[2] = thisString;

+ 20 - 23
Jint/Runtime/MruPropertyCache2.cs

@@ -6,6 +6,7 @@ namespace Jint.Runtime
     internal class MruPropertyCache2<TValue> where TValue : class
     {
         private Dictionary<string, TValue> _dictionary;
+        private bool _set;
         private string _key;
         private TValue _value;
 
@@ -13,17 +14,18 @@ namespace Jint.Runtime
         {
             get
             {
-                if (_key != null && _key == key)
+                if (_set && _key == key)
                 {
                     return _value;
                 }
 
-                return _dictionary != null ? _dictionary[key] : null;
+                return _dictionary?[key];
             }
 
             set
             {
                 EnsureInitialized(key);
+                _set = true;
                 _key = key;
                 _value = value;
 
@@ -38,7 +40,7 @@ namespace Jint.Runtime
         {
             get
             {
-                int count = _key != null ? 1 : 0;
+                int count = _set ? 1 : 0;
                 if (_dictionary != null)
                 {
                     count += _dictionary.Count;
@@ -51,17 +53,16 @@ namespace Jint.Runtime
         public void Add(string key, TValue value)
         {
             EnsureInitialized(key);
+            _set = true;
             _key = key;
             _value = value;
 
-            if (_dictionary != null)
-            {
-                _dictionary.Add(key, value);
-            }
+            _dictionary?.Add(key, value);
         }
 
         public void Clear()
         {
+            _set = false;
             _key = default(string);
             _value = null;
 
@@ -70,7 +71,7 @@ namespace Jint.Runtime
 
         public bool ContainsKey(string key)
         {
-            if (_key != null && _key == key)
+            if (_set && key.Equals(_key))
             {
                 return true;
             }
@@ -82,7 +83,7 @@ namespace Jint.Runtime
         {
             if (_dictionary == null)
             {
-                if (_key != null)
+                if (_set)
                 {
                     yield return new KeyValuePair<string, TValue>(_key, _value);
                 }
@@ -99,20 +100,21 @@ namespace Jint.Runtime
         public bool Remove(string key)
         {
             bool removed = false;
-            if (_key != null && _key == key)
+            if (_set && key.Equals(_key))
             {
+                _set = false;
                 _key = null;
                 _value = null;
                 removed = true;
             }
 
-            removed |= _dictionary?.Remove(key) ?? false;
+            _dictionary?.Remove(key);
             return removed;
         }
 
         public bool TryGetValue(string key, out TValue value)
         {
-            if (_key != null && _key == key)
+            if (_set && _key.Equals(key))
             {
                 value = _value;
                 return true;
@@ -124,32 +126,26 @@ namespace Jint.Runtime
                 return false;
             }
 
-            if (_dictionary.TryGetValue(key, out value))
-            {
-                _key = key;
-                _value = value;
-                return true;
-            }
-
-            return false;
+            return _dictionary.TryGetValue(key, out value);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private void EnsureInitialized(string key)
         {
-            if (_key != null && _key != key)
+            if (_set && _key != key)
             {
                 if (_dictionary == null)
                 {
                     _dictionary = new Dictionary<string, TValue>();
                 }
+
                 _dictionary[_key] = _value;
             }
         }
 
         public string[] GetKeys()
         {
-            int size = _key != null ? 1 : 0;
+            int size = _set ? 1 : 0;
             if (_dictionary != null)
             {
                 size += _dictionary.Count;
@@ -157,10 +153,11 @@ namespace Jint.Runtime
 
             var keys = new string[size];
             int n = 0;
-            if (_key != null)
+            if (_set)
             {
                 keys[n++] = _key;
             }
+
             if (_dictionary != null)
             {
                 foreach (var key in _dictionary.Keys)