Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize global identifier access a bit and reduce allocations #741

Merged
merged 7 commits into from
May 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jint/Collections/HybridDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal class HybridDictionary<TValue> : IEnumerable<KeyValuePair<Key, TValue>>

private readonly bool _checkExistingKeys;
private ListDictionary<TValue> _list;
private StringDictionarySlim<TValue> _dictionary;
internal StringDictionarySlim<TValue> _dictionary;

public HybridDictionary() : this(0, checkExistingKeys: true)
{
Expand Down
6 changes: 0 additions & 6 deletions Jint/JsValueExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public static string AsString(this JsValue value)
ThrowWrongTypeException(value, "string");
}

return AsStringWithoutTypeCheck(value);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static string AsStringWithoutTypeCheck(this JsValue value)
{
return value.ToString();
}

Expand Down
4 changes: 2 additions & 2 deletions Jint/Native/Global/GlobalObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -754,9 +754,9 @@ internal bool Set(Key property, JsValue value)
// here we are called only from global environment record context
// we can take some shortcuts to be faster

if (!Properties.TryGetValue(property, out var existingDescriptor))
if (!_properties.TryGetValue(property, out var existingDescriptor))
{
Properties[property] = new PropertyDescriptor(value, PropertyFlag.ConfigurableEnumerableWritable);
_properties[property] = new PropertyDescriptor(value, PropertyFlag.ConfigurableEnumerableWritable);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/JsValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ public JsValueDebugView(JsValue value)
Value = ((JsBoolean) value)._value + " (bool)";
break;
case Types.String:
Value = value.AsStringWithoutTypeCheck() + " (string)";
Value = value.ToString() + " (string)";
break;
case Types.Number:
Value = ((JsNumber) value)._value + " (number)";
Expand Down
8 changes: 4 additions & 4 deletions Jint/Native/Json/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public JsValue Serialize(JsValue value, JsValue replacer, JsValue space)
string item = null;
if (v.IsString())
{
item = v.AsStringWithoutTypeCheck();
item = v.ToString();
}
else if (v.IsNumber())
{
Expand Down Expand Up @@ -105,7 +105,7 @@ public JsValue Serialize(JsValue value, JsValue replacer, JsValue space)
}
else if (space.IsString())
{
var stringSpace = space.AsStringWithoutTypeCheck();
var stringSpace = space.ToString();
_gap = stringSpace.Length <= 10 ? stringSpace : stringSpace.Substring(0, 10);
}
else
Expand Down Expand Up @@ -177,7 +177,7 @@ private JsValue Str(JsValue key, ObjectInstance holder)

if (value.IsString())
{
return Quote(value.AsStringWithoutTypeCheck());
return Quote(value.ToString());
}

if (value.IsNumber())
Expand Down Expand Up @@ -264,7 +264,7 @@ private string SerializeArray(ArrayInstance value)
var strP = Str(TypeConverter.ToString(i), value);
if (strP.IsUndefined())
strP = "null";
partial.Add(strP.AsStringWithoutTypeCheck());
partial.Add(strP.ToString());
}
if (partial.Count == 0)
{
Expand Down
29 changes: 15 additions & 14 deletions Jint/Native/Object/ObjectInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ObjectInstance : JsValue, IEquatable<ObjectInstance>
private bool _initialized;
private readonly ObjectClass _class;

private PropertyDictionary _properties;
internal PropertyDictionary _properties;
internal SymbolDictionary _symbols;

internal ObjectInstance _prototype;
Expand Down Expand Up @@ -317,11 +317,6 @@ internal JsValue UnwrapJsValue(PropertyDescriptor desc)

internal static JsValue UnwrapJsValue(PropertyDescriptor desc, JsValue thisObject)
{
if (desc == PropertyDescriptor.Undefined)
{
return Undefined;
}

var value = (desc._flags & PropertyFlag.CustomJsValue) != 0
? desc.CustomValue
: desc._value;
Expand All @@ -333,6 +328,15 @@ internal static JsValue UnwrapJsValue(PropertyDescriptor desc, JsValue thisObjec
return value ?? Undefined;
}

return UnwrapFromGetter(desc, thisObject);
}

/// <summary>
/// A rarer case.
/// </summary>
[MethodImpl(MethodImplOptions.NoInlining)]
private static JsValue UnwrapFromGetter(PropertyDescriptor desc, JsValue thisObject)
{
var getter = desc.Get ?? Undefined;
if (getter.IsUndefined())
{
Expand Down Expand Up @@ -457,10 +461,7 @@ public override bool Set(JsValue property, JsValue value, JsValue receiver)
{
return parent.Set(property, value, receiver);
}
else
{
ownDesc = new PropertyDescriptor(Undefined, PropertyFlag.ConfigurableEnumerableWritable);
}
ownDesc = new PropertyDescriptor(Undefined, PropertyFlag.ConfigurableEnumerableWritable);
}

if (ownDesc.IsDataDescriptor())
Expand Down Expand Up @@ -506,7 +507,7 @@ public override bool Set(JsValue property, JsValue value, JsValue receiver)

return true;
}

/// <summary>
/// Returns a Boolean value indicating whether a
/// [[Put]] operation with PropertyName can be
Expand Down Expand Up @@ -681,6 +682,7 @@ protected static bool ValidateAndApplyPropertyDescriptor(ObjectInstance o, JsVal
};
}

propertyDescriptor._flags |= desc._flags & PropertyFlag.MutableBinding;
o.SetOwnProperty(property, propertyDescriptor);
}
else
Expand All @@ -697,7 +699,7 @@ protected static bool ValidateAndApplyPropertyDescriptor(ObjectInstance o, JsVal
var currentSet = current.Set;
var currentValue = current.Value;

if ((current._flags & PropertyFlag.ConfigurableSet | PropertyFlag.EnumerableSet | PropertyFlag.WritableSet) == 0 &&
if ((current._flags & (PropertyFlag.ConfigurableSet | PropertyFlag.EnumerableSet | PropertyFlag.WritableSet)) == 0 &&
ReferenceEquals(currentGet, null) &&
ReferenceEquals(currentSet, null) &&
ReferenceEquals(currentValue, null))
Expand Down Expand Up @@ -797,7 +799,6 @@ protected static bool ValidateAndApplyPropertyDescriptor(ObjectInstance o, JsVal

if (o is object)
{

if (!ReferenceEquals(descValue, null))
{
current.Value = descValue;
Expand All @@ -817,7 +818,7 @@ protected static bool ValidateAndApplyPropertyDescriptor(ObjectInstance o, JsVal
{
current.Configurable = desc.Configurable;
}

PropertyDescriptor mutable = null;
if (!ReferenceEquals(descGet, null))
{
Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/String/StringInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public override PropertyDescriptor GetOwnProperty(JsValue property)
return PropertyDescriptor.Undefined;
}

var str = PrimitiveValue.AsStringWithoutTypeCheck();
var str = PrimitiveValue.ToString();
var number = TypeConverter.ToNumber(property);
if (!IsInt32(number, out var index) || index < 0 || index >= str.Length)
{
Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/String/StringPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ private JsValue Concat(JsValue thisObj, JsValue[] arguments)
{
if (arguments[i].Type == Types.String)
{
capacity += arguments[i].AsStringWithoutTypeCheck().Length;
capacity += arguments[i].ToString().Length;
}
}

Expand Down
4 changes: 2 additions & 2 deletions Jint/Runtime/Environments/DeclarativeEnvironmentRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public sealed override bool HasBinding(string name)
}

internal sealed override bool TryGetBinding(
BindingName name,
in BindingName name,
bool strict,
out Binding binding,
out JsValue value)
Expand Down Expand Up @@ -65,7 +65,7 @@ public sealed override void InitializeBinding(string name, JsValue value)
_dictionary[name] = binding.ChangeValue(value);
}

internal override void SetMutableBinding(BindingName name, JsValue value, bool strict)
internal override void SetMutableBinding(in BindingName name, JsValue value, bool strict)
{
SetMutableBinding(name.Key.Name, value, strict);
}
Expand Down
6 changes: 3 additions & 3 deletions Jint/Runtime/Environments/EnvironmentRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected EnvironmentRecord(Engine engine) : base(InternalTypes.ObjectEnvironmen
public abstract bool HasBinding(string name);

internal abstract bool TryGetBinding(
BindingName name,
in BindingName name,
bool strict,
out Binding binding,
out JsValue value);
Expand Down Expand Up @@ -57,7 +57,7 @@ protected EnvironmentRecord(Engine engine) : base(InternalTypes.ObjectEnvironmen
/// <param name="strict">The identify strict mode references.</param>
public abstract void SetMutableBinding(string name, JsValue value, bool strict);

internal abstract void SetMutableBinding(BindingName name, JsValue value, bool strict);
internal abstract void SetMutableBinding(in BindingName name, JsValue value, bool strict);

/// <summary>
/// Returns the value of an already existing binding from an environment record.
Expand Down Expand Up @@ -107,7 +107,7 @@ public override bool Equals(JsValue other)
/// <summary>
/// Helper to cache JsString/Key when environments use different lookups.
/// </summary>
internal class BindingName
internal readonly struct BindingName
{
public readonly Key Key;
public readonly JsString StringValue;
Expand Down
2 changes: 1 addition & 1 deletion Jint/Runtime/Environments/FunctionEnvironmentRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ private void HandleObjectPattern(bool initiallyEmpty, JsValue argument, ObjectPa
propertyName = ExceptionHelper.ThrowArgumentOutOfRangeException<JsString>("property", "unknown object pattern property type");
}

processedProperties?.Add(propertyName.AsStringWithoutTypeCheck());
processedProperties?.Add(propertyName.ToString());
jsValues[0] = argumentObject.Get(propertyName);
SetFunctionParameter(p.Value, jsValues, 0, initiallyEmpty);
}
Expand Down