Chromium Code Reviews| Index: runtime/observatory/lib/src/service/object.dart |
| diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart |
| index 525b1b7d1402b7e3ef217b6bb521bf87f984b884..8ccd631b9ac65ad5343911325fa3fdfe574e414f 100644 |
| --- a/runtime/observatory/lib/src/service/object.dart |
| +++ b/runtime/observatory/lib/src/service/object.dart |
| @@ -93,7 +93,7 @@ class FakeVMRpcException extends RpcException { |
| } |
| /// A [ServiceObject] represents a persistent object within the vm. |
| -abstract class ServiceObject extends Observable { |
| +abstract class ServiceObject extends Observable implements M.ObjectRef { |
| static int LexicalSortName(ServiceObject o1, ServiceObject o2) { |
| return o1.name.compareTo(o2.name); |
| } |
| @@ -267,8 +267,10 @@ abstract class ServiceObject extends Observable { |
| case 'Socket': |
| obj = new Socket._empty(owner); |
| break; |
| + case 'Sentinel': |
| + obj = new Sentinel._empty(owner); |
| + break; |
| case 'Instance': |
| - case 'Sentinel': // TODO(rmacnak): Separate this out. |
| obj = new Instance._empty(owner); |
| break; |
| default: |
| @@ -2390,13 +2392,126 @@ class Class extends HeapObject implements M.Class { |
| String toString() => 'Class($vmName)'; |
| } |
| +M.InstanceKind stringToInstanceKind(String s) { |
| + switch (s) { |
| + case 'PlainInstance': |
| + return M.InstanceKind.plainInstance; |
| + case 'Null': |
| + return M.InstanceKind.vNull; |
| + case 'Bool': |
| + return M.InstanceKind.bool; |
| + case 'Double': |
| + return M.InstanceKind.double; |
| + case 'Int': |
| + return M.InstanceKind.int; |
| + case 'String': |
| + return M.InstanceKind.string; |
| + case 'List': |
| + return M.InstanceKind.list; |
| + case 'Map': |
| + return M.InstanceKind.map; |
| + case 'Float32x4': |
| + return M.InstanceKind.float32x4; |
| + case 'Float64x2': |
| + return M.InstanceKind.float64x2; |
| + case 'Int32x4': |
| + return M.InstanceKind.int32x4; |
| + case 'Uint8ClampedList': |
| + return M.InstanceKind.uint8ClampedList; |
| + case 'Uint8List': |
| + return M.InstanceKind.uint8List; |
| + case 'Uint16List': |
| + return M.InstanceKind.uint16List; |
| + case 'Uint32List': |
| + return M.InstanceKind.uint32List; |
| + case 'Uint64List': |
| + return M.InstanceKind.uint64List; |
| + case 'Int8List': |
| + return M.InstanceKind.int8List; |
| + case 'Int16List': |
| + return M.InstanceKind.int16List; |
| + case 'Int32List': |
| + return M.InstanceKind.int32List; |
| + case 'Int64List': |
| + return M.InstanceKind.int64List; |
| + case 'Float32List': |
| + return M.InstanceKind.float32List; |
| + case 'Float64List': |
| + return M.InstanceKind.float64List; |
| + case 'Int32x4List': |
| + return M.InstanceKind.int32x4List; |
| + case 'Float32x4List': |
| + return M.InstanceKind.float32x4List; |
| + case 'Float64x2List': |
| + return M.InstanceKind.float64x2List; |
| + case 'StackTrace': |
| + return M.InstanceKind.stackTrace; |
| + case 'Closure': |
| + return M.InstanceKind.closure; |
| + case 'MirrorReference': |
| + return M.InstanceKind.mirrorReference; |
| + case 'RegExp': |
| + return M.InstanceKind.regExp; |
| + case 'WeakProperty': |
| + return M.InstanceKind.weakProperty; |
| + case 'Type': |
| + return M.InstanceKind.type; |
| + case 'TypeParameter': |
| + return M.InstanceKind.typeParameter; |
| + case 'TypeRef': |
| + return M.InstanceKind.typeRef; |
| + case 'BoundedType': |
| + return M.InstanceKind.boundedType; |
| + } |
| + Logger.root.severe("Unrecognized InstanceKind: '$s'"); |
| + throw new FallThroughError(); |
| +} |
| + |
| +class Guarded<T> implements M.Guarded<T> { |
| + bool get isValue => asValue != null; |
| + bool get isSentinel => asSentinel != null; |
| + final Sentinel asSentinel; |
| + final T asValue; |
| + |
| + factory Guarded(ServiceObject obj) { |
| + if (obj is Sentinel) { |
| + return new Guarded.fromSentinel(obj); |
| + } else if (obj is T) { |
| + return new Guarded.fromValue(obj); |
| + } |
| + throw new Exception('${obj.type} is neither Sentinel or $T'); |
| + } |
| + |
| + Guarded.fromSentinel(this.asSentinel) |
| + : asValue = null; |
| + Guarded.fromValue(this.asValue) |
| + : asSentinel = null; |
| +} |
| + |
| +class BoundField implements M.BoundField { |
| + final Field decl; |
| + final Guarded<Instance> value; |
| + BoundField(this.decl, value) |
| + : value = new Guarded(value); |
| +} |
| + |
| +class MapAssociation implements M.MapAssociation { |
| + final Guarded<Instance> key; |
| + final Guarded<Instance> value; |
| + MapAssociation(key, value) |
| + : key = new Guarded(key), |
| + value = new Guarded(value); |
| +} |
| + |
| class Instance extends HeapObject implements M.Instance { |
| - @observable String kind; |
| + @observable M.InstanceKind kind; |
| @observable String valueAsString; // If primitive. |
| @observable bool valueAsStringIsTruncated; |
| - @observable ServiceFunction function; // If a closure. |
| + @observable ServiceFunction closureFunction; // If a closure. |
| @observable Context context; // If a closure. |
| @observable int length; // If a List, Map or TypedData. |
| + int count; |
| + int offset; |
| @observable Instance pattern; // If a RegExp. |
| @observable String name; |
| @@ -2407,12 +2522,12 @@ class Instance extends HeapObject implements M.Instance { |
| @observable Instance targetType; |
| @observable Instance bound; |
| - @observable var fields; |
| + @observable Iterable<BoundField> fields; |
|
Cutch
2016/08/15 23:27:08
If these are List use List instead of Iterable (he
cbernaschina
2016/08/16 00:01:44
It is for enforcing the "read only" nature of the
|
| @observable var nativeFields; |
| - @observable var elements; // If a List. |
| - @observable var associations; // If a Map. |
| - @observable var typedElements; // If a TypedData. |
| - @observable var referent; // If a MirrorReference. |
| + @observable Iterable<Guarded<ServiceObject>> elements; // If a List. |
| + @observable Iterable<MapAssociation> associations; // If a Map. |
| + @observable Iterable<dynamic> typedElements; // If a TypedData. |
| + @observable Instance referent; // If a MirrorReference. |
| @observable Instance key; // If a WeakProperty. |
| @observable Instance value; // If a WeakProperty. |
| @observable Breakpoint activationBreakpoint; // If a Closure. |
| @@ -2425,43 +2540,6 @@ class Instance extends HeapObject implements M.Instance { |
| @observable bool isCaseSensitive; // If a RegExp. |
| @observable bool isMultiLine; // If a RegExp. |
| - bool get isAbstractType { |
| - return (kind == 'Type' || kind == 'TypeRef' || |
| - kind == 'TypeParameter' || kind == 'BoundedType'); |
| - } |
| - bool get isNull => kind == 'Null'; |
| - bool get isBool => kind == 'Bool'; |
| - bool get isDouble => kind == 'Double'; |
| - bool get isString => kind == 'String'; |
| - bool get isInt => kind == 'Int'; |
| - bool get isList => kind == 'List'; |
| - bool get isMap => kind == 'Map'; |
| - bool get isTypedData { |
| - return kind == 'Uint8ClampedList' |
| - || kind == 'Uint8List' |
| - || kind == 'Uint16List' |
| - || kind == 'Uint32List' |
| - || kind == 'Uint64List' |
| - || kind == 'Int8List' |
| - || kind == 'Int16List' |
| - || kind == 'Int32List' |
| - || kind == 'Int64List' |
| - || kind == 'Float32List' |
| - || kind == 'Float64List' |
| - || kind == 'Int32x4List' |
| - || kind == 'Float32x4List' |
| - || kind == 'Float64x2List'; |
| - } |
| - bool get isSimdValue { |
| - return kind == 'Float32x4' |
| - || kind == 'Float64x2' |
| - || kind == 'Int32x4'; |
| - } |
| - bool get isRegExp => kind == 'RegExp'; |
| - bool get isMirrorReference => kind == 'MirrorReference'; |
| - bool get isWeakProperty => kind == 'WeakProperty'; |
| - bool get isClosure => kind == 'Closure'; |
| - bool get isStackTrace => kind == 'StackTrace'; |
| bool get isStackOverflowError { |
| if (clazz == null) { |
| return false; |
| @@ -2493,11 +2571,11 @@ class Instance extends HeapObject implements M.Instance { |
| _upgradeCollection(map, isolate); |
| super._update(map, mapIsRef); |
| - kind = map['kind']; |
| + kind = stringToInstanceKind(map['kind']); |
| valueAsString = map['valueAsString']; |
| // Coerce absence to false. |
| valueAsStringIsTruncated = map['valueAsStringIsTruncated'] == true; |
| - function = map['closureFunction']; |
| + closureFunction = map['closureFunction']; |
| context = map['closureContext']; |
| name = map['name']; |
| length = map['length']; |
| @@ -2508,6 +2586,8 @@ class Instance extends HeapObject implements M.Instance { |
| return; |
| } |
| + count = map['count']; |
| + offset = map['offset']; |
| isCaseSensitive = map['isCaseSensitive']; |
| isMultiLine = map['isMultiLine']; |
| bool isCompiled = map['_oneByteFunction'] is ServiceFunction; |
| @@ -2519,9 +2599,21 @@ class Instance extends HeapObject implements M.Instance { |
| twoByteBytecode = map['_twoByteBytecode']; |
| nativeFields = map['_nativeFields']; |
| - fields = map['fields']; |
| - elements = map['elements']; |
| - associations = map['associations']; |
| + if (map['fields'] != null) { |
| + fields = map['fields'] |
| + .map((f) => new BoundField(f['decl'], f['value'])).toList(); |
| + } |
| + if (map['elements'] != null) { |
| + // Should be: |
| + // elements = map['elements'].map((e) => new Guarded<Instance>(e)).toList(); |
|
Cutch
2016/08/15 23:27:08
weird indentation.
Fix the code or fix the commen
cbernaschina
2016/08/16 00:01:44
Done.
|
| + // some times we obtain object that are not InstanceRef |
| + elements = map['elements'].map((e) => new Guarded<ServiceObject>(e)) |
| + .toList(); |
| + } |
| + if (map['associations'] != null) { |
| + associations = map['associations'].map((a) => |
| + new MapAssociation(a['key'], a['value'])).toList(); |
| + }; |
| if (map['bytes'] != null) { |
| Uint8List bytes = BASE64.decode(map['bytes']); |
| switch (map['kind']) { |
| @@ -2572,7 +2664,7 @@ class Instance extends HeapObject implements M.Instance { |
| String get shortName { |
| if (isClosure) { |
| - return function.qualifiedName; |
| + return closureFunction.qualifiedName; |
| } |
| if (valueAsString != null) { |
| return valueAsString; |
| @@ -2588,8 +2680,8 @@ class Instance extends HeapObject implements M.Instance { |
| } |
| -class Context extends HeapObject { |
| - @observable var parentContext; |
| +class Context extends HeapObject implements M.Context { |
| + @observable Context parentContext; |
| @observable int length; |
| @observable var variables; |
| @@ -2726,8 +2818,45 @@ class ServiceFunction extends HeapObject implements M.Function { |
| } |
| } |
| +M.SentinelKind stringToSentinelKind(String s) { |
| + switch (s) { |
| + case 'Collected': |
| + return M.SentinelKind.collected; |
| + case 'Expired': |
| + return M.SentinelKind.expired; |
| + case 'NotInitialized': |
| + return M.SentinelKind.notInitialized; |
| + case 'BeingInitialized': |
| + return M.SentinelKind.beingInitialized; |
| + case 'OptimizedOut': |
| + return M.SentinelKind.optimizedOut; |
| + case 'Free': |
| + return M.SentinelKind.free; |
| + } |
| + Logger.root.severe("Unrecognized SentinelKind: '$s'"); |
| + throw new FallThroughError(); |
| +} |
| + |
| +class Sentinel extends ServiceObject implements M.Sentinel { |
| + |
| + M.SentinelKind kind; |
| + String valueAsString; |
| + |
| + Sentinel._empty(ServiceObjectOwner owner) : super._empty(owner); |
| + |
| + void _update(ObservableMap map, bool mapIsRef) { |
| + // Extract full properties. |
| + _upgradeCollection(map, isolate); |
| + |
| + kind = stringToSentinelKind(map['kind']); |
| + valueAsString = map['valueAsString']; |
| + _loaded = true; |
| + } |
| + |
| + String toString() => 'Sentinel($kind)'; |
| +} |
| -class Field extends HeapObject { |
| +class Field extends HeapObject implements M.FieldRef { |
| // Library or Class. |
| @observable ServiceObject dartOwner; |
| @observable Library library; |
| @@ -3282,7 +3411,7 @@ class PcDescriptor extends Observable { |
| } |
| } |
| -class PcDescriptors extends ServiceObject { |
| +class PcDescriptors extends ServiceObject implements M.PcDescriptorsRef { |
| @observable Class clazz; |
| @observable int size; |
| bool get immutable => true; |
| @@ -3312,7 +3441,9 @@ class PcDescriptors extends ServiceObject { |
| } |
| } |
| -class LocalVarDescriptor extends Observable { |
| +class LocalVarDescriptor extends Observable |
| + implements M.LocalVarDescriptorsRef { |
| + @reflectable final String id; |
| @reflectable final String name; |
| @reflectable final int index; |
| @reflectable final int beginPos; |
| @@ -3320,7 +3451,7 @@ class LocalVarDescriptor extends Observable { |
| @reflectable final int scopeId; |
| @reflectable final String kind; |
| - LocalVarDescriptor(this.name, this.index, this.beginPos, this.endPos, |
| + LocalVarDescriptor(this.id, this.name, this.index, this.beginPos, this.endPos, |
| this.scopeId, this.kind); |
| } |
| @@ -3341,6 +3472,7 @@ class LocalVarDescriptors extends ServiceObject { |
| size = m['size']; |
| descriptors.clear(); |
| for (var descriptor in m['members']) { |
| + var id = descriptor['name']; |
| var name = descriptor['name']; |
| var index = descriptor['index']; |
| var beginPos = descriptor['beginPos']; |
| @@ -3348,12 +3480,13 @@ class LocalVarDescriptors extends ServiceObject { |
| var scopeId = descriptor['scopeId']; |
| var kind = descriptor['kind'].trim(); |
| descriptors.add( |
| - new LocalVarDescriptor(name, index, beginPos, endPos, scopeId, kind)); |
| + new LocalVarDescriptor(id, name, index, beginPos, endPos, scopeId, |
| + kind)); |
| } |
| } |
| } |
| -class ObjectPool extends HeapObject { |
| +class ObjectPool extends HeapObject implements M.ObjectPoolRef { |
| bool get immutable => false; |
| @observable int length; |
| @@ -3373,7 +3506,7 @@ class ObjectPool extends HeapObject { |
| } |
| } |
| -class ICData extends HeapObject { |
| +class ICData extends HeapObject implements M.ICDataRef { |
| @observable ServiceObject dartOwner; |
| @observable String selector; |
| @observable Instance argumentsDescriptor; |
| @@ -3397,7 +3530,7 @@ class ICData extends HeapObject { |
| } |
| } |
| -class MegamorphicCache extends HeapObject { |
| +class MegamorphicCache extends HeapObject implements M.MegamorphicCacheRef { |
| @observable int mask; |
| @observable Instance buckets; |
| @observable String selector; |
| @@ -3422,7 +3555,7 @@ class MegamorphicCache extends HeapObject { |
| } |
| } |
| -class Instructions extends HeapObject { |
| +class Instructions extends HeapObject implements M.InstructionsRef { |
| bool get immutable => true; |
| @observable Code code; |
| @@ -3442,7 +3575,7 @@ class Instructions extends HeapObject { |
| } |
| } |
| -class TokenStream extends HeapObject { |
| +class TokenStream extends HeapObject implements M.TokenStreamRef { |
| bool get immutable => true; |
| @observable String privateKey; |