Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorMike Krüger <mikkrg@microsoft.com>2018-02-26 10:57:19 +0300
committerMike Krüger <mikkrg@microsoft.com>2018-02-26 10:57:19 +0300
commitadc3318054a0f0315d422f58ef12e6552f26c5ae (patch)
tree1cc3c404dcdfbcac343d6531d51604bafcb766d0 /main/src
parent53b566cb7d54703faaa1c160c270abdf9a3f3cf3 (diff)
[Core] Use roslyn ObjectPool class for the string builder cache.
Core doesn't have an ivt to roslyn but using objectpool as source isn't much of a problem - it's about ~100 LOC and using an own pooling system gives us some flexibility we may need.
Diffstat (limited to 'main/src')
-rw-r--r--main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs8
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Logging/AssertLoggingTraceListener.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core/ObjectPool.cs269
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core/SharedPools.cs58
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringBuilderCache.cs397
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/SearchResult.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/Ambience.cs4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MarkupUtilities.cs2
9 files changed, 346 insertions, 402 deletions
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs
index 8a7609ab5a..6a49c74505 100644
--- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs
+++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeGeneration/AbstractGenerateAction.cs
@@ -121,12 +121,12 @@ namespace MonoDevelop.CodeGeneration
static string AddIndent (string text, string indent)
{
var doc = TextEditorFactory.CreateNewReadonlyDocument (new StringTextSource (text), "");
- var result = StringBuilderCache.New ();
+ var result = StringBuilderCache.Allocate ();
foreach (var line in doc.GetLines ()) {
result.Append (indent);
result.Append (doc.GetTextAt (line.SegmentIncludingDelimiter));
}
- return result.ToString ();
+ return StringBuilderCache.ReturnAndFree (result);
}
public void GenerateCode (Gtk.TreeView treeView)
@@ -145,7 +145,7 @@ namespace MonoDevelop.CodeGeneration
includedMembers.Add (store.GetValue (iter, 3));
}
}
- var output = StringBuilderCache.New ();
+ var output = StringBuilderCache.Allocate ();
string indent = options.Editor.GetVirtualIndentationString (options.Editor.CaretLine);
foreach (string nodeText in GenerateCode (includedMembers)) {
if (output.Length > 0) {
@@ -159,7 +159,7 @@ namespace MonoDevelop.CodeGeneration
var data = options.Editor;
data.EnsureCaretIsNotVirtual ();
int offset = data.CaretOffset;
- var text = output.ToString ().TrimStart ();
+ var text = StringBuilderCache.ReturnAndFree (output).TrimStart ();
using (var undo = data.OpenUndoGroup ()) {
data.InsertAtCaret (text);
OnTheFlyFormatter.Format (data, options.DocumentContext, offset, offset + text.Length);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Logging/AssertLoggingTraceListener.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Logging/AssertLoggingTraceListener.cs
index f9f8bf53c7..3778df5720 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Logging/AssertLoggingTraceListener.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Logging/AssertLoggingTraceListener.cs
@@ -45,7 +45,7 @@ namespace MonoDevelop.Core.Logging
if (callerFrame == frames.Length - 1)
callerFrame = 0;
- var sb = StringBuilderCache.New();
+ var sb = StringBuilderCache.Allocate();
if (IsRealMessage (message)) {
if (!string.IsNullOrEmpty (detailMessage)) {
sb.AppendFormat ("Failed assertion: {0} - {1}", message, detailMessage);
@@ -61,7 +61,7 @@ namespace MonoDevelop.Core.Logging
sb.Append ("\n");
FormatStackTrace (sb, frames, callerFrame);
- LoggingService.LogError (sb.ToString ());
+ LoggingService.LogError (StringBuilderCache.ReturnAndFree(sb));
}
static bool IsRealMessage (string message)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
index 108da5d396..6285a560d1 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
@@ -757,6 +757,8 @@
<Compile Include="MonoDevelop.FSW\FileSystemWatcher.cs" />
<Compile Include="MonoDevelop.FSW\Mono\FileSystemWatcher.cs" />
<Compile Include="MonoDevelop.Core\StringBuilderCache.cs" />
+ <Compile Include="MonoDevelop.Core\ObjectPool.cs" />
+ <Compile Include="MonoDevelop.Core\SharedPools.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/ObjectPool.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/ObjectPool.cs
new file mode 100644
index 0000000000..93b3464ff2
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/ObjectPool.cs
@@ -0,0 +1,269 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+// define TRACE_LEAKS to get additional diagnostics that can lead to the leak sources. note: it will
+// make everything about 2-3x slower
+//
+// #define TRACE_LEAKS
+
+// define DETECT_LEAKS to detect possible leaks
+// #if DEBUG
+// #define DETECT_LEAKS //for now always enable DETECT_LEAKS in debug.
+// #endif
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+
+#if DETECT_LEAKS
+using System.Runtime.CompilerServices;
+
+#endif
+
+namespace MonoDevelop.Core
+{
+ /// <summary>
+ /// Generic implementation of object pooling pattern with predefined pool size limit. The main
+ /// purpose is that limited number of frequently used objects can be kept in the pool for
+ /// further recycling.
+ ///
+ /// Notes:
+ /// 1) it is not the goal to keep all returned objects. Pool is not meant for storage. If there
+ /// is no space in the pool, extra returned objects will be dropped.
+ ///
+ /// 2) it is implied that if object was obtained from a pool, the caller will return it back in
+ /// a relatively short time. Keeping checked out objects for long durations is ok, but
+ /// reduces usefulness of pooling. Just new up your own.
+ ///
+ /// Not returning objects to the pool in not detrimental to the pool's work, but is a bad practice.
+ /// Rationale:
+ /// If there is no intent for reusing the object, do not use pool - just use "new".
+ /// </summary>
+ internal class ObjectPool<T> where T : class
+ {
+ [DebuggerDisplay ("{Value,nq}")]
+ private struct Element
+ {
+ internal T Value;
+ }
+
+ /// <remarks>
+ /// Not using System.Func{T} because this file is linked into the (debugger) Formatter,
+ /// which does not have that type (since it compiles against .NET 2.0).
+ /// </remarks>
+ internal delegate T Factory ();
+
+ // Storage for the pool objects. The first item is stored in a dedicated field because we
+ // expect to be able to satisfy most requests from it.
+ private T _firstItem;
+ private readonly Element [] _items;
+
+ // factory is stored for the lifetime of the pool. We will call this only when pool needs to
+ // expand. compared to "new T()", Func gives more flexibility to implementers and faster
+ // than "new T()".
+ private readonly Factory _factory;
+
+#if DETECT_LEAKS
+ private static readonly ConditionalWeakTable<T, LeakTracker> leakTrackers = new ConditionalWeakTable<T, LeakTracker>();
+
+ private class LeakTracker : IDisposable
+ {
+ private volatile bool disposed;
+
+#if TRACE_LEAKS
+ internal volatile object Trace = null;
+#endif
+
+ public void Dispose()
+ {
+ disposed = true;
+ GC.SuppressFinalize(this);
+ }
+
+ private string GetTrace()
+ {
+#if TRACE_LEAKS
+ return Trace == null ? "" : Trace.ToString();
+#else
+ return "Leak tracing information is disabled. Define TRACE_LEAKS on ObjectPool`1.cs to get more info \n";
+#endif
+ }
+
+ ~LeakTracker()
+ {
+ if (!this.disposed && !Environment.HasShutdownStarted)
+ {
+ var trace = GetTrace();
+
+ // If you are seeing this message it means that object has been allocated from the pool
+ // and has not been returned back. This is not critical, but turns pool into rather
+ // inefficient kind of "new".
+ Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nPool detected potential leaking of {typeof(T)}. \n Location of the leak: \n {GetTrace()} TRACEOBJECTPOOLLEAKS_END");
+ }
+ }
+ }
+#endif
+
+ internal ObjectPool (Factory factory)
+ : this (factory, Environment.ProcessorCount * 2)
+ { }
+
+ internal ObjectPool (Factory factory, int size)
+ {
+ Debug.Assert (size >= 1);
+ _factory = factory;
+ _items = new Element [size - 1];
+ }
+
+ private T CreateInstance ()
+ {
+ var inst = _factory ();
+ return inst;
+ }
+
+ /// <summary>
+ /// Produces an instance.
+ /// </summary>
+ /// <remarks>
+ /// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
+ /// Note that Free will try to store recycled objects close to the start thus statistically
+ /// reducing how far we will typically search.
+ /// </remarks>
+ internal T Allocate ()
+ {
+ // PERF: Examine the first element. If that fails, AllocateSlow will look at the remaining elements.
+ // Note that the initial read is optimistically not synchronized. That is intentional.
+ // We will interlock only when we have a candidate. in a worst case we may miss some
+ // recently returned objects. Not a big deal.
+ T inst = _firstItem;
+ if (inst == null || inst != Interlocked.CompareExchange (ref _firstItem, null, inst)) {
+ inst = AllocateSlow ();
+ }
+
+#if DETECT_LEAKS
+ var tracker = new LeakTracker();
+ leakTrackers.Add(inst, tracker);
+
+#if TRACE_LEAKS
+ var frame = CaptureStackTrace();
+ tracker.Trace = frame;
+#endif
+#endif
+ return inst;
+ }
+
+ private T AllocateSlow ()
+ {
+ var items = _items;
+
+ for (int i = 0; i < items.Length; i++) {
+ // Note that the initial read is optimistically not synchronized. That is intentional.
+ // We will interlock only when we have a candidate. in a worst case we may miss some
+ // recently returned objects. Not a big deal.
+ T inst = items [i].Value;
+ if (inst != null) {
+ if (inst == Interlocked.CompareExchange (ref items [i].Value, null, inst)) {
+ return inst;
+ }
+ }
+ }
+
+ return CreateInstance ();
+ }
+
+ /// <summary>
+ /// Returns objects to the pool.
+ /// </summary>
+ /// <remarks>
+ /// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
+ /// Note that Free will try to store recycled objects close to the start thus statistically
+ /// reducing how far we will typically search in Allocate.
+ /// </remarks>
+ internal void Free (T obj)
+ {
+ Validate (obj);
+ ForgetTrackedObject (obj);
+
+ if (_firstItem == null) {
+ // Intentionally not using interlocked here.
+ // In a worst case scenario two objects may be stored into same slot.
+ // It is very unlikely to happen and will only mean that one of the objects will get collected.
+ _firstItem = obj;
+ } else {
+ FreeSlow (obj);
+ }
+ }
+
+ private void FreeSlow (T obj)
+ {
+ var items = _items;
+ for (int i = 0; i < items.Length; i++) {
+ if (items [i].Value == null) {
+ // Intentionally not using interlocked here.
+ // In a worst case scenario two objects may be stored into same slot.
+ // It is very unlikely to happen and will only mean that one of the objects will get collected.
+ items [i].Value = obj;
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Removes an object from leak tracking.
+ ///
+ /// This is called when an object is returned to the pool. It may also be explicitly
+ /// called if an object allocated from the pool is intentionally not being returned
+ /// to the pool. This can be of use with pooled arrays if the consumer wants to
+ /// return a larger array to the pool than was originally allocated.
+ /// </summary>
+ [Conditional ("DEBUG")]
+ internal void ForgetTrackedObject (T old, T replacement = null)
+ {
+#if DETECT_LEAKS
+ LeakTracker tracker;
+ if (leakTrackers.TryGetValue(old, out tracker))
+ {
+ tracker.Dispose();
+ leakTrackers.Remove(old);
+ }
+ else
+ {
+ var trace = CaptureStackTrace();
+ Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nObject of type {typeof(T)} was freed, but was not from pool. \n Callstack: \n {trace} TRACEOBJECTPOOLLEAKS_END");
+ }
+
+ if (replacement != null)
+ {
+ tracker = new LeakTracker();
+ leakTrackers.Add(replacement, tracker);
+ }
+#endif
+ }
+
+#if DETECT_LEAKS
+ private static Lazy<Type> _stackTraceType = new Lazy<Type>(() => Type.GetType("System.Diagnostics.StackTrace"));
+
+ private static object CaptureStackTrace()
+ {
+ return Activator.CreateInstance(_stackTraceType.Value);
+ }
+#endif
+
+ [Conditional ("DEBUG")]
+ private void Validate (object obj)
+ {
+ Debug.Assert (obj != null, "freeing null?");
+
+ Debug.Assert (_firstItem != obj, "freeing twice?");
+
+ var items = _items;
+ for (int i = 0; i < items.Length; i++) {
+ var value = items [i].Value;
+ if (value == null) {
+ }
+ return;
+
+ Debug.Assert (value != obj, "freeing twice?");
+ }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/SharedPools.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/SharedPools.cs
new file mode 100644
index 0000000000..b74dd4a279
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/SharedPools.cs
@@ -0,0 +1,58 @@
+//
+// StringBuilderCache.cs
+//
+// Author:
+// Mike Krüger <mikkrg@microsoft.com>
+//
+// Copyright (c) 2018 Microsoft Corporation. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+namespace MonoDevelop.Core
+{
+ static class SharedPools
+ {
+ /// <summary>
+ /// pool that uses default constructor with 100 elements pooled
+ /// </summary>
+ public static ObjectPool<T> BigDefault<T> () where T : class, new()
+ {
+ return DefaultBigPool<T>.Instance;
+ }
+
+ /// <summary>
+ /// pool that uses default constructor with 20 elements pooled
+ /// </summary>
+ public static ObjectPool<T> Default<T> () where T : class, new()
+ {
+ return DefaultNormalPool<T>.Instance;
+ }
+
+ static class DefaultBigPool<T> where T : class, new()
+ {
+ public static readonly ObjectPool<T> Instance = new ObjectPool<T> (() => new T (), 100);
+ }
+
+ static class DefaultNormalPool<T> where T : class, new()
+ {
+ public static readonly ObjectPool<T> Instance = new ObjectPool<T> (() => new T (), 20);
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringBuilderCache.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringBuilderCache.cs
index a184724f47..b1cde57805 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringBuilderCache.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringBuilderCache.cs
@@ -24,12 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-using System;
-using System.Diagnostics;
using System.Text;
-using System.Threading;
-using System.Collections.Immutable;
-using System.Security.Cryptography;
namespace MonoDevelop.Core
{
@@ -38,401 +33,21 @@ namespace MonoDevelop.Core
/// </summary>
public static class StringBuilderCache
{
- static ImmutableQueue<CachedStringBuilder> pool = ImmutableQueue<CachedStringBuilder>.Empty;
-
- public static CachedStringBuilder New ()
+ public static StringBuilder Allocate ()
{
- pool = pool.Dequeue (out CachedStringBuilder result);
- if (result != null) {
- result.Cached = false;
- return result;
- }
- return new CachedStringBuilder ();
+ return SharedPools.Default<StringBuilder> ().Allocate ();
}
- internal static void Put (CachedStringBuilder sb)
+ public static void Free (StringBuilder sb)
{
sb.Clear ();
- sb.Cached = true;
- pool = pool.Enqueue (sb);
- }
- }
-
- /// <summary>
- /// A string builder which puts itself into the object pool on a ToString() call.
- /// </summary>
- public class CachedStringBuilder
- {
- readonly StringBuilder sb = new StringBuilder ();
-
- internal bool Cached { get; set; }
-
- public int Capacity { get => sb.Capacity; set => sb.Capacity = value; }
- public int Length { get => sb.Length; set => sb.Length = value; }
-
- public int MaxCapacity { get => sb.MaxCapacity; }
-
- public char this [int index] { get => sb [index]; set => sb [index] = value; }
-
- public CachedStringBuilder Append (long value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (ulong value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (uint value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (ushort value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (string value, int startIndex, int count)
- {
- sb.Append (value, startIndex, count);
- return this;
- }
-
- public CachedStringBuilder Append (string value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (float value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (sbyte value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (object value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (int value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (char [] value, int startIndex, int charCount)
- {
- sb.Append (value, startIndex, charCount);
- return this;
- }
-
- public CachedStringBuilder Append (double value)
- {
- sb.Append (value);
- return this;
+ SharedPools.Default<StringBuilder> ().Free (sb);
}
- public CachedStringBuilder Append (decimal value)
+ public static string ReturnAndFree (StringBuilder sb)
{
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (char [] value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (char value, int repeatCount)
- {
- sb.Append (value, repeatCount);
- return this;
- }
-
- public unsafe CachedStringBuilder Append (char* value, int valueCount)
- {
- sb.Append (value, valueCount);
- return this;
- }
-
- public CachedStringBuilder Append (char value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (byte value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (bool value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder Append (short value)
- {
- sb.Append (value);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (string format, object arg0, object arg1, object arg2)
- {
- sb.AppendFormat (format, arg0, arg1, arg2);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (string format, params object [] args)
- {
- sb.AppendFormat (format, args);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (string format, object arg0, object arg1)
- {
- sb.AppendFormat (format, arg0, arg1);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (string format, object arg0)
- {
- sb.AppendFormat (format, arg0);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (IFormatProvider provider, string format, object arg0, object arg1, object arg2)
- {
- sb.AppendFormat (provider, format, arg0, arg1, arg2);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (IFormatProvider provider, string format, object arg0, object arg1)
- {
- sb.AppendFormat (provider, format, arg0, arg1);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (IFormatProvider provider, string format, object arg0)
- {
- sb.AppendFormat (provider, format, arg0);
- return this;
- }
-
- public CachedStringBuilder AppendFormat (IFormatProvider provider, string format, params object [] args)
- {
- sb.AppendFormat (provider, format, args);
- return this;
- }
-
- public CachedStringBuilder AppendLine ()
- {
- sb.AppendLine ();
- return this;
- }
-
- public CachedStringBuilder AppendLine (string value)
- {
- sb.AppendLine (value);
- return this;
- }
-
- public CachedStringBuilder Clear ()
- {
- sb.Clear ();
- return this;
- }
-
- public void CopyTo (int sourceIndex, char [] destination, int destinationIndex, int count)
- {
- sb.CopyTo (sourceIndex, destination, destinationIndex, count);
- }
-
- public int EnsureCapacity (int capacity)
- {
- return sb.EnsureCapacity(capacity);
- }
-
- public bool Equals (StringBuilder sb)
- {
- return this.sb.Equals (sb);
- }
-
- public bool Equals (CachedStringBuilder csb)
- {
- return this.sb.Equals (csb.sb);
- }
-
- public CachedStringBuilder Insert (int index, uint value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, ushort value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, string value, int count)
- {
- sb.Insert (index, value, count);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, string value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, float value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, sbyte value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, ulong value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, object value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, double value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, int value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, decimal value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, char [] value, int startIndex, int charCount)
- {
- sb.Insert (index, value, startIndex, charCount);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, char [] value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, char value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, byte value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, bool value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, long value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Insert (int index, short value)
- {
- sb.Insert (index, value);
- return this;
- }
-
- public CachedStringBuilder Remove (int startIndex, int length)
- {
- sb.Remove (startIndex, length);
- return this;
- }
-
- public CachedStringBuilder Replace (string oldValue, string newValue, int startIndex, int count)
- {
- sb.Replace (oldValue, newValue, startIndex, count);
- return this;
- }
-
- public CachedStringBuilder Replace (char oldChar, char newChar)
- {
- sb.Replace (oldChar, newChar);
- return this;
- }
-
- public CachedStringBuilder Replace (char oldChar, char newChar, int startIndex, int count)
- {
- sb.Replace (oldChar, newChar, startIndex, count);
- return this;
- }
-
- public CachedStringBuilder Replace (string oldValue, string newValue)
- {
- sb.Replace (oldValue, newValue);
- return this;
- }
-
- public override string ToString ()
- {
- if (Cached)
- throw new InvalidOperationException ("Object is cached.");
var result = sb.ToString ();
- StringBuilderCache.Put (this);
- return result;
- }
-
- public string ToString (int startIndex, int length)
- {
- if (Cached)
- throw new InvalidOperationException ("Object is cached.");
- var result = sb.ToString (startIndex, length);
- StringBuilderCache.Put (this);
+ Free (sb);
return result;
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/SearchResult.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/SearchResult.cs
index 3da90ec0c1..c6e6c03918 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/SearchResult.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/SearchResult.cs
@@ -106,7 +106,7 @@ namespace MonoDevelop.Components.MainToolbar
{
var lane = StringMatcher.GetMatcher (toMatch, true).GetMatch (text);
var matchHexColor = selected ? selectedResultMatchTextColor : resultMatchTextColor;
- var result = StringBuilderCache.New ();
+ var result = StringBuilderCache.Allocate ();
if (lane != null) {
int lastPos = 0;
for (int n=0; n < lane.Length; n++) {
@@ -125,7 +125,7 @@ namespace MonoDevelop.Components.MainToolbar
} else {
MarkupUtilities.AppendEscapedString (result, text, 0, text.Length);
}
- return result.ToString ();
+ return StringBuilderCache.ReturnAndFree (result);
}
public virtual bool CanActivate {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/Ambience.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/Ambience.cs
index b48f83becd..5f50205a70 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/Ambience.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/Ambience.cs
@@ -106,9 +106,9 @@ namespace MonoDevelop.Ide.TypeSystem
if (String.IsNullOrEmpty (str))
return string.Empty;
- var sb = StringBuilderCache.New ();
+ var sb = StringBuilderCache.Allocate ();
MarkupUtilities.AppendEscapedString (sb, str, 0, str.Length);
- return sb.ToString ();
+ return StringBuilderCache.ReturnAndFree(sb);
}
#region Documentation
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MarkupUtilities.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MarkupUtilities.cs
index 5331637730..2cc64ee033 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MarkupUtilities.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MarkupUtilities.cs
@@ -40,7 +40,7 @@ namespace MonoDevelop.Ide.TypeSystem
static string EscapedApostrophe = "&apos;";
static string EscapedQuote = "&quot;";
- public static void AppendEscapedString (CachedStringBuilder builder, string toEscape, int start, int count)
+ public static void AppendEscapedString (StringBuilder builder, string toEscape, int start, int count)
{
if (toEscape == null)
return;