Skip to content

Commit

Permalink
UserData: Cache descriptors. Slight optimise Dictionary->Table conver…
Browse files Browse the repository at this point in the history
…sion
  • Loading branch information
CallumDev committed Aug 17, 2023
1 parent c15a84f commit 34e859c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/WattleScript.Interpreter/DataTypes/Table.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using WattleScript.Interpreter.Interop.Converters;

namespace WattleScript.Interpreter
{
Expand Down Expand Up @@ -242,7 +243,7 @@ LinkedListNode<TablePair> MapFind(DynValue key)
return pair;
}

void MapAdd(DynValue key, DynValue value)
internal void MapAdd(DynValue key, DynValue value)
{
var node = valueList.AddLast(new TablePair(key, value));
valueMap.Add(key, node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal static Table ConvertIDictionaryToTable(Script script, System.Collection
{
DynValue key = ClrToScriptConversions.ObjectToDynValue(script, kvp.Key);
DynValue val = ClrToScriptConversions.ObjectToDynValue(script, kvp.Value);
t.Set(key, val);
t.MapAdd(key, val);
}

return t;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ private static IUserDataDescriptor PerformRegistration(Type type, IUserDataDescr

if (result != oldDescriptor)
{
lock (cache_Lock) {
_descriptorCacheInterfaces = new Dictionary<Type, IUserDataDescriptor>();
_descriptorCacheNoInterfaces = new Dictionary<Type, IUserDataDescriptor>();
}

if (result == null)
{
s_TypeRegistry.Remove(type);
Expand Down Expand Up @@ -227,22 +232,51 @@ internal static InteropAccessMode ResolveDefaultAccessModeForType(InteropAccessM
}


private static Dictionary<Type, IUserDataDescriptor> _descriptorCacheNoInterfaces =
new Dictionary<Type, IUserDataDescriptor>();

private static Dictionary<Type, IUserDataDescriptor> _descriptorCacheInterfaces =
new Dictionary<Type, IUserDataDescriptor>();

private static object cache_Lock = new object();

internal static IUserDataDescriptor GetDescriptorForType(Type type, bool searchInterfaces)
{
lock (cache_Lock)
{
if (searchInterfaces && _descriptorCacheInterfaces.TryGetValue(type, out var cached))
return cached;
if (!searchInterfaces && _descriptorCacheNoInterfaces.TryGetValue(type, out cached))
return cached;
}
var created = GetDescriptorForType_Internal(type, searchInterfaces);
lock (cache_Lock)
{
if (searchInterfaces)
_descriptorCacheInterfaces[type] = created;
else
_descriptorCacheNoInterfaces[type] = created;
}

return created;
}


/// <summary>
/// Gets the best possible type descriptor for a specified CLR type.
/// </summary>
/// <param name="type">The CLR type for which the descriptor is desired.</param>
/// <param name="searchInterfaces">if set to <c>true</c> interfaces are used in the search.</param>
/// <returns></returns>
internal static IUserDataDescriptor GetDescriptorForType(Type type, bool searchInterfaces)
internal static IUserDataDescriptor GetDescriptorForType_Internal(Type type, bool searchInterfaces)
{
lock (s_Lock)
{
IUserDataDescriptor typeDescriptor = null;

// if the type has been explicitly registered, return its descriptor as it's complete
if (s_TypeRegistry.ContainsKey(type))
return s_TypeRegistry[type];
if (s_TypeRegistry.TryGetValue(type, out var existingType))
return existingType;

if (RegistrationPolicy.AllowTypeAutoRegistration(type))
{
Expand Down

0 comments on commit 34e859c

Please sign in to comment.