| 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 |