1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 using System.ComponentModel;
19 using System.Diagnostics;
21 using System.Dynamic.Utils;
23 using Microsoft.Scripting.Utils;
27 namespace System.Runtime.CompilerServices {
29 namespace Microsoft.Runtime.CompilerServices {
32 /// This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
33 /// Represents a cache of runtime binding rules.
35 /// <typeparam name="T">The delegate type.</typeparam>
36 [EditorBrowsable(EditorBrowsableState.Never), DebuggerStepThrough]
37 public class RuleCache<T> where T : class {
38 private T[] _rules = new T[0];
39 private readonly Object cacheLock = new Object();
41 private const int MaxRules = 128;
43 internal RuleCache() { }
45 internal T[] GetRules() {
49 // move the rule +2 up.
50 // this is called on every successful rule.
51 internal void MoveRule(T rule, int i) {
52 // limit search to MaxSearch elements.
53 // Rule should not get too far unless it has been already moved up.
54 // need a lock to make sure we are moving the right rule and not loosing any.
56 const int MaxSearch = 8;
57 int count = _rules.Length - i;
58 if (count > MaxSearch) {
63 int max = Math.Min(_rules.Length, i + count);
64 for (int index = i; index < max; index++) {
65 if (_rules[index] == rule) {
73 T oldRule = _rules[oldIndex];
74 _rules[oldIndex] = _rules[oldIndex - 1];
75 _rules[oldIndex - 1] = _rules[oldIndex - 2];
76 _rules[oldIndex - 2] = oldRule;
80 internal void AddRule(T newRule) {
81 // need a lock to make sure we are not loosing rules.
83 _rules = AddOrInsert(_rules, newRule);
87 internal void ReplaceRule(T oldRule, T newRule) {
88 // need a lock to make sure we are replacing the right rule
90 int i = Array.IndexOf(_rules, oldRule);
97 _rules = AddOrInsert(_rules, newRule);
102 // Adds to end or or inserts items at InsertPosition
103 private const int InsertPosition = MaxRules / 2;
105 private static T[] AddOrInsert(T[] rules, T item) {
106 if (rules.Length < InsertPosition) {
107 return rules.AddLast(item);
112 int newLength = rules.Length + 1;
113 if (newLength > MaxRules) {
114 newLength = MaxRules;
117 newRules = new T[newLength];
120 Array.Copy(rules, 0, newRules, 0, InsertPosition);
121 newRules[InsertPosition] = item;
122 Array.Copy(rules, InsertPosition, newRules, InsertPosition + 1, newLength - InsertPosition - 1);