Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: tools/immic/lib/src/struct_layout.dart

Issue 2035023003: Remove service-compiler related code. (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/immic/lib/src/resources/objc/ImmiBase.h ('k') | tools/immic/pubspec.lock » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library immic.struct_builder;
6
7 import 'parser.dart';
8 import 'primitives.dart' as primitives;
9
10 import 'dart:collection';
11 import 'dart:core' hide Type;
12 import 'dart:math' show max;
13
14 const int POINTER_SIZE = 8;
15
16 int _roundUp(int n, int alignment) {
17 return (n + alignment - 1) & ~(alignment - 1);
18 }
19
20 class StructLayout {
21 final Map<String, StructSlot> _slots;
22 final int size;
23 final List<_StructHole> _holes;
24 StructLayout._(this._slots, this.size, this._holes);
25
26 factory StructLayout(Struct struct) {
27 _StructBuilder builder = new _StructBuilder();
28
29 struct.slots.forEach(builder.addSlot);
30 // TODO(zerny): Support unions in nodes.
31 if (struct.unions.isNotEmpty) {
32 builder.addUnionSlots(struct.unions.single);
33 }
34 return builder.finalize(0);
35 }
36
37 factory StructLayout.forArguments(List<Formal> arguments) {
38 _StructBuilder builder = new _StructBuilder();
39 arguments.forEach(builder.addSlot);
40 return builder.finalize(POINTER_SIZE);
41 }
42
43 Iterable<StructSlot> get slots => _slots.values;
44 StructSlot operator[](Formal slot) => _slots[slot.name];
45 }
46
47 class StructSlot {
48 final Formal slot;
49 final int offset;
50 final int size;
51
52 final Union union;
53 final int unionTag;
54
55 StructSlot(this.slot, this.offset, this.size, this.union, this.unionTag);
56
57 bool get isUnionSlot => union != null;
58 }
59
60 class _StructRegion {
61 final int size;
62 final int alignment;
63
64 final bool isUnion;
65 final owner;
66
67 _StructRegion.forSlot(this.size, this.alignment, Formal this.owner)
68 : isUnion = false;
69
70 _StructRegion.forUnion(this.size, this.alignment, Union this.owner)
71 : isUnion = true;
72
73 Formal get slot {
74 assert(!isUnion);
75 return owner;
76 }
77
78 Union get union {
79 assert(isUnion);
80 return owner;
81 }
82 }
83
84 class _StructHole extends LinkedListEntry {
85 int begin;
86 int end;
87 _StructHole(this.begin, this.end);
88
89 int get size => end - begin;
90 }
91
92 class _StructBuilder {
93 final List<_StructRegion> regions = <_StructRegion>[];
94 final Map<String, StructSlot> slots = new LinkedHashMap<String, StructSlot>();
95 final LinkedList<_StructHole> holes = new LinkedList<_StructHole>();
96 int used = 0;
97
98 StructLayout finalize(int minimum) {
99 // Sort the regions by size, so we get the largest regions first.
100 regions.sort((x, y) => y.size - x.size);
101
102 for (_StructRegion region in regions) {
103 int offset = allocate(region.size, region.alignment);
104 if (region.isUnion) {
105 Union union = region.union;
106 int tag = 1;
107 union.slots.forEach((Formal slot) {
108 _defineSlot(slot, offset, computeSize(slot.type), union, tag++);
109 });
110 } else {
111 _defineSlot(region.slot, offset, region.size, null, -1);
112 }
113 }
114
115 int size = max(allocate(0, POINTER_SIZE), minimum);
116 return new StructLayout._(slots, size, holes.toList());
117 }
118
119 int allocate(int size, int alignment) {
120 int result = _allocateFromHole(size, alignment);
121 if (result >= 0) return result;
122
123 result = _roundUp(used, alignment);
124 int padding = result - used;
125 if (padding > 0) {
126 holes.add(new _StructHole(result - padding, result));
127 }
128 used = result + size;
129 return result;
130 }
131
132 int _allocateFromHole(int size, int alignment) {
133 if (size == 0) return -1;
134 for (_StructHole hole in holes) {
135 int offset = _roundUp(hole.begin, alignment);
136 if (offset + size <= hole.end) {
137 _splitHole(hole, offset, size);
138 return offset;
139 }
140 }
141 return -1;
142 }
143
144 void _splitHole(_StructHole hole, int offset, int size) {
145 int end = hole.end;
146 if (offset + size < end) {
147 // Insert hole after.
148 hole.insertAfter(new _StructHole(offset + size, end));
149 }
150 // Shrink the hole before.
151 hole.end = offset;
152 if (hole.size == 0) holes.remove(hole);
153 }
154
155 void addSlot(Formal slot) {
156 Type type = slot.type;
157 int size = computeSize(type);
158 int alignment = computeAlignment(type);
159 regions.add(new _StructRegion.forSlot(size, alignment, slot));
160 }
161
162 void addUnionSlots(Union union) {
163 List<Formal> unionSlots = union.slots;
164 if (unionSlots.isEmpty) return;
165
166 int unionSize = 0;
167 int unionAlignment = 0;
168 unionSlots.forEach((Formal slot) {
169 Type type = slot.type;
170 int size = computeSize(type);
171 if (size > unionSize) unionSize = size;
172 int alignment = computeAlignment(type);
173 if (alignment > unionAlignment) unionAlignment = alignment;
174 });
175
176 regions.add(new _StructRegion.forUnion(unionSize, unionAlignment, union));
177 }
178
179 void _defineSlot(Formal slot, int offset, int size, Union union, int tag) {
180 String name = slot.name;
181 if (slots.containsKey(name)) {
182 throw new UnsupportedError("Duplicate slot '$name' in struct.");
183 }
184 slots[name] = new StructSlot(slot, offset, size, union, tag);
185 }
186
187 int computeSize(Type type) {
188 if (type.isPointer || type.isList || type.isString || type.isNode) {
189 return POINTER_SIZE;
190 }
191 if (type.isPrimitive) return primitives.size(type.primitiveType);
192
193 Struct struct = type.resolved;
194 StructLayout layout = struct.layout;
195 for (_StructHole hole in layout._holes) {
196 holes.add(new _StructHole(hole.begin, hole.end));
197 }
198 return _roundUp(layout.size, POINTER_SIZE);
199 }
200
201 int computeAlignment(Type type) {
202 return (type.isPrimitive && !type.isList && !type.isString)
203 ? primitives.size(type.primitiveType)
204 : POINTER_SIZE;
205 }
206 }
OLDNEW
« no previous file with comments | « tools/immic/lib/src/resources/objc/ImmiBase.h ('k') | tools/immic/pubspec.lock » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698