OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |