/* Function to add as well as update the records array */ public void UpdateType(mdr.ValueTypes type) { /* We do not track Undefined and Null values right now */ if (type == mdr.ValueTypes.Undefined || type == mdr.ValueTypes.Null) { return; } for (var i = 0; i < length; ++i) { if (records[i].type == type) { records[i].freq++; return; } } if (length < size) { records[length].type = type; records[length++].freq = 1; return; } missCount++; }
/* Returns the hotType if its freq crosses HOTNESS_THRESHOLD */ public mdr.ValueTypes GetHotType() { int maxCount = 0; int totalCount = 0; mdr.ValueTypes retVal = mdr.ValueTypes.DValueRef; if (missCount > MAX_MISS_COUNT) { return(mdr.ValueTypes.DValueRef); } for (var i = 0; i < length; ++i) { if (records[i].freq > maxCount) { retVal = records[i].type; maxCount = records[i].freq; } totalCount += records[i].freq; } if (totalCount != 0 && maxCount / totalCount > HOTNESS_THRESHOLD) { return(retVal); } else { return(mdr.ValueTypes.DValueRef); } }
protected Expression() : base() { ///NOTE: constructors must call the following after all class paramters are assigned. /// ValueType = CodeGen.TypeCalculator.GetType(this); /// It is important not to rely on virutal function here since we are in constructor! ValueType = mdr.ValueTypes.Unknown; }
public mdr.ValueTypes GetHotType() { if (_hotType == mdr.ValueTypes.Unknown) { _hotType = GetTypeWithHighestFreq(TypeProfile); } return(_hotType); }
/// <summary> /// To simplify code gen, we first put the value on the stack and then call this /// function which in turn uses Assign.Run functions to write to the callFrame.Value /// </summary> public void StoreValue(int index, mdr.ValueTypes valueType) { LoadValue(index, mdr.ValueTypes.DValueRef); //Console.WriteLine("{0}", valueType); if (valueType == mdr.ValueTypes.Known) { throw new JSDeoptFailedException(); } Call(CodeGen.Types.Operations.Assign.Get(valueType)); }
/// <summary> /// Loads the reference of the callFrame.Value[index] and if necessary calls the .AsT() on it /// </summary> public void LoadValue(int index, mdr.ValueTypes valueType = mdr.ValueTypes.DValueRef) { Ldarg_CallFrame(); Ldfld(CodeGen.Types.CallFrame.Values); Ldc_I4(index); Ldelema(CodeGen.Types.DValue.TypeOf); if (valueType != mdr.ValueTypes.DValueRef) { Call(CodeGen.Types.DValue.As(valueType)); } }
protected override void DeclareNonParamSymbol(JSSymbol symbol, mdr.ValueTypes symbolValueType, LocalBuilder contextMap) { if (symbol.SymbolType == JSSymbol.SymbolTypes.Global && _currFuncMetadata.EnableInlineCache) { if (_globalContext == null) { _globalContext = _localVars.Declare(Types.DObject.TypeOf, "__gc"); _ilGen.LoadRuntimeInstance(); _ilGen.Ldfld(Types.Runtime.GlobalContext); _ilGen.Stloc(_globalContext); } } else { base.DeclareNonParamSymbol(symbol, symbolValueType, contextMap); } }
void UpdateType(Expression expression, mdr.ValueTypes type) { var oldType = GetType(expression); var newType = TypeCalculator.ResolveType(oldType, type); if (oldType != newType) { m.Util.Diagnose.Debug.WriteLine("---->> Type of the expression {0} changed to {1}", expression.ToString(), newType.ToString()); SetType(expression, newType); if (type == mdr.ValueTypes.Unknown) { Enqueue(expression); } else { VisitUser(expression); } } }
public mdr.ValueTypes GetHotPrimitiveType() { if (_hotType == mdr.ValueTypes.Unknown) { var hotType = GetTypeWithHighestFreq(TypeProfile); if (hotType != mdr.ValueTypes.DValueRef && mdr.ValueTypesHelper.IsPrimitive(hotType) && hotType != mdr.ValueTypes.Undefined && hotType != mdr.ValueTypes.Null) { _hotType = hotType; } else { _hotType = mdr.ValueTypes.DValueRef; } } return(_hotType); }
void UpdateType(JSSymbol symbol, mdr.ValueTypes type) { if (type == mdr.ValueTypes.Unknown) { return; } var oldType = GetType(symbol); var newType = TypeCalculator.ResolveType(oldType, type); switch (newType) { case mdr.ValueTypes.Undefined: case mdr.ValueTypes.Null: case mdr.ValueTypes.Unknown: newType = mdr.ValueTypes.DValueRef; //All of these cases are handled by a DValue break; case mdr.ValueTypes.DValue: if (symbol.IsParameter) { //We already have a DValue as argument, so just need to point to that and use its storage newType = mdr.ValueTypes.DValueRef; } break; } if (oldType != newType) { m.Util.Diagnose.Debug.WriteLine("---->> Type of the symbol {0} changed to {1}", symbol.Name.ToString(), newType.ToString()); SetType(symbol, newType); //symbol.Types.Add(type); foreach (var r in symbol.Readers) { Enqueue(r); } } }
public void UpdateTypeProfile(GuardedCast node, mdr.ValueTypes type) { if (node.ProfileIndex < GuardProfileData.Count && node.ProfileIndex != -1) { var prof = GuardProfileData[node.ProfileIndex]; prof.UpdateNodeProfile(type); } else { GuardNodeProfile prof = new GuardNodeProfile(type); if (node.ProfileIndex == -1) { node.ProfileIndex = GuardProfileData.Count; GuardProfileData.Add(prof); jsMD.GuardProfileSize++; } else { _resizeProfileData <GuardNodeProfile>(GuardProfileData, node.ProfileIndex + 1, null); GuardProfileData[node.ProfileIndex] = prof; } } }
//############################################################################################################################### // Named local handling internal LocalBuilder Declare(mdr.ValueTypes type, string name) { return(Declare(Types.TypeOf(type), name)); }
public void SetType(Expression expression, mdr.ValueTypes type) { expression.ValueType = type; }
public void SetType(JSSymbol symbol, mdr.ValueTypes type) { symbol.ValueType = type; }
public void SetType(Expression expression, mdr.ValueTypes type) { ExpressionTypes[expression] = type; }
public void SetType(JSSymbol symbol, mdr.ValueTypes type) { SymbolTypes[symbol] = type; }
////Constructor //public GuardNodeProfile(mdr.ValueTypes type) //{ // TypeProfile.UpdateType(type); //} public void UpdateNodeProfile(mdr.ValueTypes type) { TypeProfile.UpdateType(type); }
/// <summary> /// Function in this region convert the top of the stack to the corresponding type. /// This is purely for CIL code generation and independent of JS semantics. /// </summary> protected virtual void AsX(mdr.ValueTypes type) { Debug.Assert(_result.ValueType == mdr.ValueTypes.DValueRef, "Make sure that the result type is DvalueRef before calling AsX."); _ilGen.Call(Types.DValue.As(type)); _result.ValueType = type; }
public static int RunAndUpdateBinaryOperationIC(ref mdr.CallFrame callFrame, int index, IR.NodeType nodeType, int resultIndex, mdr.ValueTypes i0Type, mdr.ValueTypes i1Type, bool i0TypeCheck, bool i1TypeCheck) { var ilGen = JSRuntime.Instance.AsmGenerator.GetILGenerator(); var funcMetadata = callFrame.Function.Metadata; var methodName = funcMetadata.FullName + "__" + index.ToString(); ilGen.BeginICMethod(methodName); CreateBinaryOperationIC(ilGen, nodeType, resultIndex, i0Type, i1Type, i0TypeCheck, i1TypeCheck); ilGen.Ldc_I4(index + 1); ilGen.Ret(); ilGen.WriteComment("Reinstalling this at index {0}", index); var m = ilGen.EndICMethod((JSFunctionMetadata)funcMetadata); funcMetadata.InlineCache[index] = m; return(m(ref callFrame, index)); }
public JSIntrinsicImp(mdr.ValueTypes returnType, string name, Action <ILGen.BaseILGenerator, Expressions.MethodCall> execute) { ReturnType = returnType; Name = name; Execute = execute; }
string TypeName(mdr.ValueTypes t, bool addCaret) { return(TypeName(CodeGen.Types.TypeOf(t), addCaret)); }
//############################################################################################################################### // temporary local handling internal LocalBuilder PushTemporary(mdr.ValueTypes type) { return(PushTemporary(Types.TypeOf(type))); }
//############################################################################################################################### // Symbols' local handling internal LocalBuilder Declare(mdr.ValueTypes type, JSSymbol symbol) { return(Declare(Types.TypeOf(type), symbol)); }
//############################################################################################################################### // Unnamed local handling internal LocalBuilder Declare(mdr.ValueTypes type, IR.WriteTemporaryExpression temporary) { return(Declare(Types.TypeOf(type), temporary)); }
protected override void PerformLookup(ReadIndexerExpression node, LocalBuilder obj, mdr.ValueTypes objType, mdr.ValueTypes indexType, LocalBuilder value) { if (objType == mdr.ValueTypes.Array && indexType == mdr.ValueTypes.Int32) { base.PerformLookup(node, obj, objType, indexType, value); } else { _ilGen.Callvirt(Types.DObject.GetPropertyDescriptor.Get(_result.ValueType)); //_ilGen.Callvirt(Types.DObject.GetField(_result.ValueType)); int profIndex = _currFuncMetadata.GetProfileIndex(node); _ilGen.Ldloc(_profiler); _ilGen.Ldc_I4(profIndex); _ilGen.Ldloc(obj); _ilGen.Call(Types.DObject.GetMap); _ilGen.Call(Types.Operations.Internals.UpdateMapProfile); _ilGen.Ldloc(obj); _ilGen.Ldloca(value); _ilGen.Callvirt(Types.PropertyDescriptor.Get_DObject_DValueRef); } }
protected MethodCacheBase(Type declaringType, string methodName, int numberOfOperands, bool hasOutput) { TypeOf = declaringType; MethodName = methodName; NumberOfOperands = numberOfOperands; _methods = new Dictionary<int, MethodInfo>(); _returnTypes = new Dictionary<int, mdr.ValueTypes>(); _uniqueReturnType = mdr.ValueTypes.Undefined; foreach (var m in TypeOf.GetMethods()) { if (m.Name != MethodName) continue; var parameters = m.GetParameters(); Debug.Assert(parameters.Length >= NumberOfOperands, "Method {0} has {1} parameters which is less than expected {2}", m, parameters.Length, NumberOfOperands); var key = GetKey(m); Debug.Assert(!_methods.ContainsKey(key), "Method {0} in {1} is already in the hash!", m, m.DeclaringType.FullName); _methods[key] = m; mdr.ValueTypes returnType; if (hasOutput) { if (m.ReturnType == Types.ClrSys.Void || m.ReturnType == null) { Debug.Assert(parameters.Length > NumberOfOperands, "Method {0} has no return value and no reference parameter", m); var refParameterIndex = NumberOfOperands; //parameters.Length-1; returnType = ValueTypeOf(parameters[refParameterIndex].ParameterType); Debug.Assert(returnType == mdr.ValueTypes.DValueRef, "Method {0} has invalid reference parameter type {1} at position {2}", m, returnType, refParameterIndex); } else returnType = ValueTypeOf(m.ReturnType); } else { Debug.Assert(m.ReturnType == Types.ClrSys.Void || m.ReturnType == null, "Constructor says method does not have output, but {0} has a return value!", m); returnType = mdr.ValueTypes.Unknown; } _returnTypes[key] = returnType; //Previous assert guarantees that we don't have the key here as well if (_uniqueReturnType == mdr.ValueTypes.Undefined) _uniqueReturnType = returnType; else if (_uniqueReturnType != returnType) _uniqueReturnType = mdr.ValueTypes.Unknown; } }
bool HasTypeChanged(Expression expression, mdr.ValueTypes oldType) { var expressionValueType = GetType(expression); return(oldType != expressionValueType); }
public void SetType(JSSymbol symbol, mdr.ValueTypes type) { _cgInfo.SetType(symbol, type); }
public void SetType(Expression expression, mdr.ValueTypes type) { _cgInfo.SetType(expression, type); }
internal static JSIntrinsicImp Add(mdr.ValueTypes returnType, string name, Action <ILGen.BaseILGenerator, Expressions.MethodCall> execute) { return(Add(new JSIntrinsicImp(returnType, name, execute))); }
public static void CreateBinaryOperationIC(ILGen.BaseILGenerator ilGen, IR.NodeType nodeType, int resultIndex, mdr.ValueTypes i0Type, mdr.ValueTypes i1Type, bool i0TypeCheck, bool i1TypeCheck) { ilGen.WriteComment("IC method for {0}({1}, {2}) written to {3}", nodeType, i0Type, i0Type, resultIndex); var values = ilGen.DeclareLocal(CodeGen.Types.DValue.ArrayOf); ilGen.Ldarg_CallFrame(); ilGen.Ldfld(CodeGen.Types.CallFrame.Values); ilGen.Stloc(values); ///Try to make a better guess on the unknown types. if (i0Type == mdr.ValueTypes.DValueRef) { if (i1Type != mdr.ValueTypes.DValueRef) { i0Type = i1Type; } else { i0Type = i1Type = mdr.ValueTypes.Int32; //Just a guess! } } else if (i1Type == mdr.ValueTypes.DValueRef) { i1Type = i0Type; } var t0 = ilGen.DeclareLocal(CodeGen.Types.ClrSys.Int32); //if (i0TypeCheck) { LoadValue(ilGen, values, resultIndex, mdr.ValueTypes.DValueRef); ilGen.Call(CodeGen.Types.DValue.GetValueType); ilGen.Stloc(t0); } var t1 = ilGen.DeclareLocal(CodeGen.Types.ClrSys.Int32); //if (i0TypeCheck) { LoadValue(ilGen, values, resultIndex + 1, mdr.ValueTypes.DValueRef); ilGen.Call(CodeGen.Types.DValue.GetValueType); ilGen.Stloc(t1); } var guardFail = ilGen.DefineLabel(); var done = ilGen.DefineLabel(); ilGen.Ldloc(t0); ilGen.Ldc_I4(8); ilGen.Shl(); ilGen.Ldloc(t1); ilGen.Or(); ilGen.Ldc_I4(((int)i0Type << 8) | (int)i1Type); ilGen.Bne_Un(guardFail); var operation = CodeGen.Types.Operations.Binary.Get(nodeType); var mi = operation.Get(i0Type, i1Type); var returnType = operation.ReturnType(i0Type, i1Type); if (returnType == mdr.ValueTypes.DValueRef) { Debug.Assert(mi.GetParameters().Length == 3 && mi.GetParameters()[2].ParameterType == CodeGen.Types.TypeOf(mdr.ValueTypes.DValueRef), "Invalid situation, method {0} must get a third parameter of type 'ref DValue'", mi); LoadValue(ilGen, values, resultIndex, i0Type); LoadValue(ilGen, values, resultIndex + 1, i1Type); LoadValue(ilGen, values, resultIndex, mdr.ValueTypes.DValueRef); ilGen.Call(mi); } else { LoadValue(ilGen, values, resultIndex, mdr.ValueTypes.DValueRef); LoadValue(ilGen, values, resultIndex, i0Type); LoadValue(ilGen, values, resultIndex + 1, i1Type); ilGen.Call(mi); ilGen.Call(CodeGen.Types.DValue.Set.Get(returnType)); } ilGen.Br(done); ilGen.MarkLabel(guardFail); ilGen.Ldarg_CallFrame(); ilGen.Ldarg_1(); ilGen.Ldc_I4((int)nodeType); ilGen.Ldc_I4(resultIndex); ilGen.Ldloc(t0); ilGen.Ldloc(t1); ilGen.Ldc_I4(i0TypeCheck); ilGen.Ldc_I4(i1TypeCheck); ilGen.Call(CodeGen.Types.Operations.ICMethods.RunAndUpdateBinaryOperationIC); ilGen.Ret(); ilGen.MarkLabel(done); }