public void Add(PropertyDescriptor property, PropertyMap map) { var index = GetIndex(property.NameId); var line = _lines[index]; if (line == null) _lines[index] = line = new LineItem(); line.Property = property; line.Map = map; }
public PropertyMapMetadata(DObject prototype) { Prototype = prototype; if (Prototype == null) Level = 0; else Level = Prototype.Map.Metadata.Level + 1; //We create an empty ProperyDescriptor to avoid checking for null all the time Root = new PropertyMap(this, null, new PropertyDescriptor(null, Runtime.InvalidFieldId, Runtime.InvalidFieldIndex, PropertyDescriptor.Attributes.NotEnumerable | PropertyDescriptor.Attributes.Undefined), null); }
///// <summary> ///// List of all DTypes whose prorotype is using this DType! ///// </summary> //LinkedList<WeakReference> _subTypes; ///// <summary> ///// Number of actual fields (as opposed to inherited fields that might be added) ///// if (DObject.DType==this) DObject.Fields.Length >= this.OwnFiledsCount; ///// </summary> //public int OwnFieldsCount { get; private set; } internal PropertyMap(PropertyMapMetadata metadata, PropertyMap parent, PropertyDescriptor property, PropertyDescriptor overriddenProperty) { Metadata = metadata; Parent = parent; Property = property; OverriddenPropery = overriddenProperty; UniqueId = _uniqueIdCounter++; Debug.Assert(Metadata != null, "PropertyMap.Metadata cannot be null"); Debug.Assert(Property != null, "PropertyMap.Property cannot be null"); }
public PropertyDescriptor Get(int fieldId, PropertyMap map) { var index = GetIndex(fieldId); var line = _lines[index]; if ( line == null || line.Map != map || line.Property.NameId != fieldId ) { return null; } return line.Property; }
protected Runtime(RuntimeConfiguration configuration) { _inheritPropertyObjectCacheMaxIndex = 0; //We need to first set the Instance since the following constructors may use it! Runtime.Instance = this; Configuration = configuration; configuration.ParseArgs();//Do this now before anyone tries to read any configuration value. if (configuration.EnableTimers) { Timers = new m.Util.Timers(); _timer = StartSimpleTimer(true, "MCJS"); } if (configuration.EnableCounters) Counters = new m.Util.Counters(); EmptyPropertyMapMetadata = new PropertyMapMetadata(null); ///We can initialize commong field Ids to save lookups later ValueOfFieldId = GetFieldId("valueOf"); ToStringFieldId = GetFieldId("toString"); PrototypeFieldId = GetFieldId("prototype"); LengthFieldId = GetFieldId("length"); ///In each instance of Runtime we need to first reset prototypes in case a program has changed them //DUndefinedPrototype = new DObject(root.Root); DObjectPrototype = new DObject(EmptyPropertyMapMetadata.Root); DObjectMap = GetRootMapOfPrototype(DObjectPrototype); DFunctionPrototype = new DObject(DObjectMap); DFunctionMap = GetRootMapOfPrototype(DFunctionPrototype); DNumberPrototype = new DObject(DObjectMap); DNumberMap = GetRootMapOfPrototype(DNumberPrototype); DStringPrototype = new DObject(DObjectMap); DStringMap = GetRootMapOfPrototype(DStringPrototype); DBooleanPrototype = new DObject(DObjectMap); DBooleanMap = GetRootMapOfPrototype(DBooleanPrototype); DArrayPrototype = new DObject(DObjectMap); DArrayMap = GetRootMapOfPrototype(DArrayPrototype); DRegExpPrototype = new DObject(DObjectMap); DRegExpMap = GetRootMapOfPrototype(DRegExpPrototype); //Now need to recreate default values based on fresh prototypes. DefaultDUndefined = new DUndefined(); DefaultDNull = new DNull(); //DefaultDObject = new DObject(); //DefaultDDouble = new DDouble(default(double)); //DefaultDString = new DString(default(string)); //DefaultDInt = new DInt(default(int)); //DefaultDBoolean = new DBoolean(default(bool)); //DefaultDFunction = new DFunction(null); //DefaultDArray = new DArray(); //DefaultDProperty = new DProperty(); ArrayItemAccessor = new PropertyDescriptor(null) { Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { value = (obj as DArray).Elements[pd.Index]; /*if (mdr.Runtime.Instance.Configuration.ProfileStats) { mdr.Runtime.Instance.Counters.GetCounter("ArrayItemAccessor").Count++; }*/ }, Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { (obj as DArray).Elements[pd.Index] = value; }, }; StringItemAccessor = new PropertyDescriptor(null) { Getter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { var strObj = obj.FirstInPrototypeChainAs<DString>(); value.Set(strObj.PrimitiveValue.AsString()[pd.Index]); }, Setter = (mdr.PropertyDescriptor pd, mdr.DObject obj, ref mdr.DValue value) => { var strObj = obj.FirstInPrototypeChainAs<DString>(); var chars = strObj.PrimitiveValue.AsString().ToCharArray(); chars[pd.Index] = value.AsChar(); strObj.PrimitiveValue.Set(new String(chars)); }, }; var lengthFieldName = GetFieldName(LengthFieldId); ProtoInitializer.InitDArrayPrototype(DArrayPrototype, lengthFieldName); ProtoInitializer.InitDStringPrototype(DStringPrototype, lengthFieldName); var protoFieldName = GetFieldName(PrototypeFieldId); ProtoInitializer.InitDFunctionPrototype(DFunctionPrototype, protoFieldName, PrototypeFieldId); }
static public void UpdateLastAcessedPropertyCache(int index, PropertyMap map, PropertyDescriptor pd) { //We need to check the index and extent or map if needed. //index &=0xFFFF _lastAccessedPropertyCache[index].Map = map; _lastAccessedPropertyCache[index].Map = map; _lastAccessedPropertyCache[index].PropDesc = pd; }
static public PropertyDescriptor LookupLastAcessedPropertyCacheForWrite(int index, PropertyMap map, out PropertyMap newMap) { #if __STAT__PD if (Runtime.Instance.Configuration.ProfileStats) { Runtime.Instance.Counters.GetCounter("Last PDCache write_accesses").Count++; } #endif newMap = null; var line = _lastAccessedPropertyCache[index]; //We are going to use this many times, so we can pay the overhead of copy if (line.Map == map) { #if __STAT__PD if (Runtime.Instance.Configuration.ProfileStats) { Runtime.Instance.Counters.GetCounter("Last PDCache write_hits").Count++; if (line.PropDesc.IsInherited) { Runtime.Instance.Counters.GetCounter("Last PDCache inherited write_hits").Count++; } } #endif return line.PropDesc; } else if (line.Map != null) { if (line.Map.Parent == map) { #if __STAT__PD if (Runtime.Instance.Configuration.ProfileStats) { Runtime.Instance.Counters.GetCounter("Last PDCache write_hits").Count++; if (line.PropDesc.IsInherited) { Runtime.Instance.Counters.GetCounter("Last PDCache inherited write_hits").Count++; } } #endif newMap = line.Map; return line.PropDesc; } } return null; }
//#if __MonoCS__ // [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] //#endif static public PropertyDescriptor LookupLastAcessedPropertyCacheForRead(int index, PropertyMap map) { #if __STAT__PD if (Runtime.Instance.Configuration.ProfileStats) { Runtime.Instance.Counters.GetCounter("Last PDCache read_accesses").Count++; } #endif if (_lastAccessedPropertyCache[index].Map == map) { #if __STAT__PD if (Runtime.Instance.Configuration.ProfileStats) { Runtime.Instance.Counters.GetCounter("Last PDCache read_hits").Count++; if (_lastAccessedPropertyCache[index].PropDesc.IsInherited) { Runtime.Instance.Counters.GetCounter("Last PDCache inherited read_hits").Count++; } } #endif return _lastAccessedPropertyCache[index].PropDesc; } return null; }
public static void UpdateMapProfileForWrite(DObject obj, mjr.CodeGen.Profiler profiler, int profileIndex, int fieldId, PropertyMap oldMap) { if (profiler != null) { if (obj.Map == oldMap) { PropertyDescriptor pd = obj.GetPropertyDescriptorByFieldId(fieldId); // obj.GetPropertyDescriptor // Trace.WriteLine("YYY"); profiler.GetOrAddMapNodeProfile(profileIndex).UpdateNodeProfile(oldMap, pd); } } }
public static PropertyDescriptor UpdateMapProfile(PropertyDescriptor pd, mjr.CodeGen.Profiler profiler, int profileIndex, PropertyMap map) { if (profiler != null) { profiler.GetOrAddMapNodeProfile(profileIndex).UpdateNodeProfile(map, pd); } return pd; }
/// <summary> /// This method is public for the compiler to generate faster code by directly manipulating the map when needed /// </summary> public PropertyMap AddOwnProperty(string field, int fieldId, PropertyDescriptor.Attributes attributes) { Debug.Assert(fieldId != Runtime.InvalidFieldId, "Invalid situation! FieldId of {0} is not assigned", field); Debug.Assert(GetOwnPropertyDescriptorByFieldId(fieldId) == null, "Invalid situation! Field {0} alread exists in the map", field); PropertyMap newMap = null; if (_children == null) _children = new Dictionary<int, PropertyMap>(); int key = ((int)attributes << 16) | (fieldId & 0xFFFF); if (!_children.TryGetValue(key, out newMap)) { var overridenProperty = Metadata.GetInheritedPropertyDescriptorByFieldId(fieldId); newMap = new PropertyMap(Metadata, this, new PropertyDescriptor(field, fieldId, this.Property.Index + 1, attributes), overridenProperty); _children[key] = newMap; } return newMap; }
private PropertyMap DeleteOwnPropertyDescriptor(DObject obj, PropertyMap currMap, PropertyMap delMap) { Debug.Assert(delMap != null, "Invalid situation!"); ///In this function, we recursively add all the properties between the delMap, and this to the delMap.Parent ///currMap==this would be the end of recursion ///at the end we need to propagate the deletion to all objects whose prototype is obj var newMap = (delMap == currMap.Parent || delMap == currMap) ? delMap.Parent : DeleteOwnPropertyDescriptor(obj, currMap.Parent, delMap); if (delMap != this) { var currPropDesc = currMap.Property; newMap = newMap.AddOwnProperty(currPropDesc.Name, currPropDesc.NameId, currPropDesc.GetAttributes()); } if (currMap == this) { Debug.Assert(this.Property.Index == newMap.Property.Index + 1, "Invalid situation, we should delete on one field here!"); obj.Map = newMap; if (delMap != this) //otherwise it is just the last field so no need to copy Array.Copy(obj.Fields, delMap.Property.Index + 1, obj.Fields, delMap.Property.Index, this.Property.Index - delMap.Property.Index); var mapMetadata = Metadata.GetMapMetadataOfPrototype(obj, false); if (mapMetadata != null) mapMetadata.PropagateDeletionDownPrototypeChain(obj, delMap.Property); } return newMap; }