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

Side by Side Diff: runtime/vm/kernel_to_il.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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 | « runtime/vm/kernel_to_il.h ('k') | runtime/vm/locations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <set> 5 #include <set>
6 6
7 #include "vm/kernel_to_il.h" 7 #include "vm/kernel_to_il.h"
8 8
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/intermediate_language.h" 10 #include "vm/intermediate_language.h"
11 #include "vm/kernel_binary_flowgraph.h"
11 #include "vm/kernel_reader.h" 12 #include "vm/kernel_reader.h"
12 #include "vm/kernel_binary_flowgraph.h"
13 #include "vm/longjump.h" 13 #include "vm/longjump.h"
14 #include "vm/method_recognizer.h" 14 #include "vm/method_recognizer.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/report.h" 16 #include "vm/report.h"
17 #include "vm/resolver.h" 17 #include "vm/resolver.h"
18 #include "vm/stack_frame.h" 18 #include "vm/stack_frame.h"
19 19
20 #if !defined(DART_PRECOMPILED_RUNTIME) 20 #if !defined(DART_PRECOMPILED_RUNTIME)
21 namespace dart { 21 namespace dart {
22 22
23 DECLARE_FLAG(bool, support_externalizable_strings); 23 DECLARE_FLAG(bool, support_externalizable_strings);
24 24
25 namespace kernel { 25 namespace kernel {
26 26
27 #define Z (zone_) 27 #define Z (zone_)
28 #define H (translation_helper_) 28 #define H (translation_helper_)
29 #define T (type_translator_) 29 #define T (type_translator_)
30 #define I Isolate::Current() 30 #define I Isolate::Current()
31 31
32
33 Fragment& Fragment::operator+=(const Fragment& other) { 32 Fragment& Fragment::operator+=(const Fragment& other) {
34 if (entry == NULL) { 33 if (entry == NULL) {
35 entry = other.entry; 34 entry = other.entry;
36 current = other.current; 35 current = other.current;
37 } else if (current != NULL && other.entry != NULL) { 36 } else if (current != NULL && other.entry != NULL) {
38 current->LinkTo(other.entry); 37 current->LinkTo(other.entry);
39 current = other.current; 38 current = other.current;
40 } 39 }
41 return *this; 40 return *this;
42 } 41 }
43 42
44
45 Fragment& Fragment::operator<<=(Instruction* next) { 43 Fragment& Fragment::operator<<=(Instruction* next) {
46 if (entry == NULL) { 44 if (entry == NULL) {
47 entry = current = next; 45 entry = current = next;
48 } else if (current != NULL) { 46 } else if (current != NULL) {
49 current->LinkTo(next); 47 current->LinkTo(next);
50 current = next; 48 current = next;
51 } 49 }
52 return *this; 50 return *this;
53 } 51 }
54 52
55
56 Fragment Fragment::closed() { 53 Fragment Fragment::closed() {
57 ASSERT(entry != NULL); 54 ASSERT(entry != NULL);
58 return Fragment(entry, NULL); 55 return Fragment(entry, NULL);
59 } 56 }
60 57
61
62 Fragment operator+(const Fragment& first, const Fragment& second) { 58 Fragment operator+(const Fragment& first, const Fragment& second) {
63 Fragment result = first; 59 Fragment result = first;
64 result += second; 60 result += second;
65 return result; 61 return result;
66 } 62 }
67 63
68
69 Fragment operator<<(const Fragment& fragment, Instruction* next) { 64 Fragment operator<<(const Fragment& fragment, Instruction* next) {
70 Fragment result = fragment; 65 Fragment result = fragment;
71 result <<= next; 66 result <<= next;
72 return result; 67 return result;
73 } 68 }
74 69
75
76 TranslationHelper::TranslationHelper(Thread* thread) 70 TranslationHelper::TranslationHelper(Thread* thread)
77 : thread_(thread), 71 : thread_(thread),
78 zone_(thread->zone()), 72 zone_(thread->zone()),
79 isolate_(thread->isolate()), 73 isolate_(thread->isolate()),
80 allocation_space_(thread->IsMutatorThread() ? Heap::kNew : Heap::kOld), 74 allocation_space_(thread->IsMutatorThread() ? Heap::kNew : Heap::kOld),
81 string_offsets_(TypedData::Handle(Z)), 75 string_offsets_(TypedData::Handle(Z)),
82 string_data_(TypedData::Handle(Z)), 76 string_data_(TypedData::Handle(Z)),
83 canonical_names_(TypedData::Handle(Z)) {} 77 canonical_names_(TypedData::Handle(Z)) {}
84 78
85
86 void TranslationHelper::SetStringOffsets(const TypedData& string_offsets) { 79 void TranslationHelper::SetStringOffsets(const TypedData& string_offsets) {
87 ASSERT(string_offsets_.IsNull()); 80 ASSERT(string_offsets_.IsNull());
88 string_offsets_ = string_offsets.raw(); 81 string_offsets_ = string_offsets.raw();
89 } 82 }
90 83
91
92 void TranslationHelper::SetStringData(const TypedData& string_data) { 84 void TranslationHelper::SetStringData(const TypedData& string_data) {
93 ASSERT(string_data_.IsNull()); 85 ASSERT(string_data_.IsNull());
94 string_data_ = string_data.raw(); 86 string_data_ = string_data.raw();
95 } 87 }
96 88
97
98 void TranslationHelper::SetCanonicalNames(const TypedData& canonical_names) { 89 void TranslationHelper::SetCanonicalNames(const TypedData& canonical_names) {
99 ASSERT(canonical_names_.IsNull()); 90 ASSERT(canonical_names_.IsNull());
100 canonical_names_ = canonical_names.raw(); 91 canonical_names_ = canonical_names.raw();
101 } 92 }
102 93
103
104 intptr_t TranslationHelper::StringOffset(StringIndex index) const { 94 intptr_t TranslationHelper::StringOffset(StringIndex index) const {
105 return string_offsets_.GetUint32(index << 2); 95 return string_offsets_.GetUint32(index << 2);
106 } 96 }
107 97
108
109 intptr_t TranslationHelper::StringSize(StringIndex index) const { 98 intptr_t TranslationHelper::StringSize(StringIndex index) const {
110 return StringOffset(StringIndex(index + 1)) - StringOffset(index); 99 return StringOffset(StringIndex(index + 1)) - StringOffset(index);
111 } 100 }
112 101
113
114 uint8_t TranslationHelper::CharacterAt(StringIndex string_index, 102 uint8_t TranslationHelper::CharacterAt(StringIndex string_index,
115 intptr_t index) { 103 intptr_t index) {
116 ASSERT(index < StringSize(string_index)); 104 ASSERT(index < StringSize(string_index));
117 return string_data_.GetUint8(StringOffset(string_index) + index); 105 return string_data_.GetUint8(StringOffset(string_index) + index);
118 } 106 }
119 107
120
121 bool TranslationHelper::StringEquals(StringIndex string_index, 108 bool TranslationHelper::StringEquals(StringIndex string_index,
122 const char* other) { 109 const char* other) {
123 NoSafepointScope no_safepoint; 110 NoSafepointScope no_safepoint;
124 intptr_t length = strlen(other); 111 intptr_t length = strlen(other);
125 return (length == StringSize(string_index)) && 112 return (length == StringSize(string_index)) &&
126 (memcmp(string_data_.DataAddr(StringOffset(string_index)), other, 113 (memcmp(string_data_.DataAddr(StringOffset(string_index)), other,
127 length) == 0); 114 length) == 0);
128 } 115 }
129 116
130
131 NameIndex TranslationHelper::CanonicalNameParent(NameIndex name) { 117 NameIndex TranslationHelper::CanonicalNameParent(NameIndex name) {
132 // Canonical names are pairs of 4-byte parent and string indexes, so the size 118 // Canonical names are pairs of 4-byte parent and string indexes, so the size
133 // of an entry is 8 bytes. The parent is biased: 0 represents the root name 119 // of an entry is 8 bytes. The parent is biased: 0 represents the root name
134 // and N+1 represents the name with index N. 120 // and N+1 represents the name with index N.
135 return NameIndex(static_cast<intptr_t>(canonical_names_.GetUint32(8 * name)) - 121 return NameIndex(static_cast<intptr_t>(canonical_names_.GetUint32(8 * name)) -
136 1); 122 1);
137 } 123 }
138 124
139
140 StringIndex TranslationHelper::CanonicalNameString(NameIndex name) { 125 StringIndex TranslationHelper::CanonicalNameString(NameIndex name) {
141 return StringIndex(canonical_names_.GetUint32((8 * name) + 4)); 126 return StringIndex(canonical_names_.GetUint32((8 * name) + 4));
142 } 127 }
143 128
144
145 bool TranslationHelper::IsAdministrative(NameIndex name) { 129 bool TranslationHelper::IsAdministrative(NameIndex name) {
146 // Administrative names start with '@'. 130 // Administrative names start with '@'.
147 StringIndex name_string = CanonicalNameString(name); 131 StringIndex name_string = CanonicalNameString(name);
148 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '@'); 132 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '@');
149 } 133 }
150 134
151
152 bool TranslationHelper::IsPrivate(NameIndex name) { 135 bool TranslationHelper::IsPrivate(NameIndex name) {
153 // Private names start with '_'. 136 // Private names start with '_'.
154 StringIndex name_string = CanonicalNameString(name); 137 StringIndex name_string = CanonicalNameString(name);
155 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '_'); 138 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '_');
156 } 139 }
157 140
158
159 bool TranslationHelper::IsRoot(NameIndex name) { 141 bool TranslationHelper::IsRoot(NameIndex name) {
160 return name == -1; 142 return name == -1;
161 } 143 }
162 144
163
164 bool TranslationHelper::IsLibrary(NameIndex name) { 145 bool TranslationHelper::IsLibrary(NameIndex name) {
165 // Libraries are the only canonical names with the root as their parent. 146 // Libraries are the only canonical names with the root as their parent.
166 return !IsRoot(name) && IsRoot(CanonicalNameParent(name)); 147 return !IsRoot(name) && IsRoot(CanonicalNameParent(name));
167 } 148 }
168 149
169
170 bool TranslationHelper::IsClass(NameIndex name) { 150 bool TranslationHelper::IsClass(NameIndex name) {
171 // Classes have the library as their parent and are not an administrative 151 // Classes have the library as their parent and are not an administrative
172 // name starting with @. 152 // name starting with @.
173 return !IsAdministrative(name) && !IsRoot(name) && 153 return !IsAdministrative(name) && !IsRoot(name) &&
174 IsLibrary(CanonicalNameParent(name)); 154 IsLibrary(CanonicalNameParent(name));
175 } 155 }
176 156
177
178 bool TranslationHelper::IsMember(NameIndex name) { 157 bool TranslationHelper::IsMember(NameIndex name) {
179 return IsConstructor(name) || IsField(name) || IsProcedure(name); 158 return IsConstructor(name) || IsField(name) || IsProcedure(name);
180 } 159 }
181 160
182
183 bool TranslationHelper::IsField(NameIndex name) { 161 bool TranslationHelper::IsField(NameIndex name) {
184 // Fields with private names have the import URI of the library where they are 162 // Fields with private names have the import URI of the library where they are
185 // visible as the parent and the string "@fields" as the parent's parent. 163 // visible as the parent and the string "@fields" as the parent's parent.
186 // Fields with non-private names have the string "@fields' as the parent. 164 // Fields with non-private names have the string "@fields' as the parent.
187 if (IsRoot(name)) { 165 if (IsRoot(name)) {
188 return false; 166 return false;
189 } 167 }
190 NameIndex kind = CanonicalNameParent(name); 168 NameIndex kind = CanonicalNameParent(name);
191 if (IsPrivate(name)) { 169 if (IsPrivate(name)) {
192 kind = CanonicalNameParent(kind); 170 kind = CanonicalNameParent(kind);
193 } 171 }
194 return StringEquals(CanonicalNameString(kind), "@fields"); 172 return StringEquals(CanonicalNameString(kind), "@fields");
195 } 173 }
196 174
197
198 bool TranslationHelper::IsConstructor(NameIndex name) { 175 bool TranslationHelper::IsConstructor(NameIndex name) {
199 // Constructors with private names have the import URI of the library where 176 // Constructors with private names have the import URI of the library where
200 // they are visible as the parent and the string "@constructors" as the 177 // they are visible as the parent and the string "@constructors" as the
201 // parent's parent. Constructors with non-private names have the string 178 // parent's parent. Constructors with non-private names have the string
202 // "@constructors" as the parent. 179 // "@constructors" as the parent.
203 if (IsRoot(name)) { 180 if (IsRoot(name)) {
204 return false; 181 return false;
205 } 182 }
206 NameIndex kind = CanonicalNameParent(name); 183 NameIndex kind = CanonicalNameParent(name);
207 if (IsPrivate(name)) { 184 if (IsPrivate(name)) {
208 kind = CanonicalNameParent(kind); 185 kind = CanonicalNameParent(kind);
209 } 186 }
210 return StringEquals(CanonicalNameString(kind), "@constructors"); 187 return StringEquals(CanonicalNameString(kind), "@constructors");
211 } 188 }
212 189
213
214 bool TranslationHelper::IsProcedure(NameIndex name) { 190 bool TranslationHelper::IsProcedure(NameIndex name) {
215 return IsMethod(name) || IsGetter(name) || IsSetter(name) || IsFactory(name); 191 return IsMethod(name) || IsGetter(name) || IsSetter(name) || IsFactory(name);
216 } 192 }
217 193
218
219 bool TranslationHelper::IsMethod(NameIndex name) { 194 bool TranslationHelper::IsMethod(NameIndex name) {
220 // Methods with private names have the import URI of the library where they 195 // Methods with private names have the import URI of the library where they
221 // are visible as the parent and the string "@methods" as the parent's parent. 196 // are visible as the parent and the string "@methods" as the parent's parent.
222 // Methods with non-private names have the string "@methods" as the parent. 197 // Methods with non-private names have the string "@methods" as the parent.
223 if (IsRoot(name)) { 198 if (IsRoot(name)) {
224 return false; 199 return false;
225 } 200 }
226 NameIndex kind = CanonicalNameParent(name); 201 NameIndex kind = CanonicalNameParent(name);
227 if (IsPrivate(name)) { 202 if (IsPrivate(name)) {
228 kind = CanonicalNameParent(kind); 203 kind = CanonicalNameParent(kind);
229 } 204 }
230 return StringEquals(CanonicalNameString(kind), "@methods"); 205 return StringEquals(CanonicalNameString(kind), "@methods");
231 } 206 }
232 207
233
234 bool TranslationHelper::IsGetter(NameIndex name) { 208 bool TranslationHelper::IsGetter(NameIndex name) {
235 // Getters with private names have the import URI of the library where they 209 // Getters with private names have the import URI of the library where they
236 // are visible as the parent and the string "@getters" as the parent's parent. 210 // are visible as the parent and the string "@getters" as the parent's parent.
237 // Getters with non-private names have the string "@getters" as the parent. 211 // Getters with non-private names have the string "@getters" as the parent.
238 if (IsRoot(name)) { 212 if (IsRoot(name)) {
239 return false; 213 return false;
240 } 214 }
241 NameIndex kind = CanonicalNameParent(name); 215 NameIndex kind = CanonicalNameParent(name);
242 if (IsPrivate(name)) { 216 if (IsPrivate(name)) {
243 kind = CanonicalNameParent(kind); 217 kind = CanonicalNameParent(kind);
244 } 218 }
245 return StringEquals(CanonicalNameString(kind), "@getters"); 219 return StringEquals(CanonicalNameString(kind), "@getters");
246 } 220 }
247 221
248
249 bool TranslationHelper::IsSetter(NameIndex name) { 222 bool TranslationHelper::IsSetter(NameIndex name) {
250 // Setters with private names have the import URI of the library where they 223 // Setters with private names have the import URI of the library where they
251 // are visible as the parent and the string "@setters" as the parent's parent. 224 // are visible as the parent and the string "@setters" as the parent's parent.
252 // Setters with non-private names have the string "@setters" as the parent. 225 // Setters with non-private names have the string "@setters" as the parent.
253 if (IsRoot(name)) { 226 if (IsRoot(name)) {
254 return false; 227 return false;
255 } 228 }
256 NameIndex kind = CanonicalNameParent(name); 229 NameIndex kind = CanonicalNameParent(name);
257 if (IsPrivate(name)) { 230 if (IsPrivate(name)) {
258 kind = CanonicalNameParent(kind); 231 kind = CanonicalNameParent(kind);
259 } 232 }
260 return StringEquals(CanonicalNameString(kind), "@setters"); 233 return StringEquals(CanonicalNameString(kind), "@setters");
261 } 234 }
262 235
263
264 bool TranslationHelper::IsFactory(NameIndex name) { 236 bool TranslationHelper::IsFactory(NameIndex name) {
265 // Factories with private names have the import URI of the library where they 237 // Factories with private names have the import URI of the library where they
266 // are visible as the parent and the string "@factories" as the parent's 238 // are visible as the parent and the string "@factories" as the parent's
267 // parent. Factories with non-private names have the string "@factories" as 239 // parent. Factories with non-private names have the string "@factories" as
268 // the parent. 240 // the parent.
269 if (IsRoot(name)) { 241 if (IsRoot(name)) {
270 return false; 242 return false;
271 } 243 }
272 NameIndex kind = CanonicalNameParent(name); 244 NameIndex kind = CanonicalNameParent(name);
273 if (IsPrivate(name)) { 245 if (IsPrivate(name)) {
274 kind = CanonicalNameParent(kind); 246 kind = CanonicalNameParent(kind);
275 } 247 }
276 return StringEquals(CanonicalNameString(kind), "@factories"); 248 return StringEquals(CanonicalNameString(kind), "@factories");
277 } 249 }
278 250
279
280 NameIndex TranslationHelper::EnclosingName(NameIndex name) { 251 NameIndex TranslationHelper::EnclosingName(NameIndex name) {
281 ASSERT(IsField(name) || IsConstructor(name) || IsProcedure(name)); 252 ASSERT(IsField(name) || IsConstructor(name) || IsProcedure(name));
282 NameIndex enclosing = CanonicalNameParent(CanonicalNameParent(name)); 253 NameIndex enclosing = CanonicalNameParent(CanonicalNameParent(name));
283 if (IsPrivate(name)) { 254 if (IsPrivate(name)) {
284 enclosing = CanonicalNameParent(enclosing); 255 enclosing = CanonicalNameParent(enclosing);
285 } 256 }
286 ASSERT(IsLibrary(enclosing) || IsClass(enclosing)); 257 ASSERT(IsLibrary(enclosing) || IsClass(enclosing));
287 return enclosing; 258 return enclosing;
288 } 259 }
289 260
290
291 RawInstance* TranslationHelper::Canonicalize(const Instance& instance) { 261 RawInstance* TranslationHelper::Canonicalize(const Instance& instance) {
292 if (instance.IsNull()) return instance.raw(); 262 if (instance.IsNull()) return instance.raw();
293 263
294 const char* error_str = NULL; 264 const char* error_str = NULL;
295 RawInstance* result = instance.CheckAndCanonicalize(thread(), &error_str); 265 RawInstance* result = instance.CheckAndCanonicalize(thread(), &error_str);
296 if (result == Object::null()) { 266 if (result == Object::null()) {
297 ReportError("Invalid const object %s", error_str); 267 ReportError("Invalid const object %s", error_str);
298 } 268 }
299 return result; 269 return result;
300 } 270 }
301 271
302
303 const dart::String& TranslationHelper::DartString(const char* content, 272 const dart::String& TranslationHelper::DartString(const char* content,
304 Heap::Space space) { 273 Heap::Space space) {
305 return dart::String::ZoneHandle(Z, dart::String::New(content, space)); 274 return dart::String::ZoneHandle(Z, dart::String::New(content, space));
306 } 275 }
307 276
308
309 dart::String& TranslationHelper::DartString(StringIndex string_index, 277 dart::String& TranslationHelper::DartString(StringIndex string_index,
310 Heap::Space space) { 278 Heap::Space space) {
311 intptr_t length = StringSize(string_index); 279 intptr_t length = StringSize(string_index);
312 uint8_t* buffer = Z->Alloc<uint8_t>(length); 280 uint8_t* buffer = Z->Alloc<uint8_t>(length);
313 { 281 {
314 NoSafepointScope no_safepoint; 282 NoSafepointScope no_safepoint;
315 memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length); 283 memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length);
316 } 284 }
317 return dart::String::ZoneHandle( 285 return dart::String::ZoneHandle(
318 Z, dart::String::FromUTF8(buffer, length, space)); 286 Z, dart::String::FromUTF8(buffer, length, space));
319 } 287 }
320 288
321
322 dart::String& TranslationHelper::DartString(const uint8_t* utf8_array, 289 dart::String& TranslationHelper::DartString(const uint8_t* utf8_array,
323 intptr_t len, 290 intptr_t len,
324 Heap::Space space) { 291 Heap::Space space) {
325 return dart::String::ZoneHandle( 292 return dart::String::ZoneHandle(
326 Z, dart::String::FromUTF8(utf8_array, len, space)); 293 Z, dart::String::FromUTF8(utf8_array, len, space));
327 } 294 }
328 295
329
330 const dart::String& TranslationHelper::DartSymbol(const char* content) const { 296 const dart::String& TranslationHelper::DartSymbol(const char* content) const {
331 return dart::String::ZoneHandle(Z, Symbols::New(thread_, content)); 297 return dart::String::ZoneHandle(Z, Symbols::New(thread_, content));
332 } 298 }
333 299
334
335 dart::String& TranslationHelper::DartSymbol(StringIndex string_index) const { 300 dart::String& TranslationHelper::DartSymbol(StringIndex string_index) const {
336 intptr_t length = StringSize(string_index); 301 intptr_t length = StringSize(string_index);
337 uint8_t* buffer = Z->Alloc<uint8_t>(length); 302 uint8_t* buffer = Z->Alloc<uint8_t>(length);
338 { 303 {
339 NoSafepointScope no_safepoint; 304 NoSafepointScope no_safepoint;
340 memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length); 305 memmove(buffer, string_data_.DataAddr(StringOffset(string_index)), length);
341 } 306 }
342 return dart::String::ZoneHandle(Z, 307 return dart::String::ZoneHandle(Z,
343 Symbols::FromUTF8(thread_, buffer, length)); 308 Symbols::FromUTF8(thread_, buffer, length));
344 } 309 }
345 310
346 dart::String& TranslationHelper::DartSymbol(const uint8_t* utf8_array, 311 dart::String& TranslationHelper::DartSymbol(const uint8_t* utf8_array,
347 intptr_t len) const { 312 intptr_t len) const {
348 return dart::String::ZoneHandle(Z, 313 return dart::String::ZoneHandle(Z,
349 Symbols::FromUTF8(thread_, utf8_array, len)); 314 Symbols::FromUTF8(thread_, utf8_array, len));
350 } 315 }
351 316
352 const dart::String& TranslationHelper::DartClassName(NameIndex kernel_class) { 317 const dart::String& TranslationHelper::DartClassName(NameIndex kernel_class) {
353 ASSERT(IsClass(kernel_class)); 318 ASSERT(IsClass(kernel_class));
354 dart::String& name = DartString(CanonicalNameString(kernel_class)); 319 dart::String& name = DartString(CanonicalNameString(kernel_class));
355 return ManglePrivateName(CanonicalNameParent(kernel_class), &name); 320 return ManglePrivateName(CanonicalNameParent(kernel_class), &name);
356 } 321 }
357 322
358
359 const dart::String& TranslationHelper::DartConstructorName( 323 const dart::String& TranslationHelper::DartConstructorName(
360 NameIndex constructor) { 324 NameIndex constructor) {
361 ASSERT(IsConstructor(constructor)); 325 ASSERT(IsConstructor(constructor));
362 return DartFactoryName(constructor); 326 return DartFactoryName(constructor);
363 } 327 }
364 328
365
366 const dart::String& TranslationHelper::DartProcedureName(NameIndex procedure) { 329 const dart::String& TranslationHelper::DartProcedureName(NameIndex procedure) {
367 ASSERT(IsProcedure(procedure)); 330 ASSERT(IsProcedure(procedure));
368 if (IsSetter(procedure)) { 331 if (IsSetter(procedure)) {
369 return DartSetterName(procedure); 332 return DartSetterName(procedure);
370 } else if (IsGetter(procedure)) { 333 } else if (IsGetter(procedure)) {
371 return DartGetterName(procedure); 334 return DartGetterName(procedure);
372 } else if (IsFactory(procedure)) { 335 } else if (IsFactory(procedure)) {
373 return DartFactoryName(procedure); 336 return DartFactoryName(procedure);
374 } else { 337 } else {
375 return DartMethodName(procedure); 338 return DartMethodName(procedure);
376 } 339 }
377 } 340 }
378 341
379
380 const dart::String& TranslationHelper::DartSetterName(NameIndex setter) { 342 const dart::String& TranslationHelper::DartSetterName(NameIndex setter) {
381 return DartSetterName(CanonicalNameParent(setter), 343 return DartSetterName(CanonicalNameParent(setter),
382 CanonicalNameString(setter)); 344 CanonicalNameString(setter));
383 } 345 }
384 346
385
386 const dart::String& TranslationHelper::DartSetterName(NameIndex parent, 347 const dart::String& TranslationHelper::DartSetterName(NameIndex parent,
387 StringIndex setter) { 348 StringIndex setter) {
388 // The names flowing into [setter] are coming from the Kernel file: 349 // The names flowing into [setter] are coming from the Kernel file:
389 // * user-defined setters: `fieldname=` 350 // * user-defined setters: `fieldname=`
390 // * property-set expressions: `fieldname` 351 // * property-set expressions: `fieldname`
391 // 352 //
392 // The VM uses `get:fieldname` and `set:fieldname`. 353 // The VM uses `get:fieldname` and `set:fieldname`.
393 // 354 //
394 // => In order to be consistent, we remove the `=` always and adopt the VM 355 // => In order to be consistent, we remove the `=` always and adopt the VM
395 // conventions. 356 // conventions.
396 intptr_t size = StringSize(setter); 357 intptr_t size = StringSize(setter);
397 ASSERT(size > 0); 358 ASSERT(size > 0);
398 if (CharacterAt(setter, size - 1) == '=') { 359 if (CharacterAt(setter, size - 1) == '=') {
399 --size; 360 --size;
400 } 361 }
401 uint8_t* buffer = Z->Alloc<uint8_t>(size); 362 uint8_t* buffer = Z->Alloc<uint8_t>(size);
402 { 363 {
403 NoSafepointScope no_safepoint; 364 NoSafepointScope no_safepoint;
404 memmove(buffer, string_data_.DataAddr(StringOffset(setter)), size); 365 memmove(buffer, string_data_.DataAddr(StringOffset(setter)), size);
405 } 366 }
406 dart::String& name = dart::String::ZoneHandle( 367 dart::String& name = dart::String::ZoneHandle(
407 Z, dart::String::FromUTF8(buffer, size, allocation_space_)); 368 Z, dart::String::FromUTF8(buffer, size, allocation_space_));
408 ManglePrivateName(parent, &name, false); 369 ManglePrivateName(parent, &name, false);
409 name = dart::Field::SetterSymbol(name); 370 name = dart::Field::SetterSymbol(name);
410 return name; 371 return name;
411 } 372 }
412 373
413
414 const dart::String& TranslationHelper::DartGetterName(NameIndex getter) { 374 const dart::String& TranslationHelper::DartGetterName(NameIndex getter) {
415 return DartGetterName(CanonicalNameParent(getter), 375 return DartGetterName(CanonicalNameParent(getter),
416 CanonicalNameString(getter)); 376 CanonicalNameString(getter));
417 } 377 }
418 378
419
420 const dart::String& TranslationHelper::DartGetterName(NameIndex parent, 379 const dart::String& TranslationHelper::DartGetterName(NameIndex parent,
421 StringIndex getter) { 380 StringIndex getter) {
422 dart::String& name = DartString(getter); 381 dart::String& name = DartString(getter);
423 ManglePrivateName(parent, &name, false); 382 ManglePrivateName(parent, &name, false);
424 name = dart::Field::GetterSymbol(name); 383 name = dart::Field::GetterSymbol(name);
425 return name; 384 return name;
426 } 385 }
427 386
428
429 const dart::String& TranslationHelper::DartFieldName(NameIndex parent, 387 const dart::String& TranslationHelper::DartFieldName(NameIndex parent,
430 StringIndex field) { 388 StringIndex field) {
431 dart::String& name = DartString(field); 389 dart::String& name = DartString(field);
432 return ManglePrivateName(parent, &name); 390 return ManglePrivateName(parent, &name);
433 } 391 }
434 392
435
436 const dart::String& TranslationHelper::DartMethodName(NameIndex method) { 393 const dart::String& TranslationHelper::DartMethodName(NameIndex method) {
437 return DartMethodName(CanonicalNameParent(method), 394 return DartMethodName(CanonicalNameParent(method),
438 CanonicalNameString(method)); 395 CanonicalNameString(method));
439 } 396 }
440 397
441
442 const dart::String& TranslationHelper::DartMethodName(NameIndex parent, 398 const dart::String& TranslationHelper::DartMethodName(NameIndex parent,
443 StringIndex method) { 399 StringIndex method) {
444 dart::String& name = DartString(method); 400 dart::String& name = DartString(method);
445 return ManglePrivateName(parent, &name); 401 return ManglePrivateName(parent, &name);
446 } 402 }
447 403
448
449 const dart::String& TranslationHelper::DartFactoryName(NameIndex factory) { 404 const dart::String& TranslationHelper::DartFactoryName(NameIndex factory) {
450 ASSERT(IsConstructor(factory) || IsFactory(factory)); 405 ASSERT(IsConstructor(factory) || IsFactory(factory));
451 GrowableHandlePtrArray<const dart::String> pieces(Z, 3); 406 GrowableHandlePtrArray<const dart::String> pieces(Z, 3);
452 pieces.Add(DartClassName(EnclosingName(factory))); 407 pieces.Add(DartClassName(EnclosingName(factory)));
453 pieces.Add(Symbols::Dot()); 408 pieces.Add(Symbols::Dot());
454 // [DartMethodName] will mangle the name. 409 // [DartMethodName] will mangle the name.
455 pieces.Add(DartMethodName(factory)); 410 pieces.Add(DartMethodName(factory));
456 return dart::String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces)); 411 return dart::String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces));
457 } 412 }
458 413
459
460 RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary( 414 RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
461 NameIndex kernel_library) { 415 NameIndex kernel_library) {
462 // We only use the string and don't rely on having any particular parent. 416 // We only use the string and don't rely on having any particular parent.
463 // This ASSERT is just a sanity check. 417 // This ASSERT is just a sanity check.
464 ASSERT(IsLibrary(kernel_library) || 418 ASSERT(IsLibrary(kernel_library) ||
465 IsAdministrative(CanonicalNameParent(kernel_library))); 419 IsAdministrative(CanonicalNameParent(kernel_library)));
466 const dart::String& library_name = 420 const dart::String& library_name =
467 DartSymbol(CanonicalNameString(kernel_library)); 421 DartSymbol(CanonicalNameString(kernel_library));
468 ASSERT(!library_name.IsNull()); 422 ASSERT(!library_name.IsNull());
469 RawLibrary* library = dart::Library::LookupLibrary(thread_, library_name); 423 RawLibrary* library = dart::Library::LookupLibrary(thread_, library_name);
470 ASSERT(library != Object::null()); 424 ASSERT(library != Object::null());
471 return library; 425 return library;
472 } 426 }
473 427
474
475 RawClass* TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) { 428 RawClass* TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
476 ASSERT(IsClass(kernel_class)); 429 ASSERT(IsClass(kernel_class));
477 const dart::String& class_name = DartClassName(kernel_class); 430 const dart::String& class_name = DartClassName(kernel_class);
478 NameIndex kernel_library = CanonicalNameParent(kernel_class); 431 NameIndex kernel_library = CanonicalNameParent(kernel_class);
479 dart::Library& library = 432 dart::Library& library =
480 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_library)); 433 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_library));
481 RawClass* klass = library.LookupClassAllowPrivate(class_name); 434 RawClass* klass = library.LookupClassAllowPrivate(class_name);
482 435
483 ASSERT(klass != Object::null()); 436 ASSERT(klass != Object::null());
484 return klass; 437 return klass;
485 } 438 }
486 439
487
488 RawField* TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) { 440 RawField* TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
489 ASSERT(IsField(kernel_field)); 441 ASSERT(IsField(kernel_field));
490 NameIndex enclosing = EnclosingName(kernel_field); 442 NameIndex enclosing = EnclosingName(kernel_field);
491 443
492 dart::Class& klass = dart::Class::Handle(Z); 444 dart::Class& klass = dart::Class::Handle(Z);
493 if (IsLibrary(enclosing)) { 445 if (IsLibrary(enclosing)) {
494 dart::Library& library = 446 dart::Library& library =
495 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing)); 447 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
496 klass = library.toplevel_class(); 448 klass = library.toplevel_class();
497 } else { 449 } else {
498 ASSERT(IsClass(enclosing)); 450 ASSERT(IsClass(enclosing));
499 klass = LookupClassByKernelClass(enclosing); 451 klass = LookupClassByKernelClass(enclosing);
500 } 452 }
501 RawField* field = klass.LookupFieldAllowPrivate( 453 RawField* field = klass.LookupFieldAllowPrivate(
502 DartSymbol(CanonicalNameString(kernel_field))); 454 DartSymbol(CanonicalNameString(kernel_field)));
503 ASSERT(field != Object::null()); 455 ASSERT(field != Object::null());
504 return field; 456 return field;
505 } 457 }
506 458
507
508 RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure( 459 RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
509 NameIndex procedure) { 460 NameIndex procedure) {
510 const dart::String& procedure_name = DartProcedureName(procedure); 461 const dart::String& procedure_name = DartProcedureName(procedure);
511 462
512 // The parent is either a library or a class (in which case the procedure is a 463 // The parent is either a library or a class (in which case the procedure is a
513 // static method). 464 // static method).
514 NameIndex enclosing = EnclosingName(procedure); 465 NameIndex enclosing = EnclosingName(procedure);
515 if (IsLibrary(enclosing)) { 466 if (IsLibrary(enclosing)) {
516 dart::Library& library = 467 dart::Library& library =
517 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing)); 468 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
(...skipping 11 matching lines...) Expand all
529 // TODO(27590): We can probably get rid of this after no longer using 480 // TODO(27590): We can probably get rid of this after no longer using
530 // core libraries from the source. 481 // core libraries from the source.
531 if (function.IsRedirectingFactory()) { 482 if (function.IsRedirectingFactory()) {
532 ClassFinalizer::ResolveRedirectingFactory(klass, function); 483 ClassFinalizer::ResolveRedirectingFactory(klass, function);
533 function = function.RedirectionTarget(); 484 function = function.RedirectionTarget();
534 } 485 }
535 return function.raw(); 486 return function.raw();
536 } 487 }
537 } 488 }
538 489
539
540 RawFunction* TranslationHelper::LookupConstructorByKernelConstructor( 490 RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
541 NameIndex constructor) { 491 NameIndex constructor) {
542 ASSERT(IsConstructor(constructor)); 492 ASSERT(IsConstructor(constructor));
543 dart::Class& klass = dart::Class::Handle( 493 dart::Class& klass = dart::Class::Handle(
544 Z, LookupClassByKernelClass(EnclosingName(constructor))); 494 Z, LookupClassByKernelClass(EnclosingName(constructor)));
545 return LookupConstructorByKernelConstructor(klass, constructor); 495 return LookupConstructorByKernelConstructor(klass, constructor);
546 } 496 }
547 497
548
549 RawFunction* TranslationHelper::LookupConstructorByKernelConstructor( 498 RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
550 const dart::Class& owner, 499 const dart::Class& owner,
551 NameIndex constructor) { 500 NameIndex constructor) {
552 ASSERT(IsConstructor(constructor)); 501 ASSERT(IsConstructor(constructor));
553 RawFunction* function = 502 RawFunction* function =
554 owner.LookupConstructorAllowPrivate(DartConstructorName(constructor)); 503 owner.LookupConstructorAllowPrivate(DartConstructorName(constructor));
555 ASSERT(function != Object::null()); 504 ASSERT(function != Object::null());
556 return function; 505 return function;
557 } 506 }
558 507
559
560 dart::Type& TranslationHelper::GetCanonicalType(const dart::Class& klass) { 508 dart::Type& TranslationHelper::GetCanonicalType(const dart::Class& klass) {
561 ASSERT(!klass.IsNull()); 509 ASSERT(!klass.IsNull());
562 // Note that if cls is _Closure, the returned type will be _Closure, 510 // Note that if cls is _Closure, the returned type will be _Closure,
563 // and not the signature type. 511 // and not the signature type.
564 Type& type = Type::ZoneHandle(Z, klass.CanonicalType()); 512 Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
565 if (!type.IsNull()) { 513 if (!type.IsNull()) {
566 return type; 514 return type;
567 } 515 }
568 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), 516 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
569 klass.token_pos()); 517 klass.token_pos());
570 if (klass.is_type_finalized()) { 518 if (klass.is_type_finalized()) {
571 type ^= ClassFinalizer::FinalizeType(klass, type); 519 type ^= ClassFinalizer::FinalizeType(klass, type);
572 // Note that the receiver type may now be a malbounded type. 520 // Note that the receiver type may now be a malbounded type.
573 klass.SetCanonicalType(type); 521 klass.SetCanonicalType(type);
574 } 522 }
575 return type; 523 return type;
576 } 524 }
577 525
578
579 void TranslationHelper::ReportError(const char* format, ...) { 526 void TranslationHelper::ReportError(const char* format, ...) {
580 const Script& null_script = Script::Handle(Z); 527 const Script& null_script = Script::Handle(Z);
581 528
582 va_list args; 529 va_list args;
583 va_start(args, format); 530 va_start(args, format);
584 Report::MessageV(Report::kError, null_script, TokenPosition::kNoSource, 531 Report::MessageV(Report::kError, null_script, TokenPosition::kNoSource,
585 Report::AtLocation, format, args); 532 Report::AtLocation, format, args);
586 va_end(args); 533 va_end(args);
587 UNREACHABLE(); 534 UNREACHABLE();
588 } 535 }
589 536
590
591 void TranslationHelper::ReportError(const Error& prev_error, 537 void TranslationHelper::ReportError(const Error& prev_error,
592 const char* format, 538 const char* format,
593 ...) { 539 ...) {
594 const Script& null_script = Script::Handle(Z); 540 const Script& null_script = Script::Handle(Z);
595 541
596 va_list args; 542 va_list args;
597 va_start(args, format); 543 va_start(args, format);
598 Report::LongJumpV(prev_error, null_script, TokenPosition::kNoSource, format, 544 Report::LongJumpV(prev_error, null_script, TokenPosition::kNoSource, format,
599 args); 545 args);
600 va_end(args); 546 va_end(args);
601 UNREACHABLE(); 547 UNREACHABLE();
602 } 548 }
603 549
604
605 dart::String& TranslationHelper::ManglePrivateName(NameIndex parent, 550 dart::String& TranslationHelper::ManglePrivateName(NameIndex parent,
606 dart::String* name_to_modify, 551 dart::String* name_to_modify,
607 bool symbolize) { 552 bool symbolize) {
608 if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_') { 553 if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_') {
609 const dart::Library& library = 554 const dart::Library& library =
610 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(parent)); 555 dart::Library::Handle(Z, LookupLibraryByKernelLibrary(parent));
611 *name_to_modify = library.PrivateName(*name_to_modify); 556 *name_to_modify = library.PrivateName(*name_to_modify);
612 } else if (symbolize) { 557 } else if (symbolize) {
613 *name_to_modify = Symbols::New(thread_, *name_to_modify); 558 *name_to_modify = Symbols::New(thread_, *name_to_modify);
614 } 559 }
615 return *name_to_modify; 560 return *name_to_modify;
616 } 561 }
617 562
618
619 FlowGraphBuilder::FlowGraphBuilder( 563 FlowGraphBuilder::FlowGraphBuilder(
620 intptr_t kernel_offset, 564 intptr_t kernel_offset,
621 ParsedFunction* parsed_function, 565 ParsedFunction* parsed_function,
622 const ZoneGrowableArray<const ICData*>& ic_data_array, 566 const ZoneGrowableArray<const ICData*>& ic_data_array,
623 ZoneGrowableArray<intptr_t>* context_level_array, 567 ZoneGrowableArray<intptr_t>* context_level_array,
624 InlineExitCollector* exit_collector, 568 InlineExitCollector* exit_collector,
625 intptr_t osr_id, 569 intptr_t osr_id,
626 intptr_t first_block_id) 570 intptr_t first_block_id)
627 : translation_helper_(Thread::Current()), 571 : translation_helper_(Thread::Current()),
628 thread_(translation_helper_.thread()), 572 thread_(translation_helper_.thread()),
(...skipping 21 matching lines...) Expand all
650 try_catch_block_(NULL), 594 try_catch_block_(NULL),
651 next_used_try_index_(0), 595 next_used_try_index_(0),
652 catch_block_(NULL), 596 catch_block_(NULL),
653 streaming_flow_graph_builder_(NULL) { 597 streaming_flow_graph_builder_(NULL) {
654 Script& script = Script::Handle(Z, parsed_function->function().script()); 598 Script& script = Script::Handle(Z, parsed_function->function().script());
655 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets())); 599 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets()));
656 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); 600 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data()));
657 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names())); 601 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names()));
658 } 602 }
659 603
660
661 FlowGraphBuilder::~FlowGraphBuilder() { 604 FlowGraphBuilder::~FlowGraphBuilder() {
662 if (streaming_flow_graph_builder_ != NULL) { 605 if (streaming_flow_graph_builder_ != NULL) {
663 delete streaming_flow_graph_builder_; 606 delete streaming_flow_graph_builder_;
664 } 607 }
665 } 608 }
666 609
667
668 Fragment FlowGraphBuilder::TranslateFinallyFinalizers( 610 Fragment FlowGraphBuilder::TranslateFinallyFinalizers(
669 TryFinallyBlock* outer_finally, 611 TryFinallyBlock* outer_finally,
670 intptr_t target_context_depth) { 612 intptr_t target_context_depth) {
671 TryFinallyBlock* const saved_block = try_finally_block_; 613 TryFinallyBlock* const saved_block = try_finally_block_;
672 TryCatchBlock* const saved_try_catch_block = try_catch_block_; 614 TryCatchBlock* const saved_try_catch_block = try_catch_block_;
673 const intptr_t saved_depth = context_depth_; 615 const intptr_t saved_depth = context_depth_;
674 const intptr_t saved_try_depth = try_depth_; 616 const intptr_t saved_try_depth = try_depth_;
675 617
676 Fragment instructions; 618 Fragment instructions;
677 619
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 } 660 }
719 661
720 try_finally_block_ = saved_block; 662 try_finally_block_ = saved_block;
721 try_catch_block_ = saved_try_catch_block; 663 try_catch_block_ = saved_try_catch_block;
722 context_depth_ = saved_depth; 664 context_depth_ = saved_depth;
723 try_depth_ = saved_try_depth; 665 try_depth_ = saved_try_depth;
724 666
725 return instructions; 667 return instructions;
726 } 668 }
727 669
728
729 Fragment FlowGraphBuilder::EnterScope(intptr_t kernel_offset, 670 Fragment FlowGraphBuilder::EnterScope(intptr_t kernel_offset,
730 bool* new_context) { 671 bool* new_context) {
731 Fragment instructions; 672 Fragment instructions;
732 const intptr_t context_size = 673 const intptr_t context_size =
733 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); 674 scopes_->scopes.Lookup(kernel_offset)->num_context_variables();
734 if (context_size > 0) { 675 if (context_size > 0) {
735 instructions += PushContext(context_size); 676 instructions += PushContext(context_size);
736 instructions += Drop(); 677 instructions += Drop();
737 if (new_context != NULL) { 678 if (new_context != NULL) {
738 *new_context = true; 679 *new_context = true;
739 } 680 }
740 } 681 }
741 return instructions; 682 return instructions;
742 } 683 }
743 684
744
745 Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) { 685 Fragment FlowGraphBuilder::ExitScope(intptr_t kernel_offset) {
746 Fragment instructions; 686 Fragment instructions;
747 const intptr_t context_size = 687 const intptr_t context_size =
748 scopes_->scopes.Lookup(kernel_offset)->num_context_variables(); 688 scopes_->scopes.Lookup(kernel_offset)->num_context_variables();
749 if (context_size > 0) { 689 if (context_size > 0) {
750 instructions += PopContext(); 690 instructions += PopContext();
751 } 691 }
752 return instructions; 692 return instructions;
753 } 693 }
754 694
755
756 Fragment FlowGraphBuilder::LoadContextAt(int depth) { 695 Fragment FlowGraphBuilder::LoadContextAt(int depth) {
757 intptr_t delta = context_depth_ - depth; 696 intptr_t delta = context_depth_ - depth;
758 ASSERT(delta >= 0); 697 ASSERT(delta >= 0);
759 Fragment instructions = LoadLocal(parsed_function_->current_context_var()); 698 Fragment instructions = LoadLocal(parsed_function_->current_context_var());
760 while (delta-- > 0) { 699 while (delta-- > 0) {
761 instructions += LoadField(Context::parent_offset()); 700 instructions += LoadField(Context::parent_offset());
762 } 701 }
763 return instructions; 702 return instructions;
764 } 703 }
765 704
766
767 Fragment FlowGraphBuilder::AdjustContextTo(int depth) { 705 Fragment FlowGraphBuilder::AdjustContextTo(int depth) {
768 ASSERT(depth <= context_depth_ && depth >= 0); 706 ASSERT(depth <= context_depth_ && depth >= 0);
769 Fragment instructions; 707 Fragment instructions;
770 if (depth < context_depth_) { 708 if (depth < context_depth_) {
771 instructions += LoadContextAt(depth); 709 instructions += LoadContextAt(depth);
772 instructions += StoreLocal(TokenPosition::kNoSource, 710 instructions += StoreLocal(TokenPosition::kNoSource,
773 parsed_function_->current_context_var()); 711 parsed_function_->current_context_var());
774 instructions += Drop(); 712 instructions += Drop();
775 context_depth_ = depth; 713 context_depth_ = depth;
776 } 714 }
777 return instructions; 715 return instructions;
778 } 716 }
779 717
780
781 Fragment FlowGraphBuilder::PushContext(int size) { 718 Fragment FlowGraphBuilder::PushContext(int size) {
782 ASSERT(size > 0); 719 ASSERT(size > 0);
783 Fragment instructions = AllocateContext(size); 720 Fragment instructions = AllocateContext(size);
784 LocalVariable* context = MakeTemporary(); 721 LocalVariable* context = MakeTemporary();
785 instructions += LoadLocal(context); 722 instructions += LoadLocal(context);
786 instructions += LoadLocal(parsed_function_->current_context_var()); 723 instructions += LoadLocal(parsed_function_->current_context_var());
787 instructions += 724 instructions +=
788 StoreInstanceField(TokenPosition::kNoSource, Context::parent_offset()); 725 StoreInstanceField(TokenPosition::kNoSource, Context::parent_offset());
789 instructions += StoreLocal(TokenPosition::kNoSource, 726 instructions += StoreLocal(TokenPosition::kNoSource,
790 parsed_function_->current_context_var()); 727 parsed_function_->current_context_var());
791 ++context_depth_; 728 ++context_depth_;
792 return instructions; 729 return instructions;
793 } 730 }
794 731
795
796 Fragment FlowGraphBuilder::PopContext() { 732 Fragment FlowGraphBuilder::PopContext() {
797 return AdjustContextTo(context_depth_ - 1); 733 return AdjustContextTo(context_depth_ - 1);
798 } 734 }
799 735
800
801 Fragment FlowGraphBuilder::LoadInstantiatorTypeArguments() { 736 Fragment FlowGraphBuilder::LoadInstantiatorTypeArguments() {
802 // TODO(27590): We could use `active_class_->IsGeneric()`. 737 // TODO(27590): We could use `active_class_->IsGeneric()`.
803 Fragment instructions; 738 Fragment instructions;
804 if (scopes_->type_arguments_variable != NULL) { 739 if (scopes_->type_arguments_variable != NULL) {
805 #ifdef DEBUG 740 #ifdef DEBUG
806 Function& function = 741 Function& function =
807 Function::Handle(Z, parsed_function_->function().raw()); 742 Function::Handle(Z, parsed_function_->function().raw());
808 while (function.IsClosureFunction()) { 743 while (function.IsClosureFunction()) {
809 function = function.parent_function(); 744 function = function.parent_function();
810 } 745 }
811 ASSERT(function.IsFactory()); 746 ASSERT(function.IsFactory());
812 #endif 747 #endif
813 instructions += LoadLocal(scopes_->type_arguments_variable); 748 instructions += LoadLocal(scopes_->type_arguments_variable);
814 } else if (scopes_->this_variable != NULL && 749 } else if (scopes_->this_variable != NULL &&
815 active_class_.class_type_parameters > 0) { 750 active_class_.class_type_parameters > 0) {
816 ASSERT(!parsed_function_->function().IsFactory()); 751 ASSERT(!parsed_function_->function().IsFactory());
817 intptr_t type_arguments_field_offset = 752 intptr_t type_arguments_field_offset =
818 active_class_.klass->type_arguments_field_offset(); 753 active_class_.klass->type_arguments_field_offset();
819 ASSERT(type_arguments_field_offset != dart::Class::kNoTypeArguments); 754 ASSERT(type_arguments_field_offset != dart::Class::kNoTypeArguments);
820 755
821 instructions += LoadLocal(scopes_->this_variable); 756 instructions += LoadLocal(scopes_->this_variable);
822 instructions += LoadField(type_arguments_field_offset); 757 instructions += LoadField(type_arguments_field_offset);
823 } else { 758 } else {
824 instructions += NullConstant(); 759 instructions += NullConstant();
825 } 760 }
826 return instructions; 761 return instructions;
827 } 762 }
828 763
829
830 Fragment FlowGraphBuilder::LoadFunctionTypeArguments() { 764 Fragment FlowGraphBuilder::LoadFunctionTypeArguments() {
831 UNIMPLEMENTED(); // TODO(regis) 765 UNIMPLEMENTED(); // TODO(regis)
832 return Fragment(NULL); 766 return Fragment(NULL);
833 } 767 }
834 768
835
836 Fragment FlowGraphBuilder::InstantiateType(const AbstractType& type) { 769 Fragment FlowGraphBuilder::InstantiateType(const AbstractType& type) {
837 Value* function_type_args = Pop(); 770 Value* function_type_args = Pop();
838 Value* instantiator_type_args = Pop(); 771 Value* instantiator_type_args = Pop();
839 InstantiateTypeInstr* instr = new (Z) InstantiateTypeInstr( 772 InstantiateTypeInstr* instr = new (Z) InstantiateTypeInstr(
840 TokenPosition::kNoSource, type, instantiator_type_args, 773 TokenPosition::kNoSource, type, instantiator_type_args,
841 function_type_args, GetNextDeoptId()); 774 function_type_args, GetNextDeoptId());
842 Push(instr); 775 Push(instr);
843 return Fragment(instr); 776 return Fragment(instr);
844 } 777 }
845 778
846
847 Fragment FlowGraphBuilder::InstantiateTypeArguments( 779 Fragment FlowGraphBuilder::InstantiateTypeArguments(
848 const TypeArguments& type_arguments) { 780 const TypeArguments& type_arguments) {
849 Value* function_type_args = Pop(); 781 Value* function_type_args = Pop();
850 Value* instantiator_type_args = Pop(); 782 Value* instantiator_type_args = Pop();
851 InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr( 783 InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr(
852 TokenPosition::kNoSource, type_arguments, *active_class_.klass, 784 TokenPosition::kNoSource, type_arguments, *active_class_.klass,
853 instantiator_type_args, function_type_args, GetNextDeoptId()); 785 instantiator_type_args, function_type_args, GetNextDeoptId());
854 Push(instr); 786 Push(instr);
855 return Fragment(instr); 787 return Fragment(instr);
856 } 788 }
857 789
858
859 Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments( 790 Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments(
860 const TypeArguments& type_arguments) { 791 const TypeArguments& type_arguments) {
861 Fragment instructions; 792 Fragment instructions;
862 793
863 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 794 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
864 // There are no type references to type parameters so we can just take it. 795 // There are no type references to type parameters so we can just take it.
865 instructions += Constant(type_arguments); 796 instructions += Constant(type_arguments);
866 } else { 797 } else {
867 // The [type_arguments] vector contains a type reference to a type 798 // The [type_arguments] vector contains a type reference to a type
868 // parameter we need to resolve it. 799 // parameter we need to resolve it.
(...skipping 23 matching lines...) Expand all
892 instructions += LoadFunctionTypeArguments(); 823 instructions += LoadFunctionTypeArguments();
893 } else { 824 } else {
894 instructions += NullConstant(); 825 instructions += NullConstant();
895 } 826 }
896 instructions += InstantiateTypeArguments(type_arguments); 827 instructions += InstantiateTypeArguments(type_arguments);
897 } 828 }
898 } 829 }
899 return instructions; 830 return instructions;
900 } 831 }
901 832
902
903 Fragment FlowGraphBuilder::AllocateContext(int size) { 833 Fragment FlowGraphBuilder::AllocateContext(int size) {
904 AllocateContextInstr* allocate = 834 AllocateContextInstr* allocate =
905 new (Z) AllocateContextInstr(TokenPosition::kNoSource, size); 835 new (Z) AllocateContextInstr(TokenPosition::kNoSource, size);
906 Push(allocate); 836 Push(allocate);
907 return Fragment(allocate); 837 return Fragment(allocate);
908 } 838 }
909 839
910
911 Fragment FlowGraphBuilder::AllocateObject(TokenPosition position, 840 Fragment FlowGraphBuilder::AllocateObject(TokenPosition position,
912 const dart::Class& klass, 841 const dart::Class& klass,
913 intptr_t argument_count) { 842 intptr_t argument_count) {
914 ArgumentArray arguments = GetArguments(argument_count); 843 ArgumentArray arguments = GetArguments(argument_count);
915 AllocateObjectInstr* allocate = 844 AllocateObjectInstr* allocate =
916 new (Z) AllocateObjectInstr(position, klass, arguments); 845 new (Z) AllocateObjectInstr(position, klass, arguments);
917 Push(allocate); 846 Push(allocate);
918 return Fragment(allocate); 847 return Fragment(allocate);
919 } 848 }
920 849
921
922 Fragment FlowGraphBuilder::AllocateObject(const dart::Class& klass, 850 Fragment FlowGraphBuilder::AllocateObject(const dart::Class& klass,
923 const Function& closure_function) { 851 const Function& closure_function) {
924 ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0); 852 ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0);
925 AllocateObjectInstr* allocate = 853 AllocateObjectInstr* allocate =
926 new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments); 854 new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments);
927 allocate->set_closure_function(closure_function); 855 allocate->set_closure_function(closure_function);
928 Push(allocate); 856 Push(allocate);
929 return Fragment(allocate); 857 return Fragment(allocate);
930 } 858 }
931 859
932
933 Fragment FlowGraphBuilder::BooleanNegate() { 860 Fragment FlowGraphBuilder::BooleanNegate() {
934 BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(Pop()); 861 BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(Pop());
935 Push(negate); 862 Push(negate);
936 return Fragment(negate); 863 return Fragment(negate);
937 } 864 }
938 865
939
940 Fragment FlowGraphBuilder::StrictCompare(Token::Kind kind, 866 Fragment FlowGraphBuilder::StrictCompare(Token::Kind kind,
941 bool number_check /* = false */) { 867 bool number_check /* = false */) {
942 Value* right = Pop(); 868 Value* right = Pop();
943 Value* left = Pop(); 869 Value* left = Pop();
944 StrictCompareInstr* compare = 870 StrictCompareInstr* compare =
945 new (Z) StrictCompareInstr(TokenPosition::kNoSource, kind, left, right, 871 new (Z) StrictCompareInstr(TokenPosition::kNoSource, kind, left, right,
946 number_check, GetNextDeoptId()); 872 number_check, GetNextDeoptId());
947 Push(compare); 873 Push(compare);
948 return Fragment(compare); 874 return Fragment(compare);
949 } 875 }
950 876
951
952 Fragment FlowGraphBuilder::BranchIfTrue(TargetEntryInstr** then_entry, 877 Fragment FlowGraphBuilder::BranchIfTrue(TargetEntryInstr** then_entry,
953 TargetEntryInstr** otherwise_entry, 878 TargetEntryInstr** otherwise_entry,
954 bool negate) { 879 bool negate) {
955 Fragment instructions = Constant(Bool::True()); 880 Fragment instructions = Constant(Bool::True());
956 return instructions + BranchIfEqual(then_entry, otherwise_entry, negate); 881 return instructions + BranchIfEqual(then_entry, otherwise_entry, negate);
957 } 882 }
958 883
959
960 Fragment FlowGraphBuilder::BranchIfNull(TargetEntryInstr** then_entry, 884 Fragment FlowGraphBuilder::BranchIfNull(TargetEntryInstr** then_entry,
961 TargetEntryInstr** otherwise_entry, 885 TargetEntryInstr** otherwise_entry,
962 bool negate) { 886 bool negate) {
963 Fragment instructions = NullConstant(); 887 Fragment instructions = NullConstant();
964 return instructions + BranchIfEqual(then_entry, otherwise_entry, negate); 888 return instructions + BranchIfEqual(then_entry, otherwise_entry, negate);
965 } 889 }
966 890
967 Fragment FlowGraphBuilder::BranchIfEqual(TargetEntryInstr** then_entry, 891 Fragment FlowGraphBuilder::BranchIfEqual(TargetEntryInstr** then_entry,
968 TargetEntryInstr** otherwise_entry, 892 TargetEntryInstr** otherwise_entry,
969 bool negate) { 893 bool negate) {
970 Value* right_value = Pop(); 894 Value* right_value = Pop();
971 Value* left_value = Pop(); 895 Value* left_value = Pop();
972 StrictCompareInstr* compare = new (Z) StrictCompareInstr( 896 StrictCompareInstr* compare = new (Z) StrictCompareInstr(
973 TokenPosition::kNoSource, negate ? Token::kNE_STRICT : Token::kEQ_STRICT, 897 TokenPosition::kNoSource, negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
974 left_value, right_value, false, GetNextDeoptId()); 898 left_value, right_value, false, GetNextDeoptId());
975 BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId()); 899 BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId());
976 *then_entry = *branch->true_successor_address() = BuildTargetEntry(); 900 *then_entry = *branch->true_successor_address() = BuildTargetEntry();
977 *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry(); 901 *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
978 return Fragment(branch).closed(); 902 return Fragment(branch).closed();
979 } 903 }
980 904
981
982 Fragment FlowGraphBuilder::BranchIfStrictEqual( 905 Fragment FlowGraphBuilder::BranchIfStrictEqual(
983 TargetEntryInstr** then_entry, 906 TargetEntryInstr** then_entry,
984 TargetEntryInstr** otherwise_entry) { 907 TargetEntryInstr** otherwise_entry) {
985 Value* rhs = Pop(); 908 Value* rhs = Pop();
986 Value* lhs = Pop(); 909 Value* lhs = Pop();
987 StrictCompareInstr* compare = 910 StrictCompareInstr* compare =
988 new (Z) StrictCompareInstr(TokenPosition::kNoSource, Token::kEQ_STRICT, 911 new (Z) StrictCompareInstr(TokenPosition::kNoSource, Token::kEQ_STRICT,
989 lhs, rhs, false, GetNextDeoptId()); 912 lhs, rhs, false, GetNextDeoptId());
990 BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId()); 913 BranchInstr* branch = new (Z) BranchInstr(compare, GetNextDeoptId());
991 *then_entry = *branch->true_successor_address() = BuildTargetEntry(); 914 *then_entry = *branch->true_successor_address() = BuildTargetEntry();
992 *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry(); 915 *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
993 return Fragment(branch).closed(); 916 return Fragment(branch).closed();
994 } 917 }
995 918
996
997 Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types, 919 Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
998 intptr_t handler_index, 920 intptr_t handler_index,
999 bool needs_stacktrace) { 921 bool needs_stacktrace) {
1000 ASSERT(CurrentException()->is_captured() == 922 ASSERT(CurrentException()->is_captured() ==
1001 CurrentStackTrace()->is_captured()); 923 CurrentStackTrace()->is_captured());
1002 const bool should_restore_closure_context = 924 const bool should_restore_closure_context =
1003 CurrentException()->is_captured() || CurrentCatchContext()->is_captured(); 925 CurrentException()->is_captured() || CurrentCatchContext()->is_captured();
1004 CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr( 926 CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
1005 TokenPosition::kNoSource, // Token position of catch block. 927 TokenPosition::kNoSource, // Token position of catch block.
1006 false, // Not an artifact of compilation. 928 false, // Not an artifact of compilation.
(...skipping 14 matching lines...) Expand all
1021 context_depth_ = 0; 943 context_depth_ = 0;
1022 instructions += LoadLocal(CurrentCatchContext()); 944 instructions += LoadLocal(CurrentCatchContext());
1023 instructions += StoreLocal(TokenPosition::kNoSource, 945 instructions += StoreLocal(TokenPosition::kNoSource,
1024 parsed_function_->current_context_var()); 946 parsed_function_->current_context_var());
1025 instructions += Drop(); 947 instructions += Drop();
1026 context_depth_ = saved_context_depth; 948 context_depth_ = saved_context_depth;
1027 949
1028 return instructions; 950 return instructions;
1029 } 951 }
1030 952
1031
1032 Fragment FlowGraphBuilder::TryCatch(int try_handler_index) { 953 Fragment FlowGraphBuilder::TryCatch(int try_handler_index) {
1033 // The body of the try needs to have it's own block in order to get a new try 954 // The body of the try needs to have it's own block in order to get a new try
1034 // index. 955 // index.
1035 // 956 //
1036 // => We therefore create a block for the body (fresh try index) and another 957 // => We therefore create a block for the body (fresh try index) and another
1037 // join block (with current try index). 958 // join block (with current try index).
1038 Fragment body; 959 Fragment body;
1039 JoinEntryInstr* entry = new (Z) 960 JoinEntryInstr* entry = new (Z)
1040 JoinEntryInstr(AllocateBlockId(), try_handler_index, GetNextDeoptId()); 961 JoinEntryInstr(AllocateBlockId(), try_handler_index, GetNextDeoptId());
1041 body += LoadLocal(parsed_function_->current_context_var()); 962 body += LoadLocal(parsed_function_->current_context_var());
1042 body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext()); 963 body += StoreLocal(TokenPosition::kNoSource, CurrentCatchContext());
1043 body += Drop(); 964 body += Drop();
1044 body += Goto(entry); 965 body += Goto(entry);
1045 return Fragment(body.entry, entry); 966 return Fragment(body.entry, entry);
1046 } 967 }
1047 968
1048
1049 Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() { 969 Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() {
1050 if (IsInlining()) { 970 if (IsInlining()) {
1051 // If we are inlining don't actually attach the stack check. We must still 971 // If we are inlining don't actually attach the stack check. We must still
1052 // create the stack check in order to allocate a deopt id. 972 // create the stack check in order to allocate a deopt id.
1053 CheckStackOverflow(); 973 CheckStackOverflow();
1054 return Fragment(); 974 return Fragment();
1055 } 975 }
1056 return CheckStackOverflow(); 976 return CheckStackOverflow();
1057 } 977 }
1058 978
1059
1060 Fragment FlowGraphBuilder::CheckStackOverflow() { 979 Fragment FlowGraphBuilder::CheckStackOverflow() {
1061 return Fragment(new (Z) CheckStackOverflowInstr( 980 return Fragment(new (Z) CheckStackOverflowInstr(
1062 TokenPosition::kNoSource, loop_depth_, GetNextDeoptId())); 981 TokenPosition::kNoSource, loop_depth_, GetNextDeoptId()));
1063 } 982 }
1064 983
1065
1066 Fragment FlowGraphBuilder::CloneContext() { 984 Fragment FlowGraphBuilder::CloneContext() {
1067 LocalVariable* context_variable = parsed_function_->current_context_var(); 985 LocalVariable* context_variable = parsed_function_->current_context_var();
1068 986
1069 Fragment instructions = LoadLocal(context_variable); 987 Fragment instructions = LoadLocal(context_variable);
1070 988
1071 CloneContextInstr* clone_instruction = new (Z) 989 CloneContextInstr* clone_instruction = new (Z)
1072 CloneContextInstr(TokenPosition::kNoSource, Pop(), GetNextDeoptId()); 990 CloneContextInstr(TokenPosition::kNoSource, Pop(), GetNextDeoptId());
1073 instructions <<= clone_instruction; 991 instructions <<= clone_instruction;
1074 Push(clone_instruction); 992 Push(clone_instruction);
1075 993
1076 instructions += StoreLocal(TokenPosition::kNoSource, context_variable); 994 instructions += StoreLocal(TokenPosition::kNoSource, context_variable);
1077 instructions += Drop(); 995 instructions += Drop();
1078 return instructions; 996 return instructions;
1079 } 997 }
1080 998
1081
1082 Fragment FlowGraphBuilder::Constant(const Object& value) { 999 Fragment FlowGraphBuilder::Constant(const Object& value) {
1083 ASSERT(value.IsNotTemporaryScopedHandle()); 1000 ASSERT(value.IsNotTemporaryScopedHandle());
1084 ConstantInstr* constant = new (Z) ConstantInstr(value); 1001 ConstantInstr* constant = new (Z) ConstantInstr(value);
1085 Push(constant); 1002 Push(constant);
1086 return Fragment(constant); 1003 return Fragment(constant);
1087 } 1004 }
1088 1005
1089
1090 Fragment FlowGraphBuilder::CreateArray() { 1006 Fragment FlowGraphBuilder::CreateArray() {
1091 Value* element_count = Pop(); 1007 Value* element_count = Pop();
1092 CreateArrayInstr* array = 1008 CreateArrayInstr* array =
1093 new (Z) CreateArrayInstr(TokenPosition::kNoSource, 1009 new (Z) CreateArrayInstr(TokenPosition::kNoSource,
1094 Pop(), // Element type. 1010 Pop(), // Element type.
1095 element_count, GetNextDeoptId()); 1011 element_count, GetNextDeoptId());
1096 Push(array); 1012 Push(array);
1097 return Fragment(array); 1013 return Fragment(array);
1098 } 1014 }
1099 1015
1100
1101 Fragment FlowGraphBuilder::Goto(JoinEntryInstr* destination) { 1016 Fragment FlowGraphBuilder::Goto(JoinEntryInstr* destination) {
1102 return Fragment(new (Z) GotoInstr(destination, GetNextDeoptId())).closed(); 1017 return Fragment(new (Z) GotoInstr(destination, GetNextDeoptId())).closed();
1103 } 1018 }
1104 1019
1105
1106 Fragment FlowGraphBuilder::IntConstant(int64_t value) { 1020 Fragment FlowGraphBuilder::IntConstant(int64_t value) {
1107 return Fragment( 1021 return Fragment(
1108 Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)))); 1022 Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld))));
1109 } 1023 }
1110 1024
1111
1112 Fragment FlowGraphBuilder::InstanceCall(TokenPosition position, 1025 Fragment FlowGraphBuilder::InstanceCall(TokenPosition position,
1113 const dart::String& name, 1026 const dart::String& name,
1114 Token::Kind kind, 1027 Token::Kind kind,
1115 intptr_t argument_count, 1028 intptr_t argument_count,
1116 intptr_t checked_argument_count) { 1029 intptr_t checked_argument_count) {
1117 const intptr_t kTypeArgsLen = 0; 1030 const intptr_t kTypeArgsLen = 0;
1118 return InstanceCall(position, name, kind, kTypeArgsLen, argument_count, 1031 return InstanceCall(position, name, kind, kTypeArgsLen, argument_count,
1119 Array::null_array(), checked_argument_count); 1032 Array::null_array(), checked_argument_count);
1120 } 1033 }
1121 1034
1122
1123 Fragment FlowGraphBuilder::InstanceCall(TokenPosition position, 1035 Fragment FlowGraphBuilder::InstanceCall(TokenPosition position,
1124 const dart::String& name, 1036 const dart::String& name,
1125 Token::Kind kind, 1037 Token::Kind kind,
1126 intptr_t type_args_len, 1038 intptr_t type_args_len,
1127 intptr_t argument_count, 1039 intptr_t argument_count,
1128 const Array& argument_names, 1040 const Array& argument_names,
1129 intptr_t checked_argument_count) { 1041 intptr_t checked_argument_count) {
1130 const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0); 1042 const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
1131 ArgumentArray arguments = GetArguments(total_count); 1043 ArgumentArray arguments = GetArguments(total_count);
1132 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1044 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1133 position, name, kind, arguments, type_args_len, argument_names, 1045 position, name, kind, arguments, type_args_len, argument_names,
1134 checked_argument_count, ic_data_array_, GetNextDeoptId()); 1046 checked_argument_count, ic_data_array_, GetNextDeoptId());
1135 Push(call); 1047 Push(call);
1136 return Fragment(call); 1048 return Fragment(call);
1137 } 1049 }
1138 1050
1139
1140 Fragment FlowGraphBuilder::ClosureCall(intptr_t type_args_len, 1051 Fragment FlowGraphBuilder::ClosureCall(intptr_t type_args_len,
1141 intptr_t argument_count, 1052 intptr_t argument_count,
1142 const Array& argument_names) { 1053 const Array& argument_names) {
1143 Value* function = Pop(); 1054 Value* function = Pop();
1144 const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0); 1055 const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
1145 ArgumentArray arguments = GetArguments(total_count); 1056 ArgumentArray arguments = GetArguments(total_count);
1146 ClosureCallInstr* call = new (Z) 1057 ClosureCallInstr* call = new (Z)
1147 ClosureCallInstr(function, arguments, type_args_len, argument_names, 1058 ClosureCallInstr(function, arguments, type_args_len, argument_names,
1148 TokenPosition::kNoSource, GetNextDeoptId()); 1059 TokenPosition::kNoSource, GetNextDeoptId());
1149 Push(call); 1060 Push(call);
1150 return Fragment(call); 1061 return Fragment(call);
1151 } 1062 }
1152 1063
1153
1154 Fragment FlowGraphBuilder::ThrowException(TokenPosition position) { 1064 Fragment FlowGraphBuilder::ThrowException(TokenPosition position) {
1155 Fragment instructions; 1065 Fragment instructions;
1156 instructions += Drop(); 1066 instructions += Drop();
1157 instructions += 1067 instructions +=
1158 Fragment(new (Z) ThrowInstr(position, GetNextDeoptId())).closed(); 1068 Fragment(new (Z) ThrowInstr(position, GetNextDeoptId())).closed();
1159 // Use it's side effect of leaving a constant on the stack (does not change 1069 // Use it's side effect of leaving a constant on the stack (does not change
1160 // the graph). 1070 // the graph).
1161 NullConstant(); 1071 NullConstant();
1162 1072
1163 pending_argument_count_ -= 1; 1073 pending_argument_count_ -= 1;
1164 1074
1165 return instructions; 1075 return instructions;
1166 } 1076 }
1167 1077
1168
1169 Fragment FlowGraphBuilder::RethrowException(TokenPosition position, 1078 Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
1170 int catch_try_index) { 1079 int catch_try_index) {
1171 Fragment instructions; 1080 Fragment instructions;
1172 instructions += Drop(); 1081 instructions += Drop();
1173 instructions += Drop(); 1082 instructions += Drop();
1174 instructions += Fragment(new (Z) ReThrowInstr(position, catch_try_index, 1083 instructions += Fragment(new (Z) ReThrowInstr(position, catch_try_index,
1175 GetNextDeoptId())) 1084 GetNextDeoptId()))
1176 .closed(); 1085 .closed();
1177 // Use it's side effect of leaving a constant on the stack (does not change 1086 // Use it's side effect of leaving a constant on the stack (does not change
1178 // the graph). 1087 // the graph).
1179 NullConstant(); 1088 NullConstant();
1180 1089
1181 pending_argument_count_ -= 2; 1090 pending_argument_count_ -= 2;
1182 1091
1183 return instructions; 1092 return instructions;
1184 } 1093 }
1185 1094
1186
1187 Fragment FlowGraphBuilder::LoadClassId() { 1095 Fragment FlowGraphBuilder::LoadClassId() {
1188 LoadClassIdInstr* load = new (Z) LoadClassIdInstr(Pop()); 1096 LoadClassIdInstr* load = new (Z) LoadClassIdInstr(Pop());
1189 Push(load); 1097 Push(load);
1190 return Fragment(load); 1098 return Fragment(load);
1191 } 1099 }
1192 1100
1193
1194 const dart::Field& MayCloneField(Zone* zone, const dart::Field& field) { 1101 const dart::Field& MayCloneField(Zone* zone, const dart::Field& field) {
1195 if ((Compiler::IsBackgroundCompilation() || 1102 if ((Compiler::IsBackgroundCompilation() ||
1196 FLAG_force_clone_compiler_objects) && 1103 FLAG_force_clone_compiler_objects) &&
1197 field.IsOriginal()) { 1104 field.IsOriginal()) {
1198 return dart::Field::ZoneHandle(zone, field.CloneFromOriginal()); 1105 return dart::Field::ZoneHandle(zone, field.CloneFromOriginal());
1199 } else { 1106 } else {
1200 ASSERT(field.IsZoneHandle()); 1107 ASSERT(field.IsZoneHandle());
1201 return field; 1108 return field;
1202 } 1109 }
1203 } 1110 }
1204 1111
1205
1206 Fragment FlowGraphBuilder::LoadField(const dart::Field& field) { 1112 Fragment FlowGraphBuilder::LoadField(const dart::Field& field) {
1207 LoadFieldInstr* load = 1113 LoadFieldInstr* load =
1208 new (Z) LoadFieldInstr(Pop(), &MayCloneField(Z, field), 1114 new (Z) LoadFieldInstr(Pop(), &MayCloneField(Z, field),
1209 AbstractType::ZoneHandle(Z, field.type()), 1115 AbstractType::ZoneHandle(Z, field.type()),
1210 TokenPosition::kNoSource, parsed_function_); 1116 TokenPosition::kNoSource, parsed_function_);
1211 Push(load); 1117 Push(load);
1212 return Fragment(load); 1118 return Fragment(load);
1213 } 1119 }
1214 1120
1215
1216 Fragment FlowGraphBuilder::LoadField(intptr_t offset, intptr_t class_id) { 1121 Fragment FlowGraphBuilder::LoadField(intptr_t offset, intptr_t class_id) {
1217 LoadFieldInstr* load = new (Z) LoadFieldInstr( 1122 LoadFieldInstr* load = new (Z) LoadFieldInstr(
1218 Pop(), offset, AbstractType::ZoneHandle(Z), TokenPosition::kNoSource); 1123 Pop(), offset, AbstractType::ZoneHandle(Z), TokenPosition::kNoSource);
1219 load->set_result_cid(class_id); 1124 load->set_result_cid(class_id);
1220 Push(load); 1125 Push(load);
1221 return Fragment(load); 1126 return Fragment(load);
1222 } 1127 }
1223 1128
1224
1225 Fragment FlowGraphBuilder::LoadNativeField(MethodRecognizer::Kind kind, 1129 Fragment FlowGraphBuilder::LoadNativeField(MethodRecognizer::Kind kind,
1226 intptr_t offset, 1130 intptr_t offset,
1227 const Type& type, 1131 const Type& type,
1228 intptr_t class_id, 1132 intptr_t class_id,
1229 bool is_immutable) { 1133 bool is_immutable) {
1230 LoadFieldInstr* load = 1134 LoadFieldInstr* load =
1231 new (Z) LoadFieldInstr(Pop(), offset, type, TokenPosition::kNoSource); 1135 new (Z) LoadFieldInstr(Pop(), offset, type, TokenPosition::kNoSource);
1232 load->set_recognized_kind(kind); 1136 load->set_recognized_kind(kind);
1233 load->set_result_cid(class_id); 1137 load->set_result_cid(class_id);
1234 load->set_is_immutable(is_immutable); 1138 load->set_is_immutable(is_immutable);
1235 Push(load); 1139 Push(load);
1236 return Fragment(load); 1140 return Fragment(load);
1237 } 1141 }
1238 1142
1239
1240 Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) { 1143 Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) {
1241 Fragment instructions; 1144 Fragment instructions;
1242 if (variable->is_captured()) { 1145 if (variable->is_captured()) {
1243 instructions += LoadContextAt(variable->owner()->context_level()); 1146 instructions += LoadContextAt(variable->owner()->context_level());
1244 instructions += LoadField(Context::variable_offset(variable->index())); 1147 instructions += LoadField(Context::variable_offset(variable->index()));
1245 } else { 1148 } else {
1246 LoadLocalInstr* load = 1149 LoadLocalInstr* load =
1247 new (Z) LoadLocalInstr(*variable, TokenPosition::kNoSource); 1150 new (Z) LoadLocalInstr(*variable, TokenPosition::kNoSource);
1248 instructions <<= load; 1151 instructions <<= load;
1249 Push(load); 1152 Push(load);
1250 } 1153 }
1251 return instructions; 1154 return instructions;
1252 } 1155 }
1253 1156
1254
1255 Fragment FlowGraphBuilder::InitStaticField(const dart::Field& field) { 1157 Fragment FlowGraphBuilder::InitStaticField(const dart::Field& field) {
1256 InitStaticFieldInstr* init = new (Z) 1158 InitStaticFieldInstr* init = new (Z)
1257 InitStaticFieldInstr(Pop(), MayCloneField(Z, field), GetNextDeoptId()); 1159 InitStaticFieldInstr(Pop(), MayCloneField(Z, field), GetNextDeoptId());
1258 return Fragment(init); 1160 return Fragment(init);
1259 } 1161 }
1260 1162
1261
1262 Fragment FlowGraphBuilder::LoadStaticField() { 1163 Fragment FlowGraphBuilder::LoadStaticField() {
1263 LoadStaticFieldInstr* load = 1164 LoadStaticFieldInstr* load =
1264 new (Z) LoadStaticFieldInstr(Pop(), TokenPosition::kNoSource); 1165 new (Z) LoadStaticFieldInstr(Pop(), TokenPosition::kNoSource);
1265 Push(load); 1166 Push(load);
1266 return Fragment(load); 1167 return Fragment(load);
1267 } 1168 }
1268 1169
1269
1270 Fragment FlowGraphBuilder::NullConstant() { 1170 Fragment FlowGraphBuilder::NullConstant() {
1271 return Constant(Instance::ZoneHandle(Z, Instance::null())); 1171 return Constant(Instance::ZoneHandle(Z, Instance::null()));
1272 } 1172 }
1273 1173
1274
1275 Fragment FlowGraphBuilder::NativeCall(const dart::String* name, 1174 Fragment FlowGraphBuilder::NativeCall(const dart::String* name,
1276 const Function* function) { 1175 const Function* function) {
1277 InlineBailout("kernel::FlowGraphBuilder::NativeCall"); 1176 InlineBailout("kernel::FlowGraphBuilder::NativeCall");
1278 NativeCallInstr* call = new (Z) NativeCallInstr( 1177 NativeCallInstr* call = new (Z) NativeCallInstr(
1279 name, function, FLAG_link_natives_lazily, TokenPosition::kNoSource); 1178 name, function, FLAG_link_natives_lazily, TokenPosition::kNoSource);
1280 Push(call); 1179 Push(call);
1281 return Fragment(call); 1180 return Fragment(call);
1282 } 1181 }
1283 1182
1284
1285 Fragment FlowGraphBuilder::PushArgument() { 1183 Fragment FlowGraphBuilder::PushArgument() {
1286 PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop()); 1184 PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop());
1287 Push(argument); 1185 Push(argument);
1288 1186
1289 argument->set_temp_index(argument->temp_index() - 1); 1187 argument->set_temp_index(argument->temp_index() - 1);
1290 ++pending_argument_count_; 1188 ++pending_argument_count_;
1291 1189
1292 return Fragment(argument); 1190 return Fragment(argument);
1293 } 1191 }
1294 1192
1295
1296 Fragment FlowGraphBuilder::Return(TokenPosition position) { 1193 Fragment FlowGraphBuilder::Return(TokenPosition position) {
1297 Fragment instructions; 1194 Fragment instructions;
1298 1195
1299 instructions += CheckReturnTypeInCheckedMode(); 1196 instructions += CheckReturnTypeInCheckedMode();
1300 1197
1301 Value* value = Pop(); 1198 Value* value = Pop();
1302 ASSERT(stack_ == NULL); 1199 ASSERT(stack_ == NULL);
1303 1200
1304 const Function& function = parsed_function_->function(); 1201 const Function& function = parsed_function_->function();
1305 if (NeedsDebugStepCheck(function, position)) { 1202 if (NeedsDebugStepCheck(function, position)) {
(...skipping 13 matching lines...) Expand all
1319 1216
1320 ReturnInstr* return_instr = 1217 ReturnInstr* return_instr =
1321 new (Z) ReturnInstr(position, value, GetNextDeoptId()); 1218 new (Z) ReturnInstr(position, value, GetNextDeoptId());
1322 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); 1219 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr);
1323 1220
1324 instructions <<= return_instr; 1221 instructions <<= return_instr;
1325 1222
1326 return instructions.closed(); 1223 return instructions.closed();
1327 } 1224 }
1328 1225
1329
1330 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, 1226 Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
1331 const Function& target, 1227 const Function& target,
1332 intptr_t argument_count) { 1228 intptr_t argument_count) {
1333 return StaticCall(position, target, argument_count, Array::null_array()); 1229 return StaticCall(position, target, argument_count, Array::null_array());
1334 } 1230 }
1335 1231
1336
1337 static intptr_t GetResultCidOfListFactory(Zone* zone, 1232 static intptr_t GetResultCidOfListFactory(Zone* zone,
1338 const Function& function, 1233 const Function& function,
1339 intptr_t argument_count) { 1234 intptr_t argument_count) {
1340 if (!function.IsFactory()) { 1235 if (!function.IsFactory()) {
1341 return kDynamicCid; 1236 return kDynamicCid;
1342 } 1237 }
1343 1238
1344 const dart::Class& owner = dart::Class::Handle(zone, function.Owner()); 1239 const dart::Class& owner = dart::Class::Handle(zone, function.Owner());
1345 if ((owner.library() != dart::Library::CoreLibrary()) && 1240 if ((owner.library() != dart::Library::CoreLibrary()) &&
1346 (owner.library() != dart::Library::TypedDataLibrary())) { 1241 (owner.library() != dart::Library::TypedDataLibrary())) {
1347 return kDynamicCid; 1242 return kDynamicCid;
1348 } 1243 }
1349 1244
1350 if ((owner.Name() == Symbols::List().raw()) && 1245 if ((owner.Name() == Symbols::List().raw()) &&
1351 (function.name() == Symbols::ListFactory().raw())) { 1246 (function.name() == Symbols::ListFactory().raw())) {
1352 ASSERT(argument_count == 1 || argument_count == 2); 1247 ASSERT(argument_count == 1 || argument_count == 2);
1353 return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid; 1248 return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid;
1354 } 1249 }
1355 return FactoryRecognizer::ResultCid(function); 1250 return FactoryRecognizer::ResultCid(function);
1356 } 1251 }
1357 1252
1358
1359 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, 1253 Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
1360 const Function& target, 1254 const Function& target,
1361 intptr_t argument_count, 1255 intptr_t argument_count,
1362 const Array& argument_names) { 1256 const Array& argument_names) {
1363 ArgumentArray arguments = GetArguments(argument_count); 1257 ArgumentArray arguments = GetArguments(argument_count);
1364 const intptr_t kTypeArgsLen = 0; // Generic static calls not yet supported. 1258 const intptr_t kTypeArgsLen = 0; // Generic static calls not yet supported.
1365 StaticCallInstr* call = 1259 StaticCallInstr* call =
1366 new (Z) StaticCallInstr(position, target, kTypeArgsLen, argument_names, 1260 new (Z) StaticCallInstr(position, target, kTypeArgsLen, argument_names,
1367 arguments, ic_data_array_, GetNextDeoptId()); 1261 arguments, ic_data_array_, GetNextDeoptId());
1368 const intptr_t list_cid = 1262 const intptr_t list_cid =
1369 GetResultCidOfListFactory(Z, target, argument_count); 1263 GetResultCidOfListFactory(Z, target, argument_count);
1370 if (list_cid != kDynamicCid) { 1264 if (list_cid != kDynamicCid) {
1371 call->set_result_cid(list_cid); 1265 call->set_result_cid(list_cid);
1372 call->set_is_known_list_constructor(true); 1266 call->set_is_known_list_constructor(true);
1373 } else if (target.recognized_kind() != MethodRecognizer::kUnknown) { 1267 } else if (target.recognized_kind() != MethodRecognizer::kUnknown) {
1374 call->set_result_cid(MethodRecognizer::ResultCid(target)); 1268 call->set_result_cid(MethodRecognizer::ResultCid(target));
1375 } 1269 }
1376 Push(call); 1270 Push(call);
1377 return Fragment(call); 1271 return Fragment(call);
1378 } 1272 }
1379 1273
1380
1381 Fragment FlowGraphBuilder::StoreIndexed(intptr_t class_id) { 1274 Fragment FlowGraphBuilder::StoreIndexed(intptr_t class_id) {
1382 Value* value = Pop(); 1275 Value* value = Pop();
1383 Value* index = Pop(); 1276 Value* index = Pop();
1384 const StoreBarrierType emit_store_barrier = 1277 const StoreBarrierType emit_store_barrier =
1385 value->BindsToConstant() ? kNoStoreBarrier : kEmitStoreBarrier; 1278 value->BindsToConstant() ? kNoStoreBarrier : kEmitStoreBarrier;
1386 StoreIndexedInstr* store = new (Z) StoreIndexedInstr( 1279 StoreIndexedInstr* store = new (Z) StoreIndexedInstr(
1387 Pop(), // Array. 1280 Pop(), // Array.
1388 index, value, emit_store_barrier, Instance::ElementSizeFor(class_id), 1281 index, value, emit_store_barrier, Instance::ElementSizeFor(class_id),
1389 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource); 1282 class_id, kAlignedAccess, Thread::kNoDeoptId, TokenPosition::kNoSource);
1390 Push(store); 1283 Push(store);
1391 return Fragment(store); 1284 return Fragment(store);
1392 } 1285 }
1393 1286
1394
1395 Fragment FlowGraphBuilder::StoreInstanceField( 1287 Fragment FlowGraphBuilder::StoreInstanceField(
1396 const dart::Field& field, 1288 const dart::Field& field,
1397 bool is_initialization_store, 1289 bool is_initialization_store,
1398 StoreBarrierType emit_store_barrier) { 1290 StoreBarrierType emit_store_barrier) {
1399 Fragment instructions; 1291 Fragment instructions;
1400 1292
1401 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type()); 1293 const AbstractType& dst_type = AbstractType::ZoneHandle(Z, field.type());
1402 instructions += CheckAssignableInCheckedMode( 1294 instructions += CheckAssignableInCheckedMode(
1403 dst_type, dart::String::ZoneHandle(Z, field.name())); 1295 dst_type, dart::String::ZoneHandle(Z, field.name()));
1404 1296
1405 Value* value = Pop(); 1297 Value* value = Pop();
1406 if (value->BindsToConstant()) { 1298 if (value->BindsToConstant()) {
1407 emit_store_barrier = kNoStoreBarrier; 1299 emit_store_barrier = kNoStoreBarrier;
1408 } 1300 }
1409 1301
1410 StoreInstanceFieldInstr* store = new (Z) 1302 StoreInstanceFieldInstr* store = new (Z)
1411 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value, 1303 StoreInstanceFieldInstr(MayCloneField(Z, field), Pop(), value,
1412 emit_store_barrier, TokenPosition::kNoSource); 1304 emit_store_barrier, TokenPosition::kNoSource);
1413 store->set_is_initialization(is_initialization_store); 1305 store->set_is_initialization(is_initialization_store);
1414 instructions <<= store; 1306 instructions <<= store;
1415 1307
1416 return instructions; 1308 return instructions;
1417 } 1309 }
1418 1310
1419
1420 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( 1311 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded(
1421 const dart::Field& field, 1312 const dart::Field& field,
1422 bool is_initialization_store) { 1313 bool is_initialization_store) {
1423 Fragment instructions; 1314 Fragment instructions;
1424 const dart::Field& field_clone = MayCloneField(Z, field); 1315 const dart::Field& field_clone = MayCloneField(Z, field);
1425 if (I->use_field_guards()) { 1316 if (I->use_field_guards()) {
1426 LocalVariable* store_expression = MakeTemporary(); 1317 LocalVariable* store_expression = MakeTemporary();
1427 instructions += LoadLocal(store_expression); 1318 instructions += LoadLocal(store_expression);
1428 instructions += GuardFieldClass(field_clone, GetNextDeoptId()); 1319 instructions += GuardFieldClass(field_clone, GetNextDeoptId());
1429 instructions += LoadLocal(store_expression); 1320 instructions += LoadLocal(store_expression);
1430 instructions += GuardFieldLength(field_clone, GetNextDeoptId()); 1321 instructions += GuardFieldLength(field_clone, GetNextDeoptId());
1431 } 1322 }
1432 instructions += StoreInstanceField(field_clone, is_initialization_store); 1323 instructions += StoreInstanceField(field_clone, is_initialization_store);
1433 return instructions; 1324 return instructions;
1434 } 1325 }
1435 1326
1436
1437 Fragment FlowGraphBuilder::StoreInstanceField( 1327 Fragment FlowGraphBuilder::StoreInstanceField(
1438 TokenPosition position, 1328 TokenPosition position,
1439 intptr_t offset, 1329 intptr_t offset,
1440 StoreBarrierType emit_store_barrier) { 1330 StoreBarrierType emit_store_barrier) {
1441 Value* value = Pop(); 1331 Value* value = Pop();
1442 if (value->BindsToConstant()) { 1332 if (value->BindsToConstant()) {
1443 emit_store_barrier = kNoStoreBarrier; 1333 emit_store_barrier = kNoStoreBarrier;
1444 } 1334 }
1445 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( 1335 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
1446 offset, Pop(), value, emit_store_barrier, position); 1336 offset, Pop(), value, emit_store_barrier, position);
1447 return Fragment(store); 1337 return Fragment(store);
1448 } 1338 }
1449 1339
1450
1451 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position, 1340 Fragment FlowGraphBuilder::StoreLocal(TokenPosition position,
1452 LocalVariable* variable) { 1341 LocalVariable* variable) {
1453 Fragment instructions; 1342 Fragment instructions;
1454 if (variable->is_captured()) { 1343 if (variable->is_captured()) {
1455 LocalVariable* value = MakeTemporary(); 1344 LocalVariable* value = MakeTemporary();
1456 instructions += LoadContextAt(variable->owner()->context_level()); 1345 instructions += LoadContextAt(variable->owner()->context_level());
1457 instructions += LoadLocal(value); 1346 instructions += LoadLocal(value);
1458 instructions += StoreInstanceField( 1347 instructions += StoreInstanceField(
1459 position, Context::variable_offset(variable->index())); 1348 position, Context::variable_offset(variable->index()));
1460 } else { 1349 } else {
1461 Value* value = Pop(); 1350 Value* value = Pop();
1462 StoreLocalInstr* store = 1351 StoreLocalInstr* store =
1463 new (Z) StoreLocalInstr(*variable, value, position); 1352 new (Z) StoreLocalInstr(*variable, value, position);
1464 instructions <<= store; 1353 instructions <<= store;
1465 Push(store); 1354 Push(store);
1466 } 1355 }
1467 return instructions; 1356 return instructions;
1468 } 1357 }
1469 1358
1470
1471 Fragment FlowGraphBuilder::StoreStaticField(TokenPosition position, 1359 Fragment FlowGraphBuilder::StoreStaticField(TokenPosition position,
1472 const dart::Field& field) { 1360 const dart::Field& field) {
1473 return Fragment( 1361 return Fragment(
1474 new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), position)); 1362 new (Z) StoreStaticFieldInstr(MayCloneField(Z, field), Pop(), position));
1475 } 1363 }
1476 1364
1477
1478 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) { 1365 Fragment FlowGraphBuilder::StringInterpolate(TokenPosition position) {
1479 Value* array = Pop(); 1366 Value* array = Pop();
1480 StringInterpolateInstr* interpolate = 1367 StringInterpolateInstr* interpolate =
1481 new (Z) StringInterpolateInstr(array, position, GetNextDeoptId()); 1368 new (Z) StringInterpolateInstr(array, position, GetNextDeoptId());
1482 Push(interpolate); 1369 Push(interpolate);
1483 return Fragment(interpolate); 1370 return Fragment(interpolate);
1484 } 1371 }
1485 1372
1486
1487 Fragment FlowGraphBuilder::StringInterpolateSingle(TokenPosition position) { 1373 Fragment FlowGraphBuilder::StringInterpolateSingle(TokenPosition position) {
1488 const int kTypeArgsLen = 0; 1374 const int kTypeArgsLen = 0;
1489 const int kNumberOfArguments = 1; 1375 const int kNumberOfArguments = 1;
1490 const Array& kNoArgumentNames = Object::null_array(); 1376 const Array& kNoArgumentNames = Object::null_array();
1491 const dart::Class& cls = dart::Class::Handle( 1377 const dart::Class& cls = dart::Class::Handle(
1492 dart::Library::LookupCoreClass(Symbols::StringBase())); 1378 dart::Library::LookupCoreClass(Symbols::StringBase()));
1493 ASSERT(!cls.IsNull()); 1379 ASSERT(!cls.IsNull());
1494 const Function& function = Function::ZoneHandle( 1380 const Function& function = Function::ZoneHandle(
1495 Z, 1381 Z,
1496 Resolver::ResolveStatic( 1382 Resolver::ResolveStatic(
1497 cls, dart::Library::PrivateCoreLibName(Symbols::InterpolateSingle()), 1383 cls, dart::Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
1498 kTypeArgsLen, kNumberOfArguments, kNoArgumentNames)); 1384 kTypeArgsLen, kNumberOfArguments, kNoArgumentNames));
1499 Fragment instructions; 1385 Fragment instructions;
1500 instructions += PushArgument(); 1386 instructions += PushArgument();
1501 instructions += StaticCall(position, function, 1); 1387 instructions += StaticCall(position, function, 1);
1502 return instructions; 1388 return instructions;
1503 } 1389 }
1504 1390
1505
1506 Fragment FlowGraphBuilder::ThrowTypeError() { 1391 Fragment FlowGraphBuilder::ThrowTypeError() {
1507 const dart::Class& klass = dart::Class::ZoneHandle( 1392 const dart::Class& klass = dart::Class::ZoneHandle(
1508 Z, dart::Library::LookupCoreClass(Symbols::TypeError())); 1393 Z, dart::Library::LookupCoreClass(Symbols::TypeError()));
1509 ASSERT(!klass.IsNull()); 1394 ASSERT(!klass.IsNull());
1510 const Function& constructor = Function::ZoneHandle( 1395 const Function& constructor = Function::ZoneHandle(
1511 Z, 1396 Z,
1512 klass.LookupConstructorAllowPrivate(H.DartSymbol("_TypeError._create"))); 1397 klass.LookupConstructorAllowPrivate(H.DartSymbol("_TypeError._create")));
1513 ASSERT(!constructor.IsNull()); 1398 ASSERT(!constructor.IsNull());
1514 1399
1515 const dart::String& url = H.DartString( 1400 const dart::String& url = H.DartString(
(...skipping 25 matching lines...) Expand all
1541 instructions += StaticCall(TokenPosition::kNoSource, constructor, 5); 1426 instructions += StaticCall(TokenPosition::kNoSource, constructor, 5);
1542 instructions += Drop(); 1427 instructions += Drop();
1543 1428
1544 // Throw the exception 1429 // Throw the exception
1545 instructions += PushArgument(); 1430 instructions += PushArgument();
1546 instructions += ThrowException(TokenPosition::kNoSource); 1431 instructions += ThrowException(TokenPosition::kNoSource);
1547 1432
1548 return instructions; 1433 return instructions;
1549 } 1434 }
1550 1435
1551
1552 Fragment FlowGraphBuilder::ThrowNoSuchMethodError() { 1436 Fragment FlowGraphBuilder::ThrowNoSuchMethodError() {
1553 const dart::Class& klass = dart::Class::ZoneHandle( 1437 const dart::Class& klass = dart::Class::ZoneHandle(
1554 Z, dart::Library::LookupCoreClass(Symbols::NoSuchMethodError())); 1438 Z, dart::Library::LookupCoreClass(Symbols::NoSuchMethodError()));
1555 ASSERT(!klass.IsNull()); 1439 ASSERT(!klass.IsNull());
1556 const Function& throw_function = Function::ZoneHandle( 1440 const Function& throw_function = Function::ZoneHandle(
1557 Z, klass.LookupStaticFunctionAllowPrivate(Symbols::ThrowNew())); 1441 Z, klass.LookupStaticFunctionAllowPrivate(Symbols::ThrowNew()));
1558 ASSERT(!throw_function.IsNull()); 1442 ASSERT(!throw_function.IsNull());
1559 1443
1560 Fragment instructions; 1444 Fragment instructions;
1561 1445
(...skipping 16 matching lines...) Expand all
1578 instructions += NullConstant(); 1462 instructions += NullConstant();
1579 instructions += PushArgument(); // existingArgumentNames 1463 instructions += PushArgument(); // existingArgumentNames
1580 1464
1581 instructions += StaticCall(TokenPosition::kNoSource, throw_function, 6); 1465 instructions += StaticCall(TokenPosition::kNoSource, throw_function, 6);
1582 // Leave "result" on the stack since callers expect it to be there (even 1466 // Leave "result" on the stack since callers expect it to be there (even
1583 // though the function will result in an exception). 1467 // though the function will result in an exception).
1584 1468
1585 return instructions; 1469 return instructions;
1586 } 1470 }
1587 1471
1588
1589 RawFunction* FlowGraphBuilder::LookupMethodByMember( 1472 RawFunction* FlowGraphBuilder::LookupMethodByMember(
1590 NameIndex target, 1473 NameIndex target,
1591 const dart::String& method_name) { 1474 const dart::String& method_name) {
1592 NameIndex kernel_class = H.EnclosingName(target); 1475 NameIndex kernel_class = H.EnclosingName(target);
1593 dart::Class& klass = 1476 dart::Class& klass =
1594 dart::Class::Handle(Z, H.LookupClassByKernelClass(kernel_class)); 1477 dart::Class::Handle(Z, H.LookupClassByKernelClass(kernel_class));
1595 1478
1596 RawFunction* function = klass.LookupFunctionAllowPrivate(method_name); 1479 RawFunction* function = klass.LookupFunctionAllowPrivate(method_name);
1597 ASSERT(function != Object::null()); 1480 ASSERT(function != Object::null());
1598 return function; 1481 return function;
1599 } 1482 }
1600 1483
1601
1602 LocalVariable* FlowGraphBuilder::MakeTemporary() { 1484 LocalVariable* FlowGraphBuilder::MakeTemporary() {
1603 char name[64]; 1485 char name[64];
1604 intptr_t index = stack_->definition()->temp_index(); 1486 intptr_t index = stack_->definition()->temp_index();
1605 OS::SNPrint(name, 64, ":temp%" Pd, index); 1487 OS::SNPrint(name, 64, ":temp%" Pd, index);
1606 LocalVariable* variable = 1488 LocalVariable* variable =
1607 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 1489 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
1608 H.DartSymbol(name), Object::dynamic_type()); 1490 H.DartSymbol(name), Object::dynamic_type());
1609 // Set the index relative to the base of the expression stack including 1491 // Set the index relative to the base of the expression stack including
1610 // outgoing arguments. 1492 // outgoing arguments.
1611 variable->set_index(parsed_function_->first_stack_local_index() - 1493 variable->set_index(parsed_function_->first_stack_local_index() -
1612 parsed_function_->num_stack_locals() - 1494 parsed_function_->num_stack_locals() -
1613 pending_argument_count_ - index); 1495 pending_argument_count_ - index);
1614 1496
1615 // The value has uses as if it were a local variable. Mark the definition 1497 // The value has uses as if it were a local variable. Mark the definition
1616 // as used so that its temp index will not be cleared (causing it to never 1498 // as used so that its temp index will not be cleared (causing it to never
1617 // be materialized in the expression stack). 1499 // be materialized in the expression stack).
1618 stack_->definition()->set_ssa_temp_index(0); 1500 stack_->definition()->set_ssa_temp_index(0);
1619 1501
1620 return variable; 1502 return variable;
1621 } 1503 }
1622 1504
1623
1624 intptr_t FlowGraphBuilder::CurrentTryIndex() { 1505 intptr_t FlowGraphBuilder::CurrentTryIndex() {
1625 if (try_catch_block_ == NULL) { 1506 if (try_catch_block_ == NULL) {
1626 return CatchClauseNode::kInvalidTryIndex; 1507 return CatchClauseNode::kInvalidTryIndex;
1627 } else { 1508 } else {
1628 return try_catch_block_->try_index(); 1509 return try_catch_block_->try_index();
1629 } 1510 }
1630 } 1511 }
1631 1512
1632
1633 dart::LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) { 1513 dart::LocalVariable* FlowGraphBuilder::LookupVariable(intptr_t kernel_offset) {
1634 LocalVariable* local = scopes_->locals.Lookup(kernel_offset); 1514 LocalVariable* local = scopes_->locals.Lookup(kernel_offset);
1635 ASSERT(local != NULL); 1515 ASSERT(local != NULL);
1636 return local; 1516 return local;
1637 } 1517 }
1638 1518
1639
1640 void FlowGraphBuilder::SetTempIndex(Definition* definition) { 1519 void FlowGraphBuilder::SetTempIndex(Definition* definition) {
1641 definition->set_temp_index( 1520 definition->set_temp_index(
1642 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1); 1521 stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1);
1643 } 1522 }
1644 1523
1645
1646 void FlowGraphBuilder::Push(Definition* definition) { 1524 void FlowGraphBuilder::Push(Definition* definition) {
1647 SetTempIndex(definition); 1525 SetTempIndex(definition);
1648 Value::AddToList(new (Z) Value(definition), &stack_); 1526 Value::AddToList(new (Z) Value(definition), &stack_);
1649 } 1527 }
1650 1528
1651
1652 Value* FlowGraphBuilder::Pop() { 1529 Value* FlowGraphBuilder::Pop() {
1653 ASSERT(stack_ != NULL); 1530 ASSERT(stack_ != NULL);
1654 Value* value = stack_; 1531 Value* value = stack_;
1655 stack_ = value->next_use(); 1532 stack_ = value->next_use();
1656 if (stack_ != NULL) stack_->set_previous_use(NULL); 1533 if (stack_ != NULL) stack_->set_previous_use(NULL);
1657 1534
1658 value->set_next_use(NULL); 1535 value->set_next_use(NULL);
1659 value->set_previous_use(NULL); 1536 value->set_previous_use(NULL);
1660 value->definition()->ClearSSATempIndex(); 1537 value->definition()->ClearSSATempIndex();
1661 return value; 1538 return value;
1662 } 1539 }
1663 1540
1664
1665 Fragment FlowGraphBuilder::Drop() { 1541 Fragment FlowGraphBuilder::Drop() {
1666 ASSERT(stack_ != NULL); 1542 ASSERT(stack_ != NULL);
1667 Fragment instructions; 1543 Fragment instructions;
1668 Definition* definition = stack_->definition(); 1544 Definition* definition = stack_->definition();
1669 // The SSA renaming implementation doesn't like [LoadLocal]s without a 1545 // The SSA renaming implementation doesn't like [LoadLocal]s without a
1670 // tempindex. 1546 // tempindex.
1671 if (definition->HasSSATemp() || definition->IsLoadLocal()) { 1547 if (definition->HasSSATemp() || definition->IsLoadLocal()) {
1672 instructions <<= new (Z) DropTempsInstr(1, NULL); 1548 instructions <<= new (Z) DropTempsInstr(1, NULL);
1673 } else { 1549 } else {
1674 definition->ClearTempIndex(); 1550 definition->ClearTempIndex();
1675 } 1551 }
1676 1552
1677 Pop(); 1553 Pop();
1678 return instructions; 1554 return instructions;
1679 } 1555 }
1680 1556
1681
1682 // TODO(27590): This method should be shared with 1557 // TODO(27590): This method should be shared with
1683 // runtime/vm/object.cc:RecognizeArithmeticOp. 1558 // runtime/vm/object.cc:RecognizeArithmeticOp.
1684 Token::Kind FlowGraphBuilder::MethodKind(const dart::String& name) { 1559 Token::Kind FlowGraphBuilder::MethodKind(const dart::String& name) {
1685 ASSERT(name.IsSymbol()); 1560 ASSERT(name.IsSymbol());
1686 if (name.raw() == Symbols::Plus().raw()) { 1561 if (name.raw() == Symbols::Plus().raw()) {
1687 return Token::kADD; 1562 return Token::kADD;
1688 } else if (name.raw() == Symbols::Minus().raw()) { 1563 } else if (name.raw() == Symbols::Minus().raw()) {
1689 return Token::kSUB; 1564 return Token::kSUB;
1690 } else if (name.raw() == Symbols::Star().raw()) { 1565 } else if (name.raw() == Symbols::Star().raw()) {
1691 return Token::kMUL; 1566 return Token::kMUL;
(...skipping 30 matching lines...) Expand all
1722 } else if (name.raw() == Symbols::GreaterEqualOperator().raw()) { 1597 } else if (name.raw() == Symbols::GreaterEqualOperator().raw()) {
1723 return Token::kGTE; 1598 return Token::kGTE;
1724 } else if (dart::Field::IsGetterName(name)) { 1599 } else if (dart::Field::IsGetterName(name)) {
1725 return Token::kGET; 1600 return Token::kGET;
1726 } else if (dart::Field::IsSetterName(name)) { 1601 } else if (dart::Field::IsSetterName(name)) {
1727 return Token::kSET; 1602 return Token::kSET;
1728 } 1603 }
1729 return Token::kILLEGAL; 1604 return Token::kILLEGAL;
1730 } 1605 }
1731 1606
1732
1733 void FlowGraphBuilder::InlineBailout(const char* reason) { 1607 void FlowGraphBuilder::InlineBailout(const char* reason) {
1734 bool is_inlining = exit_collector_ != NULL; 1608 bool is_inlining = exit_collector_ != NULL;
1735 if (is_inlining) { 1609 if (is_inlining) {
1736 parsed_function_->function().set_is_inlinable(false); 1610 parsed_function_->function().set_is_inlinable(false);
1737 parsed_function_->Bailout("kernel::FlowGraphBuilder", reason); 1611 parsed_function_->Bailout("kernel::FlowGraphBuilder", reason);
1738 } 1612 }
1739 } 1613 }
1740 1614
1741
1742 FlowGraph* FlowGraphBuilder::BuildGraph() { 1615 FlowGraph* FlowGraphBuilder::BuildGraph() {
1743 const Function& function = parsed_function_->function(); 1616 const Function& function = parsed_function_->function();
1744 1617
1745 if (function.IsConstructorClosureFunction()) return NULL; 1618 if (function.IsConstructorClosureFunction()) return NULL;
1746 1619
1747 if (streaming_flow_graph_builder_ != NULL) { 1620 if (streaming_flow_graph_builder_ != NULL) {
1748 delete streaming_flow_graph_builder_; 1621 delete streaming_flow_graph_builder_;
1749 streaming_flow_graph_builder_ = NULL; 1622 streaming_flow_graph_builder_ = NULL;
1750 } 1623 }
1751 1624
1752 Script& script = Script::Handle(Z, function.script()); 1625 Script& script = Script::Handle(Z, function.script());
1753 streaming_flow_graph_builder_ = new StreamingFlowGraphBuilder( 1626 streaming_flow_graph_builder_ = new StreamingFlowGraphBuilder(
1754 this, script.kernel_data(), script.kernel_data_size()); 1627 this, script.kernel_data(), script.kernel_data_size());
1755 1628
1756 return streaming_flow_graph_builder_->BuildGraph(kernel_offset_); 1629 return streaming_flow_graph_builder_->BuildGraph(kernel_offset_);
1757 } 1630 }
1758 1631
1759
1760 Fragment FlowGraphBuilder::NativeFunctionBody(intptr_t first_positional_offset, 1632 Fragment FlowGraphBuilder::NativeFunctionBody(intptr_t first_positional_offset,
1761 const Function& function) { 1633 const Function& function) {
1762 ASSERT(function.is_native()); 1634 ASSERT(function.is_native());
1763 // We explicitly build the graph for native functions in the same way that the 1635 // We explicitly build the graph for native functions in the same way that the
1764 // from-source backend does. We should find a way to have a single component 1636 // from-source backend does. We should find a way to have a single component
1765 // to build these graphs so that this code is not duplicated. 1637 // to build these graphs so that this code is not duplicated.
1766 1638
1767 Fragment body; 1639 Fragment body;
1768 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 1640 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
1769 switch (kind) { 1641 switch (kind) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 break; 1774 break;
1903 default: { 1775 default: {
1904 dart::String& name = dart::String::ZoneHandle(Z, function.native_name()); 1776 dart::String& name = dart::String::ZoneHandle(Z, function.native_name());
1905 body += NativeCall(&name, &function); 1777 body += NativeCall(&name, &function);
1906 break; 1778 break;
1907 } 1779 }
1908 } 1780 }
1909 return body + Return(TokenPosition::kNoSource); 1781 return body + Return(TokenPosition::kNoSource);
1910 } 1782 }
1911 1783
1912
1913 Fragment FlowGraphBuilder::BuildImplicitClosureCreation( 1784 Fragment FlowGraphBuilder::BuildImplicitClosureCreation(
1914 const Function& target) { 1785 const Function& target) {
1915 Fragment fragment; 1786 Fragment fragment;
1916 const dart::Class& closure_class = 1787 const dart::Class& closure_class =
1917 dart::Class::ZoneHandle(Z, I->object_store()->closure_class()); 1788 dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
1918 fragment += AllocateObject(closure_class, target); 1789 fragment += AllocateObject(closure_class, target);
1919 LocalVariable* closure = MakeTemporary(); 1790 LocalVariable* closure = MakeTemporary();
1920 1791
1921 // The function signature can have uninstantiated class type parameters. 1792 // The function signature can have uninstantiated class type parameters.
1922 // 1793 //
(...skipping 25 matching lines...) Expand all
1948 // The context is on top of the operand stack. Store `this`. The context 1819 // The context is on top of the operand stack. Store `this`. The context
1949 // doesn't need a parent pointer because it doesn't close over anything 1820 // doesn't need a parent pointer because it doesn't close over anything
1950 // else. 1821 // else.
1951 fragment += LoadLocal(scopes_->this_variable); 1822 fragment += LoadLocal(scopes_->this_variable);
1952 fragment += 1823 fragment +=
1953 StoreInstanceField(TokenPosition::kNoSource, Context::variable_offset(0)); 1824 StoreInstanceField(TokenPosition::kNoSource, Context::variable_offset(0));
1954 1825
1955 return fragment; 1826 return fragment;
1956 } 1827 }
1957 1828
1958
1959 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field, 1829 Fragment FlowGraphBuilder::GuardFieldLength(const dart::Field& field,
1960 intptr_t deopt_id) { 1830 intptr_t deopt_id) {
1961 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id)); 1831 return Fragment(new (Z) GuardFieldLengthInstr(Pop(), field, deopt_id));
1962 } 1832 }
1963 1833
1964
1965 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field, 1834 Fragment FlowGraphBuilder::GuardFieldClass(const dart::Field& field,
1966 intptr_t deopt_id) { 1835 intptr_t deopt_id) {
1967 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id)); 1836 return Fragment(new (Z) GuardFieldClassInstr(Pop(), field, deopt_id));
1968 } 1837 }
1969 1838
1970
1971 Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode( 1839 Fragment FlowGraphBuilder::CheckVariableTypeInCheckedMode(
1972 const AbstractType& dst_type, 1840 const AbstractType& dst_type,
1973 const dart::String& name_symbol) { 1841 const dart::String& name_symbol) {
1974 if (I->type_checks()) { 1842 if (I->type_checks()) {
1975 if (dst_type.IsMalformed()) { 1843 if (dst_type.IsMalformed()) {
1976 return ThrowTypeError(); 1844 return ThrowTypeError();
1977 } 1845 }
1978 return CheckAssignableInCheckedMode(dst_type, name_symbol); 1846 return CheckAssignableInCheckedMode(dst_type, name_symbol);
1979 } 1847 }
1980 return Fragment(); 1848 return Fragment();
1981 } 1849 }
1982 1850
1983
1984 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function, 1851 bool FlowGraphBuilder::NeedsDebugStepCheck(const Function& function,
1985 TokenPosition position) { 1852 TokenPosition position) {
1986 return FLAG_support_debugger && position.IsDebugPause() && 1853 return FLAG_support_debugger && position.IsDebugPause() &&
1987 !function.is_native() && function.is_debuggable(); 1854 !function.is_native() && function.is_debuggable();
1988 } 1855 }
1989 1856
1990
1991 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value, 1857 bool FlowGraphBuilder::NeedsDebugStepCheck(Value* value,
1992 TokenPosition position) { 1858 TokenPosition position) {
1993 if (!FLAG_support_debugger || !position.IsDebugPause()) return false; 1859 if (!FLAG_support_debugger || !position.IsDebugPause()) return false;
1994 Definition* definition = value->definition(); 1860 Definition* definition = value->definition();
1995 if (definition->IsConstant() || definition->IsLoadStaticField()) return true; 1861 if (definition->IsConstant() || definition->IsLoadStaticField()) return true;
1996 if (definition->IsAllocateObject()) { 1862 if (definition->IsAllocateObject()) {
1997 return !definition->AsAllocateObject()->closure_function().IsNull(); 1863 return !definition->AsAllocateObject()->closure_function().IsNull();
1998 } 1864 }
1999 return definition->IsLoadLocal() && 1865 return definition->IsLoadLocal() &&
2000 !definition->AsLoadLocal()->local().IsInternal(); 1866 !definition->AsLoadLocal()->local().IsInternal();
2001 } 1867 }
2002 1868
2003 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) { 1869 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) {
2004 return Fragment(new (Z) DebugStepCheckInstr( 1870 return Fragment(new (Z) DebugStepCheckInstr(
2005 position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId())); 1871 position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId()));
2006 } 1872 }
2007 1873
2008
2009 Fragment FlowGraphBuilder::EvaluateAssertion() { 1874 Fragment FlowGraphBuilder::EvaluateAssertion() {
2010 const dart::Class& klass = dart::Class::ZoneHandle( 1875 const dart::Class& klass = dart::Class::ZoneHandle(
2011 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); 1876 Z, dart::Library::LookupCoreClass(Symbols::AssertionError()));
2012 ASSERT(!klass.IsNull()); 1877 ASSERT(!klass.IsNull());
2013 const Function& target = 1878 const Function& target =
2014 Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( 1879 Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate(
2015 H.DartSymbol("_evaluateAssertion"))); 1880 H.DartSymbol("_evaluateAssertion")));
2016 ASSERT(!target.IsNull()); 1881 ASSERT(!target.IsNull());
2017 return StaticCall(TokenPosition::kNoSource, target, 1); 1882 return StaticCall(TokenPosition::kNoSource, target, 1);
2018 } 1883 }
2019 1884
2020
2021 Fragment FlowGraphBuilder::CheckReturnTypeInCheckedMode() { 1885 Fragment FlowGraphBuilder::CheckReturnTypeInCheckedMode() {
2022 if (I->type_checks()) { 1886 if (I->type_checks()) {
2023 const AbstractType& return_type = 1887 const AbstractType& return_type =
2024 AbstractType::Handle(Z, parsed_function_->function().result_type()); 1888 AbstractType::Handle(Z, parsed_function_->function().result_type());
2025 return CheckAssignableInCheckedMode(return_type, Symbols::FunctionResult()); 1889 return CheckAssignableInCheckedMode(return_type, Symbols::FunctionResult());
2026 } 1890 }
2027 return Fragment(); 1891 return Fragment();
2028 } 1892 }
2029 1893
2030
2031 Fragment FlowGraphBuilder::CheckBooleanInCheckedMode() { 1894 Fragment FlowGraphBuilder::CheckBooleanInCheckedMode() {
2032 Fragment instructions; 1895 Fragment instructions;
2033 if (I->type_checks()) { 1896 if (I->type_checks()) {
2034 LocalVariable* top_of_stack = MakeTemporary(); 1897 LocalVariable* top_of_stack = MakeTemporary();
2035 instructions += LoadLocal(top_of_stack); 1898 instructions += LoadLocal(top_of_stack);
2036 instructions += AssertBool(); 1899 instructions += AssertBool();
2037 instructions += Drop(); 1900 instructions += Drop();
2038 } 1901 }
2039 return instructions; 1902 return instructions;
2040 } 1903 }
2041 1904
2042
2043 Fragment FlowGraphBuilder::CheckAssignableInCheckedMode( 1905 Fragment FlowGraphBuilder::CheckAssignableInCheckedMode(
2044 const AbstractType& dst_type, 1906 const AbstractType& dst_type,
2045 const dart::String& dst_name) { 1907 const dart::String& dst_name) {
2046 Fragment instructions; 1908 Fragment instructions;
2047 if (I->type_checks() && !dst_type.IsDynamicType() && 1909 if (I->type_checks() && !dst_type.IsDynamicType() &&
2048 !dst_type.IsObjectType() && !dst_type.IsVoidType()) { 1910 !dst_type.IsObjectType() && !dst_type.IsVoidType()) {
2049 LocalVariable* top_of_stack = MakeTemporary(); 1911 LocalVariable* top_of_stack = MakeTemporary();
2050 instructions += LoadLocal(top_of_stack); 1912 instructions += LoadLocal(top_of_stack);
2051 instructions += AssertAssignable(dst_type, dst_name); 1913 instructions += AssertAssignable(dst_type, dst_name);
2052 instructions += Drop(); 1914 instructions += Drop();
2053 } 1915 }
2054 return instructions; 1916 return instructions;
2055 } 1917 }
2056 1918
2057
2058 Fragment FlowGraphBuilder::AssertBool() { 1919 Fragment FlowGraphBuilder::AssertBool() {
2059 Value* value = Pop(); 1920 Value* value = Pop();
2060 AssertBooleanInstr* instr = new (Z) 1921 AssertBooleanInstr* instr = new (Z)
2061 AssertBooleanInstr(TokenPosition::kNoSource, value, GetNextDeoptId()); 1922 AssertBooleanInstr(TokenPosition::kNoSource, value, GetNextDeoptId());
2062 Push(instr); 1923 Push(instr);
2063 return Fragment(instr); 1924 return Fragment(instr);
2064 } 1925 }
2065 1926
2066
2067 Fragment FlowGraphBuilder::AssertAssignable(const AbstractType& dst_type, 1927 Fragment FlowGraphBuilder::AssertAssignable(const AbstractType& dst_type,
2068 const dart::String& dst_name) { 1928 const dart::String& dst_name) {
2069 Fragment instructions; 1929 Fragment instructions;
2070 Value* value = Pop(); 1930 Value* value = Pop();
2071 1931
2072 if (!dst_type.IsInstantiated(kCurrentClass)) { 1932 if (!dst_type.IsInstantiated(kCurrentClass)) {
2073 instructions += LoadInstantiatorTypeArguments(); 1933 instructions += LoadInstantiatorTypeArguments();
2074 } else { 1934 } else {
2075 instructions += NullConstant(); 1935 instructions += NullConstant();
2076 } 1936 }
2077 Value* instantiator_type_args = Pop(); 1937 Value* instantiator_type_args = Pop();
2078 1938
2079 if (!dst_type.IsInstantiated(kFunctions)) { 1939 if (!dst_type.IsInstantiated(kFunctions)) {
2080 instructions += LoadFunctionTypeArguments(); 1940 instructions += LoadFunctionTypeArguments();
2081 } else { 1941 } else {
2082 instructions += NullConstant(); 1942 instructions += NullConstant();
2083 } 1943 }
2084 Value* function_type_args = Pop(); 1944 Value* function_type_args = Pop();
2085 1945
2086 AssertAssignableInstr* instr = new (Z) AssertAssignableInstr( 1946 AssertAssignableInstr* instr = new (Z) AssertAssignableInstr(
2087 TokenPosition::kNoSource, value, instantiator_type_args, 1947 TokenPosition::kNoSource, value, instantiator_type_args,
2088 function_type_args, dst_type, dst_name, GetNextDeoptId()); 1948 function_type_args, dst_type, dst_name, GetNextDeoptId());
2089 Push(instr); 1949 Push(instr);
2090 1950
2091 instructions += Fragment(instr); 1951 instructions += Fragment(instr);
2092 1952
2093 return instructions; 1953 return instructions;
2094 } 1954 }
2095 1955
2096
2097 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( 1956 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor(
2098 const Function& method) { 1957 const Function& method) {
2099 // A method extractor is the implicit getter for a method. 1958 // A method extractor is the implicit getter for a method.
2100 const Function& function = 1959 const Function& function =
2101 Function::ZoneHandle(Z, method.extracted_method_closure()); 1960 Function::ZoneHandle(Z, method.extracted_method_closure());
2102 1961
2103 TargetEntryInstr* normal_entry = BuildTargetEntry(); 1962 TargetEntryInstr* normal_entry = BuildTargetEntry();
2104 graph_entry_ = new (Z) 1963 graph_entry_ = new (Z)
2105 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); 1964 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
2106 Fragment body(normal_entry); 1965 Fragment body(normal_entry);
2107 body += CheckStackOverflowInPrologue(); 1966 body += CheckStackOverflowInPrologue();
2108 body += BuildImplicitClosureCreation(function); 1967 body += BuildImplicitClosureCreation(function);
2109 body += Return(TokenPosition::kNoSource); 1968 body += Return(TokenPosition::kNoSource);
2110 1969
2111 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); 1970 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
2112 } 1971 }
2113 1972
2114
2115 FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher( 1973 FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher(
2116 const Function& function) { 1974 const Function& function) {
2117 // This function is specialized for a receiver class, a method name, and 1975 // This function is specialized for a receiver class, a method name, and
2118 // the arguments descriptor at a call site. 1976 // the arguments descriptor at a call site.
2119 1977
2120 TargetEntryInstr* normal_entry = BuildTargetEntry(); 1978 TargetEntryInstr* normal_entry = BuildTargetEntry();
2121 graph_entry_ = new (Z) 1979 graph_entry_ = new (Z)
2122 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId); 1980 GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
2123 1981
2124 // The backend will expect an array of default values for all the named 1982 // The backend will expect an array of default values for all the named
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2208 no_such_method = Resolver::ResolveDynamicForReceiverClass( 2066 no_such_method = Resolver::ResolveDynamicForReceiverClass(
2209 dart::Class::Handle(Z, I->object_store()->object_class()), 2067 dart::Class::Handle(Z, I->object_store()->object_class()),
2210 Symbols::NoSuchMethod(), two_arguments); 2068 Symbols::NoSuchMethod(), two_arguments);
2211 } 2069 }
2212 body += StaticCall(TokenPosition::kMinSource, no_such_method, 2); 2070 body += StaticCall(TokenPosition::kMinSource, no_such_method, 2);
2213 body += Return(TokenPosition::kNoSource); 2071 body += Return(TokenPosition::kNoSource);
2214 2072
2215 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); 2073 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
2216 } 2074 }
2217 2075
2218
2219 FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher( 2076 FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher(
2220 const Function& function) { 2077 const Function& function) {
2221 // Find the name of the field we should dispatch to. 2078 // Find the name of the field we should dispatch to.
2222 const dart::Class& owner = dart::Class::Handle(Z, function.Owner()); 2079 const dart::Class& owner = dart::Class::Handle(Z, function.Owner());
2223 ASSERT(!owner.IsNull()); 2080 ASSERT(!owner.IsNull());
2224 const dart::String& field_name = dart::String::Handle(Z, function.name()); 2081 const dart::String& field_name = dart::String::Handle(Z, function.name());
2225 const dart::String& getter_name = dart::String::ZoneHandle( 2082 const dart::String& getter_name = dart::String::ZoneHandle(
2226 Z, 2083 Z,
2227 Symbols::New(H.thread(), dart::String::Handle( 2084 Symbols::New(H.thread(), dart::String::Handle(
2228 Z, dart::Field::GetterSymbol(field_name)))); 2085 Z, dart::Field::GetterSymbol(field_name))));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(), 2161 body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(),
2305 Token::kILLEGAL, descriptor.TypeArgsLen(), 2162 Token::kILLEGAL, descriptor.TypeArgsLen(),
2306 descriptor.Count(), argument_names); 2163 descriptor.Count(), argument_names);
2307 } 2164 }
2308 2165
2309 body += Return(TokenPosition::kNoSource); 2166 body += Return(TokenPosition::kNoSource);
2310 2167
2311 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1); 2168 return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
2312 } 2169 }
2313 2170
2314
2315 TargetEntryInstr* FlowGraphBuilder::BuildTargetEntry() { 2171 TargetEntryInstr* FlowGraphBuilder::BuildTargetEntry() {
2316 return new (Z) 2172 return new (Z)
2317 TargetEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId()); 2173 TargetEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
2318 } 2174 }
2319 2175
2320
2321 JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry(intptr_t try_index) { 2176 JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry(intptr_t try_index) {
2322 return new (Z) JoinEntryInstr(AllocateBlockId(), try_index, GetNextDeoptId()); 2177 return new (Z) JoinEntryInstr(AllocateBlockId(), try_index, GetNextDeoptId());
2323 } 2178 }
2324 2179
2325
2326 JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry() { 2180 JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry() {
2327 return new (Z) 2181 return new (Z)
2328 JoinEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId()); 2182 JoinEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
2329 } 2183 }
2330 2184
2331 ArgumentArray FlowGraphBuilder::GetArguments(int count) { 2185 ArgumentArray FlowGraphBuilder::GetArguments(int count) {
2332 ArgumentArray arguments = 2186 ArgumentArray arguments =
2333 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count); 2187 new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count);
2334 arguments->SetLength(count); 2188 arguments->SetLength(count);
2335 for (intptr_t i = count - 1; i >= 0; --i) { 2189 for (intptr_t i = count - 1; i >= 0; --i) {
2336 ASSERT(stack_->definition()->IsPushArgument()); 2190 ASSERT(stack_->definition()->IsPushArgument());
2337 ASSERT(!stack_->definition()->HasSSATemp()); 2191 ASSERT(!stack_->definition()->HasSSATemp());
2338 arguments->data()[i] = stack_->definition()->AsPushArgument(); 2192 arguments->data()[i] = stack_->definition()->AsPushArgument();
2339 Drop(); 2193 Drop();
2340 } 2194 }
2341 pending_argument_count_ -= count; 2195 pending_argument_count_ -= count;
2342 ASSERT(pending_argument_count_ >= 0); 2196 ASSERT(pending_argument_count_ >= 0);
2343 return arguments; 2197 return arguments;
2344 } 2198 }
2345 2199
2346
2347 RawObject* EvaluateMetadata(const dart::Field& metadata_field) { 2200 RawObject* EvaluateMetadata(const dart::Field& metadata_field) {
2348 LongJumpScope jump; 2201 LongJumpScope jump;
2349 if (setjmp(*jump.Set()) == 0) { 2202 if (setjmp(*jump.Set()) == 0) {
2350 Thread* thread = Thread::Current(); 2203 Thread* thread = Thread::Current();
2351 Zone* zone_ = thread->zone(); 2204 Zone* zone_ = thread->zone();
2352 TranslationHelper helper(thread); 2205 TranslationHelper helper(thread);
2353 Script& script = Script::Handle(Z, metadata_field.Script()); 2206 Script& script = Script::Handle(Z, metadata_field.Script());
2354 helper.SetStringOffsets( 2207 helper.SetStringOffsets(
2355 TypedData::Handle(Z, script.kernel_string_offsets())); 2208 TypedData::Handle(Z, script.kernel_string_offsets()));
2356 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); 2209 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data()));
2357 helper.SetCanonicalNames( 2210 helper.SetCanonicalNames(
2358 TypedData::Handle(Z, script.kernel_canonical_names())); 2211 TypedData::Handle(Z, script.kernel_canonical_names()));
2359 2212
2360 StreamingFlowGraphBuilder streaming_flow_graph_builder( 2213 StreamingFlowGraphBuilder streaming_flow_graph_builder(
2361 &helper, zone_, script.kernel_data(), script.kernel_data_size()); 2214 &helper, zone_, script.kernel_data(), script.kernel_data_size());
2362 return streaming_flow_graph_builder.EvaluateMetadata( 2215 return streaming_flow_graph_builder.EvaluateMetadata(
2363 metadata_field.kernel_offset()); 2216 metadata_field.kernel_offset());
2364 } else { 2217 } else {
2365 Thread* thread = Thread::Current(); 2218 Thread* thread = Thread::Current();
2366 Error& error = Error::Handle(); 2219 Error& error = Error::Handle();
2367 error = thread->sticky_error(); 2220 error = thread->sticky_error();
2368 thread->clear_sticky_error(); 2221 thread->clear_sticky_error();
2369 return error.raw(); 2222 return error.raw();
2370 } 2223 }
2371 } 2224 }
2372 2225
2373
2374 RawObject* BuildParameterDescriptor(const Function& function) { 2226 RawObject* BuildParameterDescriptor(const Function& function) {
2375 LongJumpScope jump; 2227 LongJumpScope jump;
2376 if (setjmp(*jump.Set()) == 0) { 2228 if (setjmp(*jump.Set()) == 0) {
2377 Thread* thread = Thread::Current(); 2229 Thread* thread = Thread::Current();
2378 Zone* zone_ = thread->zone(); 2230 Zone* zone_ = thread->zone();
2379 TranslationHelper helper(thread); 2231 TranslationHelper helper(thread);
2380 Script& script = Script::Handle(Z, function.script()); 2232 Script& script = Script::Handle(Z, function.script());
2381 helper.SetStringOffsets( 2233 helper.SetStringOffsets(
2382 TypedData::Handle(Z, script.kernel_string_offsets())); 2234 TypedData::Handle(Z, script.kernel_string_offsets()));
2383 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); 2235 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data()));
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2485 StreamingFlowGraphBuilder streaming_flow_graph_builder( 2337 StreamingFlowGraphBuilder streaming_flow_graph_builder(
2486 &helper, zone_, script.kernel_data(), script.kernel_data_size()); 2338 &helper, zone_, script.kernel_data(), script.kernel_data_size());
2487 return streaming_flow_graph_builder.GetLineStartsFor( 2339 return streaming_flow_graph_builder.GetLineStartsFor(
2488 script.kernel_script_index()); 2340 script.kernel_script_index());
2489 } 2341 }
2490 2342
2491 } // namespace kernel 2343 } // namespace kernel
2492 } // namespace dart 2344 } // namespace dart
2493 2345
2494 #endif // !defined(DART_PRECOMPILED_RUNTIME) 2346 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698