OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/become.h" | 10 #include "vm/become.h" |
11 #include "vm/cpu.h" | |
12 #include "vm/bit_vector.h" | 11 #include "vm/bit_vector.h" |
13 #include "vm/bootstrap.h" | 12 #include "vm/bootstrap.h" |
14 #include "vm/class_finalizer.h" | 13 #include "vm/class_finalizer.h" |
15 #include "vm/code_observers.h" | 14 #include "vm/code_observers.h" |
16 #include "vm/compiler.h" | 15 #include "vm/compiler.h" |
17 #include "vm/compiler_stats.h" | 16 #include "vm/compiler_stats.h" |
| 17 #include "vm/cpu.h" |
18 #include "vm/dart.h" | 18 #include "vm/dart.h" |
19 #include "vm/dart_api_state.h" | 19 #include "vm/dart_api_state.h" |
20 #include "vm/dart_entry.h" | 20 #include "vm/dart_entry.h" |
21 #include "vm/datastream.h" | 21 #include "vm/datastream.h" |
22 #include "vm/debugger.h" | 22 #include "vm/debugger.h" |
23 #include "vm/deopt_instructions.h" | 23 #include "vm/deopt_instructions.h" |
24 #include "vm/disassembler.h" | 24 #include "vm/disassembler.h" |
25 #include "vm/double_conversion.h" | 25 #include "vm/double_conversion.h" |
26 #include "vm/exceptions.h" | 26 #include "vm/exceptions.h" |
27 #include "vm/growable_array.h" | 27 #include "vm/growable_array.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 85 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
86 DECLARE_FLAG(bool, trace_reload); | 86 DECLARE_FLAG(bool, trace_reload); |
87 DECLARE_FLAG(bool, write_protect_code); | 87 DECLARE_FLAG(bool, write_protect_code); |
88 DECLARE_FLAG(bool, support_externalizable_strings); | 88 DECLARE_FLAG(bool, support_externalizable_strings); |
89 | 89 |
90 static const char* const kGetterPrefix = "get:"; | 90 static const char* const kGetterPrefix = "get:"; |
91 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 91 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
92 static const char* const kSetterPrefix = "set:"; | 92 static const char* const kSetterPrefix = "set:"; |
93 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 93 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
94 | 94 |
95 | |
96 // A cache of VM heap allocated preinitialized empty ic data entry arrays. | 95 // A cache of VM heap allocated preinitialized empty ic data entry arrays. |
97 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; | 96 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; |
98 | 97 |
99 cpp_vtable Object::handle_vtable_ = 0; | 98 cpp_vtable Object::handle_vtable_ = 0; |
100 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {0}; | 99 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {0}; |
101 cpp_vtable Smi::handle_vtable_ = 0; | 100 cpp_vtable Smi::handle_vtable_ = 0; |
102 | 101 |
103 // These are initialized to a value that will force a illegal memory access if | 102 // These are initialized to a value that will force a illegal memory access if |
104 // they are being used. | 103 // they are being used. |
105 #if defined(RAW_NULL) | 104 #if defined(RAW_NULL) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 RawClass* Object::megamorphic_cache_class_ = | 175 RawClass* Object::megamorphic_cache_class_ = |
177 reinterpret_cast<RawClass*>(RAW_NULL); | 176 reinterpret_cast<RawClass*>(RAW_NULL); |
178 RawClass* Object::subtypetestcache_class_ = | 177 RawClass* Object::subtypetestcache_class_ = |
179 reinterpret_cast<RawClass*>(RAW_NULL); | 178 reinterpret_cast<RawClass*>(RAW_NULL); |
180 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 179 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
181 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 180 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
182 RawClass* Object::unhandled_exception_class_ = | 181 RawClass* Object::unhandled_exception_class_ = |
183 reinterpret_cast<RawClass*>(RAW_NULL); | 182 reinterpret_cast<RawClass*>(RAW_NULL); |
184 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 183 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
185 | 184 |
186 | |
187 const double MegamorphicCache::kLoadFactor = 0.50; | 185 const double MegamorphicCache::kLoadFactor = 0.50; |
188 | 186 |
189 | |
190 static void AppendSubString(Zone* zone, | 187 static void AppendSubString(Zone* zone, |
191 GrowableArray<const char*>* segments, | 188 GrowableArray<const char*>* segments, |
192 const char* name, | 189 const char* name, |
193 intptr_t start_pos, | 190 intptr_t start_pos, |
194 intptr_t len) { | 191 intptr_t len) { |
195 char* segment = zone->Alloc<char>(len + 1); // '\0'-terminated. | 192 char* segment = zone->Alloc<char>(len + 1); // '\0'-terminated. |
196 memmove(segment, name + start_pos, len); | 193 memmove(segment, name + start_pos, len); |
197 segment[len] = '\0'; | 194 segment[len] = '\0'; |
198 segments->Add(segment); | 195 segments->Add(segment); |
199 } | 196 } |
200 | 197 |
201 | |
202 static const char* MergeSubStrings(Zone* zone, | 198 static const char* MergeSubStrings(Zone* zone, |
203 const GrowableArray<const char*>& segments, | 199 const GrowableArray<const char*>& segments, |
204 intptr_t alloc_len) { | 200 intptr_t alloc_len) { |
205 char* result = zone->Alloc<char>(alloc_len + 1); // '\0'-terminated | 201 char* result = zone->Alloc<char>(alloc_len + 1); // '\0'-terminated |
206 intptr_t pos = 0; | 202 intptr_t pos = 0; |
207 for (intptr_t k = 0; k < segments.length(); k++) { | 203 for (intptr_t k = 0; k < segments.length(); k++) { |
208 const char* piece = segments[k]; | 204 const char* piece = segments[k]; |
209 const intptr_t piece_len = strlen(segments[k]); | 205 const intptr_t piece_len = strlen(segments[k]); |
210 memmove(result + pos, piece, piece_len); | 206 memmove(result + pos, piece, piece_len); |
211 pos += piece_len; | 207 pos += piece_len; |
212 ASSERT(pos <= alloc_len); | 208 ASSERT(pos <= alloc_len); |
213 } | 209 } |
214 result[pos] = '\0'; | 210 result[pos] = '\0'; |
215 return result; | 211 return result; |
216 } | 212 } |
217 | 213 |
218 | |
219 // Remove private keys, but retain getter/setter/constructor/mixin manglings. | 214 // Remove private keys, but retain getter/setter/constructor/mixin manglings. |
220 RawString* String::RemovePrivateKey(const String& name) { | 215 RawString* String::RemovePrivateKey(const String& name) { |
221 ASSERT(name.IsOneByteString()); | 216 ASSERT(name.IsOneByteString()); |
222 GrowableArray<uint8_t> without_key(name.Length()); | 217 GrowableArray<uint8_t> without_key(name.Length()); |
223 intptr_t i = 0; | 218 intptr_t i = 0; |
224 while (i < name.Length()) { | 219 while (i < name.Length()) { |
225 while (i < name.Length()) { | 220 while (i < name.Length()) { |
226 uint8_t c = name.CharAt(i++); | 221 uint8_t c = name.CharAt(i++); |
227 if (c == '@') break; | 222 if (c == '@') break; |
228 without_key.Add(c); | 223 without_key.Add(c); |
229 } | 224 } |
230 while (i < name.Length()) { | 225 while (i < name.Length()) { |
231 uint8_t c = name.CharAt(i); | 226 uint8_t c = name.CharAt(i); |
232 if ((c < '0') || (c > '9')) break; | 227 if ((c < '0') || (c > '9')) break; |
233 i++; | 228 i++; |
234 } | 229 } |
235 } | 230 } |
236 | 231 |
237 return String::FromLatin1(without_key.data(), without_key.length()); | 232 return String::FromLatin1(without_key.data(), without_key.length()); |
238 } | 233 } |
239 | 234 |
240 | |
241 // Takes a vm internal name and makes it suitable for external user. | 235 // Takes a vm internal name and makes it suitable for external user. |
242 // | 236 // |
243 // Examples: | 237 // Examples: |
244 // | 238 // |
245 // Internal getter and setter prefixes are changed: | 239 // Internal getter and setter prefixes are changed: |
246 // | 240 // |
247 // get:foo -> foo | 241 // get:foo -> foo |
248 // set:foo -> foo= | 242 // set:foo -> foo= |
249 // | 243 // |
250 // Private name mangling is removed, possibly multiple times: | 244 // Private name mangling is removed, possibly multiple times: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 AppendSubString(zone, &unmangled_segments, equals, 0, equals_len); | 358 AppendSubString(zone, &unmangled_segments, equals, 0, equals_len); |
365 final_len += equals_len; | 359 final_len += equals_len; |
366 } | 360 } |
367 | 361 |
368 unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len); | 362 unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len); |
369 #endif // !defined(PRODUCT) | 363 #endif // !defined(PRODUCT) |
370 | 364 |
371 return Symbols::New(thread, unmangled_name); | 365 return Symbols::New(thread, unmangled_name); |
372 } | 366 } |
373 | 367 |
374 | |
375 RawString* String::ScrubNameRetainPrivate(const String& name) { | 368 RawString* String::ScrubNameRetainPrivate(const String& name) { |
376 #if !defined(PRODUCT) | 369 #if !defined(PRODUCT) |
377 intptr_t len = name.Length(); | 370 intptr_t len = name.Length(); |
378 intptr_t start = 0; | 371 intptr_t start = 0; |
379 intptr_t at_pos = -1; // Position of '@' in the name, if any. | 372 intptr_t at_pos = -1; // Position of '@' in the name, if any. |
380 bool is_setter = false; | 373 bool is_setter = false; |
381 | 374 |
382 for (intptr_t i = start; i < len; i++) { | 375 for (intptr_t i = start; i < len; i++) { |
383 if (name.CharAt(i) == ':') { | 376 if (name.CharAt(i) == ':') { |
384 ASSERT(start == 0); // Only one : is possible in getters or setters. | 377 ASSERT(start == 0); // Only one : is possible in getters or setters. |
(...skipping 28 matching lines...) Expand all Loading... |
413 result = String::Concat(pre_at, Symbols::Equals()); | 406 result = String::Concat(pre_at, Symbols::Equals()); |
414 result = String::Concat(result, post_at); | 407 result = String::Concat(result, post_at); |
415 } | 408 } |
416 } | 409 } |
417 | 410 |
418 return result.raw(); | 411 return result.raw(); |
419 #endif // !defined(PRODUCT) | 412 #endif // !defined(PRODUCT) |
420 return name.raw(); // In PRODUCT, return argument unchanged. | 413 return name.raw(); // In PRODUCT, return argument unchanged. |
421 } | 414 } |
422 | 415 |
423 | |
424 template <typename type> | 416 template <typename type> |
425 static bool IsSpecialCharacter(type value) { | 417 static bool IsSpecialCharacter(type value) { |
426 return ((value == '"') || (value == '\n') || (value == '\f') || | 418 return ((value == '"') || (value == '\n') || (value == '\f') || |
427 (value == '\b') || (value == '\t') || (value == '\v') || | 419 (value == '\b') || (value == '\t') || (value == '\v') || |
428 (value == '\r') || (value == '\\') || (value == '$')); | 420 (value == '\r') || (value == '\\') || (value == '$')); |
429 } | 421 } |
430 | 422 |
431 | |
432 static inline bool IsAsciiNonprintable(int32_t c) { | 423 static inline bool IsAsciiNonprintable(int32_t c) { |
433 return ((0 <= c) && (c < 32)) || (c == 127); | 424 return ((0 <= c) && (c < 32)) || (c == 127); |
434 } | 425 } |
435 | 426 |
436 | |
437 static inline bool NeedsEscapeSequence(int32_t c) { | 427 static inline bool NeedsEscapeSequence(int32_t c) { |
438 return (c == '"') || (c == '\\') || (c == '$') || IsAsciiNonprintable(c); | 428 return (c == '"') || (c == '\\') || (c == '$') || IsAsciiNonprintable(c); |
439 } | 429 } |
440 | 430 |
441 | |
442 static int32_t EscapeOverhead(int32_t c) { | 431 static int32_t EscapeOverhead(int32_t c) { |
443 if (IsSpecialCharacter(c)) { | 432 if (IsSpecialCharacter(c)) { |
444 return 1; // 1 additional byte for the backslash. | 433 return 1; // 1 additional byte for the backslash. |
445 } else if (IsAsciiNonprintable(c)) { | 434 } else if (IsAsciiNonprintable(c)) { |
446 return 3; // 3 additional bytes to encode c as \x00. | 435 return 3; // 3 additional bytes to encode c as \x00. |
447 } | 436 } |
448 return 0; | 437 return 0; |
449 } | 438 } |
450 | 439 |
451 | |
452 template <typename type> | 440 template <typename type> |
453 static type SpecialCharacter(type value) { | 441 static type SpecialCharacter(type value) { |
454 if (value == '"') { | 442 if (value == '"') { |
455 return '"'; | 443 return '"'; |
456 } else if (value == '\n') { | 444 } else if (value == '\n') { |
457 return 'n'; | 445 return 'n'; |
458 } else if (value == '\f') { | 446 } else if (value == '\f') { |
459 return 'f'; | 447 return 'f'; |
460 } else if (value == '\b') { | 448 } else if (value == '\b') { |
461 return 'b'; | 449 return 'b'; |
462 } else if (value == '\t') { | 450 } else if (value == '\t') { |
463 return 't'; | 451 return 't'; |
464 } else if (value == '\v') { | 452 } else if (value == '\v') { |
465 return 'v'; | 453 return 'v'; |
466 } else if (value == '\r') { | 454 } else if (value == '\r') { |
467 return 'r'; | 455 return 'r'; |
468 } else if (value == '\\') { | 456 } else if (value == '\\') { |
469 return '\\'; | 457 return '\\'; |
470 } else if (value == '$') { | 458 } else if (value == '$') { |
471 return '$'; | 459 return '$'; |
472 } | 460 } |
473 UNREACHABLE(); | 461 UNREACHABLE(); |
474 return '\0'; | 462 return '\0'; |
475 } | 463 } |
476 | 464 |
477 | |
478 void Object::InitNull(Isolate* isolate) { | 465 void Object::InitNull(Isolate* isolate) { |
479 // Should only be run by the vm isolate. | 466 // Should only be run by the vm isolate. |
480 ASSERT(isolate == Dart::vm_isolate()); | 467 ASSERT(isolate == Dart::vm_isolate()); |
481 | 468 |
482 // TODO(iposva): NoSafepointScope needs to be added here. | 469 // TODO(iposva): NoSafepointScope needs to be added here. |
483 ASSERT(class_class() == null_); | 470 ASSERT(class_class() == null_); |
484 | 471 |
485 Heap* heap = isolate->heap(); | 472 Heap* heap = isolate->heap(); |
486 | 473 |
487 // Allocate and initialize the null instance. | 474 // Allocate and initialize the null instance. |
488 // 'null_' must be the first object allocated as it is used in allocation to | 475 // 'null_' must be the first object allocated as it is used in allocation to |
489 // clear the object. | 476 // clear the object. |
490 { | 477 { |
491 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); | 478 uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); |
492 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); | 479 null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); |
493 // The call below is using 'null_' to initialize itself. | 480 // The call below is using 'null_' to initialize itself. |
494 InitializeObject(address, kNullCid, Instance::InstanceSize(), true); | 481 InitializeObject(address, kNullCid, Instance::InstanceSize(), true); |
495 } | 482 } |
496 } | 483 } |
497 | 484 |
498 | |
499 void Object::InitOnce(Isolate* isolate) { | 485 void Object::InitOnce(Isolate* isolate) { |
500 // Should only be run by the vm isolate. | 486 // Should only be run by the vm isolate. |
501 ASSERT(isolate == Dart::vm_isolate()); | 487 ASSERT(isolate == Dart::vm_isolate()); |
502 | 488 |
503 // Initialize the static vtable values. | 489 // Initialize the static vtable values. |
504 { | 490 { |
505 Object fake_object; | 491 Object fake_object; |
506 Smi fake_smi; | 492 Smi fake_smi; |
507 Object::handle_vtable_ = fake_object.vtable(); | 493 Object::handle_vtable_ = fake_object.vtable(); |
508 Smi::handle_vtable_ = fake_smi.vtable(); | 494 Smi::handle_vtable_ = fake_smi.vtable(); |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 ASSERT(!branch_offset_error_->IsSmi()); | 969 ASSERT(!branch_offset_error_->IsSmi()); |
984 ASSERT(branch_offset_error_->IsLanguageError()); | 970 ASSERT(branch_offset_error_->IsLanguageError()); |
985 ASSERT(!speculative_inlining_error_->IsSmi()); | 971 ASSERT(!speculative_inlining_error_->IsSmi()); |
986 ASSERT(speculative_inlining_error_->IsLanguageError()); | 972 ASSERT(speculative_inlining_error_->IsLanguageError()); |
987 ASSERT(!background_compilation_error_->IsSmi()); | 973 ASSERT(!background_compilation_error_->IsSmi()); |
988 ASSERT(background_compilation_error_->IsLanguageError()); | 974 ASSERT(background_compilation_error_->IsLanguageError()); |
989 ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); | 975 ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); |
990 ASSERT(vm_isolate_snapshot_object_table_->IsArray()); | 976 ASSERT(vm_isolate_snapshot_object_table_->IsArray()); |
991 } | 977 } |
992 | 978 |
993 | |
994 // An object visitor which will mark all visited objects. This is used to | 979 // An object visitor which will mark all visited objects. This is used to |
995 // premark all objects in the vm_isolate_ heap. Also precalculates hash | 980 // premark all objects in the vm_isolate_ heap. Also precalculates hash |
996 // codes so that we can get the identity hash code of objects in the read- | 981 // codes so that we can get the identity hash code of objects in the read- |
997 // only VM isolate. | 982 // only VM isolate. |
998 class FinalizeVMIsolateVisitor : public ObjectVisitor { | 983 class FinalizeVMIsolateVisitor : public ObjectVisitor { |
999 public: | 984 public: |
1000 FinalizeVMIsolateVisitor() | 985 FinalizeVMIsolateVisitor() |
1001 #if defined(HASH_IN_OBJECT_HEADER) | 986 #if defined(HASH_IN_OBJECT_HEADER) |
1002 : counter_(1337) | 987 : counter_(1337) |
1003 #endif | 988 #endif |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 #endif | 1021 #endif |
1037 } | 1022 } |
1038 } | 1023 } |
1039 | 1024 |
1040 private: | 1025 private: |
1041 #if defined(HASH_IN_OBJECT_HEADER) | 1026 #if defined(HASH_IN_OBJECT_HEADER) |
1042 int32_t counter_; | 1027 int32_t counter_; |
1043 #endif | 1028 #endif |
1044 }; | 1029 }; |
1045 | 1030 |
1046 | |
1047 #define SET_CLASS_NAME(class_name, name) \ | 1031 #define SET_CLASS_NAME(class_name, name) \ |
1048 cls = class_name##_class(); \ | 1032 cls = class_name##_class(); \ |
1049 cls.set_name(Symbols::name()); | 1033 cls.set_name(Symbols::name()); |
1050 | 1034 |
1051 void Object::FinalizeVMIsolate(Isolate* isolate) { | 1035 void Object::FinalizeVMIsolate(Isolate* isolate) { |
1052 // Should only be run by the vm isolate. | 1036 // Should only be run by the vm isolate. |
1053 ASSERT(isolate == Dart::vm_isolate()); | 1037 ASSERT(isolate == Dart::vm_isolate()); |
1054 | 1038 |
1055 // Allocate the parameter arrays for method extractor types and names. | 1039 // Allocate the parameter arrays for method extractor types and names. |
1056 *extractor_parameter_types_ = Array::New(1, Heap::kOld); | 1040 *extractor_parameter_types_ = Array::New(1, Heap::kOld); |
1057 extractor_parameter_types_->SetAt(0, Object::dynamic_type()); | 1041 extractor_parameter_types_->SetAt(0, Object::dynamic_type()); |
1058 *extractor_parameter_names_ = Array::New(1, Heap::kOld); | 1042 *extractor_parameter_names_ = Array::New(1, Heap::kOld); |
1059 extractor_parameter_names_->SetAt(0, Symbols::This()); | 1043 extractor_parameter_names_->SetAt(0, Symbols::This()); |
1060 | 1044 |
1061 ASSERT(!extractor_parameter_types_->IsSmi()); | 1045 ASSERT(!extractor_parameter_types_->IsSmi()); |
1062 ASSERT(extractor_parameter_types_->IsArray()); | 1046 ASSERT(extractor_parameter_types_->IsArray()); |
1063 ASSERT(!extractor_parameter_names_->IsSmi()); | 1047 ASSERT(!extractor_parameter_names_->IsSmi()); |
1064 ASSERT(extractor_parameter_names_->IsArray()); | 1048 ASSERT(extractor_parameter_names_->IsArray()); |
1065 | 1049 |
1066 | |
1067 // Set up names for all VM singleton classes. | 1050 // Set up names for all VM singleton classes. |
1068 Class& cls = Class::Handle(); | 1051 Class& cls = Class::Handle(); |
1069 | 1052 |
1070 SET_CLASS_NAME(class, Class); | 1053 SET_CLASS_NAME(class, Class); |
1071 SET_CLASS_NAME(dynamic, Dynamic); | 1054 SET_CLASS_NAME(dynamic, Dynamic); |
1072 SET_CLASS_NAME(void, Void); | 1055 SET_CLASS_NAME(void, Void); |
1073 SET_CLASS_NAME(unresolved_class, UnresolvedClass); | 1056 SET_CLASS_NAME(unresolved_class, UnresolvedClass); |
1074 SET_CLASS_NAME(type_arguments, TypeArguments); | 1057 SET_CLASS_NAME(type_arguments, TypeArguments); |
1075 SET_CLASS_NAME(patch_class, PatchClass); | 1058 SET_CLASS_NAME(patch_class, PatchClass); |
1076 SET_CLASS_NAME(function, Function); | 1059 SET_CLASS_NAME(function, Function); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 ASSERT(isolate == Dart::vm_isolate()); | 1104 ASSERT(isolate == Dart::vm_isolate()); |
1122 WritableVMIsolateScope scope(Thread::Current()); | 1105 WritableVMIsolateScope scope(Thread::Current()); |
1123 FinalizeVMIsolateVisitor premarker; | 1106 FinalizeVMIsolateVisitor premarker; |
1124 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); | 1107 ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); |
1125 isolate->heap()->IterateOldObjectsNoImagePages(&premarker); | 1108 isolate->heap()->IterateOldObjectsNoImagePages(&premarker); |
1126 // Make the VM isolate read-only again after setting all objects as marked. | 1109 // Make the VM isolate read-only again after setting all objects as marked. |
1127 // Note objects in image pages are already pre-marked. | 1110 // Note objects in image pages are already pre-marked. |
1128 } | 1111 } |
1129 } | 1112 } |
1130 | 1113 |
1131 | |
1132 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { | 1114 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { |
1133 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 1115 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
1134 *vm_isolate_snapshot_object_table_ = table.raw(); | 1116 *vm_isolate_snapshot_object_table_ = table.raw(); |
1135 } | 1117 } |
1136 | 1118 |
1137 | |
1138 // Make unused space in an object whose type has been transformed safe | 1119 // Make unused space in an object whose type has been transformed safe |
1139 // for traversing during GC. | 1120 // for traversing during GC. |
1140 // The unused part of the transformed object is marked as an TypedDataInt8Array | 1121 // The unused part of the transformed object is marked as an TypedDataInt8Array |
1141 // object. | 1122 // object. |
1142 void Object::MakeUnusedSpaceTraversable(const Object& obj, | 1123 void Object::MakeUnusedSpaceTraversable(const Object& obj, |
1143 intptr_t original_size, | 1124 intptr_t original_size, |
1144 intptr_t used_size) { | 1125 intptr_t used_size) { |
1145 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); | 1126 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |
1146 ASSERT(!obj.IsNull()); | 1127 ASSERT(!obj.IsNull()); |
1147 ASSERT(original_size >= used_size); | 1128 ASSERT(original_size >= used_size); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 uint32_t old_tags; | 1160 uint32_t old_tags; |
1180 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. | 1161 // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. |
1181 do { | 1162 do { |
1182 old_tags = tags; | 1163 old_tags = tags; |
1183 tags = obj.CompareAndSwapTags(old_tags, new_tags); | 1164 tags = obj.CompareAndSwapTags(old_tags, new_tags); |
1184 } while (tags != old_tags); | 1165 } while (tags != old_tags); |
1185 } | 1166 } |
1186 } | 1167 } |
1187 } | 1168 } |
1188 | 1169 |
1189 | |
1190 void Object::VerifyBuiltinVtables() { | 1170 void Object::VerifyBuiltinVtables() { |
1191 #if defined(DEBUG) | 1171 #if defined(DEBUG) |
1192 Thread* thread = Thread::Current(); | 1172 Thread* thread = Thread::Current(); |
1193 Isolate* isolate = thread->isolate(); | 1173 Isolate* isolate = thread->isolate(); |
1194 Class& cls = Class::Handle(thread->zone(), Class::null()); | 1174 Class& cls = Class::Handle(thread->zone(), Class::null()); |
1195 for (intptr_t cid = (kIllegalCid + 1); cid < kNumPredefinedCids; cid++) { | 1175 for (intptr_t cid = (kIllegalCid + 1); cid < kNumPredefinedCids; cid++) { |
1196 if (isolate->class_table()->HasValidClassAt(cid)) { | 1176 if (isolate->class_table()->HasValidClassAt(cid)) { |
1197 cls ^= isolate->class_table()->At(cid); | 1177 cls ^= isolate->class_table()->At(cid); |
1198 ASSERT(builtin_vtables_[cid] == cls.raw_ptr()->handle_vtable_); | 1178 ASSERT(builtin_vtables_[cid] == cls.raw_ptr()->handle_vtable_); |
1199 } | 1179 } |
1200 } | 1180 } |
1201 ASSERT(builtin_vtables_[kFreeListElement] == 0); | 1181 ASSERT(builtin_vtables_[kFreeListElement] == 0); |
1202 ASSERT(builtin_vtables_[kForwardingCorpse] == 0); | 1182 ASSERT(builtin_vtables_[kForwardingCorpse] == 0); |
1203 #endif | 1183 #endif |
1204 } | 1184 } |
1205 | 1185 |
1206 | |
1207 void Object::RegisterClass(const Class& cls, | 1186 void Object::RegisterClass(const Class& cls, |
1208 const String& name, | 1187 const String& name, |
1209 const Library& lib) { | 1188 const Library& lib) { |
1210 ASSERT(name.Length() > 0); | 1189 ASSERT(name.Length() > 0); |
1211 ASSERT(name.CharAt(0) != '_'); | 1190 ASSERT(name.CharAt(0) != '_'); |
1212 cls.set_name(name); | 1191 cls.set_name(name); |
1213 lib.AddClass(cls); | 1192 lib.AddClass(cls); |
1214 } | 1193 } |
1215 | 1194 |
1216 | |
1217 void Object::RegisterPrivateClass(const Class& cls, | 1195 void Object::RegisterPrivateClass(const Class& cls, |
1218 const String& public_class_name, | 1196 const String& public_class_name, |
1219 const Library& lib) { | 1197 const Library& lib) { |
1220 ASSERT(public_class_name.Length() > 0); | 1198 ASSERT(public_class_name.Length() > 0); |
1221 ASSERT(public_class_name.CharAt(0) == '_'); | 1199 ASSERT(public_class_name.CharAt(0) == '_'); |
1222 String& str = String::Handle(); | 1200 String& str = String::Handle(); |
1223 str = lib.PrivateName(public_class_name); | 1201 str = lib.PrivateName(public_class_name); |
1224 cls.set_name(str); | 1202 cls.set_name(str); |
1225 lib.AddClass(cls); | 1203 lib.AddClass(cls); |
1226 } | 1204 } |
1227 | 1205 |
1228 | |
1229 // Initialize a new isolate from source or from a snapshot. | 1206 // Initialize a new isolate from source or from a snapshot. |
1230 // | 1207 // |
1231 // There are three possibilities: | 1208 // There are three possibilities: |
1232 // 1. Running a Kernel binary. This function will bootstrap from the KERNEL | 1209 // 1. Running a Kernel binary. This function will bootstrap from the KERNEL |
1233 // file. | 1210 // file. |
1234 // 2. There is no snapshot. This function will bootstrap from source. | 1211 // 2. There is no snapshot. This function will bootstrap from source. |
1235 // 3. There is a snapshot. The caller should initialize from the snapshot. | 1212 // 3. There is a snapshot. The caller should initialize from the snapshot. |
1236 // | 1213 // |
1237 // A non-NULL kernel argument indicates (1). A NULL kernel indicates (2) or | 1214 // A non-NULL kernel argument indicates (1). A NULL kernel indicates (2) or |
1238 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or | 1215 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 | 1837 |
1861 cls = Class::New<WeakProperty>(); | 1838 cls = Class::New<WeakProperty>(); |
1862 object_store->set_weak_property_class(cls); | 1839 object_store->set_weak_property_class(cls); |
1863 | 1840 |
1864 cls = Class::New<MirrorReference>(); | 1841 cls = Class::New<MirrorReference>(); |
1865 cls = Class::New<UserTag>(); | 1842 cls = Class::New<UserTag>(); |
1866 } | 1843 } |
1867 return Error::null(); | 1844 return Error::null(); |
1868 } | 1845 } |
1869 | 1846 |
1870 | |
1871 #if defined(DEBUG) | 1847 #if defined(DEBUG) |
1872 bool Object::InVMHeap() const { | 1848 bool Object::InVMHeap() const { |
1873 if (FLAG_verify_handles && raw()->IsVMHeapObject()) { | 1849 if (FLAG_verify_handles && raw()->IsVMHeapObject()) { |
1874 Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); | 1850 Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); |
1875 ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw()))); | 1851 ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw()))); |
1876 } | 1852 } |
1877 return raw()->IsVMHeapObject(); | 1853 return raw()->IsVMHeapObject(); |
1878 } | 1854 } |
1879 #endif // DEBUG | 1855 #endif // DEBUG |
1880 | 1856 |
1881 | |
1882 void Object::Print() const { | 1857 void Object::Print() const { |
1883 THR_Print("%s\n", ToCString()); | 1858 THR_Print("%s\n", ToCString()); |
1884 } | 1859 } |
1885 | 1860 |
1886 | |
1887 RawString* Object::DictionaryName() const { | 1861 RawString* Object::DictionaryName() const { |
1888 return String::null(); | 1862 return String::null(); |
1889 } | 1863 } |
1890 | 1864 |
1891 | |
1892 void Object::InitializeObject(uword address, | 1865 void Object::InitializeObject(uword address, |
1893 intptr_t class_id, | 1866 intptr_t class_id, |
1894 intptr_t size, | 1867 intptr_t size, |
1895 bool is_vm_object) { | 1868 bool is_vm_object) { |
1896 uword initial_value = (class_id == kInstructionsCid) | 1869 uword initial_value = (class_id == kInstructionsCid) |
1897 ? Assembler::GetBreakInstructionFiller() | 1870 ? Assembler::GetBreakInstructionFiller() |
1898 : reinterpret_cast<uword>(null_); | 1871 : reinterpret_cast<uword>(null_); |
1899 uword cur = address; | 1872 uword cur = address; |
1900 uword end = address + size; | 1873 uword end = address + size; |
1901 while (cur < end) { | 1874 while (cur < end) { |
1902 *reinterpret_cast<uword*>(cur) = initial_value; | 1875 *reinterpret_cast<uword*>(cur) = initial_value; |
1903 cur += kWordSize; | 1876 cur += kWordSize; |
1904 } | 1877 } |
1905 uint32_t tags = 0; | 1878 uint32_t tags = 0; |
1906 ASSERT(class_id != kIllegalCid); | 1879 ASSERT(class_id != kIllegalCid); |
1907 tags = RawObject::ClassIdTag::update(class_id, tags); | 1880 tags = RawObject::ClassIdTag::update(class_id, tags); |
1908 tags = RawObject::SizeTag::update(size, tags); | 1881 tags = RawObject::SizeTag::update(size, tags); |
1909 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); | 1882 tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); |
1910 reinterpret_cast<RawObject*>(address)->tags_ = tags; | 1883 reinterpret_cast<RawObject*>(address)->tags_ = tags; |
1911 #if defined(HASH_IN_OBJECT_HEADER) | 1884 #if defined(HASH_IN_OBJECT_HEADER) |
1912 reinterpret_cast<RawObject*>(address)->hash_ = 0; | 1885 reinterpret_cast<RawObject*>(address)->hash_ = 0; |
1913 #endif | 1886 #endif |
1914 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); | 1887 ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); |
1915 } | 1888 } |
1916 | 1889 |
1917 | |
1918 void Object::CheckHandle() const { | 1890 void Object::CheckHandle() const { |
1919 #if defined(DEBUG) | 1891 #if defined(DEBUG) |
1920 if (raw_ != Object::null()) { | 1892 if (raw_ != Object::null()) { |
1921 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { | 1893 if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { |
1922 ASSERT(vtable() == Smi::handle_vtable_); | 1894 ASSERT(vtable() == Smi::handle_vtable_); |
1923 return; | 1895 return; |
1924 } | 1896 } |
1925 intptr_t cid = raw_->GetClassId(); | 1897 intptr_t cid = raw_->GetClassId(); |
1926 if (cid >= kNumPredefinedCids) { | 1898 if (cid >= kNumPredefinedCids) { |
1927 cid = kInstanceCid; | 1899 cid = kInstanceCid; |
1928 } | 1900 } |
1929 ASSERT(vtable() == builtin_vtables_[cid]); | 1901 ASSERT(vtable() == builtin_vtables_[cid]); |
1930 if (FLAG_verify_handles) { | 1902 if (FLAG_verify_handles) { |
1931 Isolate* isolate = Isolate::Current(); | 1903 Isolate* isolate = Isolate::Current(); |
1932 Heap* isolate_heap = isolate->heap(); | 1904 Heap* isolate_heap = isolate->heap(); |
1933 Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); | 1905 Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); |
1934 ASSERT(isolate_heap->Contains(RawObject::ToAddr(raw_)) || | 1906 ASSERT(isolate_heap->Contains(RawObject::ToAddr(raw_)) || |
1935 vm_isolate_heap->Contains(RawObject::ToAddr(raw_))); | 1907 vm_isolate_heap->Contains(RawObject::ToAddr(raw_))); |
1936 } | 1908 } |
1937 } | 1909 } |
1938 #endif | 1910 #endif |
1939 } | 1911 } |
1940 | 1912 |
1941 | |
1942 RawObject* Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) { | 1913 RawObject* Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) { |
1943 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 1914 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
1944 Thread* thread = Thread::Current(); | 1915 Thread* thread = Thread::Current(); |
1945 Isolate* isolate = thread->isolate(); | 1916 Isolate* isolate = thread->isolate(); |
1946 // New space allocation allowed only in mutator thread (Dart thread); | 1917 // New space allocation allowed only in mutator thread (Dart thread); |
1947 ASSERT(thread->IsMutatorThread() || (space != Heap::kNew)); | 1918 ASSERT(thread->IsMutatorThread() || (space != Heap::kNew)); |
1948 ASSERT(thread->no_callback_scope_depth() == 0); | 1919 ASSERT(thread->no_callback_scope_depth() == 0); |
1949 Heap* heap = isolate->heap(); | 1920 Heap* heap = isolate->heap(); |
1950 | 1921 |
1951 uword address = heap->Allocate(size, space); | 1922 uword address = heap->Allocate(size, space); |
(...skipping 17 matching lines...) Expand all Loading... |
1969 Profiler::SampleAllocation(thread, cls_id); | 1940 Profiler::SampleAllocation(thread, cls_id); |
1970 } | 1941 } |
1971 #endif // !PRODUCT | 1942 #endif // !PRODUCT |
1972 NoSafepointScope no_safepoint; | 1943 NoSafepointScope no_safepoint; |
1973 InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate())); | 1944 InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate())); |
1974 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 1945 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
1975 ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); | 1946 ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); |
1976 return raw_obj; | 1947 return raw_obj; |
1977 } | 1948 } |
1978 | 1949 |
1979 | |
1980 class StoreBufferUpdateVisitor : public ObjectPointerVisitor { | 1950 class StoreBufferUpdateVisitor : public ObjectPointerVisitor { |
1981 public: | 1951 public: |
1982 explicit StoreBufferUpdateVisitor(Thread* thread, RawObject* obj) | 1952 explicit StoreBufferUpdateVisitor(Thread* thread, RawObject* obj) |
1983 : ObjectPointerVisitor(thread->isolate()), | 1953 : ObjectPointerVisitor(thread->isolate()), |
1984 thread_(thread), | 1954 thread_(thread), |
1985 old_obj_(obj) { | 1955 old_obj_(obj) { |
1986 ASSERT(old_obj_->IsOldObject()); | 1956 ASSERT(old_obj_->IsOldObject()); |
1987 } | 1957 } |
1988 | 1958 |
1989 void VisitPointers(RawObject** first, RawObject** last) { | 1959 void VisitPointers(RawObject** first, RawObject** last) { |
1990 for (RawObject** curr = first; curr <= last; ++curr) { | 1960 for (RawObject** curr = first; curr <= last; ++curr) { |
1991 RawObject* raw_obj = *curr; | 1961 RawObject* raw_obj = *curr; |
1992 if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) { | 1962 if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) { |
1993 old_obj_->SetRememberedBit(); | 1963 old_obj_->SetRememberedBit(); |
1994 thread_->StoreBufferAddObject(old_obj_); | 1964 thread_->StoreBufferAddObject(old_obj_); |
1995 // Remembered this object. There is no need to continue searching. | 1965 // Remembered this object. There is no need to continue searching. |
1996 return; | 1966 return; |
1997 } | 1967 } |
1998 } | 1968 } |
1999 } | 1969 } |
2000 | 1970 |
2001 private: | 1971 private: |
2002 Thread* thread_; | 1972 Thread* thread_; |
2003 RawObject* old_obj_; | 1973 RawObject* old_obj_; |
2004 | 1974 |
2005 DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor); | 1975 DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor); |
2006 }; | 1976 }; |
2007 | 1977 |
2008 | |
2009 bool Object::IsReadOnlyHandle() const { | 1978 bool Object::IsReadOnlyHandle() const { |
2010 return Dart::IsReadOnlyHandle(reinterpret_cast<uword>(this)); | 1979 return Dart::IsReadOnlyHandle(reinterpret_cast<uword>(this)); |
2011 } | 1980 } |
2012 | 1981 |
2013 | |
2014 bool Object::IsNotTemporaryScopedHandle() const { | 1982 bool Object::IsNotTemporaryScopedHandle() const { |
2015 return (IsZoneHandle() || IsReadOnlyHandle()); | 1983 return (IsZoneHandle() || IsReadOnlyHandle()); |
2016 } | 1984 } |
2017 | 1985 |
2018 | |
2019 RawObject* Object::Clone(const Object& orig, Heap::Space space) { | 1986 RawObject* Object::Clone(const Object& orig, Heap::Space space) { |
2020 const Class& cls = Class::Handle(orig.clazz()); | 1987 const Class& cls = Class::Handle(orig.clazz()); |
2021 intptr_t size = orig.raw()->Size(); | 1988 intptr_t size = orig.raw()->Size(); |
2022 RawObject* raw_clone = Object::Allocate(cls.id(), size, space); | 1989 RawObject* raw_clone = Object::Allocate(cls.id(), size, space); |
2023 NoSafepointScope no_safepoint; | 1990 NoSafepointScope no_safepoint; |
2024 // TODO(koda): This will trip when we start allocating black. | 1991 // TODO(koda): This will trip when we start allocating black. |
2025 // Revisit code below at that point, to account for the new write barrier. | 1992 // Revisit code below at that point, to account for the new write barrier. |
2026 ASSERT(!raw_clone->IsMarked()); | 1993 ASSERT(!raw_clone->IsMarked()); |
2027 // Copy the body of the original into the clone. | 1994 // Copy the body of the original into the clone. |
2028 uword orig_addr = RawObject::ToAddr(orig.raw()); | 1995 uword orig_addr = RawObject::ToAddr(orig.raw()); |
2029 uword clone_addr = RawObject::ToAddr(raw_clone); | 1996 uword clone_addr = RawObject::ToAddr(raw_clone); |
2030 static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); | 1997 static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); |
2031 memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), | 1998 memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), |
2032 reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), | 1999 reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), |
2033 size - kHeaderSizeInBytes); | 2000 size - kHeaderSizeInBytes); |
2034 // Add clone to store buffer, if needed. | 2001 // Add clone to store buffer, if needed. |
2035 if (!raw_clone->IsOldObject()) { | 2002 if (!raw_clone->IsOldObject()) { |
2036 // No need to remember an object in new space. | 2003 // No need to remember an object in new space. |
2037 return raw_clone; | 2004 return raw_clone; |
2038 } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { | 2005 } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { |
2039 // Old original doesn't need to be remembered, so neither does the clone. | 2006 // Old original doesn't need to be remembered, so neither does the clone. |
2040 return raw_clone; | 2007 return raw_clone; |
2041 } | 2008 } |
2042 StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); | 2009 StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); |
2043 raw_clone->VisitPointers(&visitor); | 2010 raw_clone->VisitPointers(&visitor); |
2044 return raw_clone; | 2011 return raw_clone; |
2045 } | 2012 } |
2046 | 2013 |
2047 | |
2048 RawString* Class::Name() const { | 2014 RawString* Class::Name() const { |
2049 return raw_ptr()->name_; | 2015 return raw_ptr()->name_; |
2050 } | 2016 } |
2051 | 2017 |
2052 | |
2053 RawString* Class::ScrubbedName() const { | 2018 RawString* Class::ScrubbedName() const { |
2054 return String::ScrubName(String::Handle(Name())); | 2019 return String::ScrubName(String::Handle(Name())); |
2055 } | 2020 } |
2056 | 2021 |
2057 | |
2058 RawString* Class::UserVisibleName() const { | 2022 RawString* Class::UserVisibleName() const { |
2059 #if !defined(PRODUCT) | 2023 #if !defined(PRODUCT) |
2060 ASSERT(raw_ptr()->user_name_ != String::null()); | 2024 ASSERT(raw_ptr()->user_name_ != String::null()); |
2061 return raw_ptr()->user_name_; | 2025 return raw_ptr()->user_name_; |
2062 #endif // !defined(PRODUCT) | 2026 #endif // !defined(PRODUCT) |
2063 return GenerateUserVisibleName(); // No caching in PRODUCT, regenerate. | 2027 return GenerateUserVisibleName(); // No caching in PRODUCT, regenerate. |
2064 } | 2028 } |
2065 | 2029 |
2066 | |
2067 bool Class::IsInFullSnapshot() const { | 2030 bool Class::IsInFullSnapshot() const { |
2068 NoSafepointScope no_safepoint; | 2031 NoSafepointScope no_safepoint; |
2069 return raw_ptr()->library_->ptr()->is_in_fullsnapshot_; | 2032 return raw_ptr()->library_->ptr()->is_in_fullsnapshot_; |
2070 } | 2033 } |
2071 | 2034 |
2072 | |
2073 RawAbstractType* Class::RareType() const { | 2035 RawAbstractType* Class::RareType() const { |
2074 const Type& type = Type::Handle(Type::New( | 2036 const Type& type = Type::Handle(Type::New( |
2075 *this, Object::null_type_arguments(), TokenPosition::kNoSource)); | 2037 *this, Object::null_type_arguments(), TokenPosition::kNoSource)); |
2076 return ClassFinalizer::FinalizeType(*this, type); | 2038 return ClassFinalizer::FinalizeType(*this, type); |
2077 } | 2039 } |
2078 | 2040 |
2079 | |
2080 RawAbstractType* Class::DeclarationType() const { | 2041 RawAbstractType* Class::DeclarationType() const { |
2081 const TypeArguments& args = TypeArguments::Handle(type_parameters()); | 2042 const TypeArguments& args = TypeArguments::Handle(type_parameters()); |
2082 const Type& type = | 2043 const Type& type = |
2083 Type::Handle(Type::New(*this, args, TokenPosition::kNoSource)); | 2044 Type::Handle(Type::New(*this, args, TokenPosition::kNoSource)); |
2084 return ClassFinalizer::FinalizeType(*this, type); | 2045 return ClassFinalizer::FinalizeType(*this, type); |
2085 } | 2046 } |
2086 | 2047 |
2087 | |
2088 template <class FakeObject> | 2048 template <class FakeObject> |
2089 RawClass* Class::New() { | 2049 RawClass* Class::New() { |
2090 ASSERT(Object::class_class() != Class::null()); | 2050 ASSERT(Object::class_class() != Class::null()); |
2091 Class& result = Class::Handle(); | 2051 Class& result = Class::Handle(); |
2092 { | 2052 { |
2093 RawObject* raw = | 2053 RawObject* raw = |
2094 Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); | 2054 Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); |
2095 NoSafepointScope no_safepoint; | 2055 NoSafepointScope no_safepoint; |
2096 result ^= raw; | 2056 result ^= raw; |
2097 } | 2057 } |
(...skipping 16 matching lines...) Expand all Loading... |
2114 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); | 2074 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); |
2115 result.set_num_type_arguments(0); | 2075 result.set_num_type_arguments(0); |
2116 result.set_num_own_type_arguments(0); | 2076 result.set_num_own_type_arguments(0); |
2117 result.set_num_native_fields(0); | 2077 result.set_num_native_fields(0); |
2118 result.set_token_pos(TokenPosition::kNoSource); | 2078 result.set_token_pos(TokenPosition::kNoSource); |
2119 result.InitEmptyFields(); | 2079 result.InitEmptyFields(); |
2120 Isolate::Current()->RegisterClass(result); | 2080 Isolate::Current()->RegisterClass(result); |
2121 return result.raw(); | 2081 return result.raw(); |
2122 } | 2082 } |
2123 | 2083 |
2124 | |
2125 static void ReportTooManyTypeArguments(const Class& cls) { | 2084 static void ReportTooManyTypeArguments(const Class& cls) { |
2126 Report::MessageF(Report::kError, Script::Handle(cls.script()), | 2085 Report::MessageF(Report::kError, Script::Handle(cls.script()), |
2127 cls.token_pos(), Report::AtLocation, | 2086 cls.token_pos(), Report::AtLocation, |
2128 "too many type parameters declared in class '%s' or in its " | 2087 "too many type parameters declared in class '%s' or in its " |
2129 "super classes", | 2088 "super classes", |
2130 String::Handle(cls.Name()).ToCString()); | 2089 String::Handle(cls.Name()).ToCString()); |
2131 UNREACHABLE(); | 2090 UNREACHABLE(); |
2132 } | 2091 } |
2133 | 2092 |
2134 | |
2135 void Class::set_num_type_arguments(intptr_t value) const { | 2093 void Class::set_num_type_arguments(intptr_t value) const { |
2136 if (!Utils::IsInt(16, value)) { | 2094 if (!Utils::IsInt(16, value)) { |
2137 ReportTooManyTypeArguments(*this); | 2095 ReportTooManyTypeArguments(*this); |
2138 } | 2096 } |
2139 StoreNonPointer(&raw_ptr()->num_type_arguments_, value); | 2097 StoreNonPointer(&raw_ptr()->num_type_arguments_, value); |
2140 } | 2098 } |
2141 | 2099 |
2142 | |
2143 void Class::set_num_own_type_arguments(intptr_t value) const { | 2100 void Class::set_num_own_type_arguments(intptr_t value) const { |
2144 if (!Utils::IsInt(16, value)) { | 2101 if (!Utils::IsInt(16, value)) { |
2145 ReportTooManyTypeArguments(*this); | 2102 ReportTooManyTypeArguments(*this); |
2146 } | 2103 } |
2147 StoreNonPointer(&raw_ptr()->num_own_type_arguments_, value); | 2104 StoreNonPointer(&raw_ptr()->num_own_type_arguments_, value); |
2148 } | 2105 } |
2149 | 2106 |
2150 | |
2151 // Initialize class fields of type Array with empty array. | 2107 // Initialize class fields of type Array with empty array. |
2152 void Class::InitEmptyFields() { | 2108 void Class::InitEmptyFields() { |
2153 if (Object::empty_array().raw() == Array::null()) { | 2109 if (Object::empty_array().raw() == Array::null()) { |
2154 // The empty array has not been initialized yet. | 2110 // The empty array has not been initialized yet. |
2155 return; | 2111 return; |
2156 } | 2112 } |
2157 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); | 2113 StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); |
2158 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); | 2114 StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); |
2159 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); | 2115 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |
2160 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); | 2116 StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); |
2161 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, | 2117 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, |
2162 Object::empty_array().raw()); | 2118 Object::empty_array().raw()); |
2163 } | 2119 } |
2164 | 2120 |
2165 | |
2166 RawArray* Class::OffsetToFieldMap(bool original_classes) const { | 2121 RawArray* Class::OffsetToFieldMap(bool original_classes) const { |
2167 Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); | 2122 Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); |
2168 if (array.IsNull()) { | 2123 if (array.IsNull()) { |
2169 ASSERT(is_finalized()); | 2124 ASSERT(is_finalized()); |
2170 const intptr_t length = raw_ptr()->instance_size_in_words_; | 2125 const intptr_t length = raw_ptr()->instance_size_in_words_; |
2171 array = Array::New(length, Heap::kOld); | 2126 array = Array::New(length, Heap::kOld); |
2172 Class& cls = Class::Handle(this->raw()); | 2127 Class& cls = Class::Handle(this->raw()); |
2173 Array& fields = Array::Handle(); | 2128 Array& fields = Array::Handle(); |
2174 Field& f = Field::Handle(); | 2129 Field& f = Field::Handle(); |
2175 while (!cls.IsNull()) { | 2130 while (!cls.IsNull()) { |
2176 fields = cls.fields(); | 2131 fields = cls.fields(); |
2177 for (intptr_t i = 0; i < fields.Length(); ++i) { | 2132 for (intptr_t i = 0; i < fields.Length(); ++i) { |
2178 f ^= fields.At(i); | 2133 f ^= fields.At(i); |
2179 if (f.is_instance()) { | 2134 if (f.is_instance()) { |
2180 array.SetAt(f.Offset() >> kWordSizeLog2, f); | 2135 array.SetAt(f.Offset() >> kWordSizeLog2, f); |
2181 } | 2136 } |
2182 } | 2137 } |
2183 cls = cls.SuperClass(original_classes); | 2138 cls = cls.SuperClass(original_classes); |
2184 } | 2139 } |
2185 StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw()); | 2140 StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw()); |
2186 } | 2141 } |
2187 return array.raw(); | 2142 return array.raw(); |
2188 } | 2143 } |
2189 | 2144 |
2190 | |
2191 bool Class::HasInstanceFields() const { | 2145 bool Class::HasInstanceFields() const { |
2192 const Array& field_array = Array::Handle(fields()); | 2146 const Array& field_array = Array::Handle(fields()); |
2193 Field& field = Field::Handle(); | 2147 Field& field = Field::Handle(); |
2194 for (intptr_t i = 0; i < field_array.Length(); ++i) { | 2148 for (intptr_t i = 0; i < field_array.Length(); ++i) { |
2195 field ^= field_array.At(i); | 2149 field ^= field_array.At(i); |
2196 if (!field.is_static()) { | 2150 if (!field.is_static()) { |
2197 return true; | 2151 return true; |
2198 } | 2152 } |
2199 } | 2153 } |
2200 return false; | 2154 return false; |
2201 } | 2155 } |
2202 | 2156 |
2203 | |
2204 class FunctionName { | 2157 class FunctionName { |
2205 public: | 2158 public: |
2206 FunctionName(const String& name, String* tmp_string) | 2159 FunctionName(const String& name, String* tmp_string) |
2207 : name_(name), tmp_string_(tmp_string) {} | 2160 : name_(name), tmp_string_(tmp_string) {} |
2208 bool Matches(const Function& function) const { | 2161 bool Matches(const Function& function) const { |
2209 if (name_.IsSymbol()) { | 2162 if (name_.IsSymbol()) { |
2210 return name_.raw() == function.name(); | 2163 return name_.raw() == function.name(); |
2211 } else { | 2164 } else { |
2212 *tmp_string_ = function.name(); | 2165 *tmp_string_ = function.name(); |
2213 return name_.Equals(*tmp_string_); | 2166 return name_.Equals(*tmp_string_); |
2214 } | 2167 } |
2215 } | 2168 } |
2216 intptr_t Hash() const { return name_.Hash(); } | 2169 intptr_t Hash() const { return name_.Hash(); } |
2217 | 2170 |
2218 private: | 2171 private: |
2219 const String& name_; | 2172 const String& name_; |
2220 String* tmp_string_; | 2173 String* tmp_string_; |
2221 }; | 2174 }; |
2222 | 2175 |
2223 | |
2224 // Traits for looking up Functions by name. | 2176 // Traits for looking up Functions by name. |
2225 class ClassFunctionsTraits { | 2177 class ClassFunctionsTraits { |
2226 public: | 2178 public: |
2227 static const char* Name() { return "ClassFunctionsTraits"; } | 2179 static const char* Name() { return "ClassFunctionsTraits"; } |
2228 static bool ReportStats() { return false; } | 2180 static bool ReportStats() { return false; } |
2229 | 2181 |
2230 // Called when growing the table. | 2182 // Called when growing the table. |
2231 static bool IsMatch(const Object& a, const Object& b) { | 2183 static bool IsMatch(const Object& a, const Object& b) { |
2232 ASSERT(a.IsFunction() && b.IsFunction()); | 2184 ASSERT(a.IsFunction() && b.IsFunction()); |
2233 // Function objects are always canonical. | 2185 // Function objects are always canonical. |
2234 return a.raw() == b.raw(); | 2186 return a.raw() == b.raw(); |
2235 } | 2187 } |
2236 static bool IsMatch(const FunctionName& name, const Object& obj) { | 2188 static bool IsMatch(const FunctionName& name, const Object& obj) { |
2237 return name.Matches(Function::Cast(obj)); | 2189 return name.Matches(Function::Cast(obj)); |
2238 } | 2190 } |
2239 static uword Hash(const Object& key) { | 2191 static uword Hash(const Object& key) { |
2240 return String::HashRawSymbol(Function::Cast(key).name()); | 2192 return String::HashRawSymbol(Function::Cast(key).name()); |
2241 } | 2193 } |
2242 static uword Hash(const FunctionName& name) { return name.Hash(); } | 2194 static uword Hash(const FunctionName& name) { return name.Hash(); } |
2243 }; | 2195 }; |
2244 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; | 2196 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; |
2245 | 2197 |
2246 | |
2247 void Class::SetFunctions(const Array& value) const { | 2198 void Class::SetFunctions(const Array& value) const { |
2248 ASSERT(Thread::Current()->IsMutatorThread()); | 2199 ASSERT(Thread::Current()->IsMutatorThread()); |
2249 ASSERT(!value.IsNull()); | 2200 ASSERT(!value.IsNull()); |
2250 StorePointer(&raw_ptr()->functions_, value.raw()); | 2201 StorePointer(&raw_ptr()->functions_, value.raw()); |
2251 const intptr_t len = value.Length(); | 2202 const intptr_t len = value.Length(); |
2252 if (len >= kFunctionLookupHashTreshold) { | 2203 if (len >= kFunctionLookupHashTreshold) { |
2253 ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld)); | 2204 ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld)); |
2254 Function& func = Function::Handle(); | 2205 Function& func = Function::Handle(); |
2255 for (intptr_t i = 0; i < len; ++i) { | 2206 for (intptr_t i = 0; i < len; ++i) { |
2256 func ^= value.At(i); | 2207 func ^= value.At(i); |
2257 // Verify that all the functions in the array have this class as owner. | 2208 // Verify that all the functions in the array have this class as owner. |
2258 ASSERT(func.Owner() == raw()); | 2209 ASSERT(func.Owner() == raw()); |
2259 set.Insert(func); | 2210 set.Insert(func); |
2260 } | 2211 } |
2261 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); | 2212 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); |
2262 } else { | 2213 } else { |
2263 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); | 2214 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); |
2264 } | 2215 } |
2265 } | 2216 } |
2266 | 2217 |
2267 | |
2268 void Class::AddFunction(const Function& function) const { | 2218 void Class::AddFunction(const Function& function) const { |
2269 ASSERT(Thread::Current()->IsMutatorThread()); | 2219 ASSERT(Thread::Current()->IsMutatorThread()); |
2270 const Array& arr = Array::Handle(functions()); | 2220 const Array& arr = Array::Handle(functions()); |
2271 const Array& new_arr = | 2221 const Array& new_arr = |
2272 Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); | 2222 Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); |
2273 new_arr.SetAt(arr.Length(), function); | 2223 new_arr.SetAt(arr.Length(), function); |
2274 StorePointer(&raw_ptr()->functions_, new_arr.raw()); | 2224 StorePointer(&raw_ptr()->functions_, new_arr.raw()); |
2275 // Add to hash table, if any. | 2225 // Add to hash table, if any. |
2276 const intptr_t new_len = new_arr.Length(); | 2226 const intptr_t new_len = new_arr.Length(); |
2277 if (new_len == kFunctionLookupHashTreshold) { | 2227 if (new_len == kFunctionLookupHashTreshold) { |
2278 // Transition to using hash table. | 2228 // Transition to using hash table. |
2279 SetFunctions(new_arr); | 2229 SetFunctions(new_arr); |
2280 } else if (new_len > kFunctionLookupHashTreshold) { | 2230 } else if (new_len > kFunctionLookupHashTreshold) { |
2281 ClassFunctionsSet set(raw_ptr()->functions_hash_table_); | 2231 ClassFunctionsSet set(raw_ptr()->functions_hash_table_); |
2282 set.Insert(function); | 2232 set.Insert(function); |
2283 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); | 2233 StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); |
2284 } | 2234 } |
2285 } | 2235 } |
2286 | 2236 |
2287 | |
2288 void Class::RemoveFunction(const Function& function) const { | 2237 void Class::RemoveFunction(const Function& function) const { |
2289 ASSERT(Thread::Current()->IsMutatorThread()); | 2238 ASSERT(Thread::Current()->IsMutatorThread()); |
2290 const Array& arr = Array::Handle(functions()); | 2239 const Array& arr = Array::Handle(functions()); |
2291 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); | 2240 StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |
2292 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); | 2241 StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); |
2293 Function& entry = Function::Handle(); | 2242 Function& entry = Function::Handle(); |
2294 for (intptr_t i = 0; i < arr.Length(); i++) { | 2243 for (intptr_t i = 0; i < arr.Length(); i++) { |
2295 entry ^= arr.At(i); | 2244 entry ^= arr.At(i); |
2296 if (function.raw() != entry.raw()) { | 2245 if (function.raw() != entry.raw()) { |
2297 AddFunction(entry); | 2246 AddFunction(entry); |
2298 } | 2247 } |
2299 } | 2248 } |
2300 } | 2249 } |
2301 | 2250 |
2302 | |
2303 RawFunction* Class::FunctionFromIndex(intptr_t idx) const { | 2251 RawFunction* Class::FunctionFromIndex(intptr_t idx) const { |
2304 const Array& funcs = Array::Handle(functions()); | 2252 const Array& funcs = Array::Handle(functions()); |
2305 if ((idx < 0) || (idx >= funcs.Length())) { | 2253 if ((idx < 0) || (idx >= funcs.Length())) { |
2306 return Function::null(); | 2254 return Function::null(); |
2307 } | 2255 } |
2308 Function& func = Function::Handle(); | 2256 Function& func = Function::Handle(); |
2309 func ^= funcs.At(idx); | 2257 func ^= funcs.At(idx); |
2310 ASSERT(!func.IsNull()); | 2258 ASSERT(!func.IsNull()); |
2311 return func.raw(); | 2259 return func.raw(); |
2312 } | 2260 } |
2313 | 2261 |
2314 | |
2315 RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const { | 2262 RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const { |
2316 const Array& funcs = Array::Handle(functions()); | 2263 const Array& funcs = Array::Handle(functions()); |
2317 if ((idx < 0) || (idx >= funcs.Length())) { | 2264 if ((idx < 0) || (idx >= funcs.Length())) { |
2318 return Function::null(); | 2265 return Function::null(); |
2319 } | 2266 } |
2320 Function& func = Function::Handle(); | 2267 Function& func = Function::Handle(); |
2321 func ^= funcs.At(idx); | 2268 func ^= funcs.At(idx); |
2322 ASSERT(!func.IsNull()); | 2269 ASSERT(!func.IsNull()); |
2323 if (!func.HasImplicitClosureFunction()) { | 2270 if (!func.HasImplicitClosureFunction()) { |
2324 return Function::null(); | 2271 return Function::null(); |
2325 } | 2272 } |
2326 const Function& closure_func = | 2273 const Function& closure_func = |
2327 Function::Handle(func.ImplicitClosureFunction()); | 2274 Function::Handle(func.ImplicitClosureFunction()); |
2328 ASSERT(!closure_func.IsNull()); | 2275 ASSERT(!closure_func.IsNull()); |
2329 return closure_func.raw(); | 2276 return closure_func.raw(); |
2330 } | 2277 } |
2331 | 2278 |
2332 | |
2333 intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const { | 2279 intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const { |
2334 Thread* thread = Thread::Current(); | 2280 Thread* thread = Thread::Current(); |
2335 if (EnsureIsFinalized(thread) != Error::null()) { | 2281 if (EnsureIsFinalized(thread) != Error::null()) { |
2336 return -1; | 2282 return -1; |
2337 } | 2283 } |
2338 REUSABLE_ARRAY_HANDLESCOPE(thread); | 2284 REUSABLE_ARRAY_HANDLESCOPE(thread); |
2339 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 2285 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
2340 Array& funcs = thread->ArrayHandle(); | 2286 Array& funcs = thread->ArrayHandle(); |
2341 Function& function = thread->FunctionHandle(); | 2287 Function& function = thread->FunctionHandle(); |
2342 funcs ^= functions(); | 2288 funcs ^= functions(); |
2343 ASSERT(!funcs.IsNull()); | 2289 ASSERT(!funcs.IsNull()); |
2344 Function& implicit_closure = Function::Handle(thread->zone()); | 2290 Function& implicit_closure = Function::Handle(thread->zone()); |
2345 const intptr_t len = funcs.Length(); | 2291 const intptr_t len = funcs.Length(); |
2346 for (intptr_t i = 0; i < len; i++) { | 2292 for (intptr_t i = 0; i < len; i++) { |
2347 function ^= funcs.At(i); | 2293 function ^= funcs.At(i); |
2348 implicit_closure ^= function.implicit_closure_function(); | 2294 implicit_closure ^= function.implicit_closure_function(); |
2349 if (implicit_closure.IsNull()) { | 2295 if (implicit_closure.IsNull()) { |
2350 // Skip non-implicit closure functions. | 2296 // Skip non-implicit closure functions. |
2351 continue; | 2297 continue; |
2352 } | 2298 } |
2353 if (needle.raw() == implicit_closure.raw()) { | 2299 if (needle.raw() == implicit_closure.raw()) { |
2354 return i; | 2300 return i; |
2355 } | 2301 } |
2356 } | 2302 } |
2357 // No function found. | 2303 // No function found. |
2358 return -1; | 2304 return -1; |
2359 } | 2305 } |
2360 | 2306 |
2361 | |
2362 intptr_t Class::FindInvocationDispatcherFunctionIndex( | 2307 intptr_t Class::FindInvocationDispatcherFunctionIndex( |
2363 const Function& needle) const { | 2308 const Function& needle) const { |
2364 Thread* thread = Thread::Current(); | 2309 Thread* thread = Thread::Current(); |
2365 if (EnsureIsFinalized(thread) != Error::null()) { | 2310 if (EnsureIsFinalized(thread) != Error::null()) { |
2366 return -1; | 2311 return -1; |
2367 } | 2312 } |
2368 REUSABLE_ARRAY_HANDLESCOPE(thread); | 2313 REUSABLE_ARRAY_HANDLESCOPE(thread); |
2369 REUSABLE_OBJECT_HANDLESCOPE(thread); | 2314 REUSABLE_OBJECT_HANDLESCOPE(thread); |
2370 Array& funcs = thread->ArrayHandle(); | 2315 Array& funcs = thread->ArrayHandle(); |
2371 Object& object = thread->ObjectHandle(); | 2316 Object& object = thread->ObjectHandle(); |
2372 funcs ^= invocation_dispatcher_cache(); | 2317 funcs ^= invocation_dispatcher_cache(); |
2373 ASSERT(!funcs.IsNull()); | 2318 ASSERT(!funcs.IsNull()); |
2374 const intptr_t len = funcs.Length(); | 2319 const intptr_t len = funcs.Length(); |
2375 for (intptr_t i = 0; i < len; i++) { | 2320 for (intptr_t i = 0; i < len; i++) { |
2376 object = funcs.At(i); | 2321 object = funcs.At(i); |
2377 // The invocation_dispatcher_cache is a table with some entries that | 2322 // The invocation_dispatcher_cache is a table with some entries that |
2378 // are functions. | 2323 // are functions. |
2379 if (object.IsFunction()) { | 2324 if (object.IsFunction()) { |
2380 if (Function::Cast(object).raw() == needle.raw()) { | 2325 if (Function::Cast(object).raw() == needle.raw()) { |
2381 return i; | 2326 return i; |
2382 } | 2327 } |
2383 } | 2328 } |
2384 } | 2329 } |
2385 // No function found. | 2330 // No function found. |
2386 return -1; | 2331 return -1; |
2387 } | 2332 } |
2388 | 2333 |
2389 | |
2390 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const { | 2334 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const { |
2391 Thread* thread = Thread::Current(); | 2335 Thread* thread = Thread::Current(); |
2392 REUSABLE_ARRAY_HANDLESCOPE(thread); | 2336 REUSABLE_ARRAY_HANDLESCOPE(thread); |
2393 REUSABLE_OBJECT_HANDLESCOPE(thread); | 2337 REUSABLE_OBJECT_HANDLESCOPE(thread); |
2394 Array& dispatcher_cache = thread->ArrayHandle(); | 2338 Array& dispatcher_cache = thread->ArrayHandle(); |
2395 Object& object = thread->ObjectHandle(); | 2339 Object& object = thread->ObjectHandle(); |
2396 dispatcher_cache ^= invocation_dispatcher_cache(); | 2340 dispatcher_cache ^= invocation_dispatcher_cache(); |
2397 object = dispatcher_cache.At(idx); | 2341 object = dispatcher_cache.At(idx); |
2398 if (!object.IsFunction()) { | 2342 if (!object.IsFunction()) { |
2399 return Function::null(); | 2343 return Function::null(); |
2400 } | 2344 } |
2401 return Function::Cast(object).raw(); | 2345 return Function::Cast(object).raw(); |
2402 } | 2346 } |
2403 | 2347 |
2404 | |
2405 void Class::set_signature_function(const Function& value) const { | 2348 void Class::set_signature_function(const Function& value) const { |
2406 ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); | 2349 ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); |
2407 StorePointer(&raw_ptr()->signature_function_, value.raw()); | 2350 StorePointer(&raw_ptr()->signature_function_, value.raw()); |
2408 } | 2351 } |
2409 | 2352 |
2410 | |
2411 void Class::set_state_bits(intptr_t bits) const { | 2353 void Class::set_state_bits(intptr_t bits) const { |
2412 StoreNonPointer(&raw_ptr()->state_bits_, static_cast<uint16_t>(bits)); | 2354 StoreNonPointer(&raw_ptr()->state_bits_, static_cast<uint16_t>(bits)); |
2413 } | 2355 } |
2414 | 2356 |
2415 | |
2416 void Class::set_library(const Library& value) const { | 2357 void Class::set_library(const Library& value) const { |
2417 StorePointer(&raw_ptr()->library_, value.raw()); | 2358 StorePointer(&raw_ptr()->library_, value.raw()); |
2418 } | 2359 } |
2419 | 2360 |
2420 | |
2421 void Class::set_type_parameters(const TypeArguments& value) const { | 2361 void Class::set_type_parameters(const TypeArguments& value) const { |
2422 StorePointer(&raw_ptr()->type_parameters_, value.raw()); | 2362 StorePointer(&raw_ptr()->type_parameters_, value.raw()); |
2423 } | 2363 } |
2424 | 2364 |
2425 | |
2426 intptr_t Class::NumTypeParameters(Thread* thread) const { | 2365 intptr_t Class::NumTypeParameters(Thread* thread) const { |
2427 if (IsMixinApplication() && !is_mixin_type_applied()) { | 2366 if (IsMixinApplication() && !is_mixin_type_applied()) { |
2428 ClassFinalizer::ApplyMixinType(*this); | 2367 ClassFinalizer::ApplyMixinType(*this); |
2429 } | 2368 } |
2430 if (type_parameters() == TypeArguments::null()) { | 2369 if (type_parameters() == TypeArguments::null()) { |
2431 const intptr_t cid = id(); | 2370 const intptr_t cid = id(); |
2432 if ((cid == kArrayCid) || (cid == kImmutableArrayCid) || | 2371 if ((cid == kArrayCid) || (cid == kImmutableArrayCid) || |
2433 (cid == kGrowableObjectArrayCid)) { | 2372 (cid == kGrowableObjectArrayCid)) { |
2434 return 1; // List's type parameter may not have been parsed yet. | 2373 return 1; // List's type parameter may not have been parsed yet. |
2435 } | 2374 } |
2436 return 0; | 2375 return 0; |
2437 } | 2376 } |
2438 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 2377 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
2439 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 2378 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
2440 type_params = type_parameters(); | 2379 type_params = type_parameters(); |
2441 return type_params.Length(); | 2380 return type_params.Length(); |
2442 } | 2381 } |
2443 | 2382 |
2444 | |
2445 intptr_t Class::NumOwnTypeArguments() const { | 2383 intptr_t Class::NumOwnTypeArguments() const { |
2446 // Return cached value if already calculated. | 2384 // Return cached value if already calculated. |
2447 if (num_own_type_arguments() != kUnknownNumTypeArguments) { | 2385 if (num_own_type_arguments() != kUnknownNumTypeArguments) { |
2448 return num_own_type_arguments(); | 2386 return num_own_type_arguments(); |
2449 } | 2387 } |
2450 Thread* thread = Thread::Current(); | 2388 Thread* thread = Thread::Current(); |
2451 Isolate* isolate = thread->isolate(); | 2389 Isolate* isolate = thread->isolate(); |
2452 Zone* zone = thread->zone(); | 2390 Zone* zone = thread->zone(); |
2453 const intptr_t num_type_params = NumTypeParameters(); | 2391 const intptr_t num_type_params = NumTypeParameters(); |
2454 if (!FLAG_overlap_type_arguments || (num_type_params == 0) || | 2392 if (!FLAG_overlap_type_arguments || (num_type_params == 0) || |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 // Overlap found. | 2446 // Overlap found. |
2509 set_num_own_type_arguments(num_type_params - num_overlapping_type_args); | 2447 set_num_own_type_arguments(num_type_params - num_overlapping_type_args); |
2510 return num_type_params - num_overlapping_type_args; | 2448 return num_type_params - num_overlapping_type_args; |
2511 } | 2449 } |
2512 } | 2450 } |
2513 // No overlap found. | 2451 // No overlap found. |
2514 set_num_own_type_arguments(num_type_params); | 2452 set_num_own_type_arguments(num_type_params); |
2515 return num_type_params; | 2453 return num_type_params; |
2516 } | 2454 } |
2517 | 2455 |
2518 | |
2519 intptr_t Class::NumTypeArguments() const { | 2456 intptr_t Class::NumTypeArguments() const { |
2520 // Return cached value if already calculated. | 2457 // Return cached value if already calculated. |
2521 if (num_type_arguments() != kUnknownNumTypeArguments) { | 2458 if (num_type_arguments() != kUnknownNumTypeArguments) { |
2522 return num_type_arguments(); | 2459 return num_type_arguments(); |
2523 } | 2460 } |
2524 // To work properly, this call requires the super class of this class to be | 2461 // To work properly, this call requires the super class of this class to be |
2525 // resolved, which is checked by the type_class() call on the super type. | 2462 // resolved, which is checked by the type_class() call on the super type. |
2526 // Note that calling type_class() on a MixinAppType fails. | 2463 // Note that calling type_class() on a MixinAppType fails. |
2527 Thread* thread = Thread::Current(); | 2464 Thread* thread = Thread::Current(); |
2528 Zone* zone = thread->zone(); | 2465 Zone* zone = thread->zone(); |
(...skipping 16 matching lines...) Expand all Loading... |
2545 // sup_type, but not as sup_type itself. | 2482 // sup_type, but not as sup_type itself. |
2546 ASSERT(sup_type.IsType()); | 2483 ASSERT(sup_type.IsType()); |
2547 ClassFinalizer::ResolveTypeClass(cls, Type::Cast(sup_type)); | 2484 ClassFinalizer::ResolveTypeClass(cls, Type::Cast(sup_type)); |
2548 cls = sup_type.type_class(); | 2485 cls = sup_type.type_class(); |
2549 ASSERT(!cls.IsTypedefClass()); | 2486 ASSERT(!cls.IsTypedefClass()); |
2550 } while (true); | 2487 } while (true); |
2551 set_num_type_arguments(num_type_args); | 2488 set_num_type_arguments(num_type_args); |
2552 return num_type_args; | 2489 return num_type_args; |
2553 } | 2490 } |
2554 | 2491 |
2555 | |
2556 RawClass* Class::SuperClass(bool original_classes) const { | 2492 RawClass* Class::SuperClass(bool original_classes) const { |
2557 Thread* thread = Thread::Current(); | 2493 Thread* thread = Thread::Current(); |
2558 Zone* zone = thread->zone(); | 2494 Zone* zone = thread->zone(); |
2559 Isolate* isolate = thread->isolate(); | 2495 Isolate* isolate = thread->isolate(); |
2560 if (super_type() == AbstractType::null()) { | 2496 if (super_type() == AbstractType::null()) { |
2561 return Class::null(); | 2497 return Class::null(); |
2562 } | 2498 } |
2563 const AbstractType& sup_type = AbstractType::Handle(zone, super_type()); | 2499 const AbstractType& sup_type = AbstractType::Handle(zone, super_type()); |
2564 const intptr_t type_class_id = sup_type.type_class_id(); | 2500 const intptr_t type_class_id = sup_type.type_class_id(); |
2565 if (original_classes) { | 2501 if (original_classes) { |
2566 return isolate->GetClassForHeapWalkAt(type_class_id); | 2502 return isolate->GetClassForHeapWalkAt(type_class_id); |
2567 } else { | 2503 } else { |
2568 return isolate->class_table()->At(type_class_id); | 2504 return isolate->class_table()->At(type_class_id); |
2569 } | 2505 } |
2570 } | 2506 } |
2571 | 2507 |
2572 | |
2573 void Class::set_super_type(const AbstractType& value) const { | 2508 void Class::set_super_type(const AbstractType& value) const { |
2574 ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()) || | 2509 ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()) || |
2575 value.IsMixinAppType()); | 2510 value.IsMixinAppType()); |
2576 StorePointer(&raw_ptr()->super_type_, value.raw()); | 2511 StorePointer(&raw_ptr()->super_type_, value.raw()); |
2577 } | 2512 } |
2578 | 2513 |
2579 | |
2580 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { | 2514 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { |
2581 ASSERT(!type_name.IsNull()); | 2515 ASSERT(!type_name.IsNull()); |
2582 Thread* thread = Thread::Current(); | 2516 Thread* thread = Thread::Current(); |
2583 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 2517 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
2584 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); | 2518 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |
2585 REUSABLE_STRING_HANDLESCOPE(thread); | 2519 REUSABLE_STRING_HANDLESCOPE(thread); |
2586 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 2520 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
2587 TypeParameter& type_param = thread->TypeParameterHandle(); | 2521 TypeParameter& type_param = thread->TypeParameterHandle(); |
2588 String& type_param_name = thread->StringHandle(); | 2522 String& type_param_name = thread->StringHandle(); |
2589 | 2523 |
2590 type_params ^= type_parameters(); | 2524 type_params ^= type_parameters(); |
2591 if (!type_params.IsNull()) { | 2525 if (!type_params.IsNull()) { |
2592 const intptr_t num_type_params = type_params.Length(); | 2526 const intptr_t num_type_params = type_params.Length(); |
2593 for (intptr_t i = 0; i < num_type_params; i++) { | 2527 for (intptr_t i = 0; i < num_type_params; i++) { |
2594 type_param ^= type_params.TypeAt(i); | 2528 type_param ^= type_params.TypeAt(i); |
2595 type_param_name = type_param.name(); | 2529 type_param_name = type_param.name(); |
2596 if (type_param_name.Equals(type_name)) { | 2530 if (type_param_name.Equals(type_name)) { |
2597 return type_param.raw(); | 2531 return type_param.raw(); |
2598 } | 2532 } |
2599 } | 2533 } |
2600 } | 2534 } |
2601 return TypeParameter::null(); | 2535 return TypeParameter::null(); |
2602 } | 2536 } |
2603 | 2537 |
2604 | |
2605 void Class::CalculateFieldOffsets() const { | 2538 void Class::CalculateFieldOffsets() const { |
2606 Array& flds = Array::Handle(fields()); | 2539 Array& flds = Array::Handle(fields()); |
2607 const Class& super = Class::Handle(SuperClass()); | 2540 const Class& super = Class::Handle(SuperClass()); |
2608 intptr_t offset = 0; | 2541 intptr_t offset = 0; |
2609 intptr_t type_args_field_offset = kNoTypeArguments; | 2542 intptr_t type_args_field_offset = kNoTypeArguments; |
2610 if (super.IsNull()) { | 2543 if (super.IsNull()) { |
2611 offset = Instance::NextFieldOffset(); | 2544 offset = Instance::NextFieldOffset(); |
2612 ASSERT(offset > 0); | 2545 ASSERT(offset > 0); |
2613 } else { | 2546 } else { |
2614 ASSERT(super.is_finalized() || super.is_prefinalized()); | 2547 ASSERT(super.is_finalized() || super.is_prefinalized()); |
(...skipping 27 matching lines...) Expand all Loading... |
2642 if (!field.is_static()) { | 2575 if (!field.is_static()) { |
2643 ASSERT(field.Offset() == 0); | 2576 ASSERT(field.Offset() == 0); |
2644 field.SetOffset(offset); | 2577 field.SetOffset(offset); |
2645 offset += kWordSize; | 2578 offset += kWordSize; |
2646 } | 2579 } |
2647 } | 2580 } |
2648 set_instance_size(RoundedAllocationSize(offset)); | 2581 set_instance_size(RoundedAllocationSize(offset)); |
2649 set_next_field_offset(offset); | 2582 set_next_field_offset(offset); |
2650 } | 2583 } |
2651 | 2584 |
2652 | |
2653 RawFunction* Class::GetInvocationDispatcher(const String& target_name, | 2585 RawFunction* Class::GetInvocationDispatcher(const String& target_name, |
2654 const Array& args_desc, | 2586 const Array& args_desc, |
2655 RawFunction::Kind kind, | 2587 RawFunction::Kind kind, |
2656 bool create_if_absent) const { | 2588 bool create_if_absent) const { |
2657 enum { kNameIndex = 0, kArgsDescIndex, kFunctionIndex, kEntrySize }; | 2589 enum { kNameIndex = 0, kArgsDescIndex, kFunctionIndex, kEntrySize }; |
2658 | 2590 |
2659 ASSERT(kind == RawFunction::kNoSuchMethodDispatcher || | 2591 ASSERT(kind == RawFunction::kNoSuchMethodDispatcher || |
2660 kind == RawFunction::kInvokeFieldDispatcher); | 2592 kind == RawFunction::kInvokeFieldDispatcher); |
2661 Function& dispatcher = Function::Handle(); | 2593 Function& dispatcher = Function::Handle(); |
2662 Array& cache = Array::Handle(invocation_dispatcher_cache()); | 2594 Array& cache = Array::Handle(invocation_dispatcher_cache()); |
(...skipping 25 matching lines...) Expand all Loading... |
2688 set_invocation_dispatcher_cache(cache); | 2620 set_invocation_dispatcher_cache(cache); |
2689 } | 2621 } |
2690 dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind); | 2622 dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind); |
2691 cache.SetAt(i + kNameIndex, target_name); | 2623 cache.SetAt(i + kNameIndex, target_name); |
2692 cache.SetAt(i + kArgsDescIndex, args_desc); | 2624 cache.SetAt(i + kArgsDescIndex, args_desc); |
2693 cache.SetAt(i + kFunctionIndex, dispatcher); | 2625 cache.SetAt(i + kFunctionIndex, dispatcher); |
2694 } | 2626 } |
2695 return dispatcher.raw(); | 2627 return dispatcher.raw(); |
2696 } | 2628 } |
2697 | 2629 |
2698 | |
2699 RawFunction* Class::CreateInvocationDispatcher(const String& target_name, | 2630 RawFunction* Class::CreateInvocationDispatcher(const String& target_name, |
2700 const Array& args_desc, | 2631 const Array& args_desc, |
2701 RawFunction::Kind kind) const { | 2632 RawFunction::Kind kind) const { |
2702 Thread* thread = Thread::Current(); | 2633 Thread* thread = Thread::Current(); |
2703 Zone* zone = thread->zone(); | 2634 Zone* zone = thread->zone(); |
2704 Function& invocation = Function::Handle( | 2635 Function& invocation = Function::Handle( |
2705 zone, Function::New( | 2636 zone, Function::New( |
2706 String::Handle(zone, Symbols::New(thread, target_name)), kind, | 2637 String::Handle(zone, Symbols::New(thread, target_name)), kind, |
2707 false, // Not static. | 2638 false, // Not static. |
2708 false, // Not const. | 2639 false, // Not const. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 } | 2678 } |
2748 invocation.set_result_type(Object::dynamic_type()); | 2679 invocation.set_result_type(Object::dynamic_type()); |
2749 invocation.set_is_debuggable(false); | 2680 invocation.set_is_debuggable(false); |
2750 invocation.set_is_visible(false); | 2681 invocation.set_is_visible(false); |
2751 invocation.set_is_reflectable(false); | 2682 invocation.set_is_reflectable(false); |
2752 invocation.set_saved_args_desc(args_desc); | 2683 invocation.set_saved_args_desc(args_desc); |
2753 | 2684 |
2754 return invocation.raw(); | 2685 return invocation.raw(); |
2755 } | 2686 } |
2756 | 2687 |
2757 | |
2758 // Method extractors are used to create implicit closures from methods. | 2688 // Method extractors are used to create implicit closures from methods. |
2759 // When an expression obj.M is evaluated for the first time and receiver obj | 2689 // When an expression obj.M is evaluated for the first time and receiver obj |
2760 // does not have a getter called M but has a method called M then an extractor | 2690 // does not have a getter called M but has a method called M then an extractor |
2761 // is created and injected as a getter (under the name get:M) into the class | 2691 // is created and injected as a getter (under the name get:M) into the class |
2762 // owning method M. | 2692 // owning method M. |
2763 RawFunction* Function::CreateMethodExtractor(const String& getter_name) const { | 2693 RawFunction* Function::CreateMethodExtractor(const String& getter_name) const { |
2764 Thread* thread = Thread::Current(); | 2694 Thread* thread = Thread::Current(); |
2765 Zone* zone = thread->zone(); | 2695 Zone* zone = thread->zone(); |
2766 ASSERT(Field::IsGetterName(getter_name)); | 2696 ASSERT(Field::IsGetterName(getter_name)); |
2767 const Function& closure_function = | 2697 const Function& closure_function = |
(...skipping 22 matching lines...) Expand all Loading... |
2790 | 2720 |
2791 extractor.set_extracted_method_closure(closure_function); | 2721 extractor.set_extracted_method_closure(closure_function); |
2792 extractor.set_is_debuggable(false); | 2722 extractor.set_is_debuggable(false); |
2793 extractor.set_is_visible(false); | 2723 extractor.set_is_visible(false); |
2794 | 2724 |
2795 owner.AddFunction(extractor); | 2725 owner.AddFunction(extractor); |
2796 | 2726 |
2797 return extractor.raw(); | 2727 return extractor.raw(); |
2798 } | 2728 } |
2799 | 2729 |
2800 | |
2801 RawFunction* Function::GetMethodExtractor(const String& getter_name) const { | 2730 RawFunction* Function::GetMethodExtractor(const String& getter_name) const { |
2802 ASSERT(Field::IsGetterName(getter_name)); | 2731 ASSERT(Field::IsGetterName(getter_name)); |
2803 const Function& closure_function = | 2732 const Function& closure_function = |
2804 Function::Handle(ImplicitClosureFunction()); | 2733 Function::Handle(ImplicitClosureFunction()); |
2805 const Class& owner = Class::Handle(closure_function.Owner()); | 2734 const Class& owner = Class::Handle(closure_function.Owner()); |
2806 Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name)); | 2735 Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name)); |
2807 if (result.IsNull()) { | 2736 if (result.IsNull()) { |
2808 result ^= CreateMethodExtractor(getter_name); | 2737 result ^= CreateMethodExtractor(getter_name); |
2809 } | 2738 } |
2810 ASSERT(result.kind() == RawFunction::kMethodExtractor); | 2739 ASSERT(result.kind() == RawFunction::kMethodExtractor); |
2811 return result.raw(); | 2740 return result.raw(); |
2812 } | 2741 } |
2813 | 2742 |
2814 | |
2815 RawArray* Class::invocation_dispatcher_cache() const { | 2743 RawArray* Class::invocation_dispatcher_cache() const { |
2816 return raw_ptr()->invocation_dispatcher_cache_; | 2744 return raw_ptr()->invocation_dispatcher_cache_; |
2817 } | 2745 } |
2818 | 2746 |
2819 | |
2820 void Class::set_invocation_dispatcher_cache(const Array& cache) const { | 2747 void Class::set_invocation_dispatcher_cache(const Array& cache) const { |
2821 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw()); | 2748 StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw()); |
2822 } | 2749 } |
2823 | 2750 |
2824 | |
2825 void Class::Finalize() const { | 2751 void Class::Finalize() const { |
2826 ASSERT(Thread::Current()->IsMutatorThread()); | 2752 ASSERT(Thread::Current()->IsMutatorThread()); |
2827 ASSERT(!Isolate::Current()->all_classes_finalized()); | 2753 ASSERT(!Isolate::Current()->all_classes_finalized()); |
2828 ASSERT(!is_finalized()); | 2754 ASSERT(!is_finalized()); |
2829 // Prefinalized classes have a VM internal representation and no Dart fields. | 2755 // Prefinalized classes have a VM internal representation and no Dart fields. |
2830 // Their instance size is precomputed and field offsets are known. | 2756 // Their instance size is precomputed and field offsets are known. |
2831 if (!is_prefinalized()) { | 2757 if (!is_prefinalized()) { |
2832 // Compute offsets of instance fields and instance size. | 2758 // Compute offsets of instance fields and instance size. |
2833 CalculateFieldOffsets(); | 2759 CalculateFieldOffsets(); |
2834 } | 2760 } |
2835 set_is_finalized(); | 2761 set_is_finalized(); |
2836 } | 2762 } |
2837 | 2763 |
2838 | |
2839 class CHACodeArray : public WeakCodeReferences { | 2764 class CHACodeArray : public WeakCodeReferences { |
2840 public: | 2765 public: |
2841 explicit CHACodeArray(const Class& cls) | 2766 explicit CHACodeArray(const Class& cls) |
2842 : WeakCodeReferences(Array::Handle(cls.dependent_code())), cls_(cls) {} | 2767 : WeakCodeReferences(Array::Handle(cls.dependent_code())), cls_(cls) {} |
2843 | 2768 |
2844 virtual void UpdateArrayTo(const Array& value) { | 2769 virtual void UpdateArrayTo(const Array& value) { |
2845 // TODO(fschneider): Fails for classes in the VM isolate. | 2770 // TODO(fschneider): Fails for classes in the VM isolate. |
2846 cls_.set_dependent_code(value); | 2771 cls_.set_dependent_code(value); |
2847 } | 2772 } |
2848 | 2773 |
(...skipping 13 matching lines...) Expand all Loading... |
2862 " (%s)\n", | 2787 " (%s)\n", |
2863 function.ToFullyQualifiedCString(), cls_.ToCString()); | 2788 function.ToFullyQualifiedCString(), cls_.ToCString()); |
2864 } | 2789 } |
2865 } | 2790 } |
2866 | 2791 |
2867 private: | 2792 private: |
2868 const Class& cls_; | 2793 const Class& cls_; |
2869 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); | 2794 DISALLOW_COPY_AND_ASSIGN(CHACodeArray); |
2870 }; | 2795 }; |
2871 | 2796 |
2872 | |
2873 #if defined(DEBUG) | 2797 #if defined(DEBUG) |
2874 static bool IsMutatorOrAtSafepoint() { | 2798 static bool IsMutatorOrAtSafepoint() { |
2875 Thread* thread = Thread::Current(); | 2799 Thread* thread = Thread::Current(); |
2876 return thread->IsMutatorThread() || thread->IsAtSafepoint(); | 2800 return thread->IsMutatorThread() || thread->IsAtSafepoint(); |
2877 } | 2801 } |
2878 #endif | 2802 #endif |
2879 | 2803 |
2880 | |
2881 void Class::RegisterCHACode(const Code& code) { | 2804 void Class::RegisterCHACode(const Code& code) { |
2882 if (FLAG_trace_cha) { | 2805 if (FLAG_trace_cha) { |
2883 THR_Print("RegisterCHACode '%s' depends on class '%s'\n", | 2806 THR_Print("RegisterCHACode '%s' depends on class '%s'\n", |
2884 Function::Handle(code.function()).ToQualifiedCString(), | 2807 Function::Handle(code.function()).ToQualifiedCString(), |
2885 ToCString()); | 2808 ToCString()); |
2886 } | 2809 } |
2887 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 2810 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
2888 ASSERT(code.is_optimized()); | 2811 ASSERT(code.is_optimized()); |
2889 CHACodeArray a(*this); | 2812 CHACodeArray a(*this); |
2890 a.Register(code); | 2813 a.Register(code); |
2891 } | 2814 } |
2892 | 2815 |
2893 | |
2894 void Class::DisableCHAOptimizedCode(const Class& subclass) { | 2816 void Class::DisableCHAOptimizedCode(const Class& subclass) { |
2895 ASSERT(Thread::Current()->IsMutatorThread()); | 2817 ASSERT(Thread::Current()->IsMutatorThread()); |
2896 CHACodeArray a(*this); | 2818 CHACodeArray a(*this); |
2897 if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) { | 2819 if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) { |
2898 THR_Print("Adding subclass %s\n", subclass.ToCString()); | 2820 THR_Print("Adding subclass %s\n", subclass.ToCString()); |
2899 } | 2821 } |
2900 a.DisableCode(); | 2822 a.DisableCode(); |
2901 } | 2823 } |
2902 | 2824 |
2903 | |
2904 void Class::DisableAllCHAOptimizedCode() { | 2825 void Class::DisableAllCHAOptimizedCode() { |
2905 DisableCHAOptimizedCode(Class::Handle()); | 2826 DisableCHAOptimizedCode(Class::Handle()); |
2906 } | 2827 } |
2907 | 2828 |
2908 | |
2909 bool Class::TraceAllocation(Isolate* isolate) const { | 2829 bool Class::TraceAllocation(Isolate* isolate) const { |
2910 #ifndef PRODUCT | 2830 #ifndef PRODUCT |
2911 ClassTable* class_table = isolate->class_table(); | 2831 ClassTable* class_table = isolate->class_table(); |
2912 return class_table->TraceAllocationFor(id()); | 2832 return class_table->TraceAllocationFor(id()); |
2913 #else | 2833 #else |
2914 return false; | 2834 return false; |
2915 #endif | 2835 #endif |
2916 } | 2836 } |
2917 | 2837 |
2918 | |
2919 void Class::SetTraceAllocation(bool trace_allocation) const { | 2838 void Class::SetTraceAllocation(bool trace_allocation) const { |
2920 #ifndef PRODUCT | 2839 #ifndef PRODUCT |
2921 Isolate* isolate = Isolate::Current(); | 2840 Isolate* isolate = Isolate::Current(); |
2922 const bool changed = trace_allocation != this->TraceAllocation(isolate); | 2841 const bool changed = trace_allocation != this->TraceAllocation(isolate); |
2923 if (changed) { | 2842 if (changed) { |
2924 ClassTable* class_table = isolate->class_table(); | 2843 ClassTable* class_table = isolate->class_table(); |
2925 class_table->SetTraceAllocationFor(id(), trace_allocation); | 2844 class_table->SetTraceAllocationFor(id(), trace_allocation); |
2926 DisableAllocationStub(); | 2845 DisableAllocationStub(); |
2927 } | 2846 } |
2928 #else | 2847 #else |
2929 UNREACHABLE(); | 2848 UNREACHABLE(); |
2930 #endif | 2849 #endif |
2931 } | 2850 } |
2932 | 2851 |
2933 | |
2934 bool Class::ValidatePostFinalizePatch(const Class& orig_class, | 2852 bool Class::ValidatePostFinalizePatch(const Class& orig_class, |
2935 Error* error) const { | 2853 Error* error) const { |
2936 ASSERT(error != NULL); | 2854 ASSERT(error != NULL); |
2937 // Not allowed to add new fields in a post finalization patch. | 2855 // Not allowed to add new fields in a post finalization patch. |
2938 if (fields() != Object::empty_array().raw()) { | 2856 if (fields() != Object::empty_array().raw()) { |
2939 *error = LanguageError::NewFormatted( | 2857 *error = LanguageError::NewFormatted( |
2940 *error, // No previous error. | 2858 *error, // No previous error. |
2941 Script::Handle(script()), token_pos(), Report::AtLocation, | 2859 Script::Handle(script()), token_pos(), Report::AtLocation, |
2942 Report::kError, Heap::kNew, | 2860 Report::kError, Heap::kNew, |
2943 "new fields are not allowed for this patch"); | 2861 "new fields are not allowed for this patch"); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2985 Script::Handle(script()), token_pos(), Report::AtLocation, | 2903 Script::Handle(script()), token_pos(), Report::AtLocation, |
2986 Report::kError, Heap::kNew, | 2904 Report::kError, Heap::kNew, |
2987 "'%s' is not private and therefore cannot be patched", | 2905 "'%s' is not private and therefore cannot be patched", |
2988 name.ToCString()); | 2906 name.ToCString()); |
2989 return false; | 2907 return false; |
2990 } | 2908 } |
2991 } | 2909 } |
2992 return true; | 2910 return true; |
2993 } | 2911 } |
2994 | 2912 |
2995 | |
2996 void Class::set_dependent_code(const Array& array) const { | 2913 void Class::set_dependent_code(const Array& array) const { |
2997 StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 2914 StorePointer(&raw_ptr()->dependent_code_, array.raw()); |
2998 } | 2915 } |
2999 | 2916 |
3000 | |
3001 // Apply the members from the patch class to the original class. | 2917 // Apply the members from the patch class to the original class. |
3002 bool Class::ApplyPatch(const Class& patch, Error* error) const { | 2918 bool Class::ApplyPatch(const Class& patch, Error* error) const { |
3003 ASSERT(error != NULL); | 2919 ASSERT(error != NULL); |
3004 ASSERT(!is_finalized()); | 2920 ASSERT(!is_finalized()); |
3005 // Shared handles used during the iteration. | 2921 // Shared handles used during the iteration. |
3006 String& member_name = String::Handle(); | 2922 String& member_name = String::Handle(); |
3007 | 2923 |
3008 const PatchClass& patch_class = PatchClass::Handle( | 2924 const PatchClass& patch_class = PatchClass::Handle( |
3009 PatchClass::New(*this, Script::Handle(patch.script()))); | 2925 PatchClass::New(*this, Script::Handle(patch.script()))); |
3010 | 2926 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 SetFields(new_list); | 3020 SetFields(new_list); |
3105 | 3021 |
3106 // The functions and fields in the patch class are no longer needed. | 3022 // The functions and fields in the patch class are no longer needed. |
3107 // The patch class itself is also no longer needed. | 3023 // The patch class itself is also no longer needed. |
3108 patch.SetFunctions(Object::empty_array()); | 3024 patch.SetFunctions(Object::empty_array()); |
3109 patch.SetFields(Object::empty_array()); | 3025 patch.SetFields(Object::empty_array()); |
3110 Library::Handle(patch.library()).RemovePatchClass(patch); | 3026 Library::Handle(patch.library()).RemovePatchClass(patch); |
3111 return true; | 3027 return true; |
3112 } | 3028 } |
3113 | 3029 |
3114 | |
3115 static RawString* BuildClosureSource(const Array& formal_params, | 3030 static RawString* BuildClosureSource(const Array& formal_params, |
3116 const String& expr) { | 3031 const String& expr) { |
3117 const GrowableObjectArray& src_pieces = | 3032 const GrowableObjectArray& src_pieces = |
3118 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3033 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
3119 String& piece = String::Handle(); | 3034 String& piece = String::Handle(); |
3120 src_pieces.Add(Symbols::LParen()); | 3035 src_pieces.Add(Symbols::LParen()); |
3121 // Add formal parameters. | 3036 // Add formal parameters. |
3122 intptr_t num_formals = formal_params.Length(); | 3037 intptr_t num_formals = formal_params.Length(); |
3123 for (intptr_t i = 0; i < num_formals; i++) { | 3038 for (intptr_t i = 0; i < num_formals; i++) { |
3124 if (i > 0) { | 3039 if (i > 0) { |
3125 src_pieces.Add(Symbols::CommaSpace()); | 3040 src_pieces.Add(Symbols::CommaSpace()); |
3126 } | 3041 } |
3127 piece ^= formal_params.At(i); | 3042 piece ^= formal_params.At(i); |
3128 src_pieces.Add(piece); | 3043 src_pieces.Add(piece); |
3129 } | 3044 } |
3130 src_pieces.Add(Symbols::RParenArrow()); | 3045 src_pieces.Add(Symbols::RParenArrow()); |
3131 src_pieces.Add(expr); | 3046 src_pieces.Add(expr); |
3132 src_pieces.Add(Symbols::Semicolon()); | 3047 src_pieces.Add(Symbols::Semicolon()); |
3133 return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces))); | 3048 return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces))); |
3134 } | 3049 } |
3135 | 3050 |
3136 | |
3137 RawFunction* Function::EvaluateHelper(const Class& cls, | 3051 RawFunction* Function::EvaluateHelper(const Class& cls, |
3138 const String& expr, | 3052 const String& expr, |
3139 const Array& param_names, | 3053 const Array& param_names, |
3140 bool is_static) { | 3054 bool is_static) { |
3141 const String& func_src = | 3055 const String& func_src = |
3142 String::Handle(BuildClosureSource(param_names, expr)); | 3056 String::Handle(BuildClosureSource(param_names, expr)); |
3143 Script& script = Script::Handle(); | 3057 Script& script = Script::Handle(); |
3144 script = | 3058 script = |
3145 Script::New(Symbols::EvalSourceUri(), func_src, RawScript::kEvaluateTag); | 3059 Script::New(Symbols::EvalSourceUri(), func_src, RawScript::kEvaluateTag); |
3146 // In order to tokenize the source, we need to get the key to mangle | 3060 // In order to tokenize the source, we need to get the key to mangle |
3147 // private names from the library from which the class originates. | 3061 // private names from the library from which the class originates. |
3148 const Library& lib = Library::Handle(cls.library()); | 3062 const Library& lib = Library::Handle(cls.library()); |
3149 ASSERT(!lib.IsNull()); | 3063 ASSERT(!lib.IsNull()); |
3150 const String& lib_key = String::Handle(lib.private_key()); | 3064 const String& lib_key = String::Handle(lib.private_key()); |
3151 script.Tokenize(lib_key, false); | 3065 script.Tokenize(lib_key, false); |
3152 | 3066 |
3153 const Function& func = | 3067 const Function& func = |
3154 Function::Handle(Function::NewEvalFunction(cls, script, is_static)); | 3068 Function::Handle(Function::NewEvalFunction(cls, script, is_static)); |
3155 func.set_result_type(Object::dynamic_type()); | 3069 func.set_result_type(Object::dynamic_type()); |
3156 const intptr_t num_implicit_params = is_static ? 0 : 1; | 3070 const intptr_t num_implicit_params = is_static ? 0 : 1; |
3157 func.set_num_fixed_parameters(num_implicit_params + param_names.Length()); | 3071 func.set_num_fixed_parameters(num_implicit_params + param_names.Length()); |
3158 func.SetNumOptionalParameters(0, true); | 3072 func.SetNumOptionalParameters(0, true); |
3159 func.SetIsOptimizable(false); | 3073 func.SetIsOptimizable(false); |
3160 return func.raw(); | 3074 return func.raw(); |
3161 } | 3075 } |
3162 | 3076 |
3163 | |
3164 RawObject* Class::Evaluate(const String& expr, | 3077 RawObject* Class::Evaluate(const String& expr, |
3165 const Array& param_names, | 3078 const Array& param_names, |
3166 const Array& param_values) const { | 3079 const Array& param_values) const { |
3167 ASSERT(Thread::Current()->IsMutatorThread()); | 3080 ASSERT(Thread::Current()->IsMutatorThread()); |
3168 if (id() < kInstanceCid) { | 3081 if (id() < kInstanceCid) { |
3169 const Instance& exception = Instance::Handle( | 3082 const Instance& exception = Instance::Handle( |
3170 String::New("Cannot evaluate against a VM internal class")); | 3083 String::New("Cannot evaluate against a VM internal class")); |
3171 const Instance& stacktrace = Instance::Handle(); | 3084 const Instance& stacktrace = Instance::Handle(); |
3172 return UnhandledException::New(exception, stacktrace); | 3085 return UnhandledException::New(exception, stacktrace); |
3173 } | 3086 } |
3174 | 3087 |
3175 const Function& eval_func = Function::Handle( | 3088 const Function& eval_func = Function::Handle( |
3176 Function::EvaluateHelper(*this, expr, param_names, true)); | 3089 Function::EvaluateHelper(*this, expr, param_names, true)); |
3177 const Object& result = | 3090 const Object& result = |
3178 Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); | 3091 Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); |
3179 return result.raw(); | 3092 return result.raw(); |
3180 } | 3093 } |
3181 | 3094 |
3182 | |
3183 // Ensure that top level parsing of the class has been done. | 3095 // Ensure that top level parsing of the class has been done. |
3184 RawError* Class::EnsureIsFinalized(Thread* thread) const { | 3096 RawError* Class::EnsureIsFinalized(Thread* thread) const { |
3185 // Finalized classes have already been parsed. | 3097 // Finalized classes have already been parsed. |
3186 if (is_finalized()) { | 3098 if (is_finalized()) { |
3187 return Error::null(); | 3099 return Error::null(); |
3188 } | 3100 } |
3189 if (Compiler::IsBackgroundCompilation()) { | 3101 if (Compiler::IsBackgroundCompilation()) { |
3190 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, | 3102 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, |
3191 "Class finalization while compiling"); | 3103 "Class finalization while compiling"); |
3192 } | 3104 } |
3193 ASSERT(thread->IsMutatorThread()); | 3105 ASSERT(thread->IsMutatorThread()); |
3194 ASSERT(thread != NULL); | 3106 ASSERT(thread != NULL); |
3195 const Error& error = | 3107 const Error& error = |
3196 Error::Handle(thread->zone(), Compiler::CompileClass(*this)); | 3108 Error::Handle(thread->zone(), Compiler::CompileClass(*this)); |
3197 if (!error.IsNull()) { | 3109 if (!error.IsNull()) { |
3198 ASSERT(thread == Thread::Current()); | 3110 ASSERT(thread == Thread::Current()); |
3199 if (thread->long_jump_base() != NULL) { | 3111 if (thread->long_jump_base() != NULL) { |
3200 Report::LongJump(error); | 3112 Report::LongJump(error); |
3201 UNREACHABLE(); | 3113 UNREACHABLE(); |
3202 } | 3114 } |
3203 } | 3115 } |
3204 return error.raw(); | 3116 return error.raw(); |
3205 } | 3117 } |
3206 | 3118 |
3207 | |
3208 void Class::SetFields(const Array& value) const { | 3119 void Class::SetFields(const Array& value) const { |
3209 ASSERT(!value.IsNull()); | 3120 ASSERT(!value.IsNull()); |
3210 #if defined(DEBUG) | 3121 #if defined(DEBUG) |
3211 // Verify that all the fields in the array have this class as owner. | 3122 // Verify that all the fields in the array have this class as owner. |
3212 Field& field = Field::Handle(); | 3123 Field& field = Field::Handle(); |
3213 intptr_t len = value.Length(); | 3124 intptr_t len = value.Length(); |
3214 for (intptr_t i = 0; i < len; i++) { | 3125 for (intptr_t i = 0; i < len; i++) { |
3215 field ^= value.At(i); | 3126 field ^= value.At(i); |
3216 ASSERT(field.IsOriginal()); | 3127 ASSERT(field.IsOriginal()); |
3217 ASSERT(field.Owner() == raw()); | 3128 ASSERT(field.Owner() == raw()); |
3218 } | 3129 } |
3219 #endif | 3130 #endif |
3220 // The value of static fields is already initialized to null. | 3131 // The value of static fields is already initialized to null. |
3221 StorePointer(&raw_ptr()->fields_, value.raw()); | 3132 StorePointer(&raw_ptr()->fields_, value.raw()); |
3222 } | 3133 } |
3223 | 3134 |
3224 | |
3225 void Class::AddField(const Field& field) const { | 3135 void Class::AddField(const Field& field) const { |
3226 const Array& arr = Array::Handle(fields()); | 3136 const Array& arr = Array::Handle(fields()); |
3227 const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); | 3137 const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); |
3228 new_arr.SetAt(arr.Length(), field); | 3138 new_arr.SetAt(arr.Length(), field); |
3229 SetFields(new_arr); | 3139 SetFields(new_arr); |
3230 } | 3140 } |
3231 | 3141 |
3232 | |
3233 void Class::AddFields(const GrowableArray<const Field*>& new_fields) const { | 3142 void Class::AddFields(const GrowableArray<const Field*>& new_fields) const { |
3234 const intptr_t num_new_fields = new_fields.length(); | 3143 const intptr_t num_new_fields = new_fields.length(); |
3235 if (num_new_fields == 0) return; | 3144 if (num_new_fields == 0) return; |
3236 const Array& arr = Array::Handle(fields()); | 3145 const Array& arr = Array::Handle(fields()); |
3237 const intptr_t num_old_fields = arr.Length(); | 3146 const intptr_t num_old_fields = arr.Length(); |
3238 const Array& new_arr = Array::Handle( | 3147 const Array& new_arr = Array::Handle( |
3239 Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld)); | 3148 Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld)); |
3240 for (intptr_t i = 0; i < num_new_fields; i++) { | 3149 for (intptr_t i = 0; i < num_new_fields; i++) { |
3241 new_arr.SetAt(i + num_old_fields, *new_fields.At(i)); | 3150 new_arr.SetAt(i + num_old_fields, *new_fields.At(i)); |
3242 } | 3151 } |
3243 SetFields(new_arr); | 3152 SetFields(new_arr); |
3244 } | 3153 } |
3245 | 3154 |
3246 | |
3247 void Class::InjectCIDFields() const { | 3155 void Class::InjectCIDFields() const { |
3248 Thread* thread = Thread::Current(); | 3156 Thread* thread = Thread::Current(); |
3249 Zone* zone = thread->zone(); | 3157 Zone* zone = thread->zone(); |
3250 Field& field = Field::Handle(zone); | 3158 Field& field = Field::Handle(zone); |
3251 Smi& value = Smi::Handle(zone); | 3159 Smi& value = Smi::Handle(zone); |
3252 String& field_name = String::Handle(zone); | 3160 String& field_name = String::Handle(zone); |
3253 | 3161 |
3254 #define CLASS_LIST_WITH_NULL(V) \ | 3162 #define CLASS_LIST_WITH_NULL(V) \ |
3255 V(Null) \ | 3163 V(Null) \ |
3256 CLASS_LIST_NO_OBJECT(V) | 3164 CLASS_LIST_NO_OBJECT(V) |
3257 | 3165 |
3258 #define ADD_SET_FIELD(clazz) \ | 3166 #define ADD_SET_FIELD(clazz) \ |
3259 field_name = Symbols::New(thread, "cid" #clazz); \ | 3167 field_name = Symbols::New(thread, "cid" #clazz); \ |
3260 field = \ | 3168 field = \ |
3261 Field::New(field_name, true, false, true, false, *this, \ | 3169 Field::New(field_name, true, false, true, false, *this, \ |
3262 Type::Handle(Type::IntType()), TokenPosition::kMinSource); \ | 3170 Type::Handle(Type::IntType()), TokenPosition::kMinSource); \ |
3263 value = Smi::New(k##clazz##Cid); \ | 3171 value = Smi::New(k##clazz##Cid); \ |
3264 field.SetStaticValue(value, true); \ | 3172 field.SetStaticValue(value, true); \ |
3265 AddField(field); | 3173 AddField(field); |
3266 | 3174 |
3267 CLASS_LIST_WITH_NULL(ADD_SET_FIELD) | 3175 CLASS_LIST_WITH_NULL(ADD_SET_FIELD) |
3268 #undef ADD_SET_FIELD | 3176 #undef ADD_SET_FIELD |
3269 #undef CLASS_LIST_WITH_NULL | 3177 #undef CLASS_LIST_WITH_NULL |
3270 } | 3178 } |
3271 | 3179 |
3272 | |
3273 template <class FakeInstance> | 3180 template <class FakeInstance> |
3274 RawClass* Class::NewCommon(intptr_t index) { | 3181 RawClass* Class::NewCommon(intptr_t index) { |
3275 ASSERT(Object::class_class() != Class::null()); | 3182 ASSERT(Object::class_class() != Class::null()); |
3276 Class& result = Class::Handle(); | 3183 Class& result = Class::Handle(); |
3277 { | 3184 { |
3278 RawObject* raw = | 3185 RawObject* raw = |
3279 Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); | 3186 Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); |
3280 NoSafepointScope no_safepoint; | 3187 NoSafepointScope no_safepoint; |
3281 result ^= raw; | 3188 result ^= raw; |
3282 } | 3189 } |
3283 FakeInstance fake; | 3190 FakeInstance fake; |
3284 ASSERT(fake.IsInstance()); | 3191 ASSERT(fake.IsInstance()); |
3285 result.set_handle_vtable(fake.vtable()); | 3192 result.set_handle_vtable(fake.vtable()); |
3286 result.set_instance_size(FakeInstance::InstanceSize()); | 3193 result.set_instance_size(FakeInstance::InstanceSize()); |
3287 result.set_next_field_offset(FakeInstance::NextFieldOffset()); | 3194 result.set_next_field_offset(FakeInstance::NextFieldOffset()); |
3288 result.set_id(index); | 3195 result.set_id(index); |
3289 result.set_state_bits(0); | 3196 result.set_state_bits(0); |
3290 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); | 3197 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); |
3291 result.set_num_type_arguments(kUnknownNumTypeArguments); | 3198 result.set_num_type_arguments(kUnknownNumTypeArguments); |
3292 result.set_num_own_type_arguments(kUnknownNumTypeArguments); | 3199 result.set_num_own_type_arguments(kUnknownNumTypeArguments); |
3293 result.set_num_native_fields(0); | 3200 result.set_num_native_fields(0); |
3294 result.set_token_pos(TokenPosition::kNoSource); | 3201 result.set_token_pos(TokenPosition::kNoSource); |
3295 result.InitEmptyFields(); | 3202 result.InitEmptyFields(); |
3296 return result.raw(); | 3203 return result.raw(); |
3297 } | 3204 } |
3298 | 3205 |
3299 | |
3300 template <class FakeInstance> | 3206 template <class FakeInstance> |
3301 RawClass* Class::New(intptr_t index) { | 3207 RawClass* Class::New(intptr_t index) { |
3302 Class& result = Class::Handle(NewCommon<FakeInstance>(index)); | 3208 Class& result = Class::Handle(NewCommon<FakeInstance>(index)); |
3303 Isolate::Current()->RegisterClass(result); | 3209 Isolate::Current()->RegisterClass(result); |
3304 return result.raw(); | 3210 return result.raw(); |
3305 } | 3211 } |
3306 | 3212 |
3307 | |
3308 RawClass* Class::New(const Library& lib, | 3213 RawClass* Class::New(const Library& lib, |
3309 const String& name, | 3214 const String& name, |
3310 const Script& script, | 3215 const Script& script, |
3311 TokenPosition token_pos) { | 3216 TokenPosition token_pos) { |
3312 Class& result = Class::Handle(NewCommon<Instance>(kIllegalCid)); | 3217 Class& result = Class::Handle(NewCommon<Instance>(kIllegalCid)); |
3313 result.set_library(lib); | 3218 result.set_library(lib); |
3314 result.set_name(name); | 3219 result.set_name(name); |
3315 result.set_script(script); | 3220 result.set_script(script); |
3316 result.set_token_pos(token_pos); | 3221 result.set_token_pos(token_pos); |
3317 Isolate::Current()->RegisterClass(result); | 3222 Isolate::Current()->RegisterClass(result); |
3318 return result.raw(); | 3223 return result.raw(); |
3319 } | 3224 } |
3320 | 3225 |
3321 | |
3322 RawClass* Class::NewInstanceClass() { | 3226 RawClass* Class::NewInstanceClass() { |
3323 return Class::New<Instance>(kIllegalCid); | 3227 return Class::New<Instance>(kIllegalCid); |
3324 } | 3228 } |
3325 | 3229 |
3326 | |
3327 RawClass* Class::NewNativeWrapper(const Library& library, | 3230 RawClass* Class::NewNativeWrapper(const Library& library, |
3328 const String& name, | 3231 const String& name, |
3329 int field_count) { | 3232 int field_count) { |
3330 Class& cls = Class::Handle(library.LookupClass(name)); | 3233 Class& cls = Class::Handle(library.LookupClass(name)); |
3331 if (cls.IsNull()) { | 3234 if (cls.IsNull()) { |
3332 cls = New(library, name, Script::Handle(), TokenPosition::kNoSource); | 3235 cls = New(library, name, Script::Handle(), TokenPosition::kNoSource); |
3333 cls.SetFields(Object::empty_array()); | 3236 cls.SetFields(Object::empty_array()); |
3334 cls.SetFunctions(Object::empty_array()); | 3237 cls.SetFunctions(Object::empty_array()); |
3335 // Set super class to Object. | 3238 // Set super class to Object. |
3336 cls.set_super_type(Type::Handle(Type::ObjectType())); | 3239 cls.set_super_type(Type::Handle(Type::ObjectType())); |
3337 // Compute instance size. First word contains a pointer to a properly | 3240 // Compute instance size. First word contains a pointer to a properly |
3338 // sized typed array once the first native field has been set. | 3241 // sized typed array once the first native field has been set. |
3339 intptr_t instance_size = sizeof(RawInstance) + kWordSize; | 3242 intptr_t instance_size = sizeof(RawInstance) + kWordSize; |
3340 cls.set_instance_size(RoundedAllocationSize(instance_size)); | 3243 cls.set_instance_size(RoundedAllocationSize(instance_size)); |
3341 cls.set_next_field_offset(instance_size); | 3244 cls.set_next_field_offset(instance_size); |
3342 cls.set_num_native_fields(field_count); | 3245 cls.set_num_native_fields(field_count); |
3343 cls.set_is_finalized(); | 3246 cls.set_is_finalized(); |
3344 cls.set_is_type_finalized(); | 3247 cls.set_is_type_finalized(); |
3345 cls.set_is_synthesized_class(); | 3248 cls.set_is_synthesized_class(); |
3346 cls.set_is_cycle_free(); | 3249 cls.set_is_cycle_free(); |
3347 library.AddClass(cls); | 3250 library.AddClass(cls); |
3348 return cls.raw(); | 3251 return cls.raw(); |
3349 } else { | 3252 } else { |
3350 return Class::null(); | 3253 return Class::null(); |
3351 } | 3254 } |
3352 } | 3255 } |
3353 | 3256 |
3354 | |
3355 RawClass* Class::NewStringClass(intptr_t class_id) { | 3257 RawClass* Class::NewStringClass(intptr_t class_id) { |
3356 intptr_t instance_size; | 3258 intptr_t instance_size; |
3357 if (class_id == kOneByteStringCid) { | 3259 if (class_id == kOneByteStringCid) { |
3358 instance_size = OneByteString::InstanceSize(); | 3260 instance_size = OneByteString::InstanceSize(); |
3359 } else if (class_id == kTwoByteStringCid) { | 3261 } else if (class_id == kTwoByteStringCid) { |
3360 instance_size = TwoByteString::InstanceSize(); | 3262 instance_size = TwoByteString::InstanceSize(); |
3361 } else if (class_id == kExternalOneByteStringCid) { | 3263 } else if (class_id == kExternalOneByteStringCid) { |
3362 instance_size = ExternalOneByteString::InstanceSize(); | 3264 instance_size = ExternalOneByteString::InstanceSize(); |
3363 } else { | 3265 } else { |
3364 ASSERT(class_id == kExternalTwoByteStringCid); | 3266 ASSERT(class_id == kExternalTwoByteStringCid); |
3365 instance_size = ExternalTwoByteString::InstanceSize(); | 3267 instance_size = ExternalTwoByteString::InstanceSize(); |
3366 } | 3268 } |
3367 Class& result = Class::Handle(New<String>(class_id)); | 3269 Class& result = Class::Handle(New<String>(class_id)); |
3368 result.set_instance_size(instance_size); | 3270 result.set_instance_size(instance_size); |
3369 result.set_next_field_offset(String::NextFieldOffset()); | 3271 result.set_next_field_offset(String::NextFieldOffset()); |
3370 result.set_is_prefinalized(); | 3272 result.set_is_prefinalized(); |
3371 return result.raw(); | 3273 return result.raw(); |
3372 } | 3274 } |
3373 | 3275 |
3374 | |
3375 RawClass* Class::NewTypedDataClass(intptr_t class_id) { | 3276 RawClass* Class::NewTypedDataClass(intptr_t class_id) { |
3376 ASSERT(RawObject::IsTypedDataClassId(class_id)); | 3277 ASSERT(RawObject::IsTypedDataClassId(class_id)); |
3377 intptr_t instance_size = TypedData::InstanceSize(); | 3278 intptr_t instance_size = TypedData::InstanceSize(); |
3378 Class& result = Class::Handle(New<TypedData>(class_id)); | 3279 Class& result = Class::Handle(New<TypedData>(class_id)); |
3379 result.set_instance_size(instance_size); | 3280 result.set_instance_size(instance_size); |
3380 result.set_next_field_offset(TypedData::NextFieldOffset()); | 3281 result.set_next_field_offset(TypedData::NextFieldOffset()); |
3381 result.set_is_prefinalized(); | 3282 result.set_is_prefinalized(); |
3382 return result.raw(); | 3283 return result.raw(); |
3383 } | 3284 } |
3384 | 3285 |
3385 | |
3386 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) { | 3286 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) { |
3387 ASSERT(RawObject::IsTypedDataViewClassId(class_id)); | 3287 ASSERT(RawObject::IsTypedDataViewClassId(class_id)); |
3388 Class& result = Class::Handle(New<Instance>(class_id)); | 3288 Class& result = Class::Handle(New<Instance>(class_id)); |
3389 result.set_instance_size(0); | 3289 result.set_instance_size(0); |
3390 result.set_next_field_offset(-kWordSize); | 3290 result.set_next_field_offset(-kWordSize); |
3391 return result.raw(); | 3291 return result.raw(); |
3392 } | 3292 } |
3393 | 3293 |
3394 | |
3395 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) { | 3294 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) { |
3396 ASSERT(RawObject::IsExternalTypedDataClassId(class_id)); | 3295 ASSERT(RawObject::IsExternalTypedDataClassId(class_id)); |
3397 intptr_t instance_size = ExternalTypedData::InstanceSize(); | 3296 intptr_t instance_size = ExternalTypedData::InstanceSize(); |
3398 Class& result = Class::Handle(New<ExternalTypedData>(class_id)); | 3297 Class& result = Class::Handle(New<ExternalTypedData>(class_id)); |
3399 result.set_instance_size(instance_size); | 3298 result.set_instance_size(instance_size); |
3400 result.set_next_field_offset(ExternalTypedData::NextFieldOffset()); | 3299 result.set_next_field_offset(ExternalTypedData::NextFieldOffset()); |
3401 result.set_is_prefinalized(); | 3300 result.set_is_prefinalized(); |
3402 return result.raw(); | 3301 return result.raw(); |
3403 } | 3302 } |
3404 | 3303 |
3405 | |
3406 void Class::set_name(const String& value) const { | 3304 void Class::set_name(const String& value) const { |
3407 ASSERT(raw_ptr()->name_ == String::null()); | 3305 ASSERT(raw_ptr()->name_ == String::null()); |
3408 ASSERT(value.IsSymbol()); | 3306 ASSERT(value.IsSymbol()); |
3409 StorePointer(&raw_ptr()->name_, value.raw()); | 3307 StorePointer(&raw_ptr()->name_, value.raw()); |
3410 #if !defined(PRODUCT) | 3308 #if !defined(PRODUCT) |
3411 if (raw_ptr()->user_name_ == String::null()) { | 3309 if (raw_ptr()->user_name_ == String::null()) { |
3412 // TODO(johnmccutchan): Eagerly set user name for VM isolate classes, | 3310 // TODO(johnmccutchan): Eagerly set user name for VM isolate classes, |
3413 // lazily set user name for the other classes. | 3311 // lazily set user name for the other classes. |
3414 // Generate and set user_name. | 3312 // Generate and set user_name. |
3415 const String& user_name = String::Handle(GenerateUserVisibleName()); | 3313 const String& user_name = String::Handle(GenerateUserVisibleName()); |
3416 set_user_name(user_name); | 3314 set_user_name(user_name); |
3417 } | 3315 } |
3418 #endif // !defined(PRODUCT) | 3316 #endif // !defined(PRODUCT) |
3419 } | 3317 } |
3420 | 3318 |
3421 | |
3422 #if !defined(PRODUCT) | 3319 #if !defined(PRODUCT) |
3423 void Class::set_user_name(const String& value) const { | 3320 void Class::set_user_name(const String& value) const { |
3424 StorePointer(&raw_ptr()->user_name_, value.raw()); | 3321 StorePointer(&raw_ptr()->user_name_, value.raw()); |
3425 } | 3322 } |
3426 #endif // !defined(PRODUCT) | 3323 #endif // !defined(PRODUCT) |
3427 | 3324 |
3428 | |
3429 RawString* Class::GenerateUserVisibleName() const { | 3325 RawString* Class::GenerateUserVisibleName() const { |
3430 if (FLAG_show_internal_names) { | 3326 if (FLAG_show_internal_names) { |
3431 return Name(); | 3327 return Name(); |
3432 } | 3328 } |
3433 switch (id()) { | 3329 switch (id()) { |
3434 case kFloat32x4Cid: | 3330 case kFloat32x4Cid: |
3435 return Symbols::Float32x4().raw(); | 3331 return Symbols::Float32x4().raw(); |
3436 case kInt32x4Cid: | 3332 case kInt32x4Cid: |
3437 return Symbols::Int32x4().raw(); | 3333 return Symbols::Int32x4().raw(); |
3438 case kTypedDataInt8ArrayCid: | 3334 case kTypedDataInt8ArrayCid: |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3566 case kArrayCid: | 3462 case kArrayCid: |
3567 case kImmutableArrayCid: | 3463 case kImmutableArrayCid: |
3568 case kGrowableObjectArrayCid: | 3464 case kGrowableObjectArrayCid: |
3569 return Symbols::List().raw(); | 3465 return Symbols::List().raw(); |
3570 #endif // !defined(PRODUCT) | 3466 #endif // !defined(PRODUCT) |
3571 } | 3467 } |
3572 const String& name = String::Handle(Name()); | 3468 const String& name = String::Handle(Name()); |
3573 return String::ScrubName(name); | 3469 return String::ScrubName(name); |
3574 } | 3470 } |
3575 | 3471 |
3576 | |
3577 void Class::set_script(const Script& value) const { | 3472 void Class::set_script(const Script& value) const { |
3578 StorePointer(&raw_ptr()->script_, value.raw()); | 3473 StorePointer(&raw_ptr()->script_, value.raw()); |
3579 } | 3474 } |
3580 | 3475 |
3581 | |
3582 void Class::set_token_pos(TokenPosition token_pos) const { | 3476 void Class::set_token_pos(TokenPosition token_pos) const { |
3583 ASSERT(!token_pos.IsClassifying()); | 3477 ASSERT(!token_pos.IsClassifying()); |
3584 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 3478 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
3585 } | 3479 } |
3586 | 3480 |
3587 | |
3588 TokenPosition Class::ComputeEndTokenPos() const { | 3481 TokenPosition Class::ComputeEndTokenPos() const { |
3589 // Return the begin token for synthetic classes. | 3482 // Return the begin token for synthetic classes. |
3590 if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) { | 3483 if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) { |
3591 return token_pos(); | 3484 return token_pos(); |
3592 } | 3485 } |
3593 | 3486 |
3594 Zone* zone = Thread::Current()->zone(); | 3487 Zone* zone = Thread::Current()->zone(); |
3595 const Script& scr = Script::Handle(zone, script()); | 3488 const Script& scr = Script::Handle(zone, script()); |
3596 ASSERT(!scr.IsNull()); | 3489 ASSERT(!scr.IsNull()); |
3597 | 3490 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 if (--level == 0) { | 3522 if (--level == 0) { |
3630 return tkit.CurrentPosition(); | 3523 return tkit.CurrentPosition(); |
3631 } | 3524 } |
3632 } | 3525 } |
3633 tkit.Advance(); | 3526 tkit.Advance(); |
3634 } | 3527 } |
3635 UNREACHABLE(); | 3528 UNREACHABLE(); |
3636 return TokenPosition::kNoSource; | 3529 return TokenPosition::kNoSource; |
3637 } | 3530 } |
3638 | 3531 |
3639 | |
3640 void Class::set_is_implemented() const { | 3532 void Class::set_is_implemented() const { |
3641 set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_)); | 3533 set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_)); |
3642 } | 3534 } |
3643 | 3535 |
3644 | |
3645 void Class::set_is_abstract() const { | 3536 void Class::set_is_abstract() const { |
3646 set_state_bits(AbstractBit::update(true, raw_ptr()->state_bits_)); | 3537 set_state_bits(AbstractBit::update(true, raw_ptr()->state_bits_)); |
3647 } | 3538 } |
3648 | 3539 |
3649 | |
3650 void Class::set_is_type_finalized() const { | 3540 void Class::set_is_type_finalized() const { |
3651 set_state_bits(TypeFinalizedBit::update(true, raw_ptr()->state_bits_)); | 3541 set_state_bits(TypeFinalizedBit::update(true, raw_ptr()->state_bits_)); |
3652 } | 3542 } |
3653 | 3543 |
3654 | |
3655 void Class::set_is_patch() const { | 3544 void Class::set_is_patch() const { |
3656 set_state_bits(PatchBit::update(true, raw_ptr()->state_bits_)); | 3545 set_state_bits(PatchBit::update(true, raw_ptr()->state_bits_)); |
3657 } | 3546 } |
3658 | 3547 |
3659 | |
3660 void Class::set_is_synthesized_class() const { | 3548 void Class::set_is_synthesized_class() const { |
3661 set_state_bits(SynthesizedClassBit::update(true, raw_ptr()->state_bits_)); | 3549 set_state_bits(SynthesizedClassBit::update(true, raw_ptr()->state_bits_)); |
3662 } | 3550 } |
3663 | 3551 |
3664 | |
3665 void Class::set_is_enum_class() const { | 3552 void Class::set_is_enum_class() const { |
3666 set_state_bits(EnumBit::update(true, raw_ptr()->state_bits_)); | 3553 set_state_bits(EnumBit::update(true, raw_ptr()->state_bits_)); |
3667 } | 3554 } |
3668 | 3555 |
3669 | |
3670 void Class::set_is_const() const { | 3556 void Class::set_is_const() const { |
3671 set_state_bits(ConstBit::update(true, raw_ptr()->state_bits_)); | 3557 set_state_bits(ConstBit::update(true, raw_ptr()->state_bits_)); |
3672 } | 3558 } |
3673 | 3559 |
3674 | |
3675 void Class::set_is_mixin_app_alias() const { | 3560 void Class::set_is_mixin_app_alias() const { |
3676 set_state_bits(MixinAppAliasBit::update(true, raw_ptr()->state_bits_)); | 3561 set_state_bits(MixinAppAliasBit::update(true, raw_ptr()->state_bits_)); |
3677 } | 3562 } |
3678 | 3563 |
3679 | |
3680 void Class::set_is_mixin_type_applied() const { | 3564 void Class::set_is_mixin_type_applied() const { |
3681 set_state_bits(MixinTypeAppliedBit::update(true, raw_ptr()->state_bits_)); | 3565 set_state_bits(MixinTypeAppliedBit::update(true, raw_ptr()->state_bits_)); |
3682 } | 3566 } |
3683 | 3567 |
3684 | |
3685 void Class::set_is_fields_marked_nullable() const { | 3568 void Class::set_is_fields_marked_nullable() const { |
3686 set_state_bits(FieldsMarkedNullableBit::update(true, raw_ptr()->state_bits_)); | 3569 set_state_bits(FieldsMarkedNullableBit::update(true, raw_ptr()->state_bits_)); |
3687 } | 3570 } |
3688 | 3571 |
3689 | |
3690 void Class::set_is_cycle_free() const { | 3572 void Class::set_is_cycle_free() const { |
3691 ASSERT(!is_cycle_free()); | 3573 ASSERT(!is_cycle_free()); |
3692 set_state_bits(CycleFreeBit::update(true, raw_ptr()->state_bits_)); | 3574 set_state_bits(CycleFreeBit::update(true, raw_ptr()->state_bits_)); |
3693 } | 3575 } |
3694 | 3576 |
3695 | |
3696 void Class::set_is_allocated(bool value) const { | 3577 void Class::set_is_allocated(bool value) const { |
3697 set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_)); | 3578 set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_)); |
3698 } | 3579 } |
3699 | 3580 |
3700 | |
3701 void Class::set_is_finalized() const { | 3581 void Class::set_is_finalized() const { |
3702 ASSERT(!is_finalized()); | 3582 ASSERT(!is_finalized()); |
3703 set_state_bits( | 3583 set_state_bits( |
3704 ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_)); | 3584 ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_)); |
3705 } | 3585 } |
3706 | 3586 |
3707 | |
3708 void Class::SetRefinalizeAfterPatch() const { | 3587 void Class::SetRefinalizeAfterPatch() const { |
3709 ASSERT(!IsTopLevel()); | 3588 ASSERT(!IsTopLevel()); |
3710 set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch, | 3589 set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch, |
3711 raw_ptr()->state_bits_)); | 3590 raw_ptr()->state_bits_)); |
3712 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); | 3591 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); |
3713 } | 3592 } |
3714 | 3593 |
3715 | |
3716 void Class::ResetFinalization() const { | 3594 void Class::ResetFinalization() const { |
3717 ASSERT(IsTopLevel() || IsClosureClass()); | 3595 ASSERT(IsTopLevel() || IsClosureClass()); |
3718 set_state_bits( | 3596 set_state_bits( |
3719 ClassFinalizedBits::update(RawClass::kAllocated, raw_ptr()->state_bits_)); | 3597 ClassFinalizedBits::update(RawClass::kAllocated, raw_ptr()->state_bits_)); |
3720 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); | 3598 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); |
3721 } | 3599 } |
3722 | 3600 |
3723 | |
3724 void Class::set_is_prefinalized() const { | 3601 void Class::set_is_prefinalized() const { |
3725 ASSERT(!is_finalized()); | 3602 ASSERT(!is_finalized()); |
3726 set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized, | 3603 set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized, |
3727 raw_ptr()->state_bits_)); | 3604 raw_ptr()->state_bits_)); |
3728 } | 3605 } |
3729 | 3606 |
3730 | |
3731 void Class::set_is_marked_for_parsing() const { | 3607 void Class::set_is_marked_for_parsing() const { |
3732 set_state_bits(MarkedForParsingBit::update(true, raw_ptr()->state_bits_)); | 3608 set_state_bits(MarkedForParsingBit::update(true, raw_ptr()->state_bits_)); |
3733 } | 3609 } |
3734 | 3610 |
3735 | |
3736 void Class::reset_is_marked_for_parsing() const { | 3611 void Class::reset_is_marked_for_parsing() const { |
3737 set_state_bits(MarkedForParsingBit::update(false, raw_ptr()->state_bits_)); | 3612 set_state_bits(MarkedForParsingBit::update(false, raw_ptr()->state_bits_)); |
3738 } | 3613 } |
3739 | 3614 |
3740 | |
3741 void Class::set_interfaces(const Array& value) const { | 3615 void Class::set_interfaces(const Array& value) const { |
3742 ASSERT(!value.IsNull()); | 3616 ASSERT(!value.IsNull()); |
3743 StorePointer(&raw_ptr()->interfaces_, value.raw()); | 3617 StorePointer(&raw_ptr()->interfaces_, value.raw()); |
3744 } | 3618 } |
3745 | 3619 |
3746 | |
3747 void Class::set_mixin(const Type& value) const { | 3620 void Class::set_mixin(const Type& value) const { |
3748 ASSERT(!value.IsNull()); | 3621 ASSERT(!value.IsNull()); |
3749 StorePointer(&raw_ptr()->mixin_, value.raw()); | 3622 StorePointer(&raw_ptr()->mixin_, value.raw()); |
3750 } | 3623 } |
3751 | 3624 |
3752 | |
3753 bool Class::IsMixinApplication() const { | 3625 bool Class::IsMixinApplication() const { |
3754 return mixin() != Type::null(); | 3626 return mixin() != Type::null(); |
3755 } | 3627 } |
3756 | 3628 |
3757 | |
3758 RawClass* Class::GetPatchClass() const { | 3629 RawClass* Class::GetPatchClass() const { |
3759 const Library& lib = Library::Handle(library()); | 3630 const Library& lib = Library::Handle(library()); |
3760 return lib.GetPatchClass(String::Handle(Name())); | 3631 return lib.GetPatchClass(String::Handle(Name())); |
3761 } | 3632 } |
3762 | 3633 |
3763 | |
3764 void Class::AddDirectSubclass(const Class& subclass) const { | 3634 void Class::AddDirectSubclass(const Class& subclass) const { |
3765 ASSERT(!subclass.IsNull()); | 3635 ASSERT(!subclass.IsNull()); |
3766 ASSERT(subclass.SuperClass() == raw()); | 3636 ASSERT(subclass.SuperClass() == raw()); |
3767 // Do not keep track of the direct subclasses of class Object. | 3637 // Do not keep track of the direct subclasses of class Object. |
3768 ASSERT(!IsObjectClass()); | 3638 ASSERT(!IsObjectClass()); |
3769 GrowableObjectArray& direct_subclasses = | 3639 GrowableObjectArray& direct_subclasses = |
3770 GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); | 3640 GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); |
3771 if (direct_subclasses.IsNull()) { | 3641 if (direct_subclasses.IsNull()) { |
3772 direct_subclasses = GrowableObjectArray::New(4, Heap::kOld); | 3642 direct_subclasses = GrowableObjectArray::New(4, Heap::kOld); |
3773 StorePointer(&raw_ptr()->direct_subclasses_, direct_subclasses.raw()); | 3643 StorePointer(&raw_ptr()->direct_subclasses_, direct_subclasses.raw()); |
3774 } | 3644 } |
3775 #if defined(DEBUG) | 3645 #if defined(DEBUG) |
3776 // Verify that the same class is not added twice. | 3646 // Verify that the same class is not added twice. |
3777 for (intptr_t i = 0; i < direct_subclasses.Length(); i++) { | 3647 for (intptr_t i = 0; i < direct_subclasses.Length(); i++) { |
3778 ASSERT(direct_subclasses.At(i) != subclass.raw()); | 3648 ASSERT(direct_subclasses.At(i) != subclass.raw()); |
3779 } | 3649 } |
3780 #endif | 3650 #endif |
3781 direct_subclasses.Add(subclass, Heap::kOld); | 3651 direct_subclasses.Add(subclass, Heap::kOld); |
3782 } | 3652 } |
3783 | 3653 |
3784 | |
3785 void Class::ClearDirectSubclasses() const { | 3654 void Class::ClearDirectSubclasses() const { |
3786 StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null()); | 3655 StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null()); |
3787 } | 3656 } |
3788 | 3657 |
3789 | |
3790 RawArray* Class::constants() const { | 3658 RawArray* Class::constants() const { |
3791 return raw_ptr()->constants_; | 3659 return raw_ptr()->constants_; |
3792 } | 3660 } |
3793 | 3661 |
3794 void Class::set_constants(const Array& value) const { | 3662 void Class::set_constants(const Array& value) const { |
3795 ASSERT(!value.IsNull()); | 3663 ASSERT(!value.IsNull()); |
3796 StorePointer(&raw_ptr()->constants_, value.raw()); | 3664 StorePointer(&raw_ptr()->constants_, value.raw()); |
3797 } | 3665 } |
3798 | 3666 |
3799 | |
3800 RawType* Class::canonical_type() const { | 3667 RawType* Class::canonical_type() const { |
3801 return raw_ptr()->canonical_type_; | 3668 return raw_ptr()->canonical_type_; |
3802 } | 3669 } |
3803 | 3670 |
3804 | |
3805 void Class::set_canonical_type(const Type& value) const { | 3671 void Class::set_canonical_type(const Type& value) const { |
3806 ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld()); | 3672 ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld()); |
3807 StorePointer(&raw_ptr()->canonical_type_, value.raw()); | 3673 StorePointer(&raw_ptr()->canonical_type_, value.raw()); |
3808 } | 3674 } |
3809 | 3675 |
3810 | |
3811 RawType* Class::CanonicalType() const { | 3676 RawType* Class::CanonicalType() const { |
3812 return raw_ptr()->canonical_type_; | 3677 return raw_ptr()->canonical_type_; |
3813 } | 3678 } |
3814 | 3679 |
3815 | |
3816 void Class::SetCanonicalType(const Type& type) const { | 3680 void Class::SetCanonicalType(const Type& type) const { |
3817 ASSERT((canonical_type() == Object::null()) || | 3681 ASSERT((canonical_type() == Object::null()) || |
3818 (canonical_type() == type.raw())); // Set during own finalization. | 3682 (canonical_type() == type.raw())); // Set during own finalization. |
3819 set_canonical_type(type); | 3683 set_canonical_type(type); |
3820 } | 3684 } |
3821 | 3685 |
3822 | |
3823 void Class::set_allocation_stub(const Code& value) const { | 3686 void Class::set_allocation_stub(const Code& value) const { |
3824 // Never clear the stub as it may still be a target, but will be GC-d if | 3687 // Never clear the stub as it may still be a target, but will be GC-d if |
3825 // not referenced. | 3688 // not referenced. |
3826 ASSERT(!value.IsNull()); | 3689 ASSERT(!value.IsNull()); |
3827 ASSERT(raw_ptr()->allocation_stub_ == Code::null()); | 3690 ASSERT(raw_ptr()->allocation_stub_ == Code::null()); |
3828 StorePointer(&raw_ptr()->allocation_stub_, value.raw()); | 3691 StorePointer(&raw_ptr()->allocation_stub_, value.raw()); |
3829 } | 3692 } |
3830 | 3693 |
3831 | |
3832 void Class::DisableAllocationStub() const { | 3694 void Class::DisableAllocationStub() const { |
3833 const Code& existing_stub = Code::Handle(allocation_stub()); | 3695 const Code& existing_stub = Code::Handle(allocation_stub()); |
3834 if (existing_stub.IsNull()) { | 3696 if (existing_stub.IsNull()) { |
3835 return; | 3697 return; |
3836 } | 3698 } |
3837 ASSERT(!existing_stub.IsDisabled()); | 3699 ASSERT(!existing_stub.IsDisabled()); |
3838 // Change the stub so that the next caller will regenerate the stub. | 3700 // Change the stub so that the next caller will regenerate the stub. |
3839 existing_stub.DisableStubCode(); | 3701 existing_stub.DisableStubCode(); |
3840 // Disassociate the existing stub from class. | 3702 // Disassociate the existing stub from class. |
3841 StorePointer(&raw_ptr()->allocation_stub_, Code::null()); | 3703 StorePointer(&raw_ptr()->allocation_stub_, Code::null()); |
3842 } | 3704 } |
3843 | 3705 |
3844 | |
3845 bool Class::IsDartFunctionClass() const { | 3706 bool Class::IsDartFunctionClass() const { |
3846 return raw() == Type::Handle(Type::DartFunctionType()).type_class(); | 3707 return raw() == Type::Handle(Type::DartFunctionType()).type_class(); |
3847 } | 3708 } |
3848 | 3709 |
3849 | |
3850 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. | 3710 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |
3851 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. | 3711 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |
3852 // Type S is specified by this class parameterized with 'type_arguments', and | 3712 // Type S is specified by this class parameterized with 'type_arguments', and |
3853 // type T by class 'other' parameterized with 'other_type_arguments'. | 3713 // type T by class 'other' parameterized with 'other_type_arguments'. |
3854 // This class and class 'other' do not need to be finalized, however, they must | 3714 // This class and class 'other' do not need to be finalized, however, they must |
3855 // be resolved as well as their interfaces. | 3715 // be resolved as well as their interfaces. |
3856 bool Class::TypeTestNonRecursive(const Class& cls, | 3716 bool Class::TypeTestNonRecursive(const Class& cls, |
3857 Class::TypeTestKind test_kind, | 3717 Class::TypeTestKind test_kind, |
3858 const TypeArguments& type_arguments, | 3718 const TypeArguments& type_arguments, |
3859 const Class& other, | 3719 const Class& other, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3987 // "Recurse" up the class hierarchy until we have reached the top. | 3847 // "Recurse" up the class hierarchy until we have reached the top. |
3988 thsi = thsi.SuperClass(); | 3848 thsi = thsi.SuperClass(); |
3989 if (thsi.IsNull()) { | 3849 if (thsi.IsNull()) { |
3990 return false; | 3850 return false; |
3991 } | 3851 } |
3992 } | 3852 } |
3993 UNREACHABLE(); | 3853 UNREACHABLE(); |
3994 return false; | 3854 return false; |
3995 } | 3855 } |
3996 | 3856 |
3997 | |
3998 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. | 3857 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |
3999 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. | 3858 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |
4000 // Type S is specified by this class parameterized with 'type_arguments', and | 3859 // Type S is specified by this class parameterized with 'type_arguments', and |
4001 // type T by class 'other' parameterized with 'other_type_arguments'. | 3860 // type T by class 'other' parameterized with 'other_type_arguments'. |
4002 // This class and class 'other' do not need to be finalized, however, they must | 3861 // This class and class 'other' do not need to be finalized, however, they must |
4003 // be resolved as well as their interfaces. | 3862 // be resolved as well as their interfaces. |
4004 bool Class::TypeTest(TypeTestKind test_kind, | 3863 bool Class::TypeTest(TypeTestKind test_kind, |
4005 const TypeArguments& type_arguments, | 3864 const TypeArguments& type_arguments, |
4006 const Class& other, | 3865 const Class& other, |
4007 const TypeArguments& other_type_arguments, | 3866 const TypeArguments& other_type_arguments, |
4008 Error* bound_error, | 3867 Error* bound_error, |
4009 TrailPtr bound_trail, | 3868 TrailPtr bound_trail, |
4010 Heap::Space space) const { | 3869 Heap::Space space) const { |
4011 return TypeTestNonRecursive(*this, test_kind, type_arguments, other, | 3870 return TypeTestNonRecursive(*this, test_kind, type_arguments, other, |
4012 other_type_arguments, bound_error, bound_trail, | 3871 other_type_arguments, bound_error, bound_trail, |
4013 space); | 3872 space); |
4014 } | 3873 } |
4015 | 3874 |
4016 | |
4017 bool Class::IsTopLevel() const { | 3875 bool Class::IsTopLevel() const { |
4018 return Name() == Symbols::TopLevel().raw(); | 3876 return Name() == Symbols::TopLevel().raw(); |
4019 } | 3877 } |
4020 | 3878 |
4021 | |
4022 bool Class::IsPrivate() const { | 3879 bool Class::IsPrivate() const { |
4023 return Library::IsPrivate(String::Handle(Name())); | 3880 return Library::IsPrivate(String::Handle(Name())); |
4024 } | 3881 } |
4025 | 3882 |
4026 | |
4027 RawFunction* Class::LookupDynamicFunction(const String& name) const { | 3883 RawFunction* Class::LookupDynamicFunction(const String& name) const { |
4028 return LookupFunction(name, kInstance); | 3884 return LookupFunction(name, kInstance); |
4029 } | 3885 } |
4030 | 3886 |
4031 | |
4032 RawFunction* Class::LookupDynamicFunctionAllowAbstract( | 3887 RawFunction* Class::LookupDynamicFunctionAllowAbstract( |
4033 const String& name) const { | 3888 const String& name) const { |
4034 return LookupFunction(name, kInstanceAllowAbstract); | 3889 return LookupFunction(name, kInstanceAllowAbstract); |
4035 } | 3890 } |
4036 | 3891 |
4037 | |
4038 RawFunction* Class::LookupDynamicFunctionAllowPrivate( | 3892 RawFunction* Class::LookupDynamicFunctionAllowPrivate( |
4039 const String& name) const { | 3893 const String& name) const { |
4040 return LookupFunctionAllowPrivate(name, kInstance); | 3894 return LookupFunctionAllowPrivate(name, kInstance); |
4041 } | 3895 } |
4042 | 3896 |
4043 | |
4044 RawFunction* Class::LookupStaticFunction(const String& name) const { | 3897 RawFunction* Class::LookupStaticFunction(const String& name) const { |
4045 return LookupFunction(name, kStatic); | 3898 return LookupFunction(name, kStatic); |
4046 } | 3899 } |
4047 | 3900 |
4048 | |
4049 RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const { | 3901 RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const { |
4050 return LookupFunctionAllowPrivate(name, kStatic); | 3902 return LookupFunctionAllowPrivate(name, kStatic); |
4051 } | 3903 } |
4052 | 3904 |
4053 | |
4054 RawFunction* Class::LookupConstructor(const String& name) const { | 3905 RawFunction* Class::LookupConstructor(const String& name) const { |
4055 return LookupFunction(name, kConstructor); | 3906 return LookupFunction(name, kConstructor); |
4056 } | 3907 } |
4057 | 3908 |
4058 | |
4059 RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const { | 3909 RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const { |
4060 return LookupFunctionAllowPrivate(name, kConstructor); | 3910 return LookupFunctionAllowPrivate(name, kConstructor); |
4061 } | 3911 } |
4062 | 3912 |
4063 | |
4064 RawFunction* Class::LookupFactory(const String& name) const { | 3913 RawFunction* Class::LookupFactory(const String& name) const { |
4065 return LookupFunction(name, kFactory); | 3914 return LookupFunction(name, kFactory); |
4066 } | 3915 } |
4067 | 3916 |
4068 | |
4069 RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const { | 3917 RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const { |
4070 return LookupFunctionAllowPrivate(name, kFactory); | 3918 return LookupFunctionAllowPrivate(name, kFactory); |
4071 } | 3919 } |
4072 | 3920 |
4073 | |
4074 RawFunction* Class::LookupFunction(const String& name) const { | 3921 RawFunction* Class::LookupFunction(const String& name) const { |
4075 return LookupFunction(name, kAny); | 3922 return LookupFunction(name, kAny); |
4076 } | 3923 } |
4077 | 3924 |
4078 | |
4079 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const { | 3925 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const { |
4080 return LookupFunctionAllowPrivate(name, kAny); | 3926 return LookupFunctionAllowPrivate(name, kAny); |
4081 } | 3927 } |
4082 | 3928 |
4083 | |
4084 RawFunction* Class::LookupCallFunctionForTypeTest() const { | 3929 RawFunction* Class::LookupCallFunctionForTypeTest() const { |
4085 // If this class is not compiled yet, it is too early to lookup a call | 3930 // If this class is not compiled yet, it is too early to lookup a call |
4086 // function. This case should only occur during bounds checking at compile | 3931 // function. This case should only occur during bounds checking at compile |
4087 // time. Return null as if the call method did not exist, so the type test | 3932 // time. Return null as if the call method did not exist, so the type test |
4088 // may return false, but without a bound error, and the bound check will get | 3933 // may return false, but without a bound error, and the bound check will get |
4089 // postponed to runtime. | 3934 // postponed to runtime. |
4090 if (!is_finalized()) { | 3935 if (!is_finalized()) { |
4091 return Function::null(); | 3936 return Function::null(); |
4092 } | 3937 } |
4093 Zone* zone = Thread::Current()->zone(); | 3938 Zone* zone = Thread::Current()->zone(); |
4094 Class& cls = Class::Handle(zone, raw()); | 3939 Class& cls = Class::Handle(zone, raw()); |
4095 Function& call_function = Function::Handle(zone); | 3940 Function& call_function = Function::Handle(zone); |
4096 do { | 3941 do { |
4097 ASSERT(cls.is_finalized()); | 3942 ASSERT(cls.is_finalized()); |
4098 call_function = cls.LookupDynamicFunctionAllowAbstract(Symbols::Call()); | 3943 call_function = cls.LookupDynamicFunctionAllowAbstract(Symbols::Call()); |
4099 cls = cls.SuperClass(); | 3944 cls = cls.SuperClass(); |
4100 } while (call_function.IsNull() && !cls.IsNull()); | 3945 } while (call_function.IsNull() && !cls.IsNull()); |
4101 if (!call_function.IsNull()) { | 3946 if (!call_function.IsNull()) { |
4102 // Make sure the signature is finalized before using it in a type test. | 3947 // Make sure the signature is finalized before using it in a type test. |
4103 ClassFinalizer::FinalizeSignature( | 3948 ClassFinalizer::FinalizeSignature( |
4104 cls, call_function, ClassFinalizer::kFinalize); // No bounds checking. | 3949 cls, call_function, ClassFinalizer::kFinalize); // No bounds checking. |
4105 } | 3950 } |
4106 return call_function.raw(); | 3951 return call_function.raw(); |
4107 } | 3952 } |
4108 | 3953 |
4109 | |
4110 // Returns true if 'prefix' and 'accessor_name' match 'name'. | 3954 // Returns true if 'prefix' and 'accessor_name' match 'name'. |
4111 static bool MatchesAccessorName(const String& name, | 3955 static bool MatchesAccessorName(const String& name, |
4112 const char* prefix, | 3956 const char* prefix, |
4113 intptr_t prefix_length, | 3957 intptr_t prefix_length, |
4114 const String& accessor_name) { | 3958 const String& accessor_name) { |
4115 intptr_t name_len = name.Length(); | 3959 intptr_t name_len = name.Length(); |
4116 intptr_t accessor_name_len = accessor_name.Length(); | 3960 intptr_t accessor_name_len = accessor_name.Length(); |
4117 | 3961 |
4118 if (name_len != (accessor_name_len + prefix_length)) { | 3962 if (name_len != (accessor_name_len + prefix_length)) { |
4119 return false; | 3963 return false; |
4120 } | 3964 } |
4121 for (intptr_t i = 0; i < prefix_length; i++) { | 3965 for (intptr_t i = 0; i < prefix_length; i++) { |
4122 if (name.CharAt(i) != prefix[i]) { | 3966 if (name.CharAt(i) != prefix[i]) { |
4123 return false; | 3967 return false; |
4124 } | 3968 } |
4125 } | 3969 } |
4126 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { | 3970 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { |
4127 if (name.CharAt(j) != accessor_name.CharAt(i)) { | 3971 if (name.CharAt(j) != accessor_name.CharAt(i)) { |
4128 return false; | 3972 return false; |
4129 } | 3973 } |
4130 } | 3974 } |
4131 return true; | 3975 return true; |
4132 } | 3976 } |
4133 | 3977 |
4134 | |
4135 RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) { | 3978 RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) { |
4136 if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) { | 3979 if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) { |
4137 if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) { | 3980 if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) { |
4138 return func.raw(); | 3981 return func.raw(); |
4139 } | 3982 } |
4140 } else if (kind == kStatic) { | 3983 } else if (kind == kStatic) { |
4141 if (func.IsStaticFunction()) { | 3984 if (func.IsStaticFunction()) { |
4142 return func.raw(); | 3985 return func.raw(); |
4143 } | 3986 } |
4144 } else if (kind == kConstructor) { | 3987 } else if (kind == kConstructor) { |
4145 if (func.IsGenerativeConstructor()) { | 3988 if (func.IsGenerativeConstructor()) { |
4146 ASSERT(!func.is_static()); | 3989 ASSERT(!func.is_static()); |
4147 return func.raw(); | 3990 return func.raw(); |
4148 } | 3991 } |
4149 } else if (kind == kFactory) { | 3992 } else if (kind == kFactory) { |
4150 if (func.IsFactory()) { | 3993 if (func.IsFactory()) { |
4151 ASSERT(func.is_static()); | 3994 ASSERT(func.is_static()); |
4152 return func.raw(); | 3995 return func.raw(); |
4153 } | 3996 } |
4154 } else if (kind == kAny) { | 3997 } else if (kind == kAny) { |
4155 return func.raw(); | 3998 return func.raw(); |
4156 } | 3999 } |
4157 return Function::null(); | 4000 return Function::null(); |
4158 } | 4001 } |
4159 | 4002 |
4160 | |
4161 RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { | 4003 RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { |
4162 Thread* thread = Thread::Current(); | 4004 Thread* thread = Thread::Current(); |
4163 if (EnsureIsFinalized(thread) != Error::null()) { | 4005 if (EnsureIsFinalized(thread) != Error::null()) { |
4164 return Function::null(); | 4006 return Function::null(); |
4165 } | 4007 } |
4166 REUSABLE_ARRAY_HANDLESCOPE(thread); | 4008 REUSABLE_ARRAY_HANDLESCOPE(thread); |
4167 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 4009 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
4168 Array& funcs = thread->ArrayHandle(); | 4010 Array& funcs = thread->ArrayHandle(); |
4169 funcs ^= functions(); | 4011 funcs ^= functions(); |
4170 ASSERT(!funcs.IsNull()); | 4012 ASSERT(!funcs.IsNull()); |
(...skipping 30 matching lines...) Expand all Loading... |
4201 function_name ^= function.name(); | 4043 function_name ^= function.name(); |
4202 if (function_name.Equals(name)) { | 4044 if (function_name.Equals(name)) { |
4203 return CheckFunctionType(function, kind); | 4045 return CheckFunctionType(function, kind); |
4204 } | 4046 } |
4205 } | 4047 } |
4206 } | 4048 } |
4207 // No function found. | 4049 // No function found. |
4208 return Function::null(); | 4050 return Function::null(); |
4209 } | 4051 } |
4210 | 4052 |
4211 | |
4212 RawFunction* Class::LookupFunctionAllowPrivate(const String& name, | 4053 RawFunction* Class::LookupFunctionAllowPrivate(const String& name, |
4213 MemberKind kind) const { | 4054 MemberKind kind) const { |
4214 Thread* thread = Thread::Current(); | 4055 Thread* thread = Thread::Current(); |
4215 if (EnsureIsFinalized(thread) != Error::null()) { | 4056 if (EnsureIsFinalized(thread) != Error::null()) { |
4216 return Function::null(); | 4057 return Function::null(); |
4217 } | 4058 } |
4218 REUSABLE_ARRAY_HANDLESCOPE(thread); | 4059 REUSABLE_ARRAY_HANDLESCOPE(thread); |
4219 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 4060 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
4220 REUSABLE_STRING_HANDLESCOPE(thread); | 4061 REUSABLE_STRING_HANDLESCOPE(thread); |
4221 Array& funcs = thread->ArrayHandle(); | 4062 Array& funcs = thread->ArrayHandle(); |
4222 funcs ^= functions(); | 4063 funcs ^= functions(); |
4223 ASSERT(!funcs.IsNull()); | 4064 ASSERT(!funcs.IsNull()); |
4224 const intptr_t len = funcs.Length(); | 4065 const intptr_t len = funcs.Length(); |
4225 Function& function = thread->FunctionHandle(); | 4066 Function& function = thread->FunctionHandle(); |
4226 String& function_name = thread->StringHandle(); | 4067 String& function_name = thread->StringHandle(); |
4227 for (intptr_t i = 0; i < len; i++) { | 4068 for (intptr_t i = 0; i < len; i++) { |
4228 function ^= funcs.At(i); | 4069 function ^= funcs.At(i); |
4229 function_name ^= function.name(); | 4070 function_name ^= function.name(); |
4230 if (String::EqualsIgnoringPrivateKey(function_name, name)) { | 4071 if (String::EqualsIgnoringPrivateKey(function_name, name)) { |
4231 return CheckFunctionType(function, kind); | 4072 return CheckFunctionType(function, kind); |
4232 } | 4073 } |
4233 } | 4074 } |
4234 // No function found. | 4075 // No function found. |
4235 return Function::null(); | 4076 return Function::null(); |
4236 } | 4077 } |
4237 | 4078 |
4238 | |
4239 RawFunction* Class::LookupGetterFunction(const String& name) const { | 4079 RawFunction* Class::LookupGetterFunction(const String& name) const { |
4240 return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name); | 4080 return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name); |
4241 } | 4081 } |
4242 | 4082 |
4243 | |
4244 RawFunction* Class::LookupSetterFunction(const String& name) const { | 4083 RawFunction* Class::LookupSetterFunction(const String& name) const { |
4245 return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name); | 4084 return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name); |
4246 } | 4085 } |
4247 | 4086 |
4248 | |
4249 RawFunction* Class::LookupAccessorFunction(const char* prefix, | 4087 RawFunction* Class::LookupAccessorFunction(const char* prefix, |
4250 intptr_t prefix_length, | 4088 intptr_t prefix_length, |
4251 const String& name) const { | 4089 const String& name) const { |
4252 Thread* thread = Thread::Current(); | 4090 Thread* thread = Thread::Current(); |
4253 if (EnsureIsFinalized(thread) != Error::null()) { | 4091 if (EnsureIsFinalized(thread) != Error::null()) { |
4254 return Function::null(); | 4092 return Function::null(); |
4255 } | 4093 } |
4256 REUSABLE_ARRAY_HANDLESCOPE(thread); | 4094 REUSABLE_ARRAY_HANDLESCOPE(thread); |
4257 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 4095 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
4258 REUSABLE_STRING_HANDLESCOPE(thread); | 4096 REUSABLE_STRING_HANDLESCOPE(thread); |
4259 Array& funcs = thread->ArrayHandle(); | 4097 Array& funcs = thread->ArrayHandle(); |
4260 funcs ^= functions(); | 4098 funcs ^= functions(); |
4261 intptr_t len = funcs.Length(); | 4099 intptr_t len = funcs.Length(); |
4262 Function& function = thread->FunctionHandle(); | 4100 Function& function = thread->FunctionHandle(); |
4263 String& function_name = thread->StringHandle(); | 4101 String& function_name = thread->StringHandle(); |
4264 for (intptr_t i = 0; i < len; i++) { | 4102 for (intptr_t i = 0; i < len; i++) { |
4265 function ^= funcs.At(i); | 4103 function ^= funcs.At(i); |
4266 function_name ^= function.name(); | 4104 function_name ^= function.name(); |
4267 if (MatchesAccessorName(function_name, prefix, prefix_length, name)) { | 4105 if (MatchesAccessorName(function_name, prefix, prefix_length, name)) { |
4268 return function.raw(); | 4106 return function.raw(); |
4269 } | 4107 } |
4270 } | 4108 } |
4271 | 4109 |
4272 // No function found. | 4110 // No function found. |
4273 return Function::null(); | 4111 return Function::null(); |
4274 } | 4112 } |
4275 | 4113 |
4276 | |
4277 RawField* Class::LookupInstanceField(const String& name) const { | 4114 RawField* Class::LookupInstanceField(const String& name) const { |
4278 return LookupField(name, kInstance); | 4115 return LookupField(name, kInstance); |
4279 } | 4116 } |
4280 | 4117 |
4281 | |
4282 RawField* Class::LookupStaticField(const String& name) const { | 4118 RawField* Class::LookupStaticField(const String& name) const { |
4283 return LookupField(name, kStatic); | 4119 return LookupField(name, kStatic); |
4284 } | 4120 } |
4285 | 4121 |
4286 | |
4287 RawField* Class::LookupField(const String& name) const { | 4122 RawField* Class::LookupField(const String& name) const { |
4288 return LookupField(name, kAny); | 4123 return LookupField(name, kAny); |
4289 } | 4124 } |
4290 | 4125 |
4291 | |
4292 RawField* Class::LookupField(const String& name, MemberKind kind) const { | 4126 RawField* Class::LookupField(const String& name, MemberKind kind) const { |
4293 Thread* thread = Thread::Current(); | 4127 Thread* thread = Thread::Current(); |
4294 if (EnsureIsFinalized(thread) != Error::null()) { | 4128 if (EnsureIsFinalized(thread) != Error::null()) { |
4295 return Field::null(); | 4129 return Field::null(); |
4296 } | 4130 } |
4297 REUSABLE_ARRAY_HANDLESCOPE(thread); | 4131 REUSABLE_ARRAY_HANDLESCOPE(thread); |
4298 REUSABLE_FIELD_HANDLESCOPE(thread); | 4132 REUSABLE_FIELD_HANDLESCOPE(thread); |
4299 REUSABLE_STRING_HANDLESCOPE(thread); | 4133 REUSABLE_STRING_HANDLESCOPE(thread); |
4300 Array& flds = thread->ArrayHandle(); | 4134 Array& flds = thread->ArrayHandle(); |
4301 flds ^= fields(); | 4135 flds ^= fields(); |
(...skipping 26 matching lines...) Expand all Loading... |
4328 return field.is_static() ? field.raw() : Field::null(); | 4162 return field.is_static() ? field.raw() : Field::null(); |
4329 } | 4163 } |
4330 ASSERT(kind == kAny); | 4164 ASSERT(kind == kAny); |
4331 return field.raw(); | 4165 return field.raw(); |
4332 } | 4166 } |
4333 } | 4167 } |
4334 } | 4168 } |
4335 return Field::null(); | 4169 return Field::null(); |
4336 } | 4170 } |
4337 | 4171 |
4338 | |
4339 RawField* Class::LookupFieldAllowPrivate(const String& name, | 4172 RawField* Class::LookupFieldAllowPrivate(const String& name, |
4340 bool instance_only) const { | 4173 bool instance_only) const { |
4341 // Use slow string compare, ignoring privacy name mangling. | 4174 // Use slow string compare, ignoring privacy name mangling. |
4342 Thread* thread = Thread::Current(); | 4175 Thread* thread = Thread::Current(); |
4343 if (EnsureIsFinalized(thread) != Error::null()) { | 4176 if (EnsureIsFinalized(thread) != Error::null()) { |
4344 return Field::null(); | 4177 return Field::null(); |
4345 } | 4178 } |
4346 REUSABLE_ARRAY_HANDLESCOPE(thread); | 4179 REUSABLE_ARRAY_HANDLESCOPE(thread); |
4347 REUSABLE_FIELD_HANDLESCOPE(thread); | 4180 REUSABLE_FIELD_HANDLESCOPE(thread); |
4348 REUSABLE_STRING_HANDLESCOPE(thread); | 4181 REUSABLE_STRING_HANDLESCOPE(thread); |
(...skipping 10 matching lines...) Expand all Loading... |
4359 // If we only care about instance fields, skip statics. | 4192 // If we only care about instance fields, skip statics. |
4360 continue; | 4193 continue; |
4361 } | 4194 } |
4362 if (String::EqualsIgnoringPrivateKey(field_name, name)) { | 4195 if (String::EqualsIgnoringPrivateKey(field_name, name)) { |
4363 return field.raw(); | 4196 return field.raw(); |
4364 } | 4197 } |
4365 } | 4198 } |
4366 return Field::null(); | 4199 return Field::null(); |
4367 } | 4200 } |
4368 | 4201 |
4369 | |
4370 RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const { | 4202 RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const { |
4371 Field& field = Field::Handle(LookupFieldAllowPrivate(name, true)); | 4203 Field& field = Field::Handle(LookupFieldAllowPrivate(name, true)); |
4372 if (!field.IsNull() && !field.is_static()) { | 4204 if (!field.IsNull() && !field.is_static()) { |
4373 return field.raw(); | 4205 return field.raw(); |
4374 } | 4206 } |
4375 return Field::null(); | 4207 return Field::null(); |
4376 } | 4208 } |
4377 | 4209 |
4378 | |
4379 RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const { | 4210 RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const { |
4380 Field& field = Field::Handle(LookupFieldAllowPrivate(name)); | 4211 Field& field = Field::Handle(LookupFieldAllowPrivate(name)); |
4381 if (!field.IsNull() && field.is_static()) { | 4212 if (!field.IsNull() && field.is_static()) { |
4382 return field.raw(); | 4213 return field.raw(); |
4383 } | 4214 } |
4384 return Field::null(); | 4215 return Field::null(); |
4385 } | 4216 } |
4386 | 4217 |
4387 | |
4388 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const { | 4218 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const { |
4389 Zone* zone = Thread::Current()->zone(); | 4219 Zone* zone = Thread::Current()->zone(); |
4390 const Library& lib = Library::Handle(zone, library()); | 4220 const Library& lib = Library::Handle(zone, library()); |
4391 const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); | 4221 const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); |
4392 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 4222 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
4393 return LibraryPrefix::Cast(obj).raw(); | 4223 return LibraryPrefix::Cast(obj).raw(); |
4394 } | 4224 } |
4395 return LibraryPrefix::null(); | 4225 return LibraryPrefix::null(); |
4396 } | 4226 } |
4397 | 4227 |
4398 | |
4399 const char* Class::ToCString() const { | 4228 const char* Class::ToCString() const { |
4400 const Library& lib = Library::Handle(library()); | 4229 const Library& lib = Library::Handle(library()); |
4401 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); | 4230 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); |
4402 const char* patch_prefix = is_patch() ? "Patch " : ""; | 4231 const char* patch_prefix = is_patch() ? "Patch " : ""; |
4403 const char* class_name = String::Handle(Name()).ToCString(); | 4232 const char* class_name = String::Handle(Name()).ToCString(); |
4404 return OS::SCreate(Thread::Current()->zone(), "%s %sClass: %s", library_name, | 4233 return OS::SCreate(Thread::Current()->zone(), "%s %sClass: %s", library_name, |
4405 patch_prefix, class_name); | 4234 patch_prefix, class_name); |
4406 } | 4235 } |
4407 | 4236 |
4408 | |
4409 // Returns an instance of Double or Double::null(). | 4237 // Returns an instance of Double or Double::null(). |
4410 // 'index' points to either: | 4238 // 'index' points to either: |
4411 // - constants_list_ position of found element, or | 4239 // - constants_list_ position of found element, or |
4412 // - constants_list_ position where new canonical can be inserted. | 4240 // - constants_list_ position where new canonical can be inserted. |
4413 RawDouble* Class::LookupCanonicalDouble(Zone* zone, | 4241 RawDouble* Class::LookupCanonicalDouble(Zone* zone, |
4414 double value, | 4242 double value, |
4415 intptr_t* index) const { | 4243 intptr_t* index) const { |
4416 ASSERT(this->raw() == Isolate::Current()->object_store()->double_class()); | 4244 ASSERT(this->raw() == Isolate::Current()->object_store()->double_class()); |
4417 const Array& constants = Array::Handle(zone, this->constants()); | 4245 const Array& constants = Array::Handle(zone, this->constants()); |
4418 const intptr_t constants_len = constants.Length(); | 4246 const intptr_t constants_len = constants.Length(); |
4419 // Linear search to see whether this value is already present in the | 4247 // Linear search to see whether this value is already present in the |
4420 // list of canonicalized constants. | 4248 // list of canonicalized constants. |
4421 Double& canonical_value = Double::Handle(zone); | 4249 Double& canonical_value = Double::Handle(zone); |
4422 while (*index < constants_len) { | 4250 while (*index < constants_len) { |
4423 canonical_value ^= constants.At(*index); | 4251 canonical_value ^= constants.At(*index); |
4424 if (canonical_value.IsNull()) { | 4252 if (canonical_value.IsNull()) { |
4425 break; | 4253 break; |
4426 } | 4254 } |
4427 if (canonical_value.BitwiseEqualsToDouble(value)) { | 4255 if (canonical_value.BitwiseEqualsToDouble(value)) { |
4428 ASSERT(canonical_value.IsCanonical()); | 4256 ASSERT(canonical_value.IsCanonical()); |
4429 return canonical_value.raw(); | 4257 return canonical_value.raw(); |
4430 } | 4258 } |
4431 *index = *index + 1; | 4259 *index = *index + 1; |
4432 } | 4260 } |
4433 return Double::null(); | 4261 return Double::null(); |
4434 } | 4262 } |
4435 | 4263 |
4436 | |
4437 RawMint* Class::LookupCanonicalMint(Zone* zone, | 4264 RawMint* Class::LookupCanonicalMint(Zone* zone, |
4438 int64_t value, | 4265 int64_t value, |
4439 intptr_t* index) const { | 4266 intptr_t* index) const { |
4440 ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class()); | 4267 ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class()); |
4441 const Array& constants = Array::Handle(zone, this->constants()); | 4268 const Array& constants = Array::Handle(zone, this->constants()); |
4442 const intptr_t constants_len = constants.Length(); | 4269 const intptr_t constants_len = constants.Length(); |
4443 // Linear search to see whether this value is already present in the | 4270 // Linear search to see whether this value is already present in the |
4444 // list of canonicalized constants. | 4271 // list of canonicalized constants. |
4445 Mint& canonical_value = Mint::Handle(zone); | 4272 Mint& canonical_value = Mint::Handle(zone); |
4446 while (*index < constants_len) { | 4273 while (*index < constants_len) { |
4447 canonical_value ^= constants.At(*index); | 4274 canonical_value ^= constants.At(*index); |
4448 if (canonical_value.IsNull()) { | 4275 if (canonical_value.IsNull()) { |
4449 break; | 4276 break; |
4450 } | 4277 } |
4451 if (canonical_value.value() == value) { | 4278 if (canonical_value.value() == value) { |
4452 ASSERT(canonical_value.IsCanonical()); | 4279 ASSERT(canonical_value.IsCanonical()); |
4453 return canonical_value.raw(); | 4280 return canonical_value.raw(); |
4454 } | 4281 } |
4455 *index = *index + 1; | 4282 *index = *index + 1; |
4456 } | 4283 } |
4457 return Mint::null(); | 4284 return Mint::null(); |
4458 } | 4285 } |
4459 | 4286 |
4460 | |
4461 RawBigint* Class::LookupCanonicalBigint(Zone* zone, | 4287 RawBigint* Class::LookupCanonicalBigint(Zone* zone, |
4462 const Bigint& value, | 4288 const Bigint& value, |
4463 intptr_t* index) const { | 4289 intptr_t* index) const { |
4464 ASSERT(this->raw() == Isolate::Current()->object_store()->bigint_class()); | 4290 ASSERT(this->raw() == Isolate::Current()->object_store()->bigint_class()); |
4465 const Array& constants = Array::Handle(zone, this->constants()); | 4291 const Array& constants = Array::Handle(zone, this->constants()); |
4466 const intptr_t constants_len = constants.Length(); | 4292 const intptr_t constants_len = constants.Length(); |
4467 // Linear search to see whether this value is already present in the | 4293 // Linear search to see whether this value is already present in the |
4468 // list of canonicalized constants. | 4294 // list of canonicalized constants. |
4469 Bigint& canonical_value = Bigint::Handle(zone); | 4295 Bigint& canonical_value = Bigint::Handle(zone); |
4470 while (*index < constants_len) { | 4296 while (*index < constants_len) { |
4471 canonical_value ^= constants.At(*index); | 4297 canonical_value ^= constants.At(*index); |
4472 if (canonical_value.IsNull()) { | 4298 if (canonical_value.IsNull()) { |
4473 break; | 4299 break; |
4474 } | 4300 } |
4475 if (canonical_value.Equals(value)) { | 4301 if (canonical_value.Equals(value)) { |
4476 ASSERT(canonical_value.IsCanonical()); | 4302 ASSERT(canonical_value.IsCanonical()); |
4477 return canonical_value.raw(); | 4303 return canonical_value.raw(); |
4478 } | 4304 } |
4479 *index = *index + 1; | 4305 *index = *index + 1; |
4480 } | 4306 } |
4481 return Bigint::null(); | 4307 return Bigint::null(); |
4482 } | 4308 } |
4483 | 4309 |
4484 | |
4485 class CanonicalInstanceKey { | 4310 class CanonicalInstanceKey { |
4486 public: | 4311 public: |
4487 explicit CanonicalInstanceKey(const Instance& key) : key_(key) { | 4312 explicit CanonicalInstanceKey(const Instance& key) : key_(key) { |
4488 ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType())); | 4313 ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType())); |
4489 } | 4314 } |
4490 bool Matches(const Instance& obj) const { | 4315 bool Matches(const Instance& obj) const { |
4491 ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType())); | 4316 ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType())); |
4492 if (key_.CanonicalizeEquals(obj)) { | 4317 if (key_.CanonicalizeEquals(obj)) { |
4493 ASSERT(obj.IsCanonical()); | 4318 ASSERT(obj.IsCanonical()); |
4494 return true; | 4319 return true; |
4495 } | 4320 } |
4496 return false; | 4321 return false; |
4497 } | 4322 } |
4498 uword Hash() const { return key_.ComputeCanonicalTableHash(); } | 4323 uword Hash() const { return key_.ComputeCanonicalTableHash(); } |
4499 const Instance& key_; | 4324 const Instance& key_; |
4500 | 4325 |
4501 private: | 4326 private: |
4502 DISALLOW_ALLOCATION(); | 4327 DISALLOW_ALLOCATION(); |
4503 }; | 4328 }; |
4504 | 4329 |
4505 | |
4506 // Traits for looking up Canonical Instances based on a hash of the fields. | 4330 // Traits for looking up Canonical Instances based on a hash of the fields. |
4507 class CanonicalInstanceTraits { | 4331 class CanonicalInstanceTraits { |
4508 public: | 4332 public: |
4509 static const char* Name() { return "CanonicalInstanceTraits"; } | 4333 static const char* Name() { return "CanonicalInstanceTraits"; } |
4510 static bool ReportStats() { return false; } | 4334 static bool ReportStats() { return false; } |
4511 | 4335 |
4512 // Called when growing the table. | 4336 // Called when growing the table. |
4513 static bool IsMatch(const Object& a, const Object& b) { | 4337 static bool IsMatch(const Object& a, const Object& b) { |
4514 ASSERT(!(a.IsString() || a.IsInteger() || a.IsAbstractType())); | 4338 ASSERT(!(a.IsString() || a.IsInteger() || a.IsAbstractType())); |
4515 ASSERT(!(b.IsString() || b.IsInteger() || b.IsAbstractType())); | 4339 ASSERT(!(b.IsString() || b.IsInteger() || b.IsAbstractType())); |
4516 return a.raw() == b.raw(); | 4340 return a.raw() == b.raw(); |
4517 } | 4341 } |
4518 static bool IsMatch(const CanonicalInstanceKey& a, const Object& b) { | 4342 static bool IsMatch(const CanonicalInstanceKey& a, const Object& b) { |
4519 return a.Matches(Instance::Cast(b)); | 4343 return a.Matches(Instance::Cast(b)); |
4520 } | 4344 } |
4521 static uword Hash(const Object& key) { | 4345 static uword Hash(const Object& key) { |
4522 ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType())); | 4346 ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType())); |
4523 ASSERT(key.IsInstance()); | 4347 ASSERT(key.IsInstance()); |
4524 return Instance::Cast(key).ComputeCanonicalTableHash(); | 4348 return Instance::Cast(key).ComputeCanonicalTableHash(); |
4525 } | 4349 } |
4526 static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); } | 4350 static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); } |
4527 static RawObject* NewKey(const CanonicalInstanceKey& obj) { | 4351 static RawObject* NewKey(const CanonicalInstanceKey& obj) { |
4528 return obj.key_.raw(); | 4352 return obj.key_.raw(); |
4529 } | 4353 } |
4530 }; | 4354 }; |
4531 typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet; | 4355 typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet; |
4532 | 4356 |
4533 | |
4534 RawInstance* Class::LookupCanonicalInstance(Zone* zone, | 4357 RawInstance* Class::LookupCanonicalInstance(Zone* zone, |
4535 const Instance& value) const { | 4358 const Instance& value) const { |
4536 ASSERT(this->raw() == value.clazz()); | 4359 ASSERT(this->raw() == value.clazz()); |
4537 ASSERT(is_finalized()); | 4360 ASSERT(is_finalized()); |
4538 Instance& canonical_value = Instance::Handle(zone); | 4361 Instance& canonical_value = Instance::Handle(zone); |
4539 if (this->constants() != Object::empty_array().raw()) { | 4362 if (this->constants() != Object::empty_array().raw()) { |
4540 CanonicalInstancesSet constants(zone, this->constants()); | 4363 CanonicalInstancesSet constants(zone, this->constants()); |
4541 canonical_value ^= constants.GetOrNull(CanonicalInstanceKey(value)); | 4364 canonical_value ^= constants.GetOrNull(CanonicalInstanceKey(value)); |
4542 this->set_constants(constants.Release()); | 4365 this->set_constants(constants.Release()); |
4543 } | 4366 } |
4544 return canonical_value.raw(); | 4367 return canonical_value.raw(); |
4545 } | 4368 } |
4546 | 4369 |
4547 | |
4548 RawInstance* Class::InsertCanonicalConstant(Zone* zone, | 4370 RawInstance* Class::InsertCanonicalConstant(Zone* zone, |
4549 const Instance& constant) const { | 4371 const Instance& constant) const { |
4550 ASSERT(this->raw() == constant.clazz()); | 4372 ASSERT(this->raw() == constant.clazz()); |
4551 Instance& canonical_value = Instance::Handle(zone); | 4373 Instance& canonical_value = Instance::Handle(zone); |
4552 if (this->constants() == Object::empty_array().raw()) { | 4374 if (this->constants() == Object::empty_array().raw()) { |
4553 CanonicalInstancesSet constants( | 4375 CanonicalInstancesSet constants( |
4554 HashTables::New<CanonicalInstancesSet>(128, Heap::kOld)); | 4376 HashTables::New<CanonicalInstancesSet>(128, Heap::kOld)); |
4555 canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); | 4377 canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); |
4556 this->set_constants(constants.Release()); | 4378 this->set_constants(constants.Release()); |
4557 } else { | 4379 } else { |
4558 CanonicalInstancesSet constants(Thread::Current()->zone(), | 4380 CanonicalInstancesSet constants(Thread::Current()->zone(), |
4559 this->constants()); | 4381 this->constants()); |
4560 canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); | 4382 canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); |
4561 this->set_constants(constants.Release()); | 4383 this->set_constants(constants.Release()); |
4562 } | 4384 } |
4563 return canonical_value.raw(); | 4385 return canonical_value.raw(); |
4564 } | 4386 } |
4565 | 4387 |
4566 | |
4567 void Class::InsertCanonicalNumber(Zone* zone, | 4388 void Class::InsertCanonicalNumber(Zone* zone, |
4568 intptr_t index, | 4389 intptr_t index, |
4569 const Number& constant) const { | 4390 const Number& constant) const { |
4570 // The constant needs to be added to the list. Grow the list if it is full. | 4391 // The constant needs to be added to the list. Grow the list if it is full. |
4571 Array& canonical_list = Array::Handle(zone, constants()); | 4392 Array& canonical_list = Array::Handle(zone, constants()); |
4572 const intptr_t list_len = canonical_list.Length(); | 4393 const intptr_t list_len = canonical_list.Length(); |
4573 if (index >= list_len) { | 4394 if (index >= list_len) { |
4574 const intptr_t new_length = list_len + 4 + (list_len >> 2); | 4395 const intptr_t new_length = list_len + 4 + (list_len >> 2); |
4575 canonical_list ^= Array::Grow(canonical_list, new_length, Heap::kOld); | 4396 canonical_list ^= Array::Grow(canonical_list, new_length, Heap::kOld); |
4576 set_constants(canonical_list); | 4397 set_constants(canonical_list); |
4577 } | 4398 } |
4578 canonical_list.SetAt(index, constant); | 4399 canonical_list.SetAt(index, constant); |
4579 } | 4400 } |
4580 | 4401 |
4581 | |
4582 void Class::RehashConstants(Zone* zone) const { | 4402 void Class::RehashConstants(Zone* zone) const { |
4583 intptr_t cid = id(); | 4403 intptr_t cid = id(); |
4584 if ((cid == kMintCid) || (cid == kBigintCid) || (cid == kDoubleCid)) { | 4404 if ((cid == kMintCid) || (cid == kBigintCid) || (cid == kDoubleCid)) { |
4585 // Constants stored as a plain list, no rehashing needed. | 4405 // Constants stored as a plain list, no rehashing needed. |
4586 return; | 4406 return; |
4587 } | 4407 } |
4588 | 4408 |
4589 const Array& old_constants = Array::Handle(zone, constants()); | 4409 const Array& old_constants = Array::Handle(zone, constants()); |
4590 if (old_constants.Length() == 0) return; | 4410 if (old_constants.Length() == 0) return; |
4591 | 4411 |
4592 set_constants(Object::empty_array()); | 4412 set_constants(Object::empty_array()); |
4593 CanonicalInstancesSet set(zone, old_constants.raw()); | 4413 CanonicalInstancesSet set(zone, old_constants.raw()); |
4594 Instance& constant = Instance::Handle(zone); | 4414 Instance& constant = Instance::Handle(zone); |
4595 CanonicalInstancesSet::Iterator it(&set); | 4415 CanonicalInstancesSet::Iterator it(&set); |
4596 while (it.MoveNext()) { | 4416 while (it.MoveNext()) { |
4597 constant ^= set.GetKey(it.Current()); | 4417 constant ^= set.GetKey(it.Current()); |
4598 ASSERT(!constant.IsNull()); | 4418 ASSERT(!constant.IsNull()); |
4599 ASSERT(constant.IsCanonical()); | 4419 ASSERT(constant.IsCanonical()); |
4600 InsertCanonicalConstant(zone, constant); | 4420 InsertCanonicalConstant(zone, constant); |
4601 } | 4421 } |
4602 set.Release(); | 4422 set.Release(); |
4603 } | 4423 } |
4604 | 4424 |
4605 | |
4606 RawUnresolvedClass* UnresolvedClass::New(const Object& library_prefix, | 4425 RawUnresolvedClass* UnresolvedClass::New(const Object& library_prefix, |
4607 const String& ident, | 4426 const String& ident, |
4608 TokenPosition token_pos) { | 4427 TokenPosition token_pos) { |
4609 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); | 4428 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); |
4610 type.set_library_or_library_prefix(library_prefix); | 4429 type.set_library_or_library_prefix(library_prefix); |
4611 type.set_ident(ident); | 4430 type.set_ident(ident); |
4612 type.set_token_pos(token_pos); | 4431 type.set_token_pos(token_pos); |
4613 return type.raw(); | 4432 return type.raw(); |
4614 } | 4433 } |
4615 | 4434 |
4616 | |
4617 RawUnresolvedClass* UnresolvedClass::New() { | 4435 RawUnresolvedClass* UnresolvedClass::New() { |
4618 ASSERT(Object::unresolved_class_class() != Class::null()); | 4436 ASSERT(Object::unresolved_class_class() != Class::null()); |
4619 RawObject* raw = Object::Allocate( | 4437 RawObject* raw = Object::Allocate( |
4620 UnresolvedClass::kClassId, UnresolvedClass::InstanceSize(), Heap::kOld); | 4438 UnresolvedClass::kClassId, UnresolvedClass::InstanceSize(), Heap::kOld); |
4621 return reinterpret_cast<RawUnresolvedClass*>(raw); | 4439 return reinterpret_cast<RawUnresolvedClass*>(raw); |
4622 } | 4440 } |
4623 | 4441 |
4624 | |
4625 void UnresolvedClass::set_token_pos(TokenPosition token_pos) const { | 4442 void UnresolvedClass::set_token_pos(TokenPosition token_pos) const { |
4626 ASSERT(!token_pos.IsClassifying()); | 4443 ASSERT(!token_pos.IsClassifying()); |
4627 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 4444 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
4628 } | 4445 } |
4629 | 4446 |
4630 | |
4631 void UnresolvedClass::set_ident(const String& ident) const { | 4447 void UnresolvedClass::set_ident(const String& ident) const { |
4632 StorePointer(&raw_ptr()->ident_, ident.raw()); | 4448 StorePointer(&raw_ptr()->ident_, ident.raw()); |
4633 } | 4449 } |
4634 | 4450 |
4635 | |
4636 void UnresolvedClass::set_library_or_library_prefix( | 4451 void UnresolvedClass::set_library_or_library_prefix( |
4637 const Object& library_prefix) const { | 4452 const Object& library_prefix) const { |
4638 StorePointer(&raw_ptr()->library_or_library_prefix_, library_prefix.raw()); | 4453 StorePointer(&raw_ptr()->library_or_library_prefix_, library_prefix.raw()); |
4639 } | 4454 } |
4640 | 4455 |
4641 | |
4642 RawString* UnresolvedClass::Name() const { | 4456 RawString* UnresolvedClass::Name() const { |
4643 if (library_or_library_prefix() != Object::null()) { | 4457 if (library_or_library_prefix() != Object::null()) { |
4644 Thread* thread = Thread::Current(); | 4458 Thread* thread = Thread::Current(); |
4645 Zone* zone = thread->zone(); | 4459 Zone* zone = thread->zone(); |
4646 const Object& lib_prefix = | 4460 const Object& lib_prefix = |
4647 Object::Handle(zone, library_or_library_prefix()); | 4461 Object::Handle(zone, library_or_library_prefix()); |
4648 String& name = String::Handle(zone); // Qualifier. | 4462 String& name = String::Handle(zone); // Qualifier. |
4649 if (lib_prefix.IsLibraryPrefix()) { | 4463 if (lib_prefix.IsLibraryPrefix()) { |
4650 name = LibraryPrefix::Cast(lib_prefix).name(); | 4464 name = LibraryPrefix::Cast(lib_prefix).name(); |
4651 } else { | 4465 } else { |
4652 name = Library::Cast(lib_prefix).name(); | 4466 name = Library::Cast(lib_prefix).name(); |
4653 } | 4467 } |
4654 GrowableHandlePtrArray<const String> strs(zone, 3); | 4468 GrowableHandlePtrArray<const String> strs(zone, 3); |
4655 strs.Add(name); | 4469 strs.Add(name); |
4656 strs.Add(Symbols::Dot()); | 4470 strs.Add(Symbols::Dot()); |
4657 strs.Add(String::Handle(zone, ident())); | 4471 strs.Add(String::Handle(zone, ident())); |
4658 return Symbols::FromConcatAll(thread, strs); | 4472 return Symbols::FromConcatAll(thread, strs); |
4659 } else { | 4473 } else { |
4660 return ident(); | 4474 return ident(); |
4661 } | 4475 } |
4662 } | 4476 } |
4663 | 4477 |
4664 | |
4665 const char* UnresolvedClass::ToCString() const { | 4478 const char* UnresolvedClass::ToCString() const { |
4666 const char* cname = String::Handle(Name()).ToCString(); | 4479 const char* cname = String::Handle(Name()).ToCString(); |
4667 return OS::SCreate(Thread::Current()->zone(), "unresolved class '%s'", cname); | 4480 return OS::SCreate(Thread::Current()->zone(), "unresolved class '%s'", cname); |
4668 } | 4481 } |
4669 | 4482 |
4670 | |
4671 static uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) { | 4483 static uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) { |
4672 hash += other_hash; | 4484 hash += other_hash; |
4673 hash += hash << 10; | 4485 hash += hash << 10; |
4674 hash ^= hash >> 6; // Logical shift, unsigned hash. | 4486 hash ^= hash >> 6; // Logical shift, unsigned hash. |
4675 return hash; | 4487 return hash; |
4676 } | 4488 } |
4677 | 4489 |
4678 | |
4679 static uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) { | 4490 static uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) { |
4680 hash += hash << 3; | 4491 hash += hash << 3; |
4681 hash ^= hash >> 11; // Logical shift, unsigned hash. | 4492 hash ^= hash >> 11; // Logical shift, unsigned hash. |
4682 hash += hash << 15; | 4493 hash += hash << 15; |
4683 // FinalizeHash gets called with values for hashbits that are bigger than 31 | 4494 // FinalizeHash gets called with values for hashbits that are bigger than 31 |
4684 // (like kBitsPerWord - 1). Therefore we are careful to use a type | 4495 // (like kBitsPerWord - 1). Therefore we are careful to use a type |
4685 // (uintptr_t) big enough to avoid undefined behavior with the left shift. | 4496 // (uintptr_t) big enough to avoid undefined behavior with the left shift. |
4686 hash &= (static_cast<uintptr_t>(1) << hashbits) - 1; | 4497 hash &= (static_cast<uintptr_t>(1) << hashbits) - 1; |
4687 return (hash == 0) ? 1 : hash; | 4498 return (hash == 0) ? 1 : hash; |
4688 } | 4499 } |
4689 | 4500 |
4690 | |
4691 intptr_t TypeArguments::ComputeHash() const { | 4501 intptr_t TypeArguments::ComputeHash() const { |
4692 if (IsNull()) return 0; | 4502 if (IsNull()) return 0; |
4693 const intptr_t num_types = Length(); | 4503 const intptr_t num_types = Length(); |
4694 if (IsRaw(0, num_types)) return 0; | 4504 if (IsRaw(0, num_types)) return 0; |
4695 uint32_t result = 0; | 4505 uint32_t result = 0; |
4696 AbstractType& type = AbstractType::Handle(); | 4506 AbstractType& type = AbstractType::Handle(); |
4697 for (intptr_t i = 0; i < num_types; i++) { | 4507 for (intptr_t i = 0; i < num_types; i++) { |
4698 type = TypeAt(i); | 4508 type = TypeAt(i); |
4699 // The hash may be calculated during type finalization (for debugging | 4509 // The hash may be calculated during type finalization (for debugging |
4700 // purposes only) while a type argument is still temporarily null. | 4510 // purposes only) while a type argument is still temporarily null. |
4701 result = CombineHashes(result, type.IsNull() ? 0 : type.Hash()); | 4511 result = CombineHashes(result, type.IsNull() ? 0 : type.Hash()); |
4702 } | 4512 } |
4703 result = FinalizeHash(result, kHashBits); | 4513 result = FinalizeHash(result, kHashBits); |
4704 SetHash(result); | 4514 SetHash(result); |
4705 return result; | 4515 return result; |
4706 } | 4516 } |
4707 | 4517 |
4708 | |
4709 RawString* TypeArguments::SubvectorName(intptr_t from_index, | 4518 RawString* TypeArguments::SubvectorName(intptr_t from_index, |
4710 intptr_t len, | 4519 intptr_t len, |
4711 NameVisibility name_visibility) const { | 4520 NameVisibility name_visibility) const { |
4712 Thread* thread = Thread::Current(); | 4521 Thread* thread = Thread::Current(); |
4713 Zone* zone = thread->zone(); | 4522 Zone* zone = thread->zone(); |
4714 ASSERT(from_index + len <= Length()); | 4523 ASSERT(from_index + len <= Length()); |
4715 String& name = String::Handle(zone); | 4524 String& name = String::Handle(zone); |
4716 const intptr_t num_strings = | 4525 const intptr_t num_strings = |
4717 (len == 0) ? 2 : 2 * len + 1; // "<""T"", ""T"">". | 4526 (len == 0) ? 2 : 2 * len + 1; // "<""T"", ""T"">". |
4718 GrowableHandlePtrArray<const String> pieces(zone, num_strings); | 4527 GrowableHandlePtrArray<const String> pieces(zone, num_strings); |
4719 pieces.Add(Symbols::LAngleBracket()); | 4528 pieces.Add(Symbols::LAngleBracket()); |
4720 AbstractType& type = AbstractType::Handle(zone); | 4529 AbstractType& type = AbstractType::Handle(zone); |
4721 for (intptr_t i = 0; i < len; i++) { | 4530 for (intptr_t i = 0; i < len; i++) { |
4722 type = TypeAt(from_index + i); | 4531 type = TypeAt(from_index + i); |
4723 name = type.BuildName(name_visibility); | 4532 name = type.BuildName(name_visibility); |
4724 pieces.Add(name); | 4533 pieces.Add(name); |
4725 if (i < len - 1) { | 4534 if (i < len - 1) { |
4726 pieces.Add(Symbols::CommaSpace()); | 4535 pieces.Add(Symbols::CommaSpace()); |
4727 } | 4536 } |
4728 } | 4537 } |
4729 pieces.Add(Symbols::RAngleBracket()); | 4538 pieces.Add(Symbols::RAngleBracket()); |
4730 ASSERT(pieces.length() == num_strings); | 4539 ASSERT(pieces.length() == num_strings); |
4731 return Symbols::FromConcatAll(thread, pieces); | 4540 return Symbols::FromConcatAll(thread, pieces); |
4732 } | 4541 } |
4733 | 4542 |
4734 | |
4735 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other, | 4543 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other, |
4736 intptr_t from_index, | 4544 intptr_t from_index, |
4737 intptr_t len, | 4545 intptr_t len, |
4738 TrailPtr trail) const { | 4546 TrailPtr trail) const { |
4739 if (this->raw() == other.raw()) { | 4547 if (this->raw() == other.raw()) { |
4740 return true; | 4548 return true; |
4741 } | 4549 } |
4742 if (IsNull() || other.IsNull()) { | 4550 if (IsNull() || other.IsNull()) { |
4743 return false; | 4551 return false; |
4744 } | 4552 } |
4745 const intptr_t num_types = Length(); | 4553 const intptr_t num_types = Length(); |
4746 if (num_types != other.Length()) { | 4554 if (num_types != other.Length()) { |
4747 return false; | 4555 return false; |
4748 } | 4556 } |
4749 AbstractType& type = AbstractType::Handle(); | 4557 AbstractType& type = AbstractType::Handle(); |
4750 AbstractType& other_type = AbstractType::Handle(); | 4558 AbstractType& other_type = AbstractType::Handle(); |
4751 for (intptr_t i = from_index; i < from_index + len; i++) { | 4559 for (intptr_t i = from_index; i < from_index + len; i++) { |
4752 type = TypeAt(i); | 4560 type = TypeAt(i); |
4753 other_type = other.TypeAt(i); | 4561 other_type = other.TypeAt(i); |
4754 if (!type.IsNull() && !type.IsEquivalent(other_type, trail)) { | 4562 if (!type.IsNull() && !type.IsEquivalent(other_type, trail)) { |
4755 return false; | 4563 return false; |
4756 } | 4564 } |
4757 } | 4565 } |
4758 return true; | 4566 return true; |
4759 } | 4567 } |
4760 | 4568 |
4761 | |
4762 bool TypeArguments::IsRecursive() const { | 4569 bool TypeArguments::IsRecursive() const { |
4763 if (IsNull()) return false; | 4570 if (IsNull()) return false; |
4764 const intptr_t num_types = Length(); | 4571 const intptr_t num_types = Length(); |
4765 AbstractType& type = AbstractType::Handle(); | 4572 AbstractType& type = AbstractType::Handle(); |
4766 for (intptr_t i = 0; i < num_types; i++) { | 4573 for (intptr_t i = 0; i < num_types; i++) { |
4767 type = TypeAt(i); | 4574 type = TypeAt(i); |
4768 // If this type argument is null, the type parameterized with this type | 4575 // If this type argument is null, the type parameterized with this type |
4769 // argument is still being finalized and is definitely recursive. The null | 4576 // argument is still being finalized and is definitely recursive. The null |
4770 // type argument will be replaced by a non-null type before the type is | 4577 // type argument will be replaced by a non-null type before the type is |
4771 // marked as finalized. | 4578 // marked as finalized. |
4772 if (type.IsNull() || type.IsRecursive()) { | 4579 if (type.IsNull() || type.IsRecursive()) { |
4773 return true; | 4580 return true; |
4774 } | 4581 } |
4775 } | 4582 } |
4776 return false; | 4583 return false; |
4777 } | 4584 } |
4778 | 4585 |
4779 | |
4780 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, | 4586 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, |
4781 intptr_t from_index, | 4587 intptr_t from_index, |
4782 intptr_t len) const { | 4588 intptr_t len) const { |
4783 ASSERT(Length() >= (from_index + len)); | 4589 ASSERT(Length() >= (from_index + len)); |
4784 AbstractType& type = AbstractType::Handle(); | 4590 AbstractType& type = AbstractType::Handle(); |
4785 Class& type_class = Class::Handle(); | 4591 Class& type_class = Class::Handle(); |
4786 for (intptr_t i = 0; i < len; i++) { | 4592 for (intptr_t i = 0; i < len; i++) { |
4787 type = TypeAt(from_index + i); | 4593 type = TypeAt(from_index + i); |
4788 if (type.IsNull()) { | 4594 if (type.IsNull()) { |
4789 return false; | 4595 return false; |
4790 } | 4596 } |
4791 if (!type.HasResolvedTypeClass()) { | 4597 if (!type.HasResolvedTypeClass()) { |
4792 if (raw_instantiated && type.IsTypeParameter()) { | 4598 if (raw_instantiated && type.IsTypeParameter()) { |
4793 // An uninstantiated type parameter is equivalent to dynamic (even in | 4599 // An uninstantiated type parameter is equivalent to dynamic (even in |
4794 // the presence of a malformed bound in checked mode). | 4600 // the presence of a malformed bound in checked mode). |
4795 continue; | 4601 continue; |
4796 } | 4602 } |
4797 return false; | 4603 return false; |
4798 } | 4604 } |
4799 type_class = type.type_class(); | 4605 type_class = type.type_class(); |
4800 if (!type_class.IsDynamicClass()) { | 4606 if (!type_class.IsDynamicClass()) { |
4801 return false; | 4607 return false; |
4802 } | 4608 } |
4803 } | 4609 } |
4804 return true; | 4610 return true; |
4805 } | 4611 } |
4806 | 4612 |
4807 | |
4808 bool TypeArguments::TypeTest(TypeTestKind test_kind, | 4613 bool TypeArguments::TypeTest(TypeTestKind test_kind, |
4809 const TypeArguments& other, | 4614 const TypeArguments& other, |
4810 intptr_t from_index, | 4615 intptr_t from_index, |
4811 intptr_t len, | 4616 intptr_t len, |
4812 Error* bound_error, | 4617 Error* bound_error, |
4813 TrailPtr bound_trail, | 4618 TrailPtr bound_trail, |
4814 Heap::Space space) const { | 4619 Heap::Space space) const { |
4815 ASSERT(Length() >= (from_index + len)); | 4620 ASSERT(Length() >= (from_index + len)); |
4816 ASSERT(!other.IsNull()); | 4621 ASSERT(!other.IsNull()); |
4817 ASSERT(other.Length() >= (from_index + len)); | 4622 ASSERT(other.Length() >= (from_index + len)); |
4818 AbstractType& type = AbstractType::Handle(); | 4623 AbstractType& type = AbstractType::Handle(); |
4819 AbstractType& other_type = AbstractType::Handle(); | 4624 AbstractType& other_type = AbstractType::Handle(); |
4820 for (intptr_t i = 0; i < len; i++) { | 4625 for (intptr_t i = 0; i < len; i++) { |
4821 type = TypeAt(from_index + i); | 4626 type = TypeAt(from_index + i); |
4822 other_type = other.TypeAt(from_index + i); | 4627 other_type = other.TypeAt(from_index + i); |
4823 if (type.IsNull() || other_type.IsNull() || | 4628 if (type.IsNull() || other_type.IsNull() || |
4824 !type.TypeTest(test_kind, other_type, bound_error, bound_trail, | 4629 !type.TypeTest(test_kind, other_type, bound_error, bound_trail, |
4825 space)) { | 4630 space)) { |
4826 return false; | 4631 return false; |
4827 } | 4632 } |
4828 } | 4633 } |
4829 return true; | 4634 return true; |
4830 } | 4635 } |
4831 | 4636 |
4832 | |
4833 bool TypeArguments::HasInstantiations() const { | 4637 bool TypeArguments::HasInstantiations() const { |
4834 const Array& prior_instantiations = Array::Handle(instantiations()); | 4638 const Array& prior_instantiations = Array::Handle(instantiations()); |
4835 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. | 4639 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. |
4836 return prior_instantiations.Length() > 1; | 4640 return prior_instantiations.Length() > 1; |
4837 } | 4641 } |
4838 | 4642 |
4839 | |
4840 intptr_t TypeArguments::NumInstantiations() const { | 4643 intptr_t TypeArguments::NumInstantiations() const { |
4841 const Array& prior_instantiations = Array::Handle(instantiations()); | 4644 const Array& prior_instantiations = Array::Handle(instantiations()); |
4842 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. | 4645 ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel. |
4843 intptr_t num = 0; | 4646 intptr_t num = 0; |
4844 intptr_t i = 0; | 4647 intptr_t i = 0; |
4845 while (prior_instantiations.At(i) != Smi::New(StubCode::kNoInstantiator)) { | 4648 while (prior_instantiations.At(i) != Smi::New(StubCode::kNoInstantiator)) { |
4846 i += StubCode::kInstantiationSizeInWords; | 4649 i += StubCode::kInstantiationSizeInWords; |
4847 num++; | 4650 num++; |
4848 } | 4651 } |
4849 return num; | 4652 return num; |
4850 } | 4653 } |
4851 | 4654 |
4852 | |
4853 RawArray* TypeArguments::instantiations() const { | 4655 RawArray* TypeArguments::instantiations() const { |
4854 return raw_ptr()->instantiations_; | 4656 return raw_ptr()->instantiations_; |
4855 } | 4657 } |
4856 | 4658 |
4857 | |
4858 void TypeArguments::set_instantiations(const Array& value) const { | 4659 void TypeArguments::set_instantiations(const Array& value) const { |
4859 ASSERT(!value.IsNull()); | 4660 ASSERT(!value.IsNull()); |
4860 StorePointer(&raw_ptr()->instantiations_, value.raw()); | 4661 StorePointer(&raw_ptr()->instantiations_, value.raw()); |
4861 } | 4662 } |
4862 | 4663 |
4863 | |
4864 intptr_t TypeArguments::Length() const { | 4664 intptr_t TypeArguments::Length() const { |
4865 if (IsNull()) { | 4665 if (IsNull()) { |
4866 return 0; | 4666 return 0; |
4867 } | 4667 } |
4868 return Smi::Value(raw_ptr()->length_); | 4668 return Smi::Value(raw_ptr()->length_); |
4869 } | 4669 } |
4870 | 4670 |
4871 | |
4872 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 4671 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
4873 return *TypeAddr(index); | 4672 return *TypeAddr(index); |
4874 } | 4673 } |
4875 | 4674 |
4876 | |
4877 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | 4675 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { |
4878 ASSERT(!IsCanonical()); | 4676 ASSERT(!IsCanonical()); |
4879 StorePointer(TypeAddr(index), value.raw()); | 4677 StorePointer(TypeAddr(index), value.raw()); |
4880 } | 4678 } |
4881 | 4679 |
4882 | |
4883 bool TypeArguments::IsResolved() const { | 4680 bool TypeArguments::IsResolved() const { |
4884 if (IsCanonical()) { | 4681 if (IsCanonical()) { |
4885 return true; | 4682 return true; |
4886 } | 4683 } |
4887 AbstractType& type = AbstractType::Handle(); | 4684 AbstractType& type = AbstractType::Handle(); |
4888 const intptr_t num_types = Length(); | 4685 const intptr_t num_types = Length(); |
4889 for (intptr_t i = 0; i < num_types; i++) { | 4686 for (intptr_t i = 0; i < num_types; i++) { |
4890 type = TypeAt(i); | 4687 type = TypeAt(i); |
4891 if (!type.IsResolved()) { | 4688 if (!type.IsResolved()) { |
4892 return false; | 4689 return false; |
4893 } | 4690 } |
4894 } | 4691 } |
4895 return true; | 4692 return true; |
4896 } | 4693 } |
4897 | 4694 |
4898 | |
4899 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, | 4695 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, |
4900 intptr_t len, | 4696 intptr_t len, |
4901 Genericity genericity, | 4697 Genericity genericity, |
4902 intptr_t num_free_fun_type_params, | 4698 intptr_t num_free_fun_type_params, |
4903 TrailPtr trail) const { | 4699 TrailPtr trail) const { |
4904 ASSERT(!IsNull()); | 4700 ASSERT(!IsNull()); |
4905 AbstractType& type = AbstractType::Handle(); | 4701 AbstractType& type = AbstractType::Handle(); |
4906 for (intptr_t i = 0; i < len; i++) { | 4702 for (intptr_t i = 0; i < len; i++) { |
4907 type = TypeAt(from_index + i); | 4703 type = TypeAt(from_index + i); |
4908 // If this type argument T is null, the type A containing T in its flattened | 4704 // If this type argument T is null, the type A containing T in its flattened |
4909 // type argument vector V is recursive and is still being finalized. | 4705 // type argument vector V is recursive and is still being finalized. |
4910 // T is the type argument of a super type of A. T is being instantiated | 4706 // T is the type argument of a super type of A. T is being instantiated |
4911 // during finalization of V, which is also the instantiator. T depends | 4707 // during finalization of V, which is also the instantiator. T depends |
4912 // solely on the type parameters of A and will be replaced by a non-null | 4708 // solely on the type parameters of A and will be replaced by a non-null |
4913 // type before A is marked as finalized. | 4709 // type before A is marked as finalized. |
4914 if (!type.IsNull() && | 4710 if (!type.IsNull() && |
4915 !type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 4711 !type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |
4916 return false; | 4712 return false; |
4917 } | 4713 } |
4918 } | 4714 } |
4919 return true; | 4715 return true; |
4920 } | 4716 } |
4921 | 4717 |
4922 | |
4923 bool TypeArguments::IsUninstantiatedIdentity() const { | 4718 bool TypeArguments::IsUninstantiatedIdentity() const { |
4924 AbstractType& type = AbstractType::Handle(); | 4719 AbstractType& type = AbstractType::Handle(); |
4925 const intptr_t num_types = Length(); | 4720 const intptr_t num_types = Length(); |
4926 for (intptr_t i = 0; i < num_types; i++) { | 4721 for (intptr_t i = 0; i < num_types; i++) { |
4927 type = TypeAt(i); | 4722 type = TypeAt(i); |
4928 if (type.IsNull()) { | 4723 if (type.IsNull()) { |
4929 continue; | 4724 continue; |
4930 } | 4725 } |
4931 if (!type.IsTypeParameter()) { | 4726 if (!type.IsTypeParameter()) { |
4932 return false; | 4727 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
4948 if (!bound.IsObjectType() && !bound.IsDynamicType()) { | 4743 if (!bound.IsObjectType() && !bound.IsDynamicType()) { |
4949 return false; | 4744 return false; |
4950 } | 4745 } |
4951 } | 4746 } |
4952 return true; | 4747 return true; |
4953 // Note that it is not necessary to verify at runtime that the instantiator | 4748 // Note that it is not necessary to verify at runtime that the instantiator |
4954 // type vector is long enough, since this uninstantiated vector contains as | 4749 // type vector is long enough, since this uninstantiated vector contains as |
4955 // many different type parameters as it is long. | 4750 // many different type parameters as it is long. |
4956 } | 4751 } |
4957 | 4752 |
4958 | |
4959 // Return true if this uninstantiated type argument vector, once instantiated | 4753 // Return true if this uninstantiated type argument vector, once instantiated |
4960 // at runtime, is a prefix of the type argument vector of its instantiator. | 4754 // at runtime, is a prefix of the type argument vector of its instantiator. |
4961 bool TypeArguments::CanShareInstantiatorTypeArguments( | 4755 bool TypeArguments::CanShareInstantiatorTypeArguments( |
4962 const Class& instantiator_class) const { | 4756 const Class& instantiator_class) const { |
4963 ASSERT(!IsInstantiated()); | 4757 ASSERT(!IsInstantiated()); |
4964 const intptr_t num_type_args = Length(); | 4758 const intptr_t num_type_args = Length(); |
4965 const intptr_t num_instantiator_type_args = | 4759 const intptr_t num_instantiator_type_args = |
4966 instantiator_class.NumTypeArguments(); | 4760 instantiator_class.NumTypeArguments(); |
4967 if (num_type_args > num_instantiator_type_args) { | 4761 if (num_type_args > num_instantiator_type_args) { |
4968 // This vector cannot be a prefix of a shorter vector. | 4762 // This vector cannot be a prefix of a shorter vector. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5017 i++) { | 4811 i++) { |
5018 type_arg = TypeAt(i); | 4812 type_arg = TypeAt(i); |
5019 super_type_arg = super_type_args.TypeAt(i); | 4813 super_type_arg = super_type_args.TypeAt(i); |
5020 if (!type_arg.Equals(super_type_arg)) { | 4814 if (!type_arg.Equals(super_type_arg)) { |
5021 return false; | 4815 return false; |
5022 } | 4816 } |
5023 } | 4817 } |
5024 return true; | 4818 return true; |
5025 } | 4819 } |
5026 | 4820 |
5027 | |
5028 bool TypeArguments::IsFinalized() const { | 4821 bool TypeArguments::IsFinalized() const { |
5029 ASSERT(!IsNull()); | 4822 ASSERT(!IsNull()); |
5030 AbstractType& type = AbstractType::Handle(); | 4823 AbstractType& type = AbstractType::Handle(); |
5031 const intptr_t num_types = Length(); | 4824 const intptr_t num_types = Length(); |
5032 for (intptr_t i = 0; i < num_types; i++) { | 4825 for (intptr_t i = 0; i < num_types; i++) { |
5033 type = TypeAt(i); | 4826 type = TypeAt(i); |
5034 if (!type.IsFinalized()) { | 4827 if (!type.IsFinalized()) { |
5035 return false; | 4828 return false; |
5036 } | 4829 } |
5037 } | 4830 } |
5038 return true; | 4831 return true; |
5039 } | 4832 } |
5040 | 4833 |
5041 | |
5042 bool TypeArguments::IsBounded() const { | 4834 bool TypeArguments::IsBounded() const { |
5043 AbstractType& type = AbstractType::Handle(); | 4835 AbstractType& type = AbstractType::Handle(); |
5044 const intptr_t num_types = Length(); | 4836 const intptr_t num_types = Length(); |
5045 for (intptr_t i = 0; i < num_types; i++) { | 4837 for (intptr_t i = 0; i < num_types; i++) { |
5046 type = TypeAt(i); | 4838 type = TypeAt(i); |
5047 if (type.IsBoundedType()) { | 4839 if (type.IsBoundedType()) { |
5048 return true; | 4840 return true; |
5049 } | 4841 } |
5050 if (type.IsTypeParameter()) { | 4842 if (type.IsTypeParameter()) { |
5051 const AbstractType& bound = | 4843 const AbstractType& bound = |
5052 AbstractType::Handle(TypeParameter::Cast(type).bound()); | 4844 AbstractType::Handle(TypeParameter::Cast(type).bound()); |
5053 if (!bound.IsObjectType() && !bound.IsDynamicType()) { | 4845 if (!bound.IsObjectType() && !bound.IsDynamicType()) { |
5054 return true; | 4846 return true; |
5055 } | 4847 } |
5056 continue; | 4848 continue; |
5057 } | 4849 } |
5058 const TypeArguments& type_args = | 4850 const TypeArguments& type_args = |
5059 TypeArguments::Handle(Type::Cast(type).arguments()); | 4851 TypeArguments::Handle(Type::Cast(type).arguments()); |
5060 if (!type_args.IsNull() && type_args.IsBounded()) { | 4852 if (!type_args.IsNull() && type_args.IsBounded()) { |
5061 return true; | 4853 return true; |
5062 } | 4854 } |
5063 } | 4855 } |
5064 return false; | 4856 return false; |
5065 } | 4857 } |
5066 | 4858 |
5067 | |
5068 RawTypeArguments* TypeArguments::InstantiateFrom( | 4859 RawTypeArguments* TypeArguments::InstantiateFrom( |
5069 const TypeArguments& instantiator_type_arguments, | 4860 const TypeArguments& instantiator_type_arguments, |
5070 const TypeArguments& function_type_arguments, | 4861 const TypeArguments& function_type_arguments, |
5071 Error* bound_error, | 4862 Error* bound_error, |
5072 TrailPtr instantiation_trail, | 4863 TrailPtr instantiation_trail, |
5073 TrailPtr bound_trail, | 4864 TrailPtr bound_trail, |
5074 Heap::Space space) const { | 4865 Heap::Space space) const { |
5075 ASSERT(!IsInstantiated()); | 4866 ASSERT(!IsInstantiated()); |
5076 if (!instantiator_type_arguments.IsNull() && IsUninstantiatedIdentity() && | 4867 if (!instantiator_type_arguments.IsNull() && IsUninstantiatedIdentity() && |
5077 (instantiator_type_arguments.Length() == Length())) { | 4868 (instantiator_type_arguments.Length() == Length())) { |
(...skipping 14 matching lines...) Expand all Loading... |
5092 if (!type.IsNull() && !type.IsInstantiated()) { | 4883 if (!type.IsNull() && !type.IsInstantiated()) { |
5093 type = type.InstantiateFrom(instantiator_type_arguments, | 4884 type = type.InstantiateFrom(instantiator_type_arguments, |
5094 function_type_arguments, bound_error, | 4885 function_type_arguments, bound_error, |
5095 instantiation_trail, bound_trail, space); | 4886 instantiation_trail, bound_trail, space); |
5096 } | 4887 } |
5097 instantiated_array.SetTypeAt(i, type); | 4888 instantiated_array.SetTypeAt(i, type); |
5098 } | 4889 } |
5099 return instantiated_array.raw(); | 4890 return instantiated_array.raw(); |
5100 } | 4891 } |
5101 | 4892 |
5102 | |
5103 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( | 4893 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( |
5104 const TypeArguments& instantiator_type_arguments, | 4894 const TypeArguments& instantiator_type_arguments, |
5105 const TypeArguments& function_type_arguments, | 4895 const TypeArguments& function_type_arguments, |
5106 Error* bound_error) const { | 4896 Error* bound_error) const { |
5107 ASSERT(!IsInstantiated()); | 4897 ASSERT(!IsInstantiated()); |
5108 ASSERT(instantiator_type_arguments.IsNull() || | 4898 ASSERT(instantiator_type_arguments.IsNull() || |
5109 instantiator_type_arguments.IsCanonical()); | 4899 instantiator_type_arguments.IsCanonical()); |
5110 // TODO(regis): It is not clear yet whether we will canonicalize the result | 4900 // TODO(regis): It is not clear yet whether we will canonicalize the result |
5111 // of the concatenation of function_type_arguments in a nested generic | 4901 // of the concatenation of function_type_arguments in a nested generic |
5112 // function. Leave the assert for now to be safe, but plan on revisiting. | 4902 // function. Leave the assert for now to be safe, but plan on revisiting. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5156 ASSERT((index + StubCode::kInstantiationSizeInWords) < length); | 4946 ASSERT((index + StubCode::kInstantiationSizeInWords) < length); |
5157 } | 4947 } |
5158 prior_instantiations.SetAt(index + 0, instantiator_type_arguments); | 4948 prior_instantiations.SetAt(index + 0, instantiator_type_arguments); |
5159 prior_instantiations.SetAt(index + 1, function_type_arguments); | 4949 prior_instantiations.SetAt(index + 1, function_type_arguments); |
5160 prior_instantiations.SetAt(index + 2, result); | 4950 prior_instantiations.SetAt(index + 2, result); |
5161 prior_instantiations.SetAt(index + 3, | 4951 prior_instantiations.SetAt(index + 3, |
5162 Smi::Handle(Smi::New(StubCode::kNoInstantiator))); | 4952 Smi::Handle(Smi::New(StubCode::kNoInstantiator))); |
5163 return result.raw(); | 4953 return result.raw(); |
5164 } | 4954 } |
5165 | 4955 |
5166 | |
5167 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { | 4956 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |
5168 if (len < 0 || len > kMaxElements) { | 4957 if (len < 0 || len > kMaxElements) { |
5169 // This should be caught before we reach here. | 4958 // This should be caught before we reach here. |
5170 FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len); | 4959 FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len); |
5171 } | 4960 } |
5172 TypeArguments& result = TypeArguments::Handle(); | 4961 TypeArguments& result = TypeArguments::Handle(); |
5173 { | 4962 { |
5174 RawObject* raw = Object::Allocate(TypeArguments::kClassId, | 4963 RawObject* raw = Object::Allocate(TypeArguments::kClassId, |
5175 TypeArguments::InstanceSize(len), space); | 4964 TypeArguments::InstanceSize(len), space); |
5176 NoSafepointScope no_safepoint; | 4965 NoSafepointScope no_safepoint; |
5177 result ^= raw; | 4966 result ^= raw; |
5178 // Length must be set before we start storing into the array. | 4967 // Length must be set before we start storing into the array. |
5179 result.SetLength(len); | 4968 result.SetLength(len); |
5180 result.SetHash(0); | 4969 result.SetHash(0); |
5181 } | 4970 } |
5182 // The zero array should have been initialized. | 4971 // The zero array should have been initialized. |
5183 ASSERT(Object::zero_array().raw() != Array::null()); | 4972 ASSERT(Object::zero_array().raw() != Array::null()); |
5184 COMPILE_ASSERT(StubCode::kNoInstantiator == 0); | 4973 COMPILE_ASSERT(StubCode::kNoInstantiator == 0); |
5185 result.set_instantiations(Object::zero_array()); | 4974 result.set_instantiations(Object::zero_array()); |
5186 return result.raw(); | 4975 return result.raw(); |
5187 } | 4976 } |
5188 | 4977 |
5189 | |
5190 RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const { | 4978 RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const { |
5191 ASSERT((index >= 0) && (index < Length())); | 4979 ASSERT((index >= 0) && (index < Length())); |
5192 return &raw_ptr()->types()[index]; | 4980 return &raw_ptr()->types()[index]; |
5193 } | 4981 } |
5194 | 4982 |
5195 | |
5196 void TypeArguments::SetLength(intptr_t value) const { | 4983 void TypeArguments::SetLength(intptr_t value) const { |
5197 ASSERT(!IsCanonical()); | 4984 ASSERT(!IsCanonical()); |
5198 // This is only safe because we create a new Smi, which does not cause | 4985 // This is only safe because we create a new Smi, which does not cause |
5199 // heap allocation. | 4986 // heap allocation. |
5200 StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 4987 StoreSmi(&raw_ptr()->length_, Smi::New(value)); |
5201 } | 4988 } |
5202 | 4989 |
5203 | |
5204 RawTypeArguments* TypeArguments::CloneUnfinalized() const { | 4990 RawTypeArguments* TypeArguments::CloneUnfinalized() const { |
5205 if (IsNull() || IsFinalized()) { | 4991 if (IsNull() || IsFinalized()) { |
5206 return raw(); | 4992 return raw(); |
5207 } | 4993 } |
5208 ASSERT(IsResolved()); | 4994 ASSERT(IsResolved()); |
5209 AbstractType& type = AbstractType::Handle(); | 4995 AbstractType& type = AbstractType::Handle(); |
5210 const intptr_t num_types = Length(); | 4996 const intptr_t num_types = Length(); |
5211 const TypeArguments& clone = | 4997 const TypeArguments& clone = |
5212 TypeArguments::Handle(TypeArguments::New(num_types)); | 4998 TypeArguments::Handle(TypeArguments::New(num_types)); |
5213 for (intptr_t i = 0; i < num_types; i++) { | 4999 for (intptr_t i = 0; i < num_types; i++) { |
5214 type = TypeAt(i); | 5000 type = TypeAt(i); |
5215 type = type.CloneUnfinalized(); | 5001 type = type.CloneUnfinalized(); |
5216 clone.SetTypeAt(i, type); | 5002 clone.SetTypeAt(i, type); |
5217 } | 5003 } |
5218 ASSERT(clone.IsResolved()); | 5004 ASSERT(clone.IsResolved()); |
5219 return clone.raw(); | 5005 return clone.raw(); |
5220 } | 5006 } |
5221 | 5007 |
5222 | |
5223 RawTypeArguments* TypeArguments::CloneUninstantiated(const Class& new_owner, | 5008 RawTypeArguments* TypeArguments::CloneUninstantiated(const Class& new_owner, |
5224 TrailPtr trail) const { | 5009 TrailPtr trail) const { |
5225 ASSERT(!IsNull()); | 5010 ASSERT(!IsNull()); |
5226 ASSERT(IsFinalized()); | 5011 ASSERT(IsFinalized()); |
5227 ASSERT(!IsInstantiated()); | 5012 ASSERT(!IsInstantiated()); |
5228 AbstractType& type = AbstractType::Handle(); | 5013 AbstractType& type = AbstractType::Handle(); |
5229 const intptr_t num_types = Length(); | 5014 const intptr_t num_types = Length(); |
5230 const TypeArguments& clone = | 5015 const TypeArguments& clone = |
5231 TypeArguments::Handle(TypeArguments::New(num_types)); | 5016 TypeArguments::Handle(TypeArguments::New(num_types)); |
5232 for (intptr_t i = 0; i < num_types; i++) { | 5017 for (intptr_t i = 0; i < num_types; i++) { |
5233 type = TypeAt(i); | 5018 type = TypeAt(i); |
5234 if (!type.IsInstantiated()) { | 5019 if (!type.IsInstantiated()) { |
5235 type = type.CloneUninstantiated(new_owner, trail); | 5020 type = type.CloneUninstantiated(new_owner, trail); |
5236 } | 5021 } |
5237 clone.SetTypeAt(i, type); | 5022 clone.SetTypeAt(i, type); |
5238 } | 5023 } |
5239 ASSERT(clone.IsFinalized()); | 5024 ASSERT(clone.IsFinalized()); |
5240 return clone.raw(); | 5025 return clone.raw(); |
5241 } | 5026 } |
5242 | 5027 |
5243 | |
5244 RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const { | 5028 RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const { |
5245 if (IsNull() || IsCanonical()) { | 5029 if (IsNull() || IsCanonical()) { |
5246 ASSERT(IsOld()); | 5030 ASSERT(IsOld()); |
5247 return this->raw(); | 5031 return this->raw(); |
5248 } | 5032 } |
5249 const intptr_t num_types = Length(); | 5033 const intptr_t num_types = Length(); |
5250 if (IsRaw(0, num_types)) { | 5034 if (IsRaw(0, num_types)) { |
5251 return TypeArguments::null(); | 5035 return TypeArguments::null(); |
5252 } | 5036 } |
5253 Thread* thread = Thread::Current(); | 5037 Thread* thread = Thread::Current(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5302 } | 5086 } |
5303 object_store->set_canonical_type_arguments(table.Release()); | 5087 object_store->set_canonical_type_arguments(table.Release()); |
5304 } | 5088 } |
5305 ASSERT(result.Equals(*this)); | 5089 ASSERT(result.Equals(*this)); |
5306 ASSERT(!result.IsNull()); | 5090 ASSERT(!result.IsNull()); |
5307 ASSERT(result.IsTypeArguments()); | 5091 ASSERT(result.IsTypeArguments()); |
5308 ASSERT(result.IsCanonical()); | 5092 ASSERT(result.IsCanonical()); |
5309 return result.raw(); | 5093 return result.raw(); |
5310 } | 5094 } |
5311 | 5095 |
5312 | |
5313 RawString* TypeArguments::EnumerateURIs() const { | 5096 RawString* TypeArguments::EnumerateURIs() const { |
5314 if (IsNull()) { | 5097 if (IsNull()) { |
5315 return Symbols::Empty().raw(); | 5098 return Symbols::Empty().raw(); |
5316 } | 5099 } |
5317 Thread* thread = Thread::Current(); | 5100 Thread* thread = Thread::Current(); |
5318 Zone* zone = thread->zone(); | 5101 Zone* zone = thread->zone(); |
5319 AbstractType& type = AbstractType::Handle(zone); | 5102 AbstractType& type = AbstractType::Handle(zone); |
5320 const intptr_t num_types = Length(); | 5103 const intptr_t num_types = Length(); |
5321 const Array& pieces = Array::Handle(zone, Array::New(num_types)); | 5104 const Array& pieces = Array::Handle(zone, Array::New(num_types)); |
5322 for (intptr_t i = 0; i < num_types; i++) { | 5105 for (intptr_t i = 0; i < num_types; i++) { |
5323 type = TypeAt(i); | 5106 type = TypeAt(i); |
5324 pieces.SetAt(i, String::Handle(zone, type.EnumerateURIs())); | 5107 pieces.SetAt(i, String::Handle(zone, type.EnumerateURIs())); |
5325 } | 5108 } |
5326 return String::ConcatAll(pieces); | 5109 return String::ConcatAll(pieces); |
5327 } | 5110 } |
5328 | 5111 |
5329 | |
5330 const char* TypeArguments::ToCString() const { | 5112 const char* TypeArguments::ToCString() const { |
5331 if (IsNull()) { | 5113 if (IsNull()) { |
5332 return "TypeArguments: null"; | 5114 return "TypeArguments: null"; |
5333 } | 5115 } |
5334 Zone* zone = Thread::Current()->zone(); | 5116 Zone* zone = Thread::Current()->zone(); |
5335 const char* prev_cstr = OS::SCreate(zone, "TypeArguments: (%" Pd ")", | 5117 const char* prev_cstr = OS::SCreate(zone, "TypeArguments: (%" Pd ")", |
5336 Smi::Value(raw_ptr()->hash_)); | 5118 Smi::Value(raw_ptr()->hash_)); |
5337 for (int i = 0; i < Length(); i++) { | 5119 for (int i = 0; i < Length(); i++) { |
5338 const AbstractType& type_at = AbstractType::Handle(zone, TypeAt(i)); | 5120 const AbstractType& type_at = AbstractType::Handle(zone, TypeAt(i)); |
5339 const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); | 5121 const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); |
5340 char* chars = OS::SCreate(zone, "%s [%s]", prev_cstr, type_cstr); | 5122 char* chars = OS::SCreate(zone, "%s [%s]", prev_cstr, type_cstr); |
5341 prev_cstr = chars; | 5123 prev_cstr = chars; |
5342 } | 5124 } |
5343 return prev_cstr; | 5125 return prev_cstr; |
5344 } | 5126 } |
5345 | 5127 |
5346 | |
5347 const char* PatchClass::ToCString() const { | 5128 const char* PatchClass::ToCString() const { |
5348 const Class& cls = Class::Handle(patched_class()); | 5129 const Class& cls = Class::Handle(patched_class()); |
5349 const char* cls_name = cls.ToCString(); | 5130 const char* cls_name = cls.ToCString(); |
5350 return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name); | 5131 return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name); |
5351 } | 5132 } |
5352 | 5133 |
5353 | |
5354 RawPatchClass* PatchClass::New(const Class& patched_class, | 5134 RawPatchClass* PatchClass::New(const Class& patched_class, |
5355 const Class& origin_class) { | 5135 const Class& origin_class) { |
5356 const PatchClass& result = PatchClass::Handle(PatchClass::New()); | 5136 const PatchClass& result = PatchClass::Handle(PatchClass::New()); |
5357 result.set_patched_class(patched_class); | 5137 result.set_patched_class(patched_class); |
5358 result.set_origin_class(origin_class); | 5138 result.set_origin_class(origin_class); |
5359 result.set_script(Script::Handle(origin_class.script())); | 5139 result.set_script(Script::Handle(origin_class.script())); |
5360 return result.raw(); | 5140 return result.raw(); |
5361 } | 5141 } |
5362 | 5142 |
5363 | |
5364 RawPatchClass* PatchClass::New(const Class& patched_class, | 5143 RawPatchClass* PatchClass::New(const Class& patched_class, |
5365 const Script& script) { | 5144 const Script& script) { |
5366 const PatchClass& result = PatchClass::Handle(PatchClass::New()); | 5145 const PatchClass& result = PatchClass::Handle(PatchClass::New()); |
5367 result.set_patched_class(patched_class); | 5146 result.set_patched_class(patched_class); |
5368 result.set_origin_class(patched_class); | 5147 result.set_origin_class(patched_class); |
5369 result.set_script(script); | 5148 result.set_script(script); |
5370 return result.raw(); | 5149 return result.raw(); |
5371 } | 5150 } |
5372 | 5151 |
5373 | |
5374 RawPatchClass* PatchClass::New() { | 5152 RawPatchClass* PatchClass::New() { |
5375 ASSERT(Object::patch_class_class() != Class::null()); | 5153 ASSERT(Object::patch_class_class() != Class::null()); |
5376 RawObject* raw = Object::Allocate(PatchClass::kClassId, | 5154 RawObject* raw = Object::Allocate(PatchClass::kClassId, |
5377 PatchClass::InstanceSize(), Heap::kOld); | 5155 PatchClass::InstanceSize(), Heap::kOld); |
5378 return reinterpret_cast<RawPatchClass*>(raw); | 5156 return reinterpret_cast<RawPatchClass*>(raw); |
5379 } | 5157 } |
5380 | 5158 |
5381 | |
5382 void PatchClass::set_patched_class(const Class& value) const { | 5159 void PatchClass::set_patched_class(const Class& value) const { |
5383 StorePointer(&raw_ptr()->patched_class_, value.raw()); | 5160 StorePointer(&raw_ptr()->patched_class_, value.raw()); |
5384 } | 5161 } |
5385 | 5162 |
5386 | |
5387 void PatchClass::set_origin_class(const Class& value) const { | 5163 void PatchClass::set_origin_class(const Class& value) const { |
5388 StorePointer(&raw_ptr()->origin_class_, value.raw()); | 5164 StorePointer(&raw_ptr()->origin_class_, value.raw()); |
5389 } | 5165 } |
5390 | 5166 |
5391 | |
5392 void PatchClass::set_script(const Script& value) const { | 5167 void PatchClass::set_script(const Script& value) const { |
5393 StorePointer(&raw_ptr()->script_, value.raw()); | 5168 StorePointer(&raw_ptr()->script_, value.raw()); |
5394 } | 5169 } |
5395 | 5170 |
5396 | |
5397 intptr_t Function::Hash() const { | 5171 intptr_t Function::Hash() const { |
5398 return String::HashRawSymbol(name()); | 5172 return String::HashRawSymbol(name()); |
5399 } | 5173 } |
5400 | 5174 |
5401 | |
5402 bool Function::HasBreakpoint() const { | 5175 bool Function::HasBreakpoint() const { |
5403 if (!FLAG_support_debugger) { | 5176 if (!FLAG_support_debugger) { |
5404 return false; | 5177 return false; |
5405 } | 5178 } |
5406 Thread* thread = Thread::Current(); | 5179 Thread* thread = Thread::Current(); |
5407 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); | 5180 return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); |
5408 } | 5181 } |
5409 | 5182 |
5410 | |
5411 void Function::InstallOptimizedCode(const Code& code) const { | 5183 void Function::InstallOptimizedCode(const Code& code) const { |
5412 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 5184 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5413 // We may not have previous code if FLAG_precompile is set. | 5185 // We may not have previous code if FLAG_precompile is set. |
5414 // Hot-reload may have already disabled the current code. | 5186 // Hot-reload may have already disabled the current code. |
5415 if (HasCode() && !Code::Handle(CurrentCode()).IsDisabled()) { | 5187 if (HasCode() && !Code::Handle(CurrentCode()).IsDisabled()) { |
5416 Code::Handle(CurrentCode()).DisableDartCode(); | 5188 Code::Handle(CurrentCode()).DisableDartCode(); |
5417 } | 5189 } |
5418 AttachCode(code); | 5190 AttachCode(code); |
5419 } | 5191 } |
5420 | 5192 |
5421 | |
5422 void Function::SetInstructions(const Code& value) const { | 5193 void Function::SetInstructions(const Code& value) const { |
5423 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 5194 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5424 SetInstructionsSafe(value); | 5195 SetInstructionsSafe(value); |
5425 } | 5196 } |
5426 | 5197 |
5427 | |
5428 void Function::SetInstructionsSafe(const Code& value) const { | 5198 void Function::SetInstructionsSafe(const Code& value) const { |
5429 StorePointer(&raw_ptr()->code_, value.raw()); | 5199 StorePointer(&raw_ptr()->code_, value.raw()); |
5430 StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint()); | 5200 StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint()); |
5431 } | 5201 } |
5432 | 5202 |
5433 | |
5434 void Function::AttachCode(const Code& value) const { | 5203 void Function::AttachCode(const Code& value) const { |
5435 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 5204 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
5436 // Finish setting up code before activating it. | 5205 // Finish setting up code before activating it. |
5437 value.set_owner(*this); | 5206 value.set_owner(*this); |
5438 SetInstructions(value); | 5207 SetInstructions(value); |
5439 ASSERT(Function::Handle(value.function()).IsNull() || | 5208 ASSERT(Function::Handle(value.function()).IsNull() || |
5440 (value.function() == this->raw())); | 5209 (value.function() == this->raw())); |
5441 } | 5210 } |
5442 | 5211 |
5443 | |
5444 bool Function::HasCode() const { | 5212 bool Function::HasCode() const { |
5445 ASSERT(raw_ptr()->code_ != Code::null()); | 5213 ASSERT(raw_ptr()->code_ != Code::null()); |
5446 return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); | 5214 return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); |
5447 } | 5215 } |
5448 | 5216 |
5449 | |
5450 void Function::ClearCode() const { | 5217 void Function::ClearCode() const { |
5451 #if defined(DART_PRECOMPILED_RUNTIME) | 5218 #if defined(DART_PRECOMPILED_RUNTIME) |
5452 UNREACHABLE(); | 5219 UNREACHABLE(); |
5453 #else | 5220 #else |
5454 ASSERT(Thread::Current()->IsMutatorThread()); | 5221 ASSERT(Thread::Current()->IsMutatorThread()); |
5455 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); | 5222 StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); |
5456 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 5223 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); |
5457 #endif | 5224 #endif |
5458 } | 5225 } |
5459 | 5226 |
5460 | |
5461 void Function::EnsureHasCompiledUnoptimizedCode() const { | 5227 void Function::EnsureHasCompiledUnoptimizedCode() const { |
5462 Thread* thread = Thread::Current(); | 5228 Thread* thread = Thread::Current(); |
5463 Zone* zone = thread->zone(); | 5229 Zone* zone = thread->zone(); |
5464 ASSERT(thread->IsMutatorThread()); | 5230 ASSERT(thread->IsMutatorThread()); |
5465 | 5231 |
5466 const Error& error = | 5232 const Error& error = |
5467 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); | 5233 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); |
5468 if (!error.IsNull()) { | 5234 if (!error.IsNull()) { |
5469 Exceptions::PropagateError(error); | 5235 Exceptions::PropagateError(error); |
5470 } | 5236 } |
5471 } | 5237 } |
5472 | 5238 |
5473 | |
5474 void Function::SwitchToUnoptimizedCode() const { | 5239 void Function::SwitchToUnoptimizedCode() const { |
5475 ASSERT(HasOptimizedCode()); | 5240 ASSERT(HasOptimizedCode()); |
5476 Thread* thread = Thread::Current(); | 5241 Thread* thread = Thread::Current(); |
5477 Isolate* isolate = thread->isolate(); | 5242 Isolate* isolate = thread->isolate(); |
5478 Zone* zone = thread->zone(); | 5243 Zone* zone = thread->zone(); |
5479 ASSERT(thread->IsMutatorThread()); | 5244 ASSERT(thread->IsMutatorThread()); |
5480 const Code& current_code = Code::Handle(zone, CurrentCode()); | 5245 const Code& current_code = Code::Handle(zone, CurrentCode()); |
5481 | 5246 |
5482 if (FLAG_trace_deoptimization_verbose) { | 5247 if (FLAG_trace_deoptimization_verbose) { |
5483 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", | 5248 THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", |
5484 ToFullyQualifiedCString(), current_code.UncheckedEntryPoint()); | 5249 ToFullyQualifiedCString(), current_code.UncheckedEntryPoint()); |
5485 } | 5250 } |
5486 current_code.DisableDartCode(); | 5251 current_code.DisableDartCode(); |
5487 const Error& error = | 5252 const Error& error = |
5488 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); | 5253 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); |
5489 if (!error.IsNull()) { | 5254 if (!error.IsNull()) { |
5490 Exceptions::PropagateError(error); | 5255 Exceptions::PropagateError(error); |
5491 } | 5256 } |
5492 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); | 5257 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); |
5493 AttachCode(unopt_code); | 5258 AttachCode(unopt_code); |
5494 unopt_code.Enable(); | 5259 unopt_code.Enable(); |
5495 isolate->TrackDeoptimizedCode(current_code); | 5260 isolate->TrackDeoptimizedCode(current_code); |
5496 } | 5261 } |
5497 | 5262 |
5498 | |
5499 void Function::SwitchToLazyCompiledUnoptimizedCode() const { | 5263 void Function::SwitchToLazyCompiledUnoptimizedCode() const { |
5500 if (!HasOptimizedCode()) { | 5264 if (!HasOptimizedCode()) { |
5501 return; | 5265 return; |
5502 } | 5266 } |
5503 | 5267 |
5504 Thread* thread = Thread::Current(); | 5268 Thread* thread = Thread::Current(); |
5505 Zone* zone = thread->zone(); | 5269 Zone* zone = thread->zone(); |
5506 ASSERT(thread->IsMutatorThread()); | 5270 ASSERT(thread->IsMutatorThread()); |
5507 | 5271 |
5508 const Code& current_code = Code::Handle(zone, CurrentCode()); | 5272 const Code& current_code = Code::Handle(zone, CurrentCode()); |
5509 TIR_Print("Disabling optimized code for %s\n", ToCString()); | 5273 TIR_Print("Disabling optimized code for %s\n", ToCString()); |
5510 current_code.DisableDartCode(); | 5274 current_code.DisableDartCode(); |
5511 | 5275 |
5512 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); | 5276 const Code& unopt_code = Code::Handle(zone, unoptimized_code()); |
5513 if (unopt_code.IsNull()) { | 5277 if (unopt_code.IsNull()) { |
5514 // Set the lazy compile code. | 5278 // Set the lazy compile code. |
5515 TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); | 5279 TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); |
5516 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 5280 SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); |
5517 return; | 5281 return; |
5518 } | 5282 } |
5519 | 5283 |
5520 TIR_Print("Switched to unoptimized code for %s\n", ToCString()); | 5284 TIR_Print("Switched to unoptimized code for %s\n", ToCString()); |
5521 | 5285 |
5522 AttachCode(unopt_code); | 5286 AttachCode(unopt_code); |
5523 unopt_code.Enable(); | 5287 unopt_code.Enable(); |
5524 } | 5288 } |
5525 | 5289 |
5526 | |
5527 void Function::set_unoptimized_code(const Code& value) const { | 5290 void Function::set_unoptimized_code(const Code& value) const { |
5528 #if defined(DART_PRECOMPILED_RUNTIME) | 5291 #if defined(DART_PRECOMPILED_RUNTIME) |
5529 UNREACHABLE(); | 5292 UNREACHABLE(); |
5530 #else | 5293 #else |
5531 ASSERT(Thread::Current()->IsMutatorThread()); | 5294 ASSERT(Thread::Current()->IsMutatorThread()); |
5532 ASSERT(value.IsNull() || !value.is_optimized()); | 5295 ASSERT(value.IsNull() || !value.is_optimized()); |
5533 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); | 5296 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); |
5534 #endif | 5297 #endif |
5535 } | 5298 } |
5536 | 5299 |
5537 | |
5538 RawContextScope* Function::context_scope() const { | 5300 RawContextScope* Function::context_scope() const { |
5539 if (IsClosureFunction()) { | 5301 if (IsClosureFunction()) { |
5540 const Object& obj = Object::Handle(raw_ptr()->data_); | 5302 const Object& obj = Object::Handle(raw_ptr()->data_); |
5541 ASSERT(!obj.IsNull()); | 5303 ASSERT(!obj.IsNull()); |
5542 return ClosureData::Cast(obj).context_scope(); | 5304 return ClosureData::Cast(obj).context_scope(); |
5543 } | 5305 } |
5544 return ContextScope::null(); | 5306 return ContextScope::null(); |
5545 } | 5307 } |
5546 | 5308 |
5547 | |
5548 void Function::set_context_scope(const ContextScope& value) const { | 5309 void Function::set_context_scope(const ContextScope& value) const { |
5549 if (IsClosureFunction()) { | 5310 if (IsClosureFunction()) { |
5550 const Object& obj = Object::Handle(raw_ptr()->data_); | 5311 const Object& obj = Object::Handle(raw_ptr()->data_); |
5551 ASSERT(!obj.IsNull()); | 5312 ASSERT(!obj.IsNull()); |
5552 ClosureData::Cast(obj).set_context_scope(value); | 5313 ClosureData::Cast(obj).set_context_scope(value); |
5553 return; | 5314 return; |
5554 } | 5315 } |
5555 UNREACHABLE(); | 5316 UNREACHABLE(); |
5556 } | 5317 } |
5557 | 5318 |
5558 | |
5559 RawInstance* Function::implicit_static_closure() const { | 5319 RawInstance* Function::implicit_static_closure() const { |
5560 if (IsImplicitStaticClosureFunction()) { | 5320 if (IsImplicitStaticClosureFunction()) { |
5561 const Object& obj = Object::Handle(raw_ptr()->data_); | 5321 const Object& obj = Object::Handle(raw_ptr()->data_); |
5562 ASSERT(!obj.IsNull()); | 5322 ASSERT(!obj.IsNull()); |
5563 return ClosureData::Cast(obj).implicit_static_closure(); | 5323 return ClosureData::Cast(obj).implicit_static_closure(); |
5564 } | 5324 } |
5565 return Instance::null(); | 5325 return Instance::null(); |
5566 } | 5326 } |
5567 | 5327 |
5568 | |
5569 void Function::set_implicit_static_closure(const Instance& closure) const { | 5328 void Function::set_implicit_static_closure(const Instance& closure) const { |
5570 if (IsImplicitStaticClosureFunction()) { | 5329 if (IsImplicitStaticClosureFunction()) { |
5571 const Object& obj = Object::Handle(raw_ptr()->data_); | 5330 const Object& obj = Object::Handle(raw_ptr()->data_); |
5572 ASSERT(!obj.IsNull()); | 5331 ASSERT(!obj.IsNull()); |
5573 ClosureData::Cast(obj).set_implicit_static_closure(closure); | 5332 ClosureData::Cast(obj).set_implicit_static_closure(closure); |
5574 return; | 5333 return; |
5575 } | 5334 } |
5576 UNREACHABLE(); | 5335 UNREACHABLE(); |
5577 } | 5336 } |
5578 | 5337 |
5579 | |
5580 RawScript* Function::eval_script() const { | 5338 RawScript* Function::eval_script() const { |
5581 const Object& obj = Object::Handle(raw_ptr()->data_); | 5339 const Object& obj = Object::Handle(raw_ptr()->data_); |
5582 if (obj.IsScript()) { | 5340 if (obj.IsScript()) { |
5583 return Script::Cast(obj).raw(); | 5341 return Script::Cast(obj).raw(); |
5584 } | 5342 } |
5585 return Script::null(); | 5343 return Script::null(); |
5586 } | 5344 } |
5587 | 5345 |
5588 | |
5589 void Function::set_eval_script(const Script& script) const { | 5346 void Function::set_eval_script(const Script& script) const { |
5590 ASSERT(token_pos() == TokenPosition::kMinSource); | 5347 ASSERT(token_pos() == TokenPosition::kMinSource); |
5591 ASSERT(raw_ptr()->data_ == Object::null()); | 5348 ASSERT(raw_ptr()->data_ == Object::null()); |
5592 set_data(script); | 5349 set_data(script); |
5593 } | 5350 } |
5594 | 5351 |
5595 | |
5596 RawFunction* Function::extracted_method_closure() const { | 5352 RawFunction* Function::extracted_method_closure() const { |
5597 ASSERT(kind() == RawFunction::kMethodExtractor); | 5353 ASSERT(kind() == RawFunction::kMethodExtractor); |
5598 const Object& obj = Object::Handle(raw_ptr()->data_); | 5354 const Object& obj = Object::Handle(raw_ptr()->data_); |
5599 ASSERT(obj.IsFunction()); | 5355 ASSERT(obj.IsFunction()); |
5600 return Function::Cast(obj).raw(); | 5356 return Function::Cast(obj).raw(); |
5601 } | 5357 } |
5602 | 5358 |
5603 | |
5604 void Function::set_extracted_method_closure(const Function& value) const { | 5359 void Function::set_extracted_method_closure(const Function& value) const { |
5605 ASSERT(kind() == RawFunction::kMethodExtractor); | 5360 ASSERT(kind() == RawFunction::kMethodExtractor); |
5606 ASSERT(raw_ptr()->data_ == Object::null()); | 5361 ASSERT(raw_ptr()->data_ == Object::null()); |
5607 set_data(value); | 5362 set_data(value); |
5608 } | 5363 } |
5609 | 5364 |
5610 | |
5611 RawArray* Function::saved_args_desc() const { | 5365 RawArray* Function::saved_args_desc() const { |
5612 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || | 5366 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |
5613 kind() == RawFunction::kInvokeFieldDispatcher); | 5367 kind() == RawFunction::kInvokeFieldDispatcher); |
5614 const Object& obj = Object::Handle(raw_ptr()->data_); | 5368 const Object& obj = Object::Handle(raw_ptr()->data_); |
5615 ASSERT(obj.IsArray()); | 5369 ASSERT(obj.IsArray()); |
5616 return Array::Cast(obj).raw(); | 5370 return Array::Cast(obj).raw(); |
5617 } | 5371 } |
5618 | 5372 |
5619 | |
5620 void Function::set_saved_args_desc(const Array& value) const { | 5373 void Function::set_saved_args_desc(const Array& value) const { |
5621 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || | 5374 ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |
5622 kind() == RawFunction::kInvokeFieldDispatcher); | 5375 kind() == RawFunction::kInvokeFieldDispatcher); |
5623 ASSERT(raw_ptr()->data_ == Object::null()); | 5376 ASSERT(raw_ptr()->data_ == Object::null()); |
5624 set_data(value); | 5377 set_data(value); |
5625 } | 5378 } |
5626 | 5379 |
5627 | |
5628 RawField* Function::LookupImplicitGetterSetterField() const { | 5380 RawField* Function::LookupImplicitGetterSetterField() const { |
5629 ASSERT((kind() == RawFunction::kImplicitGetter) || | 5381 ASSERT((kind() == RawFunction::kImplicitGetter) || |
5630 (kind() == RawFunction::kImplicitSetter) || | 5382 (kind() == RawFunction::kImplicitSetter) || |
5631 (kind() == RawFunction::kImplicitStaticFinalGetter)); | 5383 (kind() == RawFunction::kImplicitStaticFinalGetter)); |
5632 const Class& owner = Class::Handle(Owner()); | 5384 const Class& owner = Class::Handle(Owner()); |
5633 ASSERT(!owner.IsNull()); | 5385 ASSERT(!owner.IsNull()); |
5634 const Array& fields = Array::Handle(owner.fields()); | 5386 const Array& fields = Array::Handle(owner.fields()); |
5635 ASSERT(!fields.IsNull()); | 5387 ASSERT(!fields.IsNull()); |
5636 Field& field = Field::Handle(); | 5388 Field& field = Field::Handle(); |
5637 for (intptr_t i = 0; i < fields.Length(); i++) { | 5389 for (intptr_t i = 0; i < fields.Length(); i++) { |
5638 field ^= fields.At(i); | 5390 field ^= fields.At(i); |
5639 ASSERT(!field.IsNull()); | 5391 ASSERT(!field.IsNull()); |
5640 if (field.token_pos() == token_pos()) { | 5392 if (field.token_pos() == token_pos()) { |
5641 return field.raw(); | 5393 return field.raw(); |
5642 } | 5394 } |
5643 } | 5395 } |
5644 return Field::null(); | 5396 return Field::null(); |
5645 } | 5397 } |
5646 | 5398 |
5647 | |
5648 RawFunction* Function::parent_function() const { | 5399 RawFunction* Function::parent_function() const { |
5649 if (IsClosureFunction() || IsSignatureFunction()) { | 5400 if (IsClosureFunction() || IsSignatureFunction()) { |
5650 const Object& obj = Object::Handle(raw_ptr()->data_); | 5401 const Object& obj = Object::Handle(raw_ptr()->data_); |
5651 ASSERT(!obj.IsNull()); | 5402 ASSERT(!obj.IsNull()); |
5652 if (IsClosureFunction()) { | 5403 if (IsClosureFunction()) { |
5653 return ClosureData::Cast(obj).parent_function(); | 5404 return ClosureData::Cast(obj).parent_function(); |
5654 } else { | 5405 } else { |
5655 return SignatureData::Cast(obj).parent_function(); | 5406 return SignatureData::Cast(obj).parent_function(); |
5656 } | 5407 } |
5657 } | 5408 } |
5658 return Function::null(); | 5409 return Function::null(); |
5659 } | 5410 } |
5660 | 5411 |
5661 | |
5662 void Function::set_parent_function(const Function& value) const { | 5412 void Function::set_parent_function(const Function& value) const { |
5663 const Object& obj = Object::Handle(raw_ptr()->data_); | 5413 const Object& obj = Object::Handle(raw_ptr()->data_); |
5664 ASSERT(!obj.IsNull()); | 5414 ASSERT(!obj.IsNull()); |
5665 if (IsClosureFunction()) { | 5415 if (IsClosureFunction()) { |
5666 ClosureData::Cast(obj).set_parent_function(value); | 5416 ClosureData::Cast(obj).set_parent_function(value); |
5667 } else { | 5417 } else { |
5668 ASSERT(IsSignatureFunction()); | 5418 ASSERT(IsSignatureFunction()); |
5669 SignatureData::Cast(obj).set_parent_function(value); | 5419 SignatureData::Cast(obj).set_parent_function(value); |
5670 } | 5420 } |
5671 } | 5421 } |
5672 | 5422 |
5673 | |
5674 bool Function::HasGenericParent() const { | 5423 bool Function::HasGenericParent() const { |
5675 if (IsImplicitClosureFunction()) { | 5424 if (IsImplicitClosureFunction()) { |
5676 // The parent function of an implicit closure function is not the enclosing | 5425 // The parent function of an implicit closure function is not the enclosing |
5677 // function we are asking about here. | 5426 // function we are asking about here. |
5678 return false; | 5427 return false; |
5679 } | 5428 } |
5680 Function& parent = Function::Handle(parent_function()); | 5429 Function& parent = Function::Handle(parent_function()); |
5681 while (!parent.IsNull()) { | 5430 while (!parent.IsNull()) { |
5682 if (parent.IsGeneric()) { | 5431 if (parent.IsGeneric()) { |
5683 return true; | 5432 return true; |
5684 } | 5433 } |
5685 parent = parent.parent_function(); | 5434 parent = parent.parent_function(); |
5686 } | 5435 } |
5687 return false; | 5436 return false; |
5688 } | 5437 } |
5689 | 5438 |
5690 | |
5691 RawFunction* Function::implicit_closure_function() const { | 5439 RawFunction* Function::implicit_closure_function() const { |
5692 if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) { | 5440 if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) { |
5693 return Function::null(); | 5441 return Function::null(); |
5694 } | 5442 } |
5695 const Object& obj = Object::Handle(raw_ptr()->data_); | 5443 const Object& obj = Object::Handle(raw_ptr()->data_); |
5696 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray()); | 5444 ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray()); |
5697 if (obj.IsNull() || obj.IsScript()) { | 5445 if (obj.IsNull() || obj.IsScript()) { |
5698 return Function::null(); | 5446 return Function::null(); |
5699 } | 5447 } |
5700 if (obj.IsFunction()) { | 5448 if (obj.IsFunction()) { |
5701 return Function::Cast(obj).raw(); | 5449 return Function::Cast(obj).raw(); |
5702 } | 5450 } |
5703 ASSERT(is_native()); | 5451 ASSERT(is_native()); |
5704 ASSERT(obj.IsArray()); | 5452 ASSERT(obj.IsArray()); |
5705 const Object& res = Object::Handle(Array::Cast(obj).At(1)); | 5453 const Object& res = Object::Handle(Array::Cast(obj).At(1)); |
5706 return res.IsNull() ? Function::null() : Function::Cast(res).raw(); | 5454 return res.IsNull() ? Function::null() : Function::Cast(res).raw(); |
5707 } | 5455 } |
5708 | 5456 |
5709 | |
5710 void Function::set_implicit_closure_function(const Function& value) const { | 5457 void Function::set_implicit_closure_function(const Function& value) const { |
5711 ASSERT(!IsClosureFunction() && !IsSignatureFunction()); | 5458 ASSERT(!IsClosureFunction() && !IsSignatureFunction()); |
5712 if (is_native()) { | 5459 if (is_native()) { |
5713 const Object& obj = Object::Handle(raw_ptr()->data_); | 5460 const Object& obj = Object::Handle(raw_ptr()->data_); |
5714 ASSERT(obj.IsArray()); | 5461 ASSERT(obj.IsArray()); |
5715 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); | 5462 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); |
5716 Array::Cast(obj).SetAt(1, value); | 5463 Array::Cast(obj).SetAt(1, value); |
5717 } else { | 5464 } else { |
5718 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); | 5465 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); |
5719 set_data(value); | 5466 set_data(value); |
5720 } | 5467 } |
5721 } | 5468 } |
5722 | 5469 |
5723 | |
5724 RawType* Function::ExistingSignatureType() const { | 5470 RawType* Function::ExistingSignatureType() const { |
5725 const Object& obj = Object::Handle(raw_ptr()->data_); | 5471 const Object& obj = Object::Handle(raw_ptr()->data_); |
5726 ASSERT(!obj.IsNull()); | 5472 ASSERT(!obj.IsNull()); |
5727 if (IsSignatureFunction()) { | 5473 if (IsSignatureFunction()) { |
5728 return SignatureData::Cast(obj).signature_type(); | 5474 return SignatureData::Cast(obj).signature_type(); |
5729 } else { | 5475 } else { |
5730 ASSERT(IsClosureFunction()); | 5476 ASSERT(IsClosureFunction()); |
5731 return ClosureData::Cast(obj).signature_type(); | 5477 return ClosureData::Cast(obj).signature_type(); |
5732 } | 5478 } |
5733 } | 5479 } |
5734 | 5480 |
5735 | |
5736 RawFunction* Function::CanonicalSignatureFunction(TrailPtr trail) const { | 5481 RawFunction* Function::CanonicalSignatureFunction(TrailPtr trail) const { |
5737 ASSERT(!IsSignatureFunction()); | 5482 ASSERT(!IsSignatureFunction()); |
5738 Zone* zone = Thread::Current()->zone(); | 5483 Zone* zone = Thread::Current()->zone(); |
5739 Function& parent = Function::Handle(zone, parent_function()); | 5484 Function& parent = Function::Handle(zone, parent_function()); |
5740 if (!parent.IsNull() && !parent.IsSignatureFunction()) { | 5485 if (!parent.IsNull() && !parent.IsSignatureFunction()) { |
5741 // Make sure the parent function is also a signature function. | 5486 // Make sure the parent function is also a signature function. |
5742 parent = parent.CanonicalSignatureFunction(trail); | 5487 parent = parent.CanonicalSignatureFunction(trail); |
5743 } | 5488 } |
5744 const Class& owner = Class::Handle(zone, Owner()); | 5489 const Class& owner = Class::Handle(zone, Owner()); |
5745 const Function& sig_fun = Function::Handle( | 5490 const Function& sig_fun = Function::Handle( |
(...skipping 17 matching lines...) Expand all Loading... |
5763 Array::Handle(Array::New(num_params, Heap::kOld))); | 5508 Array::Handle(Array::New(num_params, Heap::kOld))); |
5764 for (intptr_t i = 0; i < num_params; i++) { | 5509 for (intptr_t i = 0; i < num_params; i++) { |
5765 type = ParameterTypeAt(i); | 5510 type = ParameterTypeAt(i); |
5766 type = type.Canonicalize(trail); | 5511 type = type.Canonicalize(trail); |
5767 sig_fun.SetParameterTypeAt(i, type); | 5512 sig_fun.SetParameterTypeAt(i, type); |
5768 } | 5513 } |
5769 sig_fun.set_parameter_names(Array::Handle(zone, parameter_names())); | 5514 sig_fun.set_parameter_names(Array::Handle(zone, parameter_names())); |
5770 return sig_fun.raw(); | 5515 return sig_fun.raw(); |
5771 } | 5516 } |
5772 | 5517 |
5773 | |
5774 RawType* Function::SignatureType() const { | 5518 RawType* Function::SignatureType() const { |
5775 Type& type = Type::Handle(ExistingSignatureType()); | 5519 Type& type = Type::Handle(ExistingSignatureType()); |
5776 if (type.IsNull()) { | 5520 if (type.IsNull()) { |
5777 // The function type of this function is not yet cached and needs to be | 5521 // The function type of this function is not yet cached and needs to be |
5778 // constructed and cached here. | 5522 // constructed and cached here. |
5779 // A function type is type parameterized in the same way as the owner class | 5523 // A function type is type parameterized in the same way as the owner class |
5780 // of its non-static signature function. | 5524 // of its non-static signature function. |
5781 // It is not type parameterized if its signature function is static, or if | 5525 // It is not type parameterized if its signature function is static, or if |
5782 // none of its result type or formal parameter types are type parameterized. | 5526 // none of its result type or formal parameter types are type parameterized. |
5783 // Unless the function type is a generic typedef, the type arguments of the | 5527 // Unless the function type is a generic typedef, the type arguments of the |
(...skipping 21 matching lines...) Expand all Loading... |
5805 const TypeArguments& signature_type_arguments = | 5549 const TypeArguments& signature_type_arguments = |
5806 TypeArguments::Handle(scope_class.type_parameters()); | 5550 TypeArguments::Handle(scope_class.type_parameters()); |
5807 // Return the still unfinalized signature type. | 5551 // Return the still unfinalized signature type. |
5808 type = Type::New(scope_class, signature_type_arguments, token_pos()); | 5552 type = Type::New(scope_class, signature_type_arguments, token_pos()); |
5809 type.set_signature(*this); | 5553 type.set_signature(*this); |
5810 SetSignatureType(type); | 5554 SetSignatureType(type); |
5811 } | 5555 } |
5812 return type.raw(); | 5556 return type.raw(); |
5813 } | 5557 } |
5814 | 5558 |
5815 | |
5816 void Function::SetSignatureType(const Type& value) const { | 5559 void Function::SetSignatureType(const Type& value) const { |
5817 const Object& obj = Object::Handle(raw_ptr()->data_); | 5560 const Object& obj = Object::Handle(raw_ptr()->data_); |
5818 ASSERT(!obj.IsNull()); | 5561 ASSERT(!obj.IsNull()); |
5819 if (IsSignatureFunction()) { | 5562 if (IsSignatureFunction()) { |
5820 SignatureData::Cast(obj).set_signature_type(value); | 5563 SignatureData::Cast(obj).set_signature_type(value); |
5821 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); | 5564 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); |
5822 } else { | 5565 } else { |
5823 ASSERT(IsClosureFunction()); | 5566 ASSERT(IsClosureFunction()); |
5824 ClosureData::Cast(obj).set_signature_type(value); | 5567 ClosureData::Cast(obj).set_signature_type(value); |
5825 } | 5568 } |
5826 } | 5569 } |
5827 | 5570 |
5828 | |
5829 bool Function::IsRedirectingFactory() const { | 5571 bool Function::IsRedirectingFactory() const { |
5830 if (!IsFactory() || !is_redirecting()) { | 5572 if (!IsFactory() || !is_redirecting()) { |
5831 return false; | 5573 return false; |
5832 } | 5574 } |
5833 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. | 5575 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. |
5834 return true; | 5576 return true; |
5835 } | 5577 } |
5836 | 5578 |
5837 | |
5838 RawType* Function::RedirectionType() const { | 5579 RawType* Function::RedirectionType() const { |
5839 ASSERT(IsRedirectingFactory()); | 5580 ASSERT(IsRedirectingFactory()); |
5840 ASSERT(!is_native()); | 5581 ASSERT(!is_native()); |
5841 const Object& obj = Object::Handle(raw_ptr()->data_); | 5582 const Object& obj = Object::Handle(raw_ptr()->data_); |
5842 ASSERT(!obj.IsNull()); | 5583 ASSERT(!obj.IsNull()); |
5843 return RedirectionData::Cast(obj).type(); | 5584 return RedirectionData::Cast(obj).type(); |
5844 } | 5585 } |
5845 | 5586 |
5846 | |
5847 const char* Function::KindToCString(RawFunction::Kind kind) { | 5587 const char* Function::KindToCString(RawFunction::Kind kind) { |
5848 switch (kind) { | 5588 switch (kind) { |
5849 case RawFunction::kRegularFunction: | 5589 case RawFunction::kRegularFunction: |
5850 return "RegularFunction"; | 5590 return "RegularFunction"; |
5851 break; | 5591 break; |
5852 case RawFunction::kClosureFunction: | 5592 case RawFunction::kClosureFunction: |
5853 return "ClosureFunction"; | 5593 return "ClosureFunction"; |
5854 break; | 5594 break; |
5855 case RawFunction::kSignatureFunction: | 5595 case RawFunction::kSignatureFunction: |
5856 return "SignatureFunction"; | 5596 return "SignatureFunction"; |
(...skipping 27 matching lines...) Expand all Loading... |
5884 break; | 5624 break; |
5885 case RawFunction::kIrregexpFunction: | 5625 case RawFunction::kIrregexpFunction: |
5886 return "IrregexpFunction"; | 5626 return "IrregexpFunction"; |
5887 break; | 5627 break; |
5888 default: | 5628 default: |
5889 UNREACHABLE(); | 5629 UNREACHABLE(); |
5890 return NULL; | 5630 return NULL; |
5891 } | 5631 } |
5892 } | 5632 } |
5893 | 5633 |
5894 | |
5895 void Function::SetRedirectionType(const Type& type) const { | 5634 void Function::SetRedirectionType(const Type& type) const { |
5896 ASSERT(IsFactory()); | 5635 ASSERT(IsFactory()); |
5897 Object& obj = Object::Handle(raw_ptr()->data_); | 5636 Object& obj = Object::Handle(raw_ptr()->data_); |
5898 if (obj.IsNull()) { | 5637 if (obj.IsNull()) { |
5899 obj = RedirectionData::New(); | 5638 obj = RedirectionData::New(); |
5900 set_data(obj); | 5639 set_data(obj); |
5901 } | 5640 } |
5902 RedirectionData::Cast(obj).set_type(type); | 5641 RedirectionData::Cast(obj).set_type(type); |
5903 } | 5642 } |
5904 | 5643 |
5905 | |
5906 RawString* Function::RedirectionIdentifier() const { | 5644 RawString* Function::RedirectionIdentifier() const { |
5907 ASSERT(IsRedirectingFactory()); | 5645 ASSERT(IsRedirectingFactory()); |
5908 const Object& obj = Object::Handle(raw_ptr()->data_); | 5646 const Object& obj = Object::Handle(raw_ptr()->data_); |
5909 ASSERT(!obj.IsNull()); | 5647 ASSERT(!obj.IsNull()); |
5910 return RedirectionData::Cast(obj).identifier(); | 5648 return RedirectionData::Cast(obj).identifier(); |
5911 } | 5649 } |
5912 | 5650 |
5913 | |
5914 void Function::SetRedirectionIdentifier(const String& identifier) const { | 5651 void Function::SetRedirectionIdentifier(const String& identifier) const { |
5915 ASSERT(IsFactory()); | 5652 ASSERT(IsFactory()); |
5916 Object& obj = Object::Handle(raw_ptr()->data_); | 5653 Object& obj = Object::Handle(raw_ptr()->data_); |
5917 if (obj.IsNull()) { | 5654 if (obj.IsNull()) { |
5918 obj = RedirectionData::New(); | 5655 obj = RedirectionData::New(); |
5919 set_data(obj); | 5656 set_data(obj); |
5920 } | 5657 } |
5921 RedirectionData::Cast(obj).set_identifier(identifier); | 5658 RedirectionData::Cast(obj).set_identifier(identifier); |
5922 } | 5659 } |
5923 | 5660 |
5924 | |
5925 RawFunction* Function::RedirectionTarget() const { | 5661 RawFunction* Function::RedirectionTarget() const { |
5926 ASSERT(IsRedirectingFactory()); | 5662 ASSERT(IsRedirectingFactory()); |
5927 const Object& obj = Object::Handle(raw_ptr()->data_); | 5663 const Object& obj = Object::Handle(raw_ptr()->data_); |
5928 ASSERT(!obj.IsNull()); | 5664 ASSERT(!obj.IsNull()); |
5929 return RedirectionData::Cast(obj).target(); | 5665 return RedirectionData::Cast(obj).target(); |
5930 } | 5666 } |
5931 | 5667 |
5932 | |
5933 void Function::SetRedirectionTarget(const Function& target) const { | 5668 void Function::SetRedirectionTarget(const Function& target) const { |
5934 ASSERT(IsFactory()); | 5669 ASSERT(IsFactory()); |
5935 Object& obj = Object::Handle(raw_ptr()->data_); | 5670 Object& obj = Object::Handle(raw_ptr()->data_); |
5936 if (obj.IsNull()) { | 5671 if (obj.IsNull()) { |
5937 obj = RedirectionData::New(); | 5672 obj = RedirectionData::New(); |
5938 set_data(obj); | 5673 set_data(obj); |
5939 } | 5674 } |
5940 RedirectionData::Cast(obj).set_target(target); | 5675 RedirectionData::Cast(obj).set_target(target); |
5941 } | 5676 } |
5942 | 5677 |
5943 | |
5944 // This field is heavily overloaded: | 5678 // This field is heavily overloaded: |
5945 // eval function: Script expression source | 5679 // eval function: Script expression source |
5946 // signature function: SignatureData | 5680 // signature function: SignatureData |
5947 // method extractor: Function extracted closure function | 5681 // method extractor: Function extracted closure function |
5948 // noSuchMethod dispatcher: Array arguments descriptor | 5682 // noSuchMethod dispatcher: Array arguments descriptor |
5949 // invoke-field dispatcher: Array arguments descriptor | 5683 // invoke-field dispatcher: Array arguments descriptor |
5950 // redirecting constructor: RedirectionData | 5684 // redirecting constructor: RedirectionData |
5951 // closure function: ClosureData | 5685 // closure function: ClosureData |
5952 // irregexp function: Array[0] = RegExp | 5686 // irregexp function: Array[0] = RegExp |
5953 // Array[1] = Smi string specialization cid | 5687 // Array[1] = Smi string specialization cid |
5954 // native function: Array[0] = String native name | 5688 // native function: Array[0] = String native name |
5955 // Array[1] = Function implicit closure function | 5689 // Array[1] = Function implicit closure function |
5956 // regular function: Function for implicit closure function | 5690 // regular function: Function for implicit closure function |
5957 void Function::set_data(const Object& value) const { | 5691 void Function::set_data(const Object& value) const { |
5958 StorePointer(&raw_ptr()->data_, value.raw()); | 5692 StorePointer(&raw_ptr()->data_, value.raw()); |
5959 } | 5693 } |
5960 | 5694 |
5961 | |
5962 bool Function::IsInFactoryScope() const { | 5695 bool Function::IsInFactoryScope() const { |
5963 if (!IsLocalFunction()) { | 5696 if (!IsLocalFunction()) { |
5964 return IsFactory(); | 5697 return IsFactory(); |
5965 } | 5698 } |
5966 Function& outer_function = Function::Handle(parent_function()); | 5699 Function& outer_function = Function::Handle(parent_function()); |
5967 while (outer_function.IsLocalFunction()) { | 5700 while (outer_function.IsLocalFunction()) { |
5968 outer_function = outer_function.parent_function(); | 5701 outer_function = outer_function.parent_function(); |
5969 } | 5702 } |
5970 return outer_function.IsFactory(); | 5703 return outer_function.IsFactory(); |
5971 } | 5704 } |
5972 | 5705 |
5973 | |
5974 void Function::set_name(const String& value) const { | 5706 void Function::set_name(const String& value) const { |
5975 ASSERT(value.IsSymbol()); | 5707 ASSERT(value.IsSymbol()); |
5976 StorePointer(&raw_ptr()->name_, value.raw()); | 5708 StorePointer(&raw_ptr()->name_, value.raw()); |
5977 } | 5709 } |
5978 | 5710 |
5979 | |
5980 void Function::set_owner(const Object& value) const { | 5711 void Function::set_owner(const Object& value) const { |
5981 ASSERT(!value.IsNull() || IsSignatureFunction()); | 5712 ASSERT(!value.IsNull() || IsSignatureFunction()); |
5982 StorePointer(&raw_ptr()->owner_, value.raw()); | 5713 StorePointer(&raw_ptr()->owner_, value.raw()); |
5983 } | 5714 } |
5984 | 5715 |
5985 | |
5986 RawRegExp* Function::regexp() const { | 5716 RawRegExp* Function::regexp() const { |
5987 ASSERT(kind() == RawFunction::kIrregexpFunction); | 5717 ASSERT(kind() == RawFunction::kIrregexpFunction); |
5988 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 5718 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |
5989 return RegExp::RawCast(pair.At(0)); | 5719 return RegExp::RawCast(pair.At(0)); |
5990 } | 5720 } |
5991 | 5721 |
5992 | |
5993 class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {}; | 5722 class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {}; |
5994 class StringSpecializationCid | 5723 class StringSpecializationCid |
5995 : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {}; | 5724 : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {}; |
5996 | 5725 |
5997 | |
5998 intptr_t Function::string_specialization_cid() const { | 5726 intptr_t Function::string_specialization_cid() const { |
5999 ASSERT(kind() == RawFunction::kIrregexpFunction); | 5727 ASSERT(kind() == RawFunction::kIrregexpFunction); |
6000 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 5728 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |
6001 return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1)))); | 5729 return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1)))); |
6002 } | 5730 } |
6003 | 5731 |
6004 | |
6005 bool Function::is_sticky_specialization() const { | 5732 bool Function::is_sticky_specialization() const { |
6006 ASSERT(kind() == RawFunction::kIrregexpFunction); | 5733 ASSERT(kind() == RawFunction::kIrregexpFunction); |
6007 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 5734 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |
6008 return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1)))); | 5735 return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1)))); |
6009 } | 5736 } |
6010 | 5737 |
6011 | |
6012 void Function::SetRegExpData(const RegExp& regexp, | 5738 void Function::SetRegExpData(const RegExp& regexp, |
6013 intptr_t string_specialization_cid, | 5739 intptr_t string_specialization_cid, |
6014 bool sticky) const { | 5740 bool sticky) const { |
6015 ASSERT(kind() == RawFunction::kIrregexpFunction); | 5741 ASSERT(kind() == RawFunction::kIrregexpFunction); |
6016 ASSERT(RawObject::IsStringClassId(string_specialization_cid)); | 5742 ASSERT(RawObject::IsStringClassId(string_specialization_cid)); |
6017 ASSERT(raw_ptr()->data_ == Object::null()); | 5743 ASSERT(raw_ptr()->data_ == Object::null()); |
6018 const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); | 5744 const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); |
6019 pair.SetAt(0, regexp); | 5745 pair.SetAt(0, regexp); |
6020 pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) | | 5746 pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) | |
6021 StringSpecializationCid::encode( | 5747 StringSpecializationCid::encode( |
6022 string_specialization_cid)))); | 5748 string_specialization_cid)))); |
6023 set_data(pair); | 5749 set_data(pair); |
6024 } | 5750 } |
6025 | 5751 |
6026 | |
6027 RawString* Function::native_name() const { | 5752 RawString* Function::native_name() const { |
6028 ASSERT(is_native()); | 5753 ASSERT(is_native()); |
6029 const Object& obj = Object::Handle(raw_ptr()->data_); | 5754 const Object& obj = Object::Handle(raw_ptr()->data_); |
6030 ASSERT(obj.IsArray()); | 5755 ASSERT(obj.IsArray()); |
6031 return String::RawCast(Array::Cast(obj).At(0)); | 5756 return String::RawCast(Array::Cast(obj).At(0)); |
6032 } | 5757 } |
6033 | 5758 |
6034 | |
6035 void Function::set_native_name(const String& value) const { | 5759 void Function::set_native_name(const String& value) const { |
6036 ASSERT(is_native()); | 5760 ASSERT(is_native()); |
6037 ASSERT(raw_ptr()->data_ == Object::null()); | 5761 ASSERT(raw_ptr()->data_ == Object::null()); |
6038 const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); | 5762 const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); |
6039 pair.SetAt(0, value); | 5763 pair.SetAt(0, value); |
6040 // pair[1] will be the implicit closure function if needed. | 5764 // pair[1] will be the implicit closure function if needed. |
6041 set_data(pair); | 5765 set_data(pair); |
6042 } | 5766 } |
6043 | 5767 |
6044 | |
6045 void Function::set_result_type(const AbstractType& value) const { | 5768 void Function::set_result_type(const AbstractType& value) const { |
6046 ASSERT(!value.IsNull()); | 5769 ASSERT(!value.IsNull()); |
6047 StorePointer(&raw_ptr()->result_type_, value.raw()); | 5770 StorePointer(&raw_ptr()->result_type_, value.raw()); |
6048 if (value.IsFunctionType()) { | 5771 if (value.IsFunctionType()) { |
6049 // The function result type may refer to this function's type parameters. | 5772 // The function result type may refer to this function's type parameters. |
6050 // Change its parent function. | 5773 // Change its parent function. |
6051 const Function& result_signature_function = | 5774 const Function& result_signature_function = |
6052 Function::Handle(Type::Cast(value).signature()); | 5775 Function::Handle(Type::Cast(value).signature()); |
6053 result_signature_function.set_parent_function(*this); | 5776 result_signature_function.set_parent_function(*this); |
6054 } | 5777 } |
6055 } | 5778 } |
6056 | 5779 |
6057 | |
6058 RawAbstractType* Function::ParameterTypeAt(intptr_t index) const { | 5780 RawAbstractType* Function::ParameterTypeAt(intptr_t index) const { |
6059 const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); | 5781 const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); |
6060 return AbstractType::RawCast(parameter_types.At(index)); | 5782 return AbstractType::RawCast(parameter_types.At(index)); |
6061 } | 5783 } |
6062 | 5784 |
6063 | |
6064 void Function::SetParameterTypeAt(intptr_t index, | 5785 void Function::SetParameterTypeAt(intptr_t index, |
6065 const AbstractType& value) const { | 5786 const AbstractType& value) const { |
6066 ASSERT(!value.IsNull()); | 5787 ASSERT(!value.IsNull()); |
6067 // Method extractor parameters are shared and are in the VM heap. | 5788 // Method extractor parameters are shared and are in the VM heap. |
6068 ASSERT(kind() != RawFunction::kMethodExtractor); | 5789 ASSERT(kind() != RawFunction::kMethodExtractor); |
6069 const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); | 5790 const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); |
6070 parameter_types.SetAt(index, value); | 5791 parameter_types.SetAt(index, value); |
6071 } | 5792 } |
6072 | 5793 |
6073 | |
6074 void Function::set_parameter_types(const Array& value) const { | 5794 void Function::set_parameter_types(const Array& value) const { |
6075 StorePointer(&raw_ptr()->parameter_types_, value.raw()); | 5795 StorePointer(&raw_ptr()->parameter_types_, value.raw()); |
6076 } | 5796 } |
6077 | 5797 |
6078 | |
6079 RawString* Function::ParameterNameAt(intptr_t index) const { | 5798 RawString* Function::ParameterNameAt(intptr_t index) const { |
6080 const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); | 5799 const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); |
6081 return String::RawCast(parameter_names.At(index)); | 5800 return String::RawCast(parameter_names.At(index)); |
6082 } | 5801 } |
6083 | 5802 |
6084 | |
6085 void Function::SetParameterNameAt(intptr_t index, const String& value) const { | 5803 void Function::SetParameterNameAt(intptr_t index, const String& value) const { |
6086 ASSERT(!value.IsNull() && value.IsSymbol()); | 5804 ASSERT(!value.IsNull() && value.IsSymbol()); |
6087 const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); | 5805 const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); |
6088 parameter_names.SetAt(index, value); | 5806 parameter_names.SetAt(index, value); |
6089 } | 5807 } |
6090 | 5808 |
6091 | |
6092 void Function::set_parameter_names(const Array& value) const { | 5809 void Function::set_parameter_names(const Array& value) const { |
6093 StorePointer(&raw_ptr()->parameter_names_, value.raw()); | 5810 StorePointer(&raw_ptr()->parameter_names_, value.raw()); |
6094 } | 5811 } |
6095 | 5812 |
6096 | |
6097 void Function::set_type_parameters(const TypeArguments& value) const { | 5813 void Function::set_type_parameters(const TypeArguments& value) const { |
6098 StorePointer(&raw_ptr()->type_parameters_, value.raw()); | 5814 StorePointer(&raw_ptr()->type_parameters_, value.raw()); |
6099 } | 5815 } |
6100 | 5816 |
6101 | |
6102 intptr_t Function::NumTypeParameters(Thread* thread) const { | 5817 intptr_t Function::NumTypeParameters(Thread* thread) const { |
6103 if (type_parameters() == TypeArguments::null()) { | 5818 if (type_parameters() == TypeArguments::null()) { |
6104 return 0; | 5819 return 0; |
6105 } | 5820 } |
6106 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 5821 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
6107 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 5822 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
6108 type_params = type_parameters(); | 5823 type_params = type_parameters(); |
6109 // We require null to represent a non-generic function. | 5824 // We require null to represent a non-generic function. |
6110 ASSERT(type_params.Length() != 0); | 5825 ASSERT(type_params.Length() != 0); |
6111 return type_params.Length(); | 5826 return type_params.Length(); |
6112 } | 5827 } |
6113 | 5828 |
6114 | |
6115 intptr_t Function::NumParentTypeParameters() const { | 5829 intptr_t Function::NumParentTypeParameters() const { |
6116 if (IsImplicitClosureFunction()) { | 5830 if (IsImplicitClosureFunction()) { |
6117 return 0; | 5831 return 0; |
6118 } | 5832 } |
6119 Thread* thread = Thread::Current(); | 5833 Thread* thread = Thread::Current(); |
6120 Function& parent = Function::Handle(parent_function()); | 5834 Function& parent = Function::Handle(parent_function()); |
6121 intptr_t num_parent_type_params = 0; | 5835 intptr_t num_parent_type_params = 0; |
6122 while (!parent.IsNull()) { | 5836 while (!parent.IsNull()) { |
6123 num_parent_type_params += parent.NumTypeParameters(thread); | 5837 num_parent_type_params += parent.NumTypeParameters(thread); |
6124 parent ^= parent.parent_function(); | 5838 parent ^= parent.parent_function(); |
6125 } | 5839 } |
6126 return num_parent_type_params; | 5840 return num_parent_type_params; |
6127 } | 5841 } |
6128 | 5842 |
6129 | |
6130 RawTypeParameter* Function::LookupTypeParameter( | 5843 RawTypeParameter* Function::LookupTypeParameter( |
6131 const String& type_name, | 5844 const String& type_name, |
6132 intptr_t* function_level) const { | 5845 intptr_t* function_level) const { |
6133 ASSERT(!type_name.IsNull()); | 5846 ASSERT(!type_name.IsNull()); |
6134 Thread* thread = Thread::Current(); | 5847 Thread* thread = Thread::Current(); |
6135 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 5848 REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |
6136 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); | 5849 REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |
6137 REUSABLE_STRING_HANDLESCOPE(thread); | 5850 REUSABLE_STRING_HANDLESCOPE(thread); |
6138 REUSABLE_FUNCTION_HANDLESCOPE(thread); | 5851 REUSABLE_FUNCTION_HANDLESCOPE(thread); |
6139 TypeArguments& type_params = thread->TypeArgumentsHandle(); | 5852 TypeArguments& type_params = thread->TypeArgumentsHandle(); |
(...skipping 20 matching lines...) Expand all Loading... |
6160 break; | 5873 break; |
6161 } | 5874 } |
6162 function ^= function.parent_function(); | 5875 function ^= function.parent_function(); |
6163 if (function_level != NULL) { | 5876 if (function_level != NULL) { |
6164 (*function_level)--; | 5877 (*function_level)--; |
6165 } | 5878 } |
6166 } | 5879 } |
6167 return TypeParameter::null(); | 5880 return TypeParameter::null(); |
6168 } | 5881 } |
6169 | 5882 |
6170 | |
6171 void Function::set_kind(RawFunction::Kind value) const { | 5883 void Function::set_kind(RawFunction::Kind value) const { |
6172 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); | 5884 set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); |
6173 } | 5885 } |
6174 | 5886 |
6175 | |
6176 void Function::set_modifier(RawFunction::AsyncModifier value) const { | 5887 void Function::set_modifier(RawFunction::AsyncModifier value) const { |
6177 set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); | 5888 set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); |
6178 } | 5889 } |
6179 | 5890 |
6180 | |
6181 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { | 5891 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { |
6182 // Prevent multiple settings of kind. | 5892 // Prevent multiple settings of kind. |
6183 ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); | 5893 ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); |
6184 set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); | 5894 set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); |
6185 } | 5895 } |
6186 | 5896 |
6187 | |
6188 void Function::set_token_pos(TokenPosition token_pos) const { | 5897 void Function::set_token_pos(TokenPosition token_pos) const { |
6189 #if defined(DART_PRECOMPILED_RUNTIME) | 5898 #if defined(DART_PRECOMPILED_RUNTIME) |
6190 UNREACHABLE(); | 5899 UNREACHABLE(); |
6191 #else | 5900 #else |
6192 ASSERT(!token_pos.IsClassifying() || IsMethodExtractor()); | 5901 ASSERT(!token_pos.IsClassifying() || IsMethodExtractor()); |
6193 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 5902 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
6194 #endif | 5903 #endif |
6195 } | 5904 } |
6196 | 5905 |
6197 | |
6198 void Function::set_kind_tag(uint32_t value) const { | 5906 void Function::set_kind_tag(uint32_t value) const { |
6199 StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); | 5907 StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); |
6200 } | 5908 } |
6201 | 5909 |
6202 | |
6203 void Function::set_num_fixed_parameters(intptr_t value) const { | 5910 void Function::set_num_fixed_parameters(intptr_t value) const { |
6204 ASSERT(value >= 0); | 5911 ASSERT(value >= 0); |
6205 ASSERT(Utils::IsInt(16, value)); | 5912 ASSERT(Utils::IsInt(16, value)); |
6206 StoreNonPointer(&raw_ptr()->num_fixed_parameters_, | 5913 StoreNonPointer(&raw_ptr()->num_fixed_parameters_, |
6207 static_cast<int16_t>(value)); | 5914 static_cast<int16_t>(value)); |
6208 } | 5915 } |
6209 | 5916 |
6210 | |
6211 void Function::set_num_optional_parameters(intptr_t value) const { | 5917 void Function::set_num_optional_parameters(intptr_t value) const { |
6212 // A positive value indicates positional params, a negative one named params. | 5918 // A positive value indicates positional params, a negative one named params. |
6213 ASSERT(Utils::IsInt(16, value)); | 5919 ASSERT(Utils::IsInt(16, value)); |
6214 StoreNonPointer(&raw_ptr()->num_optional_parameters_, | 5920 StoreNonPointer(&raw_ptr()->num_optional_parameters_, |
6215 static_cast<int16_t>(value)); | 5921 static_cast<int16_t>(value)); |
6216 } | 5922 } |
6217 | 5923 |
6218 | |
6219 void Function::SetNumOptionalParameters(intptr_t num_optional_parameters, | 5924 void Function::SetNumOptionalParameters(intptr_t num_optional_parameters, |
6220 bool are_optional_positional) const { | 5925 bool are_optional_positional) const { |
6221 ASSERT(num_optional_parameters >= 0); | 5926 ASSERT(num_optional_parameters >= 0); |
6222 set_num_optional_parameters(are_optional_positional | 5927 set_num_optional_parameters(are_optional_positional |
6223 ? num_optional_parameters | 5928 ? num_optional_parameters |
6224 : -num_optional_parameters); | 5929 : -num_optional_parameters); |
6225 } | 5930 } |
6226 | 5931 |
6227 | |
6228 bool Function::IsOptimizable() const { | 5932 bool Function::IsOptimizable() const { |
6229 if (FLAG_precompiled_mode) { | 5933 if (FLAG_precompiled_mode) { |
6230 return true; | 5934 return true; |
6231 } | 5935 } |
6232 if (is_native()) { | 5936 if (is_native()) { |
6233 // Native methods don't need to be optimized. | 5937 // Native methods don't need to be optimized. |
6234 return false; | 5938 return false; |
6235 } | 5939 } |
6236 const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos(); | 5940 const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos(); |
6237 if (is_optimizable() && (script() != Script::null()) && | 5941 if (is_optimizable() && (script() != Script::null()) && |
6238 (function_length < FLAG_huge_method_cutoff_in_tokens)) { | 5942 (function_length < FLAG_huge_method_cutoff_in_tokens)) { |
6239 // Additional check needed for implicit getters. | 5943 // Additional check needed for implicit getters. |
6240 return (unoptimized_code() == Object::null()) || | 5944 return (unoptimized_code() == Object::null()) || |
6241 (Code::Handle(unoptimized_code()).Size() < | 5945 (Code::Handle(unoptimized_code()).Size() < |
6242 FLAG_huge_method_cutoff_in_code_size); | 5946 FLAG_huge_method_cutoff_in_code_size); |
6243 } | 5947 } |
6244 return false; | 5948 return false; |
6245 } | 5949 } |
6246 | 5950 |
6247 | |
6248 void Function::SetIsOptimizable(bool value) const { | 5951 void Function::SetIsOptimizable(bool value) const { |
6249 ASSERT(!is_native()); | 5952 ASSERT(!is_native()); |
6250 set_is_optimizable(value); | 5953 set_is_optimizable(value); |
6251 if (!value) { | 5954 if (!value) { |
6252 set_is_inlinable(false); | 5955 set_is_inlinable(false); |
6253 set_usage_counter(INT_MIN); | 5956 set_usage_counter(INT_MIN); |
6254 } | 5957 } |
6255 } | 5958 } |
6256 | 5959 |
6257 | |
6258 bool Function::CanBeInlined() const { | 5960 bool Function::CanBeInlined() const { |
6259 Thread* thread = Thread::Current(); | 5961 Thread* thread = Thread::Current(); |
6260 return is_inlinable() && !is_external() && !is_generated_body() && | 5962 return is_inlinable() && !is_external() && !is_generated_body() && |
6261 (!FLAG_support_debugger || | 5963 (!FLAG_support_debugger || |
6262 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); | 5964 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); |
6263 } | 5965 } |
6264 | 5966 |
6265 | |
6266 intptr_t Function::NumParameters() const { | 5967 intptr_t Function::NumParameters() const { |
6267 return num_fixed_parameters() + NumOptionalParameters(); | 5968 return num_fixed_parameters() + NumOptionalParameters(); |
6268 } | 5969 } |
6269 | 5970 |
6270 | |
6271 intptr_t Function::NumImplicitParameters() const { | 5971 intptr_t Function::NumImplicitParameters() const { |
6272 if (kind() == RawFunction::kConstructor) { | 5972 if (kind() == RawFunction::kConstructor) { |
6273 // Type arguments for factory; instance for generative constructor. | 5973 // Type arguments for factory; instance for generative constructor. |
6274 return 1; | 5974 return 1; |
6275 } | 5975 } |
6276 if ((kind() == RawFunction::kClosureFunction) || | 5976 if ((kind() == RawFunction::kClosureFunction) || |
6277 (kind() == RawFunction::kSignatureFunction)) { | 5977 (kind() == RawFunction::kSignatureFunction)) { |
6278 return 1; // Closure object. | 5978 return 1; // Closure object. |
6279 } | 5979 } |
6280 if (!is_static()) { | 5980 if (!is_static()) { |
6281 // Closure functions defined inside instance (i.e. non-static) functions are | 5981 // Closure functions defined inside instance (i.e. non-static) functions are |
6282 // marked as non-static, but they do not have a receiver. | 5982 // marked as non-static, but they do not have a receiver. |
6283 // Closures are handled above. | 5983 // Closures are handled above. |
6284 ASSERT((kind() != RawFunction::kClosureFunction) && | 5984 ASSERT((kind() != RawFunction::kClosureFunction) && |
6285 (kind() != RawFunction::kSignatureFunction)); | 5985 (kind() != RawFunction::kSignatureFunction)); |
6286 return 1; // Receiver. | 5986 return 1; // Receiver. |
6287 } | 5987 } |
6288 return 0; // No implicit parameters. | 5988 return 0; // No implicit parameters. |
6289 } | 5989 } |
6290 | 5990 |
6291 | |
6292 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments, | 5991 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments, |
6293 intptr_t num_arguments, | 5992 intptr_t num_arguments, |
6294 intptr_t num_named_arguments, | 5993 intptr_t num_named_arguments, |
6295 String* error_message) const { | 5994 String* error_message) const { |
6296 if ((num_type_arguments != 0) && | 5995 if ((num_type_arguments != 0) && |
6297 (num_type_arguments != NumTypeParameters())) { | 5996 (num_type_arguments != NumTypeParameters())) { |
6298 if (error_message != NULL) { | 5997 if (error_message != NULL) { |
6299 const intptr_t kMessageBufferSize = 64; | 5998 const intptr_t kMessageBufferSize = 64; |
6300 char message_buffer[kMessageBufferSize]; | 5999 char message_buffer[kMessageBufferSize]; |
6301 OS::SNPrint(message_buffer, kMessageBufferSize, | 6000 OS::SNPrint(message_buffer, kMessageBufferSize, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6355 num_fixed_parameters() - num_hidden_params); | 6054 num_fixed_parameters() - num_hidden_params); |
6356 // Allocate in old space because it can be invoked in background | 6055 // Allocate in old space because it can be invoked in background |
6357 // optimizing compilation. | 6056 // optimizing compilation. |
6358 *error_message = String::New(message_buffer, Heap::kOld); | 6057 *error_message = String::New(message_buffer, Heap::kOld); |
6359 } | 6058 } |
6360 return false; // Too few fixed and/or positional arguments. | 6059 return false; // Too few fixed and/or positional arguments. |
6361 } | 6060 } |
6362 return true; | 6061 return true; |
6363 } | 6062 } |
6364 | 6063 |
6365 | |
6366 bool Function::AreValidArguments(intptr_t num_type_arguments, | 6064 bool Function::AreValidArguments(intptr_t num_type_arguments, |
6367 intptr_t num_arguments, | 6065 intptr_t num_arguments, |
6368 const Array& argument_names, | 6066 const Array& argument_names, |
6369 String* error_message) const { | 6067 String* error_message) const { |
6370 const intptr_t num_named_arguments = | 6068 const intptr_t num_named_arguments = |
6371 argument_names.IsNull() ? 0 : argument_names.Length(); | 6069 argument_names.IsNull() ? 0 : argument_names.Length(); |
6372 if (!AreValidArgumentCounts(num_type_arguments, num_arguments, | 6070 if (!AreValidArgumentCounts(num_type_arguments, num_arguments, |
6373 num_named_arguments, error_message)) { | 6071 num_named_arguments, error_message)) { |
6374 return false; | 6072 return false; |
6375 } | 6073 } |
(...skipping 25 matching lines...) Expand all Loading... |
6401 // Allocate in old space because it can be invoked in background | 6099 // Allocate in old space because it can be invoked in background |
6402 // optimizing compilation. | 6100 // optimizing compilation. |
6403 *error_message = String::New(message_buffer, Heap::kOld); | 6101 *error_message = String::New(message_buffer, Heap::kOld); |
6404 } | 6102 } |
6405 return false; | 6103 return false; |
6406 } | 6104 } |
6407 } | 6105 } |
6408 return true; | 6106 return true; |
6409 } | 6107 } |
6410 | 6108 |
6411 | |
6412 bool Function::AreValidArguments(const ArgumentsDescriptor& args_desc, | 6109 bool Function::AreValidArguments(const ArgumentsDescriptor& args_desc, |
6413 String* error_message) const { | 6110 String* error_message) const { |
6414 const intptr_t num_type_arguments = args_desc.TypeArgsLen(); | 6111 const intptr_t num_type_arguments = args_desc.TypeArgsLen(); |
6415 const intptr_t num_arguments = args_desc.Count(); | 6112 const intptr_t num_arguments = args_desc.Count(); |
6416 const intptr_t num_named_arguments = args_desc.NamedCount(); | 6113 const intptr_t num_named_arguments = args_desc.NamedCount(); |
6417 | 6114 |
6418 if (!AreValidArgumentCounts(num_type_arguments, num_arguments, | 6115 if (!AreValidArgumentCounts(num_type_arguments, num_arguments, |
6419 num_named_arguments, error_message)) { | 6116 num_named_arguments, error_message)) { |
6420 return false; | 6117 return false; |
6421 } | 6118 } |
(...skipping 25 matching lines...) Expand all Loading... |
6447 // Allocate in old space because it can be invoked in background | 6144 // Allocate in old space because it can be invoked in background |
6448 // optimizing compilation. | 6145 // optimizing compilation. |
6449 *error_message = String::New(message_buffer, Heap::kOld); | 6146 *error_message = String::New(message_buffer, Heap::kOld); |
6450 } | 6147 } |
6451 return false; | 6148 return false; |
6452 } | 6149 } |
6453 } | 6150 } |
6454 return true; | 6151 return true; |
6455 } | 6152 } |
6456 | 6153 |
6457 | |
6458 // Helper allocating a C string buffer in the zone, printing the fully qualified | 6154 // Helper allocating a C string buffer in the zone, printing the fully qualified |
6459 // name of a function in it, and replacing ':' by '_' to make sure the | 6155 // name of a function in it, and replacing ':' by '_' to make sure the |
6460 // constructed name is a valid C++ identifier for debugging purpose. | 6156 // constructed name is a valid C++ identifier for debugging purpose. |
6461 // Set 'chars' to allocated buffer and return number of written characters. | 6157 // Set 'chars' to allocated buffer and return number of written characters. |
6462 | 6158 |
6463 enum QualifiedFunctionLibKind { | 6159 enum QualifiedFunctionLibKind { |
6464 kQualifiedFunctionLibKindLibUrl, | 6160 kQualifiedFunctionLibKindLibUrl, |
6465 kQualifiedFunctionLibKindLibName | 6161 kQualifiedFunctionLibKindLibName |
6466 }; | 6162 }; |
6467 | 6163 |
6468 | |
6469 static intptr_t ConstructFunctionFullyQualifiedCString( | 6164 static intptr_t ConstructFunctionFullyQualifiedCString( |
6470 const Function& function, | 6165 const Function& function, |
6471 char** chars, | 6166 char** chars, |
6472 intptr_t reserve_len, | 6167 intptr_t reserve_len, |
6473 bool with_lib, | 6168 bool with_lib, |
6474 QualifiedFunctionLibKind lib_kind) { | 6169 QualifiedFunctionLibKind lib_kind) { |
6475 const char* name = String::Handle(function.name()).ToCString(); | 6170 const char* name = String::Handle(function.name()).ToCString(); |
6476 const char* function_format = (reserve_len == 0) ? "%s" : "%s_"; | 6171 const char* function_format = (reserve_len == 0) ? "%s" : "%s_"; |
6477 reserve_len += OS::SNPrint(NULL, 0, function_format, name); | 6172 reserve_len += OS::SNPrint(NULL, 0, function_format, name); |
6478 const Function& parent = Function::Handle(function.parent_function()); | 6173 const Function& parent = Function::Handle(function.parent_function()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6518 written += OS::SNPrint(next, reserve_len + 1, function_format, name); | 6213 written += OS::SNPrint(next, reserve_len + 1, function_format, name); |
6519 // Replace ":" with "_". | 6214 // Replace ":" with "_". |
6520 while (true) { | 6215 while (true) { |
6521 next = strchr(next, ':'); | 6216 next = strchr(next, ':'); |
6522 if (next == NULL) break; | 6217 if (next == NULL) break; |
6523 *next = '_'; | 6218 *next = '_'; |
6524 } | 6219 } |
6525 return written; | 6220 return written; |
6526 } | 6221 } |
6527 | 6222 |
6528 | |
6529 const char* Function::ToFullyQualifiedCString() const { | 6223 const char* Function::ToFullyQualifiedCString() const { |
6530 char* chars = NULL; | 6224 char* chars = NULL; |
6531 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, | 6225 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, |
6532 kQualifiedFunctionLibKindLibUrl); | 6226 kQualifiedFunctionLibKindLibUrl); |
6533 return chars; | 6227 return chars; |
6534 } | 6228 } |
6535 | 6229 |
6536 | |
6537 const char* Function::ToLibNamePrefixedQualifiedCString() const { | 6230 const char* Function::ToLibNamePrefixedQualifiedCString() const { |
6538 char* chars = NULL; | 6231 char* chars = NULL; |
6539 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, | 6232 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, |
6540 kQualifiedFunctionLibKindLibName); | 6233 kQualifiedFunctionLibKindLibName); |
6541 return chars; | 6234 return chars; |
6542 } | 6235 } |
6543 | 6236 |
6544 | |
6545 const char* Function::ToQualifiedCString() const { | 6237 const char* Function::ToQualifiedCString() const { |
6546 char* chars = NULL; | 6238 char* chars = NULL; |
6547 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, false, | 6239 ConstructFunctionFullyQualifiedCString(*this, &chars, 0, false, |
6548 kQualifiedFunctionLibKindLibUrl); | 6240 kQualifiedFunctionLibKindLibUrl); |
6549 return chars; | 6241 return chars; |
6550 } | 6242 } |
6551 | 6243 |
6552 | |
6553 bool Function::HasCompatibleParametersWith(const Function& other, | 6244 bool Function::HasCompatibleParametersWith(const Function& other, |
6554 Error* bound_error) const { | 6245 Error* bound_error) const { |
6555 ASSERT(Isolate::Current()->error_on_bad_override()); | 6246 ASSERT(Isolate::Current()->error_on_bad_override()); |
6556 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 6247 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
6557 // Check that this function's signature type is a subtype of the other | 6248 // Check that this function's signature type is a subtype of the other |
6558 // function's signature type. | 6249 // function's signature type. |
6559 // Map type parameters referred to by formal parameter types and result type | 6250 // Map type parameters referred to by formal parameter types and result type |
6560 // in the signature to dynamic before the test. | 6251 // in the signature to dynamic before the test. |
6561 // Note that type parameters declared by a generic signature are preserved. | 6252 // Note that type parameters declared by a generic signature are preserved. |
6562 Function& this_fun = Function::Handle(raw()); | 6253 Function& this_fun = Function::Handle(raw()); |
(...skipping 26 matching lines...) Expand all Loading... |
6589 } | 6280 } |
6590 // We should also check that if the other function explicitly specifies a | 6281 // We should also check that if the other function explicitly specifies a |
6591 // default value for a formal parameter, this function does not specify a | 6282 // default value for a formal parameter, this function does not specify a |
6592 // different default value for the same parameter. However, this check is not | 6283 // different default value for the same parameter. However, this check is not |
6593 // possible in the current implementation, because the default parameter | 6284 // possible in the current implementation, because the default parameter |
6594 // values are not stored in the Function object, but discarded after a | 6285 // values are not stored in the Function object, but discarded after a |
6595 // function is compiled. | 6286 // function is compiled. |
6596 return true; | 6287 return true; |
6597 } | 6288 } |
6598 | 6289 |
6599 | |
6600 RawFunction* Function::InstantiateSignatureFrom( | 6290 RawFunction* Function::InstantiateSignatureFrom( |
6601 const TypeArguments& instantiator_type_arguments, | 6291 const TypeArguments& instantiator_type_arguments, |
6602 const TypeArguments& function_type_arguments, | 6292 const TypeArguments& function_type_arguments, |
6603 Heap::Space space) const { | 6293 Heap::Space space) const { |
6604 Zone* zone = Thread::Current()->zone(); | 6294 Zone* zone = Thread::Current()->zone(); |
6605 const Object& owner = Object::Handle(zone, RawOwner()); | 6295 const Object& owner = Object::Handle(zone, RawOwner()); |
6606 const Function& parent = Function::Handle(zone, parent_function()); | 6296 const Function& parent = Function::Handle(zone, parent_function()); |
6607 ASSERT(!HasInstantiatedSignature()); | 6297 ASSERT(!HasInstantiatedSignature()); |
6608 Function& sig = Function::Handle( | 6298 Function& sig = Function::Handle( |
6609 zone, Function::NewSignatureFunction(owner, parent, | 6299 zone, Function::NewSignatureFunction(owner, parent, |
(...skipping 17 matching lines...) Expand all Loading... |
6627 type = type.InstantiateFrom(instantiator_type_arguments, | 6317 type = type.InstantiateFrom(instantiator_type_arguments, |
6628 function_type_arguments, NULL, NULL, NULL, | 6318 function_type_arguments, NULL, NULL, NULL, |
6629 space); | 6319 space); |
6630 } | 6320 } |
6631 sig.SetParameterTypeAt(i, type); | 6321 sig.SetParameterTypeAt(i, type); |
6632 } | 6322 } |
6633 sig.set_parameter_names(Array::Handle(zone, parameter_names())); | 6323 sig.set_parameter_names(Array::Handle(zone, parameter_names())); |
6634 return sig.raw(); | 6324 return sig.raw(); |
6635 } | 6325 } |
6636 | 6326 |
6637 | |
6638 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 6327 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |
6639 // of this function is a subtype or a supertype of the type of the specified | 6328 // of this function is a subtype or a supertype of the type of the specified |
6640 // parameter of the other function. | 6329 // parameter of the other function. |
6641 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 6330 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |
6642 // parameter of this function is more specific than the type of the specified | 6331 // parameter of this function is more specific than the type of the specified |
6643 // parameter of the other function. | 6332 // parameter of the other function. |
6644 // Note that we do not apply contravariance of parameter types, but covariance | 6333 // Note that we do not apply contravariance of parameter types, but covariance |
6645 // of both parameter types and result type. | 6334 // of both parameter types and result type. |
6646 bool Function::TestParameterType(TypeTestKind test_kind, | 6335 bool Function::TestParameterType(TypeTestKind test_kind, |
6647 intptr_t parameter_position, | 6336 intptr_t parameter_position, |
(...skipping 22 matching lines...) Expand all Loading... |
6670 } else { | 6359 } else { |
6671 ASSERT(test_kind == kIsMoreSpecificThan); | 6360 ASSERT(test_kind == kIsMoreSpecificThan); |
6672 if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, | 6361 if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, |
6673 bound_trail, space)) { | 6362 bound_trail, space)) { |
6674 return false; | 6363 return false; |
6675 } | 6364 } |
6676 } | 6365 } |
6677 return true; | 6366 return true; |
6678 } | 6367 } |
6679 | 6368 |
6680 | |
6681 bool Function::HasSameTypeParametersAndBounds(const Function& other) const { | 6369 bool Function::HasSameTypeParametersAndBounds(const Function& other) const { |
6682 Thread* thread = Thread::Current(); | 6370 Thread* thread = Thread::Current(); |
6683 Zone* zone = thread->zone(); | 6371 Zone* zone = thread->zone(); |
6684 const intptr_t num_type_params = NumTypeParameters(thread); | 6372 const intptr_t num_type_params = NumTypeParameters(thread); |
6685 if (num_type_params != other.NumTypeParameters(thread)) { | 6373 if (num_type_params != other.NumTypeParameters(thread)) { |
6686 return false; | 6374 return false; |
6687 } | 6375 } |
6688 if (num_type_params > 0) { | 6376 if (num_type_params > 0) { |
6689 const TypeArguments& type_params = | 6377 const TypeArguments& type_params = |
6690 TypeArguments::Handle(zone, type_parameters()); | 6378 TypeArguments::Handle(zone, type_parameters()); |
(...skipping 13 matching lines...) Expand all Loading... |
6704 other_bound = other_type_param.bound(); | 6392 other_bound = other_type_param.bound(); |
6705 ASSERT(other_bound.IsFinalized()); | 6393 ASSERT(other_bound.IsFinalized()); |
6706 if (!bound.Equals(other_bound)) { | 6394 if (!bound.Equals(other_bound)) { |
6707 return false; | 6395 return false; |
6708 } | 6396 } |
6709 } | 6397 } |
6710 } | 6398 } |
6711 return true; | 6399 return true; |
6712 } | 6400 } |
6713 | 6401 |
6714 | |
6715 bool Function::TypeTest(TypeTestKind test_kind, | 6402 bool Function::TypeTest(TypeTestKind test_kind, |
6716 const Function& other, | 6403 const Function& other, |
6717 Error* bound_error, | 6404 Error* bound_error, |
6718 TrailPtr bound_trail, | 6405 TrailPtr bound_trail, |
6719 Heap::Space space) const { | 6406 Heap::Space space) const { |
6720 const intptr_t num_fixed_params = num_fixed_parameters(); | 6407 const intptr_t num_fixed_params = num_fixed_parameters(); |
6721 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 6408 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |
6722 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 6409 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |
6723 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 6410 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |
6724 const intptr_t other_num_opt_pos_params = | 6411 const intptr_t other_num_opt_pos_params = |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6809 break; | 6496 break; |
6810 } | 6497 } |
6811 } | 6498 } |
6812 if (!found_param_name) { | 6499 if (!found_param_name) { |
6813 return false; | 6500 return false; |
6814 } | 6501 } |
6815 } | 6502 } |
6816 return true; | 6503 return true; |
6817 } | 6504 } |
6818 | 6505 |
6819 | |
6820 // The compiler generates an implicit constructor if a class definition | 6506 // The compiler generates an implicit constructor if a class definition |
6821 // does not contain an explicit constructor or factory. The implicit | 6507 // does not contain an explicit constructor or factory. The implicit |
6822 // constructor has the same token position as the owner class. | 6508 // constructor has the same token position as the owner class. |
6823 bool Function::IsImplicitConstructor() const { | 6509 bool Function::IsImplicitConstructor() const { |
6824 return IsGenerativeConstructor() && (token_pos() == end_token_pos()); | 6510 return IsGenerativeConstructor() && (token_pos() == end_token_pos()); |
6825 } | 6511 } |
6826 | 6512 |
6827 | |
6828 bool Function::IsImplicitClosureFunction() const { | 6513 bool Function::IsImplicitClosureFunction() const { |
6829 if (!IsClosureFunction()) { | 6514 if (!IsClosureFunction()) { |
6830 return false; | 6515 return false; |
6831 } | 6516 } |
6832 const Function& parent = Function::Handle(parent_function()); | 6517 const Function& parent = Function::Handle(parent_function()); |
6833 return (parent.implicit_closure_function() == raw()); | 6518 return (parent.implicit_closure_function() == raw()); |
6834 } | 6519 } |
6835 | 6520 |
6836 | |
6837 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) { | 6521 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) { |
6838 NoSafepointScope no_safepoint; | 6522 NoSafepointScope no_safepoint; |
6839 uint32_t kind_tag = func->ptr()->kind_tag_; | 6523 uint32_t kind_tag = func->ptr()->kind_tag_; |
6840 if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) { | 6524 if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) { |
6841 return false; | 6525 return false; |
6842 } | 6526 } |
6843 if (!StaticBit::decode(kind_tag)) { | 6527 if (!StaticBit::decode(kind_tag)) { |
6844 return false; | 6528 return false; |
6845 } | 6529 } |
6846 RawClosureData* data = reinterpret_cast<RawClosureData*>(func->ptr()->data_); | 6530 RawClosureData* data = reinterpret_cast<RawClosureData*>(func->ptr()->data_); |
6847 RawFunction* parent_function = data->ptr()->parent_function_; | 6531 RawFunction* parent_function = data->ptr()->parent_function_; |
6848 return (parent_function->ptr()->data_ == reinterpret_cast<RawObject*>(func)); | 6532 return (parent_function->ptr()->data_ == reinterpret_cast<RawObject*>(func)); |
6849 } | 6533 } |
6850 | 6534 |
6851 | |
6852 bool Function::IsConstructorClosureFunction() const { | 6535 bool Function::IsConstructorClosureFunction() const { |
6853 return IsClosureFunction() && | 6536 return IsClosureFunction() && |
6854 String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix()); | 6537 String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix()); |
6855 } | 6538 } |
6856 | 6539 |
6857 | |
6858 RawFunction* Function::New(Heap::Space space) { | 6540 RawFunction* Function::New(Heap::Space space) { |
6859 ASSERT(Object::function_class() != Class::null()); | 6541 ASSERT(Object::function_class() != Class::null()); |
6860 RawObject* raw = | 6542 RawObject* raw = |
6861 Object::Allocate(Function::kClassId, Function::InstanceSize(), space); | 6543 Object::Allocate(Function::kClassId, Function::InstanceSize(), space); |
6862 return reinterpret_cast<RawFunction*>(raw); | 6544 return reinterpret_cast<RawFunction*>(raw); |
6863 } | 6545 } |
6864 | 6546 |
6865 | |
6866 RawFunction* Function::New(const String& name, | 6547 RawFunction* Function::New(const String& name, |
6867 RawFunction::Kind kind, | 6548 RawFunction::Kind kind, |
6868 bool is_static, | 6549 bool is_static, |
6869 bool is_const, | 6550 bool is_const, |
6870 bool is_abstract, | 6551 bool is_abstract, |
6871 bool is_external, | 6552 bool is_external, |
6872 bool is_native, | 6553 bool is_native, |
6873 const Object& owner, | 6554 const Object& owner, |
6874 TokenPosition token_pos, | 6555 TokenPosition token_pos, |
6875 Heap::Space space) { | 6556 Heap::Space space) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6920 SignatureData::Handle(SignatureData::New(space)); | 6601 SignatureData::Handle(SignatureData::New(space)); |
6921 result.set_data(data); | 6602 result.set_data(data); |
6922 } else { | 6603 } else { |
6923 // Functions other than signature functions have no reason to be allocated | 6604 // Functions other than signature functions have no reason to be allocated |
6924 // in new space. | 6605 // in new space. |
6925 ASSERT(space == Heap::kOld); | 6606 ASSERT(space == Heap::kOld); |
6926 } | 6607 } |
6927 return result.raw(); | 6608 return result.raw(); |
6928 } | 6609 } |
6929 | 6610 |
6930 | |
6931 RawFunction* Function::Clone(const Class& new_owner) const { | 6611 RawFunction* Function::Clone(const Class& new_owner) const { |
6932 ASSERT(!IsGenerativeConstructor()); | 6612 ASSERT(!IsGenerativeConstructor()); |
6933 Thread* thread = Thread::Current(); | 6613 Thread* thread = Thread::Current(); |
6934 Zone* zone = thread->zone(); | 6614 Zone* zone = thread->zone(); |
6935 Function& clone = Function::Handle(zone); | 6615 Function& clone = Function::Handle(zone); |
6936 clone ^= Object::Clone(*this, Heap::kOld); | 6616 clone ^= Object::Clone(*this, Heap::kOld); |
6937 const Class& origin = Class::Handle(zone, this->origin()); | 6617 const Class& origin = Class::Handle(zone, this->origin()); |
6938 const PatchClass& clone_owner = | 6618 const PatchClass& clone_owner = |
6939 PatchClass::Handle(zone, PatchClass::New(new_owner, origin)); | 6619 PatchClass::Handle(zone, PatchClass::New(new_owner, origin)); |
6940 clone.set_owner(clone_owner); | 6620 clone.set_owner(clone_owner); |
(...skipping 29 matching lines...) Expand all Loading... |
6970 clone.set_parameter_types(array); | 6650 clone.set_parameter_types(array); |
6971 for (intptr_t i = 0; i < num_params; i++) { | 6651 for (intptr_t i = 0; i < num_params; i++) { |
6972 type = clone.ParameterTypeAt(i); | 6652 type = clone.ParameterTypeAt(i); |
6973 type ^= type.CloneUninstantiated(new_owner); | 6653 type ^= type.CloneUninstantiated(new_owner); |
6974 clone.SetParameterTypeAt(i, type); | 6654 clone.SetParameterTypeAt(i, type); |
6975 } | 6655 } |
6976 } | 6656 } |
6977 return clone.raw(); | 6657 return clone.raw(); |
6978 } | 6658 } |
6979 | 6659 |
6980 | |
6981 RawFunction* Function::NewClosureFunction(const String& name, | 6660 RawFunction* Function::NewClosureFunction(const String& name, |
6982 const Function& parent, | 6661 const Function& parent, |
6983 TokenPosition token_pos) { | 6662 TokenPosition token_pos) { |
6984 ASSERT(!parent.IsNull()); | 6663 ASSERT(!parent.IsNull()); |
6985 // Use the owner defining the parent function and not the class containing it. | 6664 // Use the owner defining the parent function and not the class containing it. |
6986 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); | 6665 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); |
6987 ASSERT(!parent_owner.IsNull()); | 6666 ASSERT(!parent_owner.IsNull()); |
6988 const Function& result = Function::Handle( | 6667 const Function& result = Function::Handle( |
6989 Function::New(name, RawFunction::kClosureFunction, | 6668 Function::New(name, RawFunction::kClosureFunction, |
6990 /* is_static = */ parent.is_static(), | 6669 /* is_static = */ parent.is_static(), |
6991 /* is_const = */ false, | 6670 /* is_const = */ false, |
6992 /* is_abstract = */ false, | 6671 /* is_abstract = */ false, |
6993 /* is_external = */ false, | 6672 /* is_external = */ false, |
6994 /* is_native = */ false, parent_owner, token_pos)); | 6673 /* is_native = */ false, parent_owner, token_pos)); |
6995 result.set_parent_function(parent); | 6674 result.set_parent_function(parent); |
6996 return result.raw(); | 6675 return result.raw(); |
6997 } | 6676 } |
6998 | 6677 |
6999 | |
7000 RawFunction* Function::NewSignatureFunction(const Object& owner, | 6678 RawFunction* Function::NewSignatureFunction(const Object& owner, |
7001 const Function& parent, | 6679 const Function& parent, |
7002 TokenPosition token_pos, | 6680 TokenPosition token_pos, |
7003 Heap::Space space) { | 6681 Heap::Space space) { |
7004 const Function& result = Function::Handle(Function::New( | 6682 const Function& result = Function::Handle(Function::New( |
7005 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, | 6683 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, |
7006 /* is_static = */ false, | 6684 /* is_static = */ false, |
7007 /* is_const = */ false, | 6685 /* is_const = */ false, |
7008 /* is_abstract = */ false, | 6686 /* is_abstract = */ false, |
7009 /* is_external = */ false, | 6687 /* is_external = */ false, |
7010 /* is_native = */ false, | 6688 /* is_native = */ false, |
7011 owner, // Same as function type scope class. | 6689 owner, // Same as function type scope class. |
7012 token_pos, space)); | 6690 token_pos, space)); |
7013 result.set_parent_function(parent); | 6691 result.set_parent_function(parent); |
7014 result.set_is_reflectable(false); | 6692 result.set_is_reflectable(false); |
7015 result.set_is_visible(false); | 6693 result.set_is_visible(false); |
7016 result.set_is_debuggable(false); | 6694 result.set_is_debuggable(false); |
7017 return result.raw(); | 6695 return result.raw(); |
7018 } | 6696 } |
7019 | 6697 |
7020 | |
7021 RawFunction* Function::NewEvalFunction(const Class& owner, | 6698 RawFunction* Function::NewEvalFunction(const Class& owner, |
7022 const Script& script, | 6699 const Script& script, |
7023 bool is_static) { | 6700 bool is_static) { |
7024 Thread* thread = Thread::Current(); | 6701 Thread* thread = Thread::Current(); |
7025 Zone* zone = thread->zone(); | 6702 Zone* zone = thread->zone(); |
7026 const Function& result = Function::Handle( | 6703 const Function& result = Function::Handle( |
7027 zone, | 6704 zone, |
7028 Function::New(String::Handle(Symbols::New(thread, ":Eval")), | 6705 Function::New(String::Handle(Symbols::New(thread, ":Eval")), |
7029 RawFunction::kRegularFunction, is_static, | 6706 RawFunction::kRegularFunction, is_static, |
7030 /* is_const = */ false, | 6707 /* is_const = */ false, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7107 const Type& signature_type = | 6784 const Type& signature_type = |
7108 Type::Handle(zone, closure_function.SignatureType()); | 6785 Type::Handle(zone, closure_function.SignatureType()); |
7109 if (!signature_type.IsFinalized()) { | 6786 if (!signature_type.IsFinalized()) { |
7110 ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type); | 6787 ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type); |
7111 } | 6788 } |
7112 set_implicit_closure_function(closure_function); | 6789 set_implicit_closure_function(closure_function); |
7113 ASSERT(closure_function.IsImplicitClosureFunction()); | 6790 ASSERT(closure_function.IsImplicitClosureFunction()); |
7114 return closure_function.raw(); | 6791 return closure_function.raw(); |
7115 } | 6792 } |
7116 | 6793 |
7117 | |
7118 void Function::DropUncompiledImplicitClosureFunction() const { | 6794 void Function::DropUncompiledImplicitClosureFunction() const { |
7119 if (implicit_closure_function() != Function::null()) { | 6795 if (implicit_closure_function() != Function::null()) { |
7120 const Function& func = Function::Handle(implicit_closure_function()); | 6796 const Function& func = Function::Handle(implicit_closure_function()); |
7121 if (!func.HasCode()) { | 6797 if (!func.HasCode()) { |
7122 set_implicit_closure_function(Function::Handle()); | 6798 set_implicit_closure_function(Function::Handle()); |
7123 } | 6799 } |
7124 } | 6800 } |
7125 } | 6801 } |
7126 | 6802 |
7127 | |
7128 RawString* Function::UserVisibleFormalParameters() const { | 6803 RawString* Function::UserVisibleFormalParameters() const { |
7129 Thread* thread = Thread::Current(); | 6804 Thread* thread = Thread::Current(); |
7130 Zone* zone = thread->zone(); | 6805 Zone* zone = thread->zone(); |
7131 // Typically 3, 5,.. elements in 'pieces', e.g.: | 6806 // Typically 3, 5,.. elements in 'pieces', e.g.: |
7132 // '_LoadRequest', CommaSpace, '_LoadError'. | 6807 // '_LoadRequest', CommaSpace, '_LoadError'. |
7133 GrowableHandlePtrArray<const String> pieces(zone, 5); | 6808 GrowableHandlePtrArray<const String> pieces(zone, 5); |
7134 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); | 6809 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); |
7135 return Symbols::FromConcatAll(thread, pieces); | 6810 return Symbols::FromConcatAll(thread, pieces); |
7136 } | 6811 } |
7137 | 6812 |
7138 | |
7139 void Function::BuildSignatureParameters( | 6813 void Function::BuildSignatureParameters( |
7140 Thread* thread, | 6814 Thread* thread, |
7141 Zone* zone, | 6815 Zone* zone, |
7142 NameVisibility name_visibility, | 6816 NameVisibility name_visibility, |
7143 GrowableHandlePtrArray<const String>* pieces) const { | 6817 GrowableHandlePtrArray<const String>* pieces) const { |
7144 AbstractType& param_type = AbstractType::Handle(zone); | 6818 AbstractType& param_type = AbstractType::Handle(zone); |
7145 const intptr_t num_params = NumParameters(); | 6819 const intptr_t num_params = NumParameters(); |
7146 const intptr_t num_fixed_params = num_fixed_parameters(); | 6820 const intptr_t num_fixed_params = num_fixed_parameters(); |
7147 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 6821 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |
7148 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 6822 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7187 } | 6861 } |
7188 } | 6862 } |
7189 if (num_opt_pos_params > 0) { | 6863 if (num_opt_pos_params > 0) { |
7190 pieces->Add(Symbols::RBracket()); | 6864 pieces->Add(Symbols::RBracket()); |
7191 } else { | 6865 } else { |
7192 pieces->Add(Symbols::RBrace()); | 6866 pieces->Add(Symbols::RBrace()); |
7193 } | 6867 } |
7194 } | 6868 } |
7195 } | 6869 } |
7196 | 6870 |
7197 | |
7198 RawInstance* Function::ImplicitStaticClosure() const { | 6871 RawInstance* Function::ImplicitStaticClosure() const { |
7199 if (implicit_static_closure() == Instance::null()) { | 6872 if (implicit_static_closure() == Instance::null()) { |
7200 Zone* zone = Thread::Current()->zone(); | 6873 Zone* zone = Thread::Current()->zone(); |
7201 const Context& context = Object::empty_context(); | 6874 const Context& context = Object::empty_context(); |
7202 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); | 6875 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |
7203 if (!HasInstantiatedSignature(kFunctions)) { | 6876 if (!HasInstantiatedSignature(kFunctions)) { |
7204 function_type_arguments = Object::empty_type_arguments().raw(); | 6877 function_type_arguments = Object::empty_type_arguments().raw(); |
7205 } | 6878 } |
7206 Instance& closure = | 6879 Instance& closure = |
7207 Instance::Handle(zone, Closure::New(Object::null_type_arguments(), | 6880 Instance::Handle(zone, Closure::New(Object::null_type_arguments(), |
7208 function_type_arguments, *this, | 6881 function_type_arguments, *this, |
7209 context, Heap::kOld)); | 6882 context, Heap::kOld)); |
7210 set_implicit_static_closure(closure); | 6883 set_implicit_static_closure(closure); |
7211 } | 6884 } |
7212 return implicit_static_closure(); | 6885 return implicit_static_closure(); |
7213 } | 6886 } |
7214 | 6887 |
7215 | |
7216 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { | 6888 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { |
7217 ASSERT(IsImplicitClosureFunction()); | 6889 ASSERT(IsImplicitClosureFunction()); |
7218 Zone* zone = Thread::Current()->zone(); | 6890 Zone* zone = Thread::Current()->zone(); |
7219 const Context& context = Context::Handle(zone, Context::New(1)); | 6891 const Context& context = Context::Handle(zone, Context::New(1)); |
7220 context.SetAt(0, receiver); | 6892 context.SetAt(0, receiver); |
7221 TypeArguments& instantiator_type_arguments = TypeArguments::Handle(zone); | 6893 TypeArguments& instantiator_type_arguments = TypeArguments::Handle(zone); |
7222 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); | 6894 TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |
7223 if (!HasInstantiatedSignature(kCurrentClass)) { | 6895 if (!HasInstantiatedSignature(kCurrentClass)) { |
7224 instantiator_type_arguments = receiver.GetTypeArguments(); | 6896 instantiator_type_arguments = receiver.GetTypeArguments(); |
7225 } | 6897 } |
7226 if (!HasInstantiatedSignature(kFunctions)) { | 6898 if (!HasInstantiatedSignature(kFunctions)) { |
7227 function_type_arguments = Object::empty_type_arguments().raw(); | 6899 function_type_arguments = Object::empty_type_arguments().raw(); |
7228 } | 6900 } |
7229 return Closure::New(instantiator_type_arguments, function_type_arguments, | 6901 return Closure::New(instantiator_type_arguments, function_type_arguments, |
7230 *this, context); | 6902 *this, context); |
7231 } | 6903 } |
7232 | 6904 |
7233 | |
7234 RawSmi* Function::GetClosureHashCode() const { | 6905 RawSmi* Function::GetClosureHashCode() const { |
7235 ASSERT(IsClosureFunction()); | 6906 ASSERT(IsClosureFunction()); |
7236 const Object& obj = Object::Handle(raw_ptr()->data_); | 6907 const Object& obj = Object::Handle(raw_ptr()->data_); |
7237 ASSERT(!obj.IsNull()); | 6908 ASSERT(!obj.IsNull()); |
7238 if (ClosureData::Cast(obj).hash() != Object::null()) { | 6909 if (ClosureData::Cast(obj).hash() != Object::null()) { |
7239 return Smi::RawCast(ClosureData::Cast(obj).hash()); | 6910 return Smi::RawCast(ClosureData::Cast(obj).hash()); |
7240 } | 6911 } |
7241 // Hash not yet computed. Compute and cache it. | 6912 // Hash not yet computed. Compute and cache it. |
7242 const Class& cls = Class::Handle(Owner()); | 6913 const Class& cls = Class::Handle(Owner()); |
7243 intptr_t result = String::Handle(name()).Hash(); | 6914 intptr_t result = String::Handle(name()).Hash(); |
7244 result += String::Handle(Signature()).Hash(); | 6915 result += String::Handle(Signature()).Hash(); |
7245 result += String::Handle(cls.Name()).Hash(); | 6916 result += String::Handle(cls.Name()).Hash(); |
7246 // Finalize hash value like for strings so that it fits into a smi. | 6917 // Finalize hash value like for strings so that it fits into a smi. |
7247 result += result << 3; | 6918 result += result << 3; |
7248 result ^= result >> 11; | 6919 result ^= result >> 11; |
7249 result += result << 15; | 6920 result += result << 15; |
7250 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); | 6921 result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); |
7251 ClosureData::Cast(obj).set_hash(result); | 6922 ClosureData::Cast(obj).set_hash(result); |
7252 return Smi::New(result); | 6923 return Smi::New(result); |
7253 } | 6924 } |
7254 | 6925 |
7255 | |
7256 RawString* Function::BuildSignature(NameVisibility name_visibility) const { | 6926 RawString* Function::BuildSignature(NameVisibility name_visibility) const { |
7257 Thread* thread = Thread::Current(); | 6927 Thread* thread = Thread::Current(); |
7258 Zone* zone = thread->zone(); | 6928 Zone* zone = thread->zone(); |
7259 GrowableHandlePtrArray<const String> pieces(zone, 4); | 6929 GrowableHandlePtrArray<const String> pieces(zone, 4); |
7260 String& name = String::Handle(zone); | 6930 String& name = String::Handle(zone); |
7261 if (FLAG_reify_generic_functions) { | 6931 if (FLAG_reify_generic_functions) { |
7262 const TypeArguments& type_params = | 6932 const TypeArguments& type_params = |
7263 TypeArguments::Handle(zone, type_parameters()); | 6933 TypeArguments::Handle(zone, type_parameters()); |
7264 if (!type_params.IsNull()) { | 6934 if (!type_params.IsNull()) { |
7265 const intptr_t num_type_params = type_params.Length(); | 6935 const intptr_t num_type_params = type_params.Length(); |
(...skipping 20 matching lines...) Expand all Loading... |
7286 } | 6956 } |
7287 pieces.Add(Symbols::LParen()); | 6957 pieces.Add(Symbols::LParen()); |
7288 BuildSignatureParameters(thread, zone, name_visibility, &pieces); | 6958 BuildSignatureParameters(thread, zone, name_visibility, &pieces); |
7289 pieces.Add(Symbols::RParenArrow()); | 6959 pieces.Add(Symbols::RParenArrow()); |
7290 const AbstractType& res_type = AbstractType::Handle(zone, result_type()); | 6960 const AbstractType& res_type = AbstractType::Handle(zone, result_type()); |
7291 name = res_type.BuildName(name_visibility); | 6961 name = res_type.BuildName(name_visibility); |
7292 pieces.Add(name); | 6962 pieces.Add(name); |
7293 return Symbols::FromConcatAll(thread, pieces); | 6963 return Symbols::FromConcatAll(thread, pieces); |
7294 } | 6964 } |
7295 | 6965 |
7296 | |
7297 bool Function::HasInstantiatedSignature(Genericity genericity, | 6966 bool Function::HasInstantiatedSignature(Genericity genericity, |
7298 intptr_t num_free_fun_type_params, | 6967 intptr_t num_free_fun_type_params, |
7299 TrailPtr trail) const { | 6968 TrailPtr trail) const { |
7300 if (genericity != kCurrentClass) { | 6969 if (genericity != kCurrentClass) { |
7301 // We only consider the function type parameters declared by the parents of | 6970 // We only consider the function type parameters declared by the parents of |
7302 // this signature function. | 6971 // this signature function. |
7303 const int num_parent_type_params = NumParentTypeParameters(); | 6972 const int num_parent_type_params = NumParentTypeParameters(); |
7304 if (num_parent_type_params < num_free_fun_type_params) { | 6973 if (num_parent_type_params < num_free_fun_type_params) { |
7305 num_free_fun_type_params = num_parent_type_params; | 6974 num_free_fun_type_params = num_parent_type_params; |
7306 } | 6975 } |
7307 } | 6976 } |
7308 AbstractType& type = AbstractType::Handle(result_type()); | 6977 AbstractType& type = AbstractType::Handle(result_type()); |
7309 if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 6978 if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |
7310 return false; | 6979 return false; |
7311 } | 6980 } |
7312 const intptr_t num_parameters = NumParameters(); | 6981 const intptr_t num_parameters = NumParameters(); |
7313 for (intptr_t i = 0; i < num_parameters; i++) { | 6982 for (intptr_t i = 0; i < num_parameters; i++) { |
7314 type = ParameterTypeAt(i); | 6983 type = ParameterTypeAt(i); |
7315 if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 6984 if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |
7316 return false; | 6985 return false; |
7317 } | 6986 } |
7318 } | 6987 } |
7319 return true; | 6988 return true; |
7320 } | 6989 } |
7321 | 6990 |
7322 | |
7323 RawClass* Function::Owner() const { | 6991 RawClass* Function::Owner() const { |
7324 if (raw_ptr()->owner_ == Object::null()) { | 6992 if (raw_ptr()->owner_ == Object::null()) { |
7325 ASSERT(IsSignatureFunction()); | 6993 ASSERT(IsSignatureFunction()); |
7326 return Class::null(); | 6994 return Class::null(); |
7327 } | 6995 } |
7328 if (raw_ptr()->owner_->IsClass()) { | 6996 if (raw_ptr()->owner_->IsClass()) { |
7329 return Class::RawCast(raw_ptr()->owner_); | 6997 return Class::RawCast(raw_ptr()->owner_); |
7330 } | 6998 } |
7331 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6999 const Object& obj = Object::Handle(raw_ptr()->owner_); |
7332 ASSERT(obj.IsPatchClass()); | 7000 ASSERT(obj.IsPatchClass()); |
7333 return PatchClass::Cast(obj).patched_class(); | 7001 return PatchClass::Cast(obj).patched_class(); |
7334 } | 7002 } |
7335 | 7003 |
7336 | |
7337 RawClass* Function::origin() const { | 7004 RawClass* Function::origin() const { |
7338 if (raw_ptr()->owner_ == Object::null()) { | 7005 if (raw_ptr()->owner_ == Object::null()) { |
7339 ASSERT(IsSignatureFunction()); | 7006 ASSERT(IsSignatureFunction()); |
7340 return Class::null(); | 7007 return Class::null(); |
7341 } | 7008 } |
7342 if (raw_ptr()->owner_->IsClass()) { | 7009 if (raw_ptr()->owner_->IsClass()) { |
7343 return Class::RawCast(raw_ptr()->owner_); | 7010 return Class::RawCast(raw_ptr()->owner_); |
7344 } | 7011 } |
7345 const Object& obj = Object::Handle(raw_ptr()->owner_); | 7012 const Object& obj = Object::Handle(raw_ptr()->owner_); |
7346 ASSERT(obj.IsPatchClass()); | 7013 ASSERT(obj.IsPatchClass()); |
7347 return PatchClass::Cast(obj).origin_class(); | 7014 return PatchClass::Cast(obj).origin_class(); |
7348 } | 7015 } |
7349 | 7016 |
7350 | |
7351 RawScript* Function::script() const { | 7017 RawScript* Function::script() const { |
7352 // NOTE(turnidge): If you update this function, you probably want to | 7018 // NOTE(turnidge): If you update this function, you probably want to |
7353 // update Class::PatchFieldsAndFunctions() at the same time. | 7019 // update Class::PatchFieldsAndFunctions() at the same time. |
7354 if (token_pos() == TokenPosition::kMinSource) { | 7020 if (token_pos() == TokenPosition::kMinSource) { |
7355 // Testing for position 0 is an optimization that relies on temporary | 7021 // Testing for position 0 is an optimization that relies on temporary |
7356 // eval functions having token position 0. | 7022 // eval functions having token position 0. |
7357 const Script& script = Script::Handle(eval_script()); | 7023 const Script& script = Script::Handle(eval_script()); |
7358 if (!script.IsNull()) { | 7024 if (!script.IsNull()) { |
7359 return script.raw(); | 7025 return script.raw(); |
7360 } | 7026 } |
7361 } | 7027 } |
7362 if (IsClosureFunction()) { | 7028 if (IsClosureFunction()) { |
7363 return Function::Handle(parent_function()).script(); | 7029 return Function::Handle(parent_function()).script(); |
7364 } | 7030 } |
7365 const Object& obj = Object::Handle(raw_ptr()->owner_); | 7031 const Object& obj = Object::Handle(raw_ptr()->owner_); |
7366 if (obj.IsNull()) { | 7032 if (obj.IsNull()) { |
7367 ASSERT(IsSignatureFunction()); | 7033 ASSERT(IsSignatureFunction()); |
7368 return Script::null(); | 7034 return Script::null(); |
7369 } | 7035 } |
7370 if (obj.IsClass()) { | 7036 if (obj.IsClass()) { |
7371 return Class::Cast(obj).script(); | 7037 return Class::Cast(obj).script(); |
7372 } | 7038 } |
7373 ASSERT(obj.IsPatchClass()); | 7039 ASSERT(obj.IsPatchClass()); |
7374 return PatchClass::Cast(obj).script(); | 7040 return PatchClass::Cast(obj).script(); |
7375 } | 7041 } |
7376 | 7042 |
7377 | |
7378 bool Function::HasOptimizedCode() const { | 7043 bool Function::HasOptimizedCode() const { |
7379 return HasCode() && Code::Handle(CurrentCode()).is_optimized(); | 7044 return HasCode() && Code::Handle(CurrentCode()).is_optimized(); |
7380 } | 7045 } |
7381 | 7046 |
7382 | |
7383 RawString* Function::UserVisibleName() const { | 7047 RawString* Function::UserVisibleName() const { |
7384 if (FLAG_show_internal_names) { | 7048 if (FLAG_show_internal_names) { |
7385 return name(); | 7049 return name(); |
7386 } | 7050 } |
7387 return String::ScrubName(String::Handle(name())); | 7051 return String::ScrubName(String::Handle(name())); |
7388 } | 7052 } |
7389 | 7053 |
7390 | |
7391 RawString* Function::QualifiedName(NameVisibility name_visibility) const { | 7054 RawString* Function::QualifiedName(NameVisibility name_visibility) const { |
7392 ASSERT(name_visibility != kInternalName); // We never request it. | 7055 ASSERT(name_visibility != kInternalName); // We never request it. |
7393 // If |this| is the generated asynchronous body closure, use the | 7056 // If |this| is the generated asynchronous body closure, use the |
7394 // name of the parent function. | 7057 // name of the parent function. |
7395 Function& fun = Function::Handle(raw()); | 7058 Function& fun = Function::Handle(raw()); |
7396 if (fun.IsClosureFunction()) { | 7059 if (fun.IsClosureFunction()) { |
7397 // Sniff the parent function. | 7060 // Sniff the parent function. |
7398 fun = fun.parent_function(); | 7061 fun = fun.parent_function(); |
7399 ASSERT(!fun.IsNull()); | 7062 ASSERT(!fun.IsNull()); |
7400 if (!fun.IsAsyncGenerator() && !fun.IsAsyncFunction() && | 7063 if (!fun.IsAsyncGenerator() && !fun.IsAsyncFunction() && |
(...skipping 28 matching lines...) Expand all Loading... |
7429 result = String::Concat(Symbols::Dot(), result, Heap::kOld); | 7092 result = String::Concat(Symbols::Dot(), result, Heap::kOld); |
7430 const String& cls_name = String::Handle(name_visibility == kScrubbedName | 7093 const String& cls_name = String::Handle(name_visibility == kScrubbedName |
7431 ? cls.ScrubbedName() | 7094 ? cls.ScrubbedName() |
7432 : cls.UserVisibleName()); | 7095 : cls.UserVisibleName()); |
7433 result = String::Concat(cls_name, result, Heap::kOld); | 7096 result = String::Concat(cls_name, result, Heap::kOld); |
7434 } | 7097 } |
7435 } | 7098 } |
7436 return result.raw(); | 7099 return result.raw(); |
7437 } | 7100 } |
7438 | 7101 |
7439 | |
7440 RawString* Function::GetSource() const { | 7102 RawString* Function::GetSource() const { |
7441 if (IsImplicitConstructor() || IsSignatureFunction()) { | 7103 if (IsImplicitConstructor() || IsSignatureFunction()) { |
7442 // We may need to handle more cases when the restrictions on mixins are | 7104 // We may need to handle more cases when the restrictions on mixins are |
7443 // relaxed. In particular we might start associating some source with the | 7105 // relaxed. In particular we might start associating some source with the |
7444 // forwarding constructors when it becomes possible to specify a particular | 7106 // forwarding constructors when it becomes possible to specify a particular |
7445 // constructor from the mixin to use. | 7107 // constructor from the mixin to use. |
7446 return String::null(); | 7108 return String::null(); |
7447 } | 7109 } |
7448 Zone* zone = Thread::Current()->zone(); | 7110 Zone* zone = Thread::Current()->zone(); |
7449 const Script& func_script = Script::Handle(zone, script()); | 7111 const Script& func_script = Script::Handle(zone, script()); |
(...skipping 24 matching lines...) Expand all Loading... |
7474 String::Handle(zone, name()).Equals("<anonymous closure>"))) { // Cas 3. | 7136 String::Handle(zone, name()).Equals("<anonymous closure>"))) { // Cas 3. |
7475 last_tok_len = 0; | 7137 last_tok_len = 0; |
7476 } | 7138 } |
7477 const String& result = | 7139 const String& result = |
7478 String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line, | 7140 String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line, |
7479 to_col + last_tok_len)); | 7141 to_col + last_tok_len)); |
7480 ASSERT(!result.IsNull()); | 7142 ASSERT(!result.IsNull()); |
7481 return result.raw(); | 7143 return result.raw(); |
7482 } | 7144 } |
7483 | 7145 |
7484 | |
7485 // Construct fingerprint from token stream. The token stream contains also | 7146 // Construct fingerprint from token stream. The token stream contains also |
7486 // arguments. | 7147 // arguments. |
7487 int32_t Function::SourceFingerprint() const { | 7148 int32_t Function::SourceFingerprint() const { |
7488 return Script::Handle(script()).SourceFingerprint(token_pos(), | 7149 return Script::Handle(script()).SourceFingerprint(token_pos(), |
7489 end_token_pos()); | 7150 end_token_pos()); |
7490 } | 7151 } |
7491 | 7152 |
7492 | |
7493 void Function::SaveICDataMap( | 7153 void Function::SaveICDataMap( |
7494 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, | 7154 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, |
7495 const Array& edge_counters_array) const { | 7155 const Array& edge_counters_array) const { |
7496 // Compute number of ICData objects to save. | 7156 // Compute number of ICData objects to save. |
7497 // Store edge counter array in the first slot. | 7157 // Store edge counter array in the first slot. |
7498 intptr_t count = 1; | 7158 intptr_t count = 1; |
7499 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 7159 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
7500 if (deopt_id_to_ic_data[i] != NULL) { | 7160 if (deopt_id_to_ic_data[i] != NULL) { |
7501 count++; | 7161 count++; |
7502 } | 7162 } |
7503 } | 7163 } |
7504 const Array& array = Array::Handle(Array::New(count, Heap::kOld)); | 7164 const Array& array = Array::Handle(Array::New(count, Heap::kOld)); |
7505 INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); | 7165 INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); |
7506 count = 1; | 7166 count = 1; |
7507 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 7167 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |
7508 if (deopt_id_to_ic_data[i] != NULL) { | 7168 if (deopt_id_to_ic_data[i] != NULL) { |
7509 array.SetAt(count++, *deopt_id_to_ic_data[i]); | 7169 array.SetAt(count++, *deopt_id_to_ic_data[i]); |
7510 } | 7170 } |
7511 } | 7171 } |
7512 array.SetAt(0, edge_counters_array); | 7172 array.SetAt(0, edge_counters_array); |
7513 set_ic_data_array(array); | 7173 set_ic_data_array(array); |
7514 } | 7174 } |
7515 | 7175 |
7516 | |
7517 void Function::RestoreICDataMap( | 7176 void Function::RestoreICDataMap( |
7518 ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data, | 7177 ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data, |
7519 bool clone_ic_data) const { | 7178 bool clone_ic_data) const { |
7520 if (FLAG_force_clone_compiler_objects) { | 7179 if (FLAG_force_clone_compiler_objects) { |
7521 clone_ic_data = true; | 7180 clone_ic_data = true; |
7522 } | 7181 } |
7523 ASSERT(deopt_id_to_ic_data->is_empty()); | 7182 ASSERT(deopt_id_to_ic_data->is_empty()); |
7524 Zone* zone = Thread::Current()->zone(); | 7183 Zone* zone = Thread::Current()->zone(); |
7525 const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); | 7184 const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); |
7526 if (saved_ic_data.IsNull()) { | 7185 if (saved_ic_data.IsNull()) { |
(...skipping 17 matching lines...) Expand all Loading... |
7544 if (clone_ic_data) { | 7203 if (clone_ic_data) { |
7545 const ICData& original_ic_data = ICData::Handle(zone, ic_data.raw()); | 7204 const ICData& original_ic_data = ICData::Handle(zone, ic_data.raw()); |
7546 ic_data = ICData::Clone(ic_data); | 7205 ic_data = ICData::Clone(ic_data); |
7547 ic_data.SetOriginal(original_ic_data); | 7206 ic_data.SetOriginal(original_ic_data); |
7548 } | 7207 } |
7549 (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data; | 7208 (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data; |
7550 } | 7209 } |
7551 } | 7210 } |
7552 } | 7211 } |
7553 | 7212 |
7554 | |
7555 void Function::set_ic_data_array(const Array& value) const { | 7213 void Function::set_ic_data_array(const Array& value) const { |
7556 StorePointer(&raw_ptr()->ic_data_array_, value.raw()); | 7214 StorePointer(&raw_ptr()->ic_data_array_, value.raw()); |
7557 } | 7215 } |
7558 | 7216 |
7559 | |
7560 RawArray* Function::ic_data_array() const { | 7217 RawArray* Function::ic_data_array() const { |
7561 return raw_ptr()->ic_data_array_; | 7218 return raw_ptr()->ic_data_array_; |
7562 } | 7219 } |
7563 | 7220 |
7564 | |
7565 void Function::ClearICDataArray() const { | 7221 void Function::ClearICDataArray() const { |
7566 set_ic_data_array(Array::null_array()); | 7222 set_ic_data_array(Array::null_array()); |
7567 } | 7223 } |
7568 | 7224 |
7569 | |
7570 void Function::SetDeoptReasonForAll(intptr_t deopt_id, | 7225 void Function::SetDeoptReasonForAll(intptr_t deopt_id, |
7571 ICData::DeoptReasonId reason) { | 7226 ICData::DeoptReasonId reason) { |
7572 const Array& array = Array::Handle(ic_data_array()); | 7227 const Array& array = Array::Handle(ic_data_array()); |
7573 ICData& ic_data = ICData::Handle(); | 7228 ICData& ic_data = ICData::Handle(); |
7574 for (intptr_t i = 1; i < array.Length(); i++) { | 7229 for (intptr_t i = 1; i < array.Length(); i++) { |
7575 ic_data ^= array.At(i); | 7230 ic_data ^= array.At(i); |
7576 if (ic_data.deopt_id() == deopt_id) { | 7231 if (ic_data.deopt_id() == deopt_id) { |
7577 ic_data.AddDeoptReason(reason); | 7232 ic_data.AddDeoptReason(reason); |
7578 } | 7233 } |
7579 } | 7234 } |
7580 } | 7235 } |
7581 | 7236 |
7582 | |
7583 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { | 7237 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { |
7584 if ((kernel_offset() <= 0) && (SourceFingerprint() != fp)) { | 7238 if ((kernel_offset() <= 0) && (SourceFingerprint() != fp)) { |
7585 const bool recalculatingFingerprints = false; | 7239 const bool recalculatingFingerprints = false; |
7586 if (recalculatingFingerprints) { | 7240 if (recalculatingFingerprints) { |
7587 // This output can be copied into a file, then used with sed | 7241 // This output can be copied into a file, then used with sed |
7588 // to replace the old values. | 7242 // to replace the old values. |
7589 // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h | 7243 // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h |
7590 THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); | 7244 THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); |
7591 } else { | 7245 } else { |
7592 THR_Print( | 7246 THR_Print( |
7593 "FP mismatch while recognizing method %s:" | 7247 "FP mismatch while recognizing method %s:" |
7594 " expecting 0x%08x found 0x%08x\n", | 7248 " expecting 0x%08x found 0x%08x\n", |
7595 ToFullyQualifiedCString(), fp, SourceFingerprint()); | 7249 ToFullyQualifiedCString(), fp, SourceFingerprint()); |
7596 return false; | 7250 return false; |
7597 } | 7251 } |
7598 } | 7252 } |
7599 return true; | 7253 return true; |
7600 } | 7254 } |
7601 | 7255 |
7602 | |
7603 RawCode* Function::EnsureHasCode() const { | 7256 RawCode* Function::EnsureHasCode() const { |
7604 if (HasCode()) return CurrentCode(); | 7257 if (HasCode()) return CurrentCode(); |
7605 Thread* thread = Thread::Current(); | 7258 Thread* thread = Thread::Current(); |
7606 Zone* zone = thread->zone(); | 7259 Zone* zone = thread->zone(); |
7607 const Object& result = | 7260 const Object& result = |
7608 Object::Handle(zone, Compiler::CompileFunction(thread, *this)); | 7261 Object::Handle(zone, Compiler::CompileFunction(thread, *this)); |
7609 if (result.IsError()) { | 7262 if (result.IsError()) { |
7610 Exceptions::PropagateError(Error::Cast(result)); | 7263 Exceptions::PropagateError(Error::Cast(result)); |
7611 UNREACHABLE(); | 7264 UNREACHABLE(); |
7612 } | 7265 } |
7613 // Compiling in unoptimized mode should never fail if there are no errors. | 7266 // Compiling in unoptimized mode should never fail if there are no errors. |
7614 ASSERT(HasCode()); | 7267 ASSERT(HasCode()); |
7615 ASSERT(unoptimized_code() == result.raw()); | 7268 ASSERT(unoptimized_code() == result.raw()); |
7616 return CurrentCode(); | 7269 return CurrentCode(); |
7617 } | 7270 } |
7618 | 7271 |
7619 | |
7620 const char* Function::ToCString() const { | 7272 const char* Function::ToCString() const { |
7621 if (IsNull()) { | 7273 if (IsNull()) { |
7622 return "Function: null"; | 7274 return "Function: null"; |
7623 } | 7275 } |
7624 const char* static_str = is_static() ? " static" : ""; | 7276 const char* static_str = is_static() ? " static" : ""; |
7625 const char* abstract_str = is_abstract() ? " abstract" : ""; | 7277 const char* abstract_str = is_abstract() ? " abstract" : ""; |
7626 const char* kind_str = NULL; | 7278 const char* kind_str = NULL; |
7627 const char* const_str = is_const() ? " const" : ""; | 7279 const char* const_str = is_const() ? " const" : ""; |
7628 switch (kind()) { | 7280 switch (kind()) { |
7629 case RawFunction::kRegularFunction: | 7281 case RawFunction::kRegularFunction: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7661 break; | 7313 break; |
7662 default: | 7314 default: |
7663 UNREACHABLE(); | 7315 UNREACHABLE(); |
7664 } | 7316 } |
7665 const char* function_name = String::Handle(name()).ToCString(); | 7317 const char* function_name = String::Handle(name()).ToCString(); |
7666 return OS::SCreate(Thread::Current()->zone(), "Function '%s':%s%s%s%s.", | 7318 return OS::SCreate(Thread::Current()->zone(), "Function '%s':%s%s%s%s.", |
7667 function_name, static_str, abstract_str, kind_str, | 7319 function_name, static_str, abstract_str, kind_str, |
7668 const_str); | 7320 const_str); |
7669 } | 7321 } |
7670 | 7322 |
7671 | |
7672 void ClosureData::set_context_scope(const ContextScope& value) const { | 7323 void ClosureData::set_context_scope(const ContextScope& value) const { |
7673 StorePointer(&raw_ptr()->context_scope_, value.raw()); | 7324 StorePointer(&raw_ptr()->context_scope_, value.raw()); |
7674 } | 7325 } |
7675 | 7326 |
7676 | |
7677 void ClosureData::set_implicit_static_closure(const Instance& closure) const { | 7327 void ClosureData::set_implicit_static_closure(const Instance& closure) const { |
7678 ASSERT(!closure.IsNull()); | 7328 ASSERT(!closure.IsNull()); |
7679 ASSERT(raw_ptr()->closure_ == Instance::null()); | 7329 ASSERT(raw_ptr()->closure_ == Instance::null()); |
7680 StorePointer(&raw_ptr()->closure_, closure.raw()); | 7330 StorePointer(&raw_ptr()->closure_, closure.raw()); |
7681 } | 7331 } |
7682 | 7332 |
7683 | |
7684 void ClosureData::set_hash(intptr_t value) const { | 7333 void ClosureData::set_hash(intptr_t value) const { |
7685 StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value))); | 7334 StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value))); |
7686 } | 7335 } |
7687 | 7336 |
7688 | |
7689 void ClosureData::set_parent_function(const Function& value) const { | 7337 void ClosureData::set_parent_function(const Function& value) const { |
7690 StorePointer(&raw_ptr()->parent_function_, value.raw()); | 7338 StorePointer(&raw_ptr()->parent_function_, value.raw()); |
7691 } | 7339 } |
7692 | 7340 |
7693 | |
7694 void ClosureData::set_signature_type(const Type& value) const { | 7341 void ClosureData::set_signature_type(const Type& value) const { |
7695 StorePointer(&raw_ptr()->signature_type_, value.raw()); | 7342 StorePointer(&raw_ptr()->signature_type_, value.raw()); |
7696 } | 7343 } |
7697 | 7344 |
7698 | |
7699 RawClosureData* ClosureData::New() { | 7345 RawClosureData* ClosureData::New() { |
7700 ASSERT(Object::closure_data_class() != Class::null()); | 7346 ASSERT(Object::closure_data_class() != Class::null()); |
7701 RawObject* raw = Object::Allocate(ClosureData::kClassId, | 7347 RawObject* raw = Object::Allocate(ClosureData::kClassId, |
7702 ClosureData::InstanceSize(), Heap::kOld); | 7348 ClosureData::InstanceSize(), Heap::kOld); |
7703 return reinterpret_cast<RawClosureData*>(raw); | 7349 return reinterpret_cast<RawClosureData*>(raw); |
7704 } | 7350 } |
7705 | 7351 |
7706 | |
7707 const char* ClosureData::ToCString() const { | 7352 const char* ClosureData::ToCString() const { |
7708 if (IsNull()) { | 7353 if (IsNull()) { |
7709 return "ClosureData: null"; | 7354 return "ClosureData: null"; |
7710 } | 7355 } |
7711 const Function& parent = Function::Handle(parent_function()); | 7356 const Function& parent = Function::Handle(parent_function()); |
7712 const Type& type = Type::Handle(signature_type()); | 7357 const Type& type = Type::Handle(signature_type()); |
7713 return OS::SCreate(Thread::Current()->zone(), | 7358 return OS::SCreate(Thread::Current()->zone(), |
7714 "ClosureData: context_scope: 0x%" Px | 7359 "ClosureData: context_scope: 0x%" Px |
7715 " parent_function: %s signature_type: %s" | 7360 " parent_function: %s signature_type: %s" |
7716 " implicit_static_closure: 0x%" Px, | 7361 " implicit_static_closure: 0x%" Px, |
7717 reinterpret_cast<uword>(context_scope()), | 7362 reinterpret_cast<uword>(context_scope()), |
7718 parent.IsNull() ? "null" : parent.ToCString(), | 7363 parent.IsNull() ? "null" : parent.ToCString(), |
7719 type.IsNull() ? "null" : type.ToCString(), | 7364 type.IsNull() ? "null" : type.ToCString(), |
7720 reinterpret_cast<uword>(implicit_static_closure())); | 7365 reinterpret_cast<uword>(implicit_static_closure())); |
7721 } | 7366 } |
7722 | 7367 |
7723 | |
7724 void SignatureData::set_parent_function(const Function& value) const { | 7368 void SignatureData::set_parent_function(const Function& value) const { |
7725 StorePointer(&raw_ptr()->parent_function_, value.raw()); | 7369 StorePointer(&raw_ptr()->parent_function_, value.raw()); |
7726 } | 7370 } |
7727 | 7371 |
7728 | |
7729 void SignatureData::set_signature_type(const Type& value) const { | 7372 void SignatureData::set_signature_type(const Type& value) const { |
7730 StorePointer(&raw_ptr()->signature_type_, value.raw()); | 7373 StorePointer(&raw_ptr()->signature_type_, value.raw()); |
7731 } | 7374 } |
7732 | 7375 |
7733 | |
7734 RawSignatureData* SignatureData::New(Heap::Space space) { | 7376 RawSignatureData* SignatureData::New(Heap::Space space) { |
7735 ASSERT(Object::signature_data_class() != Class::null()); | 7377 ASSERT(Object::signature_data_class() != Class::null()); |
7736 RawObject* raw = Object::Allocate(SignatureData::kClassId, | 7378 RawObject* raw = Object::Allocate(SignatureData::kClassId, |
7737 SignatureData::InstanceSize(), space); | 7379 SignatureData::InstanceSize(), space); |
7738 return reinterpret_cast<RawSignatureData*>(raw); | 7380 return reinterpret_cast<RawSignatureData*>(raw); |
7739 } | 7381 } |
7740 | 7382 |
7741 | |
7742 const char* SignatureData::ToCString() const { | 7383 const char* SignatureData::ToCString() const { |
7743 if (IsNull()) { | 7384 if (IsNull()) { |
7744 return "SignatureData: null"; | 7385 return "SignatureData: null"; |
7745 } | 7386 } |
7746 const Function& parent = Function::Handle(parent_function()); | 7387 const Function& parent = Function::Handle(parent_function()); |
7747 const Type& type = Type::Handle(signature_type()); | 7388 const Type& type = Type::Handle(signature_type()); |
7748 return OS::SCreate(Thread::Current()->zone(), | 7389 return OS::SCreate(Thread::Current()->zone(), |
7749 "SignatureData parent_function: %s signature_type: %s", | 7390 "SignatureData parent_function: %s signature_type: %s", |
7750 parent.IsNull() ? "null" : parent.ToCString(), | 7391 parent.IsNull() ? "null" : parent.ToCString(), |
7751 type.IsNull() ? "null" : type.ToCString()); | 7392 type.IsNull() ? "null" : type.ToCString()); |
7752 } | 7393 } |
7753 | 7394 |
7754 | |
7755 void RedirectionData::set_type(const Type& value) const { | 7395 void RedirectionData::set_type(const Type& value) const { |
7756 ASSERT(!value.IsNull()); | 7396 ASSERT(!value.IsNull()); |
7757 StorePointer(&raw_ptr()->type_, value.raw()); | 7397 StorePointer(&raw_ptr()->type_, value.raw()); |
7758 } | 7398 } |
7759 | 7399 |
7760 | |
7761 void RedirectionData::set_identifier(const String& value) const { | 7400 void RedirectionData::set_identifier(const String& value) const { |
7762 StorePointer(&raw_ptr()->identifier_, value.raw()); | 7401 StorePointer(&raw_ptr()->identifier_, value.raw()); |
7763 } | 7402 } |
7764 | 7403 |
7765 | |
7766 void RedirectionData::set_target(const Function& value) const { | 7404 void RedirectionData::set_target(const Function& value) const { |
7767 StorePointer(&raw_ptr()->target_, value.raw()); | 7405 StorePointer(&raw_ptr()->target_, value.raw()); |
7768 } | 7406 } |
7769 | 7407 |
7770 | |
7771 RawRedirectionData* RedirectionData::New() { | 7408 RawRedirectionData* RedirectionData::New() { |
7772 ASSERT(Object::redirection_data_class() != Class::null()); | 7409 ASSERT(Object::redirection_data_class() != Class::null()); |
7773 RawObject* raw = Object::Allocate( | 7410 RawObject* raw = Object::Allocate( |
7774 RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld); | 7411 RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld); |
7775 return reinterpret_cast<RawRedirectionData*>(raw); | 7412 return reinterpret_cast<RawRedirectionData*>(raw); |
7776 } | 7413 } |
7777 | 7414 |
7778 | |
7779 const char* RedirectionData::ToCString() const { | 7415 const char* RedirectionData::ToCString() const { |
7780 if (IsNull()) { | 7416 if (IsNull()) { |
7781 return "RedirectionData: null"; | 7417 return "RedirectionData: null"; |
7782 } | 7418 } |
7783 const Type& redir_type = Type::Handle(type()); | 7419 const Type& redir_type = Type::Handle(type()); |
7784 const String& ident = String::Handle(identifier()); | 7420 const String& ident = String::Handle(identifier()); |
7785 const Function& target_fun = Function::Handle(target()); | 7421 const Function& target_fun = Function::Handle(target()); |
7786 return OS::SCreate(Thread::Current()->zone(), | 7422 return OS::SCreate(Thread::Current()->zone(), |
7787 "RedirectionData: type: %s identifier: %s target: %s", | 7423 "RedirectionData: type: %s identifier: %s target: %s", |
7788 redir_type.IsNull() ? "null" : redir_type.ToCString(), | 7424 redir_type.IsNull() ? "null" : redir_type.ToCString(), |
7789 ident.IsNull() ? "null" : ident.ToCString(), | 7425 ident.IsNull() ? "null" : ident.ToCString(), |
7790 target_fun.IsNull() ? "null" : target_fun.ToCString()); | 7426 target_fun.IsNull() ? "null" : target_fun.ToCString()); |
7791 } | 7427 } |
7792 | 7428 |
7793 | |
7794 RawField* Field::CloneFromOriginal() const { | 7429 RawField* Field::CloneFromOriginal() const { |
7795 return this->Clone(*this); | 7430 return this->Clone(*this); |
7796 } | 7431 } |
7797 | 7432 |
7798 | |
7799 RawField* Field::Original() const { | 7433 RawField* Field::Original() const { |
7800 if (IsNull()) { | 7434 if (IsNull()) { |
7801 return Field::null(); | 7435 return Field::null(); |
7802 } | 7436 } |
7803 Object& obj = Object::Handle(raw_ptr()->owner_); | 7437 Object& obj = Object::Handle(raw_ptr()->owner_); |
7804 if (obj.IsField()) { | 7438 if (obj.IsField()) { |
7805 return Field::RawCast(obj.raw()); | 7439 return Field::RawCast(obj.raw()); |
7806 } else { | 7440 } else { |
7807 return this->raw(); | 7441 return this->raw(); |
7808 } | 7442 } |
7809 } | 7443 } |
7810 | 7444 |
7811 | |
7812 void Field::SetOriginal(const Field& value) const { | 7445 void Field::SetOriginal(const Field& value) const { |
7813 ASSERT(value.IsOriginal()); | 7446 ASSERT(value.IsOriginal()); |
7814 ASSERT(!value.IsNull()); | 7447 ASSERT(!value.IsNull()); |
7815 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 7448 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |
7816 } | 7449 } |
7817 | 7450 |
7818 | |
7819 RawString* Field::GetterName(const String& field_name) { | 7451 RawString* Field::GetterName(const String& field_name) { |
7820 return String::Concat(Symbols::GetterPrefix(), field_name); | 7452 return String::Concat(Symbols::GetterPrefix(), field_name); |
7821 } | 7453 } |
7822 | 7454 |
7823 | |
7824 RawString* Field::GetterSymbol(const String& field_name) { | 7455 RawString* Field::GetterSymbol(const String& field_name) { |
7825 return Symbols::FromGet(Thread::Current(), field_name); | 7456 return Symbols::FromGet(Thread::Current(), field_name); |
7826 } | 7457 } |
7827 | 7458 |
7828 | |
7829 RawString* Field::LookupGetterSymbol(const String& field_name) { | 7459 RawString* Field::LookupGetterSymbol(const String& field_name) { |
7830 return Symbols::LookupFromGet(Thread::Current(), field_name); | 7460 return Symbols::LookupFromGet(Thread::Current(), field_name); |
7831 } | 7461 } |
7832 | 7462 |
7833 | |
7834 RawString* Field::SetterName(const String& field_name) { | 7463 RawString* Field::SetterName(const String& field_name) { |
7835 return String::Concat(Symbols::SetterPrefix(), field_name); | 7464 return String::Concat(Symbols::SetterPrefix(), field_name); |
7836 } | 7465 } |
7837 | 7466 |
7838 | |
7839 RawString* Field::SetterSymbol(const String& field_name) { | 7467 RawString* Field::SetterSymbol(const String& field_name) { |
7840 return Symbols::FromSet(Thread::Current(), field_name); | 7468 return Symbols::FromSet(Thread::Current(), field_name); |
7841 } | 7469 } |
7842 | 7470 |
7843 | |
7844 RawString* Field::LookupSetterSymbol(const String& field_name) { | 7471 RawString* Field::LookupSetterSymbol(const String& field_name) { |
7845 return Symbols::LookupFromSet(Thread::Current(), field_name); | 7472 return Symbols::LookupFromSet(Thread::Current(), field_name); |
7846 } | 7473 } |
7847 | 7474 |
7848 | |
7849 RawString* Field::NameFromGetter(const String& getter_name) { | 7475 RawString* Field::NameFromGetter(const String& getter_name) { |
7850 return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength, | 7476 return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength, |
7851 getter_name.Length() - kGetterPrefixLength); | 7477 getter_name.Length() - kGetterPrefixLength); |
7852 } | 7478 } |
7853 | 7479 |
7854 | |
7855 RawString* Field::NameFromSetter(const String& setter_name) { | 7480 RawString* Field::NameFromSetter(const String& setter_name) { |
7856 return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength, | 7481 return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength, |
7857 setter_name.Length() - kSetterPrefixLength); | 7482 setter_name.Length() - kSetterPrefixLength); |
7858 } | 7483 } |
7859 | 7484 |
7860 | |
7861 bool Field::IsGetterName(const String& function_name) { | 7485 bool Field::IsGetterName(const String& function_name) { |
7862 return function_name.StartsWith(Symbols::GetterPrefix()); | 7486 return function_name.StartsWith(Symbols::GetterPrefix()); |
7863 } | 7487 } |
7864 | 7488 |
7865 | |
7866 bool Field::IsSetterName(const String& function_name) { | 7489 bool Field::IsSetterName(const String& function_name) { |
7867 return function_name.StartsWith(Symbols::SetterPrefix()); | 7490 return function_name.StartsWith(Symbols::SetterPrefix()); |
7868 } | 7491 } |
7869 | 7492 |
7870 | |
7871 void Field::set_name(const String& value) const { | 7493 void Field::set_name(const String& value) const { |
7872 ASSERT(value.IsSymbol()); | 7494 ASSERT(value.IsSymbol()); |
7873 ASSERT(IsOriginal()); | 7495 ASSERT(IsOriginal()); |
7874 StorePointer(&raw_ptr()->name_, value.raw()); | 7496 StorePointer(&raw_ptr()->name_, value.raw()); |
7875 } | 7497 } |
7876 | 7498 |
7877 | |
7878 RawObject* Field::RawOwner() const { | 7499 RawObject* Field::RawOwner() const { |
7879 if (IsOriginal()) { | 7500 if (IsOriginal()) { |
7880 return raw_ptr()->owner_; | 7501 return raw_ptr()->owner_; |
7881 } else { | 7502 } else { |
7882 const Field& field = Field::Handle(Original()); | 7503 const Field& field = Field::Handle(Original()); |
7883 ASSERT(field.IsOriginal()); | 7504 ASSERT(field.IsOriginal()); |
7884 ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField()); | 7505 ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField()); |
7885 return field.raw_ptr()->owner_; | 7506 return field.raw_ptr()->owner_; |
7886 } | 7507 } |
7887 } | 7508 } |
7888 | 7509 |
7889 | |
7890 RawClass* Field::Owner() const { | 7510 RawClass* Field::Owner() const { |
7891 const Field& field = Field::Handle(Original()); | 7511 const Field& field = Field::Handle(Original()); |
7892 ASSERT(field.IsOriginal()); | 7512 ASSERT(field.IsOriginal()); |
7893 const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 7513 const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
7894 if (obj.IsClass()) { | 7514 if (obj.IsClass()) { |
7895 return Class::Cast(obj).raw(); | 7515 return Class::Cast(obj).raw(); |
7896 } | 7516 } |
7897 ASSERT(obj.IsPatchClass()); | 7517 ASSERT(obj.IsPatchClass()); |
7898 return PatchClass::Cast(obj).patched_class(); | 7518 return PatchClass::Cast(obj).patched_class(); |
7899 } | 7519 } |
7900 | 7520 |
7901 | |
7902 RawClass* Field::Origin() const { | 7521 RawClass* Field::Origin() const { |
7903 const Field& field = Field::Handle(Original()); | 7522 const Field& field = Field::Handle(Original()); |
7904 ASSERT(field.IsOriginal()); | 7523 ASSERT(field.IsOriginal()); |
7905 const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 7524 const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
7906 if (obj.IsClass()) { | 7525 if (obj.IsClass()) { |
7907 return Class::Cast(obj).raw(); | 7526 return Class::Cast(obj).raw(); |
7908 } | 7527 } |
7909 ASSERT(obj.IsPatchClass()); | 7528 ASSERT(obj.IsPatchClass()); |
7910 return PatchClass::Cast(obj).origin_class(); | 7529 return PatchClass::Cast(obj).origin_class(); |
7911 } | 7530 } |
7912 | 7531 |
7913 | |
7914 RawScript* Field::Script() const { | 7532 RawScript* Field::Script() const { |
7915 // NOTE(turnidge): If you update this function, you probably want to | 7533 // NOTE(turnidge): If you update this function, you probably want to |
7916 // update Class::PatchFieldsAndFunctions() at the same time. | 7534 // update Class::PatchFieldsAndFunctions() at the same time. |
7917 const Field& field = Field::Handle(Original()); | 7535 const Field& field = Field::Handle(Original()); |
7918 ASSERT(field.IsOriginal()); | 7536 ASSERT(field.IsOriginal()); |
7919 const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 7537 const Object& obj = Object::Handle(field.raw_ptr()->owner_); |
7920 if (obj.IsClass()) { | 7538 if (obj.IsClass()) { |
7921 return Class::Cast(obj).script(); | 7539 return Class::Cast(obj).script(); |
7922 } | 7540 } |
7923 ASSERT(obj.IsPatchClass()); | 7541 ASSERT(obj.IsPatchClass()); |
7924 return PatchClass::Cast(obj).script(); | 7542 return PatchClass::Cast(obj).script(); |
7925 } | 7543 } |
7926 | 7544 |
7927 | |
7928 // Called at finalization time | 7545 // Called at finalization time |
7929 void Field::SetFieldType(const AbstractType& value) const { | 7546 void Field::SetFieldType(const AbstractType& value) const { |
7930 ASSERT(Thread::Current()->IsMutatorThread()); | 7547 ASSERT(Thread::Current()->IsMutatorThread()); |
7931 ASSERT(IsOriginal()); | 7548 ASSERT(IsOriginal()); |
7932 ASSERT(!value.IsNull()); | 7549 ASSERT(!value.IsNull()); |
7933 if (value.raw() != type()) { | 7550 if (value.raw() != type()) { |
7934 StorePointer(&raw_ptr()->type_, value.raw()); | 7551 StorePointer(&raw_ptr()->type_, value.raw()); |
7935 } | 7552 } |
7936 } | 7553 } |
7937 | 7554 |
7938 | |
7939 RawField* Field::New() { | 7555 RawField* Field::New() { |
7940 ASSERT(Object::field_class() != Class::null()); | 7556 ASSERT(Object::field_class() != Class::null()); |
7941 RawObject* raw = | 7557 RawObject* raw = |
7942 Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld); | 7558 Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld); |
7943 return reinterpret_cast<RawField*>(raw); | 7559 return reinterpret_cast<RawField*>(raw); |
7944 } | 7560 } |
7945 | 7561 |
7946 | |
7947 void Field::InitializeNew(const Field& result, | 7562 void Field::InitializeNew(const Field& result, |
7948 const String& name, | 7563 const String& name, |
7949 bool is_static, | 7564 bool is_static, |
7950 bool is_final, | 7565 bool is_final, |
7951 bool is_const, | 7566 bool is_const, |
7952 bool is_reflectable, | 7567 bool is_reflectable, |
7953 const Object& owner, | 7568 const Object& owner, |
7954 TokenPosition token_pos) { | 7569 TokenPosition token_pos) { |
7955 result.set_name(name); | 7570 result.set_name(name); |
7956 result.set_is_static(is_static); | 7571 result.set_is_static(is_static); |
(...skipping 21 matching lines...) Expand all Loading... |
7978 result.set_is_nullable(use_guarded_cid ? false : true); | 7593 result.set_is_nullable(use_guarded_cid ? false : true); |
7979 result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 7594 result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |
7980 // Presently, we only attempt to remember the list length for final fields. | 7595 // Presently, we only attempt to remember the list length for final fields. |
7981 if (is_final && use_guarded_cid) { | 7596 if (is_final && use_guarded_cid) { |
7982 result.set_guarded_list_length(Field::kUnknownFixedLength); | 7597 result.set_guarded_list_length(Field::kUnknownFixedLength); |
7983 } else { | 7598 } else { |
7984 result.set_guarded_list_length(Field::kNoFixedLength); | 7599 result.set_guarded_list_length(Field::kNoFixedLength); |
7985 } | 7600 } |
7986 } | 7601 } |
7987 | 7602 |
7988 | |
7989 RawField* Field::New(const String& name, | 7603 RawField* Field::New(const String& name, |
7990 bool is_static, | 7604 bool is_static, |
7991 bool is_final, | 7605 bool is_final, |
7992 bool is_const, | 7606 bool is_const, |
7993 bool is_reflectable, | 7607 bool is_reflectable, |
7994 const Object& owner, | 7608 const Object& owner, |
7995 const AbstractType& type, | 7609 const AbstractType& type, |
7996 TokenPosition token_pos) { | 7610 TokenPosition token_pos) { |
7997 ASSERT(!owner.IsNull()); | 7611 ASSERT(!owner.IsNull()); |
7998 const Field& result = Field::Handle(Field::New()); | 7612 const Field& result = Field::Handle(Field::New()); |
7999 InitializeNew(result, name, is_static, is_final, is_const, is_reflectable, | 7613 InitializeNew(result, name, is_static, is_final, is_const, is_reflectable, |
8000 owner, token_pos); | 7614 owner, token_pos); |
8001 result.SetFieldType(type); | 7615 result.SetFieldType(type); |
8002 return result.raw(); | 7616 return result.raw(); |
8003 } | 7617 } |
8004 | 7618 |
8005 | |
8006 RawField* Field::NewTopLevel(const String& name, | 7619 RawField* Field::NewTopLevel(const String& name, |
8007 bool is_final, | 7620 bool is_final, |
8008 bool is_const, | 7621 bool is_const, |
8009 const Object& owner, | 7622 const Object& owner, |
8010 TokenPosition token_pos) { | 7623 TokenPosition token_pos) { |
8011 ASSERT(!owner.IsNull()); | 7624 ASSERT(!owner.IsNull()); |
8012 const Field& result = Field::Handle(Field::New()); | 7625 const Field& result = Field::Handle(Field::New()); |
8013 InitializeNew(result, name, true, /* is_static */ | 7626 InitializeNew(result, name, true, /* is_static */ |
8014 is_final, is_const, true, /* is_reflectable */ | 7627 is_final, is_const, true, /* is_reflectable */ |
8015 owner, token_pos); | 7628 owner, token_pos); |
8016 return result.raw(); | 7629 return result.raw(); |
8017 } | 7630 } |
8018 | 7631 |
8019 | |
8020 RawField* Field::Clone(const Class& new_owner) const { | 7632 RawField* Field::Clone(const Class& new_owner) const { |
8021 Field& clone = Field::Handle(); | 7633 Field& clone = Field::Handle(); |
8022 clone ^= Object::Clone(*this, Heap::kOld); | 7634 clone ^= Object::Clone(*this, Heap::kOld); |
8023 const Class& owner = Class::Handle(this->Owner()); | 7635 const Class& owner = Class::Handle(this->Owner()); |
8024 const PatchClass& clone_owner = | 7636 const PatchClass& clone_owner = |
8025 PatchClass::Handle(PatchClass::New(new_owner, owner)); | 7637 PatchClass::Handle(PatchClass::New(new_owner, owner)); |
8026 clone.set_owner(clone_owner); | 7638 clone.set_owner(clone_owner); |
8027 if (!clone.is_static()) { | 7639 if (!clone.is_static()) { |
8028 clone.SetOffset(0); | 7640 clone.SetOffset(0); |
8029 } | 7641 } |
8030 if (new_owner.NumTypeParameters() > 0) { | 7642 if (new_owner.NumTypeParameters() > 0) { |
8031 // Adjust the field type to refer to type parameters of the new owner. | 7643 // Adjust the field type to refer to type parameters of the new owner. |
8032 AbstractType& type = AbstractType::Handle(clone.type()); | 7644 AbstractType& type = AbstractType::Handle(clone.type()); |
8033 type ^= type.CloneUninstantiated(new_owner); | 7645 type ^= type.CloneUninstantiated(new_owner); |
8034 clone.SetFieldType(type); | 7646 clone.SetFieldType(type); |
8035 } | 7647 } |
8036 return clone.raw(); | 7648 return clone.raw(); |
8037 } | 7649 } |
8038 | 7650 |
8039 | |
8040 RawField* Field::Clone(const Field& original) const { | 7651 RawField* Field::Clone(const Field& original) const { |
8041 if (original.IsNull()) { | 7652 if (original.IsNull()) { |
8042 return Field::null(); | 7653 return Field::null(); |
8043 } | 7654 } |
8044 ASSERT(original.IsOriginal()); | 7655 ASSERT(original.IsOriginal()); |
8045 Field& clone = Field::Handle(); | 7656 Field& clone = Field::Handle(); |
8046 clone ^= Object::Clone(*this, Heap::kOld); | 7657 clone ^= Object::Clone(*this, Heap::kOld); |
8047 clone.SetOriginal(original); | 7658 clone.SetOriginal(original); |
8048 clone.set_kernel_offset(original.kernel_offset()); | 7659 clone.set_kernel_offset(original.kernel_offset()); |
8049 return clone.raw(); | 7660 return clone.raw(); |
8050 } | 7661 } |
8051 | 7662 |
8052 | |
8053 RawString* Field::InitializingExpression() const { | 7663 RawString* Field::InitializingExpression() const { |
8054 Thread* thread = Thread::Current(); | 7664 Thread* thread = Thread::Current(); |
8055 Zone* zone = thread->zone(); | 7665 Zone* zone = thread->zone(); |
8056 const class Script& scr = Script::Handle(zone, Script()); | 7666 const class Script& scr = Script::Handle(zone, Script()); |
8057 ASSERT(!scr.IsNull()); | 7667 ASSERT(!scr.IsNull()); |
8058 const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens()); | 7668 const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens()); |
8059 if (tkns.IsNull()) { | 7669 if (tkns.IsNull()) { |
8060 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 7670 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
8061 return String::null(); | 7671 return String::null(); |
8062 } | 7672 } |
8063 TokenStream::Iterator tkit(zone, tkns, token_pos()); | 7673 TokenStream::Iterator tkit(zone, tkns, token_pos()); |
8064 ASSERT(Token::IsIdentifier(tkit.CurrentTokenKind())); | 7674 ASSERT(Token::IsIdentifier(tkit.CurrentTokenKind())); |
8065 #if defined(DEBUG) | 7675 #if defined(DEBUG) |
8066 const String& literal = String::Handle(zone, tkit.CurrentLiteral()); | 7676 const String& literal = String::Handle(zone, tkit.CurrentLiteral()); |
8067 ASSERT(literal.raw() == name()); | 7677 ASSERT(literal.raw() == name()); |
8068 #endif | 7678 #endif |
8069 tkit.Advance(); | 7679 tkit.Advance(); |
8070 if (tkit.CurrentTokenKind() != Token::kASSIGN) { | 7680 if (tkit.CurrentTokenKind() != Token::kASSIGN) { |
8071 return String::null(); | 7681 return String::null(); |
8072 } | 7682 } |
8073 tkit.Advance(); | 7683 tkit.Advance(); |
8074 const TokenPosition start_of_expression = tkit.CurrentPosition(); | 7684 const TokenPosition start_of_expression = tkit.CurrentPosition(); |
8075 while (tkit.CurrentTokenKind() != Token::kSEMICOLON) { | 7685 while (tkit.CurrentTokenKind() != Token::kSEMICOLON) { |
8076 tkit.Advance(); | 7686 tkit.Advance(); |
8077 } | 7687 } |
8078 const TokenPosition end_of_expression = tkit.CurrentPosition(); | 7688 const TokenPosition end_of_expression = tkit.CurrentPosition(); |
8079 return scr.GetSnippet(start_of_expression, end_of_expression); | 7689 return scr.GetSnippet(start_of_expression, end_of_expression); |
8080 } | 7690 } |
8081 | 7691 |
8082 | |
8083 RawString* Field::UserVisibleName() const { | 7692 RawString* Field::UserVisibleName() const { |
8084 if (FLAG_show_internal_names) { | 7693 if (FLAG_show_internal_names) { |
8085 return name(); | 7694 return name(); |
8086 } | 7695 } |
8087 return String::ScrubName(String::Handle(name())); | 7696 return String::ScrubName(String::Handle(name())); |
8088 } | 7697 } |
8089 | 7698 |
8090 | |
8091 intptr_t Field::guarded_list_length() const { | 7699 intptr_t Field::guarded_list_length() const { |
8092 return Smi::Value(raw_ptr()->guarded_list_length_); | 7700 return Smi::Value(raw_ptr()->guarded_list_length_); |
8093 } | 7701 } |
8094 | 7702 |
8095 | |
8096 void Field::set_guarded_list_length(intptr_t list_length) const { | 7703 void Field::set_guarded_list_length(intptr_t list_length) const { |
8097 ASSERT(Thread::Current()->IsMutatorThread()); | 7704 ASSERT(Thread::Current()->IsMutatorThread()); |
8098 ASSERT(IsOriginal()); | 7705 ASSERT(IsOriginal()); |
8099 StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length)); | 7706 StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length)); |
8100 } | 7707 } |
8101 | 7708 |
8102 | |
8103 intptr_t Field::guarded_list_length_in_object_offset() const { | 7709 intptr_t Field::guarded_list_length_in_object_offset() const { |
8104 return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag; | 7710 return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag; |
8105 } | 7711 } |
8106 | 7712 |
8107 | |
8108 void Field::set_guarded_list_length_in_object_offset( | 7713 void Field::set_guarded_list_length_in_object_offset( |
8109 intptr_t list_length_offset) const { | 7714 intptr_t list_length_offset) const { |
8110 ASSERT(Thread::Current()->IsMutatorThread()); | 7715 ASSERT(Thread::Current()->IsMutatorThread()); |
8111 ASSERT(IsOriginal()); | 7716 ASSERT(IsOriginal()); |
8112 StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_, | 7717 StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_, |
8113 static_cast<int8_t>(list_length_offset - kHeapObjectTag)); | 7718 static_cast<int8_t>(list_length_offset - kHeapObjectTag)); |
8114 ASSERT(guarded_list_length_in_object_offset() == list_length_offset); | 7719 ASSERT(guarded_list_length_in_object_offset() == list_length_offset); |
8115 } | 7720 } |
8116 | 7721 |
8117 | |
8118 const char* Field::ToCString() const { | 7722 const char* Field::ToCString() const { |
8119 if (IsNull()) { | 7723 if (IsNull()) { |
8120 return "Field: null"; | 7724 return "Field: null"; |
8121 } | 7725 } |
8122 const char* kF0 = is_static() ? " static" : ""; | 7726 const char* kF0 = is_static() ? " static" : ""; |
8123 const char* kF1 = is_final() ? " final" : ""; | 7727 const char* kF1 = is_final() ? " final" : ""; |
8124 const char* kF2 = is_const() ? " const" : ""; | 7728 const char* kF2 = is_const() ? " const" : ""; |
8125 const char* field_name = String::Handle(name()).ToCString(); | 7729 const char* field_name = String::Handle(name()).ToCString(); |
8126 const Class& cls = Class::Handle(Owner()); | 7730 const Class& cls = Class::Handle(Owner()); |
8127 const char* cls_name = String::Handle(cls.Name()).ToCString(); | 7731 const char* cls_name = String::Handle(cls.Name()).ToCString(); |
8128 return OS::SCreate(Thread::Current()->zone(), "Field <%s.%s>:%s%s%s", | 7732 return OS::SCreate(Thread::Current()->zone(), "Field <%s.%s>:%s%s%s", |
8129 cls_name, field_name, kF0, kF1, kF2); | 7733 cls_name, field_name, kF0, kF1, kF2); |
8130 } | 7734 } |
8131 | 7735 |
8132 | |
8133 // Build a closure object that gets (or sets) the contents of a static | 7736 // Build a closure object that gets (or sets) the contents of a static |
8134 // field f and cache the closure in a newly created static field | 7737 // field f and cache the closure in a newly created static field |
8135 // named #f (or #f= in case of a setter). | 7738 // named #f (or #f= in case of a setter). |
8136 RawInstance* Field::AccessorClosure(bool make_setter) const { | 7739 RawInstance* Field::AccessorClosure(bool make_setter) const { |
8137 Thread* thread = Thread::Current(); | 7740 Thread* thread = Thread::Current(); |
8138 Zone* zone = thread->zone(); | 7741 Zone* zone = thread->zone(); |
8139 ASSERT(is_static()); | 7742 ASSERT(is_static()); |
8140 const Class& field_owner = Class::Handle(zone, Owner()); | 7743 const Class& field_owner = Class::Handle(zone, Owner()); |
8141 | 7744 |
8142 String& closure_name = String::Handle(zone, this->name()); | 7745 String& closure_name = String::Handle(zone, this->name()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8181 true, // is_final | 7784 true, // is_final |
8182 true, // is_const | 7785 true, // is_const |
8183 false, // is_reflectable | 7786 false, // is_reflectable |
8184 field_owner, Object::dynamic_type(), this->token_pos()); | 7787 field_owner, Object::dynamic_type(), this->token_pos()); |
8185 closure_field.SetStaticValue(Instance::Cast(result), true); | 7788 closure_field.SetStaticValue(Instance::Cast(result), true); |
8186 field_owner.AddField(closure_field); | 7789 field_owner.AddField(closure_field); |
8187 | 7790 |
8188 return Instance::RawCast(result.raw()); | 7791 return Instance::RawCast(result.raw()); |
8189 } | 7792 } |
8190 | 7793 |
8191 | |
8192 RawInstance* Field::GetterClosure() const { | 7794 RawInstance* Field::GetterClosure() const { |
8193 return AccessorClosure(false); | 7795 return AccessorClosure(false); |
8194 } | 7796 } |
8195 | 7797 |
8196 | |
8197 RawInstance* Field::SetterClosure() const { | 7798 RawInstance* Field::SetterClosure() const { |
8198 return AccessorClosure(true); | 7799 return AccessorClosure(true); |
8199 } | 7800 } |
8200 | 7801 |
8201 | |
8202 RawArray* Field::dependent_code() const { | 7802 RawArray* Field::dependent_code() const { |
8203 return raw_ptr()->dependent_code_; | 7803 return raw_ptr()->dependent_code_; |
8204 } | 7804 } |
8205 | 7805 |
8206 | |
8207 void Field::set_dependent_code(const Array& array) const { | 7806 void Field::set_dependent_code(const Array& array) const { |
8208 ASSERT(IsOriginal()); | 7807 ASSERT(IsOriginal()); |
8209 StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 7808 StorePointer(&raw_ptr()->dependent_code_, array.raw()); |
8210 } | 7809 } |
8211 | 7810 |
8212 | |
8213 class FieldDependentArray : public WeakCodeReferences { | 7811 class FieldDependentArray : public WeakCodeReferences { |
8214 public: | 7812 public: |
8215 explicit FieldDependentArray(const Field& field) | 7813 explicit FieldDependentArray(const Field& field) |
8216 : WeakCodeReferences(Array::Handle(field.dependent_code())), | 7814 : WeakCodeReferences(Array::Handle(field.dependent_code())), |
8217 field_(field) {} | 7815 field_(field) {} |
8218 | 7816 |
8219 virtual void UpdateArrayTo(const Array& value) { | 7817 virtual void UpdateArrayTo(const Array& value) { |
8220 field_.set_dependent_code(value); | 7818 field_.set_dependent_code(value); |
8221 } | 7819 } |
8222 | 7820 |
(...skipping 13 matching lines...) Expand all Loading... |
8236 " on field '%s' was violated.\n", | 7834 " on field '%s' was violated.\n", |
8237 function.ToFullyQualifiedCString(), field_.ToCString()); | 7835 function.ToFullyQualifiedCString(), field_.ToCString()); |
8238 } | 7836 } |
8239 } | 7837 } |
8240 | 7838 |
8241 private: | 7839 private: |
8242 const Field& field_; | 7840 const Field& field_; |
8243 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); | 7841 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); |
8244 }; | 7842 }; |
8245 | 7843 |
8246 | |
8247 void Field::RegisterDependentCode(const Code& code) const { | 7844 void Field::RegisterDependentCode(const Code& code) const { |
8248 ASSERT(IsOriginal()); | 7845 ASSERT(IsOriginal()); |
8249 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 7846 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
8250 ASSERT(code.is_optimized()); | 7847 ASSERT(code.is_optimized()); |
8251 FieldDependentArray a(*this); | 7848 FieldDependentArray a(*this); |
8252 a.Register(code); | 7849 a.Register(code); |
8253 } | 7850 } |
8254 | 7851 |
8255 | |
8256 void Field::DeoptimizeDependentCode() const { | 7852 void Field::DeoptimizeDependentCode() const { |
8257 ASSERT(Thread::Current()->IsMutatorThread()); | 7853 ASSERT(Thread::Current()->IsMutatorThread()); |
8258 ASSERT(IsOriginal()); | 7854 ASSERT(IsOriginal()); |
8259 FieldDependentArray a(*this); | 7855 FieldDependentArray a(*this); |
8260 a.DisableCode(); | 7856 a.DisableCode(); |
8261 } | 7857 } |
8262 | 7858 |
8263 | |
8264 bool Field::IsConsistentWith(const Field& other) const { | 7859 bool Field::IsConsistentWith(const Field& other) const { |
8265 return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) && | 7860 return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) && |
8266 (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) && | 7861 (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) && |
8267 (raw_ptr()->guarded_list_length_ == | 7862 (raw_ptr()->guarded_list_length_ == |
8268 other.raw_ptr()->guarded_list_length_) && | 7863 other.raw_ptr()->guarded_list_length_) && |
8269 (is_unboxing_candidate() == other.is_unboxing_candidate()); | 7864 (is_unboxing_candidate() == other.is_unboxing_candidate()); |
8270 } | 7865 } |
8271 | 7866 |
8272 | |
8273 bool Field::IsUninitialized() const { | 7867 bool Field::IsUninitialized() const { |
8274 const Instance& value = Instance::Handle(raw_ptr()->value_.static_value_); | 7868 const Instance& value = Instance::Handle(raw_ptr()->value_.static_value_); |
8275 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 7869 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
8276 return value.raw() == Object::sentinel().raw(); | 7870 return value.raw() == Object::sentinel().raw(); |
8277 } | 7871 } |
8278 | 7872 |
8279 | |
8280 void Field::SetPrecompiledInitializer(const Function& initializer) const { | 7873 void Field::SetPrecompiledInitializer(const Function& initializer) const { |
8281 ASSERT(IsOriginal()); | 7874 ASSERT(IsOriginal()); |
8282 StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw()); | 7875 StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw()); |
8283 } | 7876 } |
8284 | 7877 |
8285 | |
8286 bool Field::HasPrecompiledInitializer() const { | 7878 bool Field::HasPrecompiledInitializer() const { |
8287 return raw_ptr()->initializer_.precompiled_->IsHeapObject() && | 7879 return raw_ptr()->initializer_.precompiled_->IsHeapObject() && |
8288 raw_ptr()->initializer_.precompiled_->IsFunction(); | 7880 raw_ptr()->initializer_.precompiled_->IsFunction(); |
8289 } | 7881 } |
8290 | 7882 |
8291 | |
8292 void Field::SetSavedInitialStaticValue(const Instance& value) const { | 7883 void Field::SetSavedInitialStaticValue(const Instance& value) const { |
8293 ASSERT(IsOriginal()); | 7884 ASSERT(IsOriginal()); |
8294 ASSERT(!HasPrecompiledInitializer()); | 7885 ASSERT(!HasPrecompiledInitializer()); |
8295 StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw()); | 7886 StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw()); |
8296 } | 7887 } |
8297 | 7888 |
8298 | |
8299 void Field::EvaluateInitializer() const { | 7889 void Field::EvaluateInitializer() const { |
8300 ASSERT(IsOriginal()); | 7890 ASSERT(IsOriginal()); |
8301 ASSERT(is_static()); | 7891 ASSERT(is_static()); |
8302 if (StaticValue() == Object::sentinel().raw()) { | 7892 if (StaticValue() == Object::sentinel().raw()) { |
8303 SetStaticValue(Object::transition_sentinel()); | 7893 SetStaticValue(Object::transition_sentinel()); |
8304 const Object& value = | 7894 const Object& value = |
8305 Object::Handle(Compiler::EvaluateStaticInitializer(*this)); | 7895 Object::Handle(Compiler::EvaluateStaticInitializer(*this)); |
8306 if (value.IsError()) { | 7896 if (value.IsError()) { |
8307 SetStaticValue(Object::null_instance()); | 7897 SetStaticValue(Object::null_instance()); |
8308 Exceptions::PropagateError(Error::Cast(value)); | 7898 Exceptions::PropagateError(Error::Cast(value)); |
8309 UNREACHABLE(); | 7899 UNREACHABLE(); |
8310 } | 7900 } |
8311 ASSERT(value.IsNull() || value.IsInstance()); | 7901 ASSERT(value.IsNull() || value.IsInstance()); |
8312 SetStaticValue(value.IsNull() ? Instance::null_instance() | 7902 SetStaticValue(value.IsNull() ? Instance::null_instance() |
8313 : Instance::Cast(value)); | 7903 : Instance::Cast(value)); |
8314 return; | 7904 return; |
8315 } else if (StaticValue() == Object::transition_sentinel().raw()) { | 7905 } else if (StaticValue() == Object::transition_sentinel().raw()) { |
8316 const Array& ctor_args = Array::Handle(Array::New(1)); | 7906 const Array& ctor_args = Array::Handle(Array::New(1)); |
8317 const String& field_name = String::Handle(name()); | 7907 const String& field_name = String::Handle(name()); |
8318 ctor_args.SetAt(0, field_name); | 7908 ctor_args.SetAt(0, field_name); |
8319 Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args); | 7909 Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args); |
8320 UNREACHABLE(); | 7910 UNREACHABLE(); |
8321 return; | 7911 return; |
8322 } | 7912 } |
8323 UNREACHABLE(); | 7913 UNREACHABLE(); |
8324 } | 7914 } |
8325 | 7915 |
8326 | |
8327 static intptr_t GetListLength(const Object& value) { | 7916 static intptr_t GetListLength(const Object& value) { |
8328 if (value.IsTypedData()) { | 7917 if (value.IsTypedData()) { |
8329 const TypedData& list = TypedData::Cast(value); | 7918 const TypedData& list = TypedData::Cast(value); |
8330 return list.Length(); | 7919 return list.Length(); |
8331 } else if (value.IsArray()) { | 7920 } else if (value.IsArray()) { |
8332 const Array& list = Array::Cast(value); | 7921 const Array& list = Array::Cast(value); |
8333 return list.Length(); | 7922 return list.Length(); |
8334 } else if (value.IsGrowableObjectArray()) { | 7923 } else if (value.IsGrowableObjectArray()) { |
8335 // List length is variable. | 7924 // List length is variable. |
8336 return Field::kNoFixedLength; | 7925 return Field::kNoFixedLength; |
8337 } else if (value.IsExternalTypedData()) { | 7926 } else if (value.IsExternalTypedData()) { |
8338 // TODO(johnmccutchan): Enable for external typed data. | 7927 // TODO(johnmccutchan): Enable for external typed data. |
8339 return Field::kNoFixedLength; | 7928 return Field::kNoFixedLength; |
8340 } else if (RawObject::IsTypedDataViewClassId(value.GetClassId())) { | 7929 } else if (RawObject::IsTypedDataViewClassId(value.GetClassId())) { |
8341 // TODO(johnmccutchan): Enable for typed data views. | 7930 // TODO(johnmccutchan): Enable for typed data views. |
8342 return Field::kNoFixedLength; | 7931 return Field::kNoFixedLength; |
8343 } | 7932 } |
8344 return Field::kNoFixedLength; | 7933 return Field::kNoFixedLength; |
8345 } | 7934 } |
8346 | 7935 |
8347 | |
8348 static intptr_t GetListLengthOffset(intptr_t cid) { | 7936 static intptr_t GetListLengthOffset(intptr_t cid) { |
8349 if (RawObject::IsTypedDataClassId(cid)) { | 7937 if (RawObject::IsTypedDataClassId(cid)) { |
8350 return TypedData::length_offset(); | 7938 return TypedData::length_offset(); |
8351 } else if (cid == kArrayCid || cid == kImmutableArrayCid) { | 7939 } else if (cid == kArrayCid || cid == kImmutableArrayCid) { |
8352 return Array::length_offset(); | 7940 return Array::length_offset(); |
8353 } else if (cid == kGrowableObjectArrayCid) { | 7941 } else if (cid == kGrowableObjectArrayCid) { |
8354 // List length is variable. | 7942 // List length is variable. |
8355 return Field::kUnknownLengthOffset; | 7943 return Field::kUnknownLengthOffset; |
8356 } else if (RawObject::IsExternalTypedDataClassId(cid)) { | 7944 } else if (RawObject::IsExternalTypedDataClassId(cid)) { |
8357 // TODO(johnmccutchan): Enable for external typed data. | 7945 // TODO(johnmccutchan): Enable for external typed data. |
8358 return Field::kUnknownLengthOffset; | 7946 return Field::kUnknownLengthOffset; |
8359 } else if (RawObject::IsTypedDataViewClassId(cid)) { | 7947 } else if (RawObject::IsTypedDataViewClassId(cid)) { |
8360 // TODO(johnmccutchan): Enable for typed data views. | 7948 // TODO(johnmccutchan): Enable for typed data views. |
8361 return Field::kUnknownLengthOffset; | 7949 return Field::kUnknownLengthOffset; |
8362 } | 7950 } |
8363 return Field::kUnknownLengthOffset; | 7951 return Field::kUnknownLengthOffset; |
8364 } | 7952 } |
8365 | 7953 |
8366 | |
8367 const char* Field::GuardedPropertiesAsCString() const { | 7954 const char* Field::GuardedPropertiesAsCString() const { |
8368 if (guarded_cid() == kIllegalCid) { | 7955 if (guarded_cid() == kIllegalCid) { |
8369 return "<?>"; | 7956 return "<?>"; |
8370 } else if (guarded_cid() == kDynamicCid) { | 7957 } else if (guarded_cid() == kDynamicCid) { |
8371 return "<*>"; | 7958 return "<*>"; |
8372 } | 7959 } |
8373 | 7960 |
8374 const Class& cls = | 7961 const Class& cls = |
8375 Class::Handle(Isolate::Current()->class_table()->At(guarded_cid())); | 7962 Class::Handle(Isolate::Current()->class_table()->At(guarded_cid())); |
8376 const char* class_name = String::Handle(cls.Name()).ToCString(); | 7963 const char* class_name = String::Handle(cls.Name()).ToCString(); |
8377 | 7964 |
8378 if (RawObject::IsBuiltinListClassId(guarded_cid()) && !is_nullable() && | 7965 if (RawObject::IsBuiltinListClassId(guarded_cid()) && !is_nullable() && |
8379 is_final()) { | 7966 is_final()) { |
8380 ASSERT(guarded_list_length() != kUnknownFixedLength); | 7967 ASSERT(guarded_list_length() != kUnknownFixedLength); |
8381 if (guarded_list_length() == kNoFixedLength) { | 7968 if (guarded_list_length() == kNoFixedLength) { |
8382 return Thread::Current()->zone()->PrintToString("<%s [*]>", class_name); | 7969 return Thread::Current()->zone()->PrintToString("<%s [*]>", class_name); |
8383 } else { | 7970 } else { |
8384 return Thread::Current()->zone()->PrintToString( | 7971 return Thread::Current()->zone()->PrintToString( |
8385 "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), | 7972 "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), |
8386 guarded_list_length_in_object_offset()); | 7973 guarded_list_length_in_object_offset()); |
8387 } | 7974 } |
8388 } | 7975 } |
8389 | 7976 |
8390 return Thread::Current()->zone()->PrintToString( | 7977 return Thread::Current()->zone()->PrintToString( |
8391 "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); | 7978 "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); |
8392 } | 7979 } |
8393 | 7980 |
8394 | |
8395 bool Field::IsExternalizableCid(intptr_t cid) { | 7981 bool Field::IsExternalizableCid(intptr_t cid) { |
8396 if (FLAG_support_externalizable_strings) { | 7982 if (FLAG_support_externalizable_strings) { |
8397 return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid); | 7983 return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid); |
8398 } else { | 7984 } else { |
8399 return false; | 7985 return false; |
8400 } | 7986 } |
8401 } | 7987 } |
8402 | 7988 |
8403 | |
8404 void Field::InitializeGuardedListLengthInObjectOffset() const { | 7989 void Field::InitializeGuardedListLengthInObjectOffset() const { |
8405 ASSERT(IsOriginal()); | 7990 ASSERT(IsOriginal()); |
8406 if (needs_length_check() && | 7991 if (needs_length_check() && |
8407 (guarded_list_length() != Field::kUnknownFixedLength)) { | 7992 (guarded_list_length() != Field::kUnknownFixedLength)) { |
8408 const intptr_t offset = GetListLengthOffset(guarded_cid()); | 7993 const intptr_t offset = GetListLengthOffset(guarded_cid()); |
8409 set_guarded_list_length_in_object_offset(offset); | 7994 set_guarded_list_length_in_object_offset(offset); |
8410 ASSERT(offset != Field::kUnknownLengthOffset); | 7995 ASSERT(offset != Field::kUnknownLengthOffset); |
8411 } else { | 7996 } else { |
8412 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 7997 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |
8413 } | 7998 } |
8414 } | 7999 } |
8415 | 8000 |
8416 | |
8417 bool Field::UpdateGuardedCidAndLength(const Object& value) const { | 8001 bool Field::UpdateGuardedCidAndLength(const Object& value) const { |
8418 ASSERT(IsOriginal()); | 8002 ASSERT(IsOriginal()); |
8419 const intptr_t cid = value.GetClassId(); | 8003 const intptr_t cid = value.GetClassId(); |
8420 | 8004 |
8421 if (guarded_cid() == kIllegalCid) { | 8005 if (guarded_cid() == kIllegalCid) { |
8422 // Field is assigned first time. | 8006 // Field is assigned first time. |
8423 set_guarded_cid(cid); | 8007 set_guarded_cid(cid); |
8424 set_is_nullable(cid == kNullCid); | 8008 set_is_nullable(cid == kNullCid); |
8425 | 8009 |
8426 // Start tracking length if needed. | 8010 // Start tracking length if needed. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8474 if (needs_length_check()) { | 8058 if (needs_length_check()) { |
8475 ASSERT(guarded_list_length() != Field::kUnknownFixedLength); | 8059 ASSERT(guarded_list_length() != Field::kUnknownFixedLength); |
8476 set_guarded_list_length(Field::kNoFixedLength); | 8060 set_guarded_list_length(Field::kNoFixedLength); |
8477 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 8061 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |
8478 } | 8062 } |
8479 | 8063 |
8480 // Expected class id or nullability of the field changed. | 8064 // Expected class id or nullability of the field changed. |
8481 return true; | 8065 return true; |
8482 } | 8066 } |
8483 | 8067 |
8484 | |
8485 void Field::RecordStore(const Object& value) const { | 8068 void Field::RecordStore(const Object& value) const { |
8486 ASSERT(IsOriginal()); | 8069 ASSERT(IsOriginal()); |
8487 if (!Isolate::Current()->use_field_guards()) { | 8070 if (!Isolate::Current()->use_field_guards()) { |
8488 return; | 8071 return; |
8489 } | 8072 } |
8490 | 8073 |
8491 if (FLAG_trace_field_guards) { | 8074 if (FLAG_trace_field_guards) { |
8492 THR_Print("Store %s %s <- %s\n", ToCString(), GuardedPropertiesAsCString(), | 8075 THR_Print("Store %s %s <- %s\n", ToCString(), GuardedPropertiesAsCString(), |
8493 value.ToCString()); | 8076 value.ToCString()); |
8494 } | 8077 } |
8495 | 8078 |
8496 if (UpdateGuardedCidAndLength(value)) { | 8079 if (UpdateGuardedCidAndLength(value)) { |
8497 if (FLAG_trace_field_guards) { | 8080 if (FLAG_trace_field_guards) { |
8498 THR_Print(" => %s\n", GuardedPropertiesAsCString()); | 8081 THR_Print(" => %s\n", GuardedPropertiesAsCString()); |
8499 } | 8082 } |
8500 | 8083 |
8501 DeoptimizeDependentCode(); | 8084 DeoptimizeDependentCode(); |
8502 } | 8085 } |
8503 } | 8086 } |
8504 | 8087 |
8505 | |
8506 void Field::ForceDynamicGuardedCidAndLength() const { | 8088 void Field::ForceDynamicGuardedCidAndLength() const { |
8507 // Assume nothing about this field. | 8089 // Assume nothing about this field. |
8508 set_is_unboxing_candidate(false); | 8090 set_is_unboxing_candidate(false); |
8509 set_guarded_cid(kDynamicCid); | 8091 set_guarded_cid(kDynamicCid); |
8510 set_is_nullable(true); | 8092 set_is_nullable(true); |
8511 set_guarded_list_length(Field::kNoFixedLength); | 8093 set_guarded_list_length(Field::kNoFixedLength); |
8512 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 8094 set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |
8513 // Drop any code that relied on the above assumptions. | 8095 // Drop any code that relied on the above assumptions. |
8514 DeoptimizeDependentCode(); | 8096 DeoptimizeDependentCode(); |
8515 } | 8097 } |
8516 | 8098 |
8517 | |
8518 void LiteralToken::set_literal(const String& literal) const { | 8099 void LiteralToken::set_literal(const String& literal) const { |
8519 StorePointer(&raw_ptr()->literal_, literal.raw()); | 8100 StorePointer(&raw_ptr()->literal_, literal.raw()); |
8520 } | 8101 } |
8521 | 8102 |
8522 | |
8523 void LiteralToken::set_value(const Object& value) const { | 8103 void LiteralToken::set_value(const Object& value) const { |
8524 StorePointer(&raw_ptr()->value_, value.raw()); | 8104 StorePointer(&raw_ptr()->value_, value.raw()); |
8525 } | 8105 } |
8526 | 8106 |
8527 | |
8528 RawLiteralToken* LiteralToken::New() { | 8107 RawLiteralToken* LiteralToken::New() { |
8529 ASSERT(Object::literal_token_class() != Class::null()); | 8108 ASSERT(Object::literal_token_class() != Class::null()); |
8530 RawObject* raw = Object::Allocate(LiteralToken::kClassId, | 8109 RawObject* raw = Object::Allocate(LiteralToken::kClassId, |
8531 LiteralToken::InstanceSize(), Heap::kOld); | 8110 LiteralToken::InstanceSize(), Heap::kOld); |
8532 return reinterpret_cast<RawLiteralToken*>(raw); | 8111 return reinterpret_cast<RawLiteralToken*>(raw); |
8533 } | 8112 } |
8534 | 8113 |
8535 | |
8536 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { | 8114 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { |
8537 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); | 8115 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); |
8538 result.set_kind(kind); | 8116 result.set_kind(kind); |
8539 result.set_literal(literal); | 8117 result.set_literal(literal); |
8540 if (kind == Token::kINTEGER) { | 8118 if (kind == Token::kINTEGER) { |
8541 const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); | 8119 const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); |
8542 ASSERT(value.IsSmi() || value.IsOld()); | 8120 ASSERT(value.IsSmi() || value.IsOld()); |
8543 result.set_value(value); | 8121 result.set_value(value); |
8544 } else if (kind == Token::kDOUBLE) { | 8122 } else if (kind == Token::kDOUBLE) { |
8545 const Double& value = Double::Handle(Double::NewCanonical(literal)); | 8123 const Double& value = Double::Handle(Double::NewCanonical(literal)); |
8546 result.set_value(value); | 8124 result.set_value(value); |
8547 } else { | 8125 } else { |
8548 ASSERT(Token::NeedsLiteralToken(kind)); | 8126 ASSERT(Token::NeedsLiteralToken(kind)); |
8549 result.set_value(literal); | 8127 result.set_value(literal); |
8550 } | 8128 } |
8551 return result.raw(); | 8129 return result.raw(); |
8552 } | 8130 } |
8553 | 8131 |
8554 | |
8555 const char* LiteralToken::ToCString() const { | 8132 const char* LiteralToken::ToCString() const { |
8556 const String& token = String::Handle(literal()); | 8133 const String& token = String::Handle(literal()); |
8557 return token.ToCString(); | 8134 return token.ToCString(); |
8558 } | 8135 } |
8559 | 8136 |
8560 | |
8561 RawGrowableObjectArray* TokenStream::TokenObjects() const { | 8137 RawGrowableObjectArray* TokenStream::TokenObjects() const { |
8562 return raw_ptr()->token_objects_; | 8138 return raw_ptr()->token_objects_; |
8563 } | 8139 } |
8564 | 8140 |
8565 | |
8566 void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const { | 8141 void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const { |
8567 StorePointer(&raw_ptr()->token_objects_, value.raw()); | 8142 StorePointer(&raw_ptr()->token_objects_, value.raw()); |
8568 } | 8143 } |
8569 | 8144 |
8570 | |
8571 RawExternalTypedData* TokenStream::GetStream() const { | 8145 RawExternalTypedData* TokenStream::GetStream() const { |
8572 return raw_ptr()->stream_; | 8146 return raw_ptr()->stream_; |
8573 } | 8147 } |
8574 | 8148 |
8575 | |
8576 void TokenStream::SetStream(const ExternalTypedData& value) const { | 8149 void TokenStream::SetStream(const ExternalTypedData& value) const { |
8577 StorePointer(&raw_ptr()->stream_, value.raw()); | 8150 StorePointer(&raw_ptr()->stream_, value.raw()); |
8578 } | 8151 } |
8579 | 8152 |
8580 | |
8581 void TokenStream::DataFinalizer(void* isolate_callback_data, | 8153 void TokenStream::DataFinalizer(void* isolate_callback_data, |
8582 Dart_WeakPersistentHandle handle, | 8154 Dart_WeakPersistentHandle handle, |
8583 void* peer) { | 8155 void* peer) { |
8584 ASSERT(peer != NULL); | 8156 ASSERT(peer != NULL); |
8585 ::free(peer); | 8157 ::free(peer); |
8586 } | 8158 } |
8587 | 8159 |
8588 | |
8589 RawString* TokenStream::PrivateKey() const { | 8160 RawString* TokenStream::PrivateKey() const { |
8590 return raw_ptr()->private_key_; | 8161 return raw_ptr()->private_key_; |
8591 } | 8162 } |
8592 | 8163 |
8593 | |
8594 void TokenStream::SetPrivateKey(const String& value) const { | 8164 void TokenStream::SetPrivateKey(const String& value) const { |
8595 StorePointer(&raw_ptr()->private_key_, value.raw()); | 8165 StorePointer(&raw_ptr()->private_key_, value.raw()); |
8596 } | 8166 } |
8597 | 8167 |
8598 RawString* TokenStream::GenerateSource() const { | 8168 RawString* TokenStream::GenerateSource() const { |
8599 return GenerateSource(TokenPosition::kMinSource, TokenPosition::kMaxSource); | 8169 return GenerateSource(TokenPosition::kMinSource, TokenPosition::kMaxSource); |
8600 } | 8170 } |
8601 | 8171 |
8602 RawString* TokenStream::GenerateSource(TokenPosition start_pos, | 8172 RawString* TokenStream::GenerateSource(TokenPosition start_pos, |
8603 TokenPosition end_pos) const { | 8173 TokenPosition end_pos) const { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8777 } | 8347 } |
8778 | 8348 |
8779 // Setup for next iteration. | 8349 // Setup for next iteration. |
8780 prev = curr; | 8350 prev = curr; |
8781 curr = next; | 8351 curr = next; |
8782 } | 8352 } |
8783 const Array& source = Array::Handle(Array::MakeFixedLength(literals)); | 8353 const Array& source = Array::Handle(Array::MakeFixedLength(literals)); |
8784 return String::ConcatAll(source); | 8354 return String::ConcatAll(source); |
8785 } | 8355 } |
8786 | 8356 |
8787 | |
8788 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const { | 8357 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const { |
8789 Zone* zone = Thread::Current()->zone(); | 8358 Zone* zone = Thread::Current()->zone(); |
8790 Iterator iterator(zone, *this, TokenPosition::kMinSource, | 8359 Iterator iterator(zone, *this, TokenPosition::kMinSource, |
8791 Iterator::kAllTokens); | 8360 Iterator::kAllTokens); |
8792 intptr_t src_pos = 0; | 8361 intptr_t src_pos = 0; |
8793 Token::Kind kind = iterator.CurrentTokenKind(); | 8362 Token::Kind kind = iterator.CurrentTokenKind(); |
8794 while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) { | 8363 while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) { |
8795 iterator.Advance(); | 8364 iterator.Advance(); |
8796 kind = iterator.CurrentTokenKind(); | 8365 kind = iterator.CurrentTokenKind(); |
8797 src_pos++; | 8366 src_pos++; |
8798 } | 8367 } |
8799 return src_pos; | 8368 return src_pos; |
8800 } | 8369 } |
8801 | 8370 |
8802 | |
8803 RawTokenStream* TokenStream::New() { | 8371 RawTokenStream* TokenStream::New() { |
8804 ASSERT(Object::token_stream_class() != Class::null()); | 8372 ASSERT(Object::token_stream_class() != Class::null()); |
8805 RawObject* raw = Object::Allocate(TokenStream::kClassId, | 8373 RawObject* raw = Object::Allocate(TokenStream::kClassId, |
8806 TokenStream::InstanceSize(), Heap::kOld); | 8374 TokenStream::InstanceSize(), Heap::kOld); |
8807 return reinterpret_cast<RawTokenStream*>(raw); | 8375 return reinterpret_cast<RawTokenStream*>(raw); |
8808 } | 8376 } |
8809 | 8377 |
8810 | |
8811 RawTokenStream* TokenStream::New(intptr_t len) { | 8378 RawTokenStream* TokenStream::New(intptr_t len) { |
8812 if (len < 0 || len > kMaxElements) { | 8379 if (len < 0 || len > kMaxElements) { |
8813 // This should be caught before we reach here. | 8380 // This should be caught before we reach here. |
8814 FATAL1("Fatal error in TokenStream::New: invalid len %" Pd "\n", len); | 8381 FATAL1("Fatal error in TokenStream::New: invalid len %" Pd "\n", len); |
8815 } | 8382 } |
8816 uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len)); | 8383 uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len)); |
8817 ASSERT(data != NULL); | 8384 ASSERT(data != NULL); |
8818 Zone* zone = Thread::Current()->zone(); | 8385 Zone* zone = Thread::Current()->zone(); |
8819 const ExternalTypedData& stream = ExternalTypedData::Handle( | 8386 const ExternalTypedData& stream = ExternalTypedData::Handle( |
8820 zone, ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, len, | 8387 zone, ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, len, |
8821 Heap::kOld)); | 8388 Heap::kOld)); |
8822 stream.AddFinalizer(data, DataFinalizer, len); | 8389 stream.AddFinalizer(data, DataFinalizer, len); |
8823 const TokenStream& result = TokenStream::Handle(zone, TokenStream::New()); | 8390 const TokenStream& result = TokenStream::Handle(zone, TokenStream::New()); |
8824 result.SetStream(stream); | 8391 result.SetStream(stream); |
8825 return result.raw(); | 8392 return result.raw(); |
8826 } | 8393 } |
8827 | 8394 |
8828 | |
8829 // CompressedTokenMap maps String and LiteralToken keys to Smi values. | 8395 // CompressedTokenMap maps String and LiteralToken keys to Smi values. |
8830 // It also supports lookup by TokenDescriptor. | 8396 // It also supports lookup by TokenDescriptor. |
8831 class CompressedTokenTraits { | 8397 class CompressedTokenTraits { |
8832 public: | 8398 public: |
8833 static const char* Name() { return "CompressedTokenTraits"; } | 8399 static const char* Name() { return "CompressedTokenTraits"; } |
8834 static bool ReportStats() { return false; } | 8400 static bool ReportStats() { return false; } |
8835 | 8401 |
8836 static bool IsMatch(const Scanner::TokenDescriptor& descriptor, | 8402 static bool IsMatch(const Scanner::TokenDescriptor& descriptor, |
8837 const Object& key) { | 8403 const Object& key) { |
8838 if (!key.IsLiteralToken()) { | 8404 if (!key.IsLiteralToken()) { |
(...skipping 16 matching lines...) Expand all Loading... |
8855 static uword Hash(const Object& key) { | 8421 static uword Hash(const Object& key) { |
8856 if (key.IsLiteralToken()) { | 8422 if (key.IsLiteralToken()) { |
8857 return String::HashRawSymbol(LiteralToken::Cast(key).literal()); | 8423 return String::HashRawSymbol(LiteralToken::Cast(key).literal()); |
8858 } else { | 8424 } else { |
8859 return String::Cast(key).Hash(); | 8425 return String::Cast(key).Hash(); |
8860 } | 8426 } |
8861 } | 8427 } |
8862 }; | 8428 }; |
8863 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap; | 8429 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap; |
8864 | 8430 |
8865 | |
8866 // Helper class for creation of compressed token stream data. | 8431 // Helper class for creation of compressed token stream data. |
8867 class CompressedTokenStreamData : public Scanner::TokenCollector { | 8432 class CompressedTokenStreamData : public Scanner::TokenCollector { |
8868 public: | 8433 public: |
8869 static const intptr_t kInitialBufferSize = 16 * KB; | 8434 static const intptr_t kInitialBufferSize = 16 * KB; |
8870 static const bool kPrintTokenObjects = false; | 8435 static const bool kPrintTokenObjects = false; |
8871 | 8436 |
8872 CompressedTokenStreamData(const GrowableObjectArray& ta, | 8437 CompressedTokenStreamData(const GrowableObjectArray& ta, |
8873 CompressedTokenMap* map) | 8438 CompressedTokenMap* map) |
8874 : buffer_(NULL), | 8439 : buffer_(NULL), |
8875 stream_(&buffer_, Reallocate, kInitialBufferSize), | 8440 stream_(&buffer_, Reallocate, kInitialBufferSize), |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8964 WriteStream stream_; | 8529 WriteStream stream_; |
8965 const GrowableObjectArray& token_objects_; | 8530 const GrowableObjectArray& token_objects_; |
8966 CompressedTokenMap* tokens_; | 8531 CompressedTokenMap* tokens_; |
8967 Object& value_; | 8532 Object& value_; |
8968 Smi& fresh_index_smi_; | 8533 Smi& fresh_index_smi_; |
8969 intptr_t num_tokens_collected_; | 8534 intptr_t num_tokens_collected_; |
8970 | 8535 |
8971 DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); | 8536 DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); |
8972 }; | 8537 }; |
8973 | 8538 |
8974 | |
8975 RawTokenStream* TokenStream::New(const String& source, | 8539 RawTokenStream* TokenStream::New(const String& source, |
8976 const String& private_key, | 8540 const String& private_key, |
8977 bool use_shared_tokens) { | 8541 bool use_shared_tokens) { |
8978 Thread* thread = Thread::Current(); | 8542 Thread* thread = Thread::Current(); |
8979 Zone* zone = thread->zone(); | 8543 Zone* zone = thread->zone(); |
8980 | 8544 |
8981 GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone); | 8545 GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone); |
8982 Array& token_objects_map = Array::Handle(zone); | 8546 Array& token_objects_map = Array::Handle(zone); |
8983 if (use_shared_tokens) { | 8547 if (use_shared_tokens) { |
8984 // Use the shared token objects array in the object store. Allocate | 8548 // Use the shared token objects array in the object store. Allocate |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9018 result.SetTokenObjects(token_objects); | 8582 result.SetTokenObjects(token_objects); |
9019 } | 8583 } |
9020 | 8584 |
9021 token_objects_map = map.Release().raw(); | 8585 token_objects_map = map.Release().raw(); |
9022 if (use_shared_tokens) { | 8586 if (use_shared_tokens) { |
9023 thread->isolate()->object_store()->set_token_objects_map(token_objects_map); | 8587 thread->isolate()->object_store()->set_token_objects_map(token_objects_map); |
9024 } | 8588 } |
9025 return result.raw(); | 8589 return result.raw(); |
9026 } | 8590 } |
9027 | 8591 |
9028 | |
9029 void TokenStream::OpenSharedTokenList(Isolate* isolate) { | 8592 void TokenStream::OpenSharedTokenList(Isolate* isolate) { |
9030 const int kInitialSharedCapacity = 5 * 1024; | 8593 const int kInitialSharedCapacity = 5 * 1024; |
9031 ObjectStore* store = isolate->object_store(); | 8594 ObjectStore* store = isolate->object_store(); |
9032 ASSERT(store->token_objects() == GrowableObjectArray::null()); | 8595 ASSERT(store->token_objects() == GrowableObjectArray::null()); |
9033 const GrowableObjectArray& token_objects = GrowableObjectArray::Handle( | 8596 const GrowableObjectArray& token_objects = GrowableObjectArray::Handle( |
9034 GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld)); | 8597 GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld)); |
9035 store->set_token_objects(token_objects); | 8598 store->set_token_objects(token_objects); |
9036 const Array& token_objects_map = Array::Handle( | 8599 const Array& token_objects_map = Array::Handle( |
9037 HashTables::New<CompressedTokenMap>(kInitialSharedCapacity, Heap::kOld)); | 8600 HashTables::New<CompressedTokenMap>(kInitialSharedCapacity, Heap::kOld)); |
9038 store->set_token_objects_map(token_objects_map); | 8601 store->set_token_objects_map(token_objects_map); |
9039 } | 8602 } |
9040 | 8603 |
9041 | |
9042 void TokenStream::CloseSharedTokenList(Isolate* isolate) { | 8604 void TokenStream::CloseSharedTokenList(Isolate* isolate) { |
9043 isolate->object_store()->set_token_objects(GrowableObjectArray::Handle()); | 8605 isolate->object_store()->set_token_objects(GrowableObjectArray::Handle()); |
9044 isolate->object_store()->set_token_objects_map(Array::null_array()); | 8606 isolate->object_store()->set_token_objects_map(Array::null_array()); |
9045 } | 8607 } |
9046 | 8608 |
9047 | |
9048 const char* TokenStream::ToCString() const { | 8609 const char* TokenStream::ToCString() const { |
9049 return "TokenStream"; | 8610 return "TokenStream"; |
9050 } | 8611 } |
9051 | 8612 |
9052 | |
9053 TokenStream::Iterator::Iterator(Zone* zone, | 8613 TokenStream::Iterator::Iterator(Zone* zone, |
9054 const TokenStream& tokens, | 8614 const TokenStream& tokens, |
9055 TokenPosition token_pos, | 8615 TokenPosition token_pos, |
9056 Iterator::StreamType stream_type) | 8616 Iterator::StreamType stream_type) |
9057 : tokens_(TokenStream::Handle(zone, tokens.raw())), | 8617 : tokens_(TokenStream::Handle(zone, tokens.raw())), |
9058 data_(ExternalTypedData::Handle(zone, tokens.GetStream())), | 8618 data_(ExternalTypedData::Handle(zone, tokens.GetStream())), |
9059 stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()), | 8619 stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()), |
9060 token_objects_(Array::Handle( | 8620 token_objects_(Array::Handle( |
9061 zone, | 8621 zone, |
9062 GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())), | 8622 GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())), |
9063 obj_(Object::Handle(zone)), | 8623 obj_(Object::Handle(zone)), |
9064 cur_token_pos_(token_pos.Pos()), | 8624 cur_token_pos_(token_pos.Pos()), |
9065 cur_token_kind_(Token::kILLEGAL), | 8625 cur_token_kind_(Token::kILLEGAL), |
9066 cur_token_obj_index_(-1), | 8626 cur_token_obj_index_(-1), |
9067 stream_type_(stream_type) { | 8627 stream_type_(stream_type) { |
9068 ASSERT(token_pos != TokenPosition::kNoSource); | 8628 ASSERT(token_pos != TokenPosition::kNoSource); |
9069 if (token_pos.IsReal()) { | 8629 if (token_pos.IsReal()) { |
9070 SetCurrentPosition(token_pos); | 8630 SetCurrentPosition(token_pos); |
9071 } | 8631 } |
9072 } | 8632 } |
9073 | 8633 |
9074 | |
9075 void TokenStream::Iterator::SetStream(const TokenStream& tokens, | 8634 void TokenStream::Iterator::SetStream(const TokenStream& tokens, |
9076 TokenPosition token_pos) { | 8635 TokenPosition token_pos) { |
9077 tokens_ = tokens.raw(); | 8636 tokens_ = tokens.raw(); |
9078 data_ = tokens.GetStream(); | 8637 data_ = tokens.GetStream(); |
9079 stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), | 8638 stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), |
9080 data_.Length()); | 8639 data_.Length()); |
9081 token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data(); | 8640 token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data(); |
9082 obj_ = Object::null(); | 8641 obj_ = Object::null(); |
9083 cur_token_pos_ = token_pos.Pos(); | 8642 cur_token_pos_ = token_pos.Pos(); |
9084 cur_token_kind_ = Token::kILLEGAL; | 8643 cur_token_kind_ = Token::kILLEGAL; |
9085 cur_token_obj_index_ = -1; | 8644 cur_token_obj_index_ = -1; |
9086 SetCurrentPosition(token_pos); | 8645 SetCurrentPosition(token_pos); |
9087 } | 8646 } |
9088 | 8647 |
9089 | |
9090 bool TokenStream::Iterator::IsValid() const { | 8648 bool TokenStream::Iterator::IsValid() const { |
9091 return !tokens_.IsNull(); | 8649 return !tokens_.IsNull(); |
9092 } | 8650 } |
9093 | 8651 |
9094 | |
9095 Token::Kind TokenStream::Iterator::LookaheadTokenKind(intptr_t num_tokens) { | 8652 Token::Kind TokenStream::Iterator::LookaheadTokenKind(intptr_t num_tokens) { |
9096 intptr_t saved_position = stream_.Position(); | 8653 intptr_t saved_position = stream_.Position(); |
9097 Token::Kind kind = Token::kILLEGAL; | 8654 Token::Kind kind = Token::kILLEGAL; |
9098 intptr_t value = -1; | 8655 intptr_t value = -1; |
9099 intptr_t count = 0; | 8656 intptr_t count = 0; |
9100 while (count < num_tokens && value != Token::kEOS) { | 8657 while (count < num_tokens && value != Token::kEOS) { |
9101 value = ReadToken(); | 8658 value = ReadToken(); |
9102 if ((stream_type_ == kAllTokens) || | 8659 if ((stream_type_ == kAllTokens) || |
9103 (static_cast<Token::Kind>(value) != Token::kNEWLINE)) { | 8660 (static_cast<Token::Kind>(value) != Token::kNEWLINE)) { |
9104 count += 1; | 8661 count += 1; |
9105 } | 8662 } |
9106 } | 8663 } |
9107 if (value < Token::kNumTokens) { | 8664 if (value < Token::kNumTokens) { |
9108 kind = static_cast<Token::Kind>(value); | 8665 kind = static_cast<Token::Kind>(value); |
9109 } else { | 8666 } else { |
9110 value = value - Token::kNumTokens; | 8667 value = value - Token::kNumTokens; |
9111 obj_ = token_objects_.At(value); | 8668 obj_ = token_objects_.At(value); |
9112 if (obj_.IsLiteralToken()) { | 8669 if (obj_.IsLiteralToken()) { |
9113 const LiteralToken& literal_token = LiteralToken::Cast(obj_); | 8670 const LiteralToken& literal_token = LiteralToken::Cast(obj_); |
9114 kind = literal_token.kind(); | 8671 kind = literal_token.kind(); |
9115 } else { | 8672 } else { |
9116 ASSERT(obj_.IsString()); // Must be an identifier. | 8673 ASSERT(obj_.IsString()); // Must be an identifier. |
9117 kind = Token::kIDENT; | 8674 kind = Token::kIDENT; |
9118 } | 8675 } |
9119 } | 8676 } |
9120 stream_.SetPosition(saved_position); | 8677 stream_.SetPosition(saved_position); |
9121 return kind; | 8678 return kind; |
9122 } | 8679 } |
9123 | 8680 |
9124 | |
9125 TokenPosition TokenStream::Iterator::CurrentPosition() const { | 8681 TokenPosition TokenStream::Iterator::CurrentPosition() const { |
9126 return TokenPosition(cur_token_pos_); | 8682 return TokenPosition(cur_token_pos_); |
9127 } | 8683 } |
9128 | 8684 |
9129 | |
9130 void TokenStream::Iterator::SetCurrentPosition(TokenPosition token_pos) { | 8685 void TokenStream::Iterator::SetCurrentPosition(TokenPosition token_pos) { |
9131 stream_.SetPosition(token_pos.value()); | 8686 stream_.SetPosition(token_pos.value()); |
9132 Advance(); | 8687 Advance(); |
9133 } | 8688 } |
9134 | 8689 |
9135 | |
9136 void TokenStream::Iterator::Advance() { | 8690 void TokenStream::Iterator::Advance() { |
9137 intptr_t value; | 8691 intptr_t value; |
9138 do { | 8692 do { |
9139 cur_token_pos_ = stream_.Position(); | 8693 cur_token_pos_ = stream_.Position(); |
9140 value = ReadToken(); | 8694 value = ReadToken(); |
9141 } while ((stream_type_ == kNoNewlines) && | 8695 } while ((stream_type_ == kNoNewlines) && |
9142 (static_cast<Token::Kind>(value) == Token::kNEWLINE)); | 8696 (static_cast<Token::Kind>(value) == Token::kNEWLINE)); |
9143 if (value < Token::kNumTokens) { | 8697 if (value < Token::kNumTokens) { |
9144 cur_token_kind_ = static_cast<Token::Kind>(value); | 8698 cur_token_kind_ = static_cast<Token::Kind>(value); |
9145 cur_token_obj_index_ = -1; | 8699 cur_token_obj_index_ = -1; |
9146 return; | 8700 return; |
9147 } | 8701 } |
9148 cur_token_obj_index_ = value - Token::kNumTokens; | 8702 cur_token_obj_index_ = value - Token::kNumTokens; |
9149 obj_ = token_objects_.At(cur_token_obj_index_); | 8703 obj_ = token_objects_.At(cur_token_obj_index_); |
9150 if (obj_.IsLiteralToken()) { | 8704 if (obj_.IsLiteralToken()) { |
9151 const LiteralToken& literal_token = LiteralToken::Cast(obj_); | 8705 const LiteralToken& literal_token = LiteralToken::Cast(obj_); |
9152 cur_token_kind_ = literal_token.kind(); | 8706 cur_token_kind_ = literal_token.kind(); |
9153 return; | 8707 return; |
9154 } | 8708 } |
9155 ASSERT(obj_.IsString()); // Must be an identifier. | 8709 ASSERT(obj_.IsString()); // Must be an identifier. |
9156 cur_token_kind_ = Token::kIDENT; | 8710 cur_token_kind_ = Token::kIDENT; |
9157 } | 8711 } |
9158 | 8712 |
9159 | |
9160 RawObject* TokenStream::Iterator::CurrentToken() const { | 8713 RawObject* TokenStream::Iterator::CurrentToken() const { |
9161 if (cur_token_obj_index_ != -1) { | 8714 if (cur_token_obj_index_ != -1) { |
9162 return token_objects_.At(cur_token_obj_index_); | 8715 return token_objects_.At(cur_token_obj_index_); |
9163 } else { | 8716 } else { |
9164 return Smi::New(cur_token_kind_); | 8717 return Smi::New(cur_token_kind_); |
9165 } | 8718 } |
9166 } | 8719 } |
9167 | 8720 |
9168 | |
9169 RawString* TokenStream::Iterator::CurrentLiteral() const { | 8721 RawString* TokenStream::Iterator::CurrentLiteral() const { |
9170 obj_ = CurrentToken(); | 8722 obj_ = CurrentToken(); |
9171 return MakeLiteralToken(obj_); | 8723 return MakeLiteralToken(obj_); |
9172 } | 8724 } |
9173 | 8725 |
9174 | |
9175 RawString* TokenStream::Iterator::MakeLiteralToken(const Object& obj) const { | 8726 RawString* TokenStream::Iterator::MakeLiteralToken(const Object& obj) const { |
9176 if (obj.IsString()) { | 8727 if (obj.IsString()) { |
9177 return reinterpret_cast<RawString*>(obj.raw()); | 8728 return reinterpret_cast<RawString*>(obj.raw()); |
9178 } else if (obj.IsSmi()) { | 8729 } else if (obj.IsSmi()) { |
9179 Token::Kind kind = static_cast<Token::Kind>( | 8730 Token::Kind kind = static_cast<Token::Kind>( |
9180 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); | 8731 Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); |
9181 ASSERT(kind < Token::kNumTokens); | 8732 ASSERT(kind < Token::kNumTokens); |
9182 return Symbols::Token(kind).raw(); | 8733 return Symbols::Token(kind).raw(); |
9183 } else { | 8734 } else { |
9184 ASSERT(obj.IsLiteralToken()); // Must be a literal token. | 8735 ASSERT(obj.IsLiteralToken()); // Must be a literal token. |
9185 const LiteralToken& literal_token = LiteralToken::Cast(obj); | 8736 const LiteralToken& literal_token = LiteralToken::Cast(obj); |
9186 return literal_token.literal(); | 8737 return literal_token.literal(); |
9187 } | 8738 } |
9188 } | 8739 } |
9189 | 8740 |
9190 | |
9191 bool Script::HasSource() const { | 8741 bool Script::HasSource() const { |
9192 #if !defined(DART_PRECOMPILED_RUNTIME) | 8742 #if !defined(DART_PRECOMPILED_RUNTIME) |
9193 return kind() == RawScript::kKernelTag || | 8743 return kind() == RawScript::kKernelTag || |
9194 raw_ptr()->source_ != String::null(); | 8744 raw_ptr()->source_ != String::null(); |
9195 #else // !defined(DART_PRECOMPILED_RUNTIME) | 8745 #else // !defined(DART_PRECOMPILED_RUNTIME) |
9196 return raw_ptr()->source_ != String::null(); | 8746 return raw_ptr()->source_ != String::null(); |
9197 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 8747 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9198 } | 8748 } |
9199 | 8749 |
9200 | |
9201 RawString* Script::Source() const { | 8750 RawString* Script::Source() const { |
9202 String& source = String::Handle(raw_ptr()->source_); | 8751 String& source = String::Handle(raw_ptr()->source_); |
9203 if (source.IsNull()) { | 8752 if (source.IsNull()) { |
9204 return GenerateSource(); | 8753 return GenerateSource(); |
9205 } | 8754 } |
9206 return raw_ptr()->source_; | 8755 return raw_ptr()->source_; |
9207 } | 8756 } |
9208 | 8757 |
9209 | |
9210 RawString* Script::GenerateSource() const { | 8758 RawString* Script::GenerateSource() const { |
9211 #if !defined(DART_PRECOMPILED_RUNTIME) | 8759 #if !defined(DART_PRECOMPILED_RUNTIME) |
9212 if (kind() == RawScript::kKernelTag) { | 8760 if (kind() == RawScript::kKernelTag) { |
9213 String& source = String::Handle(raw_ptr()->source_); | 8761 String& source = String::Handle(raw_ptr()->source_); |
9214 if (source.IsNull()) { | 8762 if (source.IsNull()) { |
9215 // This is created lazily. Now we need it. | 8763 // This is created lazily. Now we need it. |
9216 set_source(kernel::GetSourceFor(*this)); | 8764 set_source(kernel::GetSourceFor(*this)); |
9217 } | 8765 } |
9218 return raw_ptr()->source_; | 8766 return raw_ptr()->source_; |
9219 } | 8767 } |
9220 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 8768 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9221 | 8769 |
9222 const TokenStream& token_stream = TokenStream::Handle(tokens()); | 8770 const TokenStream& token_stream = TokenStream::Handle(tokens()); |
9223 if (token_stream.IsNull()) { | 8771 if (token_stream.IsNull()) { |
9224 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 8772 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
9225 return String::null(); | 8773 return String::null(); |
9226 } | 8774 } |
9227 return token_stream.GenerateSource(); | 8775 return token_stream.GenerateSource(); |
9228 } | 8776 } |
9229 | 8777 |
9230 | |
9231 void Script::set_compile_time_constants(const Array& value) const { | 8778 void Script::set_compile_time_constants(const Array& value) const { |
9232 StorePointer(&raw_ptr()->compile_time_constants_, value.raw()); | 8779 StorePointer(&raw_ptr()->compile_time_constants_, value.raw()); |
9233 } | 8780 } |
9234 | 8781 |
9235 | |
9236 void Script::set_kernel_data(const uint8_t* kernel_data) const { | 8782 void Script::set_kernel_data(const uint8_t* kernel_data) const { |
9237 StoreNonPointer(&raw_ptr()->kernel_data_, kernel_data); | 8783 StoreNonPointer(&raw_ptr()->kernel_data_, kernel_data); |
9238 } | 8784 } |
9239 | 8785 |
9240 | |
9241 void Script::set_kernel_data_size(const intptr_t kernel_data_size) const { | 8786 void Script::set_kernel_data_size(const intptr_t kernel_data_size) const { |
9242 StoreNonPointer(&raw_ptr()->kernel_data_size_, kernel_data_size); | 8787 StoreNonPointer(&raw_ptr()->kernel_data_size_, kernel_data_size); |
9243 } | 8788 } |
9244 | 8789 |
9245 | |
9246 void Script::set_kernel_script_index(const intptr_t kernel_script_index) const { | 8790 void Script::set_kernel_script_index(const intptr_t kernel_script_index) const { |
9247 StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index); | 8791 StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index); |
9248 } | 8792 } |
9249 | 8793 |
9250 | |
9251 void Script::set_kernel_string_offsets(const TypedData& offsets) const { | 8794 void Script::set_kernel_string_offsets(const TypedData& offsets) const { |
9252 StorePointer(&raw_ptr()->kernel_string_offsets_, offsets.raw()); | 8795 StorePointer(&raw_ptr()->kernel_string_offsets_, offsets.raw()); |
9253 } | 8796 } |
9254 | 8797 |
9255 | |
9256 void Script::set_kernel_string_data(const TypedData& data) const { | 8798 void Script::set_kernel_string_data(const TypedData& data) const { |
9257 StorePointer(&raw_ptr()->kernel_string_data_, data.raw()); | 8799 StorePointer(&raw_ptr()->kernel_string_data_, data.raw()); |
9258 } | 8800 } |
9259 | 8801 |
9260 | |
9261 void Script::set_kernel_canonical_names(const TypedData& names) const { | 8802 void Script::set_kernel_canonical_names(const TypedData& names) const { |
9262 StorePointer(&raw_ptr()->kernel_canonical_names_, names.raw()); | 8803 StorePointer(&raw_ptr()->kernel_canonical_names_, names.raw()); |
9263 } | 8804 } |
9264 | 8805 |
9265 | |
9266 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { | 8806 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { |
9267 Zone* zone = Thread::Current()->zone(); | 8807 Zone* zone = Thread::Current()->zone(); |
9268 const GrowableObjectArray& info = | 8808 const GrowableObjectArray& info = |
9269 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 8809 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
9270 const String& source = String::Handle(zone, Source()); | 8810 const String& source = String::Handle(zone, Source()); |
9271 const String& key = Symbols::Empty(); | 8811 const String& key = Symbols::Empty(); |
9272 const Object& line_separator = Object::Handle(zone); | 8812 const Object& line_separator = Object::Handle(zone); |
9273 Smi& value = Smi::Handle(zone); | 8813 Smi& value = Smi::Handle(zone); |
9274 | 8814 |
9275 if (kind() == RawScript::kKernelTag) { | 8815 if (kind() == RawScript::kKernelTag) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9385 column += col_offset(); | 8925 column += col_offset(); |
9386 } | 8926 } |
9387 value = Smi::New(column); | 8927 value = Smi::New(column); |
9388 info.Add(value); | 8928 info.Add(value); |
9389 tkit.Advance(); | 8929 tkit.Advance(); |
9390 s.Scan(); | 8930 s.Scan(); |
9391 } | 8931 } |
9392 return info.raw(); | 8932 return info.raw(); |
9393 } | 8933 } |
9394 | 8934 |
9395 | |
9396 const char* Script::GetKindAsCString() const { | 8935 const char* Script::GetKindAsCString() const { |
9397 switch (kind()) { | 8936 switch (kind()) { |
9398 case RawScript::kScriptTag: | 8937 case RawScript::kScriptTag: |
9399 return "script"; | 8938 return "script"; |
9400 case RawScript::kLibraryTag: | 8939 case RawScript::kLibraryTag: |
9401 return "library"; | 8940 return "library"; |
9402 case RawScript::kSourceTag: | 8941 case RawScript::kSourceTag: |
9403 return "source"; | 8942 return "source"; |
9404 case RawScript::kPatchTag: | 8943 case RawScript::kPatchTag: |
9405 return "patch"; | 8944 return "patch"; |
9406 case RawScript::kEvaluateTag: | 8945 case RawScript::kEvaluateTag: |
9407 return "evaluate"; | 8946 return "evaluate"; |
9408 case RawScript::kKernelTag: | 8947 case RawScript::kKernelTag: |
9409 return "kernel"; | 8948 return "kernel"; |
9410 default: | 8949 default: |
9411 UNIMPLEMENTED(); | 8950 UNIMPLEMENTED(); |
9412 } | 8951 } |
9413 UNREACHABLE(); | 8952 UNREACHABLE(); |
9414 return NULL; | 8953 return NULL; |
9415 } | 8954 } |
9416 | 8955 |
9417 | |
9418 void Script::set_url(const String& value) const { | 8956 void Script::set_url(const String& value) const { |
9419 StorePointer(&raw_ptr()->url_, value.raw()); | 8957 StorePointer(&raw_ptr()->url_, value.raw()); |
9420 } | 8958 } |
9421 | 8959 |
9422 | |
9423 void Script::set_resolved_url(const String& value) const { | 8960 void Script::set_resolved_url(const String& value) const { |
9424 StorePointer(&raw_ptr()->resolved_url_, value.raw()); | 8961 StorePointer(&raw_ptr()->resolved_url_, value.raw()); |
9425 } | 8962 } |
9426 | 8963 |
9427 | |
9428 void Script::set_source(const String& value) const { | 8964 void Script::set_source(const String& value) const { |
9429 StorePointer(&raw_ptr()->source_, value.raw()); | 8965 StorePointer(&raw_ptr()->source_, value.raw()); |
9430 } | 8966 } |
9431 | 8967 |
9432 void Script::set_line_starts(const Array& value) const { | 8968 void Script::set_line_starts(const Array& value) const { |
9433 StorePointer(&raw_ptr()->line_starts_, value.raw()); | 8969 StorePointer(&raw_ptr()->line_starts_, value.raw()); |
9434 } | 8970 } |
9435 | 8971 |
9436 | |
9437 void Script::set_debug_positions(const Array& value) const { | 8972 void Script::set_debug_positions(const Array& value) const { |
9438 StorePointer(&raw_ptr()->debug_positions_, value.raw()); | 8973 StorePointer(&raw_ptr()->debug_positions_, value.raw()); |
9439 } | 8974 } |
9440 | 8975 |
9441 void Script::set_yield_positions(const Array& value) const { | 8976 void Script::set_yield_positions(const Array& value) const { |
9442 StorePointer(&raw_ptr()->yield_positions_, value.raw()); | 8977 StorePointer(&raw_ptr()->yield_positions_, value.raw()); |
9443 } | 8978 } |
9444 | 8979 |
9445 RawArray* Script::yield_positions() const { | 8980 RawArray* Script::yield_positions() const { |
9446 #if !defined(DART_PRECOMPILED_RUNTIME) | 8981 #if !defined(DART_PRECOMPILED_RUNTIME) |
9447 Array& yields = Array::Handle(raw_ptr()->yield_positions_); | 8982 Array& yields = Array::Handle(raw_ptr()->yield_positions_); |
9448 if (yields.IsNull() && kind() == RawScript::kKernelTag) { | 8983 if (yields.IsNull() && kind() == RawScript::kKernelTag) { |
9449 // This is created lazily. Now we need it. | 8984 // This is created lazily. Now we need it. |
9450 kernel::CollectTokenPositionsFor(*this); | 8985 kernel::CollectTokenPositionsFor(*this); |
9451 } | 8986 } |
9452 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 8987 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9453 return raw_ptr()->yield_positions_; | 8988 return raw_ptr()->yield_positions_; |
9454 } | 8989 } |
9455 | 8990 |
9456 | |
9457 RawArray* Script::line_starts() const { | 8991 RawArray* Script::line_starts() const { |
9458 #if !defined(DART_PRECOMPILED_RUNTIME) | 8992 #if !defined(DART_PRECOMPILED_RUNTIME) |
9459 const Array& line_starts_array = Array::Handle(raw_ptr()->line_starts_); | 8993 const Array& line_starts_array = Array::Handle(raw_ptr()->line_starts_); |
9460 if (line_starts_array.IsNull() && kind() == RawScript::kKernelTag) { | 8994 if (line_starts_array.IsNull() && kind() == RawScript::kKernelTag) { |
9461 // This is created lazily. Now we need it. | 8995 // This is created lazily. Now we need it. |
9462 set_line_starts(kernel::GetLineStartsFor(*this)); | 8996 set_line_starts(kernel::GetLineStartsFor(*this)); |
9463 } | 8997 } |
9464 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 8998 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9465 return raw_ptr()->line_starts_; | 8999 return raw_ptr()->line_starts_; |
9466 } | 9000 } |
9467 | 9001 |
9468 | |
9469 RawArray* Script::debug_positions() const { | 9002 RawArray* Script::debug_positions() const { |
9470 #if !defined(DART_PRECOMPILED_RUNTIME) | 9003 #if !defined(DART_PRECOMPILED_RUNTIME) |
9471 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); | 9004 Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); |
9472 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { | 9005 if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { |
9473 // This is created lazily. Now we need it. | 9006 // This is created lazily. Now we need it. |
9474 kernel::CollectTokenPositionsFor(*this); | 9007 kernel::CollectTokenPositionsFor(*this); |
9475 } | 9008 } |
9476 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 9009 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
9477 return raw_ptr()->debug_positions_; | 9010 return raw_ptr()->debug_positions_; |
9478 } | 9011 } |
9479 | 9012 |
9480 void Script::set_kind(RawScript::Kind value) const { | 9013 void Script::set_kind(RawScript::Kind value) const { |
9481 StoreNonPointer(&raw_ptr()->kind_, value); | 9014 StoreNonPointer(&raw_ptr()->kind_, value); |
9482 } | 9015 } |
9483 | 9016 |
9484 | |
9485 void Script::set_load_timestamp(int64_t value) const { | 9017 void Script::set_load_timestamp(int64_t value) const { |
9486 StoreNonPointer(&raw_ptr()->load_timestamp_, value); | 9018 StoreNonPointer(&raw_ptr()->load_timestamp_, value); |
9487 } | 9019 } |
9488 | 9020 |
9489 | |
9490 void Script::set_tokens(const TokenStream& value) const { | 9021 void Script::set_tokens(const TokenStream& value) const { |
9491 StorePointer(&raw_ptr()->tokens_, value.raw()); | 9022 StorePointer(&raw_ptr()->tokens_, value.raw()); |
9492 } | 9023 } |
9493 | 9024 |
9494 | |
9495 void Script::Tokenize(const String& private_key, bool use_shared_tokens) const { | 9025 void Script::Tokenize(const String& private_key, bool use_shared_tokens) const { |
9496 if (kind() == RawScript::kKernelTag) { | 9026 if (kind() == RawScript::kKernelTag) { |
9497 return; | 9027 return; |
9498 } | 9028 } |
9499 | 9029 |
9500 Thread* thread = Thread::Current(); | 9030 Thread* thread = Thread::Current(); |
9501 Zone* zone = thread->zone(); | 9031 Zone* zone = thread->zone(); |
9502 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); | 9032 const TokenStream& tkns = TokenStream::Handle(zone, tokens()); |
9503 if (!tkns.IsNull()) { | 9033 if (!tkns.IsNull()) { |
9504 // Already tokenized. | 9034 // Already tokenized. |
9505 return; | 9035 return; |
9506 } | 9036 } |
9507 // Get the source, scan and allocate the token stream. | 9037 // Get the source, scan and allocate the token stream. |
9508 VMTagScope tagScope(thread, VMTag::kCompileScannerTagId); | 9038 VMTagScope tagScope(thread, VMTag::kCompileScannerTagId); |
9509 CSTAT_TIMER_SCOPE(thread, scanner_timer); | 9039 CSTAT_TIMER_SCOPE(thread, scanner_timer); |
9510 const String& src = String::Handle(zone, Source()); | 9040 const String& src = String::Handle(zone, Source()); |
9511 const TokenStream& ts = TokenStream::Handle( | 9041 const TokenStream& ts = TokenStream::Handle( |
9512 zone, TokenStream::New(src, private_key, use_shared_tokens)); | 9042 zone, TokenStream::New(src, private_key, use_shared_tokens)); |
9513 set_tokens(ts); | 9043 set_tokens(ts); |
9514 INC_STAT(thread, src_length, src.Length()); | 9044 INC_STAT(thread, src_length, src.Length()); |
9515 } | 9045 } |
9516 | 9046 |
9517 | |
9518 void Script::SetLocationOffset(intptr_t line_offset, | 9047 void Script::SetLocationOffset(intptr_t line_offset, |
9519 intptr_t col_offset) const { | 9048 intptr_t col_offset) const { |
9520 ASSERT(line_offset >= 0); | 9049 ASSERT(line_offset >= 0); |
9521 ASSERT(col_offset >= 0); | 9050 ASSERT(col_offset >= 0); |
9522 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); | 9051 StoreNonPointer(&raw_ptr()->line_offset_, line_offset); |
9523 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); | 9052 StoreNonPointer(&raw_ptr()->col_offset_, col_offset); |
9524 } | 9053 } |
9525 | 9054 |
9526 | |
9527 // Specialized for AOT compilation, which does this lookup for every token | 9055 // Specialized for AOT compilation, which does this lookup for every token |
9528 // position that could be part of a stack trace. | 9056 // position that could be part of a stack trace. |
9529 intptr_t Script::GetTokenLineUsingLineStarts( | 9057 intptr_t Script::GetTokenLineUsingLineStarts( |
9530 TokenPosition target_token_pos) const { | 9058 TokenPosition target_token_pos) const { |
9531 if (target_token_pos.IsNoSource()) { | 9059 if (target_token_pos.IsNoSource()) { |
9532 return 0; | 9060 return 0; |
9533 } | 9061 } |
9534 Zone* zone = Thread::Current()->zone(); | 9062 Zone* zone = Thread::Current()->zone(); |
9535 Array& line_starts_array = Array::Handle(zone, line_starts()); | 9063 Array& line_starts_array = Array::Handle(zone, line_starts()); |
9536 Smi& token_pos = Smi::Handle(zone); | 9064 Smi& token_pos = Smi::Handle(zone); |
(...skipping 30 matching lines...) Expand all Loading... |
9567 token_pos ^= line_starts_array.At(midpoint); | 9095 token_pos ^= line_starts_array.At(midpoint); |
9568 if (token_pos.Value() > offset) { | 9096 if (token_pos.Value() > offset) { |
9569 max = midpoint - 1; | 9097 max = midpoint - 1; |
9570 } else { | 9098 } else { |
9571 min = midpoint; | 9099 min = midpoint; |
9572 } | 9100 } |
9573 } | 9101 } |
9574 return min + 1; // Line numbers start at 1. | 9102 return min + 1; // Line numbers start at 1. |
9575 } | 9103 } |
9576 | 9104 |
9577 | |
9578 void Script::GetTokenLocation(TokenPosition token_pos, | 9105 void Script::GetTokenLocation(TokenPosition token_pos, |
9579 intptr_t* line, | 9106 intptr_t* line, |
9580 intptr_t* column, | 9107 intptr_t* column, |
9581 intptr_t* token_len) const { | 9108 intptr_t* token_len) const { |
9582 ASSERT(line != NULL); | 9109 ASSERT(line != NULL); |
9583 Zone* zone = Thread::Current()->zone(); | 9110 Zone* zone = Thread::Current()->zone(); |
9584 | 9111 |
9585 if (kind() == RawScript::kKernelTag) { | 9112 if (kind() == RawScript::kKernelTag) { |
9586 const Array& line_starts_array = Array::Handle(zone, line_starts()); | 9113 const Array& line_starts_array = Array::Handle(zone, line_starts()); |
9587 if (line_starts_array.IsNull()) { | 9114 if (line_starts_array.IsNull()) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9673 *token_len = 1; | 9200 *token_len = 1; |
9674 } | 9201 } |
9675 } | 9202 } |
9676 // On the first line of the script we must add the column offset. | 9203 // On the first line of the script we must add the column offset. |
9677 if (relative_line == 1) { | 9204 if (relative_line == 1) { |
9678 *column += col_offset(); | 9205 *column += col_offset(); |
9679 } | 9206 } |
9680 } | 9207 } |
9681 } | 9208 } |
9682 | 9209 |
9683 | |
9684 void Script::TokenRangeAtLine(intptr_t line_number, | 9210 void Script::TokenRangeAtLine(intptr_t line_number, |
9685 TokenPosition* first_token_index, | 9211 TokenPosition* first_token_index, |
9686 TokenPosition* last_token_index) const { | 9212 TokenPosition* last_token_index) const { |
9687 ASSERT(first_token_index != NULL && last_token_index != NULL); | 9213 ASSERT(first_token_index != NULL && last_token_index != NULL); |
9688 ASSERT(line_number > 0); | 9214 ASSERT(line_number > 0); |
9689 | 9215 |
9690 if (kind() == RawScript::kKernelTag) { | 9216 if (kind() == RawScript::kKernelTag) { |
9691 const Array& line_starts_array = Array::Handle(line_starts()); | 9217 const Array& line_starts_array = Array::Handle(line_starts()); |
9692 if (line_starts_array.IsNull()) { | 9218 if (line_starts_array.IsNull()) { |
9693 // Scripts in the AOT snapshot do not have a line starts array. | 9219 // Scripts in the AOT snapshot do not have a line starts array. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9746 // know whether the previous token is a simple one or not. | 9272 // know whether the previous token is a simple one or not. |
9747 TokenPosition end_pos = *first_token_index; | 9273 TokenPosition end_pos = *first_token_index; |
9748 while (tkit.CurrentTokenKind() != Token::kNEWLINE && | 9274 while (tkit.CurrentTokenKind() != Token::kNEWLINE && |
9749 tkit.CurrentTokenKind() != Token::kEOS) { | 9275 tkit.CurrentTokenKind() != Token::kEOS) { |
9750 end_pos = tkit.CurrentPosition(); | 9276 end_pos = tkit.CurrentPosition(); |
9751 tkit.Advance(); | 9277 tkit.Advance(); |
9752 } | 9278 } |
9753 *last_token_index = end_pos; | 9279 *last_token_index = end_pos; |
9754 } | 9280 } |
9755 | 9281 |
9756 | |
9757 int32_t Script::SourceFingerprint() const { | 9282 int32_t Script::SourceFingerprint() const { |
9758 return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos), | 9283 return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos), |
9759 TokenPosition(TokenPosition::kMaxSourcePos)); | 9284 TokenPosition(TokenPosition::kMaxSourcePos)); |
9760 } | 9285 } |
9761 | 9286 |
9762 | |
9763 int32_t Script::SourceFingerprint(TokenPosition start, | 9287 int32_t Script::SourceFingerprint(TokenPosition start, |
9764 TokenPosition end) const { | 9288 TokenPosition end) const { |
9765 uint32_t result = 0; | 9289 uint32_t result = 0; |
9766 Zone* zone = Thread::Current()->zone(); | 9290 Zone* zone = Thread::Current()->zone(); |
9767 TokenStream::Iterator tokens_iterator( | 9291 TokenStream::Iterator tokens_iterator( |
9768 zone, TokenStream::Handle(zone, tokens()), start); | 9292 zone, TokenStream::Handle(zone, tokens()), start); |
9769 Object& obj = Object::Handle(zone); | 9293 Object& obj = Object::Handle(zone); |
9770 String& literal = String::Handle(zone); | 9294 String& literal = String::Handle(zone); |
9771 while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) && | 9295 while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) && |
9772 (tokens_iterator.CurrentPosition() < end)) { | 9296 (tokens_iterator.CurrentPosition() < end)) { |
(...skipping 10 matching lines...) Expand all Loading... |
9783 val = literal.Hash(); | 9307 val = literal.Hash(); |
9784 } | 9308 } |
9785 result = 31 * result + val; | 9309 result = 31 * result + val; |
9786 tokens_iterator.Advance(); | 9310 tokens_iterator.Advance(); |
9787 } | 9311 } |
9788 result = result & ((static_cast<uint32_t>(1) << 31) - 1); | 9312 result = result & ((static_cast<uint32_t>(1) << 31) - 1); |
9789 ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); | 9313 ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); |
9790 return result; | 9314 return result; |
9791 } | 9315 } |
9792 | 9316 |
9793 | |
9794 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { | 9317 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { |
9795 const String& src = String::Handle(Source()); | 9318 const String& src = String::Handle(Source()); |
9796 if (src.IsNull()) { | 9319 if (src.IsNull()) { |
9797 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 9320 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
9798 return Symbols::OptimizedOut().raw(); | 9321 return Symbols::OptimizedOut().raw(); |
9799 } | 9322 } |
9800 intptr_t relative_line_number = line_number - line_offset(); | 9323 intptr_t relative_line_number = line_number - line_offset(); |
9801 intptr_t current_line = 1; | 9324 intptr_t current_line = 1; |
9802 intptr_t line_start_idx = -1; | 9325 intptr_t line_start_idx = -1; |
9803 intptr_t last_char_idx = -1; | 9326 intptr_t last_char_idx = -1; |
(...skipping 15 matching lines...) Expand all Loading... |
9819 // Guarantee that returned string is never NULL. | 9342 // Guarantee that returned string is never NULL. |
9820 | 9343 |
9821 if (line_start_idx >= 0) { | 9344 if (line_start_idx >= 0) { |
9822 return String::SubString(src, line_start_idx, | 9345 return String::SubString(src, line_start_idx, |
9823 last_char_idx - line_start_idx + 1, space); | 9346 last_char_idx - line_start_idx + 1, space); |
9824 } else { | 9347 } else { |
9825 return Symbols::Empty().raw(); | 9348 return Symbols::Empty().raw(); |
9826 } | 9349 } |
9827 } | 9350 } |
9828 | 9351 |
9829 | |
9830 RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const { | 9352 RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const { |
9831 intptr_t from_line; | 9353 intptr_t from_line; |
9832 intptr_t from_column; | 9354 intptr_t from_column; |
9833 intptr_t to_line; | 9355 intptr_t to_line; |
9834 intptr_t to_column; | 9356 intptr_t to_column; |
9835 GetTokenLocation(from, &from_line, &from_column); | 9357 GetTokenLocation(from, &from_line, &from_column); |
9836 GetTokenLocation(to, &to_line, &to_column); | 9358 GetTokenLocation(to, &to_line, &to_column); |
9837 return GetSnippet(from_line, from_column, to_line, to_column); | 9359 return GetSnippet(from_line, from_column, to_line, to_column); |
9838 } | 9360 } |
9839 | 9361 |
9840 | |
9841 RawString* Script::GetSnippet(intptr_t from_line, | 9362 RawString* Script::GetSnippet(intptr_t from_line, |
9842 intptr_t from_column, | 9363 intptr_t from_column, |
9843 intptr_t to_line, | 9364 intptr_t to_line, |
9844 intptr_t to_column) const { | 9365 intptr_t to_column) const { |
9845 const String& src = String::Handle(Source()); | 9366 const String& src = String::Handle(Source()); |
9846 if (src.IsNull()) { | 9367 if (src.IsNull()) { |
9847 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 9368 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
9848 return Symbols::OptimizedOut().raw(); | 9369 return Symbols::OptimizedOut().raw(); |
9849 } | 9370 } |
9850 intptr_t length = src.Length(); | 9371 intptr_t length = src.Length(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9885 } | 9406 } |
9886 } | 9407 } |
9887 String& snippet = String::Handle(); | 9408 String& snippet = String::Handle(); |
9888 if ((snippet_start != -1) && (snippet_end != -1)) { | 9409 if ((snippet_start != -1) && (snippet_end != -1)) { |
9889 snippet = | 9410 snippet = |
9890 String::SubString(src, snippet_start, snippet_end - snippet_start); | 9411 String::SubString(src, snippet_start, snippet_end - snippet_start); |
9891 } | 9412 } |
9892 return snippet.raw(); | 9413 return snippet.raw(); |
9893 } | 9414 } |
9894 | 9415 |
9895 | |
9896 RawScript* Script::New() { | 9416 RawScript* Script::New() { |
9897 ASSERT(Object::script_class() != Class::null()); | 9417 ASSERT(Object::script_class() != Class::null()); |
9898 RawObject* raw = | 9418 RawObject* raw = |
9899 Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld); | 9419 Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld); |
9900 return reinterpret_cast<RawScript*>(raw); | 9420 return reinterpret_cast<RawScript*>(raw); |
9901 } | 9421 } |
9902 | 9422 |
9903 | |
9904 RawScript* Script::New(const String& url, | 9423 RawScript* Script::New(const String& url, |
9905 const String& source, | 9424 const String& source, |
9906 RawScript::Kind kind) { | 9425 RawScript::Kind kind) { |
9907 return Script::New(url, url, source, kind); | 9426 return Script::New(url, url, source, kind); |
9908 } | 9427 } |
9909 | 9428 |
9910 | |
9911 RawScript* Script::New(const String& url, | 9429 RawScript* Script::New(const String& url, |
9912 const String& resolved_url, | 9430 const String& resolved_url, |
9913 const String& source, | 9431 const String& source, |
9914 RawScript::Kind kind) { | 9432 RawScript::Kind kind) { |
9915 Thread* thread = Thread::Current(); | 9433 Thread* thread = Thread::Current(); |
9916 Zone* zone = thread->zone(); | 9434 Zone* zone = thread->zone(); |
9917 const Script& result = Script::Handle(zone, Script::New()); | 9435 const Script& result = Script::Handle(zone, Script::New()); |
9918 result.set_url(String::Handle(zone, Symbols::New(thread, url))); | 9436 result.set_url(String::Handle(zone, Symbols::New(thread, url))); |
9919 result.set_resolved_url( | 9437 result.set_resolved_url( |
9920 String::Handle(zone, Symbols::New(thread, resolved_url))); | 9438 String::Handle(zone, Symbols::New(thread, resolved_url))); |
9921 result.set_source(source); | 9439 result.set_source(source); |
9922 result.set_kind(kind); | 9440 result.set_kind(kind); |
9923 result.set_load_timestamp( | 9441 result.set_load_timestamp( |
9924 FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis()); | 9442 FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis()); |
9925 result.SetLocationOffset(0, 0); | 9443 result.SetLocationOffset(0, 0); |
9926 return result.raw(); | 9444 return result.raw(); |
9927 } | 9445 } |
9928 | 9446 |
9929 | |
9930 const char* Script::ToCString() const { | 9447 const char* Script::ToCString() const { |
9931 const String& name = String::Handle(url()); | 9448 const String& name = String::Handle(url()); |
9932 return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString()); | 9449 return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString()); |
9933 } | 9450 } |
9934 | 9451 |
9935 | |
9936 RawLibrary* Script::FindLibrary() const { | 9452 RawLibrary* Script::FindLibrary() const { |
9937 Thread* thread = Thread::Current(); | 9453 Thread* thread = Thread::Current(); |
9938 Zone* zone = thread->zone(); | 9454 Zone* zone = thread->zone(); |
9939 Isolate* isolate = thread->isolate(); | 9455 Isolate* isolate = thread->isolate(); |
9940 const GrowableObjectArray& libs = | 9456 const GrowableObjectArray& libs = |
9941 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 9457 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |
9942 Library& lib = Library::Handle(zone); | 9458 Library& lib = Library::Handle(zone); |
9943 Array& scripts = Array::Handle(zone); | 9459 Array& scripts = Array::Handle(zone); |
9944 for (intptr_t i = 0; i < libs.Length(); i++) { | 9460 for (intptr_t i = 0; i < libs.Length(); i++) { |
9945 lib ^= libs.At(i); | 9461 lib ^= libs.At(i); |
9946 scripts = lib.LoadedScripts(); | 9462 scripts = lib.LoadedScripts(); |
9947 for (intptr_t j = 0; j < scripts.Length(); j++) { | 9463 for (intptr_t j = 0; j < scripts.Length(); j++) { |
9948 if (scripts.At(j) == raw()) { | 9464 if (scripts.At(j) == raw()) { |
9949 return lib.raw(); | 9465 return lib.raw(); |
9950 } | 9466 } |
9951 } | 9467 } |
9952 } | 9468 } |
9953 return Library::null(); | 9469 return Library::null(); |
9954 } | 9470 } |
9955 | 9471 |
9956 | |
9957 DictionaryIterator::DictionaryIterator(const Library& library) | 9472 DictionaryIterator::DictionaryIterator(const Library& library) |
9958 : array_(Array::Handle(library.dictionary())), | 9473 : array_(Array::Handle(library.dictionary())), |
9959 // Last element in array is a Smi indicating the number of entries used. | 9474 // Last element in array is a Smi indicating the number of entries used. |
9960 size_(Array::Handle(library.dictionary()).Length() - 1), | 9475 size_(Array::Handle(library.dictionary()).Length() - 1), |
9961 next_ix_(0) { | 9476 next_ix_(0) { |
9962 MoveToNextObject(); | 9477 MoveToNextObject(); |
9963 } | 9478 } |
9964 | 9479 |
9965 | |
9966 RawObject* DictionaryIterator::GetNext() { | 9480 RawObject* DictionaryIterator::GetNext() { |
9967 ASSERT(HasNext()); | 9481 ASSERT(HasNext()); |
9968 int ix = next_ix_++; | 9482 int ix = next_ix_++; |
9969 MoveToNextObject(); | 9483 MoveToNextObject(); |
9970 ASSERT(array_.At(ix) != Object::null()); | 9484 ASSERT(array_.At(ix) != Object::null()); |
9971 return array_.At(ix); | 9485 return array_.At(ix); |
9972 } | 9486 } |
9973 | 9487 |
9974 | |
9975 void DictionaryIterator::MoveToNextObject() { | 9488 void DictionaryIterator::MoveToNextObject() { |
9976 Object& obj = Object::Handle(array_.At(next_ix_)); | 9489 Object& obj = Object::Handle(array_.At(next_ix_)); |
9977 while (obj.IsNull() && HasNext()) { | 9490 while (obj.IsNull() && HasNext()) { |
9978 next_ix_++; | 9491 next_ix_++; |
9979 obj = array_.At(next_ix_); | 9492 obj = array_.At(next_ix_); |
9980 } | 9493 } |
9981 } | 9494 } |
9982 | 9495 |
9983 | |
9984 ClassDictionaryIterator::ClassDictionaryIterator(const Library& library, | 9496 ClassDictionaryIterator::ClassDictionaryIterator(const Library& library, |
9985 IterationKind kind) | 9497 IterationKind kind) |
9986 : DictionaryIterator(library), | 9498 : DictionaryIterator(library), |
9987 toplevel_class_(Class::Handle((kind == kIteratePrivate) | 9499 toplevel_class_(Class::Handle((kind == kIteratePrivate) |
9988 ? library.toplevel_class() | 9500 ? library.toplevel_class() |
9989 : Class::null())) { | 9501 : Class::null())) { |
9990 MoveToNextClass(); | 9502 MoveToNextClass(); |
9991 } | 9503 } |
9992 | 9504 |
9993 | |
9994 RawClass* ClassDictionaryIterator::GetNextClass() { | 9505 RawClass* ClassDictionaryIterator::GetNextClass() { |
9995 ASSERT(HasNext()); | 9506 ASSERT(HasNext()); |
9996 Class& cls = Class::Handle(); | 9507 Class& cls = Class::Handle(); |
9997 if (next_ix_ < size_) { | 9508 if (next_ix_ < size_) { |
9998 int ix = next_ix_++; | 9509 int ix = next_ix_++; |
9999 cls ^= array_.At(ix); | 9510 cls ^= array_.At(ix); |
10000 MoveToNextClass(); | 9511 MoveToNextClass(); |
10001 return cls.raw(); | 9512 return cls.raw(); |
10002 } | 9513 } |
10003 ASSERT(!toplevel_class_.IsNull()); | 9514 ASSERT(!toplevel_class_.IsNull()); |
10004 cls = toplevel_class_.raw(); | 9515 cls = toplevel_class_.raw(); |
10005 toplevel_class_ = Class::null(); | 9516 toplevel_class_ = Class::null(); |
10006 return cls.raw(); | 9517 return cls.raw(); |
10007 } | 9518 } |
10008 | 9519 |
10009 | |
10010 void ClassDictionaryIterator::MoveToNextClass() { | 9520 void ClassDictionaryIterator::MoveToNextClass() { |
10011 Object& obj = Object::Handle(); | 9521 Object& obj = Object::Handle(); |
10012 while (next_ix_ < size_) { | 9522 while (next_ix_ < size_) { |
10013 obj = array_.At(next_ix_); | 9523 obj = array_.At(next_ix_); |
10014 if (obj.IsClass()) { | 9524 if (obj.IsClass()) { |
10015 return; | 9525 return; |
10016 } | 9526 } |
10017 next_ix_++; | 9527 next_ix_++; |
10018 } | 9528 } |
10019 } | 9529 } |
10020 | 9530 |
10021 | |
10022 LibraryPrefixIterator::LibraryPrefixIterator(const Library& library) | 9531 LibraryPrefixIterator::LibraryPrefixIterator(const Library& library) |
10023 : DictionaryIterator(library) { | 9532 : DictionaryIterator(library) { |
10024 Advance(); | 9533 Advance(); |
10025 } | 9534 } |
10026 | 9535 |
10027 | |
10028 RawLibraryPrefix* LibraryPrefixIterator::GetNext() { | 9536 RawLibraryPrefix* LibraryPrefixIterator::GetNext() { |
10029 ASSERT(HasNext()); | 9537 ASSERT(HasNext()); |
10030 int ix = next_ix_++; | 9538 int ix = next_ix_++; |
10031 Object& obj = Object::Handle(array_.At(ix)); | 9539 Object& obj = Object::Handle(array_.At(ix)); |
10032 Advance(); | 9540 Advance(); |
10033 return LibraryPrefix::Cast(obj).raw(); | 9541 return LibraryPrefix::Cast(obj).raw(); |
10034 } | 9542 } |
10035 | 9543 |
10036 | |
10037 void LibraryPrefixIterator::Advance() { | 9544 void LibraryPrefixIterator::Advance() { |
10038 Object& obj = Object::Handle(array_.At(next_ix_)); | 9545 Object& obj = Object::Handle(array_.At(next_ix_)); |
10039 while (!obj.IsLibraryPrefix() && HasNext()) { | 9546 while (!obj.IsLibraryPrefix() && HasNext()) { |
10040 next_ix_++; | 9547 next_ix_++; |
10041 obj = array_.At(next_ix_); | 9548 obj = array_.At(next_ix_); |
10042 } | 9549 } |
10043 } | 9550 } |
10044 | 9551 |
10045 | |
10046 static void ReportTooManyImports(const Library& lib) { | 9552 static void ReportTooManyImports(const Library& lib) { |
10047 const String& url = String::Handle(lib.url()); | 9553 const String& url = String::Handle(lib.url()); |
10048 Report::MessageF(Report::kError, Script::Handle(lib.LookupScript(url)), | 9554 Report::MessageF(Report::kError, Script::Handle(lib.LookupScript(url)), |
10049 TokenPosition::kNoSource, Report::AtLocation, | 9555 TokenPosition::kNoSource, Report::AtLocation, |
10050 "too many imports in library '%s'", url.ToCString()); | 9556 "too many imports in library '%s'", url.ToCString()); |
10051 UNREACHABLE(); | 9557 UNREACHABLE(); |
10052 } | 9558 } |
10053 | 9559 |
10054 | |
10055 void Library::set_num_imports(intptr_t value) const { | 9560 void Library::set_num_imports(intptr_t value) const { |
10056 if (!Utils::IsUint(16, value)) { | 9561 if (!Utils::IsUint(16, value)) { |
10057 ReportTooManyImports(*this); | 9562 ReportTooManyImports(*this); |
10058 } | 9563 } |
10059 StoreNonPointer(&raw_ptr()->num_imports_, value); | 9564 StoreNonPointer(&raw_ptr()->num_imports_, value); |
10060 } | 9565 } |
10061 | 9566 |
10062 | |
10063 void Library::SetName(const String& name) const { | 9567 void Library::SetName(const String& name) const { |
10064 // Only set name once. | 9568 // Only set name once. |
10065 ASSERT(!Loaded()); | 9569 ASSERT(!Loaded()); |
10066 ASSERT(name.IsSymbol()); | 9570 ASSERT(name.IsSymbol()); |
10067 StorePointer(&raw_ptr()->name_, name.raw()); | 9571 StorePointer(&raw_ptr()->name_, name.raw()); |
10068 } | 9572 } |
10069 | 9573 |
10070 | |
10071 void Library::SetLoadInProgress() const { | 9574 void Library::SetLoadInProgress() const { |
10072 // Must not already be in the process of being loaded. | 9575 // Must not already be in the process of being loaded. |
10073 ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested); | 9576 ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested); |
10074 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress); | 9577 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress); |
10075 } | 9578 } |
10076 | 9579 |
10077 | |
10078 void Library::SetLoadRequested() const { | 9580 void Library::SetLoadRequested() const { |
10079 // Must not be already loaded. | 9581 // Must not be already loaded. |
10080 ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated); | 9582 ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated); |
10081 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested); | 9583 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested); |
10082 } | 9584 } |
10083 | 9585 |
10084 | |
10085 void Library::SetLoaded() const { | 9586 void Library::SetLoaded() const { |
10086 // Should not be already loaded or just allocated. | 9587 // Should not be already loaded or just allocated. |
10087 ASSERT(LoadInProgress() || LoadRequested()); | 9588 ASSERT(LoadInProgress() || LoadRequested()); |
10088 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded); | 9589 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded); |
10089 } | 9590 } |
10090 | 9591 |
10091 | |
10092 void Library::SetLoadError(const Instance& error) const { | 9592 void Library::SetLoadError(const Instance& error) const { |
10093 // Should not be already successfully loaded or just allocated. | 9593 // Should not be already successfully loaded or just allocated. |
10094 ASSERT(LoadInProgress() || LoadRequested() || LoadFailed()); | 9594 ASSERT(LoadInProgress() || LoadRequested() || LoadFailed()); |
10095 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadError); | 9595 StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadError); |
10096 StorePointer(&raw_ptr()->load_error_, error.raw()); | 9596 StorePointer(&raw_ptr()->load_error_, error.raw()); |
10097 } | 9597 } |
10098 | 9598 |
10099 | |
10100 // Traits for looking up Libraries by url in a hash set. | 9599 // Traits for looking up Libraries by url in a hash set. |
10101 class LibraryUrlTraits { | 9600 class LibraryUrlTraits { |
10102 public: | 9601 public: |
10103 static const char* Name() { return "LibraryUrlTraits"; } | 9602 static const char* Name() { return "LibraryUrlTraits"; } |
10104 static bool ReportStats() { return false; } | 9603 static bool ReportStats() { return false; } |
10105 | 9604 |
10106 // Called when growing the table. | 9605 // Called when growing the table. |
10107 static bool IsMatch(const Object& a, const Object& b) { | 9606 static bool IsMatch(const Object& a, const Object& b) { |
10108 ASSERT(a.IsLibrary() && b.IsLibrary()); | 9607 ASSERT(a.IsLibrary() && b.IsLibrary()); |
10109 // Library objects are always canonical. | 9608 // Library objects are always canonical. |
10110 return a.raw() == b.raw(); | 9609 return a.raw() == b.raw(); |
10111 } | 9610 } |
10112 static uword Hash(const Object& key) { return Library::Cast(key).UrlHash(); } | 9611 static uword Hash(const Object& key) { return Library::Cast(key).UrlHash(); } |
10113 }; | 9612 }; |
10114 typedef UnorderedHashSet<LibraryUrlTraits> LibraryLoadErrorSet; | 9613 typedef UnorderedHashSet<LibraryUrlTraits> LibraryLoadErrorSet; |
10115 | 9614 |
10116 | |
10117 RawInstance* Library::TransitiveLoadError() const { | 9615 RawInstance* Library::TransitiveLoadError() const { |
10118 if (LoadError() != Instance::null()) { | 9616 if (LoadError() != Instance::null()) { |
10119 return LoadError(); | 9617 return LoadError(); |
10120 } | 9618 } |
10121 Thread* thread = Thread::Current(); | 9619 Thread* thread = Thread::Current(); |
10122 Isolate* isolate = thread->isolate(); | 9620 Isolate* isolate = thread->isolate(); |
10123 Zone* zone = thread->zone(); | 9621 Zone* zone = thread->zone(); |
10124 ObjectStore* object_store = isolate->object_store(); | 9622 ObjectStore* object_store = isolate->object_store(); |
10125 LibraryLoadErrorSet set(object_store->library_load_error_table()); | 9623 LibraryLoadErrorSet set(object_store->library_load_error_table()); |
10126 bool present = false; | 9624 bool present = false; |
(...skipping 11 matching lines...) Expand all Loading... |
10138 HANDLESCOPE(thread); | 9636 HANDLESCOPE(thread); |
10139 lib = ImportLibraryAt(i); | 9637 lib = ImportLibraryAt(i); |
10140 error = lib.TransitiveLoadError(); | 9638 error = lib.TransitiveLoadError(); |
10141 if (!error.IsNull()) { | 9639 if (!error.IsNull()) { |
10142 break; | 9640 break; |
10143 } | 9641 } |
10144 } | 9642 } |
10145 return error.raw(); | 9643 return error.raw(); |
10146 } | 9644 } |
10147 | 9645 |
10148 | |
10149 void Library::AddPatchClass(const Class& cls) const { | 9646 void Library::AddPatchClass(const Class& cls) const { |
10150 ASSERT(Thread::Current()->IsMutatorThread()); | 9647 ASSERT(Thread::Current()->IsMutatorThread()); |
10151 ASSERT(cls.is_patch()); | 9648 ASSERT(cls.is_patch()); |
10152 ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null()); | 9649 ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null()); |
10153 const GrowableObjectArray& patch_classes = | 9650 const GrowableObjectArray& patch_classes = |
10154 GrowableObjectArray::Handle(this->patch_classes()); | 9651 GrowableObjectArray::Handle(this->patch_classes()); |
10155 patch_classes.Add(cls); | 9652 patch_classes.Add(cls); |
10156 } | 9653 } |
10157 | 9654 |
10158 | |
10159 RawClass* Library::GetPatchClass(const String& name) const { | 9655 RawClass* Library::GetPatchClass(const String& name) const { |
10160 ASSERT(Thread::Current()->IsMutatorThread()); | 9656 ASSERT(Thread::Current()->IsMutatorThread()); |
10161 const GrowableObjectArray& patch_classes = | 9657 const GrowableObjectArray& patch_classes = |
10162 GrowableObjectArray::Handle(this->patch_classes()); | 9658 GrowableObjectArray::Handle(this->patch_classes()); |
10163 Object& obj = Object::Handle(); | 9659 Object& obj = Object::Handle(); |
10164 for (intptr_t i = 0; i < patch_classes.Length(); i++) { | 9660 for (intptr_t i = 0; i < patch_classes.Length(); i++) { |
10165 obj = patch_classes.At(i); | 9661 obj = patch_classes.At(i); |
10166 if (obj.IsClass() && | 9662 if (obj.IsClass() && |
10167 (Class::Cast(obj).Name() == name.raw())) { // Names are canonicalized. | 9663 (Class::Cast(obj).Name() == name.raw())) { // Names are canonicalized. |
10168 return Class::RawCast(obj.raw()); | 9664 return Class::RawCast(obj.raw()); |
10169 } | 9665 } |
10170 } | 9666 } |
10171 return Class::null(); | 9667 return Class::null(); |
10172 } | 9668 } |
10173 | 9669 |
10174 | |
10175 void Library::RemovePatchClass(const Class& cls) const { | 9670 void Library::RemovePatchClass(const Class& cls) const { |
10176 ASSERT(Thread::Current()->IsMutatorThread()); | 9671 ASSERT(Thread::Current()->IsMutatorThread()); |
10177 ASSERT(cls.is_patch()); | 9672 ASSERT(cls.is_patch()); |
10178 const GrowableObjectArray& patch_classes = | 9673 const GrowableObjectArray& patch_classes = |
10179 GrowableObjectArray::Handle(this->patch_classes()); | 9674 GrowableObjectArray::Handle(this->patch_classes()); |
10180 const intptr_t num_classes = patch_classes.Length(); | 9675 const intptr_t num_classes = patch_classes.Length(); |
10181 intptr_t i = 0; | 9676 intptr_t i = 0; |
10182 while (i < num_classes) { | 9677 while (i < num_classes) { |
10183 if (cls.raw() == patch_classes.At(i)) break; | 9678 if (cls.raw() == patch_classes.At(i)) break; |
10184 i++; | 9679 i++; |
10185 } | 9680 } |
10186 if (i == num_classes) return; | 9681 if (i == num_classes) return; |
10187 // Replace the entry with the script. We keep the script so that | 9682 // Replace the entry with the script. We keep the script so that |
10188 // Library::LoadedScripts() can find it without having to iterate | 9683 // Library::LoadedScripts() can find it without having to iterate |
10189 // over the members of each class. | 9684 // over the members of each class. |
10190 ASSERT(i < num_classes); // We must have found a class. | 9685 ASSERT(i < num_classes); // We must have found a class. |
10191 const Script& patch_script = Script::Handle(cls.script()); | 9686 const Script& patch_script = Script::Handle(cls.script()); |
10192 patch_classes.SetAt(i, patch_script); | 9687 patch_classes.SetAt(i, patch_script); |
10193 } | 9688 } |
10194 | 9689 |
10195 | |
10196 static RawString* MakeClassMetaName(Thread* thread, | 9690 static RawString* MakeClassMetaName(Thread* thread, |
10197 Zone* zone, | 9691 Zone* zone, |
10198 const Class& cls) { | 9692 const Class& cls) { |
10199 return Symbols::FromConcat(thread, Symbols::At(), | 9693 return Symbols::FromConcat(thread, Symbols::At(), |
10200 String::Handle(zone, cls.Name())); | 9694 String::Handle(zone, cls.Name())); |
10201 } | 9695 } |
10202 | 9696 |
10203 | |
10204 static RawString* MakeFieldMetaName(Thread* thread, | 9697 static RawString* MakeFieldMetaName(Thread* thread, |
10205 Zone* zone, | 9698 Zone* zone, |
10206 const Field& field) { | 9699 const Field& field) { |
10207 const String& cname = String::Handle( | 9700 const String& cname = String::Handle( |
10208 zone, | 9701 zone, |
10209 MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin()))); | 9702 MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin()))); |
10210 GrowableHandlePtrArray<const String> pieces(zone, 3); | 9703 GrowableHandlePtrArray<const String> pieces(zone, 3); |
10211 pieces.Add(cname); | 9704 pieces.Add(cname); |
10212 pieces.Add(Symbols::At()); | 9705 pieces.Add(Symbols::At()); |
10213 pieces.Add(String::Handle(field.name())); | 9706 pieces.Add(String::Handle(field.name())); |
10214 return Symbols::FromConcatAll(thread, pieces); | 9707 return Symbols::FromConcatAll(thread, pieces); |
10215 } | 9708 } |
10216 | 9709 |
10217 | |
10218 static RawString* MakeFunctionMetaName(Thread* thread, | 9710 static RawString* MakeFunctionMetaName(Thread* thread, |
10219 Zone* zone, | 9711 Zone* zone, |
10220 const Function& func) { | 9712 const Function& func) { |
10221 const String& cname = String::Handle( | 9713 const String& cname = String::Handle( |
10222 zone, | 9714 zone, |
10223 MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin()))); | 9715 MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin()))); |
10224 GrowableHandlePtrArray<const String> pieces(zone, 3); | 9716 GrowableHandlePtrArray<const String> pieces(zone, 3); |
10225 pieces.Add(cname); | 9717 pieces.Add(cname); |
10226 pieces.Add(Symbols::At()); | 9718 pieces.Add(Symbols::At()); |
10227 pieces.Add(String::Handle(func.QualifiedScrubbedName())); | 9719 pieces.Add(String::Handle(func.QualifiedScrubbedName())); |
10228 return Symbols::FromConcatAll(thread, pieces); | 9720 return Symbols::FromConcatAll(thread, pieces); |
10229 } | 9721 } |
10230 | 9722 |
10231 | |
10232 static RawString* MakeTypeParameterMetaName(Thread* thread, | 9723 static RawString* MakeTypeParameterMetaName(Thread* thread, |
10233 Zone* zone, | 9724 Zone* zone, |
10234 const TypeParameter& param) { | 9725 const TypeParameter& param) { |
10235 const String& cname = String::Handle( | 9726 const String& cname = String::Handle( |
10236 zone, | 9727 zone, |
10237 MakeClassMetaName(thread, zone, | 9728 MakeClassMetaName(thread, zone, |
10238 Class::Handle(zone, param.parameterized_class()))); | 9729 Class::Handle(zone, param.parameterized_class()))); |
10239 GrowableHandlePtrArray<const String> pieces(zone, 3); | 9730 GrowableHandlePtrArray<const String> pieces(zone, 3); |
10240 pieces.Add(cname); | 9731 pieces.Add(cname); |
10241 pieces.Add(Symbols::At()); | 9732 pieces.Add(Symbols::At()); |
10242 pieces.Add(String::Handle(param.name())); | 9733 pieces.Add(String::Handle(param.name())); |
10243 return Symbols::FromConcatAll(thread, pieces); | 9734 return Symbols::FromConcatAll(thread, pieces); |
10244 } | 9735 } |
10245 | 9736 |
10246 | |
10247 void Library::AddMetadata(const Object& owner, | 9737 void Library::AddMetadata(const Object& owner, |
10248 const String& name, | 9738 const String& name, |
10249 TokenPosition token_pos, | 9739 TokenPosition token_pos, |
10250 intptr_t kernel_offset) const { | 9740 intptr_t kernel_offset) const { |
10251 Thread* thread = Thread::Current(); | 9741 Thread* thread = Thread::Current(); |
10252 ASSERT(thread->IsMutatorThread()); | 9742 ASSERT(thread->IsMutatorThread()); |
10253 Zone* zone = thread->zone(); | 9743 Zone* zone = thread->zone(); |
10254 const String& metaname = String::Handle(zone, Symbols::New(thread, name)); | 9744 const String& metaname = String::Handle(zone, Symbols::New(thread, name)); |
10255 const Field& field = | 9745 const Field& field = |
10256 Field::Handle(zone, Field::NewTopLevel(metaname, | 9746 Field::Handle(zone, Field::NewTopLevel(metaname, |
10257 false, // is_final | 9747 false, // is_final |
10258 false, // is_const | 9748 false, // is_const |
10259 owner, token_pos)); | 9749 owner, token_pos)); |
10260 field.SetFieldType(Object::dynamic_type()); | 9750 field.SetFieldType(Object::dynamic_type()); |
10261 field.set_is_reflectable(false); | 9751 field.set_is_reflectable(false); |
10262 field.SetStaticValue(Array::empty_array(), true); | 9752 field.SetStaticValue(Array::empty_array(), true); |
10263 field.set_kernel_offset(kernel_offset); | 9753 field.set_kernel_offset(kernel_offset); |
10264 GrowableObjectArray& metadata = | 9754 GrowableObjectArray& metadata = |
10265 GrowableObjectArray::Handle(zone, this->metadata()); | 9755 GrowableObjectArray::Handle(zone, this->metadata()); |
10266 metadata.Add(field, Heap::kOld); | 9756 metadata.Add(field, Heap::kOld); |
10267 } | 9757 } |
10268 | 9758 |
10269 | |
10270 void Library::AddClassMetadata(const Class& cls, | 9759 void Library::AddClassMetadata(const Class& cls, |
10271 const Object& tl_owner, | 9760 const Object& tl_owner, |
10272 TokenPosition token_pos, | 9761 TokenPosition token_pos, |
10273 intptr_t kernel_offset) const { | 9762 intptr_t kernel_offset) const { |
10274 Thread* thread = Thread::Current(); | 9763 Thread* thread = Thread::Current(); |
10275 Zone* zone = thread->zone(); | 9764 Zone* zone = thread->zone(); |
10276 // We use the toplevel class as the owner of a class's metadata field because | 9765 // We use the toplevel class as the owner of a class's metadata field because |
10277 // a class's metadata is in scope of the library, not the class. | 9766 // a class's metadata is in scope of the library, not the class. |
10278 AddMetadata(tl_owner, | 9767 AddMetadata(tl_owner, |
10279 String::Handle(zone, MakeClassMetaName(thread, zone, cls)), | 9768 String::Handle(zone, MakeClassMetaName(thread, zone, cls)), |
10280 token_pos, kernel_offset); | 9769 token_pos, kernel_offset); |
10281 } | 9770 } |
10282 | 9771 |
10283 | |
10284 void Library::AddFieldMetadata(const Field& field, | 9772 void Library::AddFieldMetadata(const Field& field, |
10285 TokenPosition token_pos, | 9773 TokenPosition token_pos, |
10286 intptr_t kernel_offset) const { | 9774 intptr_t kernel_offset) const { |
10287 Thread* thread = Thread::Current(); | 9775 Thread* thread = Thread::Current(); |
10288 Zone* zone = thread->zone(); | 9776 Zone* zone = thread->zone(); |
10289 AddMetadata(Object::Handle(zone, field.RawOwner()), | 9777 AddMetadata(Object::Handle(zone, field.RawOwner()), |
10290 String::Handle(zone, MakeFieldMetaName(thread, zone, field)), | 9778 String::Handle(zone, MakeFieldMetaName(thread, zone, field)), |
10291 token_pos, kernel_offset); | 9779 token_pos, kernel_offset); |
10292 } | 9780 } |
10293 | 9781 |
10294 | |
10295 void Library::AddFunctionMetadata(const Function& func, | 9782 void Library::AddFunctionMetadata(const Function& func, |
10296 TokenPosition token_pos, | 9783 TokenPosition token_pos, |
10297 intptr_t kernel_offset) const { | 9784 intptr_t kernel_offset) const { |
10298 Thread* thread = Thread::Current(); | 9785 Thread* thread = Thread::Current(); |
10299 Zone* zone = thread->zone(); | 9786 Zone* zone = thread->zone(); |
10300 AddMetadata(Object::Handle(zone, func.RawOwner()), | 9787 AddMetadata(Object::Handle(zone, func.RawOwner()), |
10301 String::Handle(zone, MakeFunctionMetaName(thread, zone, func)), | 9788 String::Handle(zone, MakeFunctionMetaName(thread, zone, func)), |
10302 token_pos, kernel_offset); | 9789 token_pos, kernel_offset); |
10303 } | 9790 } |
10304 | 9791 |
10305 | |
10306 void Library::AddTypeParameterMetadata(const TypeParameter& param, | 9792 void Library::AddTypeParameterMetadata(const TypeParameter& param, |
10307 TokenPosition token_pos) const { | 9793 TokenPosition token_pos) const { |
10308 Thread* thread = Thread::Current(); | 9794 Thread* thread = Thread::Current(); |
10309 Zone* zone = thread->zone(); | 9795 Zone* zone = thread->zone(); |
10310 AddMetadata( | 9796 AddMetadata( |
10311 Class::Handle(zone, param.parameterized_class()), | 9797 Class::Handle(zone, param.parameterized_class()), |
10312 String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)), | 9798 String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)), |
10313 token_pos); | 9799 token_pos); |
10314 } | 9800 } |
10315 | 9801 |
10316 | |
10317 void Library::AddLibraryMetadata(const Object& tl_owner, | 9802 void Library::AddLibraryMetadata(const Object& tl_owner, |
10318 TokenPosition token_pos) const { | 9803 TokenPosition token_pos) const { |
10319 AddMetadata(tl_owner, Symbols::TopLevel(), token_pos); | 9804 AddMetadata(tl_owner, Symbols::TopLevel(), token_pos); |
10320 } | 9805 } |
10321 | 9806 |
10322 | |
10323 RawString* Library::MakeMetadataName(const Object& obj) const { | 9807 RawString* Library::MakeMetadataName(const Object& obj) const { |
10324 Thread* thread = Thread::Current(); | 9808 Thread* thread = Thread::Current(); |
10325 Zone* zone = thread->zone(); | 9809 Zone* zone = thread->zone(); |
10326 if (obj.IsClass()) { | 9810 if (obj.IsClass()) { |
10327 return MakeClassMetaName(thread, zone, Class::Cast(obj)); | 9811 return MakeClassMetaName(thread, zone, Class::Cast(obj)); |
10328 } else if (obj.IsField()) { | 9812 } else if (obj.IsField()) { |
10329 return MakeFieldMetaName(thread, zone, Field::Cast(obj)); | 9813 return MakeFieldMetaName(thread, zone, Field::Cast(obj)); |
10330 } else if (obj.IsFunction()) { | 9814 } else if (obj.IsFunction()) { |
10331 return MakeFunctionMetaName(thread, zone, Function::Cast(obj)); | 9815 return MakeFunctionMetaName(thread, zone, Function::Cast(obj)); |
10332 } else if (obj.IsLibrary()) { | 9816 } else if (obj.IsLibrary()) { |
10333 return Symbols::TopLevel().raw(); | 9817 return Symbols::TopLevel().raw(); |
10334 } else if (obj.IsTypeParameter()) { | 9818 } else if (obj.IsTypeParameter()) { |
10335 return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj)); | 9819 return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj)); |
10336 } | 9820 } |
10337 UNIMPLEMENTED(); | 9821 UNIMPLEMENTED(); |
10338 return String::null(); | 9822 return String::null(); |
10339 } | 9823 } |
10340 | 9824 |
10341 | |
10342 RawField* Library::GetMetadataField(const String& metaname) const { | 9825 RawField* Library::GetMetadataField(const String& metaname) const { |
10343 ASSERT(Thread::Current()->IsMutatorThread()); | 9826 ASSERT(Thread::Current()->IsMutatorThread()); |
10344 const GrowableObjectArray& metadata = | 9827 const GrowableObjectArray& metadata = |
10345 GrowableObjectArray::Handle(this->metadata()); | 9828 GrowableObjectArray::Handle(this->metadata()); |
10346 Field& entry = Field::Handle(); | 9829 Field& entry = Field::Handle(); |
10347 String& entryname = String::Handle(); | 9830 String& entryname = String::Handle(); |
10348 intptr_t num_entries = metadata.Length(); | 9831 intptr_t num_entries = metadata.Length(); |
10349 for (intptr_t i = 0; i < num_entries; i++) { | 9832 for (intptr_t i = 0; i < num_entries; i++) { |
10350 entry ^= metadata.At(i); | 9833 entry ^= metadata.At(i); |
10351 entryname = entry.name(); | 9834 entryname = entry.name(); |
10352 if (entryname.Equals(metaname)) { | 9835 if (entryname.Equals(metaname)) { |
10353 return entry.raw(); | 9836 return entry.raw(); |
10354 } | 9837 } |
10355 } | 9838 } |
10356 return Field::null(); | 9839 return Field::null(); |
10357 } | 9840 } |
10358 | 9841 |
10359 | |
10360 RawObject* Library::GetMetadata(const Object& obj) const { | 9842 RawObject* Library::GetMetadata(const Object& obj) const { |
10361 #if defined(DART_PRECOMPILED_RUNTIME) | 9843 #if defined(DART_PRECOMPILED_RUNTIME) |
10362 COMPILE_ASSERT(!FLAG_enable_mirrors); | 9844 COMPILE_ASSERT(!FLAG_enable_mirrors); |
10363 return Object::empty_array().raw(); | 9845 return Object::empty_array().raw(); |
10364 #else | 9846 #else |
10365 if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() && | 9847 if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() && |
10366 !obj.IsLibrary() && !obj.IsTypeParameter()) { | 9848 !obj.IsLibrary() && !obj.IsTypeParameter()) { |
10367 return Object::null(); | 9849 return Object::null(); |
10368 } | 9850 } |
10369 const String& metaname = String::Handle(MakeMetadataName(obj)); | 9851 const String& metaname = String::Handle(MakeMetadataName(obj)); |
(...skipping 12 matching lines...) Expand all Loading... |
10382 } | 9864 } |
10383 if (metadata.IsArray()) { | 9865 if (metadata.IsArray()) { |
10384 ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); | 9866 ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); |
10385 field.SetStaticValue(Array::Cast(metadata), true); | 9867 field.SetStaticValue(Array::Cast(metadata), true); |
10386 } | 9868 } |
10387 } | 9869 } |
10388 return metadata.raw(); | 9870 return metadata.raw(); |
10389 #endif // defined(DART_PRECOMPILED_RUNTIME) | 9871 #endif // defined(DART_PRECOMPILED_RUNTIME) |
10390 } | 9872 } |
10391 | 9873 |
10392 | |
10393 static bool ShouldBePrivate(const String& name) { | 9874 static bool ShouldBePrivate(const String& name) { |
10394 return (name.Length() >= 1 && name.CharAt(0) == '_') || | 9875 return (name.Length() >= 1 && name.CharAt(0) == '_') || |
10395 (name.Length() >= 5 && | 9876 (name.Length() >= 5 && |
10396 (name.CharAt(4) == '_' && | 9877 (name.CharAt(4) == '_' && |
10397 (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && | 9878 (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && |
10398 name.CharAt(1) == 'e' && name.CharAt(2) == 't' && | 9879 name.CharAt(1) == 'e' && name.CharAt(2) == 't' && |
10399 name.CharAt(3) == ':')); | 9880 name.CharAt(3) == ':')); |
10400 } | 9881 } |
10401 | 9882 |
10402 | |
10403 RawObject* Library::ResolveName(const String& name) const { | 9883 RawObject* Library::ResolveName(const String& name) const { |
10404 Object& obj = Object::Handle(); | 9884 Object& obj = Object::Handle(); |
10405 if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) { | 9885 if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) { |
10406 return obj.raw(); | 9886 return obj.raw(); |
10407 } | 9887 } |
10408 obj = LookupLocalObject(name); | 9888 obj = LookupLocalObject(name); |
10409 if (!obj.IsNull()) { | 9889 if (!obj.IsNull()) { |
10410 // Names that are in this library's dictionary and are unmangled | 9890 // Names that are in this library's dictionary and are unmangled |
10411 // are not cached. This reduces the size of the cache. | 9891 // are not cached. This reduces the size of the cache. |
10412 return obj.raw(); | 9892 return obj.raw(); |
10413 } | 9893 } |
10414 String& accessor_name = String::Handle(Field::LookupGetterSymbol(name)); | 9894 String& accessor_name = String::Handle(Field::LookupGetterSymbol(name)); |
10415 if (!accessor_name.IsNull()) { | 9895 if (!accessor_name.IsNull()) { |
10416 obj = LookupLocalObject(accessor_name); | 9896 obj = LookupLocalObject(accessor_name); |
10417 } | 9897 } |
10418 if (obj.IsNull()) { | 9898 if (obj.IsNull()) { |
10419 accessor_name = Field::LookupSetterSymbol(name); | 9899 accessor_name = Field::LookupSetterSymbol(name); |
10420 if (!accessor_name.IsNull()) { | 9900 if (!accessor_name.IsNull()) { |
10421 obj = LookupLocalObject(accessor_name); | 9901 obj = LookupLocalObject(accessor_name); |
10422 } | 9902 } |
10423 if (obj.IsNull() && !ShouldBePrivate(name)) { | 9903 if (obj.IsNull() && !ShouldBePrivate(name)) { |
10424 obj = LookupImportedObject(name); | 9904 obj = LookupImportedObject(name); |
10425 } | 9905 } |
10426 } | 9906 } |
10427 AddToResolvedNamesCache(name, obj); | 9907 AddToResolvedNamesCache(name, obj); |
10428 return obj.raw(); | 9908 return obj.raw(); |
10429 } | 9909 } |
10430 | 9910 |
10431 | |
10432 class StringEqualsTraits { | 9911 class StringEqualsTraits { |
10433 public: | 9912 public: |
10434 static const char* Name() { return "StringEqualsTraits"; } | 9913 static const char* Name() { return "StringEqualsTraits"; } |
10435 static bool ReportStats() { return false; } | 9914 static bool ReportStats() { return false; } |
10436 | 9915 |
10437 static bool IsMatch(const Object& a, const Object& b) { | 9916 static bool IsMatch(const Object& a, const Object& b) { |
10438 return String::Cast(a).Equals(String::Cast(b)); | 9917 return String::Cast(a).Equals(String::Cast(b)); |
10439 } | 9918 } |
10440 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } | 9919 static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } |
10441 }; | 9920 }; |
10442 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap; | 9921 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap; |
10443 | 9922 |
10444 | |
10445 // Returns true if the name is found in the cache, false no cache hit. | 9923 // Returns true if the name is found in the cache, false no cache hit. |
10446 // obj is set to the cached entry. It may be null, indicating that the | 9924 // obj is set to the cached entry. It may be null, indicating that the |
10447 // name does not resolve to anything in this library. | 9925 // name does not resolve to anything in this library. |
10448 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const { | 9926 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const { |
10449 if (resolved_names() == Array::null()) { | 9927 if (resolved_names() == Array::null()) { |
10450 return false; | 9928 return false; |
10451 } | 9929 } |
10452 ResolvedNamesMap cache(resolved_names()); | 9930 ResolvedNamesMap cache(resolved_names()); |
10453 bool present = false; | 9931 bool present = false; |
10454 *obj = cache.GetOrNull(name, &present); | 9932 *obj = cache.GetOrNull(name, &present); |
10455 // Mutator compiler thread may add entries and therefore | 9933 // Mutator compiler thread may add entries and therefore |
10456 // change 'resolved_names()' while running a background compilation; | 9934 // change 'resolved_names()' while running a background compilation; |
10457 // ASSERT that 'resolved_names()' has not changed only in mutator. | 9935 // ASSERT that 'resolved_names()' has not changed only in mutator. |
10458 #if defined(DEBUG) | 9936 #if defined(DEBUG) |
10459 if (Thread::Current()->IsMutatorThread()) { | 9937 if (Thread::Current()->IsMutatorThread()) { |
10460 ASSERT(cache.Release().raw() == resolved_names()); | 9938 ASSERT(cache.Release().raw() == resolved_names()); |
10461 } else { | 9939 } else { |
10462 // Release must be called in debug mode. | 9940 // Release must be called in debug mode. |
10463 cache.Release(); | 9941 cache.Release(); |
10464 } | 9942 } |
10465 #endif | 9943 #endif |
10466 return present; | 9944 return present; |
10467 } | 9945 } |
10468 | 9946 |
10469 | |
10470 // Add a name to the resolved name cache. This name resolves to the | 9947 // Add a name to the resolved name cache. This name resolves to the |
10471 // given object in this library scope. obj may be null, which means | 9948 // given object in this library scope. obj may be null, which means |
10472 // the name does not resolve to anything in this library scope. | 9949 // the name does not resolve to anything in this library scope. |
10473 void Library::AddToResolvedNamesCache(const String& name, | 9950 void Library::AddToResolvedNamesCache(const String& name, |
10474 const Object& obj) const { | 9951 const Object& obj) const { |
10475 if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { | 9952 if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { |
10476 return; | 9953 return; |
10477 } | 9954 } |
10478 if (resolved_names() == Array::null()) { | 9955 if (resolved_names() == Array::null()) { |
10479 InitResolvedNamesCache(); | 9956 InitResolvedNamesCache(); |
10480 } | 9957 } |
10481 ResolvedNamesMap cache(resolved_names()); | 9958 ResolvedNamesMap cache(resolved_names()); |
10482 cache.UpdateOrInsert(name, obj); | 9959 cache.UpdateOrInsert(name, obj); |
10483 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); | 9960 StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); |
10484 } | 9961 } |
10485 | 9962 |
10486 | |
10487 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const { | 9963 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const { |
10488 ASSERT(FLAG_use_exp_cache); | 9964 ASSERT(FLAG_use_exp_cache); |
10489 if (exported_names() == Array::null()) { | 9965 if (exported_names() == Array::null()) { |
10490 return false; | 9966 return false; |
10491 } | 9967 } |
10492 ResolvedNamesMap cache(exported_names()); | 9968 ResolvedNamesMap cache(exported_names()); |
10493 bool present = false; | 9969 bool present = false; |
10494 *obj = cache.GetOrNull(name, &present); | 9970 *obj = cache.GetOrNull(name, &present); |
10495 // Mutator compiler thread may add entries and therefore | 9971 // Mutator compiler thread may add entries and therefore |
10496 // change 'exported_names()' while running a background compilation; | 9972 // change 'exported_names()' while running a background compilation; |
(...skipping 15 matching lines...) Expand all Loading... |
10512 return; | 9988 return; |
10513 } | 9989 } |
10514 if (exported_names() == Array::null()) { | 9990 if (exported_names() == Array::null()) { |
10515 InitExportedNamesCache(); | 9991 InitExportedNamesCache(); |
10516 } | 9992 } |
10517 ResolvedNamesMap cache(exported_names()); | 9993 ResolvedNamesMap cache(exported_names()); |
10518 cache.UpdateOrInsert(name, obj); | 9994 cache.UpdateOrInsert(name, obj); |
10519 StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); | 9995 StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); |
10520 } | 9996 } |
10521 | 9997 |
10522 | |
10523 void Library::InvalidateResolvedName(const String& name) const { | 9998 void Library::InvalidateResolvedName(const String& name) const { |
10524 Thread* thread = Thread::Current(); | 9999 Thread* thread = Thread::Current(); |
10525 Zone* zone = thread->zone(); | 10000 Zone* zone = thread->zone(); |
10526 Object& entry = Object::Handle(zone); | 10001 Object& entry = Object::Handle(zone); |
10527 if (LookupResolvedNamesCache(name, &entry)) { | 10002 if (LookupResolvedNamesCache(name, &entry)) { |
10528 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. | 10003 // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. |
10529 ClearResolvedNamesCache(); | 10004 ClearResolvedNamesCache(); |
10530 } | 10005 } |
10531 // When a new name is added to a library, we need to invalidate all | 10006 // When a new name is added to a library, we need to invalidate all |
10532 // caches that contain an entry for this name. If the name was previously | 10007 // caches that contain an entry for this name. If the name was previously |
10533 // looked up but could not be resolved, the cache contains a null entry. | 10008 // looked up but could not be resolved, the cache contains a null entry. |
10534 GrowableObjectArray& libs = GrowableObjectArray::Handle( | 10009 GrowableObjectArray& libs = GrowableObjectArray::Handle( |
10535 zone, thread->isolate()->object_store()->libraries()); | 10010 zone, thread->isolate()->object_store()->libraries()); |
10536 Library& lib = Library::Handle(zone); | 10011 Library& lib = Library::Handle(zone); |
10537 intptr_t num_libs = libs.Length(); | 10012 intptr_t num_libs = libs.Length(); |
10538 for (intptr_t i = 0; i < num_libs; i++) { | 10013 for (intptr_t i = 0; i < num_libs; i++) { |
10539 lib ^= libs.At(i); | 10014 lib ^= libs.At(i); |
10540 if (lib.LookupExportedNamesCache(name, &entry)) { | 10015 if (lib.LookupExportedNamesCache(name, &entry)) { |
10541 lib.ClearExportedNamesCache(); | 10016 lib.ClearExportedNamesCache(); |
10542 } | 10017 } |
10543 } | 10018 } |
10544 } | 10019 } |
10545 | 10020 |
10546 | |
10547 // Invalidate all exported names caches in the isolate. | 10021 // Invalidate all exported names caches in the isolate. |
10548 void Library::InvalidateExportedNamesCaches() { | 10022 void Library::InvalidateExportedNamesCaches() { |
10549 GrowableObjectArray& libs = GrowableObjectArray::Handle( | 10023 GrowableObjectArray& libs = GrowableObjectArray::Handle( |
10550 Isolate::Current()->object_store()->libraries()); | 10024 Isolate::Current()->object_store()->libraries()); |
10551 Library& lib = Library::Handle(); | 10025 Library& lib = Library::Handle(); |
10552 intptr_t num_libs = libs.Length(); | 10026 intptr_t num_libs = libs.Length(); |
10553 for (intptr_t i = 0; i < num_libs; i++) { | 10027 for (intptr_t i = 0; i < num_libs; i++) { |
10554 lib ^= libs.At(i); | 10028 lib ^= libs.At(i); |
10555 lib.ClearExportedNamesCache(); | 10029 lib.ClearExportedNamesCache(); |
10556 } | 10030 } |
10557 } | 10031 } |
10558 | 10032 |
10559 | |
10560 void Library::RehashDictionary(const Array& old_dict, | 10033 void Library::RehashDictionary(const Array& old_dict, |
10561 intptr_t new_dict_size) const { | 10034 intptr_t new_dict_size) const { |
10562 intptr_t old_dict_size = old_dict.Length() - 1; | 10035 intptr_t old_dict_size = old_dict.Length() - 1; |
10563 const Array& new_dict = | 10036 const Array& new_dict = |
10564 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); | 10037 Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); |
10565 // Rehash all elements from the original dictionary | 10038 // Rehash all elements from the original dictionary |
10566 // to the newly allocated array. | 10039 // to the newly allocated array. |
10567 Object& entry = Class::Handle(); | 10040 Object& entry = Class::Handle(); |
10568 String& entry_name = String::Handle(); | 10041 String& entry_name = String::Handle(); |
10569 Object& new_entry = Object::Handle(); | 10042 Object& new_entry = Object::Handle(); |
(...skipping 15 matching lines...) Expand all Loading... |
10585 } | 10058 } |
10586 } | 10059 } |
10587 // Set used count. | 10060 // Set used count. |
10588 ASSERT(used < new_dict_size); // Need at least one empty slot. | 10061 ASSERT(used < new_dict_size); // Need at least one empty slot. |
10589 new_entry = Smi::New(used); | 10062 new_entry = Smi::New(used); |
10590 new_dict.SetAt(new_dict_size, new_entry); | 10063 new_dict.SetAt(new_dict_size, new_entry); |
10591 // Remember the new dictionary now. | 10064 // Remember the new dictionary now. |
10592 StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); | 10065 StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); |
10593 } | 10066 } |
10594 | 10067 |
10595 | |
10596 void Library::AddObject(const Object& obj, const String& name) const { | 10068 void Library::AddObject(const Object& obj, const String& name) const { |
10597 ASSERT(Thread::Current()->IsMutatorThread()); | 10069 ASSERT(Thread::Current()->IsMutatorThread()); |
10598 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || | 10070 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || |
10599 obj.IsLibraryPrefix()); | 10071 obj.IsLibraryPrefix()); |
10600 ASSERT(name.Equals(String::Handle(obj.DictionaryName()))); | 10072 ASSERT(name.Equals(String::Handle(obj.DictionaryName()))); |
10601 ASSERT(LookupLocalObject(name) == Object::null()); | 10073 ASSERT(LookupLocalObject(name) == Object::null()); |
10602 const Array& dict = Array::Handle(dictionary()); | 10074 const Array& dict = Array::Handle(dictionary()); |
10603 intptr_t dict_size = dict.Length() - 1; | 10075 intptr_t dict_size = dict.Length() - 1; |
10604 intptr_t index = name.Hash() % dict_size; | 10076 intptr_t index = name.Hash() % dict_size; |
10605 | 10077 |
(...skipping 17 matching lines...) Expand all Loading... |
10623 // TODO(iposva): Avoid exponential growth. | 10095 // TODO(iposva): Avoid exponential growth. |
10624 RehashDictionary(dict, 2 * dict_size); | 10096 RehashDictionary(dict, 2 * dict_size); |
10625 } | 10097 } |
10626 | 10098 |
10627 // Invalidate the cache of loaded scripts. | 10099 // Invalidate the cache of loaded scripts. |
10628 if (loaded_scripts() != Array::null()) { | 10100 if (loaded_scripts() != Array::null()) { |
10629 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 10101 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
10630 } | 10102 } |
10631 } | 10103 } |
10632 | 10104 |
10633 | |
10634 // Lookup a name in the library's re-export namespace. | 10105 // Lookup a name in the library's re-export namespace. |
10635 // This lookup can occur from two different threads: background compiler and | 10106 // This lookup can occur from two different threads: background compiler and |
10636 // mutator thread. | 10107 // mutator thread. |
10637 RawObject* Library::LookupReExport(const String& name, | 10108 RawObject* Library::LookupReExport(const String& name, |
10638 ZoneGrowableArray<intptr_t>* trail) const { | 10109 ZoneGrowableArray<intptr_t>* trail) const { |
10639 if (!HasExports()) { | 10110 if (!HasExports()) { |
10640 return Object::null(); | 10111 return Object::null(); |
10641 } | 10112 } |
10642 | 10113 |
10643 if (trail == NULL) { | 10114 if (trail == NULL) { |
(...skipping 22 matching lines...) Expand all Loading... |
10666 } | 10137 } |
10667 } | 10138 } |
10668 } | 10139 } |
10669 bool in_cycle = (trail->RemoveLast() < 0); | 10140 bool in_cycle = (trail->RemoveLast() < 0); |
10670 if (FLAG_use_exp_cache && !in_cycle && !Compiler::IsBackgroundCompilation()) { | 10141 if (FLAG_use_exp_cache && !in_cycle && !Compiler::IsBackgroundCompilation()) { |
10671 AddToExportedNamesCache(name, obj); | 10142 AddToExportedNamesCache(name, obj); |
10672 } | 10143 } |
10673 return obj.raw(); | 10144 return obj.raw(); |
10674 } | 10145 } |
10675 | 10146 |
10676 | |
10677 RawObject* Library::LookupEntry(const String& name, intptr_t* index) const { | 10147 RawObject* Library::LookupEntry(const String& name, intptr_t* index) const { |
10678 Thread* thread = Thread::Current(); | 10148 Thread* thread = Thread::Current(); |
10679 REUSABLE_ARRAY_HANDLESCOPE(thread); | 10149 REUSABLE_ARRAY_HANDLESCOPE(thread); |
10680 REUSABLE_OBJECT_HANDLESCOPE(thread); | 10150 REUSABLE_OBJECT_HANDLESCOPE(thread); |
10681 REUSABLE_STRING_HANDLESCOPE(thread); | 10151 REUSABLE_STRING_HANDLESCOPE(thread); |
10682 Array& dict = thread->ArrayHandle(); | 10152 Array& dict = thread->ArrayHandle(); |
10683 dict ^= dictionary(); | 10153 dict ^= dictionary(); |
10684 intptr_t dict_size = dict.Length() - 1; | 10154 intptr_t dict_size = dict.Length() - 1; |
10685 *index = name.Hash() % dict_size; | 10155 *index = name.Hash() % dict_size; |
10686 Object& entry = thread->ObjectHandle(); | 10156 Object& entry = thread->ObjectHandle(); |
10687 String& entry_name = thread->StringHandle(); | 10157 String& entry_name = thread->StringHandle(); |
10688 entry = dict.At(*index); | 10158 entry = dict.At(*index); |
10689 // Search the entry in the hash set. | 10159 // Search the entry in the hash set. |
10690 while (!entry.IsNull()) { | 10160 while (!entry.IsNull()) { |
10691 entry_name = entry.DictionaryName(); | 10161 entry_name = entry.DictionaryName(); |
10692 ASSERT(!entry_name.IsNull()); | 10162 ASSERT(!entry_name.IsNull()); |
10693 if (entry_name.Equals(name)) { | 10163 if (entry_name.Equals(name)) { |
10694 return entry.raw(); | 10164 return entry.raw(); |
10695 } | 10165 } |
10696 *index = (*index + 1) % dict_size; | 10166 *index = (*index + 1) % dict_size; |
10697 entry = dict.At(*index); | 10167 entry = dict.At(*index); |
10698 } | 10168 } |
10699 return Object::null(); | 10169 return Object::null(); |
10700 } | 10170 } |
10701 | 10171 |
10702 | |
10703 void Library::ReplaceObject(const Object& obj, const String& name) const { | 10172 void Library::ReplaceObject(const Object& obj, const String& name) const { |
10704 ASSERT(!Compiler::IsBackgroundCompilation()); | 10173 ASSERT(!Compiler::IsBackgroundCompilation()); |
10705 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField()); | 10174 ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField()); |
10706 ASSERT(LookupLocalObject(name) != Object::null()); | 10175 ASSERT(LookupLocalObject(name) != Object::null()); |
10707 | 10176 |
10708 intptr_t index; | 10177 intptr_t index; |
10709 LookupEntry(name, &index); | 10178 LookupEntry(name, &index); |
10710 // The value is guaranteed to be found. | 10179 // The value is guaranteed to be found. |
10711 const Array& dict = Array::Handle(dictionary()); | 10180 const Array& dict = Array::Handle(dictionary()); |
10712 dict.SetAt(index, obj); | 10181 dict.SetAt(index, obj); |
10713 } | 10182 } |
10714 | 10183 |
10715 | |
10716 void Library::AddClass(const Class& cls) const { | 10184 void Library::AddClass(const Class& cls) const { |
10717 ASSERT(!Compiler::IsBackgroundCompilation()); | 10185 ASSERT(!Compiler::IsBackgroundCompilation()); |
10718 const String& class_name = String::Handle(cls.Name()); | 10186 const String& class_name = String::Handle(cls.Name()); |
10719 AddObject(cls, class_name); | 10187 AddObject(cls, class_name); |
10720 // Link class to this library. | 10188 // Link class to this library. |
10721 cls.set_library(*this); | 10189 cls.set_library(*this); |
10722 InvalidateResolvedName(class_name); | 10190 InvalidateResolvedName(class_name); |
10723 } | 10191 } |
10724 | 10192 |
10725 | |
10726 static void AddScriptIfUnique(const GrowableObjectArray& scripts, | 10193 static void AddScriptIfUnique(const GrowableObjectArray& scripts, |
10727 const Script& candidate) { | 10194 const Script& candidate) { |
10728 if (candidate.IsNull()) { | 10195 if (candidate.IsNull()) { |
10729 return; | 10196 return; |
10730 } | 10197 } |
10731 Script& script_obj = Script::Handle(); | 10198 Script& script_obj = Script::Handle(); |
10732 | 10199 |
10733 for (int i = 0; i < scripts.Length(); i++) { | 10200 for (int i = 0; i < scripts.Length(); i++) { |
10734 script_obj ^= scripts.At(i); | 10201 script_obj ^= scripts.At(i); |
10735 if (script_obj.raw() == candidate.raw()) { | 10202 if (script_obj.raw() == candidate.raw()) { |
10736 // We already have a reference to this script. | 10203 // We already have a reference to this script. |
10737 return; | 10204 return; |
10738 } | 10205 } |
10739 } | 10206 } |
10740 // Add script to the list of scripts. | 10207 // Add script to the list of scripts. |
10741 scripts.Add(candidate); | 10208 scripts.Add(candidate); |
10742 } | 10209 } |
10743 | 10210 |
10744 | |
10745 RawArray* Library::LoadedScripts() const { | 10211 RawArray* Library::LoadedScripts() const { |
10746 ASSERT(Thread::Current()->IsMutatorThread()); | 10212 ASSERT(Thread::Current()->IsMutatorThread()); |
10747 // We compute the list of loaded scripts lazily. The result is | 10213 // We compute the list of loaded scripts lazily. The result is |
10748 // cached in loaded_scripts_. | 10214 // cached in loaded_scripts_. |
10749 if (loaded_scripts() == Array::null()) { | 10215 if (loaded_scripts() == Array::null()) { |
10750 // Iterate over the library dictionary and collect all scripts. | 10216 // Iterate over the library dictionary and collect all scripts. |
10751 const GrowableObjectArray& scripts = | 10217 const GrowableObjectArray& scripts = |
10752 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 10218 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
10753 Object& entry = Object::Handle(); | 10219 Object& entry = Object::Handle(); |
10754 Class& cls = Class::Handle(); | 10220 Class& cls = Class::Handle(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10799 } | 10265 } |
10800 } | 10266 } |
10801 | 10267 |
10802 // Create the array of scripts and cache it in loaded_scripts_. | 10268 // Create the array of scripts and cache it in loaded_scripts_. |
10803 const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts)); | 10269 const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts)); |
10804 StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw()); | 10270 StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw()); |
10805 } | 10271 } |
10806 return loaded_scripts(); | 10272 return loaded_scripts(); |
10807 } | 10273 } |
10808 | 10274 |
10809 | |
10810 // TODO(hausner): we might want to add a script dictionary to the | 10275 // TODO(hausner): we might want to add a script dictionary to the |
10811 // library class to make this lookup faster. | 10276 // library class to make this lookup faster. |
10812 RawScript* Library::LookupScript(const String& url) const { | 10277 RawScript* Library::LookupScript(const String& url) const { |
10813 const intptr_t url_length = url.Length(); | 10278 const intptr_t url_length = url.Length(); |
10814 if (url_length == 0) { | 10279 if (url_length == 0) { |
10815 return Script::null(); | 10280 return Script::null(); |
10816 } | 10281 } |
10817 const Array& scripts = Array::Handle(LoadedScripts()); | 10282 const Array& scripts = Array::Handle(LoadedScripts()); |
10818 Script& script = Script::Handle(); | 10283 Script& script = Script::Handle(); |
10819 String& script_url = String::Handle(); | 10284 String& script_url = String::Handle(); |
(...skipping 10 matching lines...) Expand all Loading... |
10830 if (((url.CharAt(0) == '/') || | 10295 if (((url.CharAt(0) == '/') || |
10831 (script_url.CharAt(start_idx - 1) == '/')) && | 10296 (script_url.CharAt(start_idx - 1) == '/')) && |
10832 url.Equals(script_url, start_idx, url_length)) { | 10297 url.Equals(script_url, start_idx, url_length)) { |
10833 return script.raw(); | 10298 return script.raw(); |
10834 } | 10299 } |
10835 } | 10300 } |
10836 } | 10301 } |
10837 return Script::null(); | 10302 return Script::null(); |
10838 } | 10303 } |
10839 | 10304 |
10840 | |
10841 RawObject* Library::LookupLocalObject(const String& name) const { | 10305 RawObject* Library::LookupLocalObject(const String& name) const { |
10842 intptr_t index; | 10306 intptr_t index; |
10843 return LookupEntry(name, &index); | 10307 return LookupEntry(name, &index); |
10844 } | 10308 } |
10845 | 10309 |
10846 | |
10847 RawField* Library::LookupFieldAllowPrivate(const String& name) const { | 10310 RawField* Library::LookupFieldAllowPrivate(const String& name) const { |
10848 Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); | 10311 Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |
10849 if (obj.IsField()) { | 10312 if (obj.IsField()) { |
10850 return Field::Cast(obj).raw(); | 10313 return Field::Cast(obj).raw(); |
10851 } | 10314 } |
10852 return Field::null(); | 10315 return Field::null(); |
10853 } | 10316 } |
10854 | 10317 |
10855 | |
10856 RawField* Library::LookupLocalField(const String& name) const { | 10318 RawField* Library::LookupLocalField(const String& name) const { |
10857 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 10319 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |
10858 if (obj.IsField()) { | 10320 if (obj.IsField()) { |
10859 return Field::Cast(obj).raw(); | 10321 return Field::Cast(obj).raw(); |
10860 } | 10322 } |
10861 return Field::null(); | 10323 return Field::null(); |
10862 } | 10324 } |
10863 | 10325 |
10864 | |
10865 RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const { | 10326 RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const { |
10866 Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); | 10327 Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |
10867 if (obj.IsFunction()) { | 10328 if (obj.IsFunction()) { |
10868 return Function::Cast(obj).raw(); | 10329 return Function::Cast(obj).raw(); |
10869 } | 10330 } |
10870 return Function::null(); | 10331 return Function::null(); |
10871 } | 10332 } |
10872 | 10333 |
10873 | |
10874 RawFunction* Library::LookupLocalFunction(const String& name) const { | 10334 RawFunction* Library::LookupLocalFunction(const String& name) const { |
10875 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 10335 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |
10876 if (obj.IsFunction()) { | 10336 if (obj.IsFunction()) { |
10877 return Function::Cast(obj).raw(); | 10337 return Function::Cast(obj).raw(); |
10878 } | 10338 } |
10879 return Function::null(); | 10339 return Function::null(); |
10880 } | 10340 } |
10881 | 10341 |
10882 | |
10883 RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const { | 10342 RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const { |
10884 Thread* thread = Thread::Current(); | 10343 Thread* thread = Thread::Current(); |
10885 Zone* zone = thread->zone(); | 10344 Zone* zone = thread->zone(); |
10886 Object& obj = Object::Handle(zone, Object::null()); | 10345 Object& obj = Object::Handle(zone, Object::null()); |
10887 obj = LookupLocalObject(name); | 10346 obj = LookupLocalObject(name); |
10888 if (obj.IsNull() && ShouldBePrivate(name)) { | 10347 if (obj.IsNull() && ShouldBePrivate(name)) { |
10889 String& private_name = String::Handle(zone, PrivateName(name)); | 10348 String& private_name = String::Handle(zone, PrivateName(name)); |
10890 obj = LookupLocalObject(private_name); | 10349 obj = LookupLocalObject(private_name); |
10891 } | 10350 } |
10892 return obj.raw(); | 10351 return obj.raw(); |
10893 } | 10352 } |
10894 | 10353 |
10895 | |
10896 RawObject* Library::LookupObjectAllowPrivate(const String& name) const { | 10354 RawObject* Library::LookupObjectAllowPrivate(const String& name) const { |
10897 // First check if name is found in the local scope of the library. | 10355 // First check if name is found in the local scope of the library. |
10898 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 10356 Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |
10899 if (!obj.IsNull()) { | 10357 if (!obj.IsNull()) { |
10900 return obj.raw(); | 10358 return obj.raw(); |
10901 } | 10359 } |
10902 | 10360 |
10903 // Do not look up private names in imported libraries. | 10361 // Do not look up private names in imported libraries. |
10904 if (ShouldBePrivate(name)) { | 10362 if (ShouldBePrivate(name)) { |
10905 return Object::null(); | 10363 return Object::null(); |
10906 } | 10364 } |
10907 | 10365 |
10908 // Now check if name is found in any imported libs. | 10366 // Now check if name is found in any imported libs. |
10909 return LookupImportedObject(name); | 10367 return LookupImportedObject(name); |
10910 } | 10368 } |
10911 | 10369 |
10912 | |
10913 RawObject* Library::LookupImportedObject(const String& name) const { | 10370 RawObject* Library::LookupImportedObject(const String& name) const { |
10914 Object& obj = Object::Handle(); | 10371 Object& obj = Object::Handle(); |
10915 Namespace& import = Namespace::Handle(); | 10372 Namespace& import = Namespace::Handle(); |
10916 Library& import_lib = Library::Handle(); | 10373 Library& import_lib = Library::Handle(); |
10917 String& import_lib_url = String::Handle(); | 10374 String& import_lib_url = String::Handle(); |
10918 String& first_import_lib_url = String::Handle(); | 10375 String& first_import_lib_url = String::Handle(); |
10919 Object& found_obj = Object::Handle(); | 10376 Object& found_obj = Object::Handle(); |
10920 String& found_obj_name = String::Handle(); | 10377 String& found_obj_name = String::Handle(); |
10921 ASSERT(!ShouldBePrivate(name)); | 10378 ASSERT(!ShouldBePrivate(name)); |
10922 for (intptr_t i = 0; i < num_imports(); i++) { | 10379 for (intptr_t i = 0; i < num_imports(); i++) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10964 if (found_obj_name.Equals(second_obj_name)) { | 10421 if (found_obj_name.Equals(second_obj_name)) { |
10965 return Object::null(); | 10422 return Object::null(); |
10966 } | 10423 } |
10967 } | 10424 } |
10968 } | 10425 } |
10969 } | 10426 } |
10970 } | 10427 } |
10971 return found_obj.raw(); | 10428 return found_obj.raw(); |
10972 } | 10429 } |
10973 | 10430 |
10974 | |
10975 RawClass* Library::LookupClass(const String& name) const { | 10431 RawClass* Library::LookupClass(const String& name) const { |
10976 Object& obj = Object::Handle(ResolveName(name)); | 10432 Object& obj = Object::Handle(ResolveName(name)); |
10977 if (obj.IsClass()) { | 10433 if (obj.IsClass()) { |
10978 return Class::Cast(obj).raw(); | 10434 return Class::Cast(obj).raw(); |
10979 } | 10435 } |
10980 return Class::null(); | 10436 return Class::null(); |
10981 } | 10437 } |
10982 | 10438 |
10983 | |
10984 RawClass* Library::LookupLocalClass(const String& name) const { | 10439 RawClass* Library::LookupLocalClass(const String& name) const { |
10985 Object& obj = Object::Handle(LookupLocalObject(name)); | 10440 Object& obj = Object::Handle(LookupLocalObject(name)); |
10986 if (obj.IsClass()) { | 10441 if (obj.IsClass()) { |
10987 return Class::Cast(obj).raw(); | 10442 return Class::Cast(obj).raw(); |
10988 } | 10443 } |
10989 return Class::null(); | 10444 return Class::null(); |
10990 } | 10445 } |
10991 | 10446 |
10992 | |
10993 RawClass* Library::LookupClassAllowPrivate(const String& name) const { | 10447 RawClass* Library::LookupClassAllowPrivate(const String& name) const { |
10994 // See if the class is available in this library or in the top level | 10448 // See if the class is available in this library or in the top level |
10995 // scope of any imported library. | 10449 // scope of any imported library. |
10996 Zone* zone = Thread::Current()->zone(); | 10450 Zone* zone = Thread::Current()->zone(); |
10997 const Class& cls = Class::Handle(zone, LookupClass(name)); | 10451 const Class& cls = Class::Handle(zone, LookupClass(name)); |
10998 if (!cls.IsNull()) { | 10452 if (!cls.IsNull()) { |
10999 return cls.raw(); | 10453 return cls.raw(); |
11000 } | 10454 } |
11001 | 10455 |
11002 // Now try to lookup the class using its private name, but only in | 10456 // Now try to lookup the class using its private name, but only in |
11003 // this library (not in imported libraries). | 10457 // this library (not in imported libraries). |
11004 if (ShouldBePrivate(name)) { | 10458 if (ShouldBePrivate(name)) { |
11005 String& private_name = String::Handle(zone, PrivateName(name)); | 10459 String& private_name = String::Handle(zone, PrivateName(name)); |
11006 const Object& obj = Object::Handle(LookupLocalObject(private_name)); | 10460 const Object& obj = Object::Handle(LookupLocalObject(private_name)); |
11007 if (obj.IsClass()) { | 10461 if (obj.IsClass()) { |
11008 return Class::Cast(obj).raw(); | 10462 return Class::Cast(obj).raw(); |
11009 } | 10463 } |
11010 } | 10464 } |
11011 return Class::null(); | 10465 return Class::null(); |
11012 } | 10466 } |
11013 | 10467 |
11014 | |
11015 // Mixin applications can have multiple private keys from different libraries. | 10468 // Mixin applications can have multiple private keys from different libraries. |
11016 RawClass* Library::SlowLookupClassAllowMultiPartPrivate( | 10469 RawClass* Library::SlowLookupClassAllowMultiPartPrivate( |
11017 const String& name) const { | 10470 const String& name) const { |
11018 Array& dict = Array::Handle(dictionary()); | 10471 Array& dict = Array::Handle(dictionary()); |
11019 Object& entry = Object::Handle(); | 10472 Object& entry = Object::Handle(); |
11020 String& cls_name = String::Handle(); | 10473 String& cls_name = String::Handle(); |
11021 for (intptr_t i = 0; i < dict.Length(); i++) { | 10474 for (intptr_t i = 0; i < dict.Length(); i++) { |
11022 entry = dict.At(i); | 10475 entry = dict.At(i); |
11023 if (entry.IsClass()) { | 10476 if (entry.IsClass()) { |
11024 cls_name = Class::Cast(entry).Name(); | 10477 cls_name = Class::Cast(entry).Name(); |
11025 // Warning: comparison is not symmetric. | 10478 // Warning: comparison is not symmetric. |
11026 if (String::EqualsIgnoringPrivateKey(cls_name, name)) { | 10479 if (String::EqualsIgnoringPrivateKey(cls_name, name)) { |
11027 return Class::Cast(entry).raw(); | 10480 return Class::Cast(entry).raw(); |
11028 } | 10481 } |
11029 } | 10482 } |
11030 } | 10483 } |
11031 return Class::null(); | 10484 return Class::null(); |
11032 } | 10485 } |
11033 | 10486 |
11034 | |
11035 RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const { | 10487 RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const { |
11036 const Object& obj = Object::Handle(LookupLocalObject(name)); | 10488 const Object& obj = Object::Handle(LookupLocalObject(name)); |
11037 if (obj.IsLibraryPrefix()) { | 10489 if (obj.IsLibraryPrefix()) { |
11038 return LibraryPrefix::Cast(obj).raw(); | 10490 return LibraryPrefix::Cast(obj).raw(); |
11039 } | 10491 } |
11040 return LibraryPrefix::null(); | 10492 return LibraryPrefix::null(); |
11041 } | 10493 } |
11042 | 10494 |
11043 | |
11044 void Library::set_toplevel_class(const Class& value) const { | 10495 void Library::set_toplevel_class(const Class& value) const { |
11045 ASSERT(raw_ptr()->toplevel_class_ == Class::null()); | 10496 ASSERT(raw_ptr()->toplevel_class_ == Class::null()); |
11046 StorePointer(&raw_ptr()->toplevel_class_, value.raw()); | 10497 StorePointer(&raw_ptr()->toplevel_class_, value.raw()); |
11047 } | 10498 } |
11048 | 10499 |
11049 | |
11050 RawLibrary* Library::ImportLibraryAt(intptr_t index) const { | 10500 RawLibrary* Library::ImportLibraryAt(intptr_t index) const { |
11051 Namespace& import = Namespace::Handle(ImportAt(index)); | 10501 Namespace& import = Namespace::Handle(ImportAt(index)); |
11052 if (import.IsNull()) { | 10502 if (import.IsNull()) { |
11053 return Library::null(); | 10503 return Library::null(); |
11054 } | 10504 } |
11055 return import.library(); | 10505 return import.library(); |
11056 } | 10506 } |
11057 | 10507 |
11058 | |
11059 RawNamespace* Library::ImportAt(intptr_t index) const { | 10508 RawNamespace* Library::ImportAt(intptr_t index) const { |
11060 if ((index < 0) || index >= num_imports()) { | 10509 if ((index < 0) || index >= num_imports()) { |
11061 return Namespace::null(); | 10510 return Namespace::null(); |
11062 } | 10511 } |
11063 const Array& import_list = Array::Handle(imports()); | 10512 const Array& import_list = Array::Handle(imports()); |
11064 return Namespace::RawCast(import_list.At(index)); | 10513 return Namespace::RawCast(import_list.At(index)); |
11065 } | 10514 } |
11066 | 10515 |
11067 | |
11068 bool Library::ImportsCorelib() const { | 10516 bool Library::ImportsCorelib() const { |
11069 Zone* zone = Thread::Current()->zone(); | 10517 Zone* zone = Thread::Current()->zone(); |
11070 Library& imported = Library::Handle(zone); | 10518 Library& imported = Library::Handle(zone); |
11071 intptr_t count = num_imports(); | 10519 intptr_t count = num_imports(); |
11072 for (int i = 0; i < count; i++) { | 10520 for (int i = 0; i < count; i++) { |
11073 imported = ImportLibraryAt(i); | 10521 imported = ImportLibraryAt(i); |
11074 if (imported.IsCoreLibrary()) { | 10522 if (imported.IsCoreLibrary()) { |
11075 return true; | 10523 return true; |
11076 } | 10524 } |
11077 } | 10525 } |
11078 LibraryPrefix& prefix = LibraryPrefix::Handle(zone); | 10526 LibraryPrefix& prefix = LibraryPrefix::Handle(zone); |
11079 LibraryPrefixIterator it(*this); | 10527 LibraryPrefixIterator it(*this); |
11080 while (it.HasNext()) { | 10528 while (it.HasNext()) { |
11081 prefix = it.GetNext(); | 10529 prefix = it.GetNext(); |
11082 count = prefix.num_imports(); | 10530 count = prefix.num_imports(); |
11083 for (int i = 0; i < count; i++) { | 10531 for (int i = 0; i < count; i++) { |
11084 imported = prefix.GetLibrary(i); | 10532 imported = prefix.GetLibrary(i); |
11085 if (imported.IsCoreLibrary()) { | 10533 if (imported.IsCoreLibrary()) { |
11086 return true; | 10534 return true; |
11087 } | 10535 } |
11088 } | 10536 } |
11089 } | 10537 } |
11090 return false; | 10538 return false; |
11091 } | 10539 } |
11092 | 10540 |
11093 | |
11094 void Library::DropDependenciesAndCaches() const { | 10541 void Library::DropDependenciesAndCaches() const { |
11095 StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); | 10542 StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); |
11096 StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); | 10543 StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); |
11097 StoreNonPointer(&raw_ptr()->num_imports_, 0); | 10544 StoreNonPointer(&raw_ptr()->num_imports_, 0); |
11098 StorePointer(&raw_ptr()->resolved_names_, Array::null()); | 10545 StorePointer(&raw_ptr()->resolved_names_, Array::null()); |
11099 StorePointer(&raw_ptr()->exported_names_, Array::null()); | 10546 StorePointer(&raw_ptr()->exported_names_, Array::null()); |
11100 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 10547 StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |
11101 } | 10548 } |
11102 | 10549 |
11103 | |
11104 void Library::AddImport(const Namespace& ns) const { | 10550 void Library::AddImport(const Namespace& ns) const { |
11105 Array& imports = Array::Handle(this->imports()); | 10551 Array& imports = Array::Handle(this->imports()); |
11106 intptr_t capacity = imports.Length(); | 10552 intptr_t capacity = imports.Length(); |
11107 if (num_imports() == capacity) { | 10553 if (num_imports() == capacity) { |
11108 capacity = capacity + kImportsCapacityIncrement + (capacity >> 2); | 10554 capacity = capacity + kImportsCapacityIncrement + (capacity >> 2); |
11109 imports = Array::Grow(imports, capacity); | 10555 imports = Array::Grow(imports, capacity); |
11110 StorePointer(&raw_ptr()->imports_, imports.raw()); | 10556 StorePointer(&raw_ptr()->imports_, imports.raw()); |
11111 } | 10557 } |
11112 intptr_t index = num_imports(); | 10558 intptr_t index = num_imports(); |
11113 imports.SetAt(index, ns); | 10559 imports.SetAt(index, ns); |
11114 set_num_imports(index + 1); | 10560 set_num_imports(index + 1); |
11115 } | 10561 } |
11116 | 10562 |
11117 | |
11118 // Convenience function to determine whether the export list is | 10563 // Convenience function to determine whether the export list is |
11119 // non-empty. | 10564 // non-empty. |
11120 bool Library::HasExports() const { | 10565 bool Library::HasExports() const { |
11121 return exports() != Object::empty_array().raw(); | 10566 return exports() != Object::empty_array().raw(); |
11122 } | 10567 } |
11123 | 10568 |
11124 | |
11125 // We add one namespace at a time to the exports array and don't | 10569 // We add one namespace at a time to the exports array and don't |
11126 // pre-allocate any unused capacity. The assumption is that | 10570 // pre-allocate any unused capacity. The assumption is that |
11127 // re-exports are quite rare. | 10571 // re-exports are quite rare. |
11128 void Library::AddExport(const Namespace& ns) const { | 10572 void Library::AddExport(const Namespace& ns) const { |
11129 Array& exports = Array::Handle(this->exports()); | 10573 Array& exports = Array::Handle(this->exports()); |
11130 intptr_t num_exports = exports.Length(); | 10574 intptr_t num_exports = exports.Length(); |
11131 exports = Array::Grow(exports, num_exports + 1); | 10575 exports = Array::Grow(exports, num_exports + 1); |
11132 StorePointer(&raw_ptr()->exports_, exports.raw()); | 10576 StorePointer(&raw_ptr()->exports_, exports.raw()); |
11133 exports.SetAt(num_exports, ns); | 10577 exports.SetAt(num_exports, ns); |
11134 } | 10578 } |
11135 | 10579 |
11136 | |
11137 static RawArray* NewDictionary(intptr_t initial_size) { | 10580 static RawArray* NewDictionary(intptr_t initial_size) { |
11138 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); | 10581 const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); |
11139 // The last element of the dictionary specifies the number of in use slots. | 10582 // The last element of the dictionary specifies the number of in use slots. |
11140 dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); | 10583 dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); |
11141 return dict.raw(); | 10584 return dict.raw(); |
11142 } | 10585 } |
11143 | 10586 |
11144 | |
11145 void Library::InitResolvedNamesCache() const { | 10587 void Library::InitResolvedNamesCache() const { |
11146 ASSERT(Thread::Current()->IsMutatorThread()); | 10588 ASSERT(Thread::Current()->IsMutatorThread()); |
11147 StorePointer(&raw_ptr()->resolved_names_, | 10589 StorePointer(&raw_ptr()->resolved_names_, |
11148 HashTables::New<ResolvedNamesMap>(64)); | 10590 HashTables::New<ResolvedNamesMap>(64)); |
11149 } | 10591 } |
11150 | 10592 |
11151 | |
11152 void Library::ClearResolvedNamesCache() const { | 10593 void Library::ClearResolvedNamesCache() const { |
11153 ASSERT(Thread::Current()->IsMutatorThread()); | 10594 ASSERT(Thread::Current()->IsMutatorThread()); |
11154 StorePointer(&raw_ptr()->resolved_names_, Array::null()); | 10595 StorePointer(&raw_ptr()->resolved_names_, Array::null()); |
11155 } | 10596 } |
11156 | 10597 |
11157 | |
11158 void Library::InitExportedNamesCache() const { | 10598 void Library::InitExportedNamesCache() const { |
11159 StorePointer(&raw_ptr()->exported_names_, | 10599 StorePointer(&raw_ptr()->exported_names_, |
11160 HashTables::New<ResolvedNamesMap>(16)); | 10600 HashTables::New<ResolvedNamesMap>(16)); |
11161 } | 10601 } |
11162 | 10602 |
11163 | |
11164 void Library::ClearExportedNamesCache() const { | 10603 void Library::ClearExportedNamesCache() const { |
11165 StorePointer(&raw_ptr()->exported_names_, Array::null()); | 10604 StorePointer(&raw_ptr()->exported_names_, Array::null()); |
11166 } | 10605 } |
11167 | 10606 |
11168 | |
11169 void Library::InitClassDictionary() const { | 10607 void Library::InitClassDictionary() const { |
11170 // TODO(iposva): Find reasonable initial size. | 10608 // TODO(iposva): Find reasonable initial size. |
11171 const int kInitialElementCount = 16; | 10609 const int kInitialElementCount = 16; |
11172 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); | 10610 StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); |
11173 } | 10611 } |
11174 | 10612 |
11175 | |
11176 void Library::InitImportList() const { | 10613 void Library::InitImportList() const { |
11177 const Array& imports = | 10614 const Array& imports = |
11178 Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); | 10615 Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); |
11179 StorePointer(&raw_ptr()->imports_, imports.raw()); | 10616 StorePointer(&raw_ptr()->imports_, imports.raw()); |
11180 StoreNonPointer(&raw_ptr()->num_imports_, 0); | 10617 StoreNonPointer(&raw_ptr()->num_imports_, 0); |
11181 } | 10618 } |
11182 | 10619 |
11183 | |
11184 RawLibrary* Library::New() { | 10620 RawLibrary* Library::New() { |
11185 ASSERT(Object::library_class() != Class::null()); | 10621 ASSERT(Object::library_class() != Class::null()); |
11186 RawObject* raw = | 10622 RawObject* raw = |
11187 Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld); | 10623 Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld); |
11188 return reinterpret_cast<RawLibrary*>(raw); | 10624 return reinterpret_cast<RawLibrary*>(raw); |
11189 } | 10625 } |
11190 | 10626 |
11191 | |
11192 RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) { | 10627 RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) { |
11193 Thread* thread = Thread::Current(); | 10628 Thread* thread = Thread::Current(); |
11194 Zone* zone = thread->zone(); | 10629 Zone* zone = thread->zone(); |
11195 ASSERT(thread->IsMutatorThread()); | 10630 ASSERT(thread->IsMutatorThread()); |
11196 // Force the url to have a hash code. | 10631 // Force the url to have a hash code. |
11197 url.Hash(); | 10632 url.Hash(); |
11198 const bool dart_scheme = url.StartsWith(Symbols::DartScheme()); | 10633 const bool dart_scheme = url.StartsWith(Symbols::DartScheme()); |
11199 const bool dart_private_scheme = | 10634 const bool dart_private_scheme = |
11200 dart_scheme && url.StartsWith(Symbols::DartSchemePrivate()); | 10635 dart_scheme && url.StartsWith(Symbols::DartSchemePrivate()); |
11201 const Library& result = Library::Handle(zone, Library::New()); | 10636 const Library& result = Library::Handle(zone, Library::New()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11241 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); | 10676 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); |
11242 ASSERT(!core_lib.IsNull()); | 10677 ASSERT(!core_lib.IsNull()); |
11243 const Namespace& ns = Namespace::Handle( | 10678 const Namespace& ns = Namespace::Handle( |
11244 zone, | 10679 zone, |
11245 Namespace::New(core_lib, Object::null_array(), Object::null_array())); | 10680 Namespace::New(core_lib, Object::null_array(), Object::null_array())); |
11246 result.AddImport(ns); | 10681 result.AddImport(ns); |
11247 } | 10682 } |
11248 return result.raw(); | 10683 return result.raw(); |
11249 } | 10684 } |
11250 | 10685 |
11251 | |
11252 RawLibrary* Library::New(const String& url) { | 10686 RawLibrary* Library::New(const String& url) { |
11253 return NewLibraryHelper(url, false); | 10687 return NewLibraryHelper(url, false); |
11254 } | 10688 } |
11255 | 10689 |
11256 | |
11257 void Library::InitCoreLibrary(Isolate* isolate) { | 10690 void Library::InitCoreLibrary(Isolate* isolate) { |
11258 Thread* thread = Thread::Current(); | 10691 Thread* thread = Thread::Current(); |
11259 Zone* zone = thread->zone(); | 10692 Zone* zone = thread->zone(); |
11260 const String& core_lib_url = Symbols::DartCore(); | 10693 const String& core_lib_url = Symbols::DartCore(); |
11261 const Library& core_lib = | 10694 const Library& core_lib = |
11262 Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false)); | 10695 Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false)); |
11263 core_lib.SetLoadRequested(); | 10696 core_lib.SetLoadRequested(); |
11264 core_lib.Register(thread); | 10697 core_lib.Register(thread); |
11265 isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib); | 10698 isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib); |
11266 isolate->object_store()->set_root_library(Library::Handle()); | 10699 isolate->object_store()->set_root_library(Library::Handle()); |
11267 | 10700 |
11268 // Hook up predefined classes without setting their library pointers. These | 10701 // Hook up predefined classes without setting their library pointers. These |
11269 // classes are coming from the VM isolate, and are shared between multiple | 10702 // classes are coming from the VM isolate, and are shared between multiple |
11270 // isolates so setting their library pointers would be wrong. | 10703 // isolates so setting their library pointers would be wrong. |
11271 const Class& cls = Class::Handle(zone, Object::dynamic_class()); | 10704 const Class& cls = Class::Handle(zone, Object::dynamic_class()); |
11272 core_lib.AddObject(cls, String::Handle(zone, cls.Name())); | 10705 core_lib.AddObject(cls, String::Handle(zone, cls.Name())); |
11273 } | 10706 } |
11274 | 10707 |
11275 | |
11276 RawObject* Library::Evaluate(const String& expr, | 10708 RawObject* Library::Evaluate(const String& expr, |
11277 const Array& param_names, | 10709 const Array& param_names, |
11278 const Array& param_values) const { | 10710 const Array& param_values) const { |
11279 // Evaluate the expression as a static function of the toplevel class. | 10711 // Evaluate the expression as a static function of the toplevel class. |
11280 Class& top_level_class = Class::Handle(toplevel_class()); | 10712 Class& top_level_class = Class::Handle(toplevel_class()); |
11281 ASSERT(top_level_class.is_finalized()); | 10713 ASSERT(top_level_class.is_finalized()); |
11282 return top_level_class.Evaluate(expr, param_names, param_values); | 10714 return top_level_class.Evaluate(expr, param_names, param_values); |
11283 } | 10715 } |
11284 | 10716 |
11285 | |
11286 void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) { | 10717 void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) { |
11287 static const int kNumNativeWrappersClasses = 4; | 10718 static const int kNumNativeWrappersClasses = 4; |
11288 COMPILE_ASSERT((kNumNativeWrappersClasses > 0) && | 10719 COMPILE_ASSERT((kNumNativeWrappersClasses > 0) && |
11289 (kNumNativeWrappersClasses < 10)); | 10720 (kNumNativeWrappersClasses < 10)); |
11290 Thread* thread = Thread::Current(); | 10721 Thread* thread = Thread::Current(); |
11291 Zone* zone = thread->zone(); | 10722 Zone* zone = thread->zone(); |
11292 const String& native_flds_lib_url = Symbols::DartNativeWrappers(); | 10723 const String& native_flds_lib_url = Symbols::DartNativeWrappers(); |
11293 const Library& native_flds_lib = Library::Handle( | 10724 const Library& native_flds_lib = Library::Handle( |
11294 zone, Library::NewLibraryHelper(native_flds_lib_url, false)); | 10725 zone, Library::NewLibraryHelper(native_flds_lib_url, false)); |
11295 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); | 10726 const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); |
(...skipping 14 matching lines...) Expand all Loading... |
11310 Class::NewNativeWrapper(native_flds_lib, cls_name, fld_cnt); | 10741 Class::NewNativeWrapper(native_flds_lib, cls_name, fld_cnt); |
11311 } | 10742 } |
11312 // NOTE: If we bootstrap from a Kernel IR file we want to generate the | 10743 // NOTE: If we bootstrap from a Kernel IR file we want to generate the |
11313 // synthetic constructors for the native wrapper classes. We leave this up to | 10744 // synthetic constructors for the native wrapper classes. We leave this up to |
11314 // the [KernelReader] who will take care of it later. | 10745 // the [KernelReader] who will take care of it later. |
11315 if (!is_kernel) { | 10746 if (!is_kernel) { |
11316 native_flds_lib.SetLoaded(); | 10747 native_flds_lib.SetLoaded(); |
11317 } | 10748 } |
11318 } | 10749 } |
11319 | 10750 |
11320 | |
11321 // LibraryLookupSet maps URIs to libraries. | 10751 // LibraryLookupSet maps URIs to libraries. |
11322 class LibraryLookupTraits { | 10752 class LibraryLookupTraits { |
11323 public: | 10753 public: |
11324 static const char* Name() { return "LibraryLookupTraits"; } | 10754 static const char* Name() { return "LibraryLookupTraits"; } |
11325 static bool ReportStats() { return false; } | 10755 static bool ReportStats() { return false; } |
11326 | 10756 |
11327 static bool IsMatch(const Object& a, const Object& b) { | 10757 static bool IsMatch(const Object& a, const Object& b) { |
11328 const String& a_str = String::Cast(a); | 10758 const String& a_str = String::Cast(a); |
11329 const String& b_str = String::Cast(b); | 10759 const String& b_str = String::Cast(b); |
11330 | 10760 |
11331 ASSERT(a_str.HasHash() && b_str.HasHash()); | 10761 ASSERT(a_str.HasHash() && b_str.HasHash()); |
11332 return a_str.Equals(b_str); | 10762 return a_str.Equals(b_str); |
11333 } | 10763 } |
11334 | 10764 |
11335 static uword Hash(const Object& key) { return String::Cast(key).Hash(); } | 10765 static uword Hash(const Object& key) { return String::Cast(key).Hash(); } |
11336 | 10766 |
11337 static RawObject* NewKey(const String& str) { return str.raw(); } | 10767 static RawObject* NewKey(const String& str) { return str.raw(); } |
11338 }; | 10768 }; |
11339 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap; | 10769 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap; |
11340 | 10770 |
11341 | |
11342 // Returns library with given url in current isolate, or NULL. | 10771 // Returns library with given url in current isolate, or NULL. |
11343 RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) { | 10772 RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) { |
11344 Zone* zone = thread->zone(); | 10773 Zone* zone = thread->zone(); |
11345 Isolate* isolate = thread->isolate(); | 10774 Isolate* isolate = thread->isolate(); |
11346 ObjectStore* object_store = isolate->object_store(); | 10775 ObjectStore* object_store = isolate->object_store(); |
11347 | 10776 |
11348 // Make sure the URL string has an associated hash code | 10777 // Make sure the URL string has an associated hash code |
11349 // to speed up the repeated equality checks. | 10778 // to speed up the repeated equality checks. |
11350 url.Hash(); | 10779 url.Hash(); |
11351 | 10780 |
11352 // Use the libraries map to lookup the library by URL. | 10781 // Use the libraries map to lookup the library by URL. |
11353 Library& lib = Library::Handle(zone); | 10782 Library& lib = Library::Handle(zone); |
11354 if (object_store->libraries_map() == Array::null()) { | 10783 if (object_store->libraries_map() == Array::null()) { |
11355 return Library::null(); | 10784 return Library::null(); |
11356 } else { | 10785 } else { |
11357 LibraryLookupMap map(object_store->libraries_map()); | 10786 LibraryLookupMap map(object_store->libraries_map()); |
11358 lib ^= map.GetOrNull(url); | 10787 lib ^= map.GetOrNull(url); |
11359 ASSERT(map.Release().raw() == object_store->libraries_map()); | 10788 ASSERT(map.Release().raw() == object_store->libraries_map()); |
11360 } | 10789 } |
11361 return lib.raw(); | 10790 return lib.raw(); |
11362 } | 10791 } |
11363 | 10792 |
11364 | |
11365 RawError* Library::Patch(const Script& script) const { | 10793 RawError* Library::Patch(const Script& script) const { |
11366 ASSERT(script.kind() == RawScript::kPatchTag); | 10794 ASSERT(script.kind() == RawScript::kPatchTag); |
11367 return Compiler::Compile(*this, script); | 10795 return Compiler::Compile(*this, script); |
11368 } | 10796 } |
11369 | 10797 |
11370 | |
11371 bool Library::IsPrivate(const String& name) { | 10798 bool Library::IsPrivate(const String& name) { |
11372 if (ShouldBePrivate(name)) return true; | 10799 if (ShouldBePrivate(name)) return true; |
11373 // Factory names: List._fromLiteral. | 10800 // Factory names: List._fromLiteral. |
11374 for (intptr_t i = 1; i < name.Length() - 1; i++) { | 10801 for (intptr_t i = 1; i < name.Length() - 1; i++) { |
11375 if (name.CharAt(i) == '.') { | 10802 if (name.CharAt(i) == '.') { |
11376 if (name.CharAt(i + 1) == '_') { | 10803 if (name.CharAt(i + 1) == '_') { |
11377 return true; | 10804 return true; |
11378 } | 10805 } |
11379 } | 10806 } |
11380 } | 10807 } |
11381 return false; | 10808 return false; |
11382 } | 10809 } |
11383 | 10810 |
11384 | |
11385 // Create a private key for this library. It is based on the hash of the | 10811 // Create a private key for this library. It is based on the hash of the |
11386 // library URI and the sequence number of the library to guarantee unique | 10812 // library URI and the sequence number of the library to guarantee unique |
11387 // private keys without having to verify. | 10813 // private keys without having to verify. |
11388 void Library::AllocatePrivateKey() const { | 10814 void Library::AllocatePrivateKey() const { |
11389 Thread* thread = Thread::Current(); | 10815 Thread* thread = Thread::Current(); |
11390 Zone* zone = thread->zone(); | 10816 Zone* zone = thread->zone(); |
11391 Isolate* isolate = thread->isolate(); | 10817 Isolate* isolate = thread->isolate(); |
11392 | 10818 |
11393 if (FLAG_support_reload && isolate->IsReloading()) { | 10819 if (FLAG_support_reload && isolate->IsReloading()) { |
11394 // When reloading, we need to make sure we use the original private key | 10820 // When reloading, we need to make sure we use the original private key |
(...skipping 19 matching lines...) Expand all Loading... |
11414 | 10840 |
11415 char private_key[32]; | 10841 char private_key[32]; |
11416 OS::SNPrint(private_key, sizeof(private_key), "%c%" Pd "%06" Pd "", | 10842 OS::SNPrint(private_key, sizeof(private_key), "%c%" Pd "%06" Pd "", |
11417 kPrivateKeySeparator, sequence_value, hash_value); | 10843 kPrivateKeySeparator, sequence_value, hash_value); |
11418 const String& key = | 10844 const String& key = |
11419 String::Handle(zone, String::New(private_key, Heap::kOld)); | 10845 String::Handle(zone, String::New(private_key, Heap::kOld)); |
11420 key.Hash(); // This string may end up in the VM isolate. | 10846 key.Hash(); // This string may end up in the VM isolate. |
11421 StorePointer(&raw_ptr()->private_key_, key.raw()); | 10847 StorePointer(&raw_ptr()->private_key_, key.raw()); |
11422 } | 10848 } |
11423 | 10849 |
11424 | |
11425 const String& Library::PrivateCoreLibName(const String& member) { | 10850 const String& Library::PrivateCoreLibName(const String& member) { |
11426 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 10851 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
11427 const String& private_name = String::ZoneHandle(core_lib.PrivateName(member)); | 10852 const String& private_name = String::ZoneHandle(core_lib.PrivateName(member)); |
11428 return private_name; | 10853 return private_name; |
11429 } | 10854 } |
11430 | 10855 |
11431 | |
11432 RawClass* Library::LookupCoreClass(const String& class_name) { | 10856 RawClass* Library::LookupCoreClass(const String& class_name) { |
11433 Thread* thread = Thread::Current(); | 10857 Thread* thread = Thread::Current(); |
11434 Zone* zone = thread->zone(); | 10858 Zone* zone = thread->zone(); |
11435 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); | 10859 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); |
11436 String& name = String::Handle(zone, class_name.raw()); | 10860 String& name = String::Handle(zone, class_name.raw()); |
11437 if (class_name.CharAt(0) == kPrivateIdentifierStart) { | 10861 if (class_name.CharAt(0) == kPrivateIdentifierStart) { |
11438 // Private identifiers are mangled on a per library basis. | 10862 // Private identifiers are mangled on a per library basis. |
11439 name = Symbols::FromConcat(thread, name, | 10863 name = Symbols::FromConcat(thread, name, |
11440 String::Handle(zone, core_lib.private_key())); | 10864 String::Handle(zone, core_lib.private_key())); |
11441 } | 10865 } |
11442 return core_lib.LookupClass(name); | 10866 return core_lib.LookupClass(name); |
11443 } | 10867 } |
11444 | 10868 |
11445 | |
11446 // Cannot handle qualified names properly as it only appends private key to | 10869 // Cannot handle qualified names properly as it only appends private key to |
11447 // the end (e.g. _Alfa.foo -> _Alfa.foo@...). | 10870 // the end (e.g. _Alfa.foo -> _Alfa.foo@...). |
11448 RawString* Library::PrivateName(const String& name) const { | 10871 RawString* Library::PrivateName(const String& name) const { |
11449 Thread* thread = Thread::Current(); | 10872 Thread* thread = Thread::Current(); |
11450 Zone* zone = thread->zone(); | 10873 Zone* zone = thread->zone(); |
11451 ASSERT(IsPrivate(name)); | 10874 ASSERT(IsPrivate(name)); |
11452 // ASSERT(strchr(name, '@') == NULL); | 10875 // ASSERT(strchr(name, '@') == NULL); |
11453 String& str = String::Handle(zone); | 10876 String& str = String::Handle(zone); |
11454 str = name.raw(); | 10877 str = name.raw(); |
11455 str = Symbols::FromConcat(thread, str, | 10878 str = Symbols::FromConcat(thread, str, |
11456 String::Handle(zone, this->private_key())); | 10879 String::Handle(zone, this->private_key())); |
11457 return str.raw(); | 10880 return str.raw(); |
11458 } | 10881 } |
11459 | 10882 |
11460 | |
11461 RawLibrary* Library::GetLibrary(intptr_t index) { | 10883 RawLibrary* Library::GetLibrary(intptr_t index) { |
11462 Thread* thread = Thread::Current(); | 10884 Thread* thread = Thread::Current(); |
11463 Zone* zone = thread->zone(); | 10885 Zone* zone = thread->zone(); |
11464 Isolate* isolate = thread->isolate(); | 10886 Isolate* isolate = thread->isolate(); |
11465 const GrowableObjectArray& libs = | 10887 const GrowableObjectArray& libs = |
11466 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 10888 GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |
11467 ASSERT(!libs.IsNull()); | 10889 ASSERT(!libs.IsNull()); |
11468 if ((0 <= index) && (index < libs.Length())) { | 10890 if ((0 <= index) && (index < libs.Length())) { |
11469 Library& lib = Library::Handle(zone); | 10891 Library& lib = Library::Handle(zone); |
11470 lib ^= libs.At(index); | 10892 lib ^= libs.At(index); |
11471 return lib.raw(); | 10893 return lib.raw(); |
11472 } | 10894 } |
11473 return Library::null(); | 10895 return Library::null(); |
11474 } | 10896 } |
11475 | 10897 |
11476 | |
11477 void Library::Register(Thread* thread) const { | 10898 void Library::Register(Thread* thread) const { |
11478 Zone* zone = thread->zone(); | 10899 Zone* zone = thread->zone(); |
11479 Isolate* isolate = thread->isolate(); | 10900 Isolate* isolate = thread->isolate(); |
11480 ObjectStore* object_store = isolate->object_store(); | 10901 ObjectStore* object_store = isolate->object_store(); |
11481 | 10902 |
11482 // A library is "registered" in two places: | 10903 // A library is "registered" in two places: |
11483 // - A growable array mapping from index to library. | 10904 // - A growable array mapping from index to library. |
11484 const String& lib_url = String::Handle(zone, url()); | 10905 const String& lib_url = String::Handle(zone, url()); |
11485 ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null()); | 10906 ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null()); |
11486 ASSERT(lib_url.HasHash()); | 10907 ASSERT(lib_url.HasHash()); |
11487 GrowableObjectArray& libs = | 10908 GrowableObjectArray& libs = |
11488 GrowableObjectArray::Handle(zone, object_store->libraries()); | 10909 GrowableObjectArray::Handle(zone, object_store->libraries()); |
11489 ASSERT(!libs.IsNull()); | 10910 ASSERT(!libs.IsNull()); |
11490 set_index(libs.Length()); | 10911 set_index(libs.Length()); |
11491 libs.Add(*this); | 10912 libs.Add(*this); |
11492 | 10913 |
11493 // - A map from URL string to library. | 10914 // - A map from URL string to library. |
11494 if (object_store->libraries_map() == Array::null()) { | 10915 if (object_store->libraries_map() == Array::null()) { |
11495 LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); | 10916 LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); |
11496 object_store->set_libraries_map(map.Release()); | 10917 object_store->set_libraries_map(map.Release()); |
11497 } | 10918 } |
11498 | 10919 |
11499 LibraryLookupMap map(object_store->libraries_map()); | 10920 LibraryLookupMap map(object_store->libraries_map()); |
11500 bool present = map.UpdateOrInsert(lib_url, *this); | 10921 bool present = map.UpdateOrInsert(lib_url, *this); |
11501 ASSERT(!present); | 10922 ASSERT(!present); |
11502 object_store->set_libraries_map(map.Release()); | 10923 object_store->set_libraries_map(map.Release()); |
11503 } | 10924 } |
11504 | 10925 |
11505 | |
11506 void Library::RegisterLibraries(Thread* thread, | 10926 void Library::RegisterLibraries(Thread* thread, |
11507 const GrowableObjectArray& libs) { | 10927 const GrowableObjectArray& libs) { |
11508 Zone* zone = thread->zone(); | 10928 Zone* zone = thread->zone(); |
11509 Isolate* isolate = thread->isolate(); | 10929 Isolate* isolate = thread->isolate(); |
11510 Library& lib = Library::Handle(zone); | 10930 Library& lib = Library::Handle(zone); |
11511 String& lib_url = String::Handle(zone); | 10931 String& lib_url = String::Handle(zone); |
11512 | 10932 |
11513 LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); | 10933 LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); |
11514 | 10934 |
11515 intptr_t len = libs.Length(); | 10935 intptr_t len = libs.Length(); |
11516 for (intptr_t i = 0; i < len; i++) { | 10936 for (intptr_t i = 0; i < len; i++) { |
11517 lib ^= libs.At(i); | 10937 lib ^= libs.At(i); |
11518 lib_url = lib.url(); | 10938 lib_url = lib.url(); |
11519 map.InsertNewOrGetValue(lib_url, lib); | 10939 map.InsertNewOrGetValue(lib_url, lib); |
11520 } | 10940 } |
11521 // Now rememeber these in the isolate's object store. | 10941 // Now rememeber these in the isolate's object store. |
11522 isolate->object_store()->set_libraries(libs); | 10942 isolate->object_store()->set_libraries(libs); |
11523 isolate->object_store()->set_libraries_map(map.Release()); | 10943 isolate->object_store()->set_libraries_map(map.Release()); |
11524 } | 10944 } |
11525 | 10945 |
11526 | |
11527 RawLibrary* Library::AsyncLibrary() { | 10946 RawLibrary* Library::AsyncLibrary() { |
11528 return Isolate::Current()->object_store()->async_library(); | 10947 return Isolate::Current()->object_store()->async_library(); |
11529 } | 10948 } |
11530 | 10949 |
11531 | |
11532 RawLibrary* Library::ConvertLibrary() { | 10950 RawLibrary* Library::ConvertLibrary() { |
11533 return Isolate::Current()->object_store()->convert_library(); | 10951 return Isolate::Current()->object_store()->convert_library(); |
11534 } | 10952 } |
11535 | 10953 |
11536 | |
11537 RawLibrary* Library::CoreLibrary() { | 10954 RawLibrary* Library::CoreLibrary() { |
11538 return Isolate::Current()->object_store()->core_library(); | 10955 return Isolate::Current()->object_store()->core_library(); |
11539 } | 10956 } |
11540 | 10957 |
11541 | |
11542 RawLibrary* Library::CollectionLibrary() { | 10958 RawLibrary* Library::CollectionLibrary() { |
11543 return Isolate::Current()->object_store()->collection_library(); | 10959 return Isolate::Current()->object_store()->collection_library(); |
11544 } | 10960 } |
11545 | 10961 |
11546 | |
11547 RawLibrary* Library::DeveloperLibrary() { | 10962 RawLibrary* Library::DeveloperLibrary() { |
11548 return Isolate::Current()->object_store()->developer_library(); | 10963 return Isolate::Current()->object_store()->developer_library(); |
11549 } | 10964 } |
11550 | 10965 |
11551 | |
11552 RawLibrary* Library::InternalLibrary() { | 10966 RawLibrary* Library::InternalLibrary() { |
11553 return Isolate::Current()->object_store()->_internal_library(); | 10967 return Isolate::Current()->object_store()->_internal_library(); |
11554 } | 10968 } |
11555 | 10969 |
11556 | |
11557 RawLibrary* Library::IsolateLibrary() { | 10970 RawLibrary* Library::IsolateLibrary() { |
11558 return Isolate::Current()->object_store()->isolate_library(); | 10971 return Isolate::Current()->object_store()->isolate_library(); |
11559 } | 10972 } |
11560 | 10973 |
11561 | |
11562 RawLibrary* Library::MathLibrary() { | 10974 RawLibrary* Library::MathLibrary() { |
11563 return Isolate::Current()->object_store()->math_library(); | 10975 return Isolate::Current()->object_store()->math_library(); |
11564 } | 10976 } |
11565 | 10977 |
11566 | |
11567 #if !defined(PRODUCT) | 10978 #if !defined(PRODUCT) |
11568 RawLibrary* Library::MirrorsLibrary() { | 10979 RawLibrary* Library::MirrorsLibrary() { |
11569 return Isolate::Current()->object_store()->mirrors_library(); | 10980 return Isolate::Current()->object_store()->mirrors_library(); |
11570 } | 10981 } |
11571 #endif | 10982 #endif |
11572 | 10983 |
11573 | |
11574 RawLibrary* Library::NativeWrappersLibrary() { | 10984 RawLibrary* Library::NativeWrappersLibrary() { |
11575 return Isolate::Current()->object_store()->native_wrappers_library(); | 10985 return Isolate::Current()->object_store()->native_wrappers_library(); |
11576 } | 10986 } |
11577 | 10987 |
11578 | |
11579 RawLibrary* Library::ProfilerLibrary() { | 10988 RawLibrary* Library::ProfilerLibrary() { |
11580 return Isolate::Current()->object_store()->profiler_library(); | 10989 return Isolate::Current()->object_store()->profiler_library(); |
11581 } | 10990 } |
11582 | 10991 |
11583 | |
11584 RawLibrary* Library::TypedDataLibrary() { | 10992 RawLibrary* Library::TypedDataLibrary() { |
11585 return Isolate::Current()->object_store()->typed_data_library(); | 10993 return Isolate::Current()->object_store()->typed_data_library(); |
11586 } | 10994 } |
11587 | 10995 |
11588 | |
11589 RawLibrary* Library::VMServiceLibrary() { | 10996 RawLibrary* Library::VMServiceLibrary() { |
11590 return Isolate::Current()->object_store()->_vmservice_library(); | 10997 return Isolate::Current()->object_store()->_vmservice_library(); |
11591 } | 10998 } |
11592 | 10999 |
11593 | |
11594 const char* Library::ToCString() const { | 11000 const char* Library::ToCString() const { |
11595 const String& name = String::Handle(url()); | 11001 const String& name = String::Handle(url()); |
11596 return OS::SCreate(Thread::Current()->zone(), "Library:'%s'", | 11002 return OS::SCreate(Thread::Current()->zone(), "Library:'%s'", |
11597 name.ToCString()); | 11003 name.ToCString()); |
11598 } | 11004 } |
11599 | 11005 |
11600 | |
11601 RawLibrary* LibraryPrefix::GetLibrary(int index) const { | 11006 RawLibrary* LibraryPrefix::GetLibrary(int index) const { |
11602 if ((index >= 0) || (index < num_imports())) { | 11007 if ((index >= 0) || (index < num_imports())) { |
11603 const Array& imports = Array::Handle(this->imports()); | 11008 const Array& imports = Array::Handle(this->imports()); |
11604 Namespace& import = Namespace::Handle(); | 11009 Namespace& import = Namespace::Handle(); |
11605 import ^= imports.At(index); | 11010 import ^= imports.At(index); |
11606 return import.library(); | 11011 return import.library(); |
11607 } | 11012 } |
11608 return Library::null(); | 11013 return Library::null(); |
11609 } | 11014 } |
11610 | 11015 |
11611 | |
11612 RawInstance* LibraryPrefix::LoadError() const { | 11016 RawInstance* LibraryPrefix::LoadError() const { |
11613 Thread* thread = Thread::Current(); | 11017 Thread* thread = Thread::Current(); |
11614 Isolate* isolate = thread->isolate(); | 11018 Isolate* isolate = thread->isolate(); |
11615 Zone* zone = thread->zone(); | 11019 Zone* zone = thread->zone(); |
11616 ObjectStore* object_store = isolate->object_store(); | 11020 ObjectStore* object_store = isolate->object_store(); |
11617 GrowableObjectArray& libs = | 11021 GrowableObjectArray& libs = |
11618 GrowableObjectArray::Handle(zone, object_store->libraries()); | 11022 GrowableObjectArray::Handle(zone, object_store->libraries()); |
11619 ASSERT(!libs.IsNull()); | 11023 ASSERT(!libs.IsNull()); |
11620 LibraryLoadErrorSet set(HashTables::New<LibraryLoadErrorSet>(libs.Length())); | 11024 LibraryLoadErrorSet set(HashTables::New<LibraryLoadErrorSet>(libs.Length())); |
11621 object_store->set_library_load_error_table(set.Release()); | 11025 object_store->set_library_load_error_table(set.Release()); |
11622 Library& lib = Library::Handle(zone); | 11026 Library& lib = Library::Handle(zone); |
11623 Instance& error = Instance::Handle(zone); | 11027 Instance& error = Instance::Handle(zone); |
11624 for (int32_t i = 0; i < num_imports(); i++) { | 11028 for (int32_t i = 0; i < num_imports(); i++) { |
11625 lib = GetLibrary(i); | 11029 lib = GetLibrary(i); |
11626 ASSERT(!lib.IsNull()); | 11030 ASSERT(!lib.IsNull()); |
11627 HANDLESCOPE(thread); | 11031 HANDLESCOPE(thread); |
11628 error = lib.TransitiveLoadError(); | 11032 error = lib.TransitiveLoadError(); |
11629 if (!error.IsNull()) { | 11033 if (!error.IsNull()) { |
11630 break; | 11034 break; |
11631 } | 11035 } |
11632 } | 11036 } |
11633 object_store->set_library_load_error_table(Object::empty_array()); | 11037 object_store->set_library_load_error_table(Object::empty_array()); |
11634 return error.raw(); | 11038 return error.raw(); |
11635 } | 11039 } |
11636 | 11040 |
11637 | |
11638 bool LibraryPrefix::ContainsLibrary(const Library& library) const { | 11041 bool LibraryPrefix::ContainsLibrary(const Library& library) const { |
11639 int32_t num_current_imports = num_imports(); | 11042 int32_t num_current_imports = num_imports(); |
11640 if (num_current_imports > 0) { | 11043 if (num_current_imports > 0) { |
11641 Library& lib = Library::Handle(); | 11044 Library& lib = Library::Handle(); |
11642 const String& url = String::Handle(library.url()); | 11045 const String& url = String::Handle(library.url()); |
11643 String& lib_url = String::Handle(); | 11046 String& lib_url = String::Handle(); |
11644 for (int32_t i = 0; i < num_current_imports; i++) { | 11047 for (int32_t i = 0; i < num_current_imports; i++) { |
11645 lib = GetLibrary(i); | 11048 lib = GetLibrary(i); |
11646 ASSERT(!lib.IsNull()); | 11049 ASSERT(!lib.IsNull()); |
11647 lib_url = lib.url(); | 11050 lib_url = lib.url(); |
11648 if (url.Equals(lib_url)) { | 11051 if (url.Equals(lib_url)) { |
11649 return true; | 11052 return true; |
11650 } | 11053 } |
11651 } | 11054 } |
11652 } | 11055 } |
11653 return false; | 11056 return false; |
11654 } | 11057 } |
11655 | 11058 |
11656 | |
11657 void LibraryPrefix::AddImport(const Namespace& import) const { | 11059 void LibraryPrefix::AddImport(const Namespace& import) const { |
11658 intptr_t num_current_imports = num_imports(); | 11060 intptr_t num_current_imports = num_imports(); |
11659 | 11061 |
11660 // Prefixes with deferred libraries can only contain one library. | 11062 // Prefixes with deferred libraries can only contain one library. |
11661 ASSERT((num_current_imports == 0) || !is_deferred_load()); | 11063 ASSERT((num_current_imports == 0) || !is_deferred_load()); |
11662 | 11064 |
11663 // The library needs to be added to the list. | 11065 // The library needs to be added to the list. |
11664 Array& imports = Array::Handle(this->imports()); | 11066 Array& imports = Array::Handle(this->imports()); |
11665 const intptr_t length = (imports.IsNull()) ? 0 : imports.Length(); | 11067 const intptr_t length = (imports.IsNull()) ? 0 : imports.Length(); |
11666 // Grow the list if it is full. | 11068 // Grow the list if it is full. |
11667 if (num_current_imports >= length) { | 11069 if (num_current_imports >= length) { |
11668 const intptr_t new_length = length + kIncrementSize + (length >> 2); | 11070 const intptr_t new_length = length + kIncrementSize + (length >> 2); |
11669 imports = Array::Grow(imports, new_length, Heap::kOld); | 11071 imports = Array::Grow(imports, new_length, Heap::kOld); |
11670 set_imports(imports); | 11072 set_imports(imports); |
11671 } | 11073 } |
11672 imports.SetAt(num_current_imports, import); | 11074 imports.SetAt(num_current_imports, import); |
11673 set_num_imports(num_current_imports + 1); | 11075 set_num_imports(num_current_imports + 1); |
11674 } | 11076 } |
11675 | 11077 |
11676 | |
11677 RawObject* LibraryPrefix::LookupObject(const String& name) const { | 11078 RawObject* LibraryPrefix::LookupObject(const String& name) const { |
11678 if (!is_loaded() && !FLAG_load_deferred_eagerly) { | 11079 if (!is_loaded() && !FLAG_load_deferred_eagerly) { |
11679 return Object::null(); | 11080 return Object::null(); |
11680 } | 11081 } |
11681 Array& imports = Array::Handle(this->imports()); | 11082 Array& imports = Array::Handle(this->imports()); |
11682 Object& obj = Object::Handle(); | 11083 Object& obj = Object::Handle(); |
11683 Namespace& import = Namespace::Handle(); | 11084 Namespace& import = Namespace::Handle(); |
11684 Library& import_lib = Library::Handle(); | 11085 Library& import_lib = Library::Handle(); |
11685 String& import_lib_url = String::Handle(); | 11086 String& import_lib_url = String::Handle(); |
11686 String& first_import_lib_url = String::Handle(); | 11087 String& first_import_lib_url = String::Handle(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11731 if (found_obj_name.Equals(second_obj_name)) { | 11132 if (found_obj_name.Equals(second_obj_name)) { |
11732 return Object::null(); | 11133 return Object::null(); |
11733 } | 11134 } |
11734 } | 11135 } |
11735 } | 11136 } |
11736 } | 11137 } |
11737 } | 11138 } |
11738 return found_obj.raw(); | 11139 return found_obj.raw(); |
11739 } | 11140 } |
11740 | 11141 |
11741 | |
11742 RawClass* LibraryPrefix::LookupClass(const String& class_name) const { | 11142 RawClass* LibraryPrefix::LookupClass(const String& class_name) const { |
11743 const Object& obj = Object::Handle(LookupObject(class_name)); | 11143 const Object& obj = Object::Handle(LookupObject(class_name)); |
11744 if (obj.IsClass()) { | 11144 if (obj.IsClass()) { |
11745 return Class::Cast(obj).raw(); | 11145 return Class::Cast(obj).raw(); |
11746 } | 11146 } |
11747 return Class::null(); | 11147 return Class::null(); |
11748 } | 11148 } |
11749 | 11149 |
11750 | |
11751 void LibraryPrefix::set_is_loaded() const { | 11150 void LibraryPrefix::set_is_loaded() const { |
11752 StoreNonPointer(&raw_ptr()->is_loaded_, true); | 11151 StoreNonPointer(&raw_ptr()->is_loaded_, true); |
11753 } | 11152 } |
11754 | 11153 |
11755 | |
11756 bool LibraryPrefix::LoadLibrary() const { | 11154 bool LibraryPrefix::LoadLibrary() const { |
11757 // Non-deferred prefixes are loaded. | 11155 // Non-deferred prefixes are loaded. |
11758 ASSERT(is_deferred_load() || is_loaded()); | 11156 ASSERT(is_deferred_load() || is_loaded()); |
11759 if (is_loaded()) { | 11157 if (is_loaded()) { |
11760 return true; // Load request has already completed. | 11158 return true; // Load request has already completed. |
11761 } | 11159 } |
11762 ASSERT(is_deferred_load()); | 11160 ASSERT(is_deferred_load()); |
11763 ASSERT(num_imports() == 1); | 11161 ASSERT(num_imports() == 1); |
11764 if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) { | 11162 if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) { |
11765 // The library list was tree-shaken away. | 11163 // The library list was tree-shaken away. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11799 if (obj.IsError()) { | 11197 if (obj.IsError()) { |
11800 Exceptions::PropagateError(Error::Cast(obj)); | 11198 Exceptions::PropagateError(Error::Cast(obj)); |
11801 } | 11199 } |
11802 } else { | 11200 } else { |
11803 // Another load request is in flight or previously failed. | 11201 // Another load request is in flight or previously failed. |
11804 ASSERT(deferred_lib.LoadRequested() || deferred_lib.LoadFailed()); | 11202 ASSERT(deferred_lib.LoadRequested() || deferred_lib.LoadFailed()); |
11805 } | 11203 } |
11806 return false; // Load request not yet completed. | 11204 return false; // Load request not yet completed. |
11807 } | 11205 } |
11808 | 11206 |
11809 | |
11810 RawArray* LibraryPrefix::dependent_code() const { | 11207 RawArray* LibraryPrefix::dependent_code() const { |
11811 return raw_ptr()->dependent_code_; | 11208 return raw_ptr()->dependent_code_; |
11812 } | 11209 } |
11813 | 11210 |
11814 | |
11815 void LibraryPrefix::set_dependent_code(const Array& array) const { | 11211 void LibraryPrefix::set_dependent_code(const Array& array) const { |
11816 StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 11212 StorePointer(&raw_ptr()->dependent_code_, array.raw()); |
11817 } | 11213 } |
11818 | 11214 |
11819 | |
11820 class PrefixDependentArray : public WeakCodeReferences { | 11215 class PrefixDependentArray : public WeakCodeReferences { |
11821 public: | 11216 public: |
11822 explicit PrefixDependentArray(const LibraryPrefix& prefix) | 11217 explicit PrefixDependentArray(const LibraryPrefix& prefix) |
11823 : WeakCodeReferences(Array::Handle(prefix.dependent_code())), | 11218 : WeakCodeReferences(Array::Handle(prefix.dependent_code())), |
11824 prefix_(prefix) {} | 11219 prefix_(prefix) {} |
11825 | 11220 |
11826 virtual void UpdateArrayTo(const Array& value) { | 11221 virtual void UpdateArrayTo(const Array& value) { |
11827 prefix_.set_dependent_code(value); | 11222 prefix_.set_dependent_code(value); |
11828 } | 11223 } |
11829 | 11224 |
(...skipping 13 matching lines...) Expand all Loading... |
11843 code.IsDisabled() ? "'patched'" : "'unpatched'", | 11238 code.IsDisabled() ? "'patched'" : "'unpatched'", |
11844 Function::Handle(code.function()).ToCString()); | 11239 Function::Handle(code.function()).ToCString()); |
11845 } | 11240 } |
11846 } | 11241 } |
11847 | 11242 |
11848 private: | 11243 private: |
11849 const LibraryPrefix& prefix_; | 11244 const LibraryPrefix& prefix_; |
11850 DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray); | 11245 DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray); |
11851 }; | 11246 }; |
11852 | 11247 |
11853 | |
11854 void LibraryPrefix::RegisterDependentCode(const Code& code) const { | 11248 void LibraryPrefix::RegisterDependentCode(const Code& code) const { |
11855 ASSERT(is_deferred_load()); | 11249 ASSERT(is_deferred_load()); |
11856 // In background compilation, a library can be loaded while we are compiling. | 11250 // In background compilation, a library can be loaded while we are compiling. |
11857 // The generated code will be rejected in that case, | 11251 // The generated code will be rejected in that case, |
11858 ASSERT(!is_loaded() || Compiler::IsBackgroundCompilation()); | 11252 ASSERT(!is_loaded() || Compiler::IsBackgroundCompilation()); |
11859 PrefixDependentArray a(*this); | 11253 PrefixDependentArray a(*this); |
11860 a.Register(code); | 11254 a.Register(code); |
11861 } | 11255 } |
11862 | 11256 |
11863 | |
11864 void LibraryPrefix::InvalidateDependentCode() const { | 11257 void LibraryPrefix::InvalidateDependentCode() const { |
11865 PrefixDependentArray a(*this); | 11258 PrefixDependentArray a(*this); |
11866 a.DisableCode(); | 11259 a.DisableCode(); |
11867 set_is_loaded(); | 11260 set_is_loaded(); |
11868 } | 11261 } |
11869 | 11262 |
11870 | |
11871 RawLibraryPrefix* LibraryPrefix::New() { | 11263 RawLibraryPrefix* LibraryPrefix::New() { |
11872 RawObject* raw = Object::Allocate(LibraryPrefix::kClassId, | 11264 RawObject* raw = Object::Allocate(LibraryPrefix::kClassId, |
11873 LibraryPrefix::InstanceSize(), Heap::kOld); | 11265 LibraryPrefix::InstanceSize(), Heap::kOld); |
11874 return reinterpret_cast<RawLibraryPrefix*>(raw); | 11266 return reinterpret_cast<RawLibraryPrefix*>(raw); |
11875 } | 11267 } |
11876 | 11268 |
11877 | |
11878 RawLibraryPrefix* LibraryPrefix::New(const String& name, | 11269 RawLibraryPrefix* LibraryPrefix::New(const String& name, |
11879 const Namespace& import, | 11270 const Namespace& import, |
11880 bool deferred_load, | 11271 bool deferred_load, |
11881 const Library& importer) { | 11272 const Library& importer) { |
11882 const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); | 11273 const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); |
11883 result.set_name(name); | 11274 result.set_name(name); |
11884 result.set_num_imports(0); | 11275 result.set_num_imports(0); |
11885 result.set_importer(importer); | 11276 result.set_importer(importer); |
11886 result.StoreNonPointer(&result.raw_ptr()->is_deferred_load_, deferred_load); | 11277 result.StoreNonPointer(&result.raw_ptr()->is_deferred_load_, deferred_load); |
11887 result.StoreNonPointer(&result.raw_ptr()->is_loaded_, !deferred_load); | 11278 result.StoreNonPointer(&result.raw_ptr()->is_loaded_, !deferred_load); |
11888 result.set_imports(Array::Handle(Array::New(kInitialSize))); | 11279 result.set_imports(Array::Handle(Array::New(kInitialSize))); |
11889 result.AddImport(import); | 11280 result.AddImport(import); |
11890 return result.raw(); | 11281 return result.raw(); |
11891 } | 11282 } |
11892 | 11283 |
11893 | |
11894 void LibraryPrefix::set_name(const String& value) const { | 11284 void LibraryPrefix::set_name(const String& value) const { |
11895 ASSERT(value.IsSymbol()); | 11285 ASSERT(value.IsSymbol()); |
11896 StorePointer(&raw_ptr()->name_, value.raw()); | 11286 StorePointer(&raw_ptr()->name_, value.raw()); |
11897 } | 11287 } |
11898 | 11288 |
11899 | |
11900 void LibraryPrefix::set_imports(const Array& value) const { | 11289 void LibraryPrefix::set_imports(const Array& value) const { |
11901 StorePointer(&raw_ptr()->imports_, value.raw()); | 11290 StorePointer(&raw_ptr()->imports_, value.raw()); |
11902 } | 11291 } |
11903 | 11292 |
11904 | |
11905 void LibraryPrefix::set_num_imports(intptr_t value) const { | 11293 void LibraryPrefix::set_num_imports(intptr_t value) const { |
11906 if (!Utils::IsUint(16, value)) { | 11294 if (!Utils::IsUint(16, value)) { |
11907 ReportTooManyImports(Library::Handle(importer())); | 11295 ReportTooManyImports(Library::Handle(importer())); |
11908 } | 11296 } |
11909 StoreNonPointer(&raw_ptr()->num_imports_, value); | 11297 StoreNonPointer(&raw_ptr()->num_imports_, value); |
11910 } | 11298 } |
11911 | 11299 |
11912 | |
11913 void LibraryPrefix::set_importer(const Library& value) const { | 11300 void LibraryPrefix::set_importer(const Library& value) const { |
11914 StorePointer(&raw_ptr()->importer_, value.raw()); | 11301 StorePointer(&raw_ptr()->importer_, value.raw()); |
11915 } | 11302 } |
11916 | 11303 |
11917 | |
11918 const char* LibraryPrefix::ToCString() const { | 11304 const char* LibraryPrefix::ToCString() const { |
11919 const String& prefix = String::Handle(name()); | 11305 const String& prefix = String::Handle(name()); |
11920 return OS::SCreate(Thread::Current()->zone(), "LibraryPrefix:'%s'", | 11306 return OS::SCreate(Thread::Current()->zone(), "LibraryPrefix:'%s'", |
11921 prefix.ToCString()); | 11307 prefix.ToCString()); |
11922 } | 11308 } |
11923 | 11309 |
11924 | |
11925 void Namespace::set_metadata_field(const Field& value) const { | 11310 void Namespace::set_metadata_field(const Field& value) const { |
11926 StorePointer(&raw_ptr()->metadata_field_, value.raw()); | 11311 StorePointer(&raw_ptr()->metadata_field_, value.raw()); |
11927 } | 11312 } |
11928 | 11313 |
11929 | |
11930 void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) { | 11314 void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) { |
11931 ASSERT(Field::Handle(metadata_field()).IsNull()); | 11315 ASSERT(Field::Handle(metadata_field()).IsNull()); |
11932 Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(), | 11316 Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(), |
11933 false, // is_final | 11317 false, // is_final |
11934 false, // is_const | 11318 false, // is_const |
11935 owner, token_pos)); | 11319 owner, token_pos)); |
11936 field.set_is_reflectable(false); | 11320 field.set_is_reflectable(false); |
11937 field.SetFieldType(Object::dynamic_type()); | 11321 field.SetFieldType(Object::dynamic_type()); |
11938 field.SetStaticValue(Array::empty_array(), true); | 11322 field.SetStaticValue(Array::empty_array(), true); |
11939 set_metadata_field(field); | 11323 set_metadata_field(field); |
11940 } | 11324 } |
11941 | 11325 |
11942 | |
11943 RawObject* Namespace::GetMetadata() const { | 11326 RawObject* Namespace::GetMetadata() const { |
11944 #if defined(DART_PRECOMPILED_RUNTIME) | 11327 #if defined(DART_PRECOMPILED_RUNTIME) |
11945 COMPILE_ASSERT(!FLAG_enable_mirrors); | 11328 COMPILE_ASSERT(!FLAG_enable_mirrors); |
11946 return Object::empty_array().raw(); | 11329 return Object::empty_array().raw(); |
11947 #else | 11330 #else |
11948 Field& field = Field::Handle(metadata_field()); | 11331 Field& field = Field::Handle(metadata_field()); |
11949 if (field.IsNull()) { | 11332 if (field.IsNull()) { |
11950 // There is no metadata for this object. | 11333 // There is no metadata for this object. |
11951 return Object::empty_array().raw(); | 11334 return Object::empty_array().raw(); |
11952 } | 11335 } |
11953 Object& metadata = Object::Handle(); | 11336 Object& metadata = Object::Handle(); |
11954 metadata = field.StaticValue(); | 11337 metadata = field.StaticValue(); |
11955 if (field.StaticValue() == Object::empty_array().raw()) { | 11338 if (field.StaticValue() == Object::empty_array().raw()) { |
11956 metadata = Parser::ParseMetadata(field); | 11339 metadata = Parser::ParseMetadata(field); |
11957 if (metadata.IsArray()) { | 11340 if (metadata.IsArray()) { |
11958 ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); | 11341 ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); |
11959 field.SetStaticValue(Array::Cast(metadata), true); | 11342 field.SetStaticValue(Array::Cast(metadata), true); |
11960 } | 11343 } |
11961 } | 11344 } |
11962 return metadata.raw(); | 11345 return metadata.raw(); |
11963 #endif // defined(DART_PRECOMPILED_RUNTIME) | 11346 #endif // defined(DART_PRECOMPILED_RUNTIME) |
11964 } | 11347 } |
11965 | 11348 |
11966 | |
11967 const char* Namespace::ToCString() const { | 11349 const char* Namespace::ToCString() const { |
11968 const Library& lib = Library::Handle(library()); | 11350 const Library& lib = Library::Handle(library()); |
11969 return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'", | 11351 return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'", |
11970 lib.ToCString()); | 11352 lib.ToCString()); |
11971 } | 11353 } |
11972 | 11354 |
11973 | |
11974 bool Namespace::HidesName(const String& name) const { | 11355 bool Namespace::HidesName(const String& name) const { |
11975 // Quick check for common case with no combinators. | 11356 // Quick check for common case with no combinators. |
11976 if (hide_names() == show_names()) { | 11357 if (hide_names() == show_names()) { |
11977 ASSERT(hide_names() == Array::null()); | 11358 ASSERT(hide_names() == Array::null()); |
11978 return false; | 11359 return false; |
11979 } | 11360 } |
11980 const String* plain_name = &name; | 11361 const String* plain_name = &name; |
11981 if (Field::IsGetterName(name)) { | 11362 if (Field::IsGetterName(name)) { |
11982 plain_name = &String::Handle(Field::NameFromGetter(name)); | 11363 plain_name = &String::Handle(Field::NameFromGetter(name)); |
11983 } else if (Field::IsSetterName(name)) { | 11364 } else if (Field::IsSetterName(name)) { |
(...skipping 24 matching lines...) Expand all Loading... |
12008 } | 11389 } |
12009 } | 11390 } |
12010 // There is a list of visible names. The name we're looking for is not | 11391 // There is a list of visible names. The name we're looking for is not |
12011 // contained in the list, so it is hidden. | 11392 // contained in the list, so it is hidden. |
12012 return true; | 11393 return true; |
12013 } | 11394 } |
12014 // The name is not filtered out. | 11395 // The name is not filtered out. |
12015 return false; | 11396 return false; |
12016 } | 11397 } |
12017 | 11398 |
12018 | |
12019 // Look up object with given name in library and filter out hidden | 11399 // Look up object with given name in library and filter out hidden |
12020 // names. Also look up getters and setters. | 11400 // names. Also look up getters and setters. |
12021 RawObject* Namespace::Lookup(const String& name, | 11401 RawObject* Namespace::Lookup(const String& name, |
12022 ZoneGrowableArray<intptr_t>* trail) const { | 11402 ZoneGrowableArray<intptr_t>* trail) const { |
12023 Zone* zone = Thread::Current()->zone(); | 11403 Zone* zone = Thread::Current()->zone(); |
12024 const Library& lib = Library::Handle(zone, library()); | 11404 const Library& lib = Library::Handle(zone, library()); |
12025 | 11405 |
12026 if (trail != NULL) { | 11406 if (trail != NULL) { |
12027 // Look for cycle in reexport graph. | 11407 // Look for cycle in reexport graph. |
12028 for (int i = 0; i < trail->length(); i++) { | 11408 for (int i = 0; i < trail->length(); i++) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12066 obj = lib.LookupReExport(setter_name, trail); | 11446 obj = lib.LookupReExport(setter_name, trail); |
12067 } | 11447 } |
12068 } | 11448 } |
12069 } | 11449 } |
12070 if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { | 11450 if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { |
12071 return Object::null(); | 11451 return Object::null(); |
12072 } | 11452 } |
12073 return obj.raw(); | 11453 return obj.raw(); |
12074 } | 11454 } |
12075 | 11455 |
12076 | |
12077 RawNamespace* Namespace::New() { | 11456 RawNamespace* Namespace::New() { |
12078 ASSERT(Object::namespace_class() != Class::null()); | 11457 ASSERT(Object::namespace_class() != Class::null()); |
12079 RawObject* raw = Object::Allocate(Namespace::kClassId, | 11458 RawObject* raw = Object::Allocate(Namespace::kClassId, |
12080 Namespace::InstanceSize(), Heap::kOld); | 11459 Namespace::InstanceSize(), Heap::kOld); |
12081 return reinterpret_cast<RawNamespace*>(raw); | 11460 return reinterpret_cast<RawNamespace*>(raw); |
12082 } | 11461 } |
12083 | 11462 |
12084 | |
12085 RawNamespace* Namespace::New(const Library& library, | 11463 RawNamespace* Namespace::New(const Library& library, |
12086 const Array& show_names, | 11464 const Array& show_names, |
12087 const Array& hide_names) { | 11465 const Array& hide_names) { |
12088 ASSERT(show_names.IsNull() || (show_names.Length() > 0)); | 11466 ASSERT(show_names.IsNull() || (show_names.Length() > 0)); |
12089 ASSERT(hide_names.IsNull() || (hide_names.Length() > 0)); | 11467 ASSERT(hide_names.IsNull() || (hide_names.Length() > 0)); |
12090 const Namespace& result = Namespace::Handle(Namespace::New()); | 11468 const Namespace& result = Namespace::Handle(Namespace::New()); |
12091 result.StorePointer(&result.raw_ptr()->library_, library.raw()); | 11469 result.StorePointer(&result.raw_ptr()->library_, library.raw()); |
12092 result.StorePointer(&result.raw_ptr()->show_names_, show_names.raw()); | 11470 result.StorePointer(&result.raw_ptr()->show_names_, show_names.raw()); |
12093 result.StorePointer(&result.raw_ptr()->hide_names_, hide_names.raw()); | 11471 result.StorePointer(&result.raw_ptr()->hide_names_, hide_names.raw()); |
12094 return result.raw(); | 11472 return result.raw(); |
12095 } | 11473 } |
12096 | 11474 |
12097 | |
12098 RawError* Library::CompileAll() { | 11475 RawError* Library::CompileAll() { |
12099 Thread* thread = Thread::Current(); | 11476 Thread* thread = Thread::Current(); |
12100 Zone* zone = thread->zone(); | 11477 Zone* zone = thread->zone(); |
12101 Error& error = Error::Handle(zone); | 11478 Error& error = Error::Handle(zone); |
12102 const GrowableObjectArray& libs = GrowableObjectArray::Handle( | 11479 const GrowableObjectArray& libs = GrowableObjectArray::Handle( |
12103 Isolate::Current()->object_store()->libraries()); | 11480 Isolate::Current()->object_store()->libraries()); |
12104 Library& lib = Library::Handle(zone); | 11481 Library& lib = Library::Handle(zone); |
12105 Class& cls = Class::Handle(zone); | 11482 Class& cls = Class::Handle(zone); |
12106 for (int i = 0; i < libs.Length(); i++) { | 11483 for (int i = 0; i < libs.Length(); i++) { |
12107 lib ^= libs.At(i); | 11484 lib ^= libs.At(i); |
(...skipping 25 matching lines...) Expand all Loading... |
12133 if (result.IsError()) { | 11510 if (result.IsError()) { |
12134 return Error::Cast(result).raw(); | 11511 return Error::Cast(result).raw(); |
12135 } | 11512 } |
12136 func.ClearICDataArray(); | 11513 func.ClearICDataArray(); |
12137 func.ClearCode(); | 11514 func.ClearCode(); |
12138 } | 11515 } |
12139 } | 11516 } |
12140 return Error::null(); | 11517 return Error::null(); |
12141 } | 11518 } |
12142 | 11519 |
12143 | |
12144 RawError* Library::ParseAll(Thread* thread) { | 11520 RawError* Library::ParseAll(Thread* thread) { |
12145 Zone* zone = thread->zone(); | 11521 Zone* zone = thread->zone(); |
12146 Error& error = Error::Handle(zone); | 11522 Error& error = Error::Handle(zone); |
12147 Isolate* isolate = thread->isolate(); | 11523 Isolate* isolate = thread->isolate(); |
12148 const GrowableObjectArray& libs = | 11524 const GrowableObjectArray& libs = |
12149 GrowableObjectArray::Handle(isolate->object_store()->libraries()); | 11525 GrowableObjectArray::Handle(isolate->object_store()->libraries()); |
12150 Library& lib = Library::Handle(zone); | 11526 Library& lib = Library::Handle(zone); |
12151 Class& cls = Class::Handle(zone); | 11527 Class& cls = Class::Handle(zone); |
12152 for (int i = 0; i < libs.Length(); i++) { | 11528 for (int i = 0; i < libs.Length(); i++) { |
12153 lib ^= libs.At(i); | 11529 lib ^= libs.At(i); |
(...skipping 24 matching lines...) Expand all Loading... |
12178 if (!error.IsNull()) { | 11554 if (!error.IsNull()) { |
12179 return error.raw(); | 11555 return error.raw(); |
12180 } | 11556 } |
12181 func.ClearICDataArray(); | 11557 func.ClearICDataArray(); |
12182 func.ClearCode(); | 11558 func.ClearCode(); |
12183 } | 11559 } |
12184 } | 11560 } |
12185 return error.raw(); | 11561 return error.raw(); |
12186 } | 11562 } |
12187 | 11563 |
12188 | |
12189 // Return Function::null() if function does not exist in libs. | 11564 // Return Function::null() if function does not exist in libs. |
12190 RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs, | 11565 RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs, |
12191 const char* class_name, | 11566 const char* class_name, |
12192 const char* function_name) { | 11567 const char* function_name) { |
12193 Thread* thread = Thread::Current(); | 11568 Thread* thread = Thread::Current(); |
12194 Zone* zone = thread->zone(); | 11569 Zone* zone = thread->zone(); |
12195 Function& func = Function::Handle(zone); | 11570 Function& func = Function::Handle(zone); |
12196 String& class_str = String::Handle(zone); | 11571 String& class_str = String::Handle(zone); |
12197 String& func_str = String::Handle(zone); | 11572 String& func_str = String::Handle(zone); |
12198 Class& cls = Class::Handle(zone); | 11573 Class& cls = Class::Handle(zone); |
(...skipping 13 matching lines...) Expand all Loading... |
12212 func = cls.LookupFunctionAllowPrivate(func_str); | 11587 func = cls.LookupFunctionAllowPrivate(func_str); |
12213 } | 11588 } |
12214 } | 11589 } |
12215 if (!func.IsNull()) { | 11590 if (!func.IsNull()) { |
12216 return func.raw(); | 11591 return func.raw(); |
12217 } | 11592 } |
12218 } | 11593 } |
12219 return Function::null(); | 11594 return Function::null(); |
12220 } | 11595 } |
12221 | 11596 |
12222 | |
12223 RawObject* Library::GetFunctionClosure(const String& name) const { | 11597 RawObject* Library::GetFunctionClosure(const String& name) const { |
12224 Thread* thread = Thread::Current(); | 11598 Thread* thread = Thread::Current(); |
12225 Zone* zone = thread->zone(); | 11599 Zone* zone = thread->zone(); |
12226 Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name)); | 11600 Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name)); |
12227 if (func.IsNull()) { | 11601 if (func.IsNull()) { |
12228 // Check whether the function is reexported into the library. | 11602 // Check whether the function is reexported into the library. |
12229 const Object& obj = Object::Handle(zone, LookupReExport(name)); | 11603 const Object& obj = Object::Handle(zone, LookupReExport(name)); |
12230 if (obj.IsFunction()) { | 11604 if (obj.IsFunction()) { |
12231 func ^= obj.raw(); | 11605 func ^= obj.raw(); |
12232 } else { | 11606 } else { |
12233 // Check if there is a getter of 'name', in which case invoke it | 11607 // Check if there is a getter of 'name', in which case invoke it |
12234 // and return the result. | 11608 // and return the result. |
12235 const String& getter_name = String::Handle(zone, Field::GetterName(name)); | 11609 const String& getter_name = String::Handle(zone, Field::GetterName(name)); |
12236 func = LookupFunctionAllowPrivate(getter_name); | 11610 func = LookupFunctionAllowPrivate(getter_name); |
12237 if (func.IsNull()) { | 11611 if (func.IsNull()) { |
12238 return Closure::null(); | 11612 return Closure::null(); |
12239 } | 11613 } |
12240 // Invoke the getter and return the result. | 11614 // Invoke the getter and return the result. |
12241 return DartEntry::InvokeFunction(func, Object::empty_array()); | 11615 return DartEntry::InvokeFunction(func, Object::empty_array()); |
12242 } | 11616 } |
12243 } | 11617 } |
12244 func = func.ImplicitClosureFunction(); | 11618 func = func.ImplicitClosureFunction(); |
12245 return func.ImplicitStaticClosure(); | 11619 return func.ImplicitStaticClosure(); |
12246 } | 11620 } |
12247 | 11621 |
12248 | |
12249 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT) | 11622 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT) |
12250 void Library::CheckFunctionFingerprints() { | 11623 void Library::CheckFunctionFingerprints() { |
12251 GrowableArray<Library*> all_libs; | 11624 GrowableArray<Library*> all_libs; |
12252 Function& func = Function::Handle(); | 11625 Function& func = Function::Handle(); |
12253 bool has_errors = false; | 11626 bool has_errors = false; |
12254 | 11627 |
12255 #define CHECK_FINGERPRINTS(class_name, function_name, dest, fp) \ | 11628 #define CHECK_FINGERPRINTS(class_name, function_name, dest, fp) \ |
12256 func = GetFunction(all_libs, #class_name, #function_name); \ | 11629 func = GetFunction(all_libs, #class_name, #function_name); \ |
12257 if (func.IsNull()) { \ | 11630 if (func.IsNull()) { \ |
12258 has_errors = true; \ | 11631 has_errors = true; \ |
(...skipping 26 matching lines...) Expand all Loading... |
12285 all_libs.Add(&Library::ZoneHandle(Library::MathLibrary())); | 11658 all_libs.Add(&Library::ZoneHandle(Library::MathLibrary())); |
12286 MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); | 11659 MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); |
12287 | 11660 |
12288 all_libs.Clear(); | 11661 all_libs.Clear(); |
12289 all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary())); | 11662 all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary())); |
12290 TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); | 11663 TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); |
12291 | 11664 |
12292 #undef CHECK_FINGERPRINTS | 11665 #undef CHECK_FINGERPRINTS |
12293 #undef CHECK_FINGERPRINTS2 | 11666 #undef CHECK_FINGERPRINTS2 |
12294 | 11667 |
12295 | |
12296 #define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp) \ | 11668 #define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp) \ |
12297 func = GetFunction(all_libs, #class_name, #factory_name); \ | 11669 func = GetFunction(all_libs, #class_name, #factory_name); \ |
12298 if (func.IsNull()) { \ | 11670 if (func.IsNull()) { \ |
12299 has_errors = true; \ | 11671 has_errors = true; \ |
12300 OS::Print("Function not found %s.%s\n", #class_name, #factory_name); \ | 11672 OS::Print("Function not found %s.%s\n", #class_name, #factory_name); \ |
12301 } else { \ | 11673 } else { \ |
12302 CHECK_FINGERPRINT2(func, symbol, cid, fp); \ | 11674 CHECK_FINGERPRINT2(func, symbol, cid, fp); \ |
12303 } | 11675 } |
12304 | 11676 |
12305 all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary())); | 11677 all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary())); |
12306 RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS); | 11678 RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS); |
12307 | 11679 |
12308 #undef CHECK_FACTORY_FINGERPRINTS | 11680 #undef CHECK_FACTORY_FINGERPRINTS |
12309 | 11681 |
12310 if (has_errors) { | 11682 if (has_errors) { |
12311 FATAL("Fingerprint mismatch."); | 11683 FATAL("Fingerprint mismatch."); |
12312 } | 11684 } |
12313 } | 11685 } |
12314 #endif // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT). | 11686 #endif // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT). |
12315 | 11687 |
12316 | |
12317 RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) { | 11688 RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) { |
12318 ASSERT(size >= 0); | 11689 ASSERT(size >= 0); |
12319 ASSERT(Object::instructions_class() != Class::null()); | 11690 ASSERT(Object::instructions_class() != Class::null()); |
12320 if (size < 0 || size > kMaxElements) { | 11691 if (size < 0 || size > kMaxElements) { |
12321 // This should be caught before we reach here. | 11692 // This should be caught before we reach here. |
12322 FATAL1("Fatal error in Instructions::New: invalid size %" Pd "\n", size); | 11693 FATAL1("Fatal error in Instructions::New: invalid size %" Pd "\n", size); |
12323 } | 11694 } |
12324 Instructions& result = Instructions::Handle(); | 11695 Instructions& result = Instructions::Handle(); |
12325 { | 11696 { |
12326 uword aligned_size = Instructions::InstanceSize(size); | 11697 uword aligned_size = Instructions::InstanceSize(size); |
12327 RawObject* raw = | 11698 RawObject* raw = |
12328 Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode); | 11699 Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode); |
12329 NoSafepointScope no_safepoint; | 11700 NoSafepointScope no_safepoint; |
12330 result ^= raw; | 11701 result ^= raw; |
12331 result.SetSize(size); | 11702 result.SetSize(size); |
12332 result.SetHasSingleEntryPoint(has_single_entry_point); | 11703 result.SetHasSingleEntryPoint(has_single_entry_point); |
12333 } | 11704 } |
12334 return result.raw(); | 11705 return result.raw(); |
12335 } | 11706 } |
12336 | 11707 |
12337 | |
12338 const char* Instructions::ToCString() const { | 11708 const char* Instructions::ToCString() const { |
12339 return "Instructions"; | 11709 return "Instructions"; |
12340 } | 11710 } |
12341 | 11711 |
12342 | |
12343 // Encode integer |value| in SLEB128 format and store into |data|. | 11712 // Encode integer |value| in SLEB128 format and store into |data|. |
12344 static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) { | 11713 static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) { |
12345 bool is_last_part = false; | 11714 bool is_last_part = false; |
12346 while (!is_last_part) { | 11715 while (!is_last_part) { |
12347 uint8_t part = value & 0x7f; | 11716 uint8_t part = value & 0x7f; |
12348 value >>= 7; | 11717 value >>= 7; |
12349 if ((value == 0 && (part & 0x40) == 0) || | 11718 if ((value == 0 && (part & 0x40) == 0) || |
12350 (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) { | 11719 (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) { |
12351 is_last_part = true; | 11720 is_last_part = true; |
12352 } else { | 11721 } else { |
12353 part |= 0x80; | 11722 part |= 0x80; |
12354 } | 11723 } |
12355 data->Add(part); | 11724 data->Add(part); |
12356 } | 11725 } |
12357 } | 11726 } |
12358 | 11727 |
12359 | |
12360 // Decode integer in SLEB128 format from |data| and update |byte_index|. | 11728 // Decode integer in SLEB128 format from |data| and update |byte_index|. |
12361 static intptr_t DecodeSLEB128(const uint8_t* data, | 11729 static intptr_t DecodeSLEB128(const uint8_t* data, |
12362 const intptr_t data_length, | 11730 const intptr_t data_length, |
12363 intptr_t* byte_index) { | 11731 intptr_t* byte_index) { |
12364 ASSERT(*byte_index < data_length); | 11732 ASSERT(*byte_index < data_length); |
12365 uword shift = 0; | 11733 uword shift = 0; |
12366 intptr_t value = 0; | 11734 intptr_t value = 0; |
12367 uint8_t part = 0; | 11735 uint8_t part = 0; |
12368 do { | 11736 do { |
12369 part = data[(*byte_index)++]; | 11737 part = data[(*byte_index)++]; |
12370 value |= static_cast<intptr_t>(part & 0x7f) << shift; | 11738 value |= static_cast<intptr_t>(part & 0x7f) << shift; |
12371 shift += 7; | 11739 shift += 7; |
12372 } while ((part & 0x80) != 0); | 11740 } while ((part & 0x80) != 0); |
12373 | 11741 |
12374 if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) { | 11742 if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) { |
12375 value |= static_cast<intptr_t>(kUwordMax << shift); | 11743 value |= static_cast<intptr_t>(kUwordMax << shift); |
12376 } | 11744 } |
12377 return value; | 11745 return value; |
12378 } | 11746 } |
12379 | 11747 |
12380 | |
12381 // Encode integer in SLEB128 format. | 11748 // Encode integer in SLEB128 format. |
12382 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, | 11749 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, |
12383 intptr_t value) { | 11750 intptr_t value) { |
12384 return EncodeSLEB128(data, value); | 11751 return EncodeSLEB128(data, value); |
12385 } | 11752 } |
12386 | 11753 |
12387 | |
12388 // Decode SLEB128 encoded integer. Update byte_index to the next integer. | 11754 // Decode SLEB128 encoded integer. Update byte_index to the next integer. |
12389 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { | 11755 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |
12390 NoSafepointScope no_safepoint; | 11756 NoSafepointScope no_safepoint; |
12391 const uint8_t* data = raw_ptr()->data(); | 11757 const uint8_t* data = raw_ptr()->data(); |
12392 return DecodeSLEB128(data, Length(), byte_index); | 11758 return DecodeSLEB128(data, Length(), byte_index); |
12393 } | 11759 } |
12394 | 11760 |
12395 | |
12396 RawObjectPool* ObjectPool::New(intptr_t len) { | 11761 RawObjectPool* ObjectPool::New(intptr_t len) { |
12397 ASSERT(Object::object_pool_class() != Class::null()); | 11762 ASSERT(Object::object_pool_class() != Class::null()); |
12398 if (len < 0 || len > kMaxElements) { | 11763 if (len < 0 || len > kMaxElements) { |
12399 // This should be caught before we reach here. | 11764 // This should be caught before we reach here. |
12400 FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len); | 11765 FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len); |
12401 } | 11766 } |
12402 ObjectPool& result = ObjectPool::Handle(); | 11767 ObjectPool& result = ObjectPool::Handle(); |
12403 { | 11768 { |
12404 uword size = ObjectPool::InstanceSize(len); | 11769 uword size = ObjectPool::InstanceSize(len); |
12405 RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld); | 11770 RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld); |
12406 NoSafepointScope no_safepoint; | 11771 NoSafepointScope no_safepoint; |
12407 result ^= raw; | 11772 result ^= raw; |
12408 result.SetLength(len); | 11773 result.SetLength(len); |
12409 } | 11774 } |
12410 | 11775 |
12411 // TODO(fschneider): Compress info array to just use just enough bits for | 11776 // TODO(fschneider): Compress info array to just use just enough bits for |
12412 // the entry type enum. | 11777 // the entry type enum. |
12413 const TypedData& info_array = TypedData::Handle( | 11778 const TypedData& info_array = TypedData::Handle( |
12414 TypedData::New(kTypedDataInt8ArrayCid, len, Heap::kOld)); | 11779 TypedData::New(kTypedDataInt8ArrayCid, len, Heap::kOld)); |
12415 result.set_info_array(info_array); | 11780 result.set_info_array(info_array); |
12416 return result.raw(); | 11781 return result.raw(); |
12417 } | 11782 } |
12418 | 11783 |
12419 | |
12420 void ObjectPool::set_info_array(const TypedData& info_array) const { | 11784 void ObjectPool::set_info_array(const TypedData& info_array) const { |
12421 StorePointer(&raw_ptr()->info_array_, info_array.raw()); | 11785 StorePointer(&raw_ptr()->info_array_, info_array.raw()); |
12422 } | 11786 } |
12423 | 11787 |
12424 | |
12425 ObjectPool::EntryType ObjectPool::InfoAt(intptr_t index) const { | 11788 ObjectPool::EntryType ObjectPool::InfoAt(intptr_t index) const { |
12426 ObjectPoolInfo pool_info(*this); | 11789 ObjectPoolInfo pool_info(*this); |
12427 return pool_info.InfoAt(index); | 11790 return pool_info.InfoAt(index); |
12428 } | 11791 } |
12429 | 11792 |
12430 | |
12431 const char* ObjectPool::ToCString() const { | 11793 const char* ObjectPool::ToCString() const { |
12432 Zone* zone = Thread::Current()->zone(); | 11794 Zone* zone = Thread::Current()->zone(); |
12433 return zone->PrintToString("ObjectPool len:%" Pd, Length()); | 11795 return zone->PrintToString("ObjectPool len:%" Pd, Length()); |
12434 } | 11796 } |
12435 | 11797 |
12436 | |
12437 void ObjectPool::DebugPrint() const { | 11798 void ObjectPool::DebugPrint() const { |
12438 THR_Print("Object Pool: 0x%" Px "{\n", reinterpret_cast<uword>(raw())); | 11799 THR_Print("Object Pool: 0x%" Px "{\n", reinterpret_cast<uword>(raw())); |
12439 for (intptr_t i = 0; i < Length(); i++) { | 11800 for (intptr_t i = 0; i < Length(); i++) { |
12440 intptr_t offset = OffsetFromIndex(i); | 11801 intptr_t offset = OffsetFromIndex(i); |
12441 THR_Print(" %" Pd " PP+0x%" Px ": ", i, offset); | 11802 THR_Print(" %" Pd " PP+0x%" Px ": ", i, offset); |
12442 if (InfoAt(i) == kTaggedObject) { | 11803 if (InfoAt(i) == kTaggedObject) { |
12443 RawObject* obj = ObjectAt(i); | 11804 RawObject* obj = ObjectAt(i); |
12444 THR_Print("0x%" Px " %s (obj)\n", reinterpret_cast<uword>(obj), | 11805 THR_Print("0x%" Px " %s (obj)\n", reinterpret_cast<uword>(obj), |
12445 Object::Handle(obj).ToCString()); | 11806 Object::Handle(obj).ToCString()); |
12446 } else if (InfoAt(i) == kNativeEntry) { | 11807 } else if (InfoAt(i) == kNativeEntry) { |
12447 THR_Print("0x%" Px " (native entry)\n", RawValueAt(i)); | 11808 THR_Print("0x%" Px " (native entry)\n", RawValueAt(i)); |
12448 } else { | 11809 } else { |
12449 THR_Print("0x%" Px " (raw)\n", RawValueAt(i)); | 11810 THR_Print("0x%" Px " (raw)\n", RawValueAt(i)); |
12450 } | 11811 } |
12451 } | 11812 } |
12452 THR_Print("}\n"); | 11813 THR_Print("}\n"); |
12453 } | 11814 } |
12454 | 11815 |
12455 | |
12456 intptr_t PcDescriptors::Length() const { | 11816 intptr_t PcDescriptors::Length() const { |
12457 return raw_ptr()->length_; | 11817 return raw_ptr()->length_; |
12458 } | 11818 } |
12459 | 11819 |
12460 | |
12461 void PcDescriptors::SetLength(intptr_t value) const { | 11820 void PcDescriptors::SetLength(intptr_t value) const { |
12462 StoreNonPointer(&raw_ptr()->length_, value); | 11821 StoreNonPointer(&raw_ptr()->length_, value); |
12463 } | 11822 } |
12464 | 11823 |
12465 | |
12466 void PcDescriptors::CopyData(GrowableArray<uint8_t>* delta_encoded_data) { | 11824 void PcDescriptors::CopyData(GrowableArray<uint8_t>* delta_encoded_data) { |
12467 NoSafepointScope no_safepoint; | 11825 NoSafepointScope no_safepoint; |
12468 uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]); | 11826 uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]); |
12469 for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) { | 11827 for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) { |
12470 data[i] = (*delta_encoded_data)[i]; | 11828 data[i] = (*delta_encoded_data)[i]; |
12471 } | 11829 } |
12472 } | 11830 } |
12473 | 11831 |
12474 | |
12475 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { | 11832 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { |
12476 ASSERT(Object::pc_descriptors_class() != Class::null()); | 11833 ASSERT(Object::pc_descriptors_class() != Class::null()); |
12477 Thread* thread = Thread::Current(); | 11834 Thread* thread = Thread::Current(); |
12478 PcDescriptors& result = PcDescriptors::Handle(thread->zone()); | 11835 PcDescriptors& result = PcDescriptors::Handle(thread->zone()); |
12479 { | 11836 { |
12480 uword size = PcDescriptors::InstanceSize(data->length()); | 11837 uword size = PcDescriptors::InstanceSize(data->length()); |
12481 RawObject* raw = | 11838 RawObject* raw = |
12482 Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); | 11839 Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); |
12483 INC_STAT(thread, total_code_size, size); | 11840 INC_STAT(thread, total_code_size, size); |
12484 INC_STAT(thread, pc_desc_size, size); | 11841 INC_STAT(thread, pc_desc_size, size); |
12485 NoSafepointScope no_safepoint; | 11842 NoSafepointScope no_safepoint; |
12486 result ^= raw; | 11843 result ^= raw; |
12487 result.SetLength(data->length()); | 11844 result.SetLength(data->length()); |
12488 result.CopyData(data); | 11845 result.CopyData(data); |
12489 } | 11846 } |
12490 return result.raw(); | 11847 return result.raw(); |
12491 } | 11848 } |
12492 | 11849 |
12493 | |
12494 RawPcDescriptors* PcDescriptors::New(intptr_t length) { | 11850 RawPcDescriptors* PcDescriptors::New(intptr_t length) { |
12495 ASSERT(Object::pc_descriptors_class() != Class::null()); | 11851 ASSERT(Object::pc_descriptors_class() != Class::null()); |
12496 Thread* thread = Thread::Current(); | 11852 Thread* thread = Thread::Current(); |
12497 PcDescriptors& result = PcDescriptors::Handle(thread->zone()); | 11853 PcDescriptors& result = PcDescriptors::Handle(thread->zone()); |
12498 { | 11854 { |
12499 uword size = PcDescriptors::InstanceSize(length); | 11855 uword size = PcDescriptors::InstanceSize(length); |
12500 RawObject* raw = | 11856 RawObject* raw = |
12501 Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); | 11857 Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); |
12502 INC_STAT(thread, total_code_size, size); | 11858 INC_STAT(thread, total_code_size, size); |
12503 INC_STAT(thread, pc_desc_size, size); | 11859 INC_STAT(thread, pc_desc_size, size); |
12504 NoSafepointScope no_safepoint; | 11860 NoSafepointScope no_safepoint; |
12505 result ^= raw; | 11861 result ^= raw; |
12506 result.SetLength(length); | 11862 result.SetLength(length); |
12507 } | 11863 } |
12508 return result.raw(); | 11864 return result.raw(); |
12509 } | 11865 } |
12510 | 11866 |
12511 | |
12512 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { | 11867 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { |
12513 switch (kind) { | 11868 switch (kind) { |
12514 case RawPcDescriptors::kDeopt: | 11869 case RawPcDescriptors::kDeopt: |
12515 return "deopt "; | 11870 return "deopt "; |
12516 case RawPcDescriptors::kIcCall: | 11871 case RawPcDescriptors::kIcCall: |
12517 return "ic-call "; | 11872 return "ic-call "; |
12518 case RawPcDescriptors::kUnoptStaticCall: | 11873 case RawPcDescriptors::kUnoptStaticCall: |
12519 return "unopt-call "; | 11874 return "unopt-call "; |
12520 case RawPcDescriptors::kRuntimeCall: | 11875 case RawPcDescriptors::kRuntimeCall: |
12521 return "runtime-call "; | 11876 return "runtime-call "; |
12522 case RawPcDescriptors::kOsrEntry: | 11877 case RawPcDescriptors::kOsrEntry: |
12523 return "osr-entry "; | 11878 return "osr-entry "; |
12524 case RawPcDescriptors::kRewind: | 11879 case RawPcDescriptors::kRewind: |
12525 return "rewind "; | 11880 return "rewind "; |
12526 case RawPcDescriptors::kOther: | 11881 case RawPcDescriptors::kOther: |
12527 return "other "; | 11882 return "other "; |
12528 case RawPcDescriptors::kAnyKind: | 11883 case RawPcDescriptors::kAnyKind: |
12529 UNREACHABLE(); | 11884 UNREACHABLE(); |
12530 break; | 11885 break; |
12531 } | 11886 } |
12532 UNREACHABLE(); | 11887 UNREACHABLE(); |
12533 return ""; | 11888 return ""; |
12534 } | 11889 } |
12535 | 11890 |
12536 | |
12537 void PcDescriptors::PrintHeaderString() { | 11891 void PcDescriptors::PrintHeaderString() { |
12538 // 4 bits per hex digit + 2 for "0x". | 11892 // 4 bits per hex digit + 2 for "0x". |
12539 const int addr_width = (kBitsPerWord / 4) + 2; | 11893 const int addr_width = (kBitsPerWord / 4) + 2; |
12540 // "*" in a printf format specifier tells it to read the field width from | 11894 // "*" in a printf format specifier tells it to read the field width from |
12541 // the printf argument list. | 11895 // the printf argument list. |
12542 THR_Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", addr_width, "pc"); | 11896 THR_Print("%-*s\tkind \tdeopt-id\ttok-ix\ttry-ix\n", addr_width, "pc"); |
12543 } | 11897 } |
12544 | 11898 |
12545 | |
12546 const char* PcDescriptors::ToCString() const { | 11899 const char* PcDescriptors::ToCString() const { |
12547 // "*" in a printf format specifier tells it to read the field width from | 11900 // "*" in a printf format specifier tells it to read the field width from |
12548 // the printf argument list. | 11901 // the printf argument list. |
12549 #define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%s\t%" Pd "\n" | 11902 #define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%s\t%" Pd "\n" |
12550 if (Length() == 0) { | 11903 if (Length() == 0) { |
12551 return "empty PcDescriptors\n"; | 11904 return "empty PcDescriptors\n"; |
12552 } | 11905 } |
12553 // 4 bits per hex digit. | 11906 // 4 bits per hex digit. |
12554 const int addr_width = kBitsPerWord / 4; | 11907 const int addr_width = kBitsPerWord / 4; |
12555 // First compute the buffer size required. | 11908 // First compute the buffer size required. |
(...skipping 14 matching lines...) Expand all Loading... |
12570 while (iter.MoveNext()) { | 11923 while (iter.MoveNext()) { |
12571 index += | 11924 index += |
12572 OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width, | 11925 OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width, |
12573 iter.PcOffset(), KindAsStr(iter.Kind()), iter.DeoptId(), | 11926 iter.PcOffset(), KindAsStr(iter.Kind()), iter.DeoptId(), |
12574 iter.TokenPos().ToCString(), iter.TryIndex()); | 11927 iter.TokenPos().ToCString(), iter.TryIndex()); |
12575 } | 11928 } |
12576 return buffer; | 11929 return buffer; |
12577 #undef FORMAT | 11930 #undef FORMAT |
12578 } | 11931 } |
12579 | 11932 |
12580 | |
12581 // Verify assumptions (in debug mode only). | 11933 // Verify assumptions (in debug mode only). |
12582 // - No two deopt descriptors have the same deoptimization id. | 11934 // - No two deopt descriptors have the same deoptimization id. |
12583 // - No two ic-call descriptors have the same deoptimization id (type feedback). | 11935 // - No two ic-call descriptors have the same deoptimization id (type feedback). |
12584 // A function without unique ids is marked as non-optimizable (e.g., because of | 11936 // A function without unique ids is marked as non-optimizable (e.g., because of |
12585 // finally blocks). | 11937 // finally blocks). |
12586 void PcDescriptors::Verify(const Function& function) const { | 11938 void PcDescriptors::Verify(const Function& function) const { |
12587 #if defined(DEBUG) | 11939 #if defined(DEBUG) |
12588 // Only check ids for unoptimized code that is optimizable. | 11940 // Only check ids for unoptimized code that is optimizable. |
12589 if (!function.IsOptimizable()) { | 11941 if (!function.IsOptimizable()) { |
12590 return; | 11942 return; |
(...skipping 23 matching lines...) Expand all Loading... |
12614 ASSERT(!deopt_ids->Contains(iter.DeoptId())); | 11966 ASSERT(!deopt_ids->Contains(iter.DeoptId())); |
12615 deopt_ids->Add(iter.DeoptId()); | 11967 deopt_ids->Add(iter.DeoptId()); |
12616 } else { | 11968 } else { |
12617 ASSERT(!iccall_ids->Contains(iter.DeoptId())); | 11969 ASSERT(!iccall_ids->Contains(iter.DeoptId())); |
12618 iccall_ids->Add(iter.DeoptId()); | 11970 iccall_ids->Add(iter.DeoptId()); |
12619 } | 11971 } |
12620 } | 11972 } |
12621 #endif // DEBUG | 11973 #endif // DEBUG |
12622 } | 11974 } |
12623 | 11975 |
12624 | |
12625 void CodeSourceMap::SetLength(intptr_t value) const { | 11976 void CodeSourceMap::SetLength(intptr_t value) const { |
12626 StoreNonPointer(&raw_ptr()->length_, value); | 11977 StoreNonPointer(&raw_ptr()->length_, value); |
12627 } | 11978 } |
12628 | 11979 |
12629 | |
12630 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { | 11980 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { |
12631 ASSERT(Object::code_source_map_class() != Class::null()); | 11981 ASSERT(Object::code_source_map_class() != Class::null()); |
12632 Thread* thread = Thread::Current(); | 11982 Thread* thread = Thread::Current(); |
12633 CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); | 11983 CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); |
12634 { | 11984 { |
12635 uword size = CodeSourceMap::InstanceSize(length); | 11985 uword size = CodeSourceMap::InstanceSize(length); |
12636 RawObject* raw = | 11986 RawObject* raw = |
12637 Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld); | 11987 Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld); |
12638 NoSafepointScope no_safepoint; | 11988 NoSafepointScope no_safepoint; |
12639 result ^= raw; | 11989 result ^= raw; |
12640 result.SetLength(length); | 11990 result.SetLength(length); |
12641 } | 11991 } |
12642 return result.raw(); | 11992 return result.raw(); |
12643 } | 11993 } |
12644 | 11994 |
12645 | |
12646 const char* CodeSourceMap::ToCString() const { | 11995 const char* CodeSourceMap::ToCString() const { |
12647 return "CodeSourceMap"; | 11996 return "CodeSourceMap"; |
12648 } | 11997 } |
12649 | 11998 |
12650 | |
12651 bool StackMap::GetBit(intptr_t bit_index) const { | 11999 bool StackMap::GetBit(intptr_t bit_index) const { |
12652 ASSERT(InRange(bit_index)); | 12000 ASSERT(InRange(bit_index)); |
12653 int byte_index = bit_index >> kBitsPerByteLog2; | 12001 int byte_index = bit_index >> kBitsPerByteLog2; |
12654 int bit_remainder = bit_index & (kBitsPerByte - 1); | 12002 int bit_remainder = bit_index & (kBitsPerByte - 1); |
12655 uint8_t byte_mask = 1U << bit_remainder; | 12003 uint8_t byte_mask = 1U << bit_remainder; |
12656 uint8_t byte = raw_ptr()->data()[byte_index]; | 12004 uint8_t byte = raw_ptr()->data()[byte_index]; |
12657 return (byte & byte_mask); | 12005 return (byte & byte_mask); |
12658 } | 12006 } |
12659 | 12007 |
12660 | |
12661 void StackMap::SetBit(intptr_t bit_index, bool value) const { | 12008 void StackMap::SetBit(intptr_t bit_index, bool value) const { |
12662 ASSERT(InRange(bit_index)); | 12009 ASSERT(InRange(bit_index)); |
12663 int byte_index = bit_index >> kBitsPerByteLog2; | 12010 int byte_index = bit_index >> kBitsPerByteLog2; |
12664 int bit_remainder = bit_index & (kBitsPerByte - 1); | 12011 int bit_remainder = bit_index & (kBitsPerByte - 1); |
12665 uint8_t byte_mask = 1U << bit_remainder; | 12012 uint8_t byte_mask = 1U << bit_remainder; |
12666 NoSafepointScope no_safepoint; | 12013 NoSafepointScope no_safepoint; |
12667 uint8_t* byte_addr = UnsafeMutableNonPointer(&raw_ptr()->data()[byte_index]); | 12014 uint8_t* byte_addr = UnsafeMutableNonPointer(&raw_ptr()->data()[byte_index]); |
12668 if (value) { | 12015 if (value) { |
12669 *byte_addr |= byte_mask; | 12016 *byte_addr |= byte_mask; |
12670 } else { | 12017 } else { |
12671 *byte_addr &= ~byte_mask; | 12018 *byte_addr &= ~byte_mask; |
12672 } | 12019 } |
12673 } | 12020 } |
12674 | 12021 |
12675 | |
12676 RawStackMap* StackMap::New(intptr_t pc_offset, | 12022 RawStackMap* StackMap::New(intptr_t pc_offset, |
12677 BitmapBuilder* bmap, | 12023 BitmapBuilder* bmap, |
12678 intptr_t slow_path_bit_count) { | 12024 intptr_t slow_path_bit_count) { |
12679 ASSERT(Object::stackmap_class() != Class::null()); | 12025 ASSERT(Object::stackmap_class() != Class::null()); |
12680 ASSERT(bmap != NULL); | 12026 ASSERT(bmap != NULL); |
12681 StackMap& result = StackMap::Handle(); | 12027 StackMap& result = StackMap::Handle(); |
12682 // Guard against integer overflow of the instance size computation. | 12028 // Guard against integer overflow of the instance size computation. |
12683 intptr_t length = bmap->Length(); | 12029 intptr_t length = bmap->Length(); |
12684 intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; | 12030 intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; |
12685 if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { | 12031 if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { |
(...skipping 14 matching lines...) Expand all Loading... |
12700 // address. | 12046 // address. |
12701 ASSERT(pc_offset >= 0); | 12047 ASSERT(pc_offset >= 0); |
12702 result.SetPcOffset(pc_offset); | 12048 result.SetPcOffset(pc_offset); |
12703 for (intptr_t i = 0; i < length; ++i) { | 12049 for (intptr_t i = 0; i < length; ++i) { |
12704 result.SetBit(i, bmap->Get(i)); | 12050 result.SetBit(i, bmap->Get(i)); |
12705 } | 12051 } |
12706 result.SetSlowPathBitCount(slow_path_bit_count); | 12052 result.SetSlowPathBitCount(slow_path_bit_count); |
12707 return result.raw(); | 12053 return result.raw(); |
12708 } | 12054 } |
12709 | 12055 |
12710 | |
12711 RawStackMap* StackMap::New(intptr_t length, | 12056 RawStackMap* StackMap::New(intptr_t length, |
12712 intptr_t slow_path_bit_count, | 12057 intptr_t slow_path_bit_count, |
12713 intptr_t pc_offset) { | 12058 intptr_t pc_offset) { |
12714 ASSERT(Object::stackmap_class() != Class::null()); | 12059 ASSERT(Object::stackmap_class() != Class::null()); |
12715 StackMap& result = StackMap::Handle(); | 12060 StackMap& result = StackMap::Handle(); |
12716 // Guard against integer overflow of the instance size computation. | 12061 // Guard against integer overflow of the instance size computation. |
12717 intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; | 12062 intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; |
12718 if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { | 12063 if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { |
12719 // This should be caught before we reach here. | 12064 // This should be caught before we reach here. |
12720 FATAL1("Fatal error in StackMap::New: invalid length %" Pd "\n", length); | 12065 FATAL1("Fatal error in StackMap::New: invalid length %" Pd "\n", length); |
12721 } | 12066 } |
12722 { | 12067 { |
12723 // StackMap data objects are associated with a code object, allocate them | 12068 // StackMap data objects are associated with a code object, allocate them |
12724 // in old generation. | 12069 // in old generation. |
12725 RawObject* raw = Object::Allocate( | 12070 RawObject* raw = Object::Allocate( |
12726 StackMap::kClassId, StackMap::InstanceSize(length), Heap::kOld); | 12071 StackMap::kClassId, StackMap::InstanceSize(length), Heap::kOld); |
12727 NoSafepointScope no_safepoint; | 12072 NoSafepointScope no_safepoint; |
12728 result ^= raw; | 12073 result ^= raw; |
12729 result.SetLength(length); | 12074 result.SetLength(length); |
12730 } | 12075 } |
12731 // When constructing a stackmap we store the pc offset in the stackmap's | 12076 // When constructing a stackmap we store the pc offset in the stackmap's |
12732 // PC. StackMapTableBuilder::FinalizeStackMaps will replace it with the pc | 12077 // PC. StackMapTableBuilder::FinalizeStackMaps will replace it with the pc |
12733 // address. | 12078 // address. |
12734 ASSERT(pc_offset >= 0); | 12079 ASSERT(pc_offset >= 0); |
12735 result.SetPcOffset(pc_offset); | 12080 result.SetPcOffset(pc_offset); |
12736 result.SetSlowPathBitCount(slow_path_bit_count); | 12081 result.SetSlowPathBitCount(slow_path_bit_count); |
12737 return result.raw(); | 12082 return result.raw(); |
12738 } | 12083 } |
12739 | 12084 |
12740 | |
12741 const char* StackMap::ToCString() const { | 12085 const char* StackMap::ToCString() const { |
12742 #define FORMAT "%#05x: " | 12086 #define FORMAT "%#05x: " |
12743 if (IsNull()) { | 12087 if (IsNull()) { |
12744 return "{null}"; | 12088 return "{null}"; |
12745 } else { | 12089 } else { |
12746 intptr_t fixed_length = OS::SNPrint(NULL, 0, FORMAT, PcOffset()) + 1; | 12090 intptr_t fixed_length = OS::SNPrint(NULL, 0, FORMAT, PcOffset()) + 1; |
12747 Thread* thread = Thread::Current(); | 12091 Thread* thread = Thread::Current(); |
12748 // Guard against integer overflow in the computation of alloc_size. | 12092 // Guard against integer overflow in the computation of alloc_size. |
12749 // | 12093 // |
12750 // TODO(kmillikin): We could just truncate the string if someone | 12094 // TODO(kmillikin): We could just truncate the string if someone |
12751 // tries to print a 2 billion plus entry stackmap. | 12095 // tries to print a 2 billion plus entry stackmap. |
12752 if (Length() > (kIntptrMax - fixed_length)) { | 12096 if (Length() > (kIntptrMax - fixed_length)) { |
12753 FATAL1("Length() is unexpectedly large (%" Pd ")", Length()); | 12097 FATAL1("Length() is unexpectedly large (%" Pd ")", Length()); |
12754 } | 12098 } |
12755 intptr_t alloc_size = fixed_length + Length(); | 12099 intptr_t alloc_size = fixed_length + Length(); |
12756 char* chars = thread->zone()->Alloc<char>(alloc_size); | 12100 char* chars = thread->zone()->Alloc<char>(alloc_size); |
12757 intptr_t index = OS::SNPrint(chars, alloc_size, FORMAT, PcOffset()); | 12101 intptr_t index = OS::SNPrint(chars, alloc_size, FORMAT, PcOffset()); |
12758 for (intptr_t i = 0; i < Length(); i++) { | 12102 for (intptr_t i = 0; i < Length(); i++) { |
12759 chars[index++] = IsObject(i) ? '1' : '0'; | 12103 chars[index++] = IsObject(i) ? '1' : '0'; |
12760 } | 12104 } |
12761 chars[index] = '\0'; | 12105 chars[index] = '\0'; |
12762 return chars; | 12106 return chars; |
12763 } | 12107 } |
12764 #undef FORMAT | 12108 #undef FORMAT |
12765 } | 12109 } |
12766 | 12110 |
12767 | |
12768 RawString* LocalVarDescriptors::GetName(intptr_t var_index) const { | 12111 RawString* LocalVarDescriptors::GetName(intptr_t var_index) const { |
12769 ASSERT(var_index < Length()); | 12112 ASSERT(var_index < Length()); |
12770 ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString()); | 12113 ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString()); |
12771 return *raw()->nameAddrAt(var_index); | 12114 return *raw()->nameAddrAt(var_index); |
12772 } | 12115 } |
12773 | 12116 |
12774 | |
12775 void LocalVarDescriptors::SetVar(intptr_t var_index, | 12117 void LocalVarDescriptors::SetVar(intptr_t var_index, |
12776 const String& name, | 12118 const String& name, |
12777 RawLocalVarDescriptors::VarInfo* info) const { | 12119 RawLocalVarDescriptors::VarInfo* info) const { |
12778 ASSERT(var_index < Length()); | 12120 ASSERT(var_index < Length()); |
12779 ASSERT(!name.IsNull()); | 12121 ASSERT(!name.IsNull()); |
12780 StorePointer(raw()->nameAddrAt(var_index), name.raw()); | 12122 StorePointer(raw()->nameAddrAt(var_index), name.raw()); |
12781 raw()->data()[var_index] = *info; | 12123 raw()->data()[var_index] = *info; |
12782 } | 12124 } |
12783 | 12125 |
12784 | |
12785 void LocalVarDescriptors::GetInfo(intptr_t var_index, | 12126 void LocalVarDescriptors::GetInfo(intptr_t var_index, |
12786 RawLocalVarDescriptors::VarInfo* info) const { | 12127 RawLocalVarDescriptors::VarInfo* info) const { |
12787 ASSERT(var_index < Length()); | 12128 ASSERT(var_index < Length()); |
12788 *info = raw()->data()[var_index]; | 12129 *info = raw()->data()[var_index]; |
12789 } | 12130 } |
12790 | 12131 |
12791 | |
12792 static int PrintVarInfo(char* buffer, | 12132 static int PrintVarInfo(char* buffer, |
12793 int len, | 12133 int len, |
12794 intptr_t i, | 12134 intptr_t i, |
12795 const String& var_name, | 12135 const String& var_name, |
12796 const RawLocalVarDescriptors::VarInfo& info) { | 12136 const RawLocalVarDescriptors::VarInfo& info) { |
12797 const RawLocalVarDescriptors::VarInfoKind kind = info.kind(); | 12137 const RawLocalVarDescriptors::VarInfoKind kind = info.kind(); |
12798 const int32_t index = info.index(); | 12138 const int32_t index = info.index(); |
12799 if (kind == RawLocalVarDescriptors::kContextLevel) { | 12139 if (kind == RawLocalVarDescriptors::kContextLevel) { |
12800 return OS::SNPrint(buffer, len, | 12140 return OS::SNPrint(buffer, len, |
12801 "%2" Pd | 12141 "%2" Pd |
12802 " %-13s level=%-3d" | 12142 " %-13s level=%-3d" |
12803 " begin=%-3d end=%d\n", | 12143 " begin=%-3d end=%d\n", |
12804 i, LocalVarDescriptors::KindToCString(kind), index, | 12144 i, LocalVarDescriptors::KindToCString(kind), index, |
12805 static_cast<int>(info.begin_pos.value()), | 12145 static_cast<int>(info.begin_pos.value()), |
12806 static_cast<int>(info.end_pos.value())); | 12146 static_cast<int>(info.end_pos.value())); |
12807 } else if (kind == RawLocalVarDescriptors::kContextVar) { | 12147 } else if (kind == RawLocalVarDescriptors::kContextVar) { |
12808 return OS::SNPrint( | 12148 return OS::SNPrint( |
12809 buffer, len, "%2" Pd | 12149 buffer, len, |
12810 " %-13s level=%-3d index=%-3d" | 12150 "%2" Pd |
12811 " begin=%-3d end=%-3d name=%s\n", | 12151 " %-13s level=%-3d index=%-3d" |
| 12152 " begin=%-3d end=%-3d name=%s\n", |
12812 i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, | 12153 i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, |
12813 static_cast<int>(info.begin_pos.Pos()), | 12154 static_cast<int>(info.begin_pos.Pos()), |
12814 static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); | 12155 static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); |
12815 } else { | 12156 } else { |
12816 return OS::SNPrint( | 12157 return OS::SNPrint( |
12817 buffer, len, "%2" Pd | 12158 buffer, len, |
12818 " %-13s scope=%-3d index=%-3d" | 12159 "%2" Pd |
12819 " begin=%-3d end=%-3d name=%s\n", | 12160 " %-13s scope=%-3d index=%-3d" |
| 12161 " begin=%-3d end=%-3d name=%s\n", |
12820 i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, | 12162 i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, |
12821 static_cast<int>(info.begin_pos.Pos()), | 12163 static_cast<int>(info.begin_pos.Pos()), |
12822 static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); | 12164 static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); |
12823 } | 12165 } |
12824 } | 12166 } |
12825 | 12167 |
12826 | |
12827 const char* LocalVarDescriptors::ToCString() const { | 12168 const char* LocalVarDescriptors::ToCString() const { |
12828 if (IsNull()) { | 12169 if (IsNull()) { |
12829 return "LocalVarDescriptors: null"; | 12170 return "LocalVarDescriptors: null"; |
12830 } | 12171 } |
12831 if (Length() == 0) { | 12172 if (Length() == 0) { |
12832 return "empty LocalVarDescriptors"; | 12173 return "empty LocalVarDescriptors"; |
12833 } | 12174 } |
12834 intptr_t len = 1; // Trailing '\0'. | 12175 intptr_t len = 1; // Trailing '\0'. |
12835 String& var_name = String::Handle(); | 12176 String& var_name = String::Handle(); |
12836 for (intptr_t i = 0; i < Length(); i++) { | 12177 for (intptr_t i = 0; i < Length(); i++) { |
12837 RawLocalVarDescriptors::VarInfo info; | 12178 RawLocalVarDescriptors::VarInfo info; |
12838 var_name = GetName(i); | 12179 var_name = GetName(i); |
12839 GetInfo(i, &info); | 12180 GetInfo(i, &info); |
12840 len += PrintVarInfo(NULL, 0, i, var_name, info); | 12181 len += PrintVarInfo(NULL, 0, i, var_name, info); |
12841 } | 12182 } |
12842 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); | 12183 char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); |
12843 buffer[0] = '\0'; | 12184 buffer[0] = '\0'; |
12844 intptr_t num_chars = 0; | 12185 intptr_t num_chars = 0; |
12845 for (intptr_t i = 0; i < Length(); i++) { | 12186 for (intptr_t i = 0; i < Length(); i++) { |
12846 RawLocalVarDescriptors::VarInfo info; | 12187 RawLocalVarDescriptors::VarInfo info; |
12847 var_name = GetName(i); | 12188 var_name = GetName(i); |
12848 GetInfo(i, &info); | 12189 GetInfo(i, &info); |
12849 num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i, | 12190 num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i, |
12850 var_name, info); | 12191 var_name, info); |
12851 } | 12192 } |
12852 return buffer; | 12193 return buffer; |
12853 } | 12194 } |
12854 | 12195 |
12855 | |
12856 const char* LocalVarDescriptors::KindToCString( | 12196 const char* LocalVarDescriptors::KindToCString( |
12857 RawLocalVarDescriptors::VarInfoKind kind) { | 12197 RawLocalVarDescriptors::VarInfoKind kind) { |
12858 switch (kind) { | 12198 switch (kind) { |
12859 case RawLocalVarDescriptors::kStackVar: | 12199 case RawLocalVarDescriptors::kStackVar: |
12860 return "StackVar"; | 12200 return "StackVar"; |
12861 case RawLocalVarDescriptors::kContextVar: | 12201 case RawLocalVarDescriptors::kContextVar: |
12862 return "ContextVar"; | 12202 return "ContextVar"; |
12863 case RawLocalVarDescriptors::kContextLevel: | 12203 case RawLocalVarDescriptors::kContextLevel: |
12864 return "ContextLevel"; | 12204 return "ContextLevel"; |
12865 case RawLocalVarDescriptors::kSavedCurrentContext: | 12205 case RawLocalVarDescriptors::kSavedCurrentContext: |
(...skipping 20 matching lines...) Expand all Loading... |
12886 Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld); | 12226 Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld); |
12887 INC_STAT(Thread::Current(), total_code_size, size); | 12227 INC_STAT(Thread::Current(), total_code_size, size); |
12888 INC_STAT(Thread::Current(), vardesc_size, size); | 12228 INC_STAT(Thread::Current(), vardesc_size, size); |
12889 NoSafepointScope no_safepoint; | 12229 NoSafepointScope no_safepoint; |
12890 result ^= raw; | 12230 result ^= raw; |
12891 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); | 12231 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); |
12892 } | 12232 } |
12893 return result.raw(); | 12233 return result.raw(); |
12894 } | 12234 } |
12895 | 12235 |
12896 | |
12897 intptr_t LocalVarDescriptors::Length() const { | 12236 intptr_t LocalVarDescriptors::Length() const { |
12898 return raw_ptr()->num_entries_; | 12237 return raw_ptr()->num_entries_; |
12899 } | 12238 } |
12900 | 12239 |
12901 | |
12902 intptr_t ExceptionHandlers::num_entries() const { | 12240 intptr_t ExceptionHandlers::num_entries() const { |
12903 return raw_ptr()->num_entries_; | 12241 return raw_ptr()->num_entries_; |
12904 } | 12242 } |
12905 | 12243 |
12906 | |
12907 void ExceptionHandlers::SetHandlerInfo(intptr_t try_index, | 12244 void ExceptionHandlers::SetHandlerInfo(intptr_t try_index, |
12908 intptr_t outer_try_index, | 12245 intptr_t outer_try_index, |
12909 uword handler_pc_offset, | 12246 uword handler_pc_offset, |
12910 bool needs_stacktrace, | 12247 bool needs_stacktrace, |
12911 bool has_catch_all, | 12248 bool has_catch_all, |
12912 TokenPosition token_pos, | 12249 TokenPosition token_pos, |
12913 bool is_generated) const { | 12250 bool is_generated) const { |
12914 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12251 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12915 NoSafepointScope no_safepoint; | 12252 NoSafepointScope no_safepoint; |
12916 ExceptionHandlerInfo* info = | 12253 ExceptionHandlerInfo* info = |
12917 UnsafeMutableNonPointer(&raw_ptr()->data()[try_index]); | 12254 UnsafeMutableNonPointer(&raw_ptr()->data()[try_index]); |
12918 info->outer_try_index = outer_try_index; | 12255 info->outer_try_index = outer_try_index; |
12919 // Some C compilers warn about the comparison always being true when using <= | 12256 // Some C compilers warn about the comparison always being true when using <= |
12920 // due to limited range of data type. | 12257 // due to limited range of data type. |
12921 ASSERT((handler_pc_offset == static_cast<uword>(kMaxUint32)) || | 12258 ASSERT((handler_pc_offset == static_cast<uword>(kMaxUint32)) || |
12922 (handler_pc_offset < static_cast<uword>(kMaxUint32))); | 12259 (handler_pc_offset < static_cast<uword>(kMaxUint32))); |
12923 info->handler_pc_offset = handler_pc_offset; | 12260 info->handler_pc_offset = handler_pc_offset; |
12924 info->needs_stacktrace = needs_stacktrace; | 12261 info->needs_stacktrace = needs_stacktrace; |
12925 info->has_catch_all = has_catch_all; | 12262 info->has_catch_all = has_catch_all; |
12926 info->is_generated = is_generated; | 12263 info->is_generated = is_generated; |
12927 } | 12264 } |
12928 | 12265 |
12929 void ExceptionHandlers::GetHandlerInfo(intptr_t try_index, | 12266 void ExceptionHandlers::GetHandlerInfo(intptr_t try_index, |
12930 ExceptionHandlerInfo* info) const { | 12267 ExceptionHandlerInfo* info) const { |
12931 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12268 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12932 ASSERT(info != NULL); | 12269 ASSERT(info != NULL); |
12933 *info = raw_ptr()->data()[try_index]; | 12270 *info = raw_ptr()->data()[try_index]; |
12934 } | 12271 } |
12935 | 12272 |
12936 | |
12937 uword ExceptionHandlers::HandlerPCOffset(intptr_t try_index) const { | 12273 uword ExceptionHandlers::HandlerPCOffset(intptr_t try_index) const { |
12938 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12274 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12939 return raw_ptr()->data()[try_index].handler_pc_offset; | 12275 return raw_ptr()->data()[try_index].handler_pc_offset; |
12940 } | 12276 } |
12941 | 12277 |
12942 | |
12943 intptr_t ExceptionHandlers::OuterTryIndex(intptr_t try_index) const { | 12278 intptr_t ExceptionHandlers::OuterTryIndex(intptr_t try_index) const { |
12944 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12279 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12945 return raw_ptr()->data()[try_index].outer_try_index; | 12280 return raw_ptr()->data()[try_index].outer_try_index; |
12946 } | 12281 } |
12947 | 12282 |
12948 | |
12949 bool ExceptionHandlers::NeedsStackTrace(intptr_t try_index) const { | 12283 bool ExceptionHandlers::NeedsStackTrace(intptr_t try_index) const { |
12950 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12284 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12951 return raw_ptr()->data()[try_index].needs_stacktrace; | 12285 return raw_ptr()->data()[try_index].needs_stacktrace; |
12952 } | 12286 } |
12953 | 12287 |
12954 | |
12955 bool ExceptionHandlers::IsGenerated(intptr_t try_index) const { | 12288 bool ExceptionHandlers::IsGenerated(intptr_t try_index) const { |
12956 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12289 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12957 return raw_ptr()->data()[try_index].is_generated; | 12290 return raw_ptr()->data()[try_index].is_generated; |
12958 } | 12291 } |
12959 | 12292 |
12960 | |
12961 bool ExceptionHandlers::HasCatchAll(intptr_t try_index) const { | 12293 bool ExceptionHandlers::HasCatchAll(intptr_t try_index) const { |
12962 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12294 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12963 return raw_ptr()->data()[try_index].has_catch_all; | 12295 return raw_ptr()->data()[try_index].has_catch_all; |
12964 } | 12296 } |
12965 | 12297 |
12966 | |
12967 void ExceptionHandlers::SetHandledTypes(intptr_t try_index, | 12298 void ExceptionHandlers::SetHandledTypes(intptr_t try_index, |
12968 const Array& handled_types) const { | 12299 const Array& handled_types) const { |
12969 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12300 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12970 ASSERT(!handled_types.IsNull()); | 12301 ASSERT(!handled_types.IsNull()); |
12971 const Array& handled_types_data = | 12302 const Array& handled_types_data = |
12972 Array::Handle(raw_ptr()->handled_types_data_); | 12303 Array::Handle(raw_ptr()->handled_types_data_); |
12973 handled_types_data.SetAt(try_index, handled_types); | 12304 handled_types_data.SetAt(try_index, handled_types); |
12974 } | 12305 } |
12975 | 12306 |
12976 | |
12977 RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const { | 12307 RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const { |
12978 ASSERT((try_index >= 0) && (try_index < num_entries())); | 12308 ASSERT((try_index >= 0) && (try_index < num_entries())); |
12979 Array& array = Array::Handle(raw_ptr()->handled_types_data_); | 12309 Array& array = Array::Handle(raw_ptr()->handled_types_data_); |
12980 array ^= array.At(try_index); | 12310 array ^= array.At(try_index); |
12981 return array.raw(); | 12311 return array.raw(); |
12982 } | 12312 } |
12983 | 12313 |
12984 | |
12985 void ExceptionHandlers::set_handled_types_data(const Array& value) const { | 12314 void ExceptionHandlers::set_handled_types_data(const Array& value) const { |
12986 StorePointer(&raw_ptr()->handled_types_data_, value.raw()); | 12315 StorePointer(&raw_ptr()->handled_types_data_, value.raw()); |
12987 } | 12316 } |
12988 | 12317 |
12989 | |
12990 RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) { | 12318 RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) { |
12991 ASSERT(Object::exception_handlers_class() != Class::null()); | 12319 ASSERT(Object::exception_handlers_class() != Class::null()); |
12992 if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { | 12320 if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { |
12993 FATAL1( | 12321 FATAL1( |
12994 "Fatal error in ExceptionHandlers::New(): " | 12322 "Fatal error in ExceptionHandlers::New(): " |
12995 "invalid num_handlers %" Pd "\n", | 12323 "invalid num_handlers %" Pd "\n", |
12996 num_handlers); | 12324 num_handlers); |
12997 } | 12325 } |
12998 ExceptionHandlers& result = ExceptionHandlers::Handle(); | 12326 ExceptionHandlers& result = ExceptionHandlers::Handle(); |
12999 { | 12327 { |
13000 uword size = ExceptionHandlers::InstanceSize(num_handlers); | 12328 uword size = ExceptionHandlers::InstanceSize(num_handlers); |
13001 RawObject* raw = | 12329 RawObject* raw = |
13002 Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); | 12330 Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); |
13003 NoSafepointScope no_safepoint; | 12331 NoSafepointScope no_safepoint; |
13004 result ^= raw; | 12332 result ^= raw; |
13005 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); | 12333 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); |
13006 } | 12334 } |
13007 const Array& handled_types_data = | 12335 const Array& handled_types_data = |
13008 (num_handlers == 0) ? Object::empty_array() | 12336 (num_handlers == 0) ? Object::empty_array() |
13009 : Array::Handle(Array::New(num_handlers, Heap::kOld)); | 12337 : Array::Handle(Array::New(num_handlers, Heap::kOld)); |
13010 result.set_handled_types_data(handled_types_data); | 12338 result.set_handled_types_data(handled_types_data); |
13011 return result.raw(); | 12339 return result.raw(); |
13012 } | 12340 } |
13013 | 12341 |
13014 | |
13015 RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) { | 12342 RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) { |
13016 ASSERT(Object::exception_handlers_class() != Class::null()); | 12343 ASSERT(Object::exception_handlers_class() != Class::null()); |
13017 const intptr_t num_handlers = handled_types_data.Length(); | 12344 const intptr_t num_handlers = handled_types_data.Length(); |
13018 if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { | 12345 if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { |
13019 FATAL1( | 12346 FATAL1( |
13020 "Fatal error in ExceptionHandlers::New(): " | 12347 "Fatal error in ExceptionHandlers::New(): " |
13021 "invalid num_handlers %" Pd "\n", | 12348 "invalid num_handlers %" Pd "\n", |
13022 num_handlers); | 12349 num_handlers); |
13023 } | 12350 } |
13024 ExceptionHandlers& result = ExceptionHandlers::Handle(); | 12351 ExceptionHandlers& result = ExceptionHandlers::Handle(); |
13025 { | 12352 { |
13026 uword size = ExceptionHandlers::InstanceSize(num_handlers); | 12353 uword size = ExceptionHandlers::InstanceSize(num_handlers); |
13027 RawObject* raw = | 12354 RawObject* raw = |
13028 Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); | 12355 Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); |
13029 NoSafepointScope no_safepoint; | 12356 NoSafepointScope no_safepoint; |
13030 result ^= raw; | 12357 result ^= raw; |
13031 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); | 12358 result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); |
13032 } | 12359 } |
13033 result.set_handled_types_data(handled_types_data); | 12360 result.set_handled_types_data(handled_types_data); |
13034 return result.raw(); | 12361 return result.raw(); |
13035 } | 12362 } |
13036 | 12363 |
13037 | |
13038 const char* ExceptionHandlers::ToCString() const { | 12364 const char* ExceptionHandlers::ToCString() const { |
13039 #define FORMAT1 "%" Pd " => %#x (%" Pd " types) (outer %d) %s\n" | 12365 #define FORMAT1 "%" Pd " => %#x (%" Pd " types) (outer %d) %s\n" |
13040 #define FORMAT2 " %d. %s\n" | 12366 #define FORMAT2 " %d. %s\n" |
13041 if (num_entries() == 0) { | 12367 if (num_entries() == 0) { |
13042 return "empty ExceptionHandlers\n"; | 12368 return "empty ExceptionHandlers\n"; |
13043 } | 12369 } |
13044 Array& handled_types = Array::Handle(); | 12370 Array& handled_types = Array::Handle(); |
13045 Type& type = Type::Handle(); | 12371 Type& type = Type::Handle(); |
13046 ExceptionHandlerInfo info; | 12372 ExceptionHandlerInfo info; |
13047 // First compute the buffer size required. | 12373 // First compute the buffer size required. |
(...skipping 29 matching lines...) Expand all Loading... |
13077 type ^= handled_types.At(k); | 12403 type ^= handled_types.At(k); |
13078 num_chars += OS::SNPrint((buffer + num_chars), (len - num_chars), FORMAT2, | 12404 num_chars += OS::SNPrint((buffer + num_chars), (len - num_chars), FORMAT2, |
13079 k, type.ToCString()); | 12405 k, type.ToCString()); |
13080 } | 12406 } |
13081 } | 12407 } |
13082 return buffer; | 12408 return buffer; |
13083 #undef FORMAT1 | 12409 #undef FORMAT1 |
13084 #undef FORMAT2 | 12410 #undef FORMAT2 |
13085 } | 12411 } |
13086 | 12412 |
13087 | |
13088 void SingleTargetCache::set_target(const Code& value) const { | 12413 void SingleTargetCache::set_target(const Code& value) const { |
13089 StorePointer(&raw_ptr()->target_, value.raw()); | 12414 StorePointer(&raw_ptr()->target_, value.raw()); |
13090 } | 12415 } |
13091 | 12416 |
13092 | |
13093 const char* SingleTargetCache::ToCString() const { | 12417 const char* SingleTargetCache::ToCString() const { |
13094 return "SingleTargetCache"; | 12418 return "SingleTargetCache"; |
13095 } | 12419 } |
13096 | 12420 |
13097 | |
13098 RawSingleTargetCache* SingleTargetCache::New() { | 12421 RawSingleTargetCache* SingleTargetCache::New() { |
13099 SingleTargetCache& result = SingleTargetCache::Handle(); | 12422 SingleTargetCache& result = SingleTargetCache::Handle(); |
13100 { | 12423 { |
13101 // IC data objects are long living objects, allocate them in old generation. | 12424 // IC data objects are long living objects, allocate them in old generation. |
13102 RawObject* raw = | 12425 RawObject* raw = |
13103 Object::Allocate(SingleTargetCache::kClassId, | 12426 Object::Allocate(SingleTargetCache::kClassId, |
13104 SingleTargetCache::InstanceSize(), Heap::kOld); | 12427 SingleTargetCache::InstanceSize(), Heap::kOld); |
13105 NoSafepointScope no_safepoint; | 12428 NoSafepointScope no_safepoint; |
13106 result ^= raw; | 12429 result ^= raw; |
13107 } | 12430 } |
13108 result.set_target(Code::Handle()); | 12431 result.set_target(Code::Handle()); |
13109 result.set_entry_point(0); | 12432 result.set_entry_point(0); |
13110 result.set_lower_limit(kIllegalCid); | 12433 result.set_lower_limit(kIllegalCid); |
13111 result.set_upper_limit(kIllegalCid); | 12434 result.set_upper_limit(kIllegalCid); |
13112 return result.raw(); | 12435 return result.raw(); |
13113 } | 12436 } |
13114 | 12437 |
13115 | |
13116 void UnlinkedCall::set_target_name(const String& value) const { | 12438 void UnlinkedCall::set_target_name(const String& value) const { |
13117 StorePointer(&raw_ptr()->target_name_, value.raw()); | 12439 StorePointer(&raw_ptr()->target_name_, value.raw()); |
13118 } | 12440 } |
13119 | 12441 |
13120 | |
13121 void UnlinkedCall::set_args_descriptor(const Array& value) const { | 12442 void UnlinkedCall::set_args_descriptor(const Array& value) const { |
13122 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 12443 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |
13123 } | 12444 } |
13124 | 12445 |
13125 | |
13126 const char* UnlinkedCall::ToCString() const { | 12446 const char* UnlinkedCall::ToCString() const { |
13127 return "UnlinkedCall"; | 12447 return "UnlinkedCall"; |
13128 } | 12448 } |
13129 | 12449 |
13130 | |
13131 RawUnlinkedCall* UnlinkedCall::New() { | 12450 RawUnlinkedCall* UnlinkedCall::New() { |
13132 RawObject* raw = Object::Allocate(UnlinkedCall::kClassId, | 12451 RawObject* raw = Object::Allocate(UnlinkedCall::kClassId, |
13133 UnlinkedCall::InstanceSize(), Heap::kOld); | 12452 UnlinkedCall::InstanceSize(), Heap::kOld); |
13134 return reinterpret_cast<RawUnlinkedCall*>(raw); | 12453 return reinterpret_cast<RawUnlinkedCall*>(raw); |
13135 } | 12454 } |
13136 | 12455 |
13137 | |
13138 void ICData::ResetSwitchable(Zone* zone) const { | 12456 void ICData::ResetSwitchable(Zone* zone) const { |
13139 ASSERT(NumArgsTested() == 1); | 12457 ASSERT(NumArgsTested() == 1); |
13140 set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1))); | 12458 set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1))); |
13141 } | 12459 } |
13142 | 12460 |
13143 | |
13144 const char* ICData::ToCString() const { | 12461 const char* ICData::ToCString() const { |
13145 const String& name = String::Handle(target_name()); | 12462 const String& name = String::Handle(target_name()); |
13146 const intptr_t num_args = NumArgsTested(); | 12463 const intptr_t num_args = NumArgsTested(); |
13147 const intptr_t num_checks = NumberOfChecks(); | 12464 const intptr_t num_checks = NumberOfChecks(); |
13148 const intptr_t type_args_len = TypeArgsLen(); | 12465 const intptr_t type_args_len = TypeArgsLen(); |
13149 return OS::SCreate(Thread::Current()->zone(), | 12466 return OS::SCreate(Thread::Current()->zone(), |
13150 "ICData target:'%s' num-args: %" Pd " num-checks: %" Pd | 12467 "ICData target:'%s' num-args: %" Pd " num-checks: %" Pd |
13151 " type-args-len: %" Pd "", | 12468 " type-args-len: %" Pd "", |
13152 name.ToCString(), num_args, num_checks, type_args_len); | 12469 name.ToCString(), num_args, num_checks, type_args_len); |
13153 } | 12470 } |
13154 | 12471 |
13155 | |
13156 RawFunction* ICData::Owner() const { | 12472 RawFunction* ICData::Owner() const { |
13157 Object& obj = Object::Handle(raw_ptr()->owner_); | 12473 Object& obj = Object::Handle(raw_ptr()->owner_); |
13158 if (obj.IsNull()) { | 12474 if (obj.IsNull()) { |
13159 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 12475 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
13160 return Function::null(); | 12476 return Function::null(); |
13161 } else if (obj.IsFunction()) { | 12477 } else if (obj.IsFunction()) { |
13162 return Function::Cast(obj).raw(); | 12478 return Function::Cast(obj).raw(); |
13163 } else { | 12479 } else { |
13164 ICData& original = ICData::Handle(); | 12480 ICData& original = ICData::Handle(); |
13165 original ^= obj.raw(); | 12481 original ^= obj.raw(); |
13166 return original.Owner(); | 12482 return original.Owner(); |
13167 } | 12483 } |
13168 } | 12484 } |
13169 | 12485 |
13170 | |
13171 RawICData* ICData::Original() const { | 12486 RawICData* ICData::Original() const { |
13172 if (IsNull()) { | 12487 if (IsNull()) { |
13173 return ICData::null(); | 12488 return ICData::null(); |
13174 } | 12489 } |
13175 Object& obj = Object::Handle(raw_ptr()->owner_); | 12490 Object& obj = Object::Handle(raw_ptr()->owner_); |
13176 if (obj.IsFunction()) { | 12491 if (obj.IsFunction()) { |
13177 return this->raw(); | 12492 return this->raw(); |
13178 } else { | 12493 } else { |
13179 return ICData::RawCast(obj.raw()); | 12494 return ICData::RawCast(obj.raw()); |
13180 } | 12495 } |
13181 } | 12496 } |
13182 | 12497 |
13183 | |
13184 void ICData::SetOriginal(const ICData& value) const { | 12498 void ICData::SetOriginal(const ICData& value) const { |
13185 ASSERT(value.IsOriginal()); | 12499 ASSERT(value.IsOriginal()); |
13186 ASSERT(!value.IsNull()); | 12500 ASSERT(!value.IsNull()); |
13187 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 12501 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |
13188 } | 12502 } |
13189 | 12503 |
13190 | |
13191 void ICData::set_owner(const Function& value) const { | 12504 void ICData::set_owner(const Function& value) const { |
13192 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 12505 StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |
13193 } | 12506 } |
13194 | 12507 |
13195 | |
13196 void ICData::set_target_name(const String& value) const { | 12508 void ICData::set_target_name(const String& value) const { |
13197 ASSERT(!value.IsNull()); | 12509 ASSERT(!value.IsNull()); |
13198 StorePointer(&raw_ptr()->target_name_, value.raw()); | 12510 StorePointer(&raw_ptr()->target_name_, value.raw()); |
13199 } | 12511 } |
13200 | 12512 |
13201 | |
13202 void ICData::set_arguments_descriptor(const Array& value) const { | 12513 void ICData::set_arguments_descriptor(const Array& value) const { |
13203 ASSERT(!value.IsNull()); | 12514 ASSERT(!value.IsNull()); |
13204 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 12515 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |
13205 } | 12516 } |
13206 | 12517 |
13207 | |
13208 void ICData::set_deopt_id(intptr_t value) const { | 12518 void ICData::set_deopt_id(intptr_t value) const { |
13209 #if defined(DART_PRECOMPILED_RUNTIME) | 12519 #if defined(DART_PRECOMPILED_RUNTIME) |
13210 UNREACHABLE(); | 12520 UNREACHABLE(); |
13211 #else | 12521 #else |
13212 ASSERT(value <= kMaxInt32); | 12522 ASSERT(value <= kMaxInt32); |
13213 StoreNonPointer(&raw_ptr()->deopt_id_, value); | 12523 StoreNonPointer(&raw_ptr()->deopt_id_, value); |
13214 #endif | 12524 #endif |
13215 } | 12525 } |
13216 | 12526 |
13217 | |
13218 void ICData::set_ic_data_array(const Array& value) const { | 12527 void ICData::set_ic_data_array(const Array& value) const { |
13219 ASSERT(!value.IsNull()); | 12528 ASSERT(!value.IsNull()); |
13220 StorePointer(&raw_ptr()->ic_data_, value.raw()); | 12529 StorePointer(&raw_ptr()->ic_data_, value.raw()); |
13221 } | 12530 } |
13222 | 12531 |
13223 | |
13224 #if defined(TAG_IC_DATA) | 12532 #if defined(TAG_IC_DATA) |
13225 void ICData::set_tag(intptr_t value) const { | 12533 void ICData::set_tag(intptr_t value) const { |
13226 StoreNonPointer(&raw_ptr()->tag_, value); | 12534 StoreNonPointer(&raw_ptr()->tag_, value); |
13227 } | 12535 } |
13228 #endif | 12536 #endif |
13229 | 12537 |
13230 intptr_t ICData::NumArgsTested() const { | 12538 intptr_t ICData::NumArgsTested() const { |
13231 return NumArgsTestedBits::decode(raw_ptr()->state_bits_); | 12539 return NumArgsTestedBits::decode(raw_ptr()->state_bits_); |
13232 } | 12540 } |
13233 | 12541 |
13234 | |
13235 intptr_t ICData::TypeArgsLen() const { | 12542 intptr_t ICData::TypeArgsLen() const { |
13236 ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor())); | 12543 ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor())); |
13237 return args_desc.TypeArgsLen(); | 12544 return args_desc.TypeArgsLen(); |
13238 } | 12545 } |
13239 | 12546 |
13240 | |
13241 void ICData::SetNumArgsTested(intptr_t value) const { | 12547 void ICData::SetNumArgsTested(intptr_t value) const { |
13242 ASSERT(Utils::IsUint(2, value)); | 12548 ASSERT(Utils::IsUint(2, value)); |
13243 StoreNonPointer(&raw_ptr()->state_bits_, | 12549 StoreNonPointer(&raw_ptr()->state_bits_, |
13244 NumArgsTestedBits::update(value, raw_ptr()->state_bits_)); | 12550 NumArgsTestedBits::update(value, raw_ptr()->state_bits_)); |
13245 } | 12551 } |
13246 | 12552 |
13247 | |
13248 uint32_t ICData::DeoptReasons() const { | 12553 uint32_t ICData::DeoptReasons() const { |
13249 return DeoptReasonBits::decode(raw_ptr()->state_bits_); | 12554 return DeoptReasonBits::decode(raw_ptr()->state_bits_); |
13250 } | 12555 } |
13251 | 12556 |
13252 | |
13253 void ICData::SetDeoptReasons(uint32_t reasons) const { | 12557 void ICData::SetDeoptReasons(uint32_t reasons) const { |
13254 StoreNonPointer(&raw_ptr()->state_bits_, | 12558 StoreNonPointer(&raw_ptr()->state_bits_, |
13255 DeoptReasonBits::update(reasons, raw_ptr()->state_bits_)); | 12559 DeoptReasonBits::update(reasons, raw_ptr()->state_bits_)); |
13256 } | 12560 } |
13257 | 12561 |
13258 | |
13259 bool ICData::HasDeoptReason(DeoptReasonId reason) const { | 12562 bool ICData::HasDeoptReason(DeoptReasonId reason) const { |
13260 ASSERT(reason <= kLastRecordedDeoptReason); | 12563 ASSERT(reason <= kLastRecordedDeoptReason); |
13261 return (DeoptReasons() & (1 << reason)) != 0; | 12564 return (DeoptReasons() & (1 << reason)) != 0; |
13262 } | 12565 } |
13263 | 12566 |
13264 | |
13265 void ICData::AddDeoptReason(DeoptReasonId reason) const { | 12567 void ICData::AddDeoptReason(DeoptReasonId reason) const { |
13266 if (reason <= kLastRecordedDeoptReason) { | 12568 if (reason <= kLastRecordedDeoptReason) { |
13267 SetDeoptReasons(DeoptReasons() | (1 << reason)); | 12569 SetDeoptReasons(DeoptReasons() | (1 << reason)); |
13268 } | 12570 } |
13269 } | 12571 } |
13270 | 12572 |
13271 | |
13272 void ICData::SetIsStaticCall(bool static_call) const { | 12573 void ICData::SetIsStaticCall(bool static_call) const { |
13273 StoreNonPointer(&raw_ptr()->state_bits_, | 12574 StoreNonPointer(&raw_ptr()->state_bits_, |
13274 StaticCallBit::update(static_call, raw_ptr()->state_bits_)); | 12575 StaticCallBit::update(static_call, raw_ptr()->state_bits_)); |
13275 } | 12576 } |
13276 | 12577 |
13277 | |
13278 bool ICData::is_static_call() const { | 12578 bool ICData::is_static_call() const { |
13279 return StaticCallBit::decode(raw_ptr()->state_bits_); | 12579 return StaticCallBit::decode(raw_ptr()->state_bits_); |
13280 } | 12580 } |
13281 | 12581 |
13282 | |
13283 void ICData::set_state_bits(uint32_t bits) const { | 12582 void ICData::set_state_bits(uint32_t bits) const { |
13284 StoreNonPointer(&raw_ptr()->state_bits_, bits); | 12583 StoreNonPointer(&raw_ptr()->state_bits_, bits); |
13285 } | 12584 } |
13286 | 12585 |
13287 | |
13288 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { | 12586 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { |
13289 return num_args + 1 /* target function*/ + 1 /* frequency */; | 12587 return num_args + 1 /* target function*/ + 1 /* frequency */; |
13290 } | 12588 } |
13291 | 12589 |
13292 | |
13293 intptr_t ICData::TestEntryLength() const { | 12590 intptr_t ICData::TestEntryLength() const { |
13294 return TestEntryLengthFor(NumArgsTested()); | 12591 return TestEntryLengthFor(NumArgsTested()); |
13295 } | 12592 } |
13296 | 12593 |
13297 | |
13298 intptr_t ICData::Length() const { | 12594 intptr_t ICData::Length() const { |
13299 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()); | 12595 return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()); |
13300 } | 12596 } |
13301 | 12597 |
13302 | |
13303 intptr_t ICData::NumberOfChecks() const { | 12598 intptr_t ICData::NumberOfChecks() const { |
13304 const intptr_t length = Length(); | 12599 const intptr_t length = Length(); |
13305 for (intptr_t i = 0; i < length; i++) { | 12600 for (intptr_t i = 0; i < length; i++) { |
13306 if (IsSentinelAt(i)) { | 12601 if (IsSentinelAt(i)) { |
13307 return i; | 12602 return i; |
13308 } | 12603 } |
13309 } | 12604 } |
13310 UNREACHABLE(); | 12605 UNREACHABLE(); |
13311 return -1; | 12606 return -1; |
13312 } | 12607 } |
13313 | 12608 |
13314 | |
13315 bool ICData::NumberOfChecksIs(intptr_t n) const { | 12609 bool ICData::NumberOfChecksIs(intptr_t n) const { |
13316 const intptr_t length = Length(); | 12610 const intptr_t length = Length(); |
13317 for (intptr_t i = 0; i < length; i++) { | 12611 for (intptr_t i = 0; i < length; i++) { |
13318 if (i == n) { | 12612 if (i == n) { |
13319 return IsSentinelAt(i); | 12613 return IsSentinelAt(i); |
13320 } else { | 12614 } else { |
13321 if (IsSentinelAt(i)) return false; | 12615 if (IsSentinelAt(i)) return false; |
13322 } | 12616 } |
13323 } | 12617 } |
13324 return n == length; | 12618 return n == length; |
13325 } | 12619 } |
13326 | 12620 |
13327 | |
13328 // Discounts any checks with usage of zero. | 12621 // Discounts any checks with usage of zero. |
13329 intptr_t ICData::NumberOfUsedChecks() const { | 12622 intptr_t ICData::NumberOfUsedChecks() const { |
13330 intptr_t n = NumberOfChecks(); | 12623 intptr_t n = NumberOfChecks(); |
13331 if (n == 0) { | 12624 if (n == 0) { |
13332 return 0; | 12625 return 0; |
13333 } | 12626 } |
13334 intptr_t count = 0; | 12627 intptr_t count = 0; |
13335 for (intptr_t i = 0; i < n; i++) { | 12628 for (intptr_t i = 0; i < n; i++) { |
13336 if (GetCountAt(i) > 0) { | 12629 if (GetCountAt(i) > 0) { |
13337 count++; | 12630 count++; |
13338 } | 12631 } |
13339 } | 12632 } |
13340 return count; | 12633 return count; |
13341 } | 12634 } |
13342 | 12635 |
13343 | |
13344 void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) { | 12636 void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) { |
13345 ASSERT(!data.IsNull()); | 12637 ASSERT(!data.IsNull()); |
13346 for (intptr_t i = 1; i <= test_entry_length; i++) { | 12638 for (intptr_t i = 1; i <= test_entry_length; i++) { |
13347 data.SetAt(data.Length() - i, smi_illegal_cid()); | 12639 data.SetAt(data.Length() - i, smi_illegal_cid()); |
13348 } | 12640 } |
13349 } | 12641 } |
13350 | 12642 |
13351 | |
13352 #if defined(DEBUG) | 12643 #if defined(DEBUG) |
13353 // Used in asserts to verify that a check is not added twice. | 12644 // Used in asserts to verify that a check is not added twice. |
13354 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 12645 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |
13355 const intptr_t len = NumberOfChecks(); | 12646 const intptr_t len = NumberOfChecks(); |
13356 for (intptr_t i = 0; i < len; i++) { | 12647 for (intptr_t i = 0; i < len; i++) { |
13357 GrowableArray<intptr_t> class_ids; | 12648 GrowableArray<intptr_t> class_ids; |
13358 GetClassIdsAt(i, &class_ids); | 12649 GetClassIdsAt(i, &class_ids); |
13359 bool matches = true; | 12650 bool matches = true; |
13360 for (intptr_t k = 0; k < class_ids.length(); k++) { | 12651 for (intptr_t k = 0; k < class_ids.length(); k++) { |
13361 ASSERT(class_ids[k] != kIllegalCid); | 12652 ASSERT(class_ids[k] != kIllegalCid); |
13362 if (class_ids[k] != cids[k]) { | 12653 if (class_ids[k] != cids[k]) { |
13363 matches = false; | 12654 matches = false; |
13364 break; | 12655 break; |
13365 } | 12656 } |
13366 } | 12657 } |
13367 if (matches) { | 12658 if (matches) { |
13368 return true; | 12659 return true; |
13369 } | 12660 } |
13370 } | 12661 } |
13371 return false; | 12662 return false; |
13372 } | 12663 } |
13373 #endif // DEBUG | 12664 #endif // DEBUG |
13374 | 12665 |
13375 | |
13376 void ICData::WriteSentinelAt(intptr_t index) const { | 12666 void ICData::WriteSentinelAt(intptr_t index) const { |
13377 const intptr_t len = Length(); | 12667 const intptr_t len = Length(); |
13378 ASSERT(index >= 0); | 12668 ASSERT(index >= 0); |
13379 ASSERT(index < len); | 12669 ASSERT(index < len); |
13380 Array& data = Array::Handle(ic_data()); | 12670 Array& data = Array::Handle(ic_data()); |
13381 const intptr_t start = index * TestEntryLength(); | 12671 const intptr_t start = index * TestEntryLength(); |
13382 const intptr_t end = start + TestEntryLength(); | 12672 const intptr_t end = start + TestEntryLength(); |
13383 for (intptr_t i = start; i < end; i++) { | 12673 for (intptr_t i = start; i < end; i++) { |
13384 data.SetAt(i, smi_illegal_cid()); | 12674 data.SetAt(i, smi_illegal_cid()); |
13385 } | 12675 } |
13386 } | 12676 } |
13387 | 12677 |
13388 | |
13389 void ICData::ClearCountAt(intptr_t index) const { | 12678 void ICData::ClearCountAt(intptr_t index) const { |
13390 ASSERT(index >= 0); | 12679 ASSERT(index >= 0); |
13391 ASSERT(index < NumberOfChecks()); | 12680 ASSERT(index < NumberOfChecks()); |
13392 SetCountAt(index, 0); | 12681 SetCountAt(index, 0); |
13393 } | 12682 } |
13394 | 12683 |
13395 | |
13396 void ICData::ClearWithSentinel() const { | 12684 void ICData::ClearWithSentinel() const { |
13397 if (IsImmutable()) { | 12685 if (IsImmutable()) { |
13398 return; | 12686 return; |
13399 } | 12687 } |
13400 // Write the sentinel value into all entries except the first one. | 12688 // Write the sentinel value into all entries except the first one. |
13401 const intptr_t len = Length(); | 12689 const intptr_t len = Length(); |
13402 if (len == 0) { | 12690 if (len == 0) { |
13403 return; | 12691 return; |
13404 } | 12692 } |
13405 // The final entry is always the sentinel. | 12693 // The final entry is always the sentinel. |
(...skipping 19 matching lines...) Expand all Loading... |
13425 GetCheckAt(0, &class_ids, &target); | 12713 GetCheckAt(0, &class_ids, &target); |
13426 if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && | 12714 if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && |
13427 (class_ids[1] == kSmiCid)) { | 12715 (class_ids[1] == kSmiCid)) { |
13428 // The smi fast path case, preserve the initial entry but reset the count. | 12716 // The smi fast path case, preserve the initial entry but reset the count. |
13429 ClearCountAt(0); | 12717 ClearCountAt(0); |
13430 return; | 12718 return; |
13431 } | 12719 } |
13432 WriteSentinelAt(0); | 12720 WriteSentinelAt(0); |
13433 } | 12721 } |
13434 | 12722 |
13435 | |
13436 void ICData::ClearAndSetStaticTarget(const Function& func) const { | 12723 void ICData::ClearAndSetStaticTarget(const Function& func) const { |
13437 if (IsImmutable()) { | 12724 if (IsImmutable()) { |
13438 return; | 12725 return; |
13439 } | 12726 } |
13440 const intptr_t len = Length(); | 12727 const intptr_t len = Length(); |
13441 if (len == 0) { | 12728 if (len == 0) { |
13442 return; | 12729 return; |
13443 } | 12730 } |
13444 // The final entry is always the sentinel. | 12731 // The final entry is always the sentinel. |
13445 ASSERT(IsSentinelAt(len - 1)); | 12732 ASSERT(IsSentinelAt(len - 1)); |
(...skipping 23 matching lines...) Expand all Loading... |
13469 const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid)); | 12756 const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid)); |
13470 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 12757 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
13471 data.SetAt(i, object_cid); | 12758 data.SetAt(i, object_cid); |
13472 } | 12759 } |
13473 data.SetAt(NumArgsTested(), func); | 12760 data.SetAt(NumArgsTested(), func); |
13474 const Smi& value = Smi::Handle(Smi::New(0)); | 12761 const Smi& value = Smi::Handle(Smi::New(0)); |
13475 data.SetAt(NumArgsTested() + 1, value); | 12762 data.SetAt(NumArgsTested() + 1, value); |
13476 } | 12763 } |
13477 } | 12764 } |
13478 | 12765 |
13479 | |
13480 // Add an initial Smi/Smi check with count 0. | 12766 // Add an initial Smi/Smi check with count 0. |
13481 bool ICData::AddSmiSmiCheckForFastSmiStubs() const { | 12767 bool ICData::AddSmiSmiCheckForFastSmiStubs() const { |
13482 bool is_smi_two_args_op = false; | 12768 bool is_smi_two_args_op = false; |
13483 | 12769 |
13484 ASSERT(NumArgsTested() == 2); | 12770 ASSERT(NumArgsTested() == 2); |
13485 const String& name = String::Handle(target_name()); | 12771 const String& name = String::Handle(target_name()); |
13486 const Class& smi_class = Class::Handle(Smi::Class()); | 12772 const Class& smi_class = Class::Handle(Smi::Class()); |
13487 Zone* zone = Thread::Current()->zone(); | 12773 Zone* zone = Thread::Current()->zone(); |
13488 const Function& smi_op_target = | 12774 const Function& smi_op_target = |
13489 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name)); | 12775 Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name)); |
(...skipping 10 matching lines...) Expand all Loading... |
13500 Function& target = Function::Handle(); | 12786 Function& target = Function::Handle(); |
13501 GetCheckAt(0, &class_ids, &target); | 12787 GetCheckAt(0, &class_ids, &target); |
13502 if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && | 12788 if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && |
13503 (class_ids[1] == kSmiCid)) { | 12789 (class_ids[1] == kSmiCid)) { |
13504 is_smi_two_args_op = true; | 12790 is_smi_two_args_op = true; |
13505 } | 12791 } |
13506 } | 12792 } |
13507 return is_smi_two_args_op; | 12793 return is_smi_two_args_op; |
13508 } | 12794 } |
13509 | 12795 |
13510 | |
13511 // Used for unoptimized static calls when no class-ids are checked. | 12796 // Used for unoptimized static calls when no class-ids are checked. |
13512 void ICData::AddTarget(const Function& target) const { | 12797 void ICData::AddTarget(const Function& target) const { |
13513 ASSERT(!target.IsNull()); | 12798 ASSERT(!target.IsNull()); |
13514 if (NumArgsTested() > 0) { | 12799 if (NumArgsTested() > 0) { |
13515 // Create a fake cid entry, so that we can store the target. | 12800 // Create a fake cid entry, so that we can store the target. |
13516 if (NumArgsTested() == 1) { | 12801 if (NumArgsTested() == 1) { |
13517 AddReceiverCheck(kObjectCid, target, 1); | 12802 AddReceiverCheck(kObjectCid, target, 1); |
13518 } else { | 12803 } else { |
13519 GrowableArray<intptr_t> class_ids(NumArgsTested()); | 12804 GrowableArray<intptr_t> class_ids(NumArgsTested()); |
13520 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 12805 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
(...skipping 16 matching lines...) Expand all Loading... |
13537 data.SetAt(data_pos++, target); | 12822 data.SetAt(data_pos++, target); |
13538 // Set count to 0 as this is called during compilation, before the | 12823 // Set count to 0 as this is called during compilation, before the |
13539 // call has been executed. | 12824 // call has been executed. |
13540 const Smi& value = Smi::Handle(Smi::New(0)); | 12825 const Smi& value = Smi::Handle(Smi::New(0)); |
13541 data.SetAt(data_pos, value); | 12826 data.SetAt(data_pos, value); |
13542 // Multithreaded access to ICData requires setting of array to be the last | 12827 // Multithreaded access to ICData requires setting of array to be the last |
13543 // operation. | 12828 // operation. |
13544 set_ic_data_array(data); | 12829 set_ic_data_array(data); |
13545 } | 12830 } |
13546 | 12831 |
13547 | |
13548 bool ICData::ValidateInterceptor(const Function& target) const { | 12832 bool ICData::ValidateInterceptor(const Function& target) const { |
13549 ObjectStore* store = Isolate::Current()->object_store(); | 12833 ObjectStore* store = Isolate::Current()->object_store(); |
13550 ASSERT((target.raw() == store->simple_instance_of_true_function()) || | 12834 ASSERT((target.raw() == store->simple_instance_of_true_function()) || |
13551 (target.raw() == store->simple_instance_of_false_function())); | 12835 (target.raw() == store->simple_instance_of_false_function())); |
13552 const String& instance_of_name = String::Handle( | 12836 const String& instance_of_name = String::Handle( |
13553 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()); | 12837 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()); |
13554 ASSERT(target_name() == instance_of_name.raw()); | 12838 ASSERT(target_name() == instance_of_name.raw()); |
13555 return true; | 12839 return true; |
13556 } | 12840 } |
13557 | 12841 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13601 } | 12885 } |
13602 ASSERT(!target.IsNull()); | 12886 ASSERT(!target.IsNull()); |
13603 data.SetAt(data_pos++, target); | 12887 data.SetAt(data_pos++, target); |
13604 value = Smi::New(count); | 12888 value = Smi::New(count); |
13605 data.SetAt(data_pos, value); | 12889 data.SetAt(data_pos, value); |
13606 // Multithreaded access to ICData requires setting of array to be the last | 12890 // Multithreaded access to ICData requires setting of array to be the last |
13607 // operation. | 12891 // operation. |
13608 set_ic_data_array(data); | 12892 set_ic_data_array(data); |
13609 } | 12893 } |
13610 | 12894 |
13611 | |
13612 RawArray* ICData::FindFreeIndex(intptr_t* index) const { | 12895 RawArray* ICData::FindFreeIndex(intptr_t* index) const { |
13613 // The final entry is always the sentinel value, don't consider it | 12896 // The final entry is always the sentinel value, don't consider it |
13614 // when searching. | 12897 // when searching. |
13615 const intptr_t len = Length() - 1; | 12898 const intptr_t len = Length() - 1; |
13616 Array& data = Array::Handle(ic_data()); | 12899 Array& data = Array::Handle(ic_data()); |
13617 *index = len; | 12900 *index = len; |
13618 for (intptr_t i = 0; i < len; i++) { | 12901 for (intptr_t i = 0; i < len; i++) { |
13619 if (IsSentinelAt(i)) { | 12902 if (IsSentinelAt(i)) { |
13620 *index = i; | 12903 *index = i; |
13621 break; | 12904 break; |
13622 } | 12905 } |
13623 } | 12906 } |
13624 if (*index < len) { | 12907 if (*index < len) { |
13625 // We've found a free slot. | 12908 // We've found a free slot. |
13626 return data.raw(); | 12909 return data.raw(); |
13627 } | 12910 } |
13628 // Append case. | 12911 // Append case. |
13629 ASSERT(*index == len); | 12912 ASSERT(*index == len); |
13630 ASSERT(*index >= 0); | 12913 ASSERT(*index >= 0); |
13631 // Grow array. | 12914 // Grow array. |
13632 const intptr_t new_len = data.Length() + TestEntryLength(); | 12915 const intptr_t new_len = data.Length() + TestEntryLength(); |
13633 data = Array::Grow(data, new_len, Heap::kOld); | 12916 data = Array::Grow(data, new_len, Heap::kOld); |
13634 WriteSentinel(data, TestEntryLength()); | 12917 WriteSentinel(data, TestEntryLength()); |
13635 return data.raw(); | 12918 return data.raw(); |
13636 } | 12919 } |
13637 | 12920 |
13638 | |
13639 void ICData::DebugDump() const { | 12921 void ICData::DebugDump() const { |
13640 const Function& owner = Function::Handle(Owner()); | 12922 const Function& owner = Function::Handle(Owner()); |
13641 THR_Print("ICData::DebugDump\n"); | 12923 THR_Print("ICData::DebugDump\n"); |
13642 THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id()); | 12924 THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id()); |
13643 THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested()); | 12925 THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested()); |
13644 THR_Print("Length = %" Pd "\n", Length()); | 12926 THR_Print("Length = %" Pd "\n", Length()); |
13645 THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks()); | 12927 THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks()); |
13646 | 12928 |
13647 GrowableArray<intptr_t> class_ids; | 12929 GrowableArray<intptr_t> class_ids; |
13648 for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 12930 for (intptr_t i = 0; i < NumberOfChecks(); i++) { |
13649 THR_Print("Check[%" Pd "]:", i); | 12931 THR_Print("Check[%" Pd "]:", i); |
13650 GetClassIdsAt(i, &class_ids); | 12932 GetClassIdsAt(i, &class_ids); |
13651 for (intptr_t c = 0; c < class_ids.length(); c++) { | 12933 for (intptr_t c = 0; c < class_ids.length(); c++) { |
13652 THR_Print(" %" Pd "", class_ids[c]); | 12934 THR_Print(" %" Pd "", class_ids[c]); |
13653 } | 12935 } |
13654 THR_Print("--- %" Pd " hits\n", GetCountAt(i)); | 12936 THR_Print("--- %" Pd " hits\n", GetCountAt(i)); |
13655 } | 12937 } |
13656 } | 12938 } |
13657 | 12939 |
13658 | |
13659 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 12940 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
13660 const Function& target, | 12941 const Function& target, |
13661 intptr_t count) const { | 12942 intptr_t count) const { |
13662 #if defined(DEBUG) | 12943 #if defined(DEBUG) |
13663 GrowableArray<intptr_t> class_ids(1); | 12944 GrowableArray<intptr_t> class_ids(1); |
13664 class_ids.Add(receiver_class_id); | 12945 class_ids.Add(receiver_class_id); |
13665 ASSERT(!HasCheck(class_ids)); | 12946 ASSERT(!HasCheck(class_ids)); |
13666 #endif // DEBUG | 12947 #endif // DEBUG |
13667 ASSERT(!target.IsNull()); | 12948 ASSERT(!target.IsNull()); |
13668 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. | 12949 ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'. |
(...skipping 22 matching lines...) Expand all Loading... |
13691 const Smi& entry_point = | 12972 const Smi& entry_point = |
13692 Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint())); | 12973 Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint())); |
13693 data.SetAt(data_pos + 1, code); | 12974 data.SetAt(data_pos + 1, code); |
13694 data.SetAt(data_pos + 2, entry_point); | 12975 data.SetAt(data_pos + 2, entry_point); |
13695 } | 12976 } |
13696 // Multithreaded access to ICData requires setting of array to be the last | 12977 // Multithreaded access to ICData requires setting of array to be the last |
13697 // operation. | 12978 // operation. |
13698 set_ic_data_array(data); | 12979 set_ic_data_array(data); |
13699 } | 12980 } |
13700 | 12981 |
13701 | |
13702 void ICData::GetCheckAt(intptr_t index, | 12982 void ICData::GetCheckAt(intptr_t index, |
13703 GrowableArray<intptr_t>* class_ids, | 12983 GrowableArray<intptr_t>* class_ids, |
13704 Function* target) const { | 12984 Function* target) const { |
13705 ASSERT(index < NumberOfChecks()); | 12985 ASSERT(index < NumberOfChecks()); |
13706 ASSERT(class_ids != NULL); | 12986 ASSERT(class_ids != NULL); |
13707 ASSERT(target != NULL); | 12987 ASSERT(target != NULL); |
13708 class_ids->Clear(); | 12988 class_ids->Clear(); |
13709 const Array& data = Array::Handle(ic_data()); | 12989 const Array& data = Array::Handle(ic_data()); |
13710 intptr_t data_pos = index * TestEntryLength(); | 12990 intptr_t data_pos = index * TestEntryLength(); |
13711 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 12991 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
13712 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); | 12992 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |
13713 } | 12993 } |
13714 (*target) ^= data.At(data_pos++); | 12994 (*target) ^= data.At(data_pos++); |
13715 } | 12995 } |
13716 | 12996 |
13717 | |
13718 bool ICData::IsSentinelAt(intptr_t index) const { | 12997 bool ICData::IsSentinelAt(intptr_t index) const { |
13719 ASSERT(index < Length()); | 12998 ASSERT(index < Length()); |
13720 const Array& data = Array::Handle(ic_data()); | 12999 const Array& data = Array::Handle(ic_data()); |
13721 const intptr_t entry_length = TestEntryLength(); | 13000 const intptr_t entry_length = TestEntryLength(); |
13722 intptr_t data_pos = index * TestEntryLength(); | 13001 intptr_t data_pos = index * TestEntryLength(); |
13723 for (intptr_t i = 0; i < entry_length; i++) { | 13002 for (intptr_t i = 0; i < entry_length; i++) { |
13724 if (data.At(data_pos++) != smi_illegal_cid().raw()) { | 13003 if (data.At(data_pos++) != smi_illegal_cid().raw()) { |
13725 return false; | 13004 return false; |
13726 } | 13005 } |
13727 } | 13006 } |
13728 // The entry at |index| was filled with the value kIllegalCid. | 13007 // The entry at |index| was filled with the value kIllegalCid. |
13729 return true; | 13008 return true; |
13730 } | 13009 } |
13731 | 13010 |
13732 | |
13733 void ICData::GetClassIdsAt(intptr_t index, | 13011 void ICData::GetClassIdsAt(intptr_t index, |
13734 GrowableArray<intptr_t>* class_ids) const { | 13012 GrowableArray<intptr_t>* class_ids) const { |
13735 ASSERT(index < Length()); | 13013 ASSERT(index < Length()); |
13736 ASSERT(class_ids != NULL); | 13014 ASSERT(class_ids != NULL); |
13737 ASSERT(!IsSentinelAt(index)); | 13015 ASSERT(!IsSentinelAt(index)); |
13738 class_ids->Clear(); | 13016 class_ids->Clear(); |
13739 const Array& data = Array::Handle(ic_data()); | 13017 const Array& data = Array::Handle(ic_data()); |
13740 intptr_t data_pos = index * TestEntryLength(); | 13018 intptr_t data_pos = index * TestEntryLength(); |
13741 for (intptr_t i = 0; i < NumArgsTested(); i++) { | 13019 for (intptr_t i = 0; i < NumArgsTested(); i++) { |
13742 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); | 13020 class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |
13743 } | 13021 } |
13744 } | 13022 } |
13745 | 13023 |
13746 | |
13747 void ICData::GetOneClassCheckAt(intptr_t index, | 13024 void ICData::GetOneClassCheckAt(intptr_t index, |
13748 intptr_t* class_id, | 13025 intptr_t* class_id, |
13749 Function* target) const { | 13026 Function* target) const { |
13750 ASSERT(class_id != NULL); | 13027 ASSERT(class_id != NULL); |
13751 ASSERT(target != NULL); | 13028 ASSERT(target != NULL); |
13752 ASSERT(NumArgsTested() == 1); | 13029 ASSERT(NumArgsTested() == 1); |
13753 const Array& data = Array::Handle(ic_data()); | 13030 const Array& data = Array::Handle(ic_data()); |
13754 const intptr_t data_pos = index * TestEntryLength(); | 13031 const intptr_t data_pos = index * TestEntryLength(); |
13755 *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); | 13032 *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); |
13756 *target ^= data.At(data_pos + 1); | 13033 *target ^= data.At(data_pos + 1); |
13757 } | 13034 } |
13758 | 13035 |
13759 | |
13760 intptr_t ICData::GetCidAt(intptr_t index) const { | 13036 intptr_t ICData::GetCidAt(intptr_t index) const { |
13761 ASSERT(NumArgsTested() == 1); | 13037 ASSERT(NumArgsTested() == 1); |
13762 const Array& data = Array::Handle(ic_data()); | 13038 const Array& data = Array::Handle(ic_data()); |
13763 const intptr_t data_pos = index * TestEntryLength(); | 13039 const intptr_t data_pos = index * TestEntryLength(); |
13764 return Smi::Value(Smi::RawCast(data.At(data_pos))); | 13040 return Smi::Value(Smi::RawCast(data.At(data_pos))); |
13765 } | 13041 } |
13766 | 13042 |
13767 | |
13768 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { | 13043 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { |
13769 GrowableArray<intptr_t> class_ids; | 13044 GrowableArray<intptr_t> class_ids; |
13770 GetClassIdsAt(index, &class_ids); | 13045 GetClassIdsAt(index, &class_ids); |
13771 return class_ids[arg_nr]; | 13046 return class_ids[arg_nr]; |
13772 } | 13047 } |
13773 | 13048 |
13774 | |
13775 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { | 13049 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { |
13776 ASSERT(index < Length()); | 13050 ASSERT(index < Length()); |
13777 ASSERT(!IsSentinelAt(index)); | 13051 ASSERT(!IsSentinelAt(index)); |
13778 const intptr_t data_pos = index * TestEntryLength(); | 13052 const intptr_t data_pos = index * TestEntryLength(); |
13779 NoSafepointScope no_safepoint; | 13053 NoSafepointScope no_safepoint; |
13780 RawArray* raw_data = ic_data(); | 13054 RawArray* raw_data = ic_data(); |
13781 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); | 13055 return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); |
13782 } | 13056 } |
13783 | 13057 |
13784 | |
13785 RawFunction* ICData::GetTargetAt(intptr_t index) const { | 13058 RawFunction* ICData::GetTargetAt(intptr_t index) const { |
13786 ASSERT(Isolate::Current()->compilation_allowed()); | 13059 ASSERT(Isolate::Current()->compilation_allowed()); |
13787 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); | 13060 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); |
13788 ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction()); | 13061 ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction()); |
13789 | 13062 |
13790 NoSafepointScope no_safepoint; | 13063 NoSafepointScope no_safepoint; |
13791 RawArray* raw_data = ic_data(); | 13064 RawArray* raw_data = ic_data(); |
13792 return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]); | 13065 return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]); |
13793 } | 13066 } |
13794 | 13067 |
13795 | |
13796 RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const { | 13068 RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const { |
13797 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); | 13069 const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); |
13798 | 13070 |
13799 NoSafepointScope no_safepoint; | 13071 NoSafepointScope no_safepoint; |
13800 RawArray* raw_data = ic_data(); | 13072 RawArray* raw_data = ic_data(); |
13801 return raw_data->ptr()->data()[data_pos]; | 13073 return raw_data->ptr()->data()[data_pos]; |
13802 } | 13074 } |
13803 | 13075 |
13804 | |
13805 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const { | 13076 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const { |
13806 ASSERT(0 <= value); | 13077 ASSERT(0 <= value); |
13807 ASSERT(value <= Smi::kMaxValue); | 13078 ASSERT(value <= Smi::kMaxValue); |
13808 SetCountAt(index, Utils::Minimum(GetCountAt(index) + value, Smi::kMaxValue)); | 13079 SetCountAt(index, Utils::Minimum(GetCountAt(index) + value, Smi::kMaxValue)); |
13809 } | 13080 } |
13810 | 13081 |
13811 | |
13812 void ICData::SetCountAt(intptr_t index, intptr_t value) const { | 13082 void ICData::SetCountAt(intptr_t index, intptr_t value) const { |
13813 ASSERT(0 <= value); | 13083 ASSERT(0 <= value); |
13814 ASSERT(value <= Smi::kMaxValue); | 13084 ASSERT(value <= Smi::kMaxValue); |
13815 | 13085 |
13816 const Array& data = Array::Handle(ic_data()); | 13086 const Array& data = Array::Handle(ic_data()); |
13817 const intptr_t data_pos = | 13087 const intptr_t data_pos = |
13818 index * TestEntryLength() + CountIndexFor(NumArgsTested()); | 13088 index * TestEntryLength() + CountIndexFor(NumArgsTested()); |
13819 data.SetAt(data_pos, Smi::Handle(Smi::New(value))); | 13089 data.SetAt(data_pos, Smi::Handle(Smi::New(value))); |
13820 } | 13090 } |
13821 | 13091 |
13822 | |
13823 intptr_t ICData::GetCountAt(intptr_t index) const { | 13092 intptr_t ICData::GetCountAt(intptr_t index) const { |
13824 ASSERT(Isolate::Current()->compilation_allowed()); | 13093 ASSERT(Isolate::Current()->compilation_allowed()); |
13825 const Array& data = Array::Handle(ic_data()); | 13094 const Array& data = Array::Handle(ic_data()); |
13826 const intptr_t data_pos = | 13095 const intptr_t data_pos = |
13827 index * TestEntryLength() + CountIndexFor(NumArgsTested()); | 13096 index * TestEntryLength() + CountIndexFor(NumArgsTested()); |
13828 intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos))); | 13097 intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos))); |
13829 if (value >= 0) return value; | 13098 if (value >= 0) return value; |
13830 | 13099 |
13831 // The counter very rarely overflows to a negative value, but if it does, we | 13100 // The counter very rarely overflows to a negative value, but if it does, we |
13832 // would rather just reset it to zero. | 13101 // would rather just reset it to zero. |
13833 SetCountAt(index, 0); | 13102 SetCountAt(index, 0); |
13834 return 0; | 13103 return 0; |
13835 } | 13104 } |
13836 | 13105 |
13837 | |
13838 intptr_t ICData::AggregateCount() const { | 13106 intptr_t ICData::AggregateCount() const { |
13839 if (IsNull()) return 0; | 13107 if (IsNull()) return 0; |
13840 const intptr_t len = NumberOfChecks(); | 13108 const intptr_t len = NumberOfChecks(); |
13841 intptr_t count = 0; | 13109 intptr_t count = 0; |
13842 for (intptr_t i = 0; i < len; i++) { | 13110 for (intptr_t i = 0; i < len; i++) { |
13843 count += GetCountAt(i); | 13111 count += GetCountAt(i); |
13844 } | 13112 } |
13845 return count; | 13113 return count; |
13846 } | 13114 } |
13847 | 13115 |
13848 | |
13849 void ICData::SetCodeAt(intptr_t index, const Code& value) const { | 13116 void ICData::SetCodeAt(intptr_t index, const Code& value) const { |
13850 ASSERT(!Isolate::Current()->compilation_allowed()); | 13117 ASSERT(!Isolate::Current()->compilation_allowed()); |
13851 const Array& data = Array::Handle(ic_data()); | 13118 const Array& data = Array::Handle(ic_data()); |
13852 const intptr_t data_pos = | 13119 const intptr_t data_pos = |
13853 index * TestEntryLength() + CodeIndexFor(NumArgsTested()); | 13120 index * TestEntryLength() + CodeIndexFor(NumArgsTested()); |
13854 data.SetAt(data_pos, value); | 13121 data.SetAt(data_pos, value); |
13855 } | 13122 } |
13856 | 13123 |
13857 | |
13858 void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const { | 13124 void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const { |
13859 ASSERT(!Isolate::Current()->compilation_allowed()); | 13125 ASSERT(!Isolate::Current()->compilation_allowed()); |
13860 const Array& data = Array::Handle(ic_data()); | 13126 const Array& data = Array::Handle(ic_data()); |
13861 const intptr_t data_pos = | 13127 const intptr_t data_pos = |
13862 index * TestEntryLength() + EntryPointIndexFor(NumArgsTested()); | 13128 index * TestEntryLength() + EntryPointIndexFor(NumArgsTested()); |
13863 data.SetAt(data_pos, value); | 13129 data.SetAt(data_pos, value); |
13864 } | 13130 } |
13865 | 13131 |
13866 | |
13867 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id, | 13132 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id, |
13868 intptr_t* count_return) const { | 13133 intptr_t* count_return) const { |
13869 const intptr_t len = NumberOfChecks(); | 13134 const intptr_t len = NumberOfChecks(); |
13870 for (intptr_t i = 0; i < len; i++) { | 13135 for (intptr_t i = 0; i < len; i++) { |
13871 if (GetReceiverClassIdAt(i) == class_id) { | 13136 if (GetReceiverClassIdAt(i) == class_id) { |
13872 *count_return = GetCountAt(i); | 13137 *count_return = GetCountAt(i); |
13873 return GetTargetAt(i); | 13138 return GetTargetAt(i); |
13874 } | 13139 } |
13875 } | 13140 } |
13876 return Function::null(); | 13141 return Function::null(); |
13877 } | 13142 } |
13878 | 13143 |
13879 | |
13880 RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid, | 13144 RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid, |
13881 const Function& target) const { | 13145 const Function& target) const { |
13882 ASSERT(!IsNull()); | 13146 ASSERT(!IsNull()); |
13883 const intptr_t kNumArgsTested = 1; | 13147 const intptr_t kNumArgsTested = 1; |
13884 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); | 13148 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); |
13885 | 13149 |
13886 // Copy count so that we copy the state "count == 0" vs "count > 0". | 13150 // Copy count so that we copy the state "count == 0" vs "count > 0". |
13887 result.AddReceiverCheck(cid, target, GetCountAt(0)); | 13151 result.AddReceiverCheck(cid, target, GetCountAt(0)); |
13888 return result.raw(); | 13152 return result.raw(); |
13889 } | 13153 } |
13890 | 13154 |
13891 | |
13892 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { | 13155 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { |
13893 ASSERT(!IsNull()); | 13156 ASSERT(!IsNull()); |
13894 ASSERT(NumArgsTested() > arg_nr); | 13157 ASSERT(NumArgsTested() > arg_nr); |
13895 if ((arg_nr == 0) && (NumArgsTested() == 1)) { | 13158 if ((arg_nr == 0) && (NumArgsTested() == 1)) { |
13896 // Frequent case. | 13159 // Frequent case. |
13897 return raw(); | 13160 return raw(); |
13898 } | 13161 } |
13899 const intptr_t kNumArgsTested = 1; | 13162 const intptr_t kNumArgsTested = 1; |
13900 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); | 13163 ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); |
13901 const intptr_t len = NumberOfChecks(); | 13164 const intptr_t len = NumberOfChecks(); |
(...skipping 19 matching lines...) Expand all Loading... |
13921 } else { | 13184 } else { |
13922 // This will make sure that Smi is first if it exists. | 13185 // This will make sure that Smi is first if it exists. |
13923 result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)), | 13186 result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)), |
13924 count); | 13187 count); |
13925 } | 13188 } |
13926 } | 13189 } |
13927 | 13190 |
13928 return result.raw(); | 13191 return result.raw(); |
13929 } | 13192 } |
13930 | 13193 |
13931 | |
13932 // (cid, count) tuple used to sort ICData by count. | 13194 // (cid, count) tuple used to sort ICData by count. |
13933 struct CidCount { | 13195 struct CidCount { |
13934 CidCount(intptr_t cid_, intptr_t count_, Function* f_) | 13196 CidCount(intptr_t cid_, intptr_t count_, Function* f_) |
13935 : cid(cid_), count(count_), function(f_) {} | 13197 : cid(cid_), count(count_), function(f_) {} |
13936 | 13198 |
13937 static int HighestCountFirst(const CidCount* a, const CidCount* b); | 13199 static int HighestCountFirst(const CidCount* a, const CidCount* b); |
13938 | 13200 |
13939 intptr_t cid; | 13201 intptr_t cid; |
13940 intptr_t count; | 13202 intptr_t count; |
13941 Function* function; | 13203 Function* function; |
13942 }; | 13204 }; |
13943 | 13205 |
13944 | |
13945 int CidCount::HighestCountFirst(const CidCount* a, const CidCount* b) { | 13206 int CidCount::HighestCountFirst(const CidCount* a, const CidCount* b) { |
13946 if (a->count > b->count) { | 13207 if (a->count > b->count) { |
13947 return -1; | 13208 return -1; |
13948 } | 13209 } |
13949 return (a->count < b->count) ? 1 : 0; | 13210 return (a->count < b->count) ? 1 : 0; |
13950 } | 13211 } |
13951 | 13212 |
13952 | |
13953 RawICData* ICData::AsUnaryClassChecksSortedByCount() const { | 13213 RawICData* ICData::AsUnaryClassChecksSortedByCount() const { |
13954 ASSERT(!IsNull()); | 13214 ASSERT(!IsNull()); |
13955 const intptr_t kNumArgsTested = 1; | 13215 const intptr_t kNumArgsTested = 1; |
13956 const intptr_t len = NumberOfChecks(); | 13216 const intptr_t len = NumberOfChecks(); |
13957 if (len <= 1) { | 13217 if (len <= 1) { |
13958 // No sorting needed. | 13218 // No sorting needed. |
13959 return AsUnaryClassChecks(); | 13219 return AsUnaryClassChecks(); |
13960 } | 13220 } |
13961 GrowableArray<CidCount> aggregate; | 13221 GrowableArray<CidCount> aggregate; |
13962 for (intptr_t i = 0; i < len; i++) { | 13222 for (intptr_t i = 0; i < len; i++) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13995 Smi::Handle(Smi::New(aggregate[i].count))); | 13255 Smi::Handle(Smi::New(aggregate[i].count))); |
13996 | 13256 |
13997 pos += result.TestEntryLength(); | 13257 pos += result.TestEntryLength(); |
13998 } | 13258 } |
13999 WriteSentinel(data, result.TestEntryLength()); | 13259 WriteSentinel(data, result.TestEntryLength()); |
14000 result.set_ic_data_array(data); | 13260 result.set_ic_data_array(data); |
14001 ASSERT(result.NumberOfChecksIs(aggregate.length())); | 13261 ASSERT(result.NumberOfChecksIs(aggregate.length())); |
14002 return result.raw(); | 13262 return result.raw(); |
14003 } | 13263 } |
14004 | 13264 |
14005 | |
14006 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { | 13265 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { |
14007 if (NumberOfChecksIs(0)) return false; | 13266 if (NumberOfChecksIs(0)) return false; |
14008 Class& cls = Class::Handle(); | 13267 Class& cls = Class::Handle(); |
14009 const intptr_t len = NumberOfChecks(); | 13268 const intptr_t len = NumberOfChecks(); |
14010 for (intptr_t i = 0; i < len; i++) { | 13269 for (intptr_t i = 0; i < len; i++) { |
14011 if (IsUsedAt(i)) { | 13270 if (IsUsedAt(i)) { |
14012 cls = Function::Handle(GetTargetAt(i)).Owner(); | 13271 cls = Function::Handle(GetTargetAt(i)).Owner(); |
14013 if (cls.id() != owner_cid) { | 13272 if (cls.id() != owner_cid) { |
14014 return false; | 13273 return false; |
14015 } | 13274 } |
14016 } | 13275 } |
14017 } | 13276 } |
14018 return true; | 13277 return true; |
14019 } | 13278 } |
14020 | 13279 |
14021 | |
14022 bool ICData::HasReceiverClassId(intptr_t class_id) const { | 13280 bool ICData::HasReceiverClassId(intptr_t class_id) const { |
14023 ASSERT(NumArgsTested() > 0); | 13281 ASSERT(NumArgsTested() > 0); |
14024 const intptr_t len = NumberOfChecks(); | 13282 const intptr_t len = NumberOfChecks(); |
14025 for (intptr_t i = 0; i < len; i++) { | 13283 for (intptr_t i = 0; i < len; i++) { |
14026 if (IsUsedAt(i)) { | 13284 if (IsUsedAt(i)) { |
14027 const intptr_t test_class_id = GetReceiverClassIdAt(i); | 13285 const intptr_t test_class_id = GetReceiverClassIdAt(i); |
14028 if (test_class_id == class_id) { | 13286 if (test_class_id == class_id) { |
14029 return true; | 13287 return true; |
14030 } | 13288 } |
14031 } | 13289 } |
14032 } | 13290 } |
14033 return false; | 13291 return false; |
14034 } | 13292 } |
14035 | 13293 |
14036 | |
14037 // Returns true if all targets are the same. | 13294 // Returns true if all targets are the same. |
14038 // TODO(srdjan): if targets are native use their C_function to compare. | 13295 // TODO(srdjan): if targets are native use their C_function to compare. |
14039 bool ICData::HasOneTarget() const { | 13296 bool ICData::HasOneTarget() const { |
14040 ASSERT(!NumberOfChecksIs(0)); | 13297 ASSERT(!NumberOfChecksIs(0)); |
14041 const Function& first_target = Function::Handle(GetTargetAt(0)); | 13298 const Function& first_target = Function::Handle(GetTargetAt(0)); |
14042 const intptr_t len = NumberOfChecks(); | 13299 const intptr_t len = NumberOfChecks(); |
14043 for (intptr_t i = 1; i < len; i++) { | 13300 for (intptr_t i = 1; i < len; i++) { |
14044 if (IsUsedAt(i) && (GetTargetAt(i) != first_target.raw())) { | 13301 if (IsUsedAt(i) && (GetTargetAt(i) != first_target.raw())) { |
14045 return false; | 13302 return false; |
14046 } | 13303 } |
14047 } | 13304 } |
14048 return true; | 13305 return true; |
14049 } | 13306 } |
14050 | 13307 |
14051 | |
14052 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, | 13308 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, |
14053 GrowableArray<intptr_t>* second) const { | 13309 GrowableArray<intptr_t>* second) const { |
14054 ASSERT(NumArgsTested() == 2); | 13310 ASSERT(NumArgsTested() == 2); |
14055 first->Clear(); | 13311 first->Clear(); |
14056 second->Clear(); | 13312 second->Clear(); |
14057 GrowableArray<intptr_t> class_ids; | 13313 GrowableArray<intptr_t> class_ids; |
14058 const intptr_t len = NumberOfChecks(); | 13314 const intptr_t len = NumberOfChecks(); |
14059 for (intptr_t i = 0; i < len; i++) { | 13315 for (intptr_t i = 0; i < len; i++) { |
14060 if (GetCountAt(i) > 0) { | 13316 if (GetCountAt(i) > 0) { |
14061 GetClassIdsAt(i, &class_ids); | 13317 GetClassIdsAt(i, &class_ids); |
14062 ASSERT(class_ids.length() == 2); | 13318 ASSERT(class_ids.length() == 2); |
14063 first->Add(class_ids[0]); | 13319 first->Add(class_ids[0]); |
14064 second->Add(class_ids[1]); | 13320 second->Add(class_ids[1]); |
14065 } | 13321 } |
14066 } | 13322 } |
14067 } | 13323 } |
14068 | 13324 |
14069 | |
14070 bool ICData::IsUsedAt(intptr_t i) const { | 13325 bool ICData::IsUsedAt(intptr_t i) const { |
14071 if (GetCountAt(i) <= 0) { | 13326 if (GetCountAt(i) <= 0) { |
14072 // Do not mistake unoptimized static call ICData for unused. | 13327 // Do not mistake unoptimized static call ICData for unused. |
14073 // See ICData::AddTarget. | 13328 // See ICData::AddTarget. |
14074 // TODO(srdjan): Make this test more robust. | 13329 // TODO(srdjan): Make this test more robust. |
14075 if (NumArgsTested() > 0) { | 13330 if (NumArgsTested() > 0) { |
14076 const intptr_t cid = GetReceiverClassIdAt(i); | 13331 const intptr_t cid = GetReceiverClassIdAt(i); |
14077 if (cid == kObjectCid) { | 13332 if (cid == kObjectCid) { |
14078 return true; | 13333 return true; |
14079 } | 13334 } |
14080 } | 13335 } |
14081 return false; | 13336 return false; |
14082 } | 13337 } |
14083 return true; | 13338 return true; |
14084 } | 13339 } |
14085 | 13340 |
14086 | |
14087 void ICData::InitOnce() { | 13341 void ICData::InitOnce() { |
14088 for (int i = 0; i < kCachedICDataArrayCount; i++) { | 13342 for (int i = 0; i < kCachedICDataArrayCount; i++) { |
14089 cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); | 13343 cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); |
14090 } | 13344 } |
14091 } | 13345 } |
14092 | 13346 |
14093 | |
14094 RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { | 13347 RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { |
14095 // IC data array must be null terminated (sentinel entry). | 13348 // IC data array must be null terminated (sentinel entry). |
14096 const intptr_t len = TestEntryLengthFor(num_args_tested); | 13349 const intptr_t len = TestEntryLengthFor(num_args_tested); |
14097 const Array& array = Array::Handle(Array::New(len, Heap::kOld)); | 13350 const Array& array = Array::Handle(Array::New(len, Heap::kOld)); |
14098 WriteSentinel(array, len); | 13351 WriteSentinel(array, len); |
14099 array.MakeImmutable(); | 13352 array.MakeImmutable(); |
14100 return array.raw(); | 13353 return array.raw(); |
14101 } | 13354 } |
14102 | 13355 |
14103 | |
14104 RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested) { | 13356 RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested) { |
14105 ASSERT(num_args_tested >= 0); | 13357 ASSERT(num_args_tested >= 0); |
14106 ASSERT(num_args_tested < kCachedICDataArrayCount); | 13358 ASSERT(num_args_tested < kCachedICDataArrayCount); |
14107 return cached_icdata_arrays_[num_args_tested]; | 13359 return cached_icdata_arrays_[num_args_tested]; |
14108 } | 13360 } |
14109 | 13361 |
14110 | |
14111 // Does not initialize ICData array. | 13362 // Does not initialize ICData array. |
14112 RawICData* ICData::NewDescriptor(Zone* zone, | 13363 RawICData* ICData::NewDescriptor(Zone* zone, |
14113 const Function& owner, | 13364 const Function& owner, |
14114 const String& target_name, | 13365 const String& target_name, |
14115 const Array& arguments_descriptor, | 13366 const Array& arguments_descriptor, |
14116 intptr_t deopt_id, | 13367 intptr_t deopt_id, |
14117 intptr_t num_args_tested, | 13368 intptr_t num_args_tested, |
14118 bool is_static_call) { | 13369 bool is_static_call) { |
14119 ASSERT(!owner.IsNull()); | 13370 ASSERT(!owner.IsNull()); |
14120 ASSERT(!target_name.IsNull()); | 13371 ASSERT(!target_name.IsNull()); |
(...skipping 14 matching lines...) Expand all Loading... |
14135 NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id)); | 13386 NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id)); |
14136 result.set_state_bits(0); | 13387 result.set_state_bits(0); |
14137 #if defined(TAG_IC_DATA) | 13388 #if defined(TAG_IC_DATA) |
14138 result.set_tag(-1); | 13389 result.set_tag(-1); |
14139 #endif | 13390 #endif |
14140 result.SetIsStaticCall(is_static_call); | 13391 result.SetIsStaticCall(is_static_call); |
14141 result.SetNumArgsTested(num_args_tested); | 13392 result.SetNumArgsTested(num_args_tested); |
14142 return result.raw(); | 13393 return result.raw(); |
14143 } | 13394 } |
14144 | 13395 |
14145 | |
14146 bool ICData::IsImmutable() const { | 13396 bool ICData::IsImmutable() const { |
14147 const Array& data = Array::Handle(ic_data()); | 13397 const Array& data = Array::Handle(ic_data()); |
14148 return data.IsImmutable(); | 13398 return data.IsImmutable(); |
14149 } | 13399 } |
14150 | 13400 |
14151 | |
14152 RawICData* ICData::New() { | 13401 RawICData* ICData::New() { |
14153 ICData& result = ICData::Handle(); | 13402 ICData& result = ICData::Handle(); |
14154 { | 13403 { |
14155 // IC data objects are long living objects, allocate them in old generation. | 13404 // IC data objects are long living objects, allocate them in old generation. |
14156 RawObject* raw = | 13405 RawObject* raw = |
14157 Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld); | 13406 Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld); |
14158 NoSafepointScope no_safepoint; | 13407 NoSafepointScope no_safepoint; |
14159 result ^= raw; | 13408 result ^= raw; |
14160 } | 13409 } |
14161 result.set_deopt_id(Thread::kNoDeoptId); | 13410 result.set_deopt_id(Thread::kNoDeoptId); |
14162 result.set_state_bits(0); | 13411 result.set_state_bits(0); |
14163 #if defined(TAG_IC_DATA) | 13412 #if defined(TAG_IC_DATA) |
14164 result.set_tag(-1); | 13413 result.set_tag(-1); |
14165 #endif | 13414 #endif |
14166 return result.raw(); | 13415 return result.raw(); |
14167 } | 13416 } |
14168 | 13417 |
14169 | |
14170 RawICData* ICData::New(const Function& owner, | 13418 RawICData* ICData::New(const Function& owner, |
14171 const String& target_name, | 13419 const String& target_name, |
14172 const Array& arguments_descriptor, | 13420 const Array& arguments_descriptor, |
14173 intptr_t deopt_id, | 13421 intptr_t deopt_id, |
14174 intptr_t num_args_tested, | 13422 intptr_t num_args_tested, |
14175 bool is_static_call) { | 13423 bool is_static_call) { |
14176 Zone* zone = Thread::Current()->zone(); | 13424 Zone* zone = Thread::Current()->zone(); |
14177 const ICData& result = ICData::Handle( | 13425 const ICData& result = ICData::Handle( |
14178 zone, NewDescriptor(zone, owner, target_name, arguments_descriptor, | 13426 zone, NewDescriptor(zone, owner, target_name, arguments_descriptor, |
14179 deopt_id, num_args_tested, is_static_call)); | 13427 deopt_id, num_args_tested, is_static_call)); |
14180 result.set_ic_data_array( | 13428 result.set_ic_data_array( |
14181 Array::Handle(zone, CachedEmptyICDataArray(num_args_tested))); | 13429 Array::Handle(zone, CachedEmptyICDataArray(num_args_tested))); |
14182 return result.raw(); | 13430 return result.raw(); |
14183 } | 13431 } |
14184 | 13432 |
14185 | |
14186 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { | 13433 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { |
14187 const ICData& result = ICData::Handle(ICData::New( | 13434 const ICData& result = ICData::Handle(ICData::New( |
14188 Function::Handle(from.Owner()), String::Handle(from.target_name()), | 13435 Function::Handle(from.Owner()), String::Handle(from.target_name()), |
14189 Array::Handle(from.arguments_descriptor()), from.deopt_id(), | 13436 Array::Handle(from.arguments_descriptor()), from.deopt_id(), |
14190 num_args_tested, from.is_static_call())); | 13437 num_args_tested, from.is_static_call())); |
14191 // Copy deoptimization reasons. | 13438 // Copy deoptimization reasons. |
14192 result.SetDeoptReasons(from.DeoptReasons()); | 13439 result.SetDeoptReasons(from.DeoptReasons()); |
14193 return result.raw(); | 13440 return result.raw(); |
14194 } | 13441 } |
14195 | 13442 |
14196 | |
14197 RawICData* ICData::Clone(const ICData& from) { | 13443 RawICData* ICData::Clone(const ICData& from) { |
14198 Zone* zone = Thread::Current()->zone(); | 13444 Zone* zone = Thread::Current()->zone(); |
14199 const ICData& result = ICData::Handle(ICData::NewDescriptor( | 13445 const ICData& result = ICData::Handle(ICData::NewDescriptor( |
14200 zone, Function::Handle(zone, from.Owner()), | 13446 zone, Function::Handle(zone, from.Owner()), |
14201 String::Handle(zone, from.target_name()), | 13447 String::Handle(zone, from.target_name()), |
14202 Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(), | 13448 Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(), |
14203 from.NumArgsTested(), from.is_static_call())); | 13449 from.NumArgsTested(), from.is_static_call())); |
14204 // Clone entry array. | 13450 // Clone entry array. |
14205 const Array& from_array = Array::Handle(zone, from.ic_data()); | 13451 const Array& from_array = Array::Handle(zone, from.ic_data()); |
14206 const intptr_t len = from_array.Length(); | 13452 const intptr_t len = from_array.Length(); |
14207 const Array& cloned_array = Array::Handle(zone, Array::New(len, Heap::kOld)); | 13453 const Array& cloned_array = Array::Handle(zone, Array::New(len, Heap::kOld)); |
14208 Object& obj = Object::Handle(zone); | 13454 Object& obj = Object::Handle(zone); |
14209 for (intptr_t i = 0; i < len; i++) { | 13455 for (intptr_t i = 0; i < len; i++) { |
14210 obj = from_array.At(i); | 13456 obj = from_array.At(i); |
14211 cloned_array.SetAt(i, obj); | 13457 cloned_array.SetAt(i, obj); |
14212 } | 13458 } |
14213 result.set_ic_data_array(cloned_array); | 13459 result.set_ic_data_array(cloned_array); |
14214 // Copy deoptimization reasons. | 13460 // Copy deoptimization reasons. |
14215 result.SetDeoptReasons(from.DeoptReasons()); | 13461 result.SetDeoptReasons(from.DeoptReasons()); |
14216 return result.raw(); | 13462 return result.raw(); |
14217 } | 13463 } |
14218 | 13464 |
14219 | |
14220 Code::Comments& Code::Comments::New(intptr_t count) { | 13465 Code::Comments& Code::Comments::New(intptr_t count) { |
14221 Comments* comments; | 13466 Comments* comments; |
14222 if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { | 13467 if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { |
14223 // This should be caught before we reach here. | 13468 // This should be caught before we reach here. |
14224 FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", | 13469 FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", |
14225 count); | 13470 count); |
14226 } | 13471 } |
14227 if (count == 0) { | 13472 if (count == 0) { |
14228 comments = new Comments(Object::empty_array()); | 13473 comments = new Comments(Object::empty_array()); |
14229 } else { | 13474 } else { |
14230 const Array& data = | 13475 const Array& data = |
14231 Array::Handle(Array::New(count * kNumberOfEntries, Heap::kOld)); | 13476 Array::Handle(Array::New(count * kNumberOfEntries, Heap::kOld)); |
14232 comments = new Comments(data); | 13477 comments = new Comments(data); |
14233 } | 13478 } |
14234 return *comments; | 13479 return *comments; |
14235 } | 13480 } |
14236 | 13481 |
14237 | |
14238 intptr_t Code::Comments::Length() const { | 13482 intptr_t Code::Comments::Length() const { |
14239 if (comments_.IsNull()) { | 13483 if (comments_.IsNull()) { |
14240 return 0; | 13484 return 0; |
14241 } | 13485 } |
14242 return comments_.Length() / kNumberOfEntries; | 13486 return comments_.Length() / kNumberOfEntries; |
14243 } | 13487 } |
14244 | 13488 |
14245 | |
14246 intptr_t Code::Comments::PCOffsetAt(intptr_t idx) const { | 13489 intptr_t Code::Comments::PCOffsetAt(intptr_t idx) const { |
14247 return Smi::Value( | 13490 return Smi::Value( |
14248 Smi::RawCast(comments_.At(idx * kNumberOfEntries + kPCOffsetEntry))); | 13491 Smi::RawCast(comments_.At(idx * kNumberOfEntries + kPCOffsetEntry))); |
14249 } | 13492 } |
14250 | 13493 |
14251 | |
14252 void Code::Comments::SetPCOffsetAt(intptr_t idx, intptr_t pc) { | 13494 void Code::Comments::SetPCOffsetAt(intptr_t idx, intptr_t pc) { |
14253 comments_.SetAt(idx * kNumberOfEntries + kPCOffsetEntry, | 13495 comments_.SetAt(idx * kNumberOfEntries + kPCOffsetEntry, |
14254 Smi::Handle(Smi::New(pc))); | 13496 Smi::Handle(Smi::New(pc))); |
14255 } | 13497 } |
14256 | 13498 |
14257 | |
14258 RawString* Code::Comments::CommentAt(intptr_t idx) const { | 13499 RawString* Code::Comments::CommentAt(intptr_t idx) const { |
14259 return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry)); | 13500 return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry)); |
14260 } | 13501 } |
14261 | 13502 |
14262 | |
14263 void Code::Comments::SetCommentAt(intptr_t idx, const String& comment) { | 13503 void Code::Comments::SetCommentAt(intptr_t idx, const String& comment) { |
14264 comments_.SetAt(idx * kNumberOfEntries + kCommentEntry, comment); | 13504 comments_.SetAt(idx * kNumberOfEntries + kCommentEntry, comment); |
14265 } | 13505 } |
14266 | 13506 |
14267 | |
14268 Code::Comments::Comments(const Array& comments) : comments_(comments) {} | 13507 Code::Comments::Comments(const Array& comments) : comments_(comments) {} |
14269 | 13508 |
14270 | |
14271 RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const { | 13509 RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const { |
14272 const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors()); | 13510 const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors()); |
14273 if (v.IsNull()) { | 13511 if (v.IsNull()) { |
14274 ASSERT(!is_optimized()); | 13512 ASSERT(!is_optimized()); |
14275 const Function& f = Function::Handle(function()); | 13513 const Function& f = Function::Handle(function()); |
14276 ASSERT(!f.IsIrregexpFunction()); // Not yet implemented. | 13514 ASSERT(!f.IsIrregexpFunction()); // Not yet implemented. |
14277 Compiler::ComputeLocalVarDescriptors(*this); | 13515 Compiler::ComputeLocalVarDescriptors(*this); |
14278 } | 13516 } |
14279 return var_descriptors(); | 13517 return var_descriptors(); |
14280 } | 13518 } |
14281 | 13519 |
14282 | |
14283 void Code::set_state_bits(intptr_t bits) const { | 13520 void Code::set_state_bits(intptr_t bits) const { |
14284 StoreNonPointer(&raw_ptr()->state_bits_, bits); | 13521 StoreNonPointer(&raw_ptr()->state_bits_, bits); |
14285 } | 13522 } |
14286 | 13523 |
14287 | |
14288 void Code::set_is_optimized(bool value) const { | 13524 void Code::set_is_optimized(bool value) const { |
14289 set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_)); | 13525 set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_)); |
14290 } | 13526 } |
14291 | 13527 |
14292 | |
14293 void Code::set_is_alive(bool value) const { | 13528 void Code::set_is_alive(bool value) const { |
14294 set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); | 13529 set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); |
14295 } | 13530 } |
14296 | 13531 |
14297 | |
14298 void Code::set_stackmaps(const Array& maps) const { | 13532 void Code::set_stackmaps(const Array& maps) const { |
14299 ASSERT(maps.IsOld()); | 13533 ASSERT(maps.IsOld()); |
14300 StorePointer(&raw_ptr()->stackmaps_, maps.raw()); | 13534 StorePointer(&raw_ptr()->stackmaps_, maps.raw()); |
14301 INC_STAT(Thread::Current(), total_code_size, | 13535 INC_STAT(Thread::Current(), total_code_size, |
14302 maps.IsNull() ? 0 : maps.Length() * sizeof(uword)); | 13536 maps.IsNull() ? 0 : maps.Length() * sizeof(uword)); |
14303 } | 13537 } |
14304 | 13538 |
14305 | |
14306 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) | 13539 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) |
14307 void Code::set_variables(const Smi& smi) const { | 13540 void Code::set_variables(const Smi& smi) const { |
14308 StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw()); | 13541 StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw()); |
14309 } | 13542 } |
14310 #else | 13543 #else |
14311 void Code::set_catch_entry_state_maps(const TypedData& maps) const { | 13544 void Code::set_catch_entry_state_maps(const TypedData& maps) const { |
14312 StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw()); | 13545 StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw()); |
14313 } | 13546 } |
14314 #endif | 13547 #endif |
14315 | 13548 |
14316 | |
14317 void Code::set_deopt_info_array(const Array& array) const { | 13549 void Code::set_deopt_info_array(const Array& array) const { |
14318 #if defined(DART_PRECOMPILED_RUNTIME) | 13550 #if defined(DART_PRECOMPILED_RUNTIME) |
14319 UNREACHABLE(); | 13551 UNREACHABLE(); |
14320 #else | 13552 #else |
14321 ASSERT(array.IsOld()); | 13553 ASSERT(array.IsOld()); |
14322 StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); | 13554 StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); |
14323 #endif | 13555 #endif |
14324 } | 13556 } |
14325 | 13557 |
14326 | |
14327 void Code::set_static_calls_target_table(const Array& value) const { | 13558 void Code::set_static_calls_target_table(const Array& value) const { |
14328 #if defined(DART_PRECOMPILED_RUNTIME) | 13559 #if defined(DART_PRECOMPILED_RUNTIME) |
14329 UNREACHABLE(); | 13560 UNREACHABLE(); |
14330 #else | 13561 #else |
14331 StorePointer(&raw_ptr()->static_calls_target_table_, value.raw()); | 13562 StorePointer(&raw_ptr()->static_calls_target_table_, value.raw()); |
14332 #endif | 13563 #endif |
14333 #if defined(DEBUG) | 13564 #if defined(DEBUG) |
14334 // Check that the table is sorted by pc offsets. | 13565 // Check that the table is sorted by pc offsets. |
14335 // FlowGraphCompiler::AddStaticCallTarget adds pc-offsets to the table while | 13566 // FlowGraphCompiler::AddStaticCallTarget adds pc-offsets to the table while |
14336 // emitting assembly. This guarantees that every succeeding pc-offset is | 13567 // emitting assembly. This guarantees that every succeeding pc-offset is |
14337 // larger than the previously added one. | 13568 // larger than the previously added one. |
14338 for (intptr_t i = kSCallTableEntryLength; i < value.Length(); | 13569 for (intptr_t i = kSCallTableEntryLength; i < value.Length(); |
14339 i += kSCallTableEntryLength) { | 13570 i += kSCallTableEntryLength) { |
14340 ASSERT(value.At(i - kSCallTableEntryLength) < value.At(i)); | 13571 ASSERT(value.At(i - kSCallTableEntryLength) < value.At(i)); |
14341 } | 13572 } |
14342 #endif // DEBUG | 13573 #endif // DEBUG |
14343 } | 13574 } |
14344 | 13575 |
14345 | |
14346 bool Code::HasBreakpoint() const { | 13576 bool Code::HasBreakpoint() const { |
14347 if (!FLAG_support_debugger) { | 13577 if (!FLAG_support_debugger) { |
14348 return false; | 13578 return false; |
14349 } | 13579 } |
14350 return Isolate::Current()->debugger()->HasBreakpoint(*this); | 13580 return Isolate::Current()->debugger()->HasBreakpoint(*this); |
14351 } | 13581 } |
14352 | 13582 |
14353 | |
14354 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, | 13583 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, |
14355 ICData::DeoptReasonId* deopt_reason, | 13584 ICData::DeoptReasonId* deopt_reason, |
14356 uint32_t* deopt_flags) const { | 13585 uint32_t* deopt_flags) const { |
14357 #if defined(DART_PRECOMPILED_RUNTIME) | 13586 #if defined(DART_PRECOMPILED_RUNTIME) |
14358 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 13587 ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |
14359 return TypedData::null(); | 13588 return TypedData::null(); |
14360 #else | 13589 #else |
14361 ASSERT(is_optimized()); | 13590 ASSERT(is_optimized()); |
14362 const Instructions& instrs = Instructions::Handle(instructions()); | 13591 const Instructions& instrs = Instructions::Handle(instructions()); |
14363 uword code_entry = instrs.PayloadStart(); | 13592 uword code_entry = instrs.PayloadStart(); |
(...skipping 14 matching lines...) Expand all Loading... |
14378 *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 13607 *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
14379 *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); | 13608 *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); |
14380 return info.raw(); | 13609 return info.raw(); |
14381 } | 13610 } |
14382 } | 13611 } |
14383 *deopt_reason = ICData::kDeoptUnknown; | 13612 *deopt_reason = ICData::kDeoptUnknown; |
14384 return TypedData::null(); | 13613 return TypedData::null(); |
14385 #endif // defined(DART_PRECOMPILED_RUNTIME) | 13614 #endif // defined(DART_PRECOMPILED_RUNTIME) |
14386 } | 13615 } |
14387 | 13616 |
14388 | |
14389 intptr_t Code::BinarySearchInSCallTable(uword pc) const { | 13617 intptr_t Code::BinarySearchInSCallTable(uword pc) const { |
14390 #if defined(DART_PRECOMPILED_RUNTIME) | 13618 #if defined(DART_PRECOMPILED_RUNTIME) |
14391 UNREACHABLE(); | 13619 UNREACHABLE(); |
14392 #else | 13620 #else |
14393 NoSafepointScope no_safepoint; | 13621 NoSafepointScope no_safepoint; |
14394 const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); | 13622 const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); |
14395 RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart())); | 13623 RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart())); |
14396 intptr_t imin = 0; | 13624 intptr_t imin = 0; |
14397 intptr_t imax = table.Length() / kSCallTableEntryLength; | 13625 intptr_t imax = table.Length() / kSCallTableEntryLength; |
14398 while (imax >= imin) { | 13626 while (imax >= imin) { |
14399 const intptr_t imid = ((imax - imin) / 2) + imin; | 13627 const intptr_t imid = ((imax - imin) / 2) + imin; |
14400 const intptr_t real_index = imid * kSCallTableEntryLength; | 13628 const intptr_t real_index = imid * kSCallTableEntryLength; |
14401 RawObject* key_in_table = table.At(real_index); | 13629 RawObject* key_in_table = table.At(real_index); |
14402 if (key_in_table < key) { | 13630 if (key_in_table < key) { |
14403 imin = imid + 1; | 13631 imin = imid + 1; |
14404 } else if (key_in_table > key) { | 13632 } else if (key_in_table > key) { |
14405 imax = imid - 1; | 13633 imax = imid - 1; |
14406 } else { | 13634 } else { |
14407 return real_index; | 13635 return real_index; |
14408 } | 13636 } |
14409 } | 13637 } |
14410 #endif | 13638 #endif |
14411 return -1; | 13639 return -1; |
14412 } | 13640 } |
14413 | 13641 |
14414 | |
14415 RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const { | 13642 RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const { |
14416 #if defined(DART_PRECOMPILED_RUNTIME) | 13643 #if defined(DART_PRECOMPILED_RUNTIME) |
14417 UNREACHABLE(); | 13644 UNREACHABLE(); |
14418 return Function::null(); | 13645 return Function::null(); |
14419 #else | 13646 #else |
14420 const intptr_t i = BinarySearchInSCallTable(pc); | 13647 const intptr_t i = BinarySearchInSCallTable(pc); |
14421 if (i < 0) { | 13648 if (i < 0) { |
14422 return Function::null(); | 13649 return Function::null(); |
14423 } | 13650 } |
14424 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 13651 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |
14425 Function& function = Function::Handle(); | 13652 Function& function = Function::Handle(); |
14426 function ^= array.At(i + kSCallTableFunctionEntry); | 13653 function ^= array.At(i + kSCallTableFunctionEntry); |
14427 return function.raw(); | 13654 return function.raw(); |
14428 #endif | 13655 #endif |
14429 } | 13656 } |
14430 | 13657 |
14431 | |
14432 RawCode* Code::GetStaticCallTargetCodeAt(uword pc) const { | 13658 RawCode* Code::GetStaticCallTargetCodeAt(uword pc) const { |
14433 #if defined(DART_PRECOMPILED_RUNTIME) | 13659 #if defined(DART_PRECOMPILED_RUNTIME) |
14434 UNREACHABLE(); | 13660 UNREACHABLE(); |
14435 return Code::null(); | 13661 return Code::null(); |
14436 #else | 13662 #else |
14437 const intptr_t i = BinarySearchInSCallTable(pc); | 13663 const intptr_t i = BinarySearchInSCallTable(pc); |
14438 if (i < 0) { | 13664 if (i < 0) { |
14439 return Code::null(); | 13665 return Code::null(); |
14440 } | 13666 } |
14441 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 13667 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |
14442 Code& code = Code::Handle(); | 13668 Code& code = Code::Handle(); |
14443 code ^= array.At(i + kSCallTableCodeEntry); | 13669 code ^= array.At(i + kSCallTableCodeEntry); |
14444 return code.raw(); | 13670 return code.raw(); |
14445 #endif | 13671 #endif |
14446 } | 13672 } |
14447 | 13673 |
14448 | |
14449 void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const { | 13674 void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const { |
14450 #if defined(DART_PRECOMPILED_RUNTIME) | 13675 #if defined(DART_PRECOMPILED_RUNTIME) |
14451 UNREACHABLE(); | 13676 UNREACHABLE(); |
14452 #else | 13677 #else |
14453 const intptr_t i = BinarySearchInSCallTable(pc); | 13678 const intptr_t i = BinarySearchInSCallTable(pc); |
14454 ASSERT(i >= 0); | 13679 ASSERT(i >= 0); |
14455 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 13680 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |
14456 ASSERT(code.IsNull() || | 13681 ASSERT(code.IsNull() || |
14457 (code.function() == array.At(i + kSCallTableFunctionEntry))); | 13682 (code.function() == array.At(i + kSCallTableFunctionEntry))); |
14458 array.SetAt(i + kSCallTableCodeEntry, code); | 13683 array.SetAt(i + kSCallTableCodeEntry, code); |
14459 #endif | 13684 #endif |
14460 } | 13685 } |
14461 | 13686 |
14462 | |
14463 void Code::SetStubCallTargetCodeAt(uword pc, const Code& code) const { | 13687 void Code::SetStubCallTargetCodeAt(uword pc, const Code& code) const { |
14464 #if defined(DART_PRECOMPILED_RUNTIME) | 13688 #if defined(DART_PRECOMPILED_RUNTIME) |
14465 UNREACHABLE(); | 13689 UNREACHABLE(); |
14466 #else | 13690 #else |
14467 const intptr_t i = BinarySearchInSCallTable(pc); | 13691 const intptr_t i = BinarySearchInSCallTable(pc); |
14468 ASSERT(i >= 0); | 13692 ASSERT(i >= 0); |
14469 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 13693 const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |
14470 #if defined(DEBUG) | 13694 #if defined(DEBUG) |
14471 if (array.At(i + kSCallTableFunctionEntry) == Function::null()) { | 13695 if (array.At(i + kSCallTableFunctionEntry) == Function::null()) { |
14472 ASSERT(!code.IsNull() && Object::Handle(code.owner()).IsClass()); | 13696 ASSERT(!code.IsNull() && Object::Handle(code.owner()).IsClass()); |
14473 } else { | 13697 } else { |
14474 ASSERT(code.IsNull() || | 13698 ASSERT(code.IsNull() || |
14475 (code.function() == array.At(i + kSCallTableFunctionEntry))); | 13699 (code.function() == array.At(i + kSCallTableFunctionEntry))); |
14476 } | 13700 } |
14477 #endif | 13701 #endif |
14478 array.SetAt(i + kSCallTableCodeEntry, code); | 13702 array.SetAt(i + kSCallTableCodeEntry, code); |
14479 #endif | 13703 #endif |
14480 } | 13704 } |
14481 | 13705 |
14482 | |
14483 void Code::Disassemble(DisassemblyFormatter* formatter) const { | 13706 void Code::Disassemble(DisassemblyFormatter* formatter) const { |
14484 #ifndef PRODUCT | 13707 #ifndef PRODUCT |
14485 if (!FLAG_support_disassembler) { | 13708 if (!FLAG_support_disassembler) { |
14486 return; | 13709 return; |
14487 } | 13710 } |
14488 const Instructions& instr = Instructions::Handle(instructions()); | 13711 const Instructions& instr = Instructions::Handle(instructions()); |
14489 uword start = instr.PayloadStart(); | 13712 uword start = instr.PayloadStart(); |
14490 if (formatter == NULL) { | 13713 if (formatter == NULL) { |
14491 Disassembler::Disassemble(start, start + instr.Size(), *this); | 13714 Disassembler::Disassemble(start, start + instr.Size(), *this); |
14492 } else { | 13715 } else { |
14493 Disassembler::Disassemble(start, start + instr.Size(), formatter, *this); | 13716 Disassembler::Disassemble(start, start + instr.Size(), formatter, *this); |
14494 } | 13717 } |
14495 #endif | 13718 #endif |
14496 } | 13719 } |
14497 | 13720 |
14498 | |
14499 const Code::Comments& Code::comments() const { | 13721 const Code::Comments& Code::comments() const { |
14500 #if defined(DART_PRECOMPILED_RUNTIME) | 13722 #if defined(DART_PRECOMPILED_RUNTIME) |
14501 Comments* comments = new Code::Comments(Array::Handle()); | 13723 Comments* comments = new Code::Comments(Array::Handle()); |
14502 #else | 13724 #else |
14503 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); | 13725 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); |
14504 #endif | 13726 #endif |
14505 return *comments; | 13727 return *comments; |
14506 } | 13728 } |
14507 | 13729 |
14508 | |
14509 void Code::set_comments(const Code::Comments& comments) const { | 13730 void Code::set_comments(const Code::Comments& comments) const { |
14510 #if defined(DART_PRECOMPILED_RUNTIME) | 13731 #if defined(DART_PRECOMPILED_RUNTIME) |
14511 UNREACHABLE(); | 13732 UNREACHABLE(); |
14512 #else | 13733 #else |
14513 ASSERT(comments.comments_.IsOld()); | 13734 ASSERT(comments.comments_.IsOld()); |
14514 StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); | 13735 StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); |
14515 #endif | 13736 #endif |
14516 } | 13737 } |
14517 | 13738 |
14518 | |
14519 void Code::SetPrologueOffset(intptr_t offset) const { | 13739 void Code::SetPrologueOffset(intptr_t offset) const { |
14520 #if defined(DART_PRECOMPILED_RUNTIME) | 13740 #if defined(DART_PRECOMPILED_RUNTIME) |
14521 UNREACHABLE(); | 13741 UNREACHABLE(); |
14522 #else | 13742 #else |
14523 ASSERT(offset >= 0); | 13743 ASSERT(offset >= 0); |
14524 StoreSmi( | 13744 StoreSmi( |
14525 reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_), | 13745 reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_), |
14526 Smi::New(offset)); | 13746 Smi::New(offset)); |
14527 #endif | 13747 #endif |
14528 } | 13748 } |
14529 | 13749 |
14530 | |
14531 intptr_t Code::GetPrologueOffset() const { | 13750 intptr_t Code::GetPrologueOffset() const { |
14532 #if defined(DART_PRECOMPILED_RUNTIME) | 13751 #if defined(DART_PRECOMPILED_RUNTIME) |
14533 return -1; | 13752 return -1; |
14534 #else | 13753 #else |
14535 const Object& object = Object::Handle(raw_ptr()->return_address_metadata_); | 13754 const Object& object = Object::Handle(raw_ptr()->return_address_metadata_); |
14536 // In the future we may put something other than a smi in | 13755 // In the future we may put something other than a smi in |
14537 // |return_address_metadata_|. | 13756 // |return_address_metadata_|. |
14538 if (object.IsNull() || !object.IsSmi()) { | 13757 if (object.IsNull() || !object.IsSmi()) { |
14539 return -1; | 13758 return -1; |
14540 } | 13759 } |
14541 return Smi::Cast(object).Value(); | 13760 return Smi::Cast(object).Value(); |
14542 #endif | 13761 #endif |
14543 } | 13762 } |
14544 | 13763 |
14545 | |
14546 RawArray* Code::inlined_id_to_function() const { | 13764 RawArray* Code::inlined_id_to_function() const { |
14547 return raw_ptr()->inlined_id_to_function_; | 13765 return raw_ptr()->inlined_id_to_function_; |
14548 } | 13766 } |
14549 | 13767 |
14550 | |
14551 void Code::set_inlined_id_to_function(const Array& value) const { | 13768 void Code::set_inlined_id_to_function(const Array& value) const { |
14552 ASSERT(value.IsOld()); | 13769 ASSERT(value.IsOld()); |
14553 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); | 13770 StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); |
14554 } | 13771 } |
14555 | 13772 |
14556 | |
14557 RawCode* Code::New(intptr_t pointer_offsets_length) { | 13773 RawCode* Code::New(intptr_t pointer_offsets_length) { |
14558 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { | 13774 if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { |
14559 // This should be caught before we reach here. | 13775 // This should be caught before we reach here. |
14560 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", | 13776 FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", |
14561 pointer_offsets_length); | 13777 pointer_offsets_length); |
14562 } | 13778 } |
14563 ASSERT(Object::code_class() != Class::null()); | 13779 ASSERT(Object::code_class() != Class::null()); |
14564 Code& result = Code::Handle(); | 13780 Code& result = Code::Handle(); |
14565 { | 13781 { |
14566 uword size = Code::InstanceSize(pointer_offsets_length); | 13782 uword size = Code::InstanceSize(pointer_offsets_length); |
14567 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); | 13783 RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); |
14568 NoSafepointScope no_safepoint; | 13784 NoSafepointScope no_safepoint; |
14569 result ^= raw; | 13785 result ^= raw; |
14570 result.set_pointer_offsets_length(pointer_offsets_length); | 13786 result.set_pointer_offsets_length(pointer_offsets_length); |
14571 result.set_is_optimized(false); | 13787 result.set_is_optimized(false); |
14572 result.set_is_alive(false); | 13788 result.set_is_alive(false); |
14573 result.set_comments(Comments::New(0)); | 13789 result.set_comments(Comments::New(0)); |
14574 result.set_compile_timestamp(0); | 13790 result.set_compile_timestamp(0); |
14575 result.set_pc_descriptors(Object::empty_descriptors()); | 13791 result.set_pc_descriptors(Object::empty_descriptors()); |
14576 } | 13792 } |
14577 return result.raw(); | 13793 return result.raw(); |
14578 } | 13794 } |
14579 | 13795 |
14580 | |
14581 RawCode* Code::FinalizeCode(const char* name, | 13796 RawCode* Code::FinalizeCode(const char* name, |
14582 Assembler* assembler, | 13797 Assembler* assembler, |
14583 bool optimized) { | 13798 bool optimized) { |
14584 Isolate* isolate = Isolate::Current(); | 13799 Isolate* isolate = Isolate::Current(); |
14585 if (!isolate->compilation_allowed()) { | 13800 if (!isolate->compilation_allowed()) { |
14586 FATAL1("Precompilation missed code %s\n", name); | 13801 FATAL1("Precompilation missed code %s\n", name); |
14587 } | 13802 } |
14588 | 13803 |
14589 ASSERT(assembler != NULL); | 13804 ASSERT(assembler != NULL); |
14590 const ObjectPool& object_pool = | 13805 const ObjectPool& object_pool = |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14658 } else { | 13873 } else { |
14659 // No prologue was ever entered, optimistically assume nothing was ever | 13874 // No prologue was ever entered, optimistically assume nothing was ever |
14660 // pushed onto the stack. | 13875 // pushed onto the stack. |
14661 code.SetPrologueOffset(assembler->CodeSize()); | 13876 code.SetPrologueOffset(assembler->CodeSize()); |
14662 } | 13877 } |
14663 INC_STAT(Thread::Current(), total_code_size, | 13878 INC_STAT(Thread::Current(), total_code_size, |
14664 code.comments().comments_.Length()); | 13879 code.comments().comments_.Length()); |
14665 return code.raw(); | 13880 return code.raw(); |
14666 } | 13881 } |
14667 | 13882 |
14668 | |
14669 RawCode* Code::FinalizeCode(const Function& function, | 13883 RawCode* Code::FinalizeCode(const Function& function, |
14670 Assembler* assembler, | 13884 Assembler* assembler, |
14671 bool optimized) { | 13885 bool optimized) { |
14672 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 13886 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |
14673 // try to avoid it. | 13887 // try to avoid it. |
14674 #ifndef PRODUCT | 13888 #ifndef PRODUCT |
14675 if (CodeObservers::AreActive()) { | 13889 if (CodeObservers::AreActive()) { |
14676 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), assembler, | 13890 return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), assembler, |
14677 optimized); | 13891 optimized); |
14678 } | 13892 } |
14679 #endif // !PRODUCT | 13893 #endif // !PRODUCT |
14680 return FinalizeCode("", assembler, optimized); | 13894 return FinalizeCode("", assembler, optimized); |
14681 } | 13895 } |
14682 | 13896 |
14683 | |
14684 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { | 13897 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { |
14685 return RawCode::ContainsPC(raw_obj, pc_); | 13898 return RawCode::ContainsPC(raw_obj, pc_); |
14686 } | 13899 } |
14687 | 13900 |
14688 | |
14689 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { | 13901 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { |
14690 ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate())); | 13902 ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate())); |
14691 if (isolate->heap() == NULL) { | 13903 if (isolate->heap() == NULL) { |
14692 return Code::null(); | 13904 return Code::null(); |
14693 } | 13905 } |
14694 NoSafepointScope no_safepoint; | 13906 NoSafepointScope no_safepoint; |
14695 SlowFindRawCodeVisitor visitor(pc); | 13907 SlowFindRawCodeVisitor visitor(pc); |
14696 RawObject* needle = isolate->heap()->FindOldObject(&visitor); | 13908 RawObject* needle = isolate->heap()->FindOldObject(&visitor); |
14697 if (needle != Code::null()) { | 13909 if (needle != Code::null()) { |
14698 return static_cast<RawCode*>(needle); | 13910 return static_cast<RawCode*>(needle); |
14699 } | 13911 } |
14700 return Code::null(); | 13912 return Code::null(); |
14701 } | 13913 } |
14702 | 13914 |
14703 | |
14704 RawCode* Code::LookupCode(uword pc) { | 13915 RawCode* Code::LookupCode(uword pc) { |
14705 return LookupCodeInIsolate(Isolate::Current(), pc); | 13916 return LookupCodeInIsolate(Isolate::Current(), pc); |
14706 } | 13917 } |
14707 | 13918 |
14708 | |
14709 RawCode* Code::LookupCodeInVmIsolate(uword pc) { | 13919 RawCode* Code::LookupCodeInVmIsolate(uword pc) { |
14710 return LookupCodeInIsolate(Dart::vm_isolate(), pc); | 13920 return LookupCodeInIsolate(Dart::vm_isolate(), pc); |
14711 } | 13921 } |
14712 | 13922 |
14713 | |
14714 // Given a pc and a timestamp, lookup the code. | 13923 // Given a pc and a timestamp, lookup the code. |
14715 RawCode* Code::FindCode(uword pc, int64_t timestamp) { | 13924 RawCode* Code::FindCode(uword pc, int64_t timestamp) { |
14716 Code& code = Code::Handle(Code::LookupCode(pc)); | 13925 Code& code = Code::Handle(Code::LookupCode(pc)); |
14717 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 13926 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |
14718 (code.PayloadStart() == pc)) { | 13927 (code.PayloadStart() == pc)) { |
14719 // Found code in isolate. | 13928 // Found code in isolate. |
14720 return code.raw(); | 13929 return code.raw(); |
14721 } | 13930 } |
14722 code ^= Code::LookupCodeInVmIsolate(pc); | 13931 code ^= Code::LookupCodeInVmIsolate(pc); |
14723 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 13932 if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |
14724 (code.PayloadStart() == pc)) { | 13933 (code.PayloadStart() == pc)) { |
14725 // Found code in VM isolate. | 13934 // Found code in VM isolate. |
14726 return code.raw(); | 13935 return code.raw(); |
14727 } | 13936 } |
14728 return Code::null(); | 13937 return Code::null(); |
14729 } | 13938 } |
14730 | 13939 |
14731 | |
14732 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { | 13940 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { |
14733 uword pc_offset = pc - PayloadStart(); | 13941 uword pc_offset = pc - PayloadStart(); |
14734 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 13942 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
14735 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 13943 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |
14736 while (iter.MoveNext()) { | 13944 while (iter.MoveNext()) { |
14737 if (iter.PcOffset() == pc_offset) { | 13945 if (iter.PcOffset() == pc_offset) { |
14738 return iter.TokenPos(); | 13946 return iter.TokenPos(); |
14739 } | 13947 } |
14740 } | 13948 } |
14741 return TokenPosition::kNoSource; | 13949 return TokenPosition::kNoSource; |
14742 } | 13950 } |
14743 | 13951 |
14744 | |
14745 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 13952 uword Code::GetPcForDeoptId(intptr_t deopt_id, |
14746 RawPcDescriptors::Kind kind) const { | 13953 RawPcDescriptors::Kind kind) const { |
14747 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 13954 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
14748 PcDescriptors::Iterator iter(descriptors, kind); | 13955 PcDescriptors::Iterator iter(descriptors, kind); |
14749 while (iter.MoveNext()) { | 13956 while (iter.MoveNext()) { |
14750 if (iter.DeoptId() == deopt_id) { | 13957 if (iter.DeoptId() == deopt_id) { |
14751 uword pc_offset = iter.PcOffset(); | 13958 uword pc_offset = iter.PcOffset(); |
14752 uword pc = PayloadStart() + pc_offset; | 13959 uword pc = PayloadStart() + pc_offset; |
14753 ASSERT(ContainsInstructionAt(pc)); | 13960 ASSERT(ContainsInstructionAt(pc)); |
14754 return pc; | 13961 return pc; |
14755 } | 13962 } |
14756 } | 13963 } |
14757 return 0; | 13964 return 0; |
14758 } | 13965 } |
14759 | 13966 |
14760 | |
14761 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 13967 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |
14762 uword pc_offset = pc - PayloadStart(); | 13968 uword pc_offset = pc - PayloadStart(); |
14763 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 13969 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
14764 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 13970 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |
14765 while (iter.MoveNext()) { | 13971 while (iter.MoveNext()) { |
14766 if (iter.PcOffset() == pc_offset) { | 13972 if (iter.PcOffset() == pc_offset) { |
14767 return iter.DeoptId(); | 13973 return iter.DeoptId(); |
14768 } | 13974 } |
14769 } | 13975 } |
14770 return Thread::kNoDeoptId; | 13976 return Thread::kNoDeoptId; |
14771 } | 13977 } |
14772 | 13978 |
14773 | |
14774 const char* Code::ToCString() const { | 13979 const char* Code::ToCString() const { |
14775 return Thread::Current()->zone()->PrintToString("Code(%s)", QualifiedName()); | 13980 return Thread::Current()->zone()->PrintToString("Code(%s)", QualifiedName()); |
14776 } | 13981 } |
14777 | 13982 |
14778 | |
14779 const char* Code::Name() const { | 13983 const char* Code::Name() const { |
14780 Zone* zone = Thread::Current()->zone(); | 13984 Zone* zone = Thread::Current()->zone(); |
14781 const Object& obj = Object::Handle(zone, owner()); | 13985 const Object& obj = Object::Handle(zone, owner()); |
14782 if (obj.IsNull()) { | 13986 if (obj.IsNull()) { |
14783 // Regular stub. | 13987 // Regular stub. |
14784 const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); | 13988 const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); |
14785 if (name == NULL) { | 13989 if (name == NULL) { |
14786 ASSERT(!StubCode::HasBeenInitialized()); | 13990 ASSERT(!StubCode::HasBeenInitialized()); |
14787 return zone->PrintToString("[this stub]"); // Not yet recorded. | 13991 return zone->PrintToString("[this stub]"); // Not yet recorded. |
14788 } | 13992 } |
14789 return zone->PrintToString("[Stub] %s", name); | 13993 return zone->PrintToString("[Stub] %s", name); |
14790 } else if (obj.IsClass()) { | 13994 } else if (obj.IsClass()) { |
14791 // Allocation stub. | 13995 // Allocation stub. |
14792 String& cls_name = String::Handle(zone, Class::Cast(obj).ScrubbedName()); | 13996 String& cls_name = String::Handle(zone, Class::Cast(obj).ScrubbedName()); |
14793 ASSERT(!cls_name.IsNull()); | 13997 ASSERT(!cls_name.IsNull()); |
14794 return zone->PrintToString("[Stub] Allocate %s", cls_name.ToCString()); | 13998 return zone->PrintToString("[Stub] Allocate %s", cls_name.ToCString()); |
14795 } else { | 13999 } else { |
14796 ASSERT(obj.IsFunction()); | 14000 ASSERT(obj.IsFunction()); |
14797 // Dart function. | 14001 // Dart function. |
14798 const char* opt = is_optimized() ? "*" : ""; | 14002 const char* opt = is_optimized() ? "*" : ""; |
14799 const char* function_name = | 14003 const char* function_name = |
14800 String::Handle(zone, Function::Cast(obj).UserVisibleName()).ToCString(); | 14004 String::Handle(zone, Function::Cast(obj).UserVisibleName()).ToCString(); |
14801 return zone->PrintToString("%s%s", opt, function_name); | 14005 return zone->PrintToString("%s%s", opt, function_name); |
14802 } | 14006 } |
14803 } | 14007 } |
14804 | 14008 |
14805 | |
14806 const char* Code::QualifiedName() const { | 14009 const char* Code::QualifiedName() const { |
14807 Zone* zone = Thread::Current()->zone(); | 14010 Zone* zone = Thread::Current()->zone(); |
14808 const Object& obj = Object::Handle(zone, owner()); | 14011 const Object& obj = Object::Handle(zone, owner()); |
14809 if (obj.IsFunction()) { | 14012 if (obj.IsFunction()) { |
14810 const char* opt = is_optimized() ? "*" : ""; | 14013 const char* opt = is_optimized() ? "*" : ""; |
14811 const char* function_name = | 14014 const char* function_name = |
14812 String::Handle(zone, Function::Cast(obj).QualifiedScrubbedName()) | 14015 String::Handle(zone, Function::Cast(obj).QualifiedScrubbedName()) |
14813 .ToCString(); | 14016 .ToCString(); |
14814 return zone->PrintToString("%s%s", opt, function_name); | 14017 return zone->PrintToString("%s%s", opt, function_name); |
14815 } | 14018 } |
14816 return Name(); | 14019 return Name(); |
14817 } | 14020 } |
14818 | 14021 |
14819 | |
14820 bool Code::IsAllocationStubCode() const { | 14022 bool Code::IsAllocationStubCode() const { |
14821 const Object& obj = Object::Handle(owner()); | 14023 const Object& obj = Object::Handle(owner()); |
14822 return obj.IsClass(); | 14024 return obj.IsClass(); |
14823 } | 14025 } |
14824 | 14026 |
14825 | |
14826 bool Code::IsStubCode() const { | 14027 bool Code::IsStubCode() const { |
14827 const Object& obj = Object::Handle(owner()); | 14028 const Object& obj = Object::Handle(owner()); |
14828 return obj.IsNull(); | 14029 return obj.IsNull(); |
14829 } | 14030 } |
14830 | 14031 |
14831 | |
14832 bool Code::IsFunctionCode() const { | 14032 bool Code::IsFunctionCode() const { |
14833 const Object& obj = Object::Handle(owner()); | 14033 const Object& obj = Object::Handle(owner()); |
14834 return obj.IsFunction(); | 14034 return obj.IsFunction(); |
14835 } | 14035 } |
14836 | 14036 |
14837 | |
14838 void Code::DisableDartCode() const { | 14037 void Code::DisableDartCode() const { |
14839 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 14038 DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |
14840 ASSERT(IsFunctionCode()); | 14039 ASSERT(IsFunctionCode()); |
14841 ASSERT(instructions() == active_instructions()); | 14040 ASSERT(instructions() == active_instructions()); |
14842 const Code& new_code = | 14041 const Code& new_code = |
14843 Code::Handle(StubCode::FixCallersTarget_entry()->code()); | 14042 Code::Handle(StubCode::FixCallersTarget_entry()->code()); |
14844 SetActiveInstructions(Instructions::Handle(new_code.instructions())); | 14043 SetActiveInstructions(Instructions::Handle(new_code.instructions())); |
14845 } | 14044 } |
14846 | 14045 |
14847 | |
14848 void Code::DisableStubCode() const { | 14046 void Code::DisableStubCode() const { |
14849 #if !defined(TARGET_ARCH_DBC) | 14047 #if !defined(TARGET_ARCH_DBC) |
14850 ASSERT(Thread::Current()->IsMutatorThread()); | 14048 ASSERT(Thread::Current()->IsMutatorThread()); |
14851 ASSERT(IsAllocationStubCode()); | 14049 ASSERT(IsAllocationStubCode()); |
14852 ASSERT(instructions() == active_instructions()); | 14050 ASSERT(instructions() == active_instructions()); |
14853 const Code& new_code = | 14051 const Code& new_code = |
14854 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); | 14052 Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); |
14855 SetActiveInstructions(Instructions::Handle(new_code.instructions())); | 14053 SetActiveInstructions(Instructions::Handle(new_code.instructions())); |
14856 #else | 14054 #else |
14857 // DBC does not use allocation stubs. | 14055 // DBC does not use allocation stubs. |
14858 UNIMPLEMENTED(); | 14056 UNIMPLEMENTED(); |
14859 #endif // !defined(TARGET_ARCH_DBC) | 14057 #endif // !defined(TARGET_ARCH_DBC) |
14860 } | 14058 } |
14861 | 14059 |
14862 | |
14863 void Code::SetActiveInstructions(const Instructions& instructions) const { | 14060 void Code::SetActiveInstructions(const Instructions& instructions) const { |
14864 #if defined(DART_PRECOMPILED_RUNTIME) | 14061 #if defined(DART_PRECOMPILED_RUNTIME) |
14865 UNREACHABLE(); | 14062 UNREACHABLE(); |
14866 #else | 14063 #else |
14867 DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); | 14064 DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); |
14868 // RawInstructions are never allocated in New space and hence a | 14065 // RawInstructions are never allocated in New space and hence a |
14869 // store buffer update is not needed here. | 14066 // store buffer update is not needed here. |
14870 StorePointer(&raw_ptr()->active_instructions_, instructions.raw()); | 14067 StorePointer(&raw_ptr()->active_instructions_, instructions.raw()); |
14871 StoreNonPointer(&raw_ptr()->entry_point_, | 14068 StoreNonPointer(&raw_ptr()->entry_point_, |
14872 Instructions::UncheckedEntryPoint(instructions.raw())); | 14069 Instructions::UncheckedEntryPoint(instructions.raw())); |
14873 StoreNonPointer(&raw_ptr()->checked_entry_point_, | 14070 StoreNonPointer(&raw_ptr()->checked_entry_point_, |
14874 Instructions::CheckedEntryPoint(instructions.raw())); | 14071 Instructions::CheckedEntryPoint(instructions.raw())); |
14875 #endif | 14072 #endif |
14876 } | 14073 } |
14877 | 14074 |
14878 | |
14879 RawStackMap* Code::GetStackMap(uint32_t pc_offset, | 14075 RawStackMap* Code::GetStackMap(uint32_t pc_offset, |
14880 Array* maps, | 14076 Array* maps, |
14881 StackMap* map) const { | 14077 StackMap* map) const { |
14882 // This code is used during iterating frames during a GC and hence it | 14078 // This code is used during iterating frames during a GC and hence it |
14883 // should not in turn start a GC. | 14079 // should not in turn start a GC. |
14884 NoSafepointScope no_safepoint; | 14080 NoSafepointScope no_safepoint; |
14885 if (stackmaps() == Array::null()) { | 14081 if (stackmaps() == Array::null()) { |
14886 // No stack maps are present in the code object which means this | 14082 // No stack maps are present in the code object which means this |
14887 // frame relies on tagged pointers. | 14083 // frame relies on tagged pointers. |
14888 return StackMap::null(); | 14084 return StackMap::null(); |
(...skipping 11 matching lines...) Expand all Loading... |
14900 } | 14096 } |
14901 // If we are missing a stack map, this must either be unoptimized code, or | 14097 // If we are missing a stack map, this must either be unoptimized code, or |
14902 // the entry to an osr function. (In which case all stack slots are | 14098 // the entry to an osr function. (In which case all stack slots are |
14903 // considered to have tagged pointers.) | 14099 // considered to have tagged pointers.) |
14904 // Running with --verify-on-transition should hit this. | 14100 // Running with --verify-on-transition should hit this. |
14905 ASSERT(!is_optimized() || | 14101 ASSERT(!is_optimized() || |
14906 (pc_offset == UncheckedEntryPoint() - PayloadStart())); | 14102 (pc_offset == UncheckedEntryPoint() - PayloadStart())); |
14907 return StackMap::null(); | 14103 return StackMap::null(); |
14908 } | 14104 } |
14909 | 14105 |
14910 | |
14911 void Code::GetInlinedFunctionsAtInstruction( | 14106 void Code::GetInlinedFunctionsAtInstruction( |
14912 intptr_t pc_offset, | 14107 intptr_t pc_offset, |
14913 GrowableArray<const Function*>* functions, | 14108 GrowableArray<const Function*>* functions, |
14914 GrowableArray<TokenPosition>* token_positions) const { | 14109 GrowableArray<TokenPosition>* token_positions) const { |
14915 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 14110 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
14916 if (map.IsNull()) { | 14111 if (map.IsNull()) { |
14917 ASSERT(!IsFunctionCode()); | 14112 ASSERT(!IsFunctionCode()); |
14918 return; // VM stub or allocation stub. | 14113 return; // VM stub or allocation stub. |
14919 } | 14114 } |
14920 const Array& id_map = Array::Handle(inlined_id_to_function()); | 14115 const Array& id_map = Array::Handle(inlined_id_to_function()); |
14921 const Function& root = Function::Handle(function()); | 14116 const Function& root = Function::Handle(function()); |
14922 CodeSourceMapReader reader(map, id_map, root); | 14117 CodeSourceMapReader reader(map, id_map, root); |
14923 reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); | 14118 reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); |
14924 } | 14119 } |
14925 | 14120 |
14926 | |
14927 #ifndef PRODUCT | 14121 #ifndef PRODUCT |
14928 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { | 14122 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { |
14929 if (!is_optimized()) { | 14123 if (!is_optimized()) { |
14930 return; // No inlining. | 14124 return; // No inlining. |
14931 } | 14125 } |
14932 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 14126 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
14933 const Array& id_map = Array::Handle(inlined_id_to_function()); | 14127 const Array& id_map = Array::Handle(inlined_id_to_function()); |
14934 const Function& root = Function::Handle(function()); | 14128 const Function& root = Function::Handle(function()); |
14935 CodeSourceMapReader reader(map, id_map, root); | 14129 CodeSourceMapReader reader(map, id_map, root); |
14936 reader.PrintJSONInlineIntervals(jsobj); | 14130 reader.PrintJSONInlineIntervals(jsobj); |
14937 } | 14131 } |
14938 #endif | 14132 #endif |
14939 | 14133 |
14940 | |
14941 void Code::DumpInlineIntervals() const { | 14134 void Code::DumpInlineIntervals() const { |
14942 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 14135 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
14943 if (map.IsNull()) { | 14136 if (map.IsNull()) { |
14944 // Stub code. | 14137 // Stub code. |
14945 return; | 14138 return; |
14946 } | 14139 } |
14947 const Array& id_map = Array::Handle(inlined_id_to_function()); | 14140 const Array& id_map = Array::Handle(inlined_id_to_function()); |
14948 const Function& root = Function::Handle(function()); | 14141 const Function& root = Function::Handle(function()); |
14949 CodeSourceMapReader reader(map, id_map, root); | 14142 CodeSourceMapReader reader(map, id_map, root); |
14950 reader.DumpInlineIntervals(PayloadStart()); | 14143 reader.DumpInlineIntervals(PayloadStart()); |
14951 } | 14144 } |
14952 | 14145 |
14953 | |
14954 void Code::DumpSourcePositions() const { | 14146 void Code::DumpSourcePositions() const { |
14955 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 14147 const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |
14956 if (map.IsNull()) { | 14148 if (map.IsNull()) { |
14957 // Stub code. | 14149 // Stub code. |
14958 return; | 14150 return; |
14959 } | 14151 } |
14960 const Array& id_map = Array::Handle(inlined_id_to_function()); | 14152 const Array& id_map = Array::Handle(inlined_id_to_function()); |
14961 const Function& root = Function::Handle(function()); | 14153 const Function& root = Function::Handle(function()); |
14962 CodeSourceMapReader reader(map, id_map, root); | 14154 CodeSourceMapReader reader(map, id_map, root); |
14963 reader.DumpSourcePositions(PayloadStart()); | 14155 reader.DumpSourcePositions(PayloadStart()); |
14964 } | 14156 } |
14965 | 14157 |
14966 | |
14967 RawArray* Code::await_token_positions() const { | 14158 RawArray* Code::await_token_positions() const { |
14968 #if defined(DART_PRECOMPILED_RUNTIME) | 14159 #if defined(DART_PRECOMPILED_RUNTIME) |
14969 return Array::null(); | 14160 return Array::null(); |
14970 #else | 14161 #else |
14971 return raw_ptr()->await_token_positions_; | 14162 return raw_ptr()->await_token_positions_; |
14972 #endif | 14163 #endif |
14973 } | 14164 } |
14974 | 14165 |
14975 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { | 14166 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { |
14976 ASSERT(num_variables >= 0); | 14167 ASSERT(num_variables >= 0); |
14977 ASSERT(Object::context_class() != Class::null()); | 14168 ASSERT(Object::context_class() != Class::null()); |
14978 | 14169 |
14979 if (num_variables < 0 || num_variables > kMaxElements) { | 14170 if (num_variables < 0 || num_variables > kMaxElements) { |
14980 // This should be caught before we reach here. | 14171 // This should be caught before we reach here. |
14981 FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n", | 14172 FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n", |
14982 num_variables); | 14173 num_variables); |
14983 } | 14174 } |
14984 Context& result = Context::Handle(); | 14175 Context& result = Context::Handle(); |
14985 { | 14176 { |
14986 RawObject* raw = Object::Allocate( | 14177 RawObject* raw = Object::Allocate( |
14987 Context::kClassId, Context::InstanceSize(num_variables), space); | 14178 Context::kClassId, Context::InstanceSize(num_variables), space); |
14988 NoSafepointScope no_safepoint; | 14179 NoSafepointScope no_safepoint; |
14989 result ^= raw; | 14180 result ^= raw; |
14990 result.set_num_variables(num_variables); | 14181 result.set_num_variables(num_variables); |
14991 } | 14182 } |
14992 return result.raw(); | 14183 return result.raw(); |
14993 } | 14184 } |
14994 | 14185 |
14995 | |
14996 const char* Context::ToCString() const { | 14186 const char* Context::ToCString() const { |
14997 if (IsNull()) { | 14187 if (IsNull()) { |
14998 return "Context: null"; | 14188 return "Context: null"; |
14999 } | 14189 } |
15000 Zone* zone = Thread::Current()->zone(); | 14190 Zone* zone = Thread::Current()->zone(); |
15001 const Context& parent_ctx = Context::Handle(parent()); | 14191 const Context& parent_ctx = Context::Handle(parent()); |
15002 if (parent_ctx.IsNull()) { | 14192 if (parent_ctx.IsNull()) { |
15003 return zone->PrintToString("Context num_variables: %" Pd "", | 14193 return zone->PrintToString("Context num_variables: %" Pd "", |
15004 num_variables()); | 14194 num_variables()); |
15005 } else { | 14195 } else { |
15006 const char* parent_str = parent_ctx.ToCString(); | 14196 const char* parent_str = parent_ctx.ToCString(); |
15007 return zone->PrintToString("Context num_variables: %" Pd " parent:{ %s }", | 14197 return zone->PrintToString("Context num_variables: %" Pd " parent:{ %s }", |
15008 num_variables(), parent_str); | 14198 num_variables(), parent_str); |
15009 } | 14199 } |
15010 } | 14200 } |
15011 | 14201 |
15012 | |
15013 static void IndentN(int count) { | 14202 static void IndentN(int count) { |
15014 for (int i = 0; i < count; i++) { | 14203 for (int i = 0; i < count; i++) { |
15015 THR_Print(" "); | 14204 THR_Print(" "); |
15016 } | 14205 } |
15017 } | 14206 } |
15018 | 14207 |
15019 | |
15020 void Context::Dump(int indent) const { | 14208 void Context::Dump(int indent) const { |
15021 if (IsNull()) { | 14209 if (IsNull()) { |
15022 IndentN(indent); | 14210 IndentN(indent); |
15023 THR_Print("Context@null\n"); | 14211 THR_Print("Context@null\n"); |
15024 return; | 14212 return; |
15025 } | 14213 } |
15026 | 14214 |
15027 IndentN(indent); | 14215 IndentN(indent); |
15028 THR_Print("Context@%p vars(%" Pd ") {\n", this->raw(), num_variables()); | 14216 THR_Print("Context@%p vars(%" Pd ") {\n", this->raw(), num_variables()); |
15029 Object& obj = Object::Handle(); | 14217 Object& obj = Object::Handle(); |
15030 for (intptr_t i = 0; i < num_variables(); i++) { | 14218 for (intptr_t i = 0; i < num_variables(); i++) { |
15031 IndentN(indent + 2); | 14219 IndentN(indent + 2); |
15032 obj = At(i); | 14220 obj = At(i); |
15033 const char* s = obj.ToCString(); | 14221 const char* s = obj.ToCString(); |
15034 if (strlen(s) > 50) { | 14222 if (strlen(s) > 50) { |
15035 THR_Print("[%" Pd "] = [first 50 chars:] %.50s...\n", i, s); | 14223 THR_Print("[%" Pd "] = [first 50 chars:] %.50s...\n", i, s); |
15036 } else { | 14224 } else { |
15037 THR_Print("[%" Pd "] = %s\n", i, s); | 14225 THR_Print("[%" Pd "] = %s\n", i, s); |
15038 } | 14226 } |
15039 } | 14227 } |
15040 | 14228 |
15041 const Context& parent_ctx = Context::Handle(parent()); | 14229 const Context& parent_ctx = Context::Handle(parent()); |
15042 if (!parent_ctx.IsNull()) { | 14230 if (!parent_ctx.IsNull()) { |
15043 parent_ctx.Dump(indent + 2); | 14231 parent_ctx.Dump(indent + 2); |
15044 } | 14232 } |
15045 IndentN(indent); | 14233 IndentN(indent); |
15046 THR_Print("}\n"); | 14234 THR_Print("}\n"); |
15047 } | 14235 } |
15048 | 14236 |
15049 | |
15050 RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) { | 14237 RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) { |
15051 ASSERT(Object::context_scope_class() != Class::null()); | 14238 ASSERT(Object::context_scope_class() != Class::null()); |
15052 if (num_variables < 0 || num_variables > kMaxElements) { | 14239 if (num_variables < 0 || num_variables > kMaxElements) { |
15053 // This should be caught before we reach here. | 14240 // This should be caught before we reach here. |
15054 FATAL1("Fatal error in ContextScope::New: invalid num_variables %" Pd "\n", | 14241 FATAL1("Fatal error in ContextScope::New: invalid num_variables %" Pd "\n", |
15055 num_variables); | 14242 num_variables); |
15056 } | 14243 } |
15057 intptr_t size = ContextScope::InstanceSize(num_variables); | 14244 intptr_t size = ContextScope::InstanceSize(num_variables); |
15058 ContextScope& result = ContextScope::Handle(); | 14245 ContextScope& result = ContextScope::Handle(); |
15059 { | 14246 { |
15060 RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld); | 14247 RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld); |
15061 NoSafepointScope no_safepoint; | 14248 NoSafepointScope no_safepoint; |
15062 result ^= raw; | 14249 result ^= raw; |
15063 result.set_num_variables(num_variables); | 14250 result.set_num_variables(num_variables); |
15064 result.set_is_implicit(is_implicit); | 14251 result.set_is_implicit(is_implicit); |
15065 } | 14252 } |
15066 return result.raw(); | 14253 return result.raw(); |
15067 } | 14254 } |
15068 | 14255 |
15069 | |
15070 TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const { | 14256 TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const { |
15071 return TokenPosition(Smi::Value(VariableDescAddr(scope_index)->token_pos)); | 14257 return TokenPosition(Smi::Value(VariableDescAddr(scope_index)->token_pos)); |
15072 } | 14258 } |
15073 | 14259 |
15074 | |
15075 void ContextScope::SetTokenIndexAt(intptr_t scope_index, | 14260 void ContextScope::SetTokenIndexAt(intptr_t scope_index, |
15076 TokenPosition token_pos) const { | 14261 TokenPosition token_pos) const { |
15077 StoreSmi(&VariableDescAddr(scope_index)->token_pos, | 14262 StoreSmi(&VariableDescAddr(scope_index)->token_pos, |
15078 Smi::New(token_pos.value())); | 14263 Smi::New(token_pos.value())); |
15079 } | 14264 } |
15080 | 14265 |
15081 | |
15082 TokenPosition ContextScope::DeclarationTokenIndexAt( | 14266 TokenPosition ContextScope::DeclarationTokenIndexAt( |
15083 intptr_t scope_index) const { | 14267 intptr_t scope_index) const { |
15084 return TokenPosition( | 14268 return TokenPosition( |
15085 Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos)); | 14269 Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos)); |
15086 } | 14270 } |
15087 | 14271 |
15088 | |
15089 void ContextScope::SetDeclarationTokenIndexAt( | 14272 void ContextScope::SetDeclarationTokenIndexAt( |
15090 intptr_t scope_index, | 14273 intptr_t scope_index, |
15091 TokenPosition declaration_token_pos) const { | 14274 TokenPosition declaration_token_pos) const { |
15092 StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos, | 14275 StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos, |
15093 Smi::New(declaration_token_pos.value())); | 14276 Smi::New(declaration_token_pos.value())); |
15094 } | 14277 } |
15095 | 14278 |
15096 | |
15097 RawString* ContextScope::NameAt(intptr_t scope_index) const { | 14279 RawString* ContextScope::NameAt(intptr_t scope_index) const { |
15098 return VariableDescAddr(scope_index)->name; | 14280 return VariableDescAddr(scope_index)->name; |
15099 } | 14281 } |
15100 | 14282 |
15101 | |
15102 void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const { | 14283 void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const { |
15103 StorePointer(&(VariableDescAddr(scope_index)->name), name.raw()); | 14284 StorePointer(&(VariableDescAddr(scope_index)->name), name.raw()); |
15104 } | 14285 } |
15105 | 14286 |
15106 | |
15107 bool ContextScope::IsFinalAt(intptr_t scope_index) const { | 14287 bool ContextScope::IsFinalAt(intptr_t scope_index) const { |
15108 return Bool::Handle(VariableDescAddr(scope_index)->is_final).value(); | 14288 return Bool::Handle(VariableDescAddr(scope_index)->is_final).value(); |
15109 } | 14289 } |
15110 | 14290 |
15111 | |
15112 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const { | 14291 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const { |
15113 StorePointer(&(VariableDescAddr(scope_index)->is_final), | 14292 StorePointer(&(VariableDescAddr(scope_index)->is_final), |
15114 Bool::Get(is_final).raw()); | 14293 Bool::Get(is_final).raw()); |
15115 } | 14294 } |
15116 | 14295 |
15117 | |
15118 bool ContextScope::IsConstAt(intptr_t scope_index) const { | 14296 bool ContextScope::IsConstAt(intptr_t scope_index) const { |
15119 return Bool::Handle(VariableDescAddr(scope_index)->is_const).value(); | 14297 return Bool::Handle(VariableDescAddr(scope_index)->is_const).value(); |
15120 } | 14298 } |
15121 | 14299 |
15122 | |
15123 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const { | 14300 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const { |
15124 StorePointer(&(VariableDescAddr(scope_index)->is_const), | 14301 StorePointer(&(VariableDescAddr(scope_index)->is_const), |
15125 Bool::Get(is_const).raw()); | 14302 Bool::Get(is_const).raw()); |
15126 } | 14303 } |
15127 | 14304 |
15128 | |
15129 RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const { | 14305 RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const { |
15130 ASSERT(!IsConstAt(scope_index)); | 14306 ASSERT(!IsConstAt(scope_index)); |
15131 return VariableDescAddr(scope_index)->type; | 14307 return VariableDescAddr(scope_index)->type; |
15132 } | 14308 } |
15133 | 14309 |
15134 | |
15135 void ContextScope::SetTypeAt(intptr_t scope_index, | 14310 void ContextScope::SetTypeAt(intptr_t scope_index, |
15136 const AbstractType& type) const { | 14311 const AbstractType& type) const { |
15137 StorePointer(&(VariableDescAddr(scope_index)->type), type.raw()); | 14312 StorePointer(&(VariableDescAddr(scope_index)->type), type.raw()); |
15138 } | 14313 } |
15139 | 14314 |
15140 | |
15141 RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const { | 14315 RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const { |
15142 ASSERT(IsConstAt(scope_index)); | 14316 ASSERT(IsConstAt(scope_index)); |
15143 return VariableDescAddr(scope_index)->value; | 14317 return VariableDescAddr(scope_index)->value; |
15144 } | 14318 } |
15145 | 14319 |
15146 | |
15147 void ContextScope::SetConstValueAt(intptr_t scope_index, | 14320 void ContextScope::SetConstValueAt(intptr_t scope_index, |
15148 const Instance& value) const { | 14321 const Instance& value) const { |
15149 ASSERT(IsConstAt(scope_index)); | 14322 ASSERT(IsConstAt(scope_index)); |
15150 StorePointer(&(VariableDescAddr(scope_index)->value), value.raw()); | 14323 StorePointer(&(VariableDescAddr(scope_index)->value), value.raw()); |
15151 } | 14324 } |
15152 | 14325 |
15153 | |
15154 intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const { | 14326 intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const { |
15155 return Smi::Value(VariableDescAddr(scope_index)->context_index); | 14327 return Smi::Value(VariableDescAddr(scope_index)->context_index); |
15156 } | 14328 } |
15157 | 14329 |
15158 | |
15159 void ContextScope::SetContextIndexAt(intptr_t scope_index, | 14330 void ContextScope::SetContextIndexAt(intptr_t scope_index, |
15160 intptr_t context_index) const { | 14331 intptr_t context_index) const { |
15161 StoreSmi(&(VariableDescAddr(scope_index)->context_index), | 14332 StoreSmi(&(VariableDescAddr(scope_index)->context_index), |
15162 Smi::New(context_index)); | 14333 Smi::New(context_index)); |
15163 } | 14334 } |
15164 | 14335 |
15165 | |
15166 intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const { | 14336 intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const { |
15167 return Smi::Value(VariableDescAddr(scope_index)->context_level); | 14337 return Smi::Value(VariableDescAddr(scope_index)->context_level); |
15168 } | 14338 } |
15169 | 14339 |
15170 | |
15171 void ContextScope::SetContextLevelAt(intptr_t scope_index, | 14340 void ContextScope::SetContextLevelAt(intptr_t scope_index, |
15172 intptr_t context_level) const { | 14341 intptr_t context_level) const { |
15173 StoreSmi(&(VariableDescAddr(scope_index)->context_level), | 14342 StoreSmi(&(VariableDescAddr(scope_index)->context_level), |
15174 Smi::New(context_level)); | 14343 Smi::New(context_level)); |
15175 } | 14344 } |
15176 | 14345 |
15177 | |
15178 const char* ContextScope::ToCString() const { | 14346 const char* ContextScope::ToCString() const { |
15179 const char* prev_cstr = "ContextScope:"; | 14347 const char* prev_cstr = "ContextScope:"; |
15180 String& name = String::Handle(); | 14348 String& name = String::Handle(); |
15181 for (int i = 0; i < num_variables(); i++) { | 14349 for (int i = 0; i < num_variables(); i++) { |
15182 name = NameAt(i); | 14350 name = NameAt(i); |
15183 const char* cname = name.ToCString(); | 14351 const char* cname = name.ToCString(); |
15184 TokenPosition pos = TokenIndexAt(i); | 14352 TokenPosition pos = TokenIndexAt(i); |
15185 intptr_t idx = ContextIndexAt(i); | 14353 intptr_t idx = ContextIndexAt(i); |
15186 intptr_t lvl = ContextLevelAt(i); | 14354 intptr_t lvl = ContextLevelAt(i); |
15187 char* chars = | 14355 char* chars = |
15188 OS::SCreate(Thread::Current()->zone(), | 14356 OS::SCreate(Thread::Current()->zone(), |
15189 "%s\nvar %s token-pos %s ctx lvl %" Pd " index %" Pd "", | 14357 "%s\nvar %s token-pos %s ctx lvl %" Pd " index %" Pd "", |
15190 prev_cstr, cname, pos.ToCString(), lvl, idx); | 14358 prev_cstr, cname, pos.ToCString(), lvl, idx); |
15191 prev_cstr = chars; | 14359 prev_cstr = chars; |
15192 } | 14360 } |
15193 return prev_cstr; | 14361 return prev_cstr; |
15194 } | 14362 } |
15195 | 14363 |
15196 | |
15197 RawArray* MegamorphicCache::buckets() const { | 14364 RawArray* MegamorphicCache::buckets() const { |
15198 return raw_ptr()->buckets_; | 14365 return raw_ptr()->buckets_; |
15199 } | 14366 } |
15200 | 14367 |
15201 | |
15202 void MegamorphicCache::set_buckets(const Array& buckets) const { | 14368 void MegamorphicCache::set_buckets(const Array& buckets) const { |
15203 StorePointer(&raw_ptr()->buckets_, buckets.raw()); | 14369 StorePointer(&raw_ptr()->buckets_, buckets.raw()); |
15204 } | 14370 } |
15205 | 14371 |
15206 | |
15207 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask | 14372 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask |
15208 // and target class ID to avoid untagging (on each iteration of the | 14373 // and target class ID to avoid untagging (on each iteration of the |
15209 // test loop) in generated code. | 14374 // test loop) in generated code. |
15210 intptr_t MegamorphicCache::mask() const { | 14375 intptr_t MegamorphicCache::mask() const { |
15211 return Smi::Value(raw_ptr()->mask_); | 14376 return Smi::Value(raw_ptr()->mask_); |
15212 } | 14377 } |
15213 | 14378 |
15214 | |
15215 void MegamorphicCache::set_mask(intptr_t mask) const { | 14379 void MegamorphicCache::set_mask(intptr_t mask) const { |
15216 StoreSmi(&raw_ptr()->mask_, Smi::New(mask)); | 14380 StoreSmi(&raw_ptr()->mask_, Smi::New(mask)); |
15217 } | 14381 } |
15218 | 14382 |
15219 | |
15220 intptr_t MegamorphicCache::filled_entry_count() const { | 14383 intptr_t MegamorphicCache::filled_entry_count() const { |
15221 return raw_ptr()->filled_entry_count_; | 14384 return raw_ptr()->filled_entry_count_; |
15222 } | 14385 } |
15223 | 14386 |
15224 | |
15225 void MegamorphicCache::set_filled_entry_count(intptr_t count) const { | 14387 void MegamorphicCache::set_filled_entry_count(intptr_t count) const { |
15226 StoreNonPointer(&raw_ptr()->filled_entry_count_, count); | 14388 StoreNonPointer(&raw_ptr()->filled_entry_count_, count); |
15227 } | 14389 } |
15228 | 14390 |
15229 | |
15230 void MegamorphicCache::set_target_name(const String& value) const { | 14391 void MegamorphicCache::set_target_name(const String& value) const { |
15231 StorePointer(&raw_ptr()->target_name_, value.raw()); | 14392 StorePointer(&raw_ptr()->target_name_, value.raw()); |
15232 } | 14393 } |
15233 | 14394 |
15234 | |
15235 void MegamorphicCache::set_arguments_descriptor(const Array& value) const { | 14395 void MegamorphicCache::set_arguments_descriptor(const Array& value) const { |
15236 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 14396 StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |
15237 } | 14397 } |
15238 | 14398 |
15239 | |
15240 RawMegamorphicCache* MegamorphicCache::New() { | 14399 RawMegamorphicCache* MegamorphicCache::New() { |
15241 MegamorphicCache& result = MegamorphicCache::Handle(); | 14400 MegamorphicCache& result = MegamorphicCache::Handle(); |
15242 { | 14401 { |
15243 RawObject* raw = | 14402 RawObject* raw = |
15244 Object::Allocate(MegamorphicCache::kClassId, | 14403 Object::Allocate(MegamorphicCache::kClassId, |
15245 MegamorphicCache::InstanceSize(), Heap::kOld); | 14404 MegamorphicCache::InstanceSize(), Heap::kOld); |
15246 NoSafepointScope no_safepoint; | 14405 NoSafepointScope no_safepoint; |
15247 result ^= raw; | 14406 result ^= raw; |
15248 } | 14407 } |
15249 result.set_filled_entry_count(0); | 14408 result.set_filled_entry_count(0); |
15250 return result.raw(); | 14409 return result.raw(); |
15251 } | 14410 } |
15252 | 14411 |
15253 | |
15254 RawMegamorphicCache* MegamorphicCache::New(const String& target_name, | 14412 RawMegamorphicCache* MegamorphicCache::New(const String& target_name, |
15255 const Array& arguments_descriptor) { | 14413 const Array& arguments_descriptor) { |
15256 MegamorphicCache& result = MegamorphicCache::Handle(); | 14414 MegamorphicCache& result = MegamorphicCache::Handle(); |
15257 { | 14415 { |
15258 RawObject* raw = | 14416 RawObject* raw = |
15259 Object::Allocate(MegamorphicCache::kClassId, | 14417 Object::Allocate(MegamorphicCache::kClassId, |
15260 MegamorphicCache::InstanceSize(), Heap::kOld); | 14418 MegamorphicCache::InstanceSize(), Heap::kOld); |
15261 NoSafepointScope no_safepoint; | 14419 NoSafepointScope no_safepoint; |
15262 result ^= raw; | 14420 result ^= raw; |
15263 } | 14421 } |
15264 const intptr_t capacity = kInitialCapacity; | 14422 const intptr_t capacity = kInitialCapacity; |
15265 const Array& buckets = | 14423 const Array& buckets = |
15266 Array::Handle(Array::New(kEntryLength * capacity, Heap::kOld)); | 14424 Array::Handle(Array::New(kEntryLength * capacity, Heap::kOld)); |
15267 const Function& handler = | 14425 const Function& handler = |
15268 Function::Handle(MegamorphicCacheTable::miss_handler(Isolate::Current())); | 14426 Function::Handle(MegamorphicCacheTable::miss_handler(Isolate::Current())); |
15269 for (intptr_t i = 0; i < capacity; ++i) { | 14427 for (intptr_t i = 0; i < capacity; ++i) { |
15270 SetEntry(buckets, i, smi_illegal_cid(), handler); | 14428 SetEntry(buckets, i, smi_illegal_cid(), handler); |
15271 } | 14429 } |
15272 result.set_buckets(buckets); | 14430 result.set_buckets(buckets); |
15273 result.set_mask(capacity - 1); | 14431 result.set_mask(capacity - 1); |
15274 result.set_target_name(target_name); | 14432 result.set_target_name(target_name); |
15275 result.set_arguments_descriptor(arguments_descriptor); | 14433 result.set_arguments_descriptor(arguments_descriptor); |
15276 result.set_filled_entry_count(0); | 14434 result.set_filled_entry_count(0); |
15277 return result.raw(); | 14435 return result.raw(); |
15278 } | 14436 } |
15279 | 14437 |
15280 | |
15281 void MegamorphicCache::EnsureCapacity() const { | 14438 void MegamorphicCache::EnsureCapacity() const { |
15282 intptr_t old_capacity = mask() + 1; | 14439 intptr_t old_capacity = mask() + 1; |
15283 double load_limit = kLoadFactor * static_cast<double>(old_capacity); | 14440 double load_limit = kLoadFactor * static_cast<double>(old_capacity); |
15284 if (static_cast<double>(filled_entry_count() + 1) > load_limit) { | 14441 if (static_cast<double>(filled_entry_count() + 1) > load_limit) { |
15285 const Array& old_buckets = Array::Handle(buckets()); | 14442 const Array& old_buckets = Array::Handle(buckets()); |
15286 intptr_t new_capacity = old_capacity * 2; | 14443 intptr_t new_capacity = old_capacity * 2; |
15287 const Array& new_buckets = | 14444 const Array& new_buckets = |
15288 Array::Handle(Array::New(kEntryLength * new_capacity)); | 14445 Array::Handle(Array::New(kEntryLength * new_capacity)); |
15289 | 14446 |
15290 Function& target = Function::Handle( | 14447 Function& target = Function::Handle( |
(...skipping 10 matching lines...) Expand all Loading... |
15301 for (intptr_t i = 0; i < old_capacity; ++i) { | 14458 for (intptr_t i = 0; i < old_capacity; ++i) { |
15302 class_id ^= GetClassId(old_buckets, i); | 14459 class_id ^= GetClassId(old_buckets, i); |
15303 if (class_id.Value() != kIllegalCid) { | 14460 if (class_id.Value() != kIllegalCid) { |
15304 target ^= GetTargetFunction(old_buckets, i); | 14461 target ^= GetTargetFunction(old_buckets, i); |
15305 Insert(class_id, target); | 14462 Insert(class_id, target); |
15306 } | 14463 } |
15307 } | 14464 } |
15308 } | 14465 } |
15309 } | 14466 } |
15310 | 14467 |
15311 | |
15312 void MegamorphicCache::Insert(const Smi& class_id, | 14468 void MegamorphicCache::Insert(const Smi& class_id, |
15313 const Function& target) const { | 14469 const Function& target) const { |
15314 ASSERT(static_cast<double>(filled_entry_count() + 1) <= | 14470 ASSERT(static_cast<double>(filled_entry_count() + 1) <= |
15315 (kLoadFactor * static_cast<double>(mask() + 1))); | 14471 (kLoadFactor * static_cast<double>(mask() + 1))); |
15316 const Array& backing_array = Array::Handle(buckets()); | 14472 const Array& backing_array = Array::Handle(buckets()); |
15317 intptr_t id_mask = mask(); | 14473 intptr_t id_mask = mask(); |
15318 intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask; | 14474 intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask; |
15319 intptr_t i = index; | 14475 intptr_t i = index; |
15320 do { | 14476 do { |
15321 if (Smi::Value(Smi::RawCast(GetClassId(backing_array, i))) == kIllegalCid) { | 14477 if (Smi::Value(Smi::RawCast(GetClassId(backing_array, i))) == kIllegalCid) { |
15322 SetEntry(backing_array, i, class_id, target); | 14478 SetEntry(backing_array, i, class_id, target); |
15323 set_filled_entry_count(filled_entry_count() + 1); | 14479 set_filled_entry_count(filled_entry_count() + 1); |
15324 return; | 14480 return; |
15325 } | 14481 } |
15326 i = (i + 1) & id_mask; | 14482 i = (i + 1) & id_mask; |
15327 } while (i != index); | 14483 } while (i != index); |
15328 UNREACHABLE(); | 14484 UNREACHABLE(); |
15329 } | 14485 } |
15330 | 14486 |
15331 | |
15332 const char* MegamorphicCache::ToCString() const { | 14487 const char* MegamorphicCache::ToCString() const { |
15333 const String& name = String::Handle(target_name()); | 14488 const String& name = String::Handle(target_name()); |
15334 return OS::SCreate(Thread::Current()->zone(), "MegamorphicCache(%s)", | 14489 return OS::SCreate(Thread::Current()->zone(), "MegamorphicCache(%s)", |
15335 name.ToCString()); | 14490 name.ToCString()); |
15336 } | 14491 } |
15337 | 14492 |
15338 | |
15339 RawSubtypeTestCache* SubtypeTestCache::New() { | 14493 RawSubtypeTestCache* SubtypeTestCache::New() { |
15340 ASSERT(Object::subtypetestcache_class() != Class::null()); | 14494 ASSERT(Object::subtypetestcache_class() != Class::null()); |
15341 SubtypeTestCache& result = SubtypeTestCache::Handle(); | 14495 SubtypeTestCache& result = SubtypeTestCache::Handle(); |
15342 { | 14496 { |
15343 // SubtypeTestCache objects are long living objects, allocate them in the | 14497 // SubtypeTestCache objects are long living objects, allocate them in the |
15344 // old generation. | 14498 // old generation. |
15345 RawObject* raw = | 14499 RawObject* raw = |
15346 Object::Allocate(SubtypeTestCache::kClassId, | 14500 Object::Allocate(SubtypeTestCache::kClassId, |
15347 SubtypeTestCache::InstanceSize(), Heap::kOld); | 14501 SubtypeTestCache::InstanceSize(), Heap::kOld); |
15348 NoSafepointScope no_safepoint; | 14502 NoSafepointScope no_safepoint; |
15349 result ^= raw; | 14503 result ^= raw; |
15350 } | 14504 } |
15351 const Array& cache = Array::Handle(Array::New(kTestEntryLength, Heap::kOld)); | 14505 const Array& cache = Array::Handle(Array::New(kTestEntryLength, Heap::kOld)); |
15352 result.set_cache(cache); | 14506 result.set_cache(cache); |
15353 return result.raw(); | 14507 return result.raw(); |
15354 } | 14508 } |
15355 | 14509 |
15356 | |
15357 void SubtypeTestCache::set_cache(const Array& value) const { | 14510 void SubtypeTestCache::set_cache(const Array& value) const { |
15358 StorePointer(&raw_ptr()->cache_, value.raw()); | 14511 StorePointer(&raw_ptr()->cache_, value.raw()); |
15359 } | 14512 } |
15360 | 14513 |
15361 | |
15362 intptr_t SubtypeTestCache::NumberOfChecks() const { | 14514 intptr_t SubtypeTestCache::NumberOfChecks() const { |
15363 NoSafepointScope no_safepoint; | 14515 NoSafepointScope no_safepoint; |
15364 // Do not count the sentinel; | 14516 // Do not count the sentinel; |
15365 return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1; | 14517 return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1; |
15366 } | 14518 } |
15367 | 14519 |
15368 | |
15369 void SubtypeTestCache::AddCheck( | 14520 void SubtypeTestCache::AddCheck( |
15370 const Object& instance_class_id_or_function, | 14521 const Object& instance_class_id_or_function, |
15371 const TypeArguments& instance_type_arguments, | 14522 const TypeArguments& instance_type_arguments, |
15372 const TypeArguments& instantiator_type_arguments, | 14523 const TypeArguments& instantiator_type_arguments, |
15373 const TypeArguments& function_type_arguments, | 14524 const TypeArguments& function_type_arguments, |
15374 const Bool& test_result) const { | 14525 const Bool& test_result) const { |
15375 intptr_t old_num = NumberOfChecks(); | 14526 intptr_t old_num = NumberOfChecks(); |
15376 Array& data = Array::Handle(cache()); | 14527 Array& data = Array::Handle(cache()); |
15377 intptr_t new_len = data.Length() + kTestEntryLength; | 14528 intptr_t new_len = data.Length() + kTestEntryLength; |
15378 data = Array::Grow(data, new_len); | 14529 data = Array::Grow(data, new_len); |
15379 set_cache(data); | 14530 set_cache(data); |
15380 intptr_t data_pos = old_num * kTestEntryLength; | 14531 intptr_t data_pos = old_num * kTestEntryLength; |
15381 data.SetAt(data_pos + kInstanceClassIdOrFunction, | 14532 data.SetAt(data_pos + kInstanceClassIdOrFunction, |
15382 instance_class_id_or_function); | 14533 instance_class_id_or_function); |
15383 data.SetAt(data_pos + kInstanceTypeArguments, instance_type_arguments); | 14534 data.SetAt(data_pos + kInstanceTypeArguments, instance_type_arguments); |
15384 data.SetAt(data_pos + kInstantiatorTypeArguments, | 14535 data.SetAt(data_pos + kInstantiatorTypeArguments, |
15385 instantiator_type_arguments); | 14536 instantiator_type_arguments); |
15386 data.SetAt(data_pos + kFunctionTypeArguments, function_type_arguments); | 14537 data.SetAt(data_pos + kFunctionTypeArguments, function_type_arguments); |
15387 data.SetAt(data_pos + kTestResult, test_result); | 14538 data.SetAt(data_pos + kTestResult, test_result); |
15388 } | 14539 } |
15389 | 14540 |
15390 | |
15391 void SubtypeTestCache::GetCheck(intptr_t ix, | 14541 void SubtypeTestCache::GetCheck(intptr_t ix, |
15392 Object* instance_class_id_or_function, | 14542 Object* instance_class_id_or_function, |
15393 TypeArguments* instance_type_arguments, | 14543 TypeArguments* instance_type_arguments, |
15394 TypeArguments* instantiator_type_arguments, | 14544 TypeArguments* instantiator_type_arguments, |
15395 TypeArguments* function_type_arguments, | 14545 TypeArguments* function_type_arguments, |
15396 Bool* test_result) const { | 14546 Bool* test_result) const { |
15397 Array& data = Array::Handle(cache()); | 14547 Array& data = Array::Handle(cache()); |
15398 intptr_t data_pos = ix * kTestEntryLength; | 14548 intptr_t data_pos = ix * kTestEntryLength; |
15399 *instance_class_id_or_function = | 14549 *instance_class_id_or_function = |
15400 data.At(data_pos + kInstanceClassIdOrFunction); | 14550 data.At(data_pos + kInstanceClassIdOrFunction); |
15401 *instance_type_arguments ^= data.At(data_pos + kInstanceTypeArguments); | 14551 *instance_type_arguments ^= data.At(data_pos + kInstanceTypeArguments); |
15402 *instantiator_type_arguments ^= | 14552 *instantiator_type_arguments ^= |
15403 data.At(data_pos + kInstantiatorTypeArguments); | 14553 data.At(data_pos + kInstantiatorTypeArguments); |
15404 *function_type_arguments ^= data.At(data_pos + kFunctionTypeArguments); | 14554 *function_type_arguments ^= data.At(data_pos + kFunctionTypeArguments); |
15405 *test_result ^= data.At(data_pos + kTestResult); | 14555 *test_result ^= data.At(data_pos + kTestResult); |
15406 } | 14556 } |
15407 | 14557 |
15408 | |
15409 const char* SubtypeTestCache::ToCString() const { | 14558 const char* SubtypeTestCache::ToCString() const { |
15410 return "SubtypeTestCache"; | 14559 return "SubtypeTestCache"; |
15411 } | 14560 } |
15412 | 14561 |
15413 | |
15414 const char* Error::ToErrorCString() const { | 14562 const char* Error::ToErrorCString() const { |
15415 if (IsNull()) { | 14563 if (IsNull()) { |
15416 return "Error: null"; | 14564 return "Error: null"; |
15417 } | 14565 } |
15418 UNREACHABLE(); | 14566 UNREACHABLE(); |
15419 return "Error"; | 14567 return "Error"; |
15420 } | 14568 } |
15421 | 14569 |
15422 | |
15423 const char* Error::ToCString() const { | 14570 const char* Error::ToCString() const { |
15424 if (IsNull()) { | 14571 if (IsNull()) { |
15425 return "Error: null"; | 14572 return "Error: null"; |
15426 } | 14573 } |
15427 // Error is an abstract class. We should never reach here. | 14574 // Error is an abstract class. We should never reach here. |
15428 UNREACHABLE(); | 14575 UNREACHABLE(); |
15429 return "Error"; | 14576 return "Error"; |
15430 } | 14577 } |
15431 | 14578 |
15432 | |
15433 RawApiError* ApiError::New() { | 14579 RawApiError* ApiError::New() { |
15434 ASSERT(Object::api_error_class() != Class::null()); | 14580 ASSERT(Object::api_error_class() != Class::null()); |
15435 RawObject* raw = Object::Allocate(ApiError::kClassId, | 14581 RawObject* raw = Object::Allocate(ApiError::kClassId, |
15436 ApiError::InstanceSize(), Heap::kOld); | 14582 ApiError::InstanceSize(), Heap::kOld); |
15437 return reinterpret_cast<RawApiError*>(raw); | 14583 return reinterpret_cast<RawApiError*>(raw); |
15438 } | 14584 } |
15439 | 14585 |
15440 | |
15441 RawApiError* ApiError::New(const String& message, Heap::Space space) { | 14586 RawApiError* ApiError::New(const String& message, Heap::Space space) { |
15442 #ifndef PRODUCT | 14587 #ifndef PRODUCT |
15443 if (FLAG_print_stacktrace_at_api_error) { | 14588 if (FLAG_print_stacktrace_at_api_error) { |
15444 OS::PrintErr("ApiError: %s\n", message.ToCString()); | 14589 OS::PrintErr("ApiError: %s\n", message.ToCString()); |
15445 Profiler::DumpStackTrace(false /* for_crash */); | 14590 Profiler::DumpStackTrace(false /* for_crash */); |
15446 } | 14591 } |
15447 #endif // !PRODUCT | 14592 #endif // !PRODUCT |
15448 | 14593 |
15449 ASSERT(Object::api_error_class() != Class::null()); | 14594 ASSERT(Object::api_error_class() != Class::null()); |
15450 ApiError& result = ApiError::Handle(); | 14595 ApiError& result = ApiError::Handle(); |
15451 { | 14596 { |
15452 RawObject* raw = | 14597 RawObject* raw = |
15453 Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space); | 14598 Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space); |
15454 NoSafepointScope no_safepoint; | 14599 NoSafepointScope no_safepoint; |
15455 result ^= raw; | 14600 result ^= raw; |
15456 } | 14601 } |
15457 result.set_message(message); | 14602 result.set_message(message); |
15458 return result.raw(); | 14603 return result.raw(); |
15459 } | 14604 } |
15460 | 14605 |
15461 | |
15462 void ApiError::set_message(const String& message) const { | 14606 void ApiError::set_message(const String& message) const { |
15463 StorePointer(&raw_ptr()->message_, message.raw()); | 14607 StorePointer(&raw_ptr()->message_, message.raw()); |
15464 } | 14608 } |
15465 | 14609 |
15466 | |
15467 const char* ApiError::ToErrorCString() const { | 14610 const char* ApiError::ToErrorCString() const { |
15468 const String& msg_str = String::Handle(message()); | 14611 const String& msg_str = String::Handle(message()); |
15469 return msg_str.ToCString(); | 14612 return msg_str.ToCString(); |
15470 } | 14613 } |
15471 | 14614 |
15472 | |
15473 const char* ApiError::ToCString() const { | 14615 const char* ApiError::ToCString() const { |
15474 return "ApiError"; | 14616 return "ApiError"; |
15475 } | 14617 } |
15476 | 14618 |
15477 | |
15478 RawLanguageError* LanguageError::New() { | 14619 RawLanguageError* LanguageError::New() { |
15479 ASSERT(Object::language_error_class() != Class::null()); | 14620 ASSERT(Object::language_error_class() != Class::null()); |
15480 RawObject* raw = Object::Allocate(LanguageError::kClassId, | 14621 RawObject* raw = Object::Allocate(LanguageError::kClassId, |
15481 LanguageError::InstanceSize(), Heap::kOld); | 14622 LanguageError::InstanceSize(), Heap::kOld); |
15482 return reinterpret_cast<RawLanguageError*>(raw); | 14623 return reinterpret_cast<RawLanguageError*>(raw); |
15483 } | 14624 } |
15484 | 14625 |
15485 | |
15486 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error, | 14626 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error, |
15487 const Script& script, | 14627 const Script& script, |
15488 TokenPosition token_pos, | 14628 TokenPosition token_pos, |
15489 bool report_after_token, | 14629 bool report_after_token, |
15490 Report::Kind kind, | 14630 Report::Kind kind, |
15491 Heap::Space space, | 14631 Heap::Space space, |
15492 const char* format, | 14632 const char* format, |
15493 va_list args) { | 14633 va_list args) { |
15494 ASSERT(Object::language_error_class() != Class::null()); | 14634 ASSERT(Object::language_error_class() != Class::null()); |
15495 LanguageError& result = LanguageError::Handle(); | 14635 LanguageError& result = LanguageError::Handle(); |
15496 { | 14636 { |
15497 RawObject* raw = Object::Allocate(LanguageError::kClassId, | 14637 RawObject* raw = Object::Allocate(LanguageError::kClassId, |
15498 LanguageError::InstanceSize(), space); | 14638 LanguageError::InstanceSize(), space); |
15499 NoSafepointScope no_safepoint; | 14639 NoSafepointScope no_safepoint; |
15500 result ^= raw; | 14640 result ^= raw; |
15501 } | 14641 } |
15502 result.set_previous_error(prev_error); | 14642 result.set_previous_error(prev_error); |
15503 result.set_script(script); | 14643 result.set_script(script); |
15504 result.set_token_pos(token_pos); | 14644 result.set_token_pos(token_pos); |
15505 result.set_report_after_token(report_after_token); | 14645 result.set_report_after_token(report_after_token); |
15506 result.set_kind(kind); | 14646 result.set_kind(kind); |
15507 result.set_message( | 14647 result.set_message( |
15508 String::Handle(String::NewFormattedV(format, args, space))); | 14648 String::Handle(String::NewFormattedV(format, args, space))); |
15509 return result.raw(); | 14649 return result.raw(); |
15510 } | 14650 } |
15511 | 14651 |
15512 | |
15513 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error, | 14652 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error, |
15514 const Script& script, | 14653 const Script& script, |
15515 TokenPosition token_pos, | 14654 TokenPosition token_pos, |
15516 bool report_after_token, | 14655 bool report_after_token, |
15517 Report::Kind kind, | 14656 Report::Kind kind, |
15518 Heap::Space space, | 14657 Heap::Space space, |
15519 const char* format, | 14658 const char* format, |
15520 ...) { | 14659 ...) { |
15521 va_list args; | 14660 va_list args; |
15522 va_start(args, format); | 14661 va_start(args, format); |
15523 RawLanguageError* result = LanguageError::NewFormattedV( | 14662 RawLanguageError* result = LanguageError::NewFormattedV( |
15524 prev_error, script, token_pos, report_after_token, kind, space, format, | 14663 prev_error, script, token_pos, report_after_token, kind, space, format, |
15525 args); | 14664 args); |
15526 NoSafepointScope no_safepoint; | 14665 NoSafepointScope no_safepoint; |
15527 va_end(args); | 14666 va_end(args); |
15528 return result; | 14667 return result; |
15529 } | 14668 } |
15530 | 14669 |
15531 | |
15532 RawLanguageError* LanguageError::New(const String& formatted_message, | 14670 RawLanguageError* LanguageError::New(const String& formatted_message, |
15533 Report::Kind kind, | 14671 Report::Kind kind, |
15534 Heap::Space space) { | 14672 Heap::Space space) { |
15535 ASSERT(Object::language_error_class() != Class::null()); | 14673 ASSERT(Object::language_error_class() != Class::null()); |
15536 LanguageError& result = LanguageError::Handle(); | 14674 LanguageError& result = LanguageError::Handle(); |
15537 { | 14675 { |
15538 RawObject* raw = Object::Allocate(LanguageError::kClassId, | 14676 RawObject* raw = Object::Allocate(LanguageError::kClassId, |
15539 LanguageError::InstanceSize(), space); | 14677 LanguageError::InstanceSize(), space); |
15540 NoSafepointScope no_safepoint; | 14678 NoSafepointScope no_safepoint; |
15541 result ^= raw; | 14679 result ^= raw; |
15542 } | 14680 } |
15543 result.set_formatted_message(formatted_message); | 14681 result.set_formatted_message(formatted_message); |
15544 result.set_kind(kind); | 14682 result.set_kind(kind); |
15545 return result.raw(); | 14683 return result.raw(); |
15546 } | 14684 } |
15547 | 14685 |
15548 | |
15549 void LanguageError::set_previous_error(const Error& value) const { | 14686 void LanguageError::set_previous_error(const Error& value) const { |
15550 StorePointer(&raw_ptr()->previous_error_, value.raw()); | 14687 StorePointer(&raw_ptr()->previous_error_, value.raw()); |
15551 } | 14688 } |
15552 | 14689 |
15553 | |
15554 void LanguageError::set_script(const Script& value) const { | 14690 void LanguageError::set_script(const Script& value) const { |
15555 StorePointer(&raw_ptr()->script_, value.raw()); | 14691 StorePointer(&raw_ptr()->script_, value.raw()); |
15556 } | 14692 } |
15557 | 14693 |
15558 | |
15559 void LanguageError::set_token_pos(TokenPosition token_pos) const { | 14694 void LanguageError::set_token_pos(TokenPosition token_pos) const { |
15560 ASSERT(!token_pos.IsClassifying()); | 14695 ASSERT(!token_pos.IsClassifying()); |
15561 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 14696 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
15562 } | 14697 } |
15563 | 14698 |
15564 | |
15565 void LanguageError::set_report_after_token(bool value) { | 14699 void LanguageError::set_report_after_token(bool value) { |
15566 StoreNonPointer(&raw_ptr()->report_after_token_, value); | 14700 StoreNonPointer(&raw_ptr()->report_after_token_, value); |
15567 } | 14701 } |
15568 | 14702 |
15569 | |
15570 void LanguageError::set_kind(uint8_t value) const { | 14703 void LanguageError::set_kind(uint8_t value) const { |
15571 StoreNonPointer(&raw_ptr()->kind_, value); | 14704 StoreNonPointer(&raw_ptr()->kind_, value); |
15572 } | 14705 } |
15573 | 14706 |
15574 | |
15575 void LanguageError::set_message(const String& value) const { | 14707 void LanguageError::set_message(const String& value) const { |
15576 StorePointer(&raw_ptr()->message_, value.raw()); | 14708 StorePointer(&raw_ptr()->message_, value.raw()); |
15577 } | 14709 } |
15578 | 14710 |
15579 | |
15580 void LanguageError::set_formatted_message(const String& value) const { | 14711 void LanguageError::set_formatted_message(const String& value) const { |
15581 StorePointer(&raw_ptr()->formatted_message_, value.raw()); | 14712 StorePointer(&raw_ptr()->formatted_message_, value.raw()); |
15582 } | 14713 } |
15583 | 14714 |
15584 | |
15585 RawString* LanguageError::FormatMessage() const { | 14715 RawString* LanguageError::FormatMessage() const { |
15586 if (formatted_message() != String::null()) { | 14716 if (formatted_message() != String::null()) { |
15587 return formatted_message(); | 14717 return formatted_message(); |
15588 } | 14718 } |
15589 String& result = String::Handle( | 14719 String& result = String::Handle( |
15590 Report::PrependSnippet(kind(), Script::Handle(script()), token_pos(), | 14720 Report::PrependSnippet(kind(), Script::Handle(script()), token_pos(), |
15591 report_after_token(), String::Handle(message()))); | 14721 report_after_token(), String::Handle(message()))); |
15592 // Prepend previous error message. | 14722 // Prepend previous error message. |
15593 const Error& prev_error = Error::Handle(previous_error()); | 14723 const Error& prev_error = Error::Handle(previous_error()); |
15594 if (!prev_error.IsNull()) { | 14724 if (!prev_error.IsNull()) { |
15595 result = String::Concat( | 14725 result = String::Concat( |
15596 String::Handle(String::New(prev_error.ToErrorCString())), result); | 14726 String::Handle(String::New(prev_error.ToErrorCString())), result); |
15597 } | 14727 } |
15598 set_formatted_message(result); | 14728 set_formatted_message(result); |
15599 return result.raw(); | 14729 return result.raw(); |
15600 } | 14730 } |
15601 | 14731 |
15602 | |
15603 const char* LanguageError::ToErrorCString() const { | 14732 const char* LanguageError::ToErrorCString() const { |
15604 Thread* thread = Thread::Current(); | 14733 Thread* thread = Thread::Current(); |
15605 NoReloadScope no_reload_scope(thread->isolate(), thread); | 14734 NoReloadScope no_reload_scope(thread->isolate(), thread); |
15606 const String& msg_str = String::Handle(FormatMessage()); | 14735 const String& msg_str = String::Handle(FormatMessage()); |
15607 return msg_str.ToCString(); | 14736 return msg_str.ToCString(); |
15608 } | 14737 } |
15609 | 14738 |
15610 | |
15611 const char* LanguageError::ToCString() const { | 14739 const char* LanguageError::ToCString() const { |
15612 return "LanguageError"; | 14740 return "LanguageError"; |
15613 } | 14741 } |
15614 | 14742 |
15615 | |
15616 RawUnhandledException* UnhandledException::New(const Instance& exception, | 14743 RawUnhandledException* UnhandledException::New(const Instance& exception, |
15617 const Instance& stacktrace, | 14744 const Instance& stacktrace, |
15618 Heap::Space space) { | 14745 Heap::Space space) { |
15619 ASSERT(Object::unhandled_exception_class() != Class::null()); | 14746 ASSERT(Object::unhandled_exception_class() != Class::null()); |
15620 UnhandledException& result = UnhandledException::Handle(); | 14747 UnhandledException& result = UnhandledException::Handle(); |
15621 { | 14748 { |
15622 RawObject* raw = | 14749 RawObject* raw = |
15623 Object::Allocate(UnhandledException::kClassId, | 14750 Object::Allocate(UnhandledException::kClassId, |
15624 UnhandledException::InstanceSize(), space); | 14751 UnhandledException::InstanceSize(), space); |
15625 NoSafepointScope no_safepoint; | 14752 NoSafepointScope no_safepoint; |
15626 result ^= raw; | 14753 result ^= raw; |
15627 } | 14754 } |
15628 result.set_exception(exception); | 14755 result.set_exception(exception); |
15629 result.set_stacktrace(stacktrace); | 14756 result.set_stacktrace(stacktrace); |
15630 return result.raw(); | 14757 return result.raw(); |
15631 } | 14758 } |
15632 | 14759 |
15633 | |
15634 RawUnhandledException* UnhandledException::New(Heap::Space space) { | 14760 RawUnhandledException* UnhandledException::New(Heap::Space space) { |
15635 ASSERT(Object::unhandled_exception_class() != Class::null()); | 14761 ASSERT(Object::unhandled_exception_class() != Class::null()); |
15636 UnhandledException& result = UnhandledException::Handle(); | 14762 UnhandledException& result = UnhandledException::Handle(); |
15637 { | 14763 { |
15638 RawObject* raw = | 14764 RawObject* raw = |
15639 Object::Allocate(UnhandledException::kClassId, | 14765 Object::Allocate(UnhandledException::kClassId, |
15640 UnhandledException::InstanceSize(), space); | 14766 UnhandledException::InstanceSize(), space); |
15641 NoSafepointScope no_safepoint; | 14767 NoSafepointScope no_safepoint; |
15642 result ^= raw; | 14768 result ^= raw; |
15643 } | 14769 } |
15644 result.set_exception(Object::null_instance()); | 14770 result.set_exception(Object::null_instance()); |
15645 result.set_stacktrace(StackTrace::Handle()); | 14771 result.set_stacktrace(StackTrace::Handle()); |
15646 return result.raw(); | 14772 return result.raw(); |
15647 } | 14773 } |
15648 | 14774 |
15649 | |
15650 void UnhandledException::set_exception(const Instance& exception) const { | 14775 void UnhandledException::set_exception(const Instance& exception) const { |
15651 StorePointer(&raw_ptr()->exception_, exception.raw()); | 14776 StorePointer(&raw_ptr()->exception_, exception.raw()); |
15652 } | 14777 } |
15653 | 14778 |
15654 | |
15655 void UnhandledException::set_stacktrace(const Instance& stacktrace) const { | 14779 void UnhandledException::set_stacktrace(const Instance& stacktrace) const { |
15656 StorePointer(&raw_ptr()->stacktrace_, stacktrace.raw()); | 14780 StorePointer(&raw_ptr()->stacktrace_, stacktrace.raw()); |
15657 } | 14781 } |
15658 | 14782 |
15659 | |
15660 const char* UnhandledException::ToErrorCString() const { | 14783 const char* UnhandledException::ToErrorCString() const { |
15661 Thread* thread = Thread::Current(); | 14784 Thread* thread = Thread::Current(); |
15662 Isolate* isolate = thread->isolate(); | 14785 Isolate* isolate = thread->isolate(); |
15663 NoReloadScope no_reload_scope(isolate, thread); | 14786 NoReloadScope no_reload_scope(isolate, thread); |
15664 HANDLESCOPE(thread); | 14787 HANDLESCOPE(thread); |
15665 Object& strtmp = Object::Handle(); | 14788 Object& strtmp = Object::Handle(); |
15666 const char* exc_str; | 14789 const char* exc_str; |
15667 if (exception() == isolate->object_store()->out_of_memory()) { | 14790 if (exception() == isolate->object_store()->out_of_memory()) { |
15668 exc_str = "Out of Memory"; | 14791 exc_str = "Out of Memory"; |
15669 } else if (exception() == isolate->object_store()->stack_overflow()) { | 14792 } else if (exception() == isolate->object_store()->stack_overflow()) { |
(...skipping 11 matching lines...) Expand all Loading... |
15681 strtmp = DartLibraryCalls::ToString(stack); | 14804 strtmp = DartLibraryCalls::ToString(stack); |
15682 const char* stack_str = | 14805 const char* stack_str = |
15683 "<Received error while converting stack trace to string>"; | 14806 "<Received error while converting stack trace to string>"; |
15684 if (!strtmp.IsError()) { | 14807 if (!strtmp.IsError()) { |
15685 stack_str = strtmp.ToCString(); | 14808 stack_str = strtmp.ToCString(); |
15686 } | 14809 } |
15687 return OS::SCreate(thread->zone(), "Unhandled exception:\n%s\n%s", exc_str, | 14810 return OS::SCreate(thread->zone(), "Unhandled exception:\n%s\n%s", exc_str, |
15688 stack_str); | 14811 stack_str); |
15689 } | 14812 } |
15690 | 14813 |
15691 | |
15692 const char* UnhandledException::ToCString() const { | 14814 const char* UnhandledException::ToCString() const { |
15693 return "UnhandledException"; | 14815 return "UnhandledException"; |
15694 } | 14816 } |
15695 | 14817 |
15696 | |
15697 RawUnwindError* UnwindError::New(const String& message, Heap::Space space) { | 14818 RawUnwindError* UnwindError::New(const String& message, Heap::Space space) { |
15698 ASSERT(Object::unwind_error_class() != Class::null()); | 14819 ASSERT(Object::unwind_error_class() != Class::null()); |
15699 UnwindError& result = UnwindError::Handle(); | 14820 UnwindError& result = UnwindError::Handle(); |
15700 { | 14821 { |
15701 RawObject* raw = Object::Allocate(UnwindError::kClassId, | 14822 RawObject* raw = Object::Allocate(UnwindError::kClassId, |
15702 UnwindError::InstanceSize(), space); | 14823 UnwindError::InstanceSize(), space); |
15703 NoSafepointScope no_safepoint; | 14824 NoSafepointScope no_safepoint; |
15704 result ^= raw; | 14825 result ^= raw; |
15705 } | 14826 } |
15706 result.set_message(message); | 14827 result.set_message(message); |
15707 result.set_is_user_initiated(false); | 14828 result.set_is_user_initiated(false); |
15708 return result.raw(); | 14829 return result.raw(); |
15709 } | 14830 } |
15710 | 14831 |
15711 | |
15712 void UnwindError::set_message(const String& message) const { | 14832 void UnwindError::set_message(const String& message) const { |
15713 StorePointer(&raw_ptr()->message_, message.raw()); | 14833 StorePointer(&raw_ptr()->message_, message.raw()); |
15714 } | 14834 } |
15715 | 14835 |
15716 | |
15717 void UnwindError::set_is_user_initiated(bool value) const { | 14836 void UnwindError::set_is_user_initiated(bool value) const { |
15718 StoreNonPointer(&raw_ptr()->is_user_initiated_, value); | 14837 StoreNonPointer(&raw_ptr()->is_user_initiated_, value); |
15719 } | 14838 } |
15720 | 14839 |
15721 | |
15722 const char* UnwindError::ToErrorCString() const { | 14840 const char* UnwindError::ToErrorCString() const { |
15723 const String& msg_str = String::Handle(message()); | 14841 const String& msg_str = String::Handle(message()); |
15724 return msg_str.ToCString(); | 14842 return msg_str.ToCString(); |
15725 } | 14843 } |
15726 | 14844 |
15727 | |
15728 const char* UnwindError::ToCString() const { | 14845 const char* UnwindError::ToCString() const { |
15729 return "UnwindError"; | 14846 return "UnwindError"; |
15730 } | 14847 } |
15731 | 14848 |
15732 | |
15733 RawObject* Instance::Evaluate(const Class& method_cls, | 14849 RawObject* Instance::Evaluate(const Class& method_cls, |
15734 const String& expr, | 14850 const String& expr, |
15735 const Array& param_names, | 14851 const Array& param_names, |
15736 const Array& param_values) const { | 14852 const Array& param_values) const { |
15737 const Function& eval_func = Function::Handle( | 14853 const Function& eval_func = Function::Handle( |
15738 Function::EvaluateHelper(method_cls, expr, param_names, false)); | 14854 Function::EvaluateHelper(method_cls, expr, param_names, false)); |
15739 const Array& args = Array::Handle(Array::New(1 + param_values.Length())); | 14855 const Array& args = Array::Handle(Array::New(1 + param_values.Length())); |
15740 PassiveObject& param = PassiveObject::Handle(); | 14856 PassiveObject& param = PassiveObject::Handle(); |
15741 args.SetAt(0, *this); | 14857 args.SetAt(0, *this); |
15742 for (intptr_t i = 0; i < param_values.Length(); i++) { | 14858 for (intptr_t i = 0; i < param_values.Length(); i++) { |
15743 param = param_values.At(i); | 14859 param = param_values.At(i); |
15744 args.SetAt(i + 1, param); | 14860 args.SetAt(i + 1, param); |
15745 } | 14861 } |
15746 return DartEntry::InvokeFunction(eval_func, args); | 14862 return DartEntry::InvokeFunction(eval_func, args); |
15747 } | 14863 } |
15748 | 14864 |
15749 | |
15750 RawObject* Instance::HashCode() const { | 14865 RawObject* Instance::HashCode() const { |
15751 // TODO(koda): Optimize for all builtin classes and all classes | 14866 // TODO(koda): Optimize for all builtin classes and all classes |
15752 // that do not override hashCode. | 14867 // that do not override hashCode. |
15753 return DartLibraryCalls::HashCode(*this); | 14868 return DartLibraryCalls::HashCode(*this); |
15754 } | 14869 } |
15755 | 14870 |
15756 | |
15757 bool Instance::CanonicalizeEquals(const Instance& other) const { | 14871 bool Instance::CanonicalizeEquals(const Instance& other) const { |
15758 if (this->raw() == other.raw()) { | 14872 if (this->raw() == other.raw()) { |
15759 return true; // "===". | 14873 return true; // "===". |
15760 } | 14874 } |
15761 | 14875 |
15762 if (other.IsNull() || (this->clazz() != other.clazz())) { | 14876 if (other.IsNull() || (this->clazz() != other.clazz())) { |
15763 return false; | 14877 return false; |
15764 } | 14878 } |
15765 | 14879 |
15766 { | 14880 { |
(...skipping 12 matching lines...) Expand all Loading... |
15779 offset += kWordSize) { | 14893 offset += kWordSize) { |
15780 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != | 14894 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != |
15781 (*reinterpret_cast<RawObject**>(other_addr + offset))) { | 14895 (*reinterpret_cast<RawObject**>(other_addr + offset))) { |
15782 return false; | 14896 return false; |
15783 } | 14897 } |
15784 } | 14898 } |
15785 } | 14899 } |
15786 return true; | 14900 return true; |
15787 } | 14901 } |
15788 | 14902 |
15789 | |
15790 uword Instance::ComputeCanonicalTableHash() const { | 14903 uword Instance::ComputeCanonicalTableHash() const { |
15791 ASSERT(!IsNull()); | 14904 ASSERT(!IsNull()); |
15792 NoSafepointScope no_safepoint; | 14905 NoSafepointScope no_safepoint; |
15793 const intptr_t instance_size = SizeFromClass(); | 14906 const intptr_t instance_size = SizeFromClass(); |
15794 ASSERT(instance_size != 0); | 14907 ASSERT(instance_size != 0); |
15795 uword hash = instance_size; | 14908 uword hash = instance_size; |
15796 uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); | 14909 uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); |
15797 for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; | 14910 for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; |
15798 offset += kWordSize) { | 14911 offset += kWordSize) { |
15799 uword value = reinterpret_cast<uword>( | 14912 uword value = reinterpret_cast<uword>( |
15800 *reinterpret_cast<RawObject**>(this_addr + offset)); | 14913 *reinterpret_cast<RawObject**>(this_addr + offset)); |
15801 hash = CombineHashes(hash, value); | 14914 hash = CombineHashes(hash, value); |
15802 } | 14915 } |
15803 return FinalizeHash(hash, (kBitsPerWord - 1)); | 14916 return FinalizeHash(hash, (kBitsPerWord - 1)); |
15804 } | 14917 } |
15805 | 14918 |
15806 | |
15807 #if defined(DEBUG) | 14919 #if defined(DEBUG) |
15808 class CheckForPointers : public ObjectPointerVisitor { | 14920 class CheckForPointers : public ObjectPointerVisitor { |
15809 public: | 14921 public: |
15810 explicit CheckForPointers(Isolate* isolate) | 14922 explicit CheckForPointers(Isolate* isolate) |
15811 : ObjectPointerVisitor(isolate), has_pointers_(false) {} | 14923 : ObjectPointerVisitor(isolate), has_pointers_(false) {} |
15812 | 14924 |
15813 bool has_pointers() const { return has_pointers_; } | 14925 bool has_pointers() const { return has_pointers_; } |
15814 | 14926 |
15815 void VisitPointers(RawObject** first, RawObject** last) { | 14927 void VisitPointers(RawObject** first, RawObject** last) { |
15816 if (first != last) { | 14928 if (first != last) { |
15817 has_pointers_ = true; | 14929 has_pointers_ = true; |
15818 } | 14930 } |
15819 } | 14931 } |
15820 | 14932 |
15821 private: | 14933 private: |
15822 bool has_pointers_; | 14934 bool has_pointers_; |
15823 | 14935 |
15824 DISALLOW_COPY_AND_ASSIGN(CheckForPointers); | 14936 DISALLOW_COPY_AND_ASSIGN(CheckForPointers); |
15825 }; | 14937 }; |
15826 #endif // DEBUG | 14938 #endif // DEBUG |
15827 | 14939 |
15828 | |
15829 bool Instance::CheckAndCanonicalizeFields(Thread* thread, | 14940 bool Instance::CheckAndCanonicalizeFields(Thread* thread, |
15830 const char** error_str) const { | 14941 const char** error_str) const { |
15831 if (GetClassId() >= kNumPredefinedCids) { | 14942 if (GetClassId() >= kNumPredefinedCids) { |
15832 // Iterate over all fields, canonicalize numbers and strings, expect all | 14943 // Iterate over all fields, canonicalize numbers and strings, expect all |
15833 // other instances to be canonical otherwise report error (return false). | 14944 // other instances to be canonical otherwise report error (return false). |
15834 Zone* zone = thread->zone(); | 14945 Zone* zone = thread->zone(); |
15835 Object& obj = Object::Handle(zone); | 14946 Object& obj = Object::Handle(zone); |
15836 const intptr_t instance_size = SizeFromClass(); | 14947 const intptr_t instance_size = SizeFromClass(); |
15837 ASSERT(instance_size != 0); | 14948 ASSERT(instance_size != 0); |
15838 for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; | 14949 for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; |
(...skipping 16 matching lines...) Expand all Loading... |
15855 #if defined(DEBUG) | 14966 #if defined(DEBUG) |
15856 // Make sure that we are not missing any fields. | 14967 // Make sure that we are not missing any fields. |
15857 CheckForPointers has_pointers(Isolate::Current()); | 14968 CheckForPointers has_pointers(Isolate::Current()); |
15858 this->raw()->VisitPointers(&has_pointers); | 14969 this->raw()->VisitPointers(&has_pointers); |
15859 ASSERT(!has_pointers.has_pointers()); | 14970 ASSERT(!has_pointers.has_pointers()); |
15860 #endif // DEBUG | 14971 #endif // DEBUG |
15861 } | 14972 } |
15862 return true; | 14973 return true; |
15863 } | 14974 } |
15864 | 14975 |
15865 | |
15866 RawInstance* Instance::CheckAndCanonicalize(Thread* thread, | 14976 RawInstance* Instance::CheckAndCanonicalize(Thread* thread, |
15867 const char** error_str) const { | 14977 const char** error_str) const { |
15868 ASSERT(!IsNull()); | 14978 ASSERT(!IsNull()); |
15869 if (this->IsCanonical()) { | 14979 if (this->IsCanonical()) { |
15870 return this->raw(); | 14980 return this->raw(); |
15871 } | 14981 } |
15872 if (!CheckAndCanonicalizeFields(thread, error_str)) { | 14982 if (!CheckAndCanonicalizeFields(thread, error_str)) { |
15873 return Instance::null(); | 14983 return Instance::null(); |
15874 } | 14984 } |
15875 Zone* zone = thread->zone(); | 14985 Zone* zone = thread->zone(); |
(...skipping 12 matching lines...) Expand all Loading... |
15888 result ^= Object::Clone(*this, Heap::kOld); | 14998 result ^= Object::Clone(*this, Heap::kOld); |
15889 } else { | 14999 } else { |
15890 result ^= this->raw(); | 15000 result ^= this->raw(); |
15891 } | 15001 } |
15892 ASSERT(result.IsOld()); | 15002 ASSERT(result.IsOld()); |
15893 result.SetCanonical(); | 15003 result.SetCanonical(); |
15894 return cls.InsertCanonicalConstant(zone, result); | 15004 return cls.InsertCanonicalConstant(zone, result); |
15895 } | 15005 } |
15896 } | 15006 } |
15897 | 15007 |
15898 | |
15899 #if defined(DEBUG) | 15008 #if defined(DEBUG) |
15900 bool Instance::CheckIsCanonical(Thread* thread) const { | 15009 bool Instance::CheckIsCanonical(Thread* thread) const { |
15901 Zone* zone = thread->zone(); | 15010 Zone* zone = thread->zone(); |
15902 Isolate* isolate = thread->isolate(); | 15011 Isolate* isolate = thread->isolate(); |
15903 Instance& result = Instance::Handle(zone); | 15012 Instance& result = Instance::Handle(zone); |
15904 const Class& cls = Class::Handle(zone, this->clazz()); | 15013 const Class& cls = Class::Handle(zone, this->clazz()); |
15905 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 15014 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
15906 result ^= cls.LookupCanonicalInstance(zone, *this); | 15015 result ^= cls.LookupCanonicalInstance(zone, *this); |
15907 return (result.raw() == this->raw()); | 15016 return (result.raw() == this->raw()); |
15908 } | 15017 } |
15909 #endif // DEBUG | 15018 #endif // DEBUG |
15910 | 15019 |
15911 | |
15912 RawAbstractType* Instance::GetType(Heap::Space space) const { | 15020 RawAbstractType* Instance::GetType(Heap::Space space) const { |
15913 if (IsNull()) { | 15021 if (IsNull()) { |
15914 return Type::NullType(); | 15022 return Type::NullType(); |
15915 } | 15023 } |
15916 const Class& cls = Class::Handle(clazz()); | 15024 const Class& cls = Class::Handle(clazz()); |
15917 if (cls.IsClosureClass()) { | 15025 if (cls.IsClosureClass()) { |
15918 const Function& signature = | 15026 const Function& signature = |
15919 Function::Handle(Closure::Cast(*this).function()); | 15027 Function::Handle(Closure::Cast(*this).function()); |
15920 Type& type = Type::Handle(signature.SignatureType()); | 15028 Type& type = Type::Handle(signature.SignatureType()); |
15921 if (!type.IsInstantiated()) { | 15029 if (!type.IsInstantiated()) { |
(...skipping 18 matching lines...) Expand all Loading... |
15940 if (cls.NumTypeArguments() > 0) { | 15048 if (cls.NumTypeArguments() > 0) { |
15941 type_arguments = GetTypeArguments(); | 15049 type_arguments = GetTypeArguments(); |
15942 } | 15050 } |
15943 type = Type::New(cls, type_arguments, TokenPosition::kNoSource, space); | 15051 type = Type::New(cls, type_arguments, TokenPosition::kNoSource, space); |
15944 type.SetIsFinalized(); | 15052 type.SetIsFinalized(); |
15945 type ^= type.Canonicalize(); | 15053 type ^= type.Canonicalize(); |
15946 } | 15054 } |
15947 return type.raw(); | 15055 return type.raw(); |
15948 } | 15056 } |
15949 | 15057 |
15950 | |
15951 RawTypeArguments* Instance::GetTypeArguments() const { | 15058 RawTypeArguments* Instance::GetTypeArguments() const { |
15952 const Class& cls = Class::Handle(clazz()); | 15059 const Class& cls = Class::Handle(clazz()); |
15953 intptr_t field_offset = cls.type_arguments_field_offset(); | 15060 intptr_t field_offset = cls.type_arguments_field_offset(); |
15954 ASSERT(field_offset != Class::kNoTypeArguments); | 15061 ASSERT(field_offset != Class::kNoTypeArguments); |
15955 TypeArguments& type_arguments = TypeArguments::Handle(); | 15062 TypeArguments& type_arguments = TypeArguments::Handle(); |
15956 type_arguments ^= *FieldAddrAtOffset(field_offset); | 15063 type_arguments ^= *FieldAddrAtOffset(field_offset); |
15957 return type_arguments.raw(); | 15064 return type_arguments.raw(); |
15958 } | 15065 } |
15959 | 15066 |
15960 | |
15961 void Instance::SetTypeArguments(const TypeArguments& value) const { | 15067 void Instance::SetTypeArguments(const TypeArguments& value) const { |
15962 ASSERT(value.IsNull() || value.IsCanonical()); | 15068 ASSERT(value.IsNull() || value.IsCanonical()); |
15963 const Class& cls = Class::Handle(clazz()); | 15069 const Class& cls = Class::Handle(clazz()); |
15964 intptr_t field_offset = cls.type_arguments_field_offset(); | 15070 intptr_t field_offset = cls.type_arguments_field_offset(); |
15965 ASSERT(field_offset != Class::kNoTypeArguments); | 15071 ASSERT(field_offset != Class::kNoTypeArguments); |
15966 SetFieldAtOffset(field_offset, value); | 15072 SetFieldAtOffset(field_offset, value); |
15967 } | 15073 } |
15968 | 15074 |
15969 | |
15970 bool Instance::IsInstanceOf( | 15075 bool Instance::IsInstanceOf( |
15971 const AbstractType& other, | 15076 const AbstractType& other, |
15972 const TypeArguments& other_instantiator_type_arguments, | 15077 const TypeArguments& other_instantiator_type_arguments, |
15973 const TypeArguments& other_function_type_arguments, | 15078 const TypeArguments& other_function_type_arguments, |
15974 Error* bound_error) const { | 15079 Error* bound_error) const { |
15975 ASSERT(other.IsFinalized()); | 15080 ASSERT(other.IsFinalized()); |
15976 ASSERT(!other.IsDynamicType()); | 15081 ASSERT(!other.IsDynamicType()); |
15977 ASSERT(!other.IsTypeRef()); // Must be dereferenced at compile time. | 15082 ASSERT(!other.IsTypeRef()); // Must be dereferenced at compile time. |
15978 ASSERT(!other.IsMalformed()); | 15083 ASSERT(!other.IsMalformed()); |
15979 ASSERT(!other.IsMalbounded()); | 15084 ASSERT(!other.IsMalbounded()); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16094 if (IsNull()) { | 15199 if (IsNull()) { |
16095 ASSERT(cls.IsNullClass()); | 15200 ASSERT(cls.IsNullClass()); |
16096 // As of Dart 1.5, the null instance and Null type are handled differently. | 15201 // As of Dart 1.5, the null instance and Null type are handled differently. |
16097 // We already checked other for dynamic and void. | 15202 // We already checked other for dynamic and void. |
16098 return other_class.IsNullClass() || other_class.IsObjectClass(); | 15203 return other_class.IsNullClass() || other_class.IsObjectClass(); |
16099 } | 15204 } |
16100 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 15205 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
16101 bound_error, NULL, Heap::kOld); | 15206 bound_error, NULL, Heap::kOld); |
16102 } | 15207 } |
16103 | 15208 |
16104 | |
16105 bool Instance::OperatorEquals(const Instance& other) const { | 15209 bool Instance::OperatorEquals(const Instance& other) const { |
16106 // TODO(koda): Optimize for all builtin classes and all classes | 15210 // TODO(koda): Optimize for all builtin classes and all classes |
16107 // that do not override operator==. | 15211 // that do not override operator==. |
16108 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 15212 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |
16109 } | 15213 } |
16110 | 15214 |
16111 | |
16112 bool Instance::IsIdenticalTo(const Instance& other) const { | 15215 bool Instance::IsIdenticalTo(const Instance& other) const { |
16113 if (raw() == other.raw()) return true; | 15216 if (raw() == other.raw()) return true; |
16114 if (IsInteger() && other.IsInteger()) { | 15217 if (IsInteger() && other.IsInteger()) { |
16115 return Integer::Cast(*this).Equals(other); | 15218 return Integer::Cast(*this).Equals(other); |
16116 } | 15219 } |
16117 if (IsDouble() && other.IsDouble()) { | 15220 if (IsDouble() && other.IsDouble()) { |
16118 double other_value = Double::Cast(other).value(); | 15221 double other_value = Double::Cast(other).value(); |
16119 return Double::Cast(*this).BitwiseEqualsToDouble(other_value); | 15222 return Double::Cast(*this).BitwiseEqualsToDouble(other_value); |
16120 } | 15223 } |
16121 return false; | 15224 return false; |
16122 } | 15225 } |
16123 | 15226 |
16124 | |
16125 intptr_t* Instance::NativeFieldsDataAddr() const { | 15227 intptr_t* Instance::NativeFieldsDataAddr() const { |
16126 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); | 15228 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |
16127 RawTypedData* native_fields = | 15229 RawTypedData* native_fields = |
16128 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); | 15230 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); |
16129 if (native_fields == TypedData::null()) { | 15231 if (native_fields == TypedData::null()) { |
16130 return NULL; | 15232 return NULL; |
16131 } | 15233 } |
16132 return reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); | 15234 return reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); |
16133 } | 15235 } |
16134 | 15236 |
16135 | |
16136 void Instance::SetNativeField(int index, intptr_t value) const { | 15237 void Instance::SetNativeField(int index, intptr_t value) const { |
16137 ASSERT(IsValidNativeIndex(index)); | 15238 ASSERT(IsValidNativeIndex(index)); |
16138 Object& native_fields = Object::Handle(*NativeFieldsAddr()); | 15239 Object& native_fields = Object::Handle(*NativeFieldsAddr()); |
16139 if (native_fields.IsNull()) { | 15240 if (native_fields.IsNull()) { |
16140 // Allocate backing storage for the native fields. | 15241 // Allocate backing storage for the native fields. |
16141 native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); | 15242 native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); |
16142 StorePointer(NativeFieldsAddr(), native_fields.raw()); | 15243 StorePointer(NativeFieldsAddr(), native_fields.raw()); |
16143 } | 15244 } |
16144 intptr_t byte_offset = index * sizeof(intptr_t); | 15245 intptr_t byte_offset = index * sizeof(intptr_t); |
16145 TypedData::Cast(native_fields).SetIntPtr(byte_offset, value); | 15246 TypedData::Cast(native_fields).SetIntPtr(byte_offset, value); |
16146 } | 15247 } |
16147 | 15248 |
16148 | |
16149 void Instance::SetNativeFields(uint16_t num_native_fields, | 15249 void Instance::SetNativeFields(uint16_t num_native_fields, |
16150 const intptr_t* field_values) const { | 15250 const intptr_t* field_values) const { |
16151 ASSERT(num_native_fields == NumNativeFields()); | 15251 ASSERT(num_native_fields == NumNativeFields()); |
16152 ASSERT(field_values != NULL); | 15252 ASSERT(field_values != NULL); |
16153 Object& native_fields = Object::Handle(*NativeFieldsAddr()); | 15253 Object& native_fields = Object::Handle(*NativeFieldsAddr()); |
16154 if (native_fields.IsNull()) { | 15254 if (native_fields.IsNull()) { |
16155 // Allocate backing storage for the native fields. | 15255 // Allocate backing storage for the native fields. |
16156 native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); | 15256 native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); |
16157 StorePointer(NativeFieldsAddr(), native_fields.raw()); | 15257 StorePointer(NativeFieldsAddr(), native_fields.raw()); |
16158 } | 15258 } |
16159 for (uint16_t i = 0; i < num_native_fields; i++) { | 15259 for (uint16_t i = 0; i < num_native_fields; i++) { |
16160 intptr_t byte_offset = i * sizeof(intptr_t); | 15260 intptr_t byte_offset = i * sizeof(intptr_t); |
16161 TypedData::Cast(native_fields).SetIntPtr(byte_offset, field_values[i]); | 15261 TypedData::Cast(native_fields).SetIntPtr(byte_offset, field_values[i]); |
16162 } | 15262 } |
16163 } | 15263 } |
16164 | 15264 |
16165 | |
16166 bool Instance::IsCallable(Function* function) const { | 15265 bool Instance::IsCallable(Function* function) const { |
16167 Class& cls = Class::Handle(clazz()); | 15266 Class& cls = Class::Handle(clazz()); |
16168 if (cls.IsClosureClass()) { | 15267 if (cls.IsClosureClass()) { |
16169 if (function != NULL) { | 15268 if (function != NULL) { |
16170 *function = Closure::Cast(*this).function(); | 15269 *function = Closure::Cast(*this).function(); |
16171 } | 15270 } |
16172 return true; | 15271 return true; |
16173 } | 15272 } |
16174 // Try to resolve a "call" method. | 15273 // Try to resolve a "call" method. |
16175 Function& call_function = Function::Handle(); | 15274 Function& call_function = Function::Handle(); |
16176 do { | 15275 do { |
16177 call_function = cls.LookupDynamicFunction(Symbols::Call()); | 15276 call_function = cls.LookupDynamicFunction(Symbols::Call()); |
16178 if (!call_function.IsNull()) { | 15277 if (!call_function.IsNull()) { |
16179 if (function != NULL) { | 15278 if (function != NULL) { |
16180 *function = call_function.raw(); | 15279 *function = call_function.raw(); |
16181 } | 15280 } |
16182 return true; | 15281 return true; |
16183 } | 15282 } |
16184 cls = cls.SuperClass(); | 15283 cls = cls.SuperClass(); |
16185 } while (!cls.IsNull()); | 15284 } while (!cls.IsNull()); |
16186 return false; | 15285 return false; |
16187 } | 15286 } |
16188 | 15287 |
16189 | |
16190 RawInstance* Instance::New(const Class& cls, Heap::Space space) { | 15288 RawInstance* Instance::New(const Class& cls, Heap::Space space) { |
16191 Thread* thread = Thread::Current(); | 15289 Thread* thread = Thread::Current(); |
16192 if (cls.EnsureIsFinalized(thread) != Error::null()) { | 15290 if (cls.EnsureIsFinalized(thread) != Error::null()) { |
16193 return Instance::null(); | 15291 return Instance::null(); |
16194 } | 15292 } |
16195 intptr_t instance_size = cls.instance_size(); | 15293 intptr_t instance_size = cls.instance_size(); |
16196 ASSERT(instance_size > 0); | 15294 ASSERT(instance_size > 0); |
16197 RawObject* raw = Object::Allocate(cls.id(), instance_size, space); | 15295 RawObject* raw = Object::Allocate(cls.id(), instance_size, space); |
16198 return reinterpret_cast<RawInstance*>(raw); | 15296 return reinterpret_cast<RawInstance*>(raw); |
16199 } | 15297 } |
16200 | 15298 |
16201 | |
16202 bool Instance::IsValidFieldOffset(intptr_t offset) const { | 15299 bool Instance::IsValidFieldOffset(intptr_t offset) const { |
16203 Thread* thread = Thread::Current(); | 15300 Thread* thread = Thread::Current(); |
16204 REUSABLE_CLASS_HANDLESCOPE(thread); | 15301 REUSABLE_CLASS_HANDLESCOPE(thread); |
16205 Class& cls = thread->ClassHandle(); | 15302 Class& cls = thread->ClassHandle(); |
16206 cls = clazz(); | 15303 cls = clazz(); |
16207 return (offset >= 0 && offset <= (cls.instance_size() - kWordSize)); | 15304 return (offset >= 0 && offset <= (cls.instance_size() - kWordSize)); |
16208 } | 15305 } |
16209 | 15306 |
16210 | |
16211 intptr_t Instance::ElementSizeFor(intptr_t cid) { | 15307 intptr_t Instance::ElementSizeFor(intptr_t cid) { |
16212 if (RawObject::IsExternalTypedDataClassId(cid)) { | 15308 if (RawObject::IsExternalTypedDataClassId(cid)) { |
16213 return ExternalTypedData::ElementSizeInBytes(cid); | 15309 return ExternalTypedData::ElementSizeInBytes(cid); |
16214 } else if (RawObject::IsTypedDataClassId(cid)) { | 15310 } else if (RawObject::IsTypedDataClassId(cid)) { |
16215 return TypedData::ElementSizeInBytes(cid); | 15311 return TypedData::ElementSizeInBytes(cid); |
16216 } | 15312 } |
16217 switch (cid) { | 15313 switch (cid) { |
16218 case kArrayCid: | 15314 case kArrayCid: |
16219 case kImmutableArrayCid: | 15315 case kImmutableArrayCid: |
16220 return Array::kBytesPerElement; | 15316 return Array::kBytesPerElement; |
16221 case kOneByteStringCid: | 15317 case kOneByteStringCid: |
16222 return OneByteString::kBytesPerElement; | 15318 return OneByteString::kBytesPerElement; |
16223 case kTwoByteStringCid: | 15319 case kTwoByteStringCid: |
16224 return TwoByteString::kBytesPerElement; | 15320 return TwoByteString::kBytesPerElement; |
16225 case kExternalOneByteStringCid: | 15321 case kExternalOneByteStringCid: |
16226 return ExternalOneByteString::kBytesPerElement; | 15322 return ExternalOneByteString::kBytesPerElement; |
16227 case kExternalTwoByteStringCid: | 15323 case kExternalTwoByteStringCid: |
16228 return ExternalTwoByteString::kBytesPerElement; | 15324 return ExternalTwoByteString::kBytesPerElement; |
16229 default: | 15325 default: |
16230 UNIMPLEMENTED(); | 15326 UNIMPLEMENTED(); |
16231 return 0; | 15327 return 0; |
16232 } | 15328 } |
16233 } | 15329 } |
16234 | 15330 |
16235 | |
16236 intptr_t Instance::DataOffsetFor(intptr_t cid) { | 15331 intptr_t Instance::DataOffsetFor(intptr_t cid) { |
16237 if (RawObject::IsExternalTypedDataClassId(cid) || | 15332 if (RawObject::IsExternalTypedDataClassId(cid) || |
16238 RawObject::IsExternalStringClassId(cid)) { | 15333 RawObject::IsExternalStringClassId(cid)) { |
16239 // Elements start at offset 0 of the external data. | 15334 // Elements start at offset 0 of the external data. |
16240 return 0; | 15335 return 0; |
16241 } | 15336 } |
16242 if (RawObject::IsTypedDataClassId(cid)) { | 15337 if (RawObject::IsTypedDataClassId(cid)) { |
16243 return TypedData::data_offset(); | 15338 return TypedData::data_offset(); |
16244 } | 15339 } |
16245 switch (cid) { | 15340 switch (cid) { |
16246 case kArrayCid: | 15341 case kArrayCid: |
16247 case kImmutableArrayCid: | 15342 case kImmutableArrayCid: |
16248 return Array::data_offset(); | 15343 return Array::data_offset(); |
16249 case kOneByteStringCid: | 15344 case kOneByteStringCid: |
16250 return OneByteString::data_offset(); | 15345 return OneByteString::data_offset(); |
16251 case kTwoByteStringCid: | 15346 case kTwoByteStringCid: |
16252 return TwoByteString::data_offset(); | 15347 return TwoByteString::data_offset(); |
16253 default: | 15348 default: |
16254 UNIMPLEMENTED(); | 15349 UNIMPLEMENTED(); |
16255 return Array::data_offset(); | 15350 return Array::data_offset(); |
16256 } | 15351 } |
16257 } | 15352 } |
16258 | 15353 |
16259 | |
16260 const char* Instance::ToCString() const { | 15354 const char* Instance::ToCString() const { |
16261 if (IsNull()) { | 15355 if (IsNull()) { |
16262 return "null"; | 15356 return "null"; |
16263 } else if (raw() == Object::sentinel().raw()) { | 15357 } else if (raw() == Object::sentinel().raw()) { |
16264 return "sentinel"; | 15358 return "sentinel"; |
16265 } else if (raw() == Object::transition_sentinel().raw()) { | 15359 } else if (raw() == Object::transition_sentinel().raw()) { |
16266 return "transition_sentinel"; | 15360 return "transition_sentinel"; |
16267 } else if (raw() == Object::unknown_constant().raw()) { | 15361 } else if (raw() == Object::unknown_constant().raw()) { |
16268 return "unknown_constant"; | 15362 return "unknown_constant"; |
16269 } else if (raw() == Object::non_constant().raw()) { | 15363 } else if (raw() == Object::non_constant().raw()) { |
(...skipping 12 matching lines...) Expand all Loading... |
16282 type_arguments = GetTypeArguments(); | 15376 type_arguments = GetTypeArguments(); |
16283 } | 15377 } |
16284 const Type& type = | 15378 const Type& type = |
16285 Type::Handle(Type::New(cls, type_arguments, TokenPosition::kNoSource)); | 15379 Type::Handle(Type::New(cls, type_arguments, TokenPosition::kNoSource)); |
16286 const String& type_name = String::Handle(type.UserVisibleName()); | 15380 const String& type_name = String::Handle(type.UserVisibleName()); |
16287 return OS::SCreate(Thread::Current()->zone(), "Instance of '%s'", | 15381 return OS::SCreate(Thread::Current()->zone(), "Instance of '%s'", |
16288 type_name.ToCString()); | 15382 type_name.ToCString()); |
16289 } | 15383 } |
16290 } | 15384 } |
16291 | 15385 |
16292 | |
16293 bool AbstractType::IsResolved() const { | 15386 bool AbstractType::IsResolved() const { |
16294 // AbstractType is an abstract class. | 15387 // AbstractType is an abstract class. |
16295 UNREACHABLE(); | 15388 UNREACHABLE(); |
16296 return false; | 15389 return false; |
16297 } | 15390 } |
16298 | 15391 |
16299 | |
16300 void AbstractType::SetIsResolved() const { | 15392 void AbstractType::SetIsResolved() const { |
16301 // AbstractType is an abstract class. | 15393 // AbstractType is an abstract class. |
16302 UNREACHABLE(); | 15394 UNREACHABLE(); |
16303 } | 15395 } |
16304 | 15396 |
16305 | |
16306 bool AbstractType::HasResolvedTypeClass() const { | 15397 bool AbstractType::HasResolvedTypeClass() const { |
16307 // AbstractType is an abstract class. | 15398 // AbstractType is an abstract class. |
16308 UNREACHABLE(); | 15399 UNREACHABLE(); |
16309 return false; | 15400 return false; |
16310 } | 15401 } |
16311 | 15402 |
16312 | |
16313 classid_t AbstractType::type_class_id() const { | 15403 classid_t AbstractType::type_class_id() const { |
16314 // AbstractType is an abstract class. | 15404 // AbstractType is an abstract class. |
16315 UNREACHABLE(); | 15405 UNREACHABLE(); |
16316 return kIllegalCid; | 15406 return kIllegalCid; |
16317 } | 15407 } |
16318 | 15408 |
16319 | |
16320 RawClass* AbstractType::type_class() const { | 15409 RawClass* AbstractType::type_class() const { |
16321 // AbstractType is an abstract class. | 15410 // AbstractType is an abstract class. |
16322 UNREACHABLE(); | 15411 UNREACHABLE(); |
16323 return Class::null(); | 15412 return Class::null(); |
16324 } | 15413 } |
16325 | 15414 |
16326 | |
16327 RawUnresolvedClass* AbstractType::unresolved_class() const { | 15415 RawUnresolvedClass* AbstractType::unresolved_class() const { |
16328 // AbstractType is an abstract class. | 15416 // AbstractType is an abstract class. |
16329 UNREACHABLE(); | 15417 UNREACHABLE(); |
16330 return UnresolvedClass::null(); | 15418 return UnresolvedClass::null(); |
16331 } | 15419 } |
16332 | 15420 |
16333 | |
16334 RawTypeArguments* AbstractType::arguments() const { | 15421 RawTypeArguments* AbstractType::arguments() const { |
16335 // AbstractType is an abstract class. | 15422 // AbstractType is an abstract class. |
16336 UNREACHABLE(); | 15423 UNREACHABLE(); |
16337 return NULL; | 15424 return NULL; |
16338 } | 15425 } |
16339 | 15426 |
16340 | |
16341 void AbstractType::set_arguments(const TypeArguments& value) const { | 15427 void AbstractType::set_arguments(const TypeArguments& value) const { |
16342 // AbstractType is an abstract class. | 15428 // AbstractType is an abstract class. |
16343 UNREACHABLE(); | 15429 UNREACHABLE(); |
16344 } | 15430 } |
16345 | 15431 |
16346 TokenPosition AbstractType::token_pos() const { | 15432 TokenPosition AbstractType::token_pos() const { |
16347 // AbstractType is an abstract class. | 15433 // AbstractType is an abstract class. |
16348 UNREACHABLE(); | 15434 UNREACHABLE(); |
16349 return TokenPosition::kNoSource; | 15435 return TokenPosition::kNoSource; |
16350 } | 15436 } |
16351 | 15437 |
16352 | |
16353 bool AbstractType::IsInstantiated(Genericity genericity, | 15438 bool AbstractType::IsInstantiated(Genericity genericity, |
16354 intptr_t num_free_fun_type_params, | 15439 intptr_t num_free_fun_type_params, |
16355 TrailPtr trail) const { | 15440 TrailPtr trail) const { |
16356 // AbstractType is an abstract class. | 15441 // AbstractType is an abstract class. |
16357 UNREACHABLE(); | 15442 UNREACHABLE(); |
16358 return false; | 15443 return false; |
16359 } | 15444 } |
16360 | 15445 |
16361 | |
16362 bool AbstractType::IsFinalized() const { | 15446 bool AbstractType::IsFinalized() const { |
16363 // AbstractType is an abstract class. | 15447 // AbstractType is an abstract class. |
16364 UNREACHABLE(); | 15448 UNREACHABLE(); |
16365 return false; | 15449 return false; |
16366 } | 15450 } |
16367 | 15451 |
16368 | |
16369 void AbstractType::SetIsFinalized() const { | 15452 void AbstractType::SetIsFinalized() const { |
16370 // AbstractType is an abstract class. | 15453 // AbstractType is an abstract class. |
16371 UNREACHABLE(); | 15454 UNREACHABLE(); |
16372 } | 15455 } |
16373 | 15456 |
16374 | |
16375 bool AbstractType::IsBeingFinalized() const { | 15457 bool AbstractType::IsBeingFinalized() const { |
16376 // AbstractType is an abstract class. | 15458 // AbstractType is an abstract class. |
16377 UNREACHABLE(); | 15459 UNREACHABLE(); |
16378 return false; | 15460 return false; |
16379 } | 15461 } |
16380 | 15462 |
16381 | |
16382 void AbstractType::SetIsBeingFinalized() const { | 15463 void AbstractType::SetIsBeingFinalized() const { |
16383 // AbstractType is an abstract class. | 15464 // AbstractType is an abstract class. |
16384 UNREACHABLE(); | 15465 UNREACHABLE(); |
16385 } | 15466 } |
16386 | 15467 |
16387 | |
16388 bool AbstractType::IsMalformed() const { | 15468 bool AbstractType::IsMalformed() const { |
16389 // AbstractType is an abstract class. | 15469 // AbstractType is an abstract class. |
16390 UNREACHABLE(); | 15470 UNREACHABLE(); |
16391 return false; | 15471 return false; |
16392 } | 15472 } |
16393 | 15473 |
16394 | |
16395 bool AbstractType::IsMalbounded() const { | 15474 bool AbstractType::IsMalbounded() const { |
16396 // AbstractType is an abstract class. | 15475 // AbstractType is an abstract class. |
16397 UNREACHABLE(); | 15476 UNREACHABLE(); |
16398 return false; | 15477 return false; |
16399 } | 15478 } |
16400 | 15479 |
16401 | |
16402 bool AbstractType::IsMalformedOrMalbounded() const { | 15480 bool AbstractType::IsMalformedOrMalbounded() const { |
16403 // AbstractType is an abstract class. | 15481 // AbstractType is an abstract class. |
16404 UNREACHABLE(); | 15482 UNREACHABLE(); |
16405 return false; | 15483 return false; |
16406 } | 15484 } |
16407 | 15485 |
16408 | |
16409 RawLanguageError* AbstractType::error() const { | 15486 RawLanguageError* AbstractType::error() const { |
16410 // AbstractType is an abstract class. | 15487 // AbstractType is an abstract class. |
16411 UNREACHABLE(); | 15488 UNREACHABLE(); |
16412 return LanguageError::null(); | 15489 return LanguageError::null(); |
16413 } | 15490 } |
16414 | 15491 |
16415 | |
16416 void AbstractType::set_error(const LanguageError& value) const { | 15492 void AbstractType::set_error(const LanguageError& value) const { |
16417 // AbstractType is an abstract class. | 15493 // AbstractType is an abstract class. |
16418 UNREACHABLE(); | 15494 UNREACHABLE(); |
16419 } | 15495 } |
16420 | 15496 |
16421 | |
16422 bool AbstractType::IsEquivalent(const Instance& other, TrailPtr trail) const { | 15497 bool AbstractType::IsEquivalent(const Instance& other, TrailPtr trail) const { |
16423 // AbstractType is an abstract class. | 15498 // AbstractType is an abstract class. |
16424 UNREACHABLE(); | 15499 UNREACHABLE(); |
16425 return false; | 15500 return false; |
16426 } | 15501 } |
16427 | 15502 |
16428 | |
16429 bool AbstractType::IsRecursive() const { | 15503 bool AbstractType::IsRecursive() const { |
16430 // AbstractType is an abstract class. | 15504 // AbstractType is an abstract class. |
16431 UNREACHABLE(); | 15505 UNREACHABLE(); |
16432 return false; | 15506 return false; |
16433 } | 15507 } |
16434 | 15508 |
16435 | |
16436 RawAbstractType* AbstractType::InstantiateFrom( | 15509 RawAbstractType* AbstractType::InstantiateFrom( |
16437 const TypeArguments& instantiator_type_arguments, | 15510 const TypeArguments& instantiator_type_arguments, |
16438 const TypeArguments& function_type_arguments, | 15511 const TypeArguments& function_type_arguments, |
16439 Error* bound_error, | 15512 Error* bound_error, |
16440 TrailPtr instantiation_trail, | 15513 TrailPtr instantiation_trail, |
16441 TrailPtr bound_trail, | 15514 TrailPtr bound_trail, |
16442 Heap::Space space) const { | 15515 Heap::Space space) const { |
16443 // AbstractType is an abstract class. | 15516 // AbstractType is an abstract class. |
16444 UNREACHABLE(); | 15517 UNREACHABLE(); |
16445 return NULL; | 15518 return NULL; |
16446 } | 15519 } |
16447 | 15520 |
16448 | |
16449 RawAbstractType* AbstractType::CloneUnfinalized() const { | 15521 RawAbstractType* AbstractType::CloneUnfinalized() const { |
16450 // AbstractType is an abstract class. | 15522 // AbstractType is an abstract class. |
16451 UNREACHABLE(); | 15523 UNREACHABLE(); |
16452 return NULL; | 15524 return NULL; |
16453 } | 15525 } |
16454 | 15526 |
16455 | |
16456 RawAbstractType* AbstractType::CloneUninstantiated(const Class& new_owner, | 15527 RawAbstractType* AbstractType::CloneUninstantiated(const Class& new_owner, |
16457 TrailPtr trail) const { | 15528 TrailPtr trail) const { |
16458 // AbstractType is an abstract class. | 15529 // AbstractType is an abstract class. |
16459 UNREACHABLE(); | 15530 UNREACHABLE(); |
16460 return NULL; | 15531 return NULL; |
16461 } | 15532 } |
16462 | 15533 |
16463 | |
16464 RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const { | 15534 RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const { |
16465 // AbstractType is an abstract class. | 15535 // AbstractType is an abstract class. |
16466 UNREACHABLE(); | 15536 UNREACHABLE(); |
16467 return NULL; | 15537 return NULL; |
16468 } | 15538 } |
16469 | 15539 |
16470 | |
16471 RawString* AbstractType::EnumerateURIs() const { | 15540 RawString* AbstractType::EnumerateURIs() const { |
16472 // AbstractType is an abstract class. | 15541 // AbstractType is an abstract class. |
16473 UNREACHABLE(); | 15542 UNREACHABLE(); |
16474 return NULL; | 15543 return NULL; |
16475 } | 15544 } |
16476 | 15545 |
16477 | |
16478 RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const { | 15546 RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const { |
16479 if (trail == NULL) { | 15547 if (trail == NULL) { |
16480 return AbstractType::null(); | 15548 return AbstractType::null(); |
16481 } | 15549 } |
16482 const intptr_t len = trail->length(); | 15550 const intptr_t len = trail->length(); |
16483 ASSERT((len % 2) == 0); | 15551 ASSERT((len % 2) == 0); |
16484 for (intptr_t i = 0; i < len; i += 2) { | 15552 for (intptr_t i = 0; i < len; i += 2) { |
16485 ASSERT(trail->At(i).IsZoneHandle()); | 15553 ASSERT(trail->At(i).IsZoneHandle()); |
16486 ASSERT(trail->At(i + 1).IsZoneHandle()); | 15554 ASSERT(trail->At(i + 1).IsZoneHandle()); |
16487 if (trail->At(i).raw() == this->raw()) { | 15555 if (trail->At(i).raw() == this->raw()) { |
16488 ASSERT(!trail->At(i + 1).IsNull()); | 15556 ASSERT(!trail->At(i + 1).IsNull()); |
16489 return trail->At(i + 1).raw(); | 15557 return trail->At(i + 1).raw(); |
16490 } | 15558 } |
16491 } | 15559 } |
16492 return AbstractType::null(); | 15560 return AbstractType::null(); |
16493 } | 15561 } |
16494 | 15562 |
16495 | |
16496 void AbstractType::AddOnlyBuddyToTrail(TrailPtr* trail, | 15563 void AbstractType::AddOnlyBuddyToTrail(TrailPtr* trail, |
16497 const AbstractType& buddy) const { | 15564 const AbstractType& buddy) const { |
16498 if (*trail == NULL) { | 15565 if (*trail == NULL) { |
16499 *trail = new Trail(Thread::Current()->zone(), 4); | 15566 *trail = new Trail(Thread::Current()->zone(), 4); |
16500 } else { | 15567 } else { |
16501 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); | 15568 ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); |
16502 } | 15569 } |
16503 (*trail)->Add(*this); | 15570 (*trail)->Add(*this); |
16504 (*trail)->Add(buddy); | 15571 (*trail)->Add(buddy); |
16505 } | 15572 } |
16506 | 15573 |
16507 | |
16508 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { | 15574 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { |
16509 if (*trail == NULL) { | 15575 if (*trail == NULL) { |
16510 *trail = new Trail(Thread::Current()->zone(), 4); | 15576 *trail = new Trail(Thread::Current()->zone(), 4); |
16511 } else { | 15577 } else { |
16512 const intptr_t len = (*trail)->length(); | 15578 const intptr_t len = (*trail)->length(); |
16513 for (intptr_t i = 0; i < len; i++) { | 15579 for (intptr_t i = 0; i < len; i++) { |
16514 if ((*trail)->At(i).raw() == this->raw()) { | 15580 if ((*trail)->At(i).raw() == this->raw()) { |
16515 return true; | 15581 return true; |
16516 } | 15582 } |
16517 } | 15583 } |
16518 } | 15584 } |
16519 (*trail)->Add(*this); | 15585 (*trail)->Add(*this); |
16520 return false; | 15586 return false; |
16521 } | 15587 } |
16522 | 15588 |
16523 | |
16524 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, | 15589 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, |
16525 const AbstractType& buddy) const { | 15590 const AbstractType& buddy) const { |
16526 if (*trail == NULL) { | 15591 if (*trail == NULL) { |
16527 *trail = new Trail(Thread::Current()->zone(), 4); | 15592 *trail = new Trail(Thread::Current()->zone(), 4); |
16528 } else { | 15593 } else { |
16529 const intptr_t len = (*trail)->length(); | 15594 const intptr_t len = (*trail)->length(); |
16530 ASSERT((len % 2) == 0); | 15595 ASSERT((len % 2) == 0); |
16531 const bool this_is_typeref = IsTypeRef(); | 15596 const bool this_is_typeref = IsTypeRef(); |
16532 const bool buddy_is_typeref = buddy.IsTypeRef(); | 15597 const bool buddy_is_typeref = buddy.IsTypeRef(); |
16533 // Note that at least one of 'this' and 'buddy' should be a typeref, with | 15598 // Note that at least one of 'this' and 'buddy' should be a typeref, with |
16534 // one exception, when the class of the 'this' type implements the 'call' | 15599 // one exception, when the class of the 'this' type implements the 'call' |
16535 // method, thereby possibly creating a recursive type (see regress_29405). | 15600 // method, thereby possibly creating a recursive type (see regress_29405). |
16536 for (intptr_t i = 0; i < len; i += 2) { | 15601 for (intptr_t i = 0; i < len; i += 2) { |
16537 if ((((*trail)->At(i).raw() == this->raw()) || | 15602 if ((((*trail)->At(i).raw() == this->raw()) || |
16538 (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && | 15603 (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && |
16539 (((*trail)->At(i + 1).raw() == buddy.raw()) || | 15604 (((*trail)->At(i + 1).raw() == buddy.raw()) || |
16540 (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { | 15605 (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { |
16541 return true; | 15606 return true; |
16542 } | 15607 } |
16543 } | 15608 } |
16544 } | 15609 } |
16545 (*trail)->Add(*this); | 15610 (*trail)->Add(*this); |
16546 (*trail)->Add(buddy); | 15611 (*trail)->Add(buddy); |
16547 return false; | 15612 return false; |
16548 } | 15613 } |
16549 | 15614 |
16550 | |
16551 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 15615 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
16552 ASSERT(name_visibility != kScrubbedName); | 15616 ASSERT(name_visibility != kScrubbedName); |
16553 Thread* thread = Thread::Current(); | 15617 Thread* thread = Thread::Current(); |
16554 Zone* zone = thread->zone(); | 15618 Zone* zone = thread->zone(); |
16555 if (IsBoundedType()) { | 15619 if (IsBoundedType()) { |
16556 const AbstractType& type = | 15620 const AbstractType& type = |
16557 AbstractType::Handle(zone, BoundedType::Cast(*this).type()); | 15621 AbstractType::Handle(zone, BoundedType::Cast(*this).type()); |
16558 if (name_visibility == kUserVisibleName) { | 15622 if (name_visibility == kUserVisibleName) { |
16559 return type.BuildName(kUserVisibleName); | 15623 return type.BuildName(kUserVisibleName); |
16560 } | 15624 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16662 zone, args.SubvectorName(first_type_param_index, num_type_params, | 15726 zone, args.SubvectorName(first_type_param_index, num_type_params, |
16663 name_visibility)); | 15727 name_visibility)); |
16664 pieces.Add(args_name); | 15728 pieces.Add(args_name); |
16665 } | 15729 } |
16666 // The name is only used for type checking and debugging purposes. | 15730 // The name is only used for type checking and debugging purposes. |
16667 // Unless profiling data shows otherwise, it is not worth caching the name in | 15731 // Unless profiling data shows otherwise, it is not worth caching the name in |
16668 // the type. | 15732 // the type. |
16669 return Symbols::FromConcatAll(thread, pieces); | 15733 return Symbols::FromConcatAll(thread, pieces); |
16670 } | 15734 } |
16671 | 15735 |
16672 | |
16673 RawString* AbstractType::ClassName() const { | 15736 RawString* AbstractType::ClassName() const { |
16674 ASSERT(!IsFunctionType()); | 15737 ASSERT(!IsFunctionType()); |
16675 if (HasResolvedTypeClass()) { | 15738 if (HasResolvedTypeClass()) { |
16676 return Class::Handle(type_class()).Name(); | 15739 return Class::Handle(type_class()).Name(); |
16677 } else { | 15740 } else { |
16678 return UnresolvedClass::Handle(unresolved_class()).Name(); | 15741 return UnresolvedClass::Handle(unresolved_class()).Name(); |
16679 } | 15742 } |
16680 } | 15743 } |
16681 | 15744 |
16682 | |
16683 bool AbstractType::IsDynamicType() const { | 15745 bool AbstractType::IsDynamicType() const { |
16684 if (IsCanonical()) { | 15746 if (IsCanonical()) { |
16685 return raw() == Object::dynamic_type().raw(); | 15747 return raw() == Object::dynamic_type().raw(); |
16686 } | 15748 } |
16687 return HasResolvedTypeClass() && (type_class() == Object::dynamic_class()); | 15749 return HasResolvedTypeClass() && (type_class() == Object::dynamic_class()); |
16688 } | 15750 } |
16689 | 15751 |
16690 | |
16691 bool AbstractType::IsVoidType() const { | 15752 bool AbstractType::IsVoidType() const { |
16692 return raw() == Object::void_type().raw(); | 15753 return raw() == Object::void_type().raw(); |
16693 } | 15754 } |
16694 | 15755 |
16695 | |
16696 bool AbstractType::IsNullType() const { | 15756 bool AbstractType::IsNullType() const { |
16697 return !IsFunctionType() && HasResolvedTypeClass() && | 15757 return !IsFunctionType() && HasResolvedTypeClass() && |
16698 (type_class() == Isolate::Current()->object_store()->null_class()); | 15758 (type_class() == Isolate::Current()->object_store()->null_class()); |
16699 } | 15759 } |
16700 | 15760 |
16701 | |
16702 bool AbstractType::IsBoolType() const { | 15761 bool AbstractType::IsBoolType() const { |
16703 return !IsFunctionType() && HasResolvedTypeClass() && | 15762 return !IsFunctionType() && HasResolvedTypeClass() && |
16704 (type_class() == Isolate::Current()->object_store()->bool_class()); | 15763 (type_class() == Isolate::Current()->object_store()->bool_class()); |
16705 } | 15764 } |
16706 | 15765 |
16707 | |
16708 bool AbstractType::IsIntType() const { | 15766 bool AbstractType::IsIntType() const { |
16709 return !IsFunctionType() && HasResolvedTypeClass() && | 15767 return !IsFunctionType() && HasResolvedTypeClass() && |
16710 (type_class() == Type::Handle(Type::IntType()).type_class()); | 15768 (type_class() == Type::Handle(Type::IntType()).type_class()); |
16711 } | 15769 } |
16712 | 15770 |
16713 | |
16714 bool AbstractType::IsInt64Type() const { | 15771 bool AbstractType::IsInt64Type() const { |
16715 return !IsFunctionType() && HasResolvedTypeClass() && | 15772 return !IsFunctionType() && HasResolvedTypeClass() && |
16716 (type_class() == Type::Handle(Type::Int64Type()).type_class()); | 15773 (type_class() == Type::Handle(Type::Int64Type()).type_class()); |
16717 } | 15774 } |
16718 | 15775 |
16719 | |
16720 bool AbstractType::IsDoubleType() const { | 15776 bool AbstractType::IsDoubleType() const { |
16721 return !IsFunctionType() && HasResolvedTypeClass() && | 15777 return !IsFunctionType() && HasResolvedTypeClass() && |
16722 (type_class() == Type::Handle(Type::Double()).type_class()); | 15778 (type_class() == Type::Handle(Type::Double()).type_class()); |
16723 } | 15779 } |
16724 | 15780 |
16725 | |
16726 bool AbstractType::IsFloat32x4Type() const { | 15781 bool AbstractType::IsFloat32x4Type() const { |
16727 return !IsFunctionType() && HasResolvedTypeClass() && | 15782 return !IsFunctionType() && HasResolvedTypeClass() && |
16728 (type_class() == Type::Handle(Type::Float32x4()).type_class()); | 15783 (type_class() == Type::Handle(Type::Float32x4()).type_class()); |
16729 } | 15784 } |
16730 | 15785 |
16731 | |
16732 bool AbstractType::IsFloat64x2Type() const { | 15786 bool AbstractType::IsFloat64x2Type() const { |
16733 return !IsFunctionType() && HasResolvedTypeClass() && | 15787 return !IsFunctionType() && HasResolvedTypeClass() && |
16734 (type_class() == Type::Handle(Type::Float64x2()).type_class()); | 15788 (type_class() == Type::Handle(Type::Float64x2()).type_class()); |
16735 } | 15789 } |
16736 | 15790 |
16737 | |
16738 bool AbstractType::IsInt32x4Type() const { | 15791 bool AbstractType::IsInt32x4Type() const { |
16739 return !IsFunctionType() && HasResolvedTypeClass() && | 15792 return !IsFunctionType() && HasResolvedTypeClass() && |
16740 (type_class() == Type::Handle(Type::Int32x4()).type_class()); | 15793 (type_class() == Type::Handle(Type::Int32x4()).type_class()); |
16741 } | 15794 } |
16742 | 15795 |
16743 | |
16744 bool AbstractType::IsNumberType() const { | 15796 bool AbstractType::IsNumberType() const { |
16745 return !IsFunctionType() && HasResolvedTypeClass() && | 15797 return !IsFunctionType() && HasResolvedTypeClass() && |
16746 (type_class() == Type::Handle(Type::Number()).type_class()); | 15798 (type_class() == Type::Handle(Type::Number()).type_class()); |
16747 } | 15799 } |
16748 | 15800 |
16749 | |
16750 bool AbstractType::IsSmiType() const { | 15801 bool AbstractType::IsSmiType() const { |
16751 return !IsFunctionType() && HasResolvedTypeClass() && | 15802 return !IsFunctionType() && HasResolvedTypeClass() && |
16752 (type_class() == Type::Handle(Type::SmiType()).type_class()); | 15803 (type_class() == Type::Handle(Type::SmiType()).type_class()); |
16753 } | 15804 } |
16754 | 15805 |
16755 | |
16756 bool AbstractType::IsStringType() const { | 15806 bool AbstractType::IsStringType() const { |
16757 return !IsFunctionType() && HasResolvedTypeClass() && | 15807 return !IsFunctionType() && HasResolvedTypeClass() && |
16758 (type_class() == Type::Handle(Type::StringType()).type_class()); | 15808 (type_class() == Type::Handle(Type::StringType()).type_class()); |
16759 } | 15809 } |
16760 | 15810 |
16761 | |
16762 bool AbstractType::IsDartFunctionType() const { | 15811 bool AbstractType::IsDartFunctionType() const { |
16763 return !IsFunctionType() && HasResolvedTypeClass() && | 15812 return !IsFunctionType() && HasResolvedTypeClass() && |
16764 (type_class() == Type::Handle(Type::DartFunctionType()).type_class()); | 15813 (type_class() == Type::Handle(Type::DartFunctionType()).type_class()); |
16765 } | 15814 } |
16766 | 15815 |
16767 | |
16768 bool AbstractType::IsDartClosureType() const { | 15816 bool AbstractType::IsDartClosureType() const { |
16769 return !IsFunctionType() && HasResolvedTypeClass() && | 15817 return !IsFunctionType() && HasResolvedTypeClass() && |
16770 (type_class() == Isolate::Current()->object_store()->closure_class()); | 15818 (type_class() == Isolate::Current()->object_store()->closure_class()); |
16771 } | 15819 } |
16772 | 15820 |
16773 | |
16774 bool AbstractType::TypeTest(TypeTestKind test_kind, | 15821 bool AbstractType::TypeTest(TypeTestKind test_kind, |
16775 const AbstractType& other, | 15822 const AbstractType& other, |
16776 Error* bound_error, | 15823 Error* bound_error, |
16777 TrailPtr bound_trail, | 15824 TrailPtr bound_trail, |
16778 Heap::Space space) const { | 15825 Heap::Space space) const { |
16779 ASSERT(IsFinalized()); | 15826 ASSERT(IsFinalized()); |
16780 ASSERT(other.IsFinalized()); | 15827 ASSERT(other.IsFinalized()); |
16781 if (IsMalformed() || other.IsMalformed()) { | 15828 if (IsMalformed() || other.IsMalformed()) { |
16782 // Malformed types involved in subtype tests should be handled specially | 15829 // Malformed types involved in subtype tests should be handled specially |
16783 // by the caller. Malformed types should only be encountered here in a | 15830 // by the caller. Malformed types should only be encountered here in a |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16934 } | 15981 } |
16935 if (IsFunctionType()) { | 15982 if (IsFunctionType()) { |
16936 return false; | 15983 return false; |
16937 } | 15984 } |
16938 return type_cls.TypeTest(test_kind, TypeArguments::Handle(zone, arguments()), | 15985 return type_cls.TypeTest(test_kind, TypeArguments::Handle(zone, arguments()), |
16939 Class::Handle(zone, other.type_class()), | 15986 Class::Handle(zone, other.type_class()), |
16940 TypeArguments::Handle(zone, other.arguments()), | 15987 TypeArguments::Handle(zone, other.arguments()), |
16941 bound_error, bound_trail, space); | 15988 bound_error, bound_trail, space); |
16942 } | 15989 } |
16943 | 15990 |
16944 | |
16945 intptr_t AbstractType::Hash() const { | 15991 intptr_t AbstractType::Hash() const { |
16946 // AbstractType is an abstract class. | 15992 // AbstractType is an abstract class. |
16947 UNREACHABLE(); | 15993 UNREACHABLE(); |
16948 return 0; | 15994 return 0; |
16949 } | 15995 } |
16950 | 15996 |
16951 | |
16952 const char* AbstractType::ToCString() const { | 15997 const char* AbstractType::ToCString() const { |
16953 if (IsNull()) { | 15998 if (IsNull()) { |
16954 return "AbstractType: null"; | 15999 return "AbstractType: null"; |
16955 } | 16000 } |
16956 // AbstractType is an abstract class. | 16001 // AbstractType is an abstract class. |
16957 UNREACHABLE(); | 16002 UNREACHABLE(); |
16958 return "AbstractType"; | 16003 return "AbstractType"; |
16959 } | 16004 } |
16960 | 16005 |
16961 | |
16962 RawType* Type::NullType() { | 16006 RawType* Type::NullType() { |
16963 return Isolate::Current()->object_store()->null_type(); | 16007 return Isolate::Current()->object_store()->null_type(); |
16964 } | 16008 } |
16965 | 16009 |
16966 | |
16967 RawType* Type::DynamicType() { | 16010 RawType* Type::DynamicType() { |
16968 return Object::dynamic_type().raw(); | 16011 return Object::dynamic_type().raw(); |
16969 } | 16012 } |
16970 | 16013 |
16971 | |
16972 RawType* Type::VoidType() { | 16014 RawType* Type::VoidType() { |
16973 return Object::void_type().raw(); | 16015 return Object::void_type().raw(); |
16974 } | 16016 } |
16975 | 16017 |
16976 | |
16977 RawType* Type::ObjectType() { | 16018 RawType* Type::ObjectType() { |
16978 return Isolate::Current()->object_store()->object_type(); | 16019 return Isolate::Current()->object_store()->object_type(); |
16979 } | 16020 } |
16980 | 16021 |
16981 | |
16982 RawType* Type::BoolType() { | 16022 RawType* Type::BoolType() { |
16983 return Isolate::Current()->object_store()->bool_type(); | 16023 return Isolate::Current()->object_store()->bool_type(); |
16984 } | 16024 } |
16985 | 16025 |
16986 | |
16987 RawType* Type::IntType() { | 16026 RawType* Type::IntType() { |
16988 return Isolate::Current()->object_store()->int_type(); | 16027 return Isolate::Current()->object_store()->int_type(); |
16989 } | 16028 } |
16990 | 16029 |
16991 | |
16992 RawType* Type::Int64Type() { | 16030 RawType* Type::Int64Type() { |
16993 return Isolate::Current()->object_store()->int64_type(); | 16031 return Isolate::Current()->object_store()->int64_type(); |
16994 } | 16032 } |
16995 | 16033 |
16996 | |
16997 RawType* Type::SmiType() { | 16034 RawType* Type::SmiType() { |
16998 return Isolate::Current()->object_store()->smi_type(); | 16035 return Isolate::Current()->object_store()->smi_type(); |
16999 } | 16036 } |
17000 | 16037 |
17001 | |
17002 RawType* Type::MintType() { | 16038 RawType* Type::MintType() { |
17003 return Isolate::Current()->object_store()->mint_type(); | 16039 return Isolate::Current()->object_store()->mint_type(); |
17004 } | 16040 } |
17005 | 16041 |
17006 | |
17007 RawType* Type::Double() { | 16042 RawType* Type::Double() { |
17008 return Isolate::Current()->object_store()->double_type(); | 16043 return Isolate::Current()->object_store()->double_type(); |
17009 } | 16044 } |
17010 | 16045 |
17011 | |
17012 RawType* Type::Float32x4() { | 16046 RawType* Type::Float32x4() { |
17013 return Isolate::Current()->object_store()->float32x4_type(); | 16047 return Isolate::Current()->object_store()->float32x4_type(); |
17014 } | 16048 } |
17015 | 16049 |
17016 | |
17017 RawType* Type::Float64x2() { | 16050 RawType* Type::Float64x2() { |
17018 return Isolate::Current()->object_store()->float64x2_type(); | 16051 return Isolate::Current()->object_store()->float64x2_type(); |
17019 } | 16052 } |
17020 | 16053 |
17021 | |
17022 RawType* Type::Int32x4() { | 16054 RawType* Type::Int32x4() { |
17023 return Isolate::Current()->object_store()->int32x4_type(); | 16055 return Isolate::Current()->object_store()->int32x4_type(); |
17024 } | 16056 } |
17025 | 16057 |
17026 | |
17027 RawType* Type::Number() { | 16058 RawType* Type::Number() { |
17028 return Isolate::Current()->object_store()->number_type(); | 16059 return Isolate::Current()->object_store()->number_type(); |
17029 } | 16060 } |
17030 | 16061 |
17031 | |
17032 RawType* Type::StringType() { | 16062 RawType* Type::StringType() { |
17033 return Isolate::Current()->object_store()->string_type(); | 16063 return Isolate::Current()->object_store()->string_type(); |
17034 } | 16064 } |
17035 | 16065 |
17036 | |
17037 RawType* Type::ArrayType() { | 16066 RawType* Type::ArrayType() { |
17038 return Isolate::Current()->object_store()->array_type(); | 16067 return Isolate::Current()->object_store()->array_type(); |
17039 } | 16068 } |
17040 | 16069 |
17041 | |
17042 RawType* Type::DartFunctionType() { | 16070 RawType* Type::DartFunctionType() { |
17043 return Isolate::Current()->object_store()->function_type(); | 16071 return Isolate::Current()->object_store()->function_type(); |
17044 } | 16072 } |
17045 | 16073 |
17046 | |
17047 RawType* Type::NewNonParameterizedType(const Class& type_class) { | 16074 RawType* Type::NewNonParameterizedType(const Class& type_class) { |
17048 ASSERT(type_class.NumTypeArguments() == 0); | 16075 ASSERT(type_class.NumTypeArguments() == 0); |
17049 Type& type = Type::Handle(type_class.CanonicalType()); | 16076 Type& type = Type::Handle(type_class.CanonicalType()); |
17050 if (type.IsNull()) { | 16077 if (type.IsNull()) { |
17051 type ^= Type::New(Object::Handle(type_class.raw()), | 16078 type ^= Type::New(Object::Handle(type_class.raw()), |
17052 Object::null_type_arguments(), TokenPosition::kNoSource); | 16079 Object::null_type_arguments(), TokenPosition::kNoSource); |
17053 type.SetIsFinalized(); | 16080 type.SetIsFinalized(); |
17054 type ^= type.Canonicalize(); | 16081 type ^= type.Canonicalize(); |
17055 } | 16082 } |
17056 ASSERT(type.IsFinalized()); | 16083 ASSERT(type.IsFinalized()); |
17057 return type.raw(); | 16084 return type.raw(); |
17058 } | 16085 } |
17059 | 16086 |
17060 | |
17061 void Type::SetIsFinalized() const { | 16087 void Type::SetIsFinalized() const { |
17062 ASSERT(!IsFinalized()); | 16088 ASSERT(!IsFinalized()); |
17063 if (IsInstantiated()) { | 16089 if (IsInstantiated()) { |
17064 ASSERT(HasResolvedTypeClass()); | 16090 ASSERT(HasResolvedTypeClass()); |
17065 set_type_state(RawType::kFinalizedInstantiated); | 16091 set_type_state(RawType::kFinalizedInstantiated); |
17066 } else { | 16092 } else { |
17067 set_type_state(RawType::kFinalizedUninstantiated); | 16093 set_type_state(RawType::kFinalizedUninstantiated); |
17068 } | 16094 } |
17069 } | 16095 } |
17070 | 16096 |
17071 | |
17072 void Type::ResetIsFinalized() const { | 16097 void Type::ResetIsFinalized() const { |
17073 ASSERT(IsFinalized()); | 16098 ASSERT(IsFinalized()); |
17074 set_type_state(RawType::kBeingFinalized); | 16099 set_type_state(RawType::kBeingFinalized); |
17075 SetIsFinalized(); | 16100 SetIsFinalized(); |
17076 } | 16101 } |
17077 | 16102 |
17078 | |
17079 void Type::SetIsBeingFinalized() const { | 16103 void Type::SetIsBeingFinalized() const { |
17080 ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized()); | 16104 ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized()); |
17081 set_type_state(RawType::kBeingFinalized); | 16105 set_type_state(RawType::kBeingFinalized); |
17082 } | 16106 } |
17083 | 16107 |
17084 | |
17085 bool Type::IsMalformed() const { | 16108 bool Type::IsMalformed() const { |
17086 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 16109 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |
17087 return false; // Valid type, but not a function type. | 16110 return false; // Valid type, but not a function type. |
17088 } | 16111 } |
17089 if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 16112 if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |
17090 return false; // Valid function type. | 16113 return false; // Valid function type. |
17091 } | 16114 } |
17092 const LanguageError& type_error = LanguageError::Handle(error()); | 16115 const LanguageError& type_error = LanguageError::Handle(error()); |
17093 ASSERT(!type_error.IsNull()); | 16116 ASSERT(!type_error.IsNull()); |
17094 return type_error.kind() == Report::kMalformedType; | 16117 return type_error.kind() == Report::kMalformedType; |
17095 } | 16118 } |
17096 | 16119 |
17097 | |
17098 bool Type::IsMalbounded() const { | 16120 bool Type::IsMalbounded() const { |
17099 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 16121 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |
17100 return false; // Valid type, but not a function type. | 16122 return false; // Valid type, but not a function type. |
17101 } | 16123 } |
17102 if (!Isolate::Current()->type_checks()) { | 16124 if (!Isolate::Current()->type_checks()) { |
17103 return false; | 16125 return false; |
17104 } | 16126 } |
17105 if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 16127 if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |
17106 return false; // Valid function type. | 16128 return false; // Valid function type. |
17107 } | 16129 } |
17108 const LanguageError& type_error = LanguageError::Handle(error()); | 16130 const LanguageError& type_error = LanguageError::Handle(error()); |
17109 ASSERT(!type_error.IsNull()); | 16131 ASSERT(!type_error.IsNull()); |
17110 return type_error.kind() == Report::kMalboundedType; | 16132 return type_error.kind() == Report::kMalboundedType; |
17111 } | 16133 } |
17112 | 16134 |
17113 | |
17114 bool Type::IsMalformedOrMalbounded() const { | 16135 bool Type::IsMalformedOrMalbounded() const { |
17115 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 16136 if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |
17116 return false; // Valid type, but not a function type. | 16137 return false; // Valid type, but not a function type. |
17117 } | 16138 } |
17118 const LanguageError& type_error = LanguageError::Handle(error()); | 16139 const LanguageError& type_error = LanguageError::Handle(error()); |
17119 if (type_error.IsNull()) { | 16140 if (type_error.IsNull()) { |
17120 return false; // Valid function type. | 16141 return false; // Valid function type. |
17121 } | 16142 } |
17122 if (type_error.kind() == Report::kMalformedType) { | 16143 if (type_error.kind() == Report::kMalformedType) { |
17123 return true; | 16144 return true; |
17124 } | 16145 } |
17125 ASSERT(type_error.kind() == Report::kMalboundedType); | 16146 ASSERT(type_error.kind() == Report::kMalboundedType); |
17126 return Isolate::Current()->type_checks(); | 16147 return Isolate::Current()->type_checks(); |
17127 } | 16148 } |
17128 | 16149 |
17129 | |
17130 RawLanguageError* Type::error() const { | 16150 RawLanguageError* Type::error() const { |
17131 if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 16151 if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |
17132 return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_); | 16152 return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_); |
17133 } | 16153 } |
17134 return LanguageError::null(); | 16154 return LanguageError::null(); |
17135 } | 16155 } |
17136 | 16156 |
17137 | |
17138 void Type::set_error(const LanguageError& value) const { | 16157 void Type::set_error(const LanguageError& value) const { |
17139 StorePointer(&raw_ptr()->sig_or_err_.error_, value.raw()); | 16158 StorePointer(&raw_ptr()->sig_or_err_.error_, value.raw()); |
17140 } | 16159 } |
17141 | 16160 |
17142 | |
17143 RawFunction* Type::signature() const { | 16161 RawFunction* Type::signature() const { |
17144 intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId(); | 16162 intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId(); |
17145 if (cid == kNullCid) { | 16163 if (cid == kNullCid) { |
17146 return Function::null(); | 16164 return Function::null(); |
17147 } | 16165 } |
17148 if (cid == kFunctionCid) { | 16166 if (cid == kFunctionCid) { |
17149 return Function::RawCast(raw_ptr()->sig_or_err_.signature_); | 16167 return Function::RawCast(raw_ptr()->sig_or_err_.signature_); |
17150 } | 16168 } |
17151 ASSERT(cid == kLanguageErrorCid); // Type is malformed or malbounded. | 16169 ASSERT(cid == kLanguageErrorCid); // Type is malformed or malbounded. |
17152 return Function::null(); | 16170 return Function::null(); |
17153 } | 16171 } |
17154 | 16172 |
17155 | |
17156 void Type::set_signature(const Function& value) const { | 16173 void Type::set_signature(const Function& value) const { |
17157 StorePointer(&raw_ptr()->sig_or_err_.signature_, value.raw()); | 16174 StorePointer(&raw_ptr()->sig_or_err_.signature_, value.raw()); |
17158 } | 16175 } |
17159 | 16176 |
17160 | |
17161 void Type::SetIsResolved() const { | 16177 void Type::SetIsResolved() const { |
17162 ASSERT(!IsResolved()); | 16178 ASSERT(!IsResolved()); |
17163 set_type_state(RawType::kResolved); | 16179 set_type_state(RawType::kResolved); |
17164 } | 16180 } |
17165 | 16181 |
17166 | |
17167 bool Type::HasResolvedTypeClass() const { | 16182 bool Type::HasResolvedTypeClass() const { |
17168 return !raw_ptr()->type_class_id_->IsHeapObject(); | 16183 return !raw_ptr()->type_class_id_->IsHeapObject(); |
17169 } | 16184 } |
17170 | 16185 |
17171 | |
17172 classid_t Type::type_class_id() const { | 16186 classid_t Type::type_class_id() const { |
17173 ASSERT(HasResolvedTypeClass()); | 16187 ASSERT(HasResolvedTypeClass()); |
17174 return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_)); | 16188 return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_)); |
17175 } | 16189 } |
17176 | 16190 |
17177 | |
17178 RawClass* Type::type_class() const { | 16191 RawClass* Type::type_class() const { |
17179 return Isolate::Current()->class_table()->At(type_class_id()); | 16192 return Isolate::Current()->class_table()->At(type_class_id()); |
17180 } | 16193 } |
17181 | 16194 |
17182 | |
17183 RawUnresolvedClass* Type::unresolved_class() const { | 16195 RawUnresolvedClass* Type::unresolved_class() const { |
17184 #ifdef DEBUG | 16196 #ifdef DEBUG |
17185 ASSERT(!HasResolvedTypeClass()); | 16197 ASSERT(!HasResolvedTypeClass()); |
17186 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); | 16198 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); |
17187 unresolved_class ^= raw_ptr()->type_class_id_; | 16199 unresolved_class ^= raw_ptr()->type_class_id_; |
17188 ASSERT(!unresolved_class.IsNull()); | 16200 ASSERT(!unresolved_class.IsNull()); |
17189 return unresolved_class.raw(); | 16201 return unresolved_class.raw(); |
17190 #else | 16202 #else |
17191 ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull()); | 16203 ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull()); |
17192 ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass()); | 16204 ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass()); |
17193 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_); | 16205 return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_); |
17194 #endif | 16206 #endif |
17195 } | 16207 } |
17196 | 16208 |
17197 | |
17198 bool Type::IsInstantiated(Genericity genericity, | 16209 bool Type::IsInstantiated(Genericity genericity, |
17199 intptr_t num_free_fun_type_params, | 16210 intptr_t num_free_fun_type_params, |
17200 TrailPtr trail) const { | 16211 TrailPtr trail) const { |
17201 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 16212 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
17202 return true; | 16213 return true; |
17203 } | 16214 } |
17204 if ((genericity == kAny) && (num_free_fun_type_params == kMaxInt32) && | 16215 if ((genericity == kAny) && (num_free_fun_type_params == kMaxInt32) && |
17205 (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) { | 16216 (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) { |
17206 return false; | 16217 return false; |
17207 } | 16218 } |
(...skipping 27 matching lines...) Expand all Loading... |
17235 // Type arguments are reset to null when finalizing such a type. | 16246 // Type arguments are reset to null when finalizing such a type. |
17236 ASSERT(!IsFinalized()); | 16247 ASSERT(!IsFinalized()); |
17237 len = num_type_args; | 16248 len = num_type_args; |
17238 } | 16249 } |
17239 } | 16250 } |
17240 return (len == 0) || | 16251 return (len == 0) || |
17241 args.IsSubvectorInstantiated(num_type_args - len, len, genericity, | 16252 args.IsSubvectorInstantiated(num_type_args - len, len, genericity, |
17242 num_free_fun_type_params, trail); | 16253 num_free_fun_type_params, trail); |
17243 } | 16254 } |
17244 | 16255 |
17245 | |
17246 RawAbstractType* Type::InstantiateFrom( | 16256 RawAbstractType* Type::InstantiateFrom( |
17247 const TypeArguments& instantiator_type_arguments, | 16257 const TypeArguments& instantiator_type_arguments, |
17248 const TypeArguments& function_type_arguments, | 16258 const TypeArguments& function_type_arguments, |
17249 Error* bound_error, | 16259 Error* bound_error, |
17250 TrailPtr instantiation_trail, | 16260 TrailPtr instantiation_trail, |
17251 TrailPtr bound_trail, | 16261 TrailPtr bound_trail, |
17252 Heap::Space space) const { | 16262 Heap::Space space) const { |
17253 Zone* zone = Thread::Current()->zone(); | 16263 Zone* zone = Thread::Current()->zone(); |
17254 ASSERT(IsFinalized() || IsBeingFinalized()); | 16264 ASSERT(IsFinalized() || IsBeingFinalized()); |
17255 ASSERT(!IsInstantiated()); | 16265 ASSERT(!IsInstantiated()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17306 } else { | 16316 } else { |
17307 instantiated_type.SetIsResolved(); | 16317 instantiated_type.SetIsResolved(); |
17308 if (IsBeingFinalized()) { | 16318 if (IsBeingFinalized()) { |
17309 instantiated_type.SetIsBeingFinalized(); | 16319 instantiated_type.SetIsBeingFinalized(); |
17310 } | 16320 } |
17311 } | 16321 } |
17312 // Canonicalization is not part of instantiation. | 16322 // Canonicalization is not part of instantiation. |
17313 return instantiated_type.raw(); | 16323 return instantiated_type.raw(); |
17314 } | 16324 } |
17315 | 16325 |
17316 | |
17317 bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const { | 16326 bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const { |
17318 ASSERT(!IsNull()); | 16327 ASSERT(!IsNull()); |
17319 if (raw() == other.raw()) { | 16328 if (raw() == other.raw()) { |
17320 return true; | 16329 return true; |
17321 } | 16330 } |
17322 if (other.IsTypeRef()) { | 16331 if (other.IsTypeRef()) { |
17323 // Unfold right hand type. Divergence is controlled by left hand type. | 16332 // Unfold right hand type. Divergence is controlled by left hand type. |
17324 const AbstractType& other_ref_type = | 16333 const AbstractType& other_ref_type = |
17325 AbstractType::Handle(TypeRef::Cast(other).type()); | 16334 AbstractType::Handle(TypeRef::Cast(other).type()); |
17326 ASSERT(!other_ref_type.IsTypeRef()); | 16335 ASSERT(!other_ref_type.IsTypeRef()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17470 return true; | 16479 return true; |
17471 } | 16480 } |
17472 for (intptr_t i = num_fixed_params; i < num_params; i++) { | 16481 for (intptr_t i = num_fixed_params; i < num_params; i++) { |
17473 if (sig_fun.ParameterNameAt(i) != other_sig_fun.ParameterNameAt(i)) { | 16482 if (sig_fun.ParameterNameAt(i) != other_sig_fun.ParameterNameAt(i)) { |
17474 return false; | 16483 return false; |
17475 } | 16484 } |
17476 } | 16485 } |
17477 return true; | 16486 return true; |
17478 } | 16487 } |
17479 | 16488 |
17480 | |
17481 bool Type::IsRecursive() const { | 16489 bool Type::IsRecursive() const { |
17482 return TypeArguments::Handle(arguments()).IsRecursive(); | 16490 return TypeArguments::Handle(arguments()).IsRecursive(); |
17483 } | 16491 } |
17484 | 16492 |
17485 | |
17486 RawAbstractType* Type::CloneUnfinalized() const { | 16493 RawAbstractType* Type::CloneUnfinalized() const { |
17487 ASSERT(IsResolved()); | 16494 ASSERT(IsResolved()); |
17488 if (IsFinalized()) { | 16495 if (IsFinalized()) { |
17489 return raw(); | 16496 return raw(); |
17490 } | 16497 } |
17491 ASSERT(!IsMalformed()); // Malformed types are finalized. | 16498 ASSERT(!IsMalformed()); // Malformed types are finalized. |
17492 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. | 16499 ASSERT(!IsBeingFinalized()); // Cloning must occur prior to finalization. |
17493 Zone* zone = Thread::Current()->zone(); | 16500 Zone* zone = Thread::Current()->zone(); |
17494 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 16501 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
17495 const TypeArguments& type_args_clone = | 16502 const TypeArguments& type_args_clone = |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17542 fun_clone.SetParameterTypeAt(i, type); | 16549 fun_clone.SetParameterTypeAt(i, type); |
17543 } | 16550 } |
17544 fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); | 16551 fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); |
17545 clone.set_signature(fun_clone); | 16552 clone.set_signature(fun_clone); |
17546 fun_clone.SetSignatureType(clone); | 16553 fun_clone.SetSignatureType(clone); |
17547 } | 16554 } |
17548 clone.SetIsResolved(); | 16555 clone.SetIsResolved(); |
17549 return clone.raw(); | 16556 return clone.raw(); |
17550 } | 16557 } |
17551 | 16558 |
17552 | |
17553 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, | 16559 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, |
17554 TrailPtr trail) const { | 16560 TrailPtr trail) const { |
17555 ASSERT(IsFinalized()); | 16561 ASSERT(IsFinalized()); |
17556 ASSERT(IsCanonical()); | 16562 ASSERT(IsCanonical()); |
17557 ASSERT(!IsMalformed()); | 16563 ASSERT(!IsMalformed()); |
17558 if (IsInstantiated()) { | 16564 if (IsInstantiated()) { |
17559 return raw(); | 16565 return raw(); |
17560 } | 16566 } |
17561 // We may recursively encounter a type already being cloned, because we clone | 16567 // We may recursively encounter a type already being cloned, because we clone |
17562 // the upper bounds of its uninstantiated type arguments in the same pass. | 16568 // the upper bounds of its uninstantiated type arguments in the same pass. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17622 AddOnlyBuddyToTrail(&trail, clone); | 16628 AddOnlyBuddyToTrail(&trail, clone); |
17623 } | 16629 } |
17624 type_args = type_args.CloneUninstantiated(new_owner, trail); | 16630 type_args = type_args.CloneUninstantiated(new_owner, trail); |
17625 clone.set_arguments(type_args); | 16631 clone.set_arguments(type_args); |
17626 } | 16632 } |
17627 clone.SetIsFinalized(); | 16633 clone.SetIsFinalized(); |
17628 clone ^= clone.Canonicalize(); | 16634 clone ^= clone.Canonicalize(); |
17629 return clone.raw(); | 16635 return clone.raw(); |
17630 } | 16636 } |
17631 | 16637 |
17632 | |
17633 RawAbstractType* Type::Canonicalize(TrailPtr trail) const { | 16638 RawAbstractType* Type::Canonicalize(TrailPtr trail) const { |
17634 ASSERT(IsFinalized()); | 16639 ASSERT(IsFinalized()); |
17635 if (IsCanonical() || IsMalformed()) { | 16640 if (IsCanonical() || IsMalformed()) { |
17636 ASSERT(IsMalformed() || TypeArguments::Handle(arguments()).IsOld()); | 16641 ASSERT(IsMalformed() || TypeArguments::Handle(arguments()).IsOld()); |
17637 return this->raw(); | 16642 return this->raw(); |
17638 } | 16643 } |
17639 Thread* thread = Thread::Current(); | 16644 Thread* thread = Thread::Current(); |
17640 Zone* zone = thread->zone(); | 16645 Zone* zone = thread->zone(); |
17641 Isolate* isolate = thread->isolate(); | 16646 Isolate* isolate = thread->isolate(); |
17642 | 16647 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17752 ASSERT(type.IsOld()); | 16757 ASSERT(type.IsOld()); |
17753 type.SetCanonical(); // Mark object as being canonical. | 16758 type.SetCanonical(); // Mark object as being canonical. |
17754 bool present = table.Insert(type); | 16759 bool present = table.Insert(type); |
17755 ASSERT(!present); | 16760 ASSERT(!present); |
17756 } | 16761 } |
17757 object_store->set_canonical_types(table.Release()); | 16762 object_store->set_canonical_types(table.Release()); |
17758 } | 16763 } |
17759 return type.raw(); | 16764 return type.raw(); |
17760 } | 16765 } |
17761 | 16766 |
17762 | |
17763 #if defined(DEBUG) | 16767 #if defined(DEBUG) |
17764 bool Type::CheckIsCanonical(Thread* thread) const { | 16768 bool Type::CheckIsCanonical(Thread* thread) const { |
17765 if (IsMalformed()) { | 16769 if (IsMalformed()) { |
17766 return true; | 16770 return true; |
17767 } | 16771 } |
17768 if (type_class() == Object::dynamic_class()) { | 16772 if (type_class() == Object::dynamic_class()) { |
17769 return (raw() == Object::dynamic_type().raw()); | 16773 return (raw() == Object::dynamic_type().raw()); |
17770 } | 16774 } |
17771 Zone* zone = thread->zone(); | 16775 Zone* zone = thread->zone(); |
17772 Isolate* isolate = thread->isolate(); | 16776 Isolate* isolate = thread->isolate(); |
(...skipping 11 matching lines...) Expand all Loading... |
17784 { | 16788 { |
17785 SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); | 16789 SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); |
17786 CanonicalTypeSet table(zone, object_store->canonical_types()); | 16790 CanonicalTypeSet table(zone, object_store->canonical_types()); |
17787 type ^= table.GetOrNull(CanonicalTypeKey(*this)); | 16791 type ^= table.GetOrNull(CanonicalTypeKey(*this)); |
17788 object_store->set_canonical_types(table.Release()); | 16792 object_store->set_canonical_types(table.Release()); |
17789 } | 16793 } |
17790 return (raw() == type.raw()); | 16794 return (raw() == type.raw()); |
17791 } | 16795 } |
17792 #endif // DEBUG | 16796 #endif // DEBUG |
17793 | 16797 |
17794 | |
17795 RawString* Type::EnumerateURIs() const { | 16798 RawString* Type::EnumerateURIs() const { |
17796 if (IsDynamicType() || IsVoidType()) { | 16799 if (IsDynamicType() || IsVoidType()) { |
17797 return Symbols::Empty().raw(); | 16800 return Symbols::Empty().raw(); |
17798 } | 16801 } |
17799 Thread* thread = Thread::Current(); | 16802 Thread* thread = Thread::Current(); |
17800 Zone* zone = thread->zone(); | 16803 Zone* zone = thread->zone(); |
17801 GrowableHandlePtrArray<const String> pieces(zone, 6); | 16804 GrowableHandlePtrArray<const String> pieces(zone, 6); |
17802 if (IsFunctionType()) { | 16805 if (IsFunctionType()) { |
17803 // The scope class and type arguments do not appear explicitly in the user | 16806 // The scope class and type arguments do not appear explicitly in the user |
17804 // visible name. The type arguments were used to instantiate the function | 16807 // visible name. The type arguments were used to instantiate the function |
(...skipping 16 matching lines...) Expand all Loading... |
17821 pieces.Add(Symbols::SpaceIsFromSpace()); | 16824 pieces.Add(Symbols::SpaceIsFromSpace()); |
17822 const Library& library = Library::Handle(zone, cls.library()); | 16825 const Library& library = Library::Handle(zone, cls.library()); |
17823 pieces.Add(String::Handle(zone, library.url())); | 16826 pieces.Add(String::Handle(zone, library.url())); |
17824 pieces.Add(Symbols::NewLine()); | 16827 pieces.Add(Symbols::NewLine()); |
17825 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 16828 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
17826 pieces.Add(String::Handle(zone, type_args.EnumerateURIs())); | 16829 pieces.Add(String::Handle(zone, type_args.EnumerateURIs())); |
17827 } | 16830 } |
17828 return Symbols::FromConcatAll(thread, pieces); | 16831 return Symbols::FromConcatAll(thread, pieces); |
17829 } | 16832 } |
17830 | 16833 |
17831 | |
17832 intptr_t Type::ComputeHash() const { | 16834 intptr_t Type::ComputeHash() const { |
17833 ASSERT(IsFinalized()); | 16835 ASSERT(IsFinalized()); |
17834 uint32_t result = 1; | 16836 uint32_t result = 1; |
17835 if (IsMalformed()) return result; | 16837 if (IsMalformed()) return result; |
17836 result = CombineHashes(result, Class::Handle(type_class()).id()); | 16838 result = CombineHashes(result, Class::Handle(type_class()).id()); |
17837 result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); | 16839 result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); |
17838 if (IsFunctionType()) { | 16840 if (IsFunctionType()) { |
17839 const Function& sig_fun = Function::Handle(signature()); | 16841 const Function& sig_fun = Function::Handle(signature()); |
17840 AbstractType& type = AbstractType::Handle(sig_fun.result_type()); | 16842 AbstractType& type = AbstractType::Handle(sig_fun.result_type()); |
17841 result = CombineHashes(result, type.Hash()); | 16843 result = CombineHashes(result, type.Hash()); |
17842 result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters()); | 16844 result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters()); |
17843 const intptr_t num_params = sig_fun.NumParameters(); | 16845 const intptr_t num_params = sig_fun.NumParameters(); |
17844 for (intptr_t i = 0; i < num_params; i++) { | 16846 for (intptr_t i = 0; i < num_params; i++) { |
17845 type = sig_fun.ParameterTypeAt(i); | 16847 type = sig_fun.ParameterTypeAt(i); |
17846 result = CombineHashes(result, type.Hash()); | 16848 result = CombineHashes(result, type.Hash()); |
17847 } | 16849 } |
17848 if (sig_fun.NumOptionalNamedParameters() > 0) { | 16850 if (sig_fun.NumOptionalNamedParameters() > 0) { |
17849 String& param_name = String::Handle(); | 16851 String& param_name = String::Handle(); |
17850 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { | 16852 for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { |
17851 param_name = sig_fun.ParameterNameAt(i); | 16853 param_name = sig_fun.ParameterNameAt(i); |
17852 result = CombineHashes(result, param_name.Hash()); | 16854 result = CombineHashes(result, param_name.Hash()); |
17853 } | 16855 } |
17854 } | 16856 } |
17855 } | 16857 } |
17856 result = FinalizeHash(result, kHashBits); | 16858 result = FinalizeHash(result, kHashBits); |
17857 SetHash(result); | 16859 SetHash(result); |
17858 return result; | 16860 return result; |
17859 } | 16861 } |
17860 | 16862 |
17861 | |
17862 void Type::set_type_class(const Class& value) const { | 16863 void Type::set_type_class(const Class& value) const { |
17863 ASSERT(!value.IsNull()); | 16864 ASSERT(!value.IsNull()); |
17864 StorePointer(&raw_ptr()->type_class_id_, | 16865 StorePointer(&raw_ptr()->type_class_id_, |
17865 reinterpret_cast<RawObject*>(Smi::New(value.id()))); | 16866 reinterpret_cast<RawObject*>(Smi::New(value.id()))); |
17866 } | 16867 } |
17867 | 16868 |
17868 | |
17869 void Type::set_unresolved_class(const Object& value) const { | 16869 void Type::set_unresolved_class(const Object& value) const { |
17870 ASSERT(!value.IsNull() && value.IsUnresolvedClass()); | 16870 ASSERT(!value.IsNull() && value.IsUnresolvedClass()); |
17871 StorePointer(&raw_ptr()->type_class_id_, value.raw()); | 16871 StorePointer(&raw_ptr()->type_class_id_, value.raw()); |
17872 } | 16872 } |
17873 | 16873 |
17874 | |
17875 void Type::set_arguments(const TypeArguments& value) const { | 16874 void Type::set_arguments(const TypeArguments& value) const { |
17876 ASSERT(!IsCanonical()); | 16875 ASSERT(!IsCanonical()); |
17877 StorePointer(&raw_ptr()->arguments_, value.raw()); | 16876 StorePointer(&raw_ptr()->arguments_, value.raw()); |
17878 } | 16877 } |
17879 | 16878 |
17880 | |
17881 RawType* Type::New(Heap::Space space) { | 16879 RawType* Type::New(Heap::Space space) { |
17882 RawObject* raw = | 16880 RawObject* raw = |
17883 Object::Allocate(Type::kClassId, Type::InstanceSize(), space); | 16881 Object::Allocate(Type::kClassId, Type::InstanceSize(), space); |
17884 return reinterpret_cast<RawType*>(raw); | 16882 return reinterpret_cast<RawType*>(raw); |
17885 } | 16883 } |
17886 | 16884 |
17887 | |
17888 RawType* Type::New(const Object& clazz, | 16885 RawType* Type::New(const Object& clazz, |
17889 const TypeArguments& arguments, | 16886 const TypeArguments& arguments, |
17890 TokenPosition token_pos, | 16887 TokenPosition token_pos, |
17891 Heap::Space space) { | 16888 Heap::Space space) { |
17892 const Type& result = Type::Handle(Type::New(space)); | 16889 const Type& result = Type::Handle(Type::New(space)); |
17893 if (clazz.IsClass()) { | 16890 if (clazz.IsClass()) { |
17894 result.set_type_class(Class::Cast(clazz)); | 16891 result.set_type_class(Class::Cast(clazz)); |
17895 } else { | 16892 } else { |
17896 result.set_unresolved_class(clazz); | 16893 result.set_unresolved_class(clazz); |
17897 } | 16894 } |
17898 result.set_arguments(arguments); | 16895 result.set_arguments(arguments); |
17899 result.SetHash(0); | 16896 result.SetHash(0); |
17900 result.set_token_pos(token_pos); | 16897 result.set_token_pos(token_pos); |
17901 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); | 16898 result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); |
17902 return result.raw(); | 16899 return result.raw(); |
17903 } | 16900 } |
17904 | 16901 |
17905 | |
17906 void Type::set_token_pos(TokenPosition token_pos) const { | 16902 void Type::set_token_pos(TokenPosition token_pos) const { |
17907 ASSERT(!token_pos.IsClassifying()); | 16903 ASSERT(!token_pos.IsClassifying()); |
17908 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 16904 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
17909 } | 16905 } |
17910 | 16906 |
17911 | |
17912 void Type::set_type_state(int8_t state) const { | 16907 void Type::set_type_state(int8_t state) const { |
17913 ASSERT((state >= RawType::kAllocated) && | 16908 ASSERT((state >= RawType::kAllocated) && |
17914 (state <= RawType::kFinalizedUninstantiated)); | 16909 (state <= RawType::kFinalizedUninstantiated)); |
17915 StoreNonPointer(&raw_ptr()->type_state_, state); | 16910 StoreNonPointer(&raw_ptr()->type_state_, state); |
17916 } | 16911 } |
17917 | 16912 |
17918 | |
17919 const char* Type::ToCString() const { | 16913 const char* Type::ToCString() const { |
17920 if (IsNull()) { | 16914 if (IsNull()) { |
17921 return "Type: null"; | 16915 return "Type: null"; |
17922 } | 16916 } |
17923 Zone* zone = Thread::Current()->zone(); | 16917 Zone* zone = Thread::Current()->zone(); |
17924 const char* unresolved = IsResolved() ? "" : "Unresolved "; | 16918 const char* unresolved = IsResolved() ? "" : "Unresolved "; |
17925 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 16919 const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |
17926 const char* args_cstr = type_args.IsNull() ? "null" : type_args.ToCString(); | 16920 const char* args_cstr = type_args.IsNull() ? "null" : type_args.ToCString(); |
17927 Class& cls = Class::Handle(zone); | 16921 Class& cls = Class::Handle(zone); |
17928 const char* class_name; | 16922 const char* class_name; |
(...skipping 19 matching lines...) Expand all Loading... |
17948 } else if (IsResolved() && IsFinalized() && IsRecursive()) { | 16942 } else if (IsResolved() && IsFinalized() && IsRecursive()) { |
17949 const intptr_t hash = Hash(); | 16943 const intptr_t hash = Hash(); |
17950 return OS::SCreate(zone, "Type: (@%p H%" Px ") class '%s', args:[%s]", | 16944 return OS::SCreate(zone, "Type: (@%p H%" Px ") class '%s', args:[%s]", |
17951 raw(), hash, class_name, args_cstr); | 16945 raw(), hash, class_name, args_cstr); |
17952 } else { | 16946 } else { |
17953 return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved, | 16947 return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved, |
17954 class_name, args_cstr); | 16948 class_name, args_cstr); |
17955 } | 16949 } |
17956 } | 16950 } |
17957 | 16951 |
17958 | |
17959 bool TypeRef::IsInstantiated(Genericity genericity, | 16952 bool TypeRef::IsInstantiated(Genericity genericity, |
17960 intptr_t num_free_fun_type_params, | 16953 intptr_t num_free_fun_type_params, |
17961 TrailPtr trail) const { | 16954 TrailPtr trail) const { |
17962 if (TestAndAddToTrail(&trail)) { | 16955 if (TestAndAddToTrail(&trail)) { |
17963 return true; | 16956 return true; |
17964 } | 16957 } |
17965 const AbstractType& ref_type = AbstractType::Handle(type()); | 16958 const AbstractType& ref_type = AbstractType::Handle(type()); |
17966 return !ref_type.IsNull() && | 16959 return !ref_type.IsNull() && |
17967 ref_type.IsInstantiated(genericity, num_free_fun_type_params, trail); | 16960 ref_type.IsInstantiated(genericity, num_free_fun_type_params, trail); |
17968 } | 16961 } |
17969 | 16962 |
17970 | |
17971 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const { | 16963 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const { |
17972 if (raw() == other.raw()) { | 16964 if (raw() == other.raw()) { |
17973 return true; | 16965 return true; |
17974 } | 16966 } |
17975 if (!other.IsAbstractType()) { | 16967 if (!other.IsAbstractType()) { |
17976 return false; | 16968 return false; |
17977 } | 16969 } |
17978 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { | 16970 if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { |
17979 return true; | 16971 return true; |
17980 } | 16972 } |
17981 const AbstractType& ref_type = AbstractType::Handle(type()); | 16973 const AbstractType& ref_type = AbstractType::Handle(type()); |
17982 return !ref_type.IsNull() && ref_type.IsEquivalent(other, trail); | 16974 return !ref_type.IsNull() && ref_type.IsEquivalent(other, trail); |
17983 } | 16975 } |
17984 | 16976 |
17985 | |
17986 RawTypeRef* TypeRef::InstantiateFrom( | 16977 RawTypeRef* TypeRef::InstantiateFrom( |
17987 const TypeArguments& instantiator_type_arguments, | 16978 const TypeArguments& instantiator_type_arguments, |
17988 const TypeArguments& function_type_arguments, | 16979 const TypeArguments& function_type_arguments, |
17989 Error* bound_error, | 16980 Error* bound_error, |
17990 TrailPtr instantiation_trail, | 16981 TrailPtr instantiation_trail, |
17991 TrailPtr bound_trail, | 16982 TrailPtr bound_trail, |
17992 Heap::Space space) const { | 16983 Heap::Space space) const { |
17993 TypeRef& instantiated_type_ref = TypeRef::Handle(); | 16984 TypeRef& instantiated_type_ref = TypeRef::Handle(); |
17994 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); | 16985 instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); |
17995 if (!instantiated_type_ref.IsNull()) { | 16986 if (!instantiated_type_ref.IsNull()) { |
17996 return instantiated_type_ref.raw(); | 16987 return instantiated_type_ref.raw(); |
17997 } | 16988 } |
17998 instantiated_type_ref = TypeRef::New(); | 16989 instantiated_type_ref = TypeRef::New(); |
17999 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); | 16990 AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); |
18000 | 16991 |
18001 AbstractType& ref_type = AbstractType::Handle(type()); | 16992 AbstractType& ref_type = AbstractType::Handle(type()); |
18002 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); | 16993 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); |
18003 AbstractType& instantiated_ref_type = AbstractType::Handle(); | 16994 AbstractType& instantiated_ref_type = AbstractType::Handle(); |
18004 instantiated_ref_type = ref_type.InstantiateFrom( | 16995 instantiated_ref_type = ref_type.InstantiateFrom( |
18005 instantiator_type_arguments, function_type_arguments, bound_error, | 16996 instantiator_type_arguments, function_type_arguments, bound_error, |
18006 instantiation_trail, bound_trail, space); | 16997 instantiation_trail, bound_trail, space); |
18007 ASSERT(!instantiated_ref_type.IsTypeRef()); | 16998 ASSERT(!instantiated_ref_type.IsTypeRef()); |
18008 instantiated_type_ref.set_type(instantiated_ref_type); | 16999 instantiated_type_ref.set_type(instantiated_ref_type); |
18009 return instantiated_type_ref.raw(); | 17000 return instantiated_type_ref.raw(); |
18010 } | 17001 } |
18011 | 17002 |
18012 | |
18013 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, | 17003 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, |
18014 TrailPtr trail) const { | 17004 TrailPtr trail) const { |
18015 TypeRef& cloned_type_ref = TypeRef::Handle(); | 17005 TypeRef& cloned_type_ref = TypeRef::Handle(); |
18016 cloned_type_ref ^= OnlyBuddyInTrail(trail); | 17006 cloned_type_ref ^= OnlyBuddyInTrail(trail); |
18017 if (!cloned_type_ref.IsNull()) { | 17007 if (!cloned_type_ref.IsNull()) { |
18018 return cloned_type_ref.raw(); | 17008 return cloned_type_ref.raw(); |
18019 } | 17009 } |
18020 cloned_type_ref = TypeRef::New(); | 17010 cloned_type_ref = TypeRef::New(); |
18021 AddOnlyBuddyToTrail(&trail, cloned_type_ref); | 17011 AddOnlyBuddyToTrail(&trail, cloned_type_ref); |
18022 AbstractType& ref_type = AbstractType::Handle(type()); | 17012 AbstractType& ref_type = AbstractType::Handle(type()); |
18023 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); | 17013 ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); |
18024 AbstractType& cloned_ref_type = AbstractType::Handle(); | 17014 AbstractType& cloned_ref_type = AbstractType::Handle(); |
18025 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); | 17015 cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); |
18026 ASSERT(!cloned_ref_type.IsTypeRef()); | 17016 ASSERT(!cloned_ref_type.IsTypeRef()); |
18027 cloned_type_ref.set_type(cloned_ref_type); | 17017 cloned_type_ref.set_type(cloned_ref_type); |
18028 return cloned_type_ref.raw(); | 17018 return cloned_type_ref.raw(); |
18029 } | 17019 } |
18030 | 17020 |
18031 | |
18032 void TypeRef::set_type(const AbstractType& value) const { | 17021 void TypeRef::set_type(const AbstractType& value) const { |
18033 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); | 17022 ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); |
18034 ASSERT(!value.IsTypeRef()); | 17023 ASSERT(!value.IsTypeRef()); |
18035 StorePointer(&raw_ptr()->type_, value.raw()); | 17024 StorePointer(&raw_ptr()->type_, value.raw()); |
18036 } | 17025 } |
18037 | 17026 |
18038 | |
18039 // A TypeRef cannot be canonical by definition. Only its referenced type can be. | 17027 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |
18040 // Consider the type Derived, where class Derived extends Base<Derived>. | 17028 // Consider the type Derived, where class Derived extends Base<Derived>. |
18041 // The first type argument of its flattened type argument vector is Derived, | 17029 // The first type argument of its flattened type argument vector is Derived, |
18042 // represented by a TypeRef pointing to itself. | 17030 // represented by a TypeRef pointing to itself. |
18043 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const { | 17031 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const { |
18044 if (TestAndAddToTrail(&trail)) { | 17032 if (TestAndAddToTrail(&trail)) { |
18045 return raw(); | 17033 return raw(); |
18046 } | 17034 } |
18047 // TODO(regis): Try to reduce the number of nodes required to represent the | 17035 // TODO(regis): Try to reduce the number of nodes required to represent the |
18048 // referenced recursive type. | 17036 // referenced recursive type. |
18049 AbstractType& ref_type = AbstractType::Handle(type()); | 17037 AbstractType& ref_type = AbstractType::Handle(type()); |
18050 ASSERT(!ref_type.IsNull()); | 17038 ASSERT(!ref_type.IsNull()); |
18051 ref_type = ref_type.Canonicalize(trail); | 17039 ref_type = ref_type.Canonicalize(trail); |
18052 set_type(ref_type); | 17040 set_type(ref_type); |
18053 return raw(); | 17041 return raw(); |
18054 } | 17042 } |
18055 | 17043 |
18056 | |
18057 #if defined(DEBUG) | 17044 #if defined(DEBUG) |
18058 bool TypeRef::CheckIsCanonical(Thread* thread) const { | 17045 bool TypeRef::CheckIsCanonical(Thread* thread) const { |
18059 AbstractType& ref_type = AbstractType::Handle(type()); | 17046 AbstractType& ref_type = AbstractType::Handle(type()); |
18060 ASSERT(!ref_type.IsNull()); | 17047 ASSERT(!ref_type.IsNull()); |
18061 return ref_type.CheckIsCanonical(thread); | 17048 return ref_type.CheckIsCanonical(thread); |
18062 } | 17049 } |
18063 #endif // DEBUG | 17050 #endif // DEBUG |
18064 | 17051 |
18065 | |
18066 RawString* TypeRef::EnumerateURIs() const { | 17052 RawString* TypeRef::EnumerateURIs() const { |
18067 Thread* thread = Thread::Current(); | 17053 Thread* thread = Thread::Current(); |
18068 Zone* zone = thread->zone(); | 17054 Zone* zone = thread->zone(); |
18069 const AbstractType& ref_type = AbstractType::Handle(zone, type()); | 17055 const AbstractType& ref_type = AbstractType::Handle(zone, type()); |
18070 ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType()); | 17056 ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType()); |
18071 GrowableHandlePtrArray<const String> pieces(zone, 6); | 17057 GrowableHandlePtrArray<const String> pieces(zone, 6); |
18072 const Class& cls = Class::Handle(zone, ref_type.type_class()); | 17058 const Class& cls = Class::Handle(zone, ref_type.type_class()); |
18073 pieces.Add(Symbols::TwoSpaces()); | 17059 pieces.Add(Symbols::TwoSpaces()); |
18074 pieces.Add(String::Handle(zone, cls.UserVisibleName())); | 17060 pieces.Add(String::Handle(zone, cls.UserVisibleName())); |
18075 // Break cycle by not printing type arguments, but '<optimized out>' instead. | 17061 // Break cycle by not printing type arguments, but '<optimized out>' instead. |
18076 pieces.Add(Symbols::OptimizedOut()); | 17062 pieces.Add(Symbols::OptimizedOut()); |
18077 pieces.Add(Symbols::SpaceIsFromSpace()); | 17063 pieces.Add(Symbols::SpaceIsFromSpace()); |
18078 const Library& library = Library::Handle(zone, cls.library()); | 17064 const Library& library = Library::Handle(zone, cls.library()); |
18079 pieces.Add(String::Handle(zone, library.url())); | 17065 pieces.Add(String::Handle(zone, library.url())); |
18080 pieces.Add(Symbols::NewLine()); | 17066 pieces.Add(Symbols::NewLine()); |
18081 return Symbols::FromConcatAll(thread, pieces); | 17067 return Symbols::FromConcatAll(thread, pieces); |
18082 } | 17068 } |
18083 | 17069 |
18084 | |
18085 intptr_t TypeRef::Hash() const { | 17070 intptr_t TypeRef::Hash() const { |
18086 // Do not calculate the hash of the referenced type to avoid divergence. | 17071 // Do not calculate the hash of the referenced type to avoid divergence. |
18087 const AbstractType& ref_type = AbstractType::Handle(type()); | 17072 const AbstractType& ref_type = AbstractType::Handle(type()); |
18088 ASSERT(!ref_type.IsNull()); | 17073 ASSERT(!ref_type.IsNull()); |
18089 const uint32_t result = Class::Handle(ref_type.type_class()).id(); | 17074 const uint32_t result = Class::Handle(ref_type.type_class()).id(); |
18090 return FinalizeHash(result, kHashBits); | 17075 return FinalizeHash(result, kHashBits); |
18091 } | 17076 } |
18092 | 17077 |
18093 | |
18094 RawTypeRef* TypeRef::New() { | 17078 RawTypeRef* TypeRef::New() { |
18095 RawObject* raw = | 17079 RawObject* raw = |
18096 Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld); | 17080 Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld); |
18097 return reinterpret_cast<RawTypeRef*>(raw); | 17081 return reinterpret_cast<RawTypeRef*>(raw); |
18098 } | 17082 } |
18099 | 17083 |
18100 | |
18101 RawTypeRef* TypeRef::New(const AbstractType& type) { | 17084 RawTypeRef* TypeRef::New(const AbstractType& type) { |
18102 const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 17085 const TypeRef& result = TypeRef::Handle(TypeRef::New()); |
18103 result.set_type(type); | 17086 result.set_type(type); |
18104 return result.raw(); | 17087 return result.raw(); |
18105 } | 17088 } |
18106 | 17089 |
18107 | |
18108 const char* TypeRef::ToCString() const { | 17090 const char* TypeRef::ToCString() const { |
18109 AbstractType& ref_type = AbstractType::Handle(type()); | 17091 AbstractType& ref_type = AbstractType::Handle(type()); |
18110 if (ref_type.IsNull()) { | 17092 if (ref_type.IsNull()) { |
18111 return "TypeRef: null"; | 17093 return "TypeRef: null"; |
18112 } | 17094 } |
18113 const char* type_cstr = | 17095 const char* type_cstr = |
18114 String::Handle(Class::Handle(type_class()).Name()).ToCString(); | 17096 String::Handle(Class::Handle(type_class()).Name()).ToCString(); |
18115 if (ref_type.IsFinalized()) { | 17097 if (ref_type.IsFinalized()) { |
18116 const intptr_t hash = ref_type.Hash(); | 17098 const intptr_t hash = ref_type.Hash(); |
18117 return OS::SCreate(Thread::Current()->zone(), | 17099 return OS::SCreate(Thread::Current()->zone(), |
18118 "TypeRef: %s<...> (@%p H%" Px ")", type_cstr, | 17100 "TypeRef: %s<...> (@%p H%" Px ")", type_cstr, |
18119 ref_type.raw(), hash); | 17101 ref_type.raw(), hash); |
18120 } else { | 17102 } else { |
18121 return OS::SCreate(Thread::Current()->zone(), "TypeRef: %s<...>", | 17103 return OS::SCreate(Thread::Current()->zone(), "TypeRef: %s<...>", |
18122 type_cstr); | 17104 type_cstr); |
18123 } | 17105 } |
18124 } | 17106 } |
18125 | 17107 |
18126 | |
18127 void TypeParameter::SetIsFinalized() const { | 17108 void TypeParameter::SetIsFinalized() const { |
18128 ASSERT(!IsFinalized()); | 17109 ASSERT(!IsFinalized()); |
18129 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 17110 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
18130 } | 17111 } |
18131 | 17112 |
18132 | |
18133 bool TypeParameter::IsInstantiated(Genericity genericity, | 17113 bool TypeParameter::IsInstantiated(Genericity genericity, |
18134 intptr_t num_free_fun_type_params, | 17114 intptr_t num_free_fun_type_params, |
18135 TrailPtr trail) const { | 17115 TrailPtr trail) const { |
18136 if (IsClassTypeParameter()) { | 17116 if (IsClassTypeParameter()) { |
18137 return genericity == kFunctions; | 17117 return genericity == kFunctions; |
18138 } | 17118 } |
18139 ASSERT(IsFunctionTypeParameter()); | 17119 ASSERT(IsFunctionTypeParameter()); |
18140 ASSERT(IsFinalized()); | 17120 ASSERT(IsFinalized()); |
18141 return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params); | 17121 return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params); |
18142 } | 17122 } |
18143 | 17123 |
18144 | |
18145 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { | 17124 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { |
18146 if (raw() == other.raw()) { | 17125 if (raw() == other.raw()) { |
18147 return true; | 17126 return true; |
18148 } | 17127 } |
18149 if (other.IsTypeRef()) { | 17128 if (other.IsTypeRef()) { |
18150 // Unfold right hand type. Divergence is controlled by left hand type. | 17129 // Unfold right hand type. Divergence is controlled by left hand type. |
18151 const AbstractType& other_ref_type = | 17130 const AbstractType& other_ref_type = |
18152 AbstractType::Handle(TypeRef::Cast(other).type()); | 17131 AbstractType::Handle(TypeRef::Cast(other).type()); |
18153 ASSERT(!other_ref_type.IsTypeRef()); | 17132 ASSERT(!other_ref_type.IsTypeRef()); |
18154 return IsEquivalent(other_ref_type, trail); | 17133 return IsEquivalent(other_ref_type, trail); |
18155 } | 17134 } |
18156 if (!other.IsTypeParameter()) { | 17135 if (!other.IsTypeParameter()) { |
18157 return false; | 17136 return false; |
18158 } | 17137 } |
18159 const TypeParameter& other_type_param = TypeParameter::Cast(other); | 17138 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
18160 if (parameterized_class_id() != other_type_param.parameterized_class_id()) { | 17139 if (parameterized_class_id() != other_type_param.parameterized_class_id()) { |
18161 return false; | 17140 return false; |
18162 } | 17141 } |
18163 // The function doesn't matter in type tests, but it does in canonicalization. | 17142 // The function doesn't matter in type tests, but it does in canonicalization. |
18164 if (parameterized_function() != other_type_param.parameterized_function()) { | 17143 if (parameterized_function() != other_type_param.parameterized_function()) { |
18165 return false; | 17144 return false; |
18166 } | 17145 } |
18167 if (IsFinalized() == other_type_param.IsFinalized()) { | 17146 if (IsFinalized() == other_type_param.IsFinalized()) { |
18168 return (index() == other_type_param.index()); | 17147 return (index() == other_type_param.index()); |
18169 } | 17148 } |
18170 return name() == other_type_param.name(); | 17149 return name() == other_type_param.name(); |
18171 } | 17150 } |
18172 | 17151 |
18173 | |
18174 void TypeParameter::set_parameterized_class(const Class& value) const { | 17152 void TypeParameter::set_parameterized_class(const Class& value) const { |
18175 // Set value may be null. | 17153 // Set value may be null. |
18176 classid_t cid = kFunctionCid; // Denotes a function type parameter. | 17154 classid_t cid = kFunctionCid; // Denotes a function type parameter. |
18177 if (!value.IsNull()) { | 17155 if (!value.IsNull()) { |
18178 cid = value.id(); | 17156 cid = value.id(); |
18179 } | 17157 } |
18180 StoreNonPointer(&raw_ptr()->parameterized_class_id_, cid); | 17158 StoreNonPointer(&raw_ptr()->parameterized_class_id_, cid); |
18181 } | 17159 } |
18182 | 17160 |
18183 | |
18184 classid_t TypeParameter::parameterized_class_id() const { | 17161 classid_t TypeParameter::parameterized_class_id() const { |
18185 return raw_ptr()->parameterized_class_id_; | 17162 return raw_ptr()->parameterized_class_id_; |
18186 } | 17163 } |
18187 | 17164 |
18188 | |
18189 RawClass* TypeParameter::parameterized_class() const { | 17165 RawClass* TypeParameter::parameterized_class() const { |
18190 classid_t cid = parameterized_class_id(); | 17166 classid_t cid = parameterized_class_id(); |
18191 if (cid == kFunctionCid) { | 17167 if (cid == kFunctionCid) { |
18192 return Class::null(); | 17168 return Class::null(); |
18193 } | 17169 } |
18194 return Isolate::Current()->class_table()->At(cid); | 17170 return Isolate::Current()->class_table()->At(cid); |
18195 } | 17171 } |
18196 | 17172 |
18197 | |
18198 void TypeParameter::set_parameterized_function(const Function& value) const { | 17173 void TypeParameter::set_parameterized_function(const Function& value) const { |
18199 StorePointer(&raw_ptr()->parameterized_function_, value.raw()); | 17174 StorePointer(&raw_ptr()->parameterized_function_, value.raw()); |
18200 } | 17175 } |
18201 | 17176 |
18202 | |
18203 void TypeParameter::set_index(intptr_t value) const { | 17177 void TypeParameter::set_index(intptr_t value) const { |
18204 ASSERT(value >= 0); | 17178 ASSERT(value >= 0); |
18205 ASSERT(Utils::IsInt(16, value)); | 17179 ASSERT(Utils::IsInt(16, value)); |
18206 StoreNonPointer(&raw_ptr()->index_, value); | 17180 StoreNonPointer(&raw_ptr()->index_, value); |
18207 } | 17181 } |
18208 | 17182 |
18209 | |
18210 void TypeParameter::set_name(const String& value) const { | 17183 void TypeParameter::set_name(const String& value) const { |
18211 ASSERT(value.IsSymbol()); | 17184 ASSERT(value.IsSymbol()); |
18212 StorePointer(&raw_ptr()->name_, value.raw()); | 17185 StorePointer(&raw_ptr()->name_, value.raw()); |
18213 } | 17186 } |
18214 | 17187 |
18215 | |
18216 void TypeParameter::set_bound(const AbstractType& value) const { | 17188 void TypeParameter::set_bound(const AbstractType& value) const { |
18217 StorePointer(&raw_ptr()->bound_, value.raw()); | 17189 StorePointer(&raw_ptr()->bound_, value.raw()); |
18218 } | 17190 } |
18219 | 17191 |
18220 | |
18221 RawAbstractType* TypeParameter::InstantiateFrom( | 17192 RawAbstractType* TypeParameter::InstantiateFrom( |
18222 const TypeArguments& instantiator_type_arguments, | 17193 const TypeArguments& instantiator_type_arguments, |
18223 const TypeArguments& function_type_arguments, | 17194 const TypeArguments& function_type_arguments, |
18224 Error* bound_error, | 17195 Error* bound_error, |
18225 TrailPtr instantiation_trail, | 17196 TrailPtr instantiation_trail, |
18226 TrailPtr bound_trail, | 17197 TrailPtr bound_trail, |
18227 Heap::Space space) const { | 17198 Heap::Space space) const { |
18228 ASSERT(IsFinalized()); | 17199 ASSERT(IsFinalized()); |
18229 if (IsFunctionTypeParameter()) { | 17200 if (IsFunctionTypeParameter()) { |
18230 // We make the distinction between a null function_type_arguments vector, | 17201 // We make the distinction between a null function_type_arguments vector, |
(...skipping 23 matching lines...) Expand all Loading... |
18254 // it is still uninstantiated and that we are instantiating at finalization | 17225 // it is still uninstantiated and that we are instantiating at finalization |
18255 // time (i.e. compile time). | 17226 // time (i.e. compile time). |
18256 // Indeed, the instantiator (type arguments of an instance) is always | 17227 // Indeed, the instantiator (type arguments of an instance) is always |
18257 // instantiated at run time and any bounds were checked during allocation. | 17228 // instantiated at run time and any bounds were checked during allocation. |
18258 // Similarly, function type arguments are always instantiated before being | 17229 // Similarly, function type arguments are always instantiated before being |
18259 // passed to a function at run time and bounds are checked as part of the | 17230 // passed to a function at run time and bounds are checked as part of the |
18260 // signature compatibility check (during call resolution or in the function | 17231 // signature compatibility check (during call resolution or in the function |
18261 // prolog). | 17232 // prolog). |
18262 } | 17233 } |
18263 | 17234 |
18264 | |
18265 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 17235 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
18266 const AbstractType& upper_bound, | 17236 const AbstractType& upper_bound, |
18267 Error* bound_error, | 17237 Error* bound_error, |
18268 TrailPtr bound_trail, | 17238 TrailPtr bound_trail, |
18269 Heap::Space space) const { | 17239 Heap::Space space) const { |
18270 ASSERT((bound_error != NULL) && bound_error->IsNull()); | 17240 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
18271 ASSERT(bounded_type.IsFinalized()); | 17241 ASSERT(bounded_type.IsFinalized()); |
18272 ASSERT(upper_bound.IsFinalized()); | 17242 ASSERT(upper_bound.IsFinalized()); |
18273 ASSERT(!bounded_type.IsMalformed()); | 17243 ASSERT(!bounded_type.IsMalformed()); |
18274 if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { | 17244 if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18317 type_param_name.ToCString(), class_name.ToCString(), | 17287 type_param_name.ToCString(), class_name.ToCString(), |
18318 declared_bound_name.ToCString(), bounded_type_name.ToCString(), | 17288 declared_bound_name.ToCString(), bounded_type_name.ToCString(), |
18319 upper_bound_name.ToCString(), | 17289 upper_bound_name.ToCString(), |
18320 String::Handle(bounded_type.EnumerateURIs()).ToCString(), | 17290 String::Handle(bounded_type.EnumerateURIs()).ToCString(), |
18321 String::Handle(upper_bound.EnumerateURIs()).ToCString()); | 17291 String::Handle(upper_bound.EnumerateURIs()).ToCString()); |
18322 } | 17292 } |
18323 } | 17293 } |
18324 return false; | 17294 return false; |
18325 } | 17295 } |
18326 | 17296 |
18327 | |
18328 RawAbstractType* TypeParameter::CloneUnfinalized() const { | 17297 RawAbstractType* TypeParameter::CloneUnfinalized() const { |
18329 if (IsFinalized()) { | 17298 if (IsFinalized()) { |
18330 return raw(); | 17299 return raw(); |
18331 } | 17300 } |
18332 // No need to clone bound, as it is not part of the finalization state. | 17301 // No need to clone bound, as it is not part of the finalization state. |
18333 return TypeParameter::New(Class::Handle(parameterized_class()), | 17302 return TypeParameter::New(Class::Handle(parameterized_class()), |
18334 Function::Handle(parameterized_function()), index(), | 17303 Function::Handle(parameterized_function()), index(), |
18335 String::Handle(name()), | 17304 String::Handle(name()), |
18336 AbstractType::Handle(bound()), token_pos()); | 17305 AbstractType::Handle(bound()), token_pos()); |
18337 } | 17306 } |
18338 | 17307 |
18339 | |
18340 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, | 17308 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, |
18341 TrailPtr trail) const { | 17309 TrailPtr trail) const { |
18342 ASSERT(IsFinalized()); | 17310 ASSERT(IsFinalized()); |
18343 Thread* thread = Thread::Current(); | 17311 Thread* thread = Thread::Current(); |
18344 Zone* zone = thread->zone(); | 17312 Zone* zone = thread->zone(); |
18345 TypeParameter& clone = TypeParameter::Handle(zone); | 17313 TypeParameter& clone = TypeParameter::Handle(zone); |
18346 clone ^= OnlyBuddyInTrail(trail); | 17314 clone ^= OnlyBuddyInTrail(trail); |
18347 if (!clone.IsNull()) { | 17315 if (!clone.IsNull()) { |
18348 return clone.raw(); | 17316 return clone.raw(); |
18349 } | 17317 } |
(...skipping 12 matching lines...) Expand all Loading... |
18362 clone = TypeParameter::New(cls, fun, new_index, String::Handle(zone, name()), | 17330 clone = TypeParameter::New(cls, fun, new_index, String::Handle(zone, name()), |
18363 upper_bound, // Not cloned yet. | 17331 upper_bound, // Not cloned yet. |
18364 token_pos()); | 17332 token_pos()); |
18365 clone.SetIsFinalized(); | 17333 clone.SetIsFinalized(); |
18366 AddOnlyBuddyToTrail(&trail, clone); | 17334 AddOnlyBuddyToTrail(&trail, clone); |
18367 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 17335 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |
18368 clone.set_bound(upper_bound); | 17336 clone.set_bound(upper_bound); |
18369 return clone.raw(); | 17337 return clone.raw(); |
18370 } | 17338 } |
18371 | 17339 |
18372 | |
18373 RawString* TypeParameter::EnumerateURIs() const { | 17340 RawString* TypeParameter::EnumerateURIs() const { |
18374 Thread* thread = Thread::Current(); | 17341 Thread* thread = Thread::Current(); |
18375 Zone* zone = thread->zone(); | 17342 Zone* zone = thread->zone(); |
18376 GrowableHandlePtrArray<const String> pieces(zone, 4); | 17343 GrowableHandlePtrArray<const String> pieces(zone, 4); |
18377 pieces.Add(Symbols::TwoSpaces()); | 17344 pieces.Add(Symbols::TwoSpaces()); |
18378 pieces.Add(String::Handle(zone, name())); | 17345 pieces.Add(String::Handle(zone, name())); |
18379 Class& cls = Class::Handle(zone, parameterized_class()); | 17346 Class& cls = Class::Handle(zone, parameterized_class()); |
18380 if (cls.IsNull()) { | 17347 if (cls.IsNull()) { |
18381 const Function& fun = Function::Handle(zone, parameterized_function()); | 17348 const Function& fun = Function::Handle(zone, parameterized_function()); |
18382 pieces.Add(Symbols::SpaceOfSpace()); | 17349 pieces.Add(Symbols::SpaceOfSpace()); |
18383 pieces.Add(String::Handle(zone, fun.UserVisibleName())); | 17350 pieces.Add(String::Handle(zone, fun.UserVisibleName())); |
18384 cls = fun.Owner(); // May be null. | 17351 cls = fun.Owner(); // May be null. |
18385 // TODO(regis): Should we keep the function owner for better error messages? | 17352 // TODO(regis): Should we keep the function owner for better error messages? |
18386 } | 17353 } |
18387 if (!cls.IsNull()) { | 17354 if (!cls.IsNull()) { |
18388 pieces.Add(Symbols::SpaceOfSpace()); | 17355 pieces.Add(Symbols::SpaceOfSpace()); |
18389 pieces.Add(String::Handle(zone, cls.UserVisibleName())); | 17356 pieces.Add(String::Handle(zone, cls.UserVisibleName())); |
18390 pieces.Add(Symbols::SpaceIsFromSpace()); | 17357 pieces.Add(Symbols::SpaceIsFromSpace()); |
18391 const Library& library = Library::Handle(zone, cls.library()); | 17358 const Library& library = Library::Handle(zone, cls.library()); |
18392 pieces.Add(String::Handle(zone, library.url())); | 17359 pieces.Add(String::Handle(zone, library.url())); |
18393 } | 17360 } |
18394 pieces.Add(Symbols::NewLine()); | 17361 pieces.Add(Symbols::NewLine()); |
18395 return Symbols::FromConcatAll(thread, pieces); | 17362 return Symbols::FromConcatAll(thread, pieces); |
18396 } | 17363 } |
18397 | 17364 |
18398 | |
18399 intptr_t TypeParameter::ComputeHash() const { | 17365 intptr_t TypeParameter::ComputeHash() const { |
18400 ASSERT(IsFinalized()); | 17366 ASSERT(IsFinalized()); |
18401 uint32_t result; | 17367 uint32_t result; |
18402 if (IsClassTypeParameter()) { | 17368 if (IsClassTypeParameter()) { |
18403 result = parameterized_class_id(); | 17369 result = parameterized_class_id(); |
18404 } else { | 17370 } else { |
18405 result = Function::Handle(parameterized_function()).Hash(); | 17371 result = Function::Handle(parameterized_function()).Hash(); |
18406 } | 17372 } |
18407 // No need to include the hash of the bound, since the type parameter is fully | 17373 // No need to include the hash of the bound, since the type parameter is fully |
18408 // identified by its class and index. | 17374 // identified by its class and index. |
18409 result = CombineHashes(result, index()); | 17375 result = CombineHashes(result, index()); |
18410 result = FinalizeHash(result, kHashBits); | 17376 result = FinalizeHash(result, kHashBits); |
18411 SetHash(result); | 17377 SetHash(result); |
18412 return result; | 17378 return result; |
18413 } | 17379 } |
18414 | 17380 |
18415 | |
18416 RawTypeParameter* TypeParameter::New() { | 17381 RawTypeParameter* TypeParameter::New() { |
18417 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 17382 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
18418 TypeParameter::InstanceSize(), Heap::kOld); | 17383 TypeParameter::InstanceSize(), Heap::kOld); |
18419 return reinterpret_cast<RawTypeParameter*>(raw); | 17384 return reinterpret_cast<RawTypeParameter*>(raw); |
18420 } | 17385 } |
18421 | 17386 |
18422 | |
18423 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, | 17387 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, |
18424 const Function& parameterized_function, | 17388 const Function& parameterized_function, |
18425 intptr_t index, | 17389 intptr_t index, |
18426 const String& name, | 17390 const String& name, |
18427 const AbstractType& bound, | 17391 const AbstractType& bound, |
18428 TokenPosition token_pos) { | 17392 TokenPosition token_pos) { |
18429 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); | 17393 ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); |
18430 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); | 17394 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |
18431 result.set_parameterized_class(parameterized_class); | 17395 result.set_parameterized_class(parameterized_class); |
18432 result.set_parameterized_function(parameterized_function); | 17396 result.set_parameterized_function(parameterized_function); |
18433 result.set_index(index); | 17397 result.set_index(index); |
18434 result.set_name(name); | 17398 result.set_name(name); |
18435 result.set_bound(bound); | 17399 result.set_bound(bound); |
18436 result.SetHash(0); | 17400 result.SetHash(0); |
18437 result.set_token_pos(token_pos); | 17401 result.set_token_pos(token_pos); |
18438 result.StoreNonPointer(&result.raw_ptr()->type_state_, | 17402 result.StoreNonPointer(&result.raw_ptr()->type_state_, |
18439 RawTypeParameter::kAllocated); | 17403 RawTypeParameter::kAllocated); |
18440 return result.raw(); | 17404 return result.raw(); |
18441 } | 17405 } |
18442 | 17406 |
18443 | |
18444 void TypeParameter::set_token_pos(TokenPosition token_pos) const { | 17407 void TypeParameter::set_token_pos(TokenPosition token_pos) const { |
18445 ASSERT(!token_pos.IsClassifying()); | 17408 ASSERT(!token_pos.IsClassifying()); |
18446 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 17409 StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |
18447 } | 17410 } |
18448 | 17411 |
18449 | |
18450 void TypeParameter::set_type_state(int8_t state) const { | 17412 void TypeParameter::set_type_state(int8_t state) const { |
18451 ASSERT((state == RawTypeParameter::kAllocated) || | 17413 ASSERT((state == RawTypeParameter::kAllocated) || |
18452 (state == RawTypeParameter::kBeingFinalized) || | 17414 (state == RawTypeParameter::kBeingFinalized) || |
18453 (state == RawTypeParameter::kFinalizedUninstantiated)); | 17415 (state == RawTypeParameter::kFinalizedUninstantiated)); |
18454 StoreNonPointer(&raw_ptr()->type_state_, state); | 17416 StoreNonPointer(&raw_ptr()->type_state_, state); |
18455 } | 17417 } |
18456 | 17418 |
18457 | |
18458 const char* TypeParameter::ToCString() const { | 17419 const char* TypeParameter::ToCString() const { |
18459 const char* name_cstr = String::Handle(Name()).ToCString(); | 17420 const char* name_cstr = String::Handle(Name()).ToCString(); |
18460 const AbstractType& upper_bound = AbstractType::Handle(bound()); | 17421 const AbstractType& upper_bound = AbstractType::Handle(bound()); |
18461 const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); | 17422 const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); |
18462 if (IsFunctionTypeParameter()) { | 17423 if (IsFunctionTypeParameter()) { |
18463 const char* format = | 17424 const char* format = |
18464 "TypeParameter: name %s; index: %d; function: %s; bound: %s"; | 17425 "TypeParameter: name %s; index: %d; function: %s; bound: %s"; |
18465 const Function& function = Function::Handle(parameterized_function()); | 17426 const Function& function = Function::Handle(parameterized_function()); |
18466 const char* fun_cstr = String::Handle(function.name()).ToCString(); | 17427 const char* fun_cstr = String::Handle(function.name()).ToCString(); |
18467 intptr_t len = | 17428 intptr_t len = |
(...skipping 10 matching lines...) Expand all Loading... |
18478 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); | 17439 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |
18479 intptr_t len = | 17440 intptr_t len = |
18480 OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + | 17441 OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + |
18481 1; | 17442 1; |
18482 char* chars = Thread::Current()->zone()->Alloc<char>(len); | 17443 char* chars = Thread::Current()->zone()->Alloc<char>(len); |
18483 OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr, bound_cstr); | 17444 OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr, bound_cstr); |
18484 return chars; | 17445 return chars; |
18485 } | 17446 } |
18486 } | 17447 } |
18487 | 17448 |
18488 | |
18489 bool BoundedType::IsMalformed() const { | 17449 bool BoundedType::IsMalformed() const { |
18490 return AbstractType::Handle(type()).IsMalformed(); | 17450 return AbstractType::Handle(type()).IsMalformed(); |
18491 } | 17451 } |
18492 | 17452 |
18493 | |
18494 bool BoundedType::IsMalbounded() const { | 17453 bool BoundedType::IsMalbounded() const { |
18495 return AbstractType::Handle(type()).IsMalbounded(); | 17454 return AbstractType::Handle(type()).IsMalbounded(); |
18496 } | 17455 } |
18497 | 17456 |
18498 | |
18499 bool BoundedType::IsMalformedOrMalbounded() const { | 17457 bool BoundedType::IsMalformedOrMalbounded() const { |
18500 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); | 17458 return AbstractType::Handle(type()).IsMalformedOrMalbounded(); |
18501 } | 17459 } |
18502 | 17460 |
18503 | |
18504 RawLanguageError* BoundedType::error() const { | 17461 RawLanguageError* BoundedType::error() const { |
18505 return AbstractType::Handle(type()).error(); | 17462 return AbstractType::Handle(type()).error(); |
18506 } | 17463 } |
18507 | 17464 |
18508 | |
18509 bool BoundedType::IsEquivalent(const Instance& other, TrailPtr trail) const { | 17465 bool BoundedType::IsEquivalent(const Instance& other, TrailPtr trail) const { |
18510 // BoundedType are not canonicalized, because their bound may get finalized | 17466 // BoundedType are not canonicalized, because their bound may get finalized |
18511 // after the BoundedType is created and initialized. | 17467 // after the BoundedType is created and initialized. |
18512 if (raw() == other.raw()) { | 17468 if (raw() == other.raw()) { |
18513 return true; | 17469 return true; |
18514 } | 17470 } |
18515 if (other.IsTypeRef()) { | 17471 if (other.IsTypeRef()) { |
18516 // Unfold right hand type. Divergence is controlled by left hand type. | 17472 // Unfold right hand type. Divergence is controlled by left hand type. |
18517 const AbstractType& other_ref_type = | 17473 const AbstractType& other_ref_type = |
18518 AbstractType::Handle(TypeRef::Cast(other).type()); | 17474 AbstractType::Handle(TypeRef::Cast(other).type()); |
(...skipping 11 matching lines...) Expand all Loading... |
18530 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 17486 const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |
18531 if (!this_type.IsEquivalent(other_type, trail)) { | 17487 if (!this_type.IsEquivalent(other_type, trail)) { |
18532 return false; | 17488 return false; |
18533 } | 17489 } |
18534 const AbstractType& this_bound = AbstractType::Handle(bound()); | 17490 const AbstractType& this_bound = AbstractType::Handle(bound()); |
18535 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 17491 const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |
18536 return this_bound.IsFinalized() && other_bound.IsFinalized() && | 17492 return this_bound.IsFinalized() && other_bound.IsFinalized() && |
18537 this_bound.Equals(other_bound); // Different graph, do not pass trail. | 17493 this_bound.Equals(other_bound); // Different graph, do not pass trail. |
18538 } | 17494 } |
18539 | 17495 |
18540 | |
18541 bool BoundedType::IsRecursive() const { | 17496 bool BoundedType::IsRecursive() const { |
18542 return AbstractType::Handle(type()).IsRecursive(); | 17497 return AbstractType::Handle(type()).IsRecursive(); |
18543 } | 17498 } |
18544 | 17499 |
18545 | |
18546 void BoundedType::set_type(const AbstractType& value) const { | 17500 void BoundedType::set_type(const AbstractType& value) const { |
18547 ASSERT(value.IsFinalized() || value.IsBeingFinalized() || | 17501 ASSERT(value.IsFinalized() || value.IsBeingFinalized() || |
18548 value.IsTypeParameter()); | 17502 value.IsTypeParameter()); |
18549 ASSERT(!value.IsMalformed()); | 17503 ASSERT(!value.IsMalformed()); |
18550 StorePointer(&raw_ptr()->type_, value.raw()); | 17504 StorePointer(&raw_ptr()->type_, value.raw()); |
18551 } | 17505 } |
18552 | 17506 |
18553 | |
18554 void BoundedType::set_bound(const AbstractType& value) const { | 17507 void BoundedType::set_bound(const AbstractType& value) const { |
18555 // The bound may still be unfinalized because of legal cycles. | 17508 // The bound may still be unfinalized because of legal cycles. |
18556 // It must be finalized before it is checked at run time, though. | 17509 // It must be finalized before it is checked at run time, though. |
18557 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); | 17510 ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |
18558 StorePointer(&raw_ptr()->bound_, value.raw()); | 17511 StorePointer(&raw_ptr()->bound_, value.raw()); |
18559 } | 17512 } |
18560 | 17513 |
18561 | |
18562 void BoundedType::set_type_parameter(const TypeParameter& value) const { | 17514 void BoundedType::set_type_parameter(const TypeParameter& value) const { |
18563 // A null type parameter is set when marking a type malformed because of a | 17515 // A null type parameter is set when marking a type malformed because of a |
18564 // bound error at compile time. | 17516 // bound error at compile time. |
18565 ASSERT(value.IsNull() || value.IsFinalized()); | 17517 ASSERT(value.IsNull() || value.IsFinalized()); |
18566 StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 17518 StorePointer(&raw_ptr()->type_parameter_, value.raw()); |
18567 } | 17519 } |
18568 | 17520 |
18569 | |
18570 RawAbstractType* BoundedType::InstantiateFrom( | 17521 RawAbstractType* BoundedType::InstantiateFrom( |
18571 const TypeArguments& instantiator_type_arguments, | 17522 const TypeArguments& instantiator_type_arguments, |
18572 const TypeArguments& function_type_arguments, | 17523 const TypeArguments& function_type_arguments, |
18573 Error* bound_error, | 17524 Error* bound_error, |
18574 TrailPtr instantiation_trail, | 17525 TrailPtr instantiation_trail, |
18575 TrailPtr bound_trail, | 17526 TrailPtr bound_trail, |
18576 Heap::Space space) const { | 17527 Heap::Space space) const { |
18577 ASSERT(IsFinalized()); | 17528 ASSERT(IsFinalized()); |
18578 AbstractType& bounded_type = AbstractType::Handle(type()); | 17529 AbstractType& bounded_type = AbstractType::Handle(type()); |
18579 ASSERT(bounded_type.IsFinalized()); | 17530 ASSERT(bounded_type.IsFinalized()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18634 // or partially instantiated bounded_type and upper_bound, but keeping | 17585 // or partially instantiated bounded_type and upper_bound, but keeping |
18635 // type_param. | 17586 // type_param. |
18636 instantiated_bounded_type = BoundedType::New( | 17587 instantiated_bounded_type = BoundedType::New( |
18637 instantiated_bounded_type, instantiated_upper_bound, type_param); | 17588 instantiated_bounded_type, instantiated_upper_bound, type_param); |
18638 } | 17589 } |
18639 } | 17590 } |
18640 } | 17591 } |
18641 return instantiated_bounded_type.raw(); | 17592 return instantiated_bounded_type.raw(); |
18642 } | 17593 } |
18643 | 17594 |
18644 | |
18645 RawAbstractType* BoundedType::CloneUnfinalized() const { | 17595 RawAbstractType* BoundedType::CloneUnfinalized() const { |
18646 if (IsFinalized()) { | 17596 if (IsFinalized()) { |
18647 return raw(); | 17597 return raw(); |
18648 } | 17598 } |
18649 const AbstractType& bounded_type = AbstractType::Handle(type()); | 17599 const AbstractType& bounded_type = AbstractType::Handle(type()); |
18650 const AbstractType& bounded_type_clone = | 17600 const AbstractType& bounded_type_clone = |
18651 AbstractType::Handle(bounded_type.CloneUnfinalized()); | 17601 AbstractType::Handle(bounded_type.CloneUnfinalized()); |
18652 if (bounded_type_clone.raw() == bounded_type.raw()) { | 17602 if (bounded_type_clone.raw() == bounded_type.raw()) { |
18653 return raw(); | 17603 return raw(); |
18654 } | 17604 } |
18655 // No need to clone bound or type parameter, as they are not part of the | 17605 // No need to clone bound or type parameter, as they are not part of the |
18656 // finalization state of this bounded type. | 17606 // finalization state of this bounded type. |
18657 return BoundedType::New(bounded_type, AbstractType::Handle(bound()), | 17607 return BoundedType::New(bounded_type, AbstractType::Handle(bound()), |
18658 TypeParameter::Handle(type_parameter())); | 17608 TypeParameter::Handle(type_parameter())); |
18659 } | 17609 } |
18660 | 17610 |
18661 | |
18662 RawAbstractType* BoundedType::CloneUninstantiated(const Class& new_owner, | 17611 RawAbstractType* BoundedType::CloneUninstantiated(const Class& new_owner, |
18663 TrailPtr trail) const { | 17612 TrailPtr trail) const { |
18664 if (IsInstantiated()) { | 17613 if (IsInstantiated()) { |
18665 return raw(); | 17614 return raw(); |
18666 } | 17615 } |
18667 AbstractType& bounded_type = AbstractType::Handle(type()); | 17616 AbstractType& bounded_type = AbstractType::Handle(type()); |
18668 bounded_type = bounded_type.CloneUninstantiated(new_owner, trail); | 17617 bounded_type = bounded_type.CloneUninstantiated(new_owner, trail); |
18669 AbstractType& upper_bound = AbstractType::Handle(bound()); | 17618 AbstractType& upper_bound = AbstractType::Handle(bound()); |
18670 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 17619 upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |
18671 TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 17620 TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
18672 type_param ^= type_param.CloneUninstantiated(new_owner, trail); | 17621 type_param ^= type_param.CloneUninstantiated(new_owner, trail); |
18673 return BoundedType::New(bounded_type, upper_bound, type_param); | 17622 return BoundedType::New(bounded_type, upper_bound, type_param); |
18674 } | 17623 } |
18675 | 17624 |
18676 | |
18677 RawString* BoundedType::EnumerateURIs() const { | 17625 RawString* BoundedType::EnumerateURIs() const { |
18678 // The bound does not appear in the user visible name. | 17626 // The bound does not appear in the user visible name. |
18679 return AbstractType::Handle(type()).EnumerateURIs(); | 17627 return AbstractType::Handle(type()).EnumerateURIs(); |
18680 } | 17628 } |
18681 | 17629 |
18682 | |
18683 intptr_t BoundedType::ComputeHash() const { | 17630 intptr_t BoundedType::ComputeHash() const { |
18684 uint32_t result = AbstractType::Handle(type()).Hash(); | 17631 uint32_t result = AbstractType::Handle(type()).Hash(); |
18685 // No need to include the hash of the bound, since the bound is defined by the | 17632 // No need to include the hash of the bound, since the bound is defined by the |
18686 // type parameter (modulo instantiation state). | 17633 // type parameter (modulo instantiation state). |
18687 result = | 17634 result = |
18688 CombineHashes(result, TypeParameter::Handle(type_parameter()).Hash()); | 17635 CombineHashes(result, TypeParameter::Handle(type_parameter()).Hash()); |
18689 result = FinalizeHash(result, kHashBits); | 17636 result = FinalizeHash(result, kHashBits); |
18690 SetHash(result); | 17637 SetHash(result); |
18691 return result; | 17638 return result; |
18692 } | 17639 } |
18693 | 17640 |
18694 | |
18695 RawBoundedType* BoundedType::New() { | 17641 RawBoundedType* BoundedType::New() { |
18696 RawObject* raw = Object::Allocate(BoundedType::kClassId, | 17642 RawObject* raw = Object::Allocate(BoundedType::kClassId, |
18697 BoundedType::InstanceSize(), Heap::kOld); | 17643 BoundedType::InstanceSize(), Heap::kOld); |
18698 return reinterpret_cast<RawBoundedType*>(raw); | 17644 return reinterpret_cast<RawBoundedType*>(raw); |
18699 } | 17645 } |
18700 | 17646 |
18701 | |
18702 RawBoundedType* BoundedType::New(const AbstractType& type, | 17647 RawBoundedType* BoundedType::New(const AbstractType& type, |
18703 const AbstractType& bound, | 17648 const AbstractType& bound, |
18704 const TypeParameter& type_parameter) { | 17649 const TypeParameter& type_parameter) { |
18705 const BoundedType& result = BoundedType::Handle(BoundedType::New()); | 17650 const BoundedType& result = BoundedType::Handle(BoundedType::New()); |
18706 result.set_type(type); | 17651 result.set_type(type); |
18707 result.set_bound(bound); | 17652 result.set_bound(bound); |
18708 result.SetHash(0); | 17653 result.SetHash(0); |
18709 result.set_type_parameter(type_parameter); | 17654 result.set_type_parameter(type_parameter); |
18710 return result.raw(); | 17655 return result.raw(); |
18711 } | 17656 } |
18712 | 17657 |
18713 | |
18714 const char* BoundedType::ToCString() const { | 17658 const char* BoundedType::ToCString() const { |
18715 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; | 17659 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; |
18716 const char* type_cstr = | 17660 const char* type_cstr = |
18717 String::Handle(AbstractType::Handle(type()).Name()).ToCString(); | 17661 String::Handle(AbstractType::Handle(type()).Name()).ToCString(); |
18718 const char* bound_cstr = | 17662 const char* bound_cstr = |
18719 String::Handle(AbstractType::Handle(bound()).Name()).ToCString(); | 17663 String::Handle(AbstractType::Handle(bound()).Name()).ToCString(); |
18720 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 17664 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
18721 const char* type_param_cstr = String::Handle(type_param.name()).ToCString(); | 17665 const char* type_param_cstr = String::Handle(type_param.name()).ToCString(); |
18722 const Class& cls = Class::Handle(type_param.parameterized_class()); | 17666 const Class& cls = Class::Handle(type_param.parameterized_class()); |
18723 const char* cls_cstr = String::Handle(cls.Name()).ToCString(); | 17667 const char* cls_cstr = String::Handle(cls.Name()).ToCString(); |
18724 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, bound_cstr, | 17668 intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, bound_cstr, |
18725 type_param_cstr, cls_cstr) + | 17669 type_param_cstr, cls_cstr) + |
18726 1; | 17670 1; |
18727 char* chars = Thread::Current()->zone()->Alloc<char>(len); | 17671 char* chars = Thread::Current()->zone()->Alloc<char>(len); |
18728 OS::SNPrint(chars, len, format, type_cstr, bound_cstr, type_param_cstr, | 17672 OS::SNPrint(chars, len, format, type_cstr, bound_cstr, type_param_cstr, |
18729 cls_cstr); | 17673 cls_cstr); |
18730 return chars; | 17674 return chars; |
18731 } | 17675 } |
18732 | 17676 |
18733 | |
18734 TokenPosition MixinAppType::token_pos() const { | 17677 TokenPosition MixinAppType::token_pos() const { |
18735 return AbstractType::Handle(MixinTypeAt(0)).token_pos(); | 17678 return AbstractType::Handle(MixinTypeAt(0)).token_pos(); |
18736 } | 17679 } |
18737 | 17680 |
18738 | |
18739 intptr_t MixinAppType::Depth() const { | 17681 intptr_t MixinAppType::Depth() const { |
18740 return Array::Handle(mixin_types()).Length(); | 17682 return Array::Handle(mixin_types()).Length(); |
18741 } | 17683 } |
18742 | 17684 |
18743 | |
18744 RawString* MixinAppType::Name() const { | 17685 RawString* MixinAppType::Name() const { |
18745 return String::New("MixinAppType"); | 17686 return String::New("MixinAppType"); |
18746 } | 17687 } |
18747 | 17688 |
18748 | |
18749 const char* MixinAppType::ToCString() const { | 17689 const char* MixinAppType::ToCString() const { |
18750 const char* format = "MixinAppType: super type: %s; first mixin type: %s"; | 17690 const char* format = "MixinAppType: super type: %s; first mixin type: %s"; |
18751 const char* super_type_cstr = | 17691 const char* super_type_cstr = |
18752 String::Handle(AbstractType::Handle(super_type()).Name()).ToCString(); | 17692 String::Handle(AbstractType::Handle(super_type()).Name()).ToCString(); |
18753 const char* first_mixin_type_cstr = | 17693 const char* first_mixin_type_cstr = |
18754 String::Handle(AbstractType::Handle(MixinTypeAt(0)).Name()).ToCString(); | 17694 String::Handle(AbstractType::Handle(MixinTypeAt(0)).Name()).ToCString(); |
18755 intptr_t len = | 17695 intptr_t len = |
18756 OS::SNPrint(NULL, 0, format, super_type_cstr, first_mixin_type_cstr) + 1; | 17696 OS::SNPrint(NULL, 0, format, super_type_cstr, first_mixin_type_cstr) + 1; |
18757 char* chars = Thread::Current()->zone()->Alloc<char>(len); | 17697 char* chars = Thread::Current()->zone()->Alloc<char>(len); |
18758 OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_type_cstr); | 17698 OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_type_cstr); |
18759 return chars; | 17699 return chars; |
18760 } | 17700 } |
18761 | 17701 |
18762 | |
18763 RawAbstractType* MixinAppType::MixinTypeAt(intptr_t depth) const { | 17702 RawAbstractType* MixinAppType::MixinTypeAt(intptr_t depth) const { |
18764 return AbstractType::RawCast(Array::Handle(mixin_types()).At(depth)); | 17703 return AbstractType::RawCast(Array::Handle(mixin_types()).At(depth)); |
18765 } | 17704 } |
18766 | 17705 |
18767 | |
18768 void MixinAppType::set_super_type(const AbstractType& value) const { | 17706 void MixinAppType::set_super_type(const AbstractType& value) const { |
18769 StorePointer(&raw_ptr()->super_type_, value.raw()); | 17707 StorePointer(&raw_ptr()->super_type_, value.raw()); |
18770 } | 17708 } |
18771 | 17709 |
18772 | |
18773 void MixinAppType::set_mixin_types(const Array& value) const { | 17710 void MixinAppType::set_mixin_types(const Array& value) const { |
18774 StorePointer(&raw_ptr()->mixin_types_, value.raw()); | 17711 StorePointer(&raw_ptr()->mixin_types_, value.raw()); |
18775 } | 17712 } |
18776 | 17713 |
18777 | |
18778 RawMixinAppType* MixinAppType::New() { | 17714 RawMixinAppType* MixinAppType::New() { |
18779 // MixinAppType objects do not survive finalization, so allocate | 17715 // MixinAppType objects do not survive finalization, so allocate |
18780 // on new heap. | 17716 // on new heap. |
18781 RawObject* raw = Object::Allocate(MixinAppType::kClassId, | 17717 RawObject* raw = Object::Allocate(MixinAppType::kClassId, |
18782 MixinAppType::InstanceSize(), Heap::kOld); | 17718 MixinAppType::InstanceSize(), Heap::kOld); |
18783 return reinterpret_cast<RawMixinAppType*>(raw); | 17719 return reinterpret_cast<RawMixinAppType*>(raw); |
18784 } | 17720 } |
18785 | 17721 |
18786 | |
18787 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, | 17722 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, |
18788 const Array& mixin_types) { | 17723 const Array& mixin_types) { |
18789 const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); | 17724 const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); |
18790 result.set_super_type(super_type); | 17725 result.set_super_type(super_type); |
18791 result.set_mixin_types(mixin_types); | 17726 result.set_mixin_types(mixin_types); |
18792 return result.raw(); | 17727 return result.raw(); |
18793 } | 17728 } |
18794 | 17729 |
18795 | |
18796 RawInstance* Number::CheckAndCanonicalize(Thread* thread, | 17730 RawInstance* Number::CheckAndCanonicalize(Thread* thread, |
18797 const char** error_str) const { | 17731 const char** error_str) const { |
18798 intptr_t cid = GetClassId(); | 17732 intptr_t cid = GetClassId(); |
18799 switch (cid) { | 17733 switch (cid) { |
18800 case kSmiCid: | 17734 case kSmiCid: |
18801 return reinterpret_cast<RawSmi*>(raw_value()); | 17735 return reinterpret_cast<RawSmi*>(raw_value()); |
18802 case kMintCid: | 17736 case kMintCid: |
18803 return Mint::NewCanonical(Mint::Cast(*this).value()); | 17737 return Mint::NewCanonical(Mint::Cast(*this).value()); |
18804 case kDoubleCid: | 17738 case kDoubleCid: |
18805 return Double::NewCanonical(Double::Cast(*this).value()); | 17739 return Double::NewCanonical(Double::Cast(*this).value()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18840 cls.InsertCanonicalNumber(zone, index, result); | 17774 cls.InsertCanonicalNumber(zone, index, result); |
18841 return result.raw(); | 17775 return result.raw(); |
18842 } | 17776 } |
18843 } | 17777 } |
18844 default: | 17778 default: |
18845 UNREACHABLE(); | 17779 UNREACHABLE(); |
18846 } | 17780 } |
18847 return Instance::null(); | 17781 return Instance::null(); |
18848 } | 17782 } |
18849 | 17783 |
18850 | |
18851 #if defined(DEBUG) | 17784 #if defined(DEBUG) |
18852 bool Number::CheckIsCanonical(Thread* thread) const { | 17785 bool Number::CheckIsCanonical(Thread* thread) const { |
18853 intptr_t cid = GetClassId(); | 17786 intptr_t cid = GetClassId(); |
18854 intptr_t idx = 0; | 17787 intptr_t idx = 0; |
18855 Zone* zone = thread->zone(); | 17788 Zone* zone = thread->zone(); |
18856 const Class& cls = Class::Handle(zone, this->clazz()); | 17789 const Class& cls = Class::Handle(zone, this->clazz()); |
18857 switch (cid) { | 17790 switch (cid) { |
18858 case kSmiCid: | 17791 case kSmiCid: |
18859 return true; | 17792 return true; |
18860 case kMintCid: { | 17793 case kMintCid: { |
(...skipping 11 matching lines...) Expand all Loading... |
18872 result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx); | 17805 result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx); |
18873 return (result.raw() == this->raw()); | 17806 return (result.raw() == this->raw()); |
18874 } | 17807 } |
18875 default: | 17808 default: |
18876 UNREACHABLE(); | 17809 UNREACHABLE(); |
18877 } | 17810 } |
18878 return false; | 17811 return false; |
18879 } | 17812 } |
18880 #endif // DEBUG | 17813 #endif // DEBUG |
18881 | 17814 |
18882 | |
18883 const char* Number::ToCString() const { | 17815 const char* Number::ToCString() const { |
18884 // Number is an interface. No instances of Number should exist. | 17816 // Number is an interface. No instances of Number should exist. |
18885 UNREACHABLE(); | 17817 UNREACHABLE(); |
18886 return "Number"; | 17818 return "Number"; |
18887 } | 17819 } |
18888 | 17820 |
18889 | |
18890 const char* Integer::ToCString() const { | 17821 const char* Integer::ToCString() const { |
18891 // Integer is an interface. No instances of Integer should exist except null. | 17822 // Integer is an interface. No instances of Integer should exist except null. |
18892 ASSERT(IsNull()); | 17823 ASSERT(IsNull()); |
18893 return "NULL Integer"; | 17824 return "NULL Integer"; |
18894 } | 17825 } |
18895 | 17826 |
18896 | |
18897 RawInteger* Integer::New(const String& str, Heap::Space space) { | 17827 RawInteger* Integer::New(const String& str, Heap::Space space) { |
18898 // We are not supposed to have integers represented as two byte strings. | 17828 // We are not supposed to have integers represented as two byte strings. |
18899 ASSERT(str.IsOneByteString()); | 17829 ASSERT(str.IsOneByteString()); |
18900 int64_t value; | 17830 int64_t value; |
18901 if (!OS::StringToInt64(str.ToCString(), &value)) { | 17831 if (!OS::StringToInt64(str.ToCString(), &value)) { |
18902 const Bigint& big = | 17832 const Bigint& big = |
18903 Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); | 17833 Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); |
18904 ASSERT(!big.FitsIntoSmi()); | 17834 ASSERT(!big.FitsIntoSmi()); |
18905 ASSERT(!big.FitsIntoInt64()); | 17835 ASSERT(!big.FitsIntoInt64()); |
18906 if (!FLAG_limit_ints_to_64_bits) { | 17836 if (!FLAG_limit_ints_to_64_bits) { |
18907 return big.raw(); | 17837 return big.raw(); |
18908 } | 17838 } |
18909 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 17839 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |
18910 value = big.AsTruncatedInt64Value(); | 17840 value = big.AsTruncatedInt64Value(); |
18911 } | 17841 } |
18912 return Integer::New(value, space); | 17842 return Integer::New(value, space); |
18913 } | 17843 } |
18914 | 17844 |
18915 | |
18916 RawInteger* Integer::NewCanonical(const String& str) { | 17845 RawInteger* Integer::NewCanonical(const String& str) { |
18917 // We are not supposed to have integers represented as two byte strings. | 17846 // We are not supposed to have integers represented as two byte strings. |
18918 ASSERT(str.IsOneByteString()); | 17847 ASSERT(str.IsOneByteString()); |
18919 int64_t value; | 17848 int64_t value; |
18920 if (!OS::StringToInt64(str.ToCString(), &value)) { | 17849 if (!OS::StringToInt64(str.ToCString(), &value)) { |
18921 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); | 17850 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); |
18922 ASSERT(!big.FitsIntoSmi()); | 17851 ASSERT(!big.FitsIntoSmi()); |
18923 ASSERT(!big.FitsIntoInt64()); | 17852 ASSERT(!big.FitsIntoInt64()); |
18924 if (!FLAG_limit_ints_to_64_bits) { | 17853 if (!FLAG_limit_ints_to_64_bits) { |
18925 return big.raw(); | 17854 return big.raw(); |
18926 } | 17855 } |
18927 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 17856 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |
18928 value = big.AsTruncatedInt64Value(); | 17857 value = big.AsTruncatedInt64Value(); |
18929 } | 17858 } |
18930 if (Smi::IsValid(value)) { | 17859 if (Smi::IsValid(value)) { |
18931 return Smi::New(static_cast<intptr_t>(value)); | 17860 return Smi::New(static_cast<intptr_t>(value)); |
18932 } | 17861 } |
18933 return Mint::NewCanonical(value); | 17862 return Mint::NewCanonical(value); |
18934 } | 17863 } |
18935 | 17864 |
18936 | |
18937 RawInteger* Integer::New(int64_t value, Heap::Space space) { | 17865 RawInteger* Integer::New(int64_t value, Heap::Space space) { |
18938 const bool is_smi = Smi::IsValid(value); | 17866 const bool is_smi = Smi::IsValid(value); |
18939 if (is_smi) { | 17867 if (is_smi) { |
18940 return Smi::New(static_cast<intptr_t>(value)); | 17868 return Smi::New(static_cast<intptr_t>(value)); |
18941 } | 17869 } |
18942 return Mint::New(value, space); | 17870 return Mint::New(value, space); |
18943 } | 17871 } |
18944 | 17872 |
18945 | |
18946 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { | 17873 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |
18947 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 17874 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
18948 if (FLAG_limit_ints_to_64_bits) { | 17875 if (FLAG_limit_ints_to_64_bits) { |
18949 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 17876 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |
18950 return Integer::New(static_cast<int64_t>(value), space); | 17877 return Integer::New(static_cast<int64_t>(value), space); |
18951 } else { | 17878 } else { |
18952 return Bigint::NewFromUint64(value, space); | 17879 return Bigint::NewFromUint64(value, space); |
18953 } | 17880 } |
18954 } else { | 17881 } else { |
18955 return Integer::New(value, space); | 17882 return Integer::New(value, space); |
18956 } | 17883 } |
18957 } | 17884 } |
18958 | 17885 |
18959 | |
18960 bool Integer::Equals(const Instance& other) const { | 17886 bool Integer::Equals(const Instance& other) const { |
18961 // Integer is an abstract class. | 17887 // Integer is an abstract class. |
18962 UNREACHABLE(); | 17888 UNREACHABLE(); |
18963 return false; | 17889 return false; |
18964 } | 17890 } |
18965 | 17891 |
18966 | |
18967 bool Integer::IsZero() const { | 17892 bool Integer::IsZero() const { |
18968 // Integer is an abstract class. | 17893 // Integer is an abstract class. |
18969 UNREACHABLE(); | 17894 UNREACHABLE(); |
18970 return false; | 17895 return false; |
18971 } | 17896 } |
18972 | 17897 |
18973 | |
18974 bool Integer::IsNegative() const { | 17898 bool Integer::IsNegative() const { |
18975 // Integer is an abstract class. | 17899 // Integer is an abstract class. |
18976 UNREACHABLE(); | 17900 UNREACHABLE(); |
18977 return false; | 17901 return false; |
18978 } | 17902 } |
18979 | 17903 |
18980 | |
18981 double Integer::AsDoubleValue() const { | 17904 double Integer::AsDoubleValue() const { |
18982 // Integer is an abstract class. | 17905 // Integer is an abstract class. |
18983 UNREACHABLE(); | 17906 UNREACHABLE(); |
18984 return 0.0; | 17907 return 0.0; |
18985 } | 17908 } |
18986 | 17909 |
18987 | |
18988 int64_t Integer::AsInt64Value() const { | 17910 int64_t Integer::AsInt64Value() const { |
18989 // Integer is an abstract class. | 17911 // Integer is an abstract class. |
18990 UNREACHABLE(); | 17912 UNREACHABLE(); |
18991 return 0; | 17913 return 0; |
18992 } | 17914 } |
18993 | 17915 |
18994 | |
18995 uint32_t Integer::AsTruncatedUint32Value() const { | 17916 uint32_t Integer::AsTruncatedUint32Value() const { |
18996 // Integer is an abstract class. | 17917 // Integer is an abstract class. |
18997 UNREACHABLE(); | 17918 UNREACHABLE(); |
18998 return 0; | 17919 return 0; |
18999 } | 17920 } |
19000 | 17921 |
19001 | |
19002 bool Integer::FitsIntoSmi() const { | 17922 bool Integer::FitsIntoSmi() const { |
19003 // Integer is an abstract class. | 17923 // Integer is an abstract class. |
19004 UNREACHABLE(); | 17924 UNREACHABLE(); |
19005 return false; | 17925 return false; |
19006 } | 17926 } |
19007 | 17927 |
19008 | |
19009 int Integer::CompareWith(const Integer& other) const { | 17928 int Integer::CompareWith(const Integer& other) const { |
19010 // Integer is an abstract class. | 17929 // Integer is an abstract class. |
19011 UNREACHABLE(); | 17930 UNREACHABLE(); |
19012 return 0; | 17931 return 0; |
19013 } | 17932 } |
19014 | 17933 |
19015 | |
19016 RawInteger* Integer::AsValidInteger() const { | 17934 RawInteger* Integer::AsValidInteger() const { |
19017 if (IsSmi()) return raw(); | 17935 if (IsSmi()) return raw(); |
19018 if (IsMint()) { | 17936 if (IsMint()) { |
19019 Mint& mint = Mint::Handle(); | 17937 Mint& mint = Mint::Handle(); |
19020 mint ^= raw(); | 17938 mint ^= raw(); |
19021 if (Smi::IsValid(mint.value())) { | 17939 if (Smi::IsValid(mint.value())) { |
19022 return Smi::New(static_cast<intptr_t>(mint.value())); | 17940 return Smi::New(static_cast<intptr_t>(mint.value())); |
19023 } else { | 17941 } else { |
19024 return raw(); | 17942 return raw(); |
19025 } | 17943 } |
19026 } | 17944 } |
19027 if (Bigint::Cast(*this).FitsIntoInt64()) { | 17945 if (Bigint::Cast(*this).FitsIntoInt64()) { |
19028 const int64_t value = AsInt64Value(); | 17946 const int64_t value = AsInt64Value(); |
19029 if (Smi::IsValid(value)) { | 17947 if (Smi::IsValid(value)) { |
19030 // This cast is safe because Smi::IsValid verifies that value will fit. | 17948 // This cast is safe because Smi::IsValid verifies that value will fit. |
19031 intptr_t val = static_cast<intptr_t>(value); | 17949 intptr_t val = static_cast<intptr_t>(value); |
19032 return Smi::New(val); | 17950 return Smi::New(val); |
19033 } | 17951 } |
19034 return Mint::New(value); | 17952 return Mint::New(value); |
19035 } | 17953 } |
19036 return raw(); | 17954 return raw(); |
19037 } | 17955 } |
19038 | 17956 |
19039 | |
19040 RawInteger* Integer::ArithmeticOp(Token::Kind operation, | 17957 RawInteger* Integer::ArithmeticOp(Token::Kind operation, |
19041 const Integer& other, | 17958 const Integer& other, |
19042 Heap::Space space) const { | 17959 Heap::Space space) const { |
19043 // In 32-bit mode, the result of any operation between two Smis will fit in a | 17960 // In 32-bit mode, the result of any operation between two Smis will fit in a |
19044 // 32-bit signed result, except the product of two Smis, which will be 64-bit. | 17961 // 32-bit signed result, except the product of two Smis, which will be 64-bit. |
19045 // In 64-bit mode, the result of any operation between two Smis will fit in a | 17962 // In 64-bit mode, the result of any operation between two Smis will fit in a |
19046 // 64-bit signed result, except the product of two Smis (see below). | 17963 // 64-bit signed result, except the product of two Smis (see below). |
19047 if (IsSmi() && other.IsSmi()) { | 17964 if (IsSmi() && other.IsSmi()) { |
19048 const intptr_t left_value = Smi::Value(Smi::RawCast(raw())); | 17965 const intptr_t left_value = Smi::Value(Smi::RawCast(raw())); |
19049 const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw())); | 17966 const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw())); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19155 return Integer::New(remainder, space); | 18072 return Integer::New(remainder, space); |
19156 } | 18073 } |
19157 default: | 18074 default: |
19158 UNIMPLEMENTED(); | 18075 UNIMPLEMENTED(); |
19159 } | 18076 } |
19160 } | 18077 } |
19161 ASSERT(!FLAG_limit_ints_to_64_bits); | 18078 ASSERT(!FLAG_limit_ints_to_64_bits); |
19162 return Integer::null(); // Notify caller that a bigint operation is required. | 18079 return Integer::null(); // Notify caller that a bigint operation is required. |
19163 } | 18080 } |
19164 | 18081 |
19165 | |
19166 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { | 18082 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { |
19167 return !op1.IsBigint() && !op2.IsBigint(); | 18083 return !op1.IsBigint() && !op2.IsBigint(); |
19168 } | 18084 } |
19169 | 18085 |
19170 | |
19171 RawInteger* Integer::BitOp(Token::Kind kind, | 18086 RawInteger* Integer::BitOp(Token::Kind kind, |
19172 const Integer& other, | 18087 const Integer& other, |
19173 Heap::Space space) const { | 18088 Heap::Space space) const { |
19174 if (IsSmi() && other.IsSmi()) { | 18089 if (IsSmi() && other.IsSmi()) { |
19175 intptr_t op1_value = Smi::Value(Smi::RawCast(raw())); | 18090 intptr_t op1_value = Smi::Value(Smi::RawCast(raw())); |
19176 intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw())); | 18091 intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw())); |
19177 intptr_t result = 0; | 18092 intptr_t result = 0; |
19178 switch (kind) { | 18093 switch (kind) { |
19179 case Token::kBIT_AND: | 18094 case Token::kBIT_AND: |
19180 result = op1_value & op2_value; | 18095 result = op1_value & op2_value; |
(...skipping 20 matching lines...) Expand all Loading... |
19201 case Token::kBIT_XOR: | 18116 case Token::kBIT_XOR: |
19202 return Integer::New(a ^ b, space); | 18117 return Integer::New(a ^ b, space); |
19203 default: | 18118 default: |
19204 UNIMPLEMENTED(); | 18119 UNIMPLEMENTED(); |
19205 } | 18120 } |
19206 } | 18121 } |
19207 ASSERT(!FLAG_limit_ints_to_64_bits); | 18122 ASSERT(!FLAG_limit_ints_to_64_bits); |
19208 return Integer::null(); // Notify caller that a bigint operation is required. | 18123 return Integer::null(); // Notify caller that a bigint operation is required. |
19209 } | 18124 } |
19210 | 18125 |
19211 | |
19212 // TODO(srdjan): Clarify handling of negative right operand in a shift op. | 18126 // TODO(srdjan): Clarify handling of negative right operand in a shift op. |
19213 RawInteger* Smi::ShiftOp(Token::Kind kind, | 18127 RawInteger* Smi::ShiftOp(Token::Kind kind, |
19214 const Smi& other, | 18128 const Smi& other, |
19215 Heap::Space space) const { | 18129 Heap::Space space) const { |
19216 intptr_t result = 0; | 18130 intptr_t result = 0; |
19217 const intptr_t left_value = Value(); | 18131 const intptr_t left_value = Value(); |
19218 const intptr_t right_value = other.Value(); | 18132 const intptr_t right_value = other.Value(); |
19219 ASSERT(right_value >= 0); | 18133 ASSERT(right_value >= 0); |
19220 switch (kind) { | 18134 switch (kind) { |
19221 case Token::kSHL: { | 18135 case Token::kSHL: { |
(...skipping 26 matching lines...) Expand all Loading... |
19248 result = left_value >> shift_amount; | 18162 result = left_value >> shift_amount; |
19249 break; | 18163 break; |
19250 } | 18164 } |
19251 default: | 18165 default: |
19252 UNIMPLEMENTED(); | 18166 UNIMPLEMENTED(); |
19253 } | 18167 } |
19254 ASSERT(Smi::IsValid(result)); | 18168 ASSERT(Smi::IsValid(result)); |
19255 return Smi::New(result); | 18169 return Smi::New(result); |
19256 } | 18170 } |
19257 | 18171 |
19258 | |
19259 bool Smi::Equals(const Instance& other) const { | 18172 bool Smi::Equals(const Instance& other) const { |
19260 if (other.IsNull() || !other.IsSmi()) { | 18173 if (other.IsNull() || !other.IsSmi()) { |
19261 return false; | 18174 return false; |
19262 } | 18175 } |
19263 return (this->Value() == Smi::Cast(other).Value()); | 18176 return (this->Value() == Smi::Cast(other).Value()); |
19264 } | 18177 } |
19265 | 18178 |
19266 | |
19267 double Smi::AsDoubleValue() const { | 18179 double Smi::AsDoubleValue() const { |
19268 return static_cast<double>(this->Value()); | 18180 return static_cast<double>(this->Value()); |
19269 } | 18181 } |
19270 | 18182 |
19271 | |
19272 int64_t Smi::AsInt64Value() const { | 18183 int64_t Smi::AsInt64Value() const { |
19273 return this->Value(); | 18184 return this->Value(); |
19274 } | 18185 } |
19275 | 18186 |
19276 | |
19277 uint32_t Smi::AsTruncatedUint32Value() const { | 18187 uint32_t Smi::AsTruncatedUint32Value() const { |
19278 return this->Value() & 0xFFFFFFFF; | 18188 return this->Value() & 0xFFFFFFFF; |
19279 } | 18189 } |
19280 | 18190 |
19281 | |
19282 int Smi::CompareWith(const Integer& other) const { | 18191 int Smi::CompareWith(const Integer& other) const { |
19283 if (other.IsSmi()) { | 18192 if (other.IsSmi()) { |
19284 const Smi& other_smi = Smi::Cast(other); | 18193 const Smi& other_smi = Smi::Cast(other); |
19285 if (this->Value() < other_smi.Value()) { | 18194 if (this->Value() < other_smi.Value()) { |
19286 return -1; | 18195 return -1; |
19287 } else if (this->Value() > other_smi.Value()) { | 18196 } else if (this->Value() > other_smi.Value()) { |
19288 return 1; | 18197 return 1; |
19289 } else { | 18198 } else { |
19290 return 0; | 18199 return 0; |
19291 } | 18200 } |
19292 } | 18201 } |
19293 ASSERT(!other.FitsIntoSmi()); | 18202 ASSERT(!other.FitsIntoSmi()); |
19294 if (other.IsMint() || other.IsBigint()) { | 18203 if (other.IsMint() || other.IsBigint()) { |
19295 if (this->IsNegative() == other.IsNegative()) { | 18204 if (this->IsNegative() == other.IsNegative()) { |
19296 return this->IsNegative() ? 1 : -1; | 18205 return this->IsNegative() ? 1 : -1; |
19297 } | 18206 } |
19298 return this->IsNegative() ? -1 : 1; | 18207 return this->IsNegative() ? -1 : 1; |
19299 } | 18208 } |
19300 UNREACHABLE(); | 18209 UNREACHABLE(); |
19301 return 0; | 18210 return 0; |
19302 } | 18211 } |
19303 | 18212 |
19304 | |
19305 const char* Smi::ToCString() const { | 18213 const char* Smi::ToCString() const { |
19306 return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value()); | 18214 return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value()); |
19307 } | 18215 } |
19308 | 18216 |
19309 | |
19310 RawClass* Smi::Class() { | 18217 RawClass* Smi::Class() { |
19311 return Isolate::Current()->object_store()->smi_class(); | 18218 return Isolate::Current()->object_store()->smi_class(); |
19312 } | 18219 } |
19313 | 18220 |
19314 | |
19315 void Mint::set_value(int64_t value) const { | 18221 void Mint::set_value(int64_t value) const { |
19316 StoreNonPointer(&raw_ptr()->value_, value); | 18222 StoreNonPointer(&raw_ptr()->value_, value); |
19317 } | 18223 } |
19318 | 18224 |
19319 | |
19320 RawMint* Mint::New(int64_t val, Heap::Space space) { | 18225 RawMint* Mint::New(int64_t val, Heap::Space space) { |
19321 // Do not allocate a Mint if Smi would do. | 18226 // Do not allocate a Mint if Smi would do. |
19322 ASSERT(!Smi::IsValid(val)); | 18227 ASSERT(!Smi::IsValid(val)); |
19323 ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null()); | 18228 ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null()); |
19324 Mint& result = Mint::Handle(); | 18229 Mint& result = Mint::Handle(); |
19325 { | 18230 { |
19326 RawObject* raw = | 18231 RawObject* raw = |
19327 Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space); | 18232 Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space); |
19328 NoSafepointScope no_safepoint; | 18233 NoSafepointScope no_safepoint; |
19329 result ^= raw; | 18234 result ^= raw; |
19330 } | 18235 } |
19331 result.set_value(val); | 18236 result.set_value(val); |
19332 return result.raw(); | 18237 return result.raw(); |
19333 } | 18238 } |
19334 | 18239 |
19335 | |
19336 RawMint* Mint::NewCanonical(int64_t value) { | 18240 RawMint* Mint::NewCanonical(int64_t value) { |
19337 // Do not allocate a Mint if Smi would do. | 18241 // Do not allocate a Mint if Smi would do. |
19338 ASSERT(!Smi::IsValid(value)); | 18242 ASSERT(!Smi::IsValid(value)); |
19339 Thread* thread = Thread::Current(); | 18243 Thread* thread = Thread::Current(); |
19340 Zone* zone = thread->zone(); | 18244 Zone* zone = thread->zone(); |
19341 Isolate* isolate = thread->isolate(); | 18245 Isolate* isolate = thread->isolate(); |
19342 const Class& cls = Class::Handle(zone, isolate->object_store()->mint_class()); | 18246 const Class& cls = Class::Handle(zone, isolate->object_store()->mint_class()); |
19343 Mint& canonical_value = Mint::Handle(zone); | 18247 Mint& canonical_value = Mint::Handle(zone); |
19344 intptr_t index = 0; | 18248 intptr_t index = 0; |
19345 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); | 18249 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); |
(...skipping 11 matching lines...) Expand all Loading... |
19357 } | 18261 } |
19358 canonical_value = Mint::New(value, Heap::kOld); | 18262 canonical_value = Mint::New(value, Heap::kOld); |
19359 canonical_value.SetCanonical(); | 18263 canonical_value.SetCanonical(); |
19360 // The value needs to be added to the constants list. Grow the list if | 18264 // The value needs to be added to the constants list. Grow the list if |
19361 // it is full. | 18265 // it is full. |
19362 cls.InsertCanonicalNumber(zone, index, canonical_value); | 18266 cls.InsertCanonicalNumber(zone, index, canonical_value); |
19363 return canonical_value.raw(); | 18267 return canonical_value.raw(); |
19364 } | 18268 } |
19365 } | 18269 } |
19366 | 18270 |
19367 | |
19368 bool Mint::Equals(const Instance& other) const { | 18271 bool Mint::Equals(const Instance& other) const { |
19369 if (this->raw() == other.raw()) { | 18272 if (this->raw() == other.raw()) { |
19370 // Both handles point to the same raw instance. | 18273 // Both handles point to the same raw instance. |
19371 return true; | 18274 return true; |
19372 } | 18275 } |
19373 if (!other.IsMint() || other.IsNull()) { | 18276 if (!other.IsMint() || other.IsNull()) { |
19374 return false; | 18277 return false; |
19375 } | 18278 } |
19376 return value() == Mint::Cast(other).value(); | 18279 return value() == Mint::Cast(other).value(); |
19377 } | 18280 } |
19378 | 18281 |
19379 | |
19380 double Mint::AsDoubleValue() const { | 18282 double Mint::AsDoubleValue() const { |
19381 return static_cast<double>(this->value()); | 18283 return static_cast<double>(this->value()); |
19382 } | 18284 } |
19383 | 18285 |
19384 | |
19385 int64_t Mint::AsInt64Value() const { | 18286 int64_t Mint::AsInt64Value() const { |
19386 return this->value(); | 18287 return this->value(); |
19387 } | 18288 } |
19388 | 18289 |
19389 | |
19390 uint32_t Mint::AsTruncatedUint32Value() const { | 18290 uint32_t Mint::AsTruncatedUint32Value() const { |
19391 return this->value() & 0xFFFFFFFF; | 18291 return this->value() & 0xFFFFFFFF; |
19392 } | 18292 } |
19393 | 18293 |
19394 | |
19395 bool Mint::FitsIntoSmi() const { | 18294 bool Mint::FitsIntoSmi() const { |
19396 return Smi::IsValid(AsInt64Value()); | 18295 return Smi::IsValid(AsInt64Value()); |
19397 } | 18296 } |
19398 | 18297 |
19399 | |
19400 int Mint::CompareWith(const Integer& other) const { | 18298 int Mint::CompareWith(const Integer& other) const { |
19401 ASSERT(!FitsIntoSmi()); | 18299 ASSERT(!FitsIntoSmi()); |
19402 if (other.IsMint() || other.IsSmi()) { | 18300 if (other.IsMint() || other.IsSmi()) { |
19403 int64_t a = AsInt64Value(); | 18301 int64_t a = AsInt64Value(); |
19404 int64_t b = other.AsInt64Value(); | 18302 int64_t b = other.AsInt64Value(); |
19405 if (a < b) { | 18303 if (a < b) { |
19406 return -1; | 18304 return -1; |
19407 } else if (a > b) { | 18305 } else if (a > b) { |
19408 return 1; | 18306 return 1; |
19409 } else { | 18307 } else { |
19410 return 0; | 18308 return 0; |
19411 } | 18309 } |
19412 } | 18310 } |
19413 ASSERT(other.IsBigint()); | 18311 ASSERT(other.IsBigint()); |
19414 ASSERT(!Bigint::Cast(other).FitsIntoInt64()); | 18312 ASSERT(!Bigint::Cast(other).FitsIntoInt64()); |
19415 if (this->IsNegative() == other.IsNegative()) { | 18313 if (this->IsNegative() == other.IsNegative()) { |
19416 return this->IsNegative() ? 1 : -1; | 18314 return this->IsNegative() ? 1 : -1; |
19417 } | 18315 } |
19418 return this->IsNegative() ? -1 : 1; | 18316 return this->IsNegative() ? -1 : 1; |
19419 } | 18317 } |
19420 | 18318 |
19421 | |
19422 const char* Mint::ToCString() const { | 18319 const char* Mint::ToCString() const { |
19423 return OS::SCreate(Thread::Current()->zone(), "%" Pd64 "", value()); | 18320 return OS::SCreate(Thread::Current()->zone(), "%" Pd64 "", value()); |
19424 } | 18321 } |
19425 | 18322 |
19426 | |
19427 void Double::set_value(double value) const { | 18323 void Double::set_value(double value) const { |
19428 StoreNonPointer(&raw_ptr()->value_, value); | 18324 StoreNonPointer(&raw_ptr()->value_, value); |
19429 } | 18325 } |
19430 | 18326 |
19431 | |
19432 bool Double::BitwiseEqualsToDouble(double value) const { | 18327 bool Double::BitwiseEqualsToDouble(double value) const { |
19433 intptr_t value_offset = Double::value_offset(); | 18328 intptr_t value_offset = Double::value_offset(); |
19434 void* this_addr = reinterpret_cast<void*>( | 18329 void* this_addr = reinterpret_cast<void*>( |
19435 reinterpret_cast<uword>(this->raw_ptr()) + value_offset); | 18330 reinterpret_cast<uword>(this->raw_ptr()) + value_offset); |
19436 void* other_addr = reinterpret_cast<void*>(&value); | 18331 void* other_addr = reinterpret_cast<void*>(&value); |
19437 return (memcmp(this_addr, other_addr, sizeof(value)) == 0); | 18332 return (memcmp(this_addr, other_addr, sizeof(value)) == 0); |
19438 } | 18333 } |
19439 | 18334 |
19440 | |
19441 bool Double::OperatorEquals(const Instance& other) const { | 18335 bool Double::OperatorEquals(const Instance& other) const { |
19442 if (this->IsNull() || other.IsNull()) { | 18336 if (this->IsNull() || other.IsNull()) { |
19443 return (this->IsNull() && other.IsNull()); | 18337 return (this->IsNull() && other.IsNull()); |
19444 } | 18338 } |
19445 if (!other.IsDouble()) { | 18339 if (!other.IsDouble()) { |
19446 return false; | 18340 return false; |
19447 } | 18341 } |
19448 return this->value() == Double::Cast(other).value(); | 18342 return this->value() == Double::Cast(other).value(); |
19449 } | 18343 } |
19450 | 18344 |
19451 | |
19452 bool Double::CanonicalizeEquals(const Instance& other) const { | 18345 bool Double::CanonicalizeEquals(const Instance& other) const { |
19453 if (this->raw() == other.raw()) { | 18346 if (this->raw() == other.raw()) { |
19454 return true; // "===". | 18347 return true; // "===". |
19455 } | 18348 } |
19456 if (other.IsNull() || !other.IsDouble()) { | 18349 if (other.IsNull() || !other.IsDouble()) { |
19457 return false; | 18350 return false; |
19458 } | 18351 } |
19459 return BitwiseEqualsToDouble(Double::Cast(other).value()); | 18352 return BitwiseEqualsToDouble(Double::Cast(other).value()); |
19460 } | 18353 } |
19461 | 18354 |
19462 | |
19463 RawDouble* Double::New(double d, Heap::Space space) { | 18355 RawDouble* Double::New(double d, Heap::Space space) { |
19464 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); | 18356 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); |
19465 Double& result = Double::Handle(); | 18357 Double& result = Double::Handle(); |
19466 { | 18358 { |
19467 RawObject* raw = | 18359 RawObject* raw = |
19468 Object::Allocate(Double::kClassId, Double::InstanceSize(), space); | 18360 Object::Allocate(Double::kClassId, Double::InstanceSize(), space); |
19469 NoSafepointScope no_safepoint; | 18361 NoSafepointScope no_safepoint; |
19470 result ^= raw; | 18362 result ^= raw; |
19471 } | 18363 } |
19472 result.set_value(d); | 18364 result.set_value(d); |
19473 return result.raw(); | 18365 return result.raw(); |
19474 } | 18366 } |
19475 | 18367 |
19476 | |
19477 RawDouble* Double::New(const String& str, Heap::Space space) { | 18368 RawDouble* Double::New(const String& str, Heap::Space space) { |
19478 double double_value; | 18369 double double_value; |
19479 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 18370 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |
19480 return Double::Handle().raw(); | 18371 return Double::Handle().raw(); |
19481 } | 18372 } |
19482 return New(double_value, space); | 18373 return New(double_value, space); |
19483 } | 18374 } |
19484 | 18375 |
19485 | |
19486 RawDouble* Double::NewCanonical(double value) { | 18376 RawDouble* Double::NewCanonical(double value) { |
19487 Thread* thread = Thread::Current(); | 18377 Thread* thread = Thread::Current(); |
19488 Zone* zone = thread->zone(); | 18378 Zone* zone = thread->zone(); |
19489 Isolate* isolate = thread->isolate(); | 18379 Isolate* isolate = thread->isolate(); |
19490 const Class& cls = Class::Handle(isolate->object_store()->double_class()); | 18380 const Class& cls = Class::Handle(isolate->object_store()->double_class()); |
19491 // Linear search to see whether this value is already present in the | 18381 // Linear search to see whether this value is already present in the |
19492 // list of canonicalized constants. | 18382 // list of canonicalized constants. |
19493 Double& canonical_value = Double::Handle(zone); | 18383 Double& canonical_value = Double::Handle(zone); |
19494 intptr_t index = 0; | 18384 intptr_t index = 0; |
19495 | 18385 |
(...skipping 12 matching lines...) Expand all Loading... |
19508 } | 18398 } |
19509 canonical_value = Double::New(value, Heap::kOld); | 18399 canonical_value = Double::New(value, Heap::kOld); |
19510 canonical_value.SetCanonical(); | 18400 canonical_value.SetCanonical(); |
19511 // The value needs to be added to the constants list. Grow the list if | 18401 // The value needs to be added to the constants list. Grow the list if |
19512 // it is full. | 18402 // it is full. |
19513 cls.InsertCanonicalNumber(zone, index, canonical_value); | 18403 cls.InsertCanonicalNumber(zone, index, canonical_value); |
19514 return canonical_value.raw(); | 18404 return canonical_value.raw(); |
19515 } | 18405 } |
19516 } | 18406 } |
19517 | 18407 |
19518 | |
19519 RawDouble* Double::NewCanonical(const String& str) { | 18408 RawDouble* Double::NewCanonical(const String& str) { |
19520 double double_value; | 18409 double double_value; |
19521 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 18410 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |
19522 return Double::Handle().raw(); | 18411 return Double::Handle().raw(); |
19523 } | 18412 } |
19524 return NewCanonical(double_value); | 18413 return NewCanonical(double_value); |
19525 } | 18414 } |
19526 | 18415 |
19527 | |
19528 RawString* Number::ToString(Heap::Space space) const { | 18416 RawString* Number::ToString(Heap::Space space) const { |
19529 // Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant. | 18417 // Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant. |
19530 const char* cstr = ToCString(); | 18418 const char* cstr = ToCString(); |
19531 intptr_t len = strlen(cstr); | 18419 intptr_t len = strlen(cstr); |
19532 // Resulting string is ASCII ... | 18420 // Resulting string is ASCII ... |
19533 #ifdef DEBUG | 18421 #ifdef DEBUG |
19534 for (intptr_t i = 0; i < len; ++i) { | 18422 for (intptr_t i = 0; i < len; ++i) { |
19535 ASSERT(static_cast<uint8_t>(cstr[i]) < 128); | 18423 ASSERT(static_cast<uint8_t>(cstr[i]) < 128); |
19536 } | 18424 } |
19537 #endif // DEBUG | 18425 #endif // DEBUG |
19538 // ... which is a subset of Latin-1. | 18426 // ... which is a subset of Latin-1. |
19539 return String::FromLatin1(reinterpret_cast<const uint8_t*>(cstr), len, space); | 18427 return String::FromLatin1(reinterpret_cast<const uint8_t*>(cstr), len, space); |
19540 } | 18428 } |
19541 | 18429 |
19542 | |
19543 const char* Double::ToCString() const { | 18430 const char* Double::ToCString() const { |
19544 if (isnan(value())) { | 18431 if (isnan(value())) { |
19545 return "NaN"; | 18432 return "NaN"; |
19546 } | 18433 } |
19547 if (isinf(value())) { | 18434 if (isinf(value())) { |
19548 return value() < 0 ? "-Infinity" : "Infinity"; | 18435 return value() < 0 ? "-Infinity" : "Infinity"; |
19549 } | 18436 } |
19550 const int kBufferSize = 128; | 18437 const int kBufferSize = 128; |
19551 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); | 18438 char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); |
19552 buffer[kBufferSize - 1] = '\0'; | 18439 buffer[kBufferSize - 1] = '\0'; |
19553 DoubleToCString(value(), buffer, kBufferSize); | 18440 DoubleToCString(value(), buffer, kBufferSize); |
19554 return buffer; | 18441 return buffer; |
19555 } | 18442 } |
19556 | 18443 |
19557 | |
19558 bool Bigint::Neg() const { | 18444 bool Bigint::Neg() const { |
19559 return Bool::Handle(neg()).value(); | 18445 return Bool::Handle(neg()).value(); |
19560 } | 18446 } |
19561 | 18447 |
19562 | |
19563 void Bigint::SetNeg(bool value) const { | 18448 void Bigint::SetNeg(bool value) const { |
19564 StorePointer(&raw_ptr()->neg_, Bool::Get(value).raw()); | 18449 StorePointer(&raw_ptr()->neg_, Bool::Get(value).raw()); |
19565 } | 18450 } |
19566 | 18451 |
19567 | |
19568 intptr_t Bigint::Used() const { | 18452 intptr_t Bigint::Used() const { |
19569 return Smi::Value(used()); | 18453 return Smi::Value(used()); |
19570 } | 18454 } |
19571 | 18455 |
19572 | |
19573 void Bigint::SetUsed(intptr_t value) const { | 18456 void Bigint::SetUsed(intptr_t value) const { |
19574 StoreSmi(&raw_ptr()->used_, Smi::New(value)); | 18457 StoreSmi(&raw_ptr()->used_, Smi::New(value)); |
19575 } | 18458 } |
19576 | 18459 |
19577 | |
19578 uint32_t Bigint::DigitAt(intptr_t index) const { | 18460 uint32_t Bigint::DigitAt(intptr_t index) const { |
19579 const TypedData& typed_data = TypedData::Handle(digits()); | 18461 const TypedData& typed_data = TypedData::Handle(digits()); |
19580 return typed_data.GetUint32(index << 2); | 18462 return typed_data.GetUint32(index << 2); |
19581 } | 18463 } |
19582 | 18464 |
19583 | |
19584 void Bigint::set_digits(const TypedData& value) const { | 18465 void Bigint::set_digits(const TypedData& value) const { |
19585 // The VM expects digits_ to be a Uint32List (not null). | 18466 // The VM expects digits_ to be a Uint32List (not null). |
19586 ASSERT(!value.IsNull() && (value.GetClassId() == kTypedDataUint32ArrayCid)); | 18467 ASSERT(!value.IsNull() && (value.GetClassId() == kTypedDataUint32ArrayCid)); |
19587 StorePointer(&raw_ptr()->digits_, value.raw()); | 18468 StorePointer(&raw_ptr()->digits_, value.raw()); |
19588 } | 18469 } |
19589 | 18470 |
19590 | |
19591 RawTypedData* Bigint::NewDigits(intptr_t length, Heap::Space space) { | 18471 RawTypedData* Bigint::NewDigits(intptr_t length, Heap::Space space) { |
19592 ASSERT(length > 0); | 18472 ASSERT(length > 0); |
19593 // Account for leading zero for 64-bit processing. | 18473 // Account for leading zero for 64-bit processing. |
19594 return TypedData::New(kTypedDataUint32ArrayCid, length + 1, space); | 18474 return TypedData::New(kTypedDataUint32ArrayCid, length + 1, space); |
19595 } | 18475 } |
19596 | 18476 |
19597 | |
19598 uint32_t Bigint::DigitAt(const TypedData& digits, intptr_t index) { | 18477 uint32_t Bigint::DigitAt(const TypedData& digits, intptr_t index) { |
19599 return digits.GetUint32(index << 2); | 18478 return digits.GetUint32(index << 2); |
19600 } | 18479 } |
19601 | 18480 |
19602 | |
19603 void Bigint::SetDigitAt(const TypedData& digits, | 18481 void Bigint::SetDigitAt(const TypedData& digits, |
19604 intptr_t index, | 18482 intptr_t index, |
19605 uint32_t value) { | 18483 uint32_t value) { |
19606 digits.SetUint32(index << 2, value); | 18484 digits.SetUint32(index << 2, value); |
19607 } | 18485 } |
19608 | 18486 |
19609 | |
19610 bool Bigint::Equals(const Instance& other) const { | 18487 bool Bigint::Equals(const Instance& other) const { |
19611 if (this->raw() == other.raw()) { | 18488 if (this->raw() == other.raw()) { |
19612 // Both handles point to the same raw instance. | 18489 // Both handles point to the same raw instance. |
19613 return true; | 18490 return true; |
19614 } | 18491 } |
19615 | 18492 |
19616 if (!other.IsBigint() || other.IsNull()) { | 18493 if (!other.IsBigint() || other.IsNull()) { |
19617 return false; | 18494 return false; |
19618 } | 18495 } |
19619 | 18496 |
19620 const Bigint& other_bgi = Bigint::Cast(other); | 18497 const Bigint& other_bgi = Bigint::Cast(other); |
19621 | 18498 |
19622 if (this->Neg() != other_bgi.Neg()) { | 18499 if (this->Neg() != other_bgi.Neg()) { |
19623 return false; | 18500 return false; |
19624 } | 18501 } |
19625 | 18502 |
19626 const intptr_t used = this->Used(); | 18503 const intptr_t used = this->Used(); |
19627 if (used != other_bgi.Used()) { | 18504 if (used != other_bgi.Used()) { |
19628 return false; | 18505 return false; |
19629 } | 18506 } |
19630 | 18507 |
19631 for (intptr_t i = 0; i < used; i++) { | 18508 for (intptr_t i = 0; i < used; i++) { |
19632 if (this->DigitAt(i) != other_bgi.DigitAt(i)) { | 18509 if (this->DigitAt(i) != other_bgi.DigitAt(i)) { |
19633 return false; | 18510 return false; |
19634 } | 18511 } |
19635 } | 18512 } |
19636 return true; | 18513 return true; |
19637 } | 18514 } |
19638 | 18515 |
19639 | |
19640 bool Bigint::CheckAndCanonicalizeFields(Thread* thread, | 18516 bool Bigint::CheckAndCanonicalizeFields(Thread* thread, |
19641 const char** error_str) const { | 18517 const char** error_str) const { |
19642 Zone* zone = thread->zone(); | 18518 Zone* zone = thread->zone(); |
19643 // Bool field neg should always be canonical. | 18519 // Bool field neg should always be canonical. |
19644 ASSERT(Bool::Handle(zone, neg()).IsCanonical()); | 18520 ASSERT(Bool::Handle(zone, neg()).IsCanonical()); |
19645 // Smi field used is canonical by definition. | 18521 // Smi field used is canonical by definition. |
19646 if (Used() > 0) { | 18522 if (Used() > 0) { |
19647 // Canonicalize TypedData field digits. | 18523 // Canonicalize TypedData field digits. |
19648 TypedData& digits_ = TypedData::Handle(zone, digits()); | 18524 TypedData& digits_ = TypedData::Handle(zone, digits()); |
19649 digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); | 18525 digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); |
19650 ASSERT(!digits_.IsNull()); | 18526 ASSERT(!digits_.IsNull()); |
19651 set_digits(digits_); | 18527 set_digits(digits_); |
19652 } else { | 18528 } else { |
19653 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); | 18529 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); |
19654 } | 18530 } |
19655 return true; | 18531 return true; |
19656 } | 18532 } |
19657 | 18533 |
19658 | |
19659 RawBigint* Bigint::New(Heap::Space space) { | 18534 RawBigint* Bigint::New(Heap::Space space) { |
19660 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18535 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |
19661 Thread* thread = Thread::Current(); | 18536 Thread* thread = Thread::Current(); |
19662 Zone* zone = thread->zone(); | 18537 Zone* zone = thread->zone(); |
19663 Isolate* isolate = thread->isolate(); | 18538 Isolate* isolate = thread->isolate(); |
19664 ASSERT(isolate->object_store()->bigint_class() != Class::null()); | 18539 ASSERT(isolate->object_store()->bigint_class() != Class::null()); |
19665 Bigint& result = Bigint::Handle(zone); | 18540 Bigint& result = Bigint::Handle(zone); |
19666 { | 18541 { |
19667 RawObject* raw = | 18542 RawObject* raw = |
19668 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); | 18543 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); |
19669 NoSafepointScope no_safepoint; | 18544 NoSafepointScope no_safepoint; |
19670 result ^= raw; | 18545 result ^= raw; |
19671 } | 18546 } |
19672 result.SetNeg(false); | 18547 result.SetNeg(false); |
19673 result.SetUsed(0); | 18548 result.SetUsed(0); |
19674 result.set_digits( | 18549 result.set_digits( |
19675 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 18550 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |
19676 return result.raw(); | 18551 return result.raw(); |
19677 } | 18552 } |
19678 | 18553 |
19679 | |
19680 RawBigint* Bigint::New(bool neg, | 18554 RawBigint* Bigint::New(bool neg, |
19681 intptr_t used, | 18555 intptr_t used, |
19682 const TypedData& digits, | 18556 const TypedData& digits, |
19683 Heap::Space space) { | 18557 Heap::Space space) { |
19684 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18558 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |
19685 ASSERT((used == 0) || | 18559 ASSERT((used == 0) || |
19686 (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); | 18560 (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); |
19687 Thread* thread = Thread::Current(); | 18561 Thread* thread = Thread::Current(); |
19688 Zone* zone = thread->zone(); | 18562 Zone* zone = thread->zone(); |
19689 Isolate* isolate = thread->isolate(); | 18563 Isolate* isolate = thread->isolate(); |
(...skipping 20 matching lines...) Expand all Loading... |
19710 } else { | 18584 } else { |
19711 neg = false; | 18585 neg = false; |
19712 result.set_digits( | 18586 result.set_digits( |
19713 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 18587 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |
19714 } | 18588 } |
19715 result.SetNeg(neg); | 18589 result.SetNeg(neg); |
19716 result.SetUsed(used); | 18590 result.SetUsed(used); |
19717 return result.raw(); | 18591 return result.raw(); |
19718 } | 18592 } |
19719 | 18593 |
19720 | |
19721 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { | 18594 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { |
19722 // Currently only used to convert Smi or Mint to hex String, therefore do | 18595 // Currently only used to convert Smi or Mint to hex String, therefore do |
19723 // not throw RangeError if --limit-ints-to-64-bits. | 18596 // not throw RangeError if --limit-ints-to-64-bits. |
19724 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18597 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |
19725 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 18598 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |
19726 bool neg; | 18599 bool neg; |
19727 uint64_t abs_value; | 18600 uint64_t abs_value; |
19728 if (value < 0) { | 18601 if (value < 0) { |
19729 neg = true; | 18602 neg = true; |
19730 abs_value = -value; | 18603 abs_value = -value; |
19731 } else { | 18604 } else { |
19732 neg = false; | 18605 neg = false; |
19733 abs_value = value; | 18606 abs_value = value; |
19734 } | 18607 } |
19735 SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); | 18608 SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); |
19736 SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); | 18609 SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); |
19737 return New(neg, 2, digits, space); | 18610 return New(neg, 2, digits, space); |
19738 } | 18611 } |
19739 | 18612 |
19740 | |
19741 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { | 18613 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { |
19742 // TODO(alexmarkov): Revise this assertion if this factory method is used | 18614 // TODO(alexmarkov): Revise this assertion if this factory method is used |
19743 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | 18615 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. |
19744 ASSERT(!FLAG_limit_ints_to_64_bits); | 18616 ASSERT(!FLAG_limit_ints_to_64_bits); |
19745 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 18617 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |
19746 SetDigitAt(digits, 0, static_cast<uint32_t>(value)); | 18618 SetDigitAt(digits, 0, static_cast<uint32_t>(value)); |
19747 SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); | 18619 SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); |
19748 return New(false, 2, digits, space); | 18620 return New(false, 2, digits, space); |
19749 } | 18621 } |
19750 | 18622 |
19751 | |
19752 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, | 18623 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, |
19753 intptr_t shift, | 18624 intptr_t shift, |
19754 Heap::Space space) { | 18625 Heap::Space space) { |
19755 // TODO(alexmarkov): Revise this assertion if this factory method is used | 18626 // TODO(alexmarkov): Revise this assertion if this factory method is used |
19756 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | 18627 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. |
19757 ASSERT(!FLAG_limit_ints_to_64_bits); | 18628 ASSERT(!FLAG_limit_ints_to_64_bits); |
19758 ASSERT(kBitsPerDigit == 32); | 18629 ASSERT(kBitsPerDigit == 32); |
19759 ASSERT(shift >= 0); | 18630 ASSERT(shift >= 0); |
19760 const intptr_t digit_shift = shift / kBitsPerDigit; | 18631 const intptr_t digit_shift = shift / kBitsPerDigit; |
19761 const intptr_t bit_shift = shift % kBitsPerDigit; | 18632 const intptr_t bit_shift = shift % kBitsPerDigit; |
19762 const intptr_t used = 3 + digit_shift; | 18633 const intptr_t used = 3 + digit_shift; |
19763 const TypedData& digits = TypedData::Handle(NewDigits(used, space)); | 18634 const TypedData& digits = TypedData::Handle(NewDigits(used, space)); |
19764 bool neg; | 18635 bool neg; |
19765 uint64_t abs_value; | 18636 uint64_t abs_value; |
19766 if (value < 0) { | 18637 if (value < 0) { |
19767 neg = true; | 18638 neg = true; |
19768 abs_value = -value; | 18639 abs_value = -value; |
19769 } else { | 18640 } else { |
19770 neg = false; | 18641 neg = false; |
19771 abs_value = value; | 18642 abs_value = value; |
19772 } | 18643 } |
19773 for (intptr_t i = 0; i < digit_shift; i++) { | 18644 for (intptr_t i = 0; i < digit_shift; i++) { |
19774 SetDigitAt(digits, i, 0); | 18645 SetDigitAt(digits, i, 0); |
19775 } | 18646 } |
19776 SetDigitAt(digits, 0 + digit_shift, | 18647 SetDigitAt(digits, 0 + digit_shift, |
19777 static_cast<uint32_t>(abs_value << bit_shift)); | 18648 static_cast<uint32_t>(abs_value << bit_shift)); |
19778 SetDigitAt(digits, 1 + digit_shift, | 18649 SetDigitAt(digits, 1 + digit_shift, |
19779 static_cast<uint32_t>(abs_value >> (32 - bit_shift))); | 18650 static_cast<uint32_t>(abs_value >> (32 - bit_shift))); |
19780 SetDigitAt(digits, 2 + digit_shift, | 18651 SetDigitAt(digits, 2 + digit_shift, |
19781 (bit_shift == 0) ? 0 : static_cast<uint32_t>(abs_value >> | 18652 (bit_shift == 0) |
19782 (64 - bit_shift))); | 18653 ? 0 |
| 18654 : static_cast<uint32_t>(abs_value >> (64 - bit_shift))); |
19783 return New(neg, used, digits, space); | 18655 return New(neg, used, digits, space); |
19784 } | 18656 } |
19785 | 18657 |
19786 | |
19787 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { | 18658 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { |
19788 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 18659 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. |
19789 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18660 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |
19790 ASSERT(str != NULL); | 18661 ASSERT(str != NULL); |
19791 bool neg = false; | 18662 bool neg = false; |
19792 TypedData& digits = TypedData::Handle(); | 18663 TypedData& digits = TypedData::Handle(); |
19793 if (str[0] == '-') { | 18664 if (str[0] == '-') { |
19794 ASSERT(str[1] != '-'); | 18665 ASSERT(str[1] != '-'); |
19795 neg = true; | 18666 neg = true; |
19796 str++; | 18667 str++; |
19797 } | 18668 } |
19798 intptr_t used; | 18669 intptr_t used; |
19799 const intptr_t str_length = strlen(str); | 18670 const intptr_t str_length = strlen(str); |
19800 if ((str_length >= 2) && (str[0] == '0') && | 18671 if ((str_length >= 2) && (str[0] == '0') && |
19801 ((str[1] == 'x') || (str[1] == 'X'))) { | 18672 ((str[1] == 'x') || (str[1] == 'X'))) { |
19802 digits = NewDigitsFromHexCString(&str[2], &used, space); | 18673 digits = NewDigitsFromHexCString(&str[2], &used, space); |
19803 } else { | 18674 } else { |
19804 digits = NewDigitsFromDecCString(str, &used, space); | 18675 digits = NewDigitsFromDecCString(str, &used, space); |
19805 } | 18676 } |
19806 return New(neg, used, digits, space); | 18677 return New(neg, used, digits, space); |
19807 } | 18678 } |
19808 | 18679 |
19809 | |
19810 RawBigint* Bigint::NewCanonical(const String& str) { | 18680 RawBigint* Bigint::NewCanonical(const String& str) { |
19811 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 18681 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. |
19812 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18682 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |
19813 Thread* thread = Thread::Current(); | 18683 Thread* thread = Thread::Current(); |
19814 Zone* zone = thread->zone(); | 18684 Zone* zone = thread->zone(); |
19815 Isolate* isolate = thread->isolate(); | 18685 Isolate* isolate = thread->isolate(); |
19816 const Bigint& value = | 18686 const Bigint& value = |
19817 Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); | 18687 Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); |
19818 const Class& cls = | 18688 const Class& cls = |
19819 Class::Handle(zone, isolate->object_store()->bigint_class()); | 18689 Class::Handle(zone, isolate->object_store()->bigint_class()); |
(...skipping 13 matching lines...) Expand all Loading... |
19833 } | 18703 } |
19834 } | 18704 } |
19835 value.SetCanonical(); | 18705 value.SetCanonical(); |
19836 // The value needs to be added to the constants list. Grow the list if | 18706 // The value needs to be added to the constants list. Grow the list if |
19837 // it is full. | 18707 // it is full. |
19838 cls.InsertCanonicalNumber(zone, index, value); | 18708 cls.InsertCanonicalNumber(zone, index, value); |
19839 return value.raw(); | 18709 return value.raw(); |
19840 } | 18710 } |
19841 } | 18711 } |
19842 | 18712 |
19843 | |
19844 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, | 18713 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, |
19845 intptr_t* used, | 18714 intptr_t* used, |
19846 Heap::Space space) { | 18715 Heap::Space space) { |
19847 const int kBitsPerHexDigit = 4; | 18716 const int kBitsPerHexDigit = 4; |
19848 const int kHexDigitsPerDigit = 8; | 18717 const int kHexDigitsPerDigit = 8; |
19849 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; | 18718 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; |
19850 intptr_t hex_i = strlen(str); // Terminating byte excluded. | 18719 intptr_t hex_i = strlen(str); // Terminating byte excluded. |
19851 if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { | 18720 if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { |
19852 FATAL("Fatal error parsing hex bigint: string too long or empty"); | 18721 FATAL("Fatal error parsing hex bigint: string too long or empty"); |
19853 } | 18722 } |
(...skipping 11 matching lines...) Expand all Loading... |
19865 digit = 0; | 18734 digit = 0; |
19866 } | 18735 } |
19867 } | 18736 } |
19868 if (bit_i != 0) { | 18737 if (bit_i != 0) { |
19869 SetDigitAt(digits, used_++, digit); | 18738 SetDigitAt(digits, used_++, digit); |
19870 } | 18739 } |
19871 *used = used_; | 18740 *used = used_; |
19872 return digits.raw(); | 18741 return digits.raw(); |
19873 } | 18742 } |
19874 | 18743 |
19875 | |
19876 RawTypedData* Bigint::NewDigitsFromDecCString(const char* str, | 18744 RawTypedData* Bigint::NewDigitsFromDecCString(const char* str, |
19877 intptr_t* used, | 18745 intptr_t* used, |
19878 Heap::Space space) { | 18746 Heap::Space space) { |
19879 // Read 9 digits a time. 10^9 < 2^32. | 18747 // Read 9 digits a time. 10^9 < 2^32. |
19880 const int kDecDigitsPerIteration = 9; | 18748 const int kDecDigitsPerIteration = 9; |
19881 const uint32_t kTenMultiplier = 1000000000; | 18749 const uint32_t kTenMultiplier = 1000000000; |
19882 ASSERT(kBitsPerDigit == 32); | 18750 ASSERT(kBitsPerDigit == 32); |
19883 const intptr_t str_length = strlen(str); | 18751 const intptr_t str_length = strlen(str); |
19884 if ((str_length <= 0) || (str_length >= kMaxInt32)) { | 18752 if ((str_length <= 0) || (str_length >= kMaxInt32)) { |
19885 FATAL("Fatal error parsing dec bigint: string too long or empty"); | 18753 FATAL("Fatal error parsing dec bigint: string too long or empty"); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19920 (static_cast<uint64_t>(DigitAt(digits, i)) * kTenMultiplier) + digit; | 18788 (static_cast<uint64_t>(DigitAt(digits, i)) * kTenMultiplier) + digit; |
19921 SetDigitAt(digits, i, static_cast<uint32_t>(product & kDigitMask)); | 18789 SetDigitAt(digits, i, static_cast<uint32_t>(product & kDigitMask)); |
19922 digit = static_cast<uint32_t>(product >> kBitsPerDigit); | 18790 digit = static_cast<uint32_t>(product >> kBitsPerDigit); |
19923 } | 18791 } |
19924 SetDigitAt(digits, used_++, digit); | 18792 SetDigitAt(digits, used_++, digit); |
19925 } | 18793 } |
19926 *used = used_; | 18794 *used = used_; |
19927 return digits.raw(); | 18795 return digits.raw(); |
19928 } | 18796 } |
19929 | 18797 |
19930 | |
19931 static double Uint64ToDouble(uint64_t x) { | 18798 static double Uint64ToDouble(uint64_t x) { |
19932 #if _WIN64 | 18799 #if _WIN64 |
19933 // For static_cast<double>(x) MSVC x64 generates | 18800 // For static_cast<double>(x) MSVC x64 generates |
19934 // | 18801 // |
19935 // cvtsi2sd xmm0, rax | 18802 // cvtsi2sd xmm0, rax |
19936 // test rax, rax | 18803 // test rax, rax |
19937 // jns done | 18804 // jns done |
19938 // addsd xmm0, static_cast<double>(2^64) | 18805 // addsd xmm0, static_cast<double>(2^64) |
19939 // done: | 18806 // done: |
19940 // | 18807 // |
(...skipping 23 matching lines...) Expand all Loading... |
19964 } else { | 18831 } else { |
19965 const double half = | 18832 const double half = |
19966 static_cast<double>(static_cast<int64_t>(x >> 1) | (y & 1)); | 18833 static_cast<double>(static_cast<int64_t>(x >> 1) | (y & 1)); |
19967 return half + half; | 18834 return half + half; |
19968 } | 18835 } |
19969 #else | 18836 #else |
19970 return static_cast<double>(x); | 18837 return static_cast<double>(x); |
19971 #endif | 18838 #endif |
19972 } | 18839 } |
19973 | 18840 |
19974 | |
19975 double Bigint::AsDoubleValue() const { | 18841 double Bigint::AsDoubleValue() const { |
19976 ASSERT(kBitsPerDigit == 32); | 18842 ASSERT(kBitsPerDigit == 32); |
19977 const intptr_t used = Used(); | 18843 const intptr_t used = Used(); |
19978 if (used == 0) { | 18844 if (used == 0) { |
19979 return 0.0; | 18845 return 0.0; |
19980 } | 18846 } |
19981 if (used <= 2) { | 18847 if (used <= 2) { |
19982 const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 18848 const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; |
19983 const uint64_t abs_value = (digit1 << 32) + DigitAt(0); | 18849 const uint64_t abs_value = (digit1 << 32) + DigitAt(0); |
19984 const double abs_double_value = Uint64ToDouble(abs_value); | 18850 const double abs_double_value = Uint64ToDouble(abs_value); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20099 // exponent by one instead of playing around with the significand. | 18965 // exponent by one instead of playing around with the significand. |
20100 const uint64_t biased_exponent = exponent + kExponentBias - 1; | 18966 const uint64_t biased_exponent = exponent + kExponentBias - 1; |
20101 // Note that we must use the plus operator instead of bit-or. | 18967 // Note that we must use the plus operator instead of bit-or. |
20102 const uint64_t double_bits = | 18968 const uint64_t double_bits = |
20103 (biased_exponent << kPhysicalSignificandSize) + significand; | 18969 (biased_exponent << kPhysicalSignificandSize) + significand; |
20104 | 18970 |
20105 const double value = bit_cast<double>(double_bits); | 18971 const double value = bit_cast<double>(double_bits); |
20106 return Neg() ? -value : value; | 18972 return Neg() ? -value : value; |
20107 } | 18973 } |
20108 | 18974 |
20109 | |
20110 bool Bigint::FitsIntoSmi() const { | 18975 bool Bigint::FitsIntoSmi() const { |
20111 return FitsIntoInt64() && Smi::IsValid(AsInt64Value()); | 18976 return FitsIntoInt64() && Smi::IsValid(AsInt64Value()); |
20112 } | 18977 } |
20113 | 18978 |
20114 | |
20115 bool Bigint::FitsIntoInt64() const { | 18979 bool Bigint::FitsIntoInt64() const { |
20116 ASSERT(Bigint::kBitsPerDigit == 32); | 18980 ASSERT(Bigint::kBitsPerDigit == 32); |
20117 const intptr_t used = Used(); | 18981 const intptr_t used = Used(); |
20118 if (used < 2) return true; | 18982 if (used < 2) return true; |
20119 if (used > 2) return false; | 18983 if (used > 2) return false; |
20120 const uint64_t digit1 = DigitAt(1); | 18984 const uint64_t digit1 = DigitAt(1); |
20121 const uint64_t value = (digit1 << 32) + DigitAt(0); | 18985 const uint64_t value = (digit1 << 32) + DigitAt(0); |
20122 uint64_t limit = Mint::kMaxValue; | 18986 uint64_t limit = Mint::kMaxValue; |
20123 if (Neg()) { | 18987 if (Neg()) { |
20124 limit++; | 18988 limit++; |
20125 } | 18989 } |
20126 return value <= limit; | 18990 return value <= limit; |
20127 } | 18991 } |
20128 | 18992 |
20129 | |
20130 int64_t Bigint::AsTruncatedInt64Value() const { | 18993 int64_t Bigint::AsTruncatedInt64Value() const { |
20131 const intptr_t used = Used(); | 18994 const intptr_t used = Used(); |
20132 if (used == 0) return 0; | 18995 if (used == 0) return 0; |
20133 const int64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 18996 const int64_t digit1 = (used > 1) ? DigitAt(1) : 0; |
20134 const int64_t value = (digit1 << 32) + DigitAt(0); | 18997 const int64_t value = (digit1 << 32) + DigitAt(0); |
20135 return Neg() ? -value : value; | 18998 return Neg() ? -value : value; |
20136 } | 18999 } |
20137 | 19000 |
20138 | |
20139 int64_t Bigint::AsInt64Value() const { | 19001 int64_t Bigint::AsInt64Value() const { |
20140 ASSERT(FitsIntoInt64()); | 19002 ASSERT(FitsIntoInt64()); |
20141 return AsTruncatedInt64Value(); | 19003 return AsTruncatedInt64Value(); |
20142 } | 19004 } |
20143 | 19005 |
20144 | |
20145 bool Bigint::FitsIntoUint64() const { | 19006 bool Bigint::FitsIntoUint64() const { |
20146 ASSERT(Bigint::kBitsPerDigit == 32); | 19007 ASSERT(Bigint::kBitsPerDigit == 32); |
20147 return !Neg() && (Used() <= 2); | 19008 return !Neg() && (Used() <= 2); |
20148 } | 19009 } |
20149 | 19010 |
20150 | |
20151 uint64_t Bigint::AsUint64Value() const { | 19011 uint64_t Bigint::AsUint64Value() const { |
20152 ASSERT(FitsIntoUint64()); | 19012 ASSERT(FitsIntoUint64()); |
20153 const intptr_t used = Used(); | 19013 const intptr_t used = Used(); |
20154 if (used == 0) return 0; | 19014 if (used == 0) return 0; |
20155 const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 19015 const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; |
20156 return (digit1 << 32) + DigitAt(0); | 19016 return (digit1 << 32) + DigitAt(0); |
20157 } | 19017 } |
20158 | 19018 |
20159 | |
20160 uint32_t Bigint::AsTruncatedUint32Value() const { | 19019 uint32_t Bigint::AsTruncatedUint32Value() const { |
20161 // Note: the previous implementation of Bigint returned the absolute value | 19020 // Note: the previous implementation of Bigint returned the absolute value |
20162 // truncated to 32 bits, which is not consistent with Smi and Mint behavior. | 19021 // truncated to 32 bits, which is not consistent with Smi and Mint behavior. |
20163 ASSERT(Bigint::kBitsPerDigit == 32); | 19022 ASSERT(Bigint::kBitsPerDigit == 32); |
20164 const intptr_t used = Used(); | 19023 const intptr_t used = Used(); |
20165 if (used == 0) return 0; | 19024 if (used == 0) return 0; |
20166 const uint32_t digit0 = DigitAt(0); | 19025 const uint32_t digit0 = DigitAt(0); |
20167 return Neg() ? static_cast<uint32_t>(-static_cast<int32_t>(digit0)) : digit0; | 19026 return Neg() ? static_cast<uint32_t>(-static_cast<int32_t>(digit0)) : digit0; |
20168 } | 19027 } |
20169 | 19028 |
20170 | |
20171 // For positive values: Smi < Mint < Bigint. | 19029 // For positive values: Smi < Mint < Bigint. |
20172 int Bigint::CompareWith(const Integer& other) const { | 19030 int Bigint::CompareWith(const Integer& other) const { |
20173 ASSERT(!FitsIntoSmi()); | 19031 ASSERT(!FitsIntoSmi()); |
20174 ASSERT(!FitsIntoInt64()); | 19032 ASSERT(!FitsIntoInt64()); |
20175 if (other.IsBigint() && (IsNegative() == other.IsNegative())) { | 19033 if (other.IsBigint() && (IsNegative() == other.IsNegative())) { |
20176 const Bigint& other_bgi = Bigint::Cast(other); | 19034 const Bigint& other_bgi = Bigint::Cast(other); |
20177 int64_t result = Used() - other_bgi.Used(); | 19035 int64_t result = Used() - other_bgi.Used(); |
20178 if (result == 0) { | 19036 if (result == 0) { |
20179 for (intptr_t i = Used(); --i >= 0;) { | 19037 for (intptr_t i = Used(); --i >= 0;) { |
20180 result = DigitAt(i); | 19038 result = DigitAt(i); |
20181 result -= other_bgi.DigitAt(i); | 19039 result -= other_bgi.DigitAt(i); |
20182 if (result != 0) break; | 19040 if (result != 0) break; |
20183 } | 19041 } |
20184 } | 19042 } |
20185 if (IsNegative()) { | 19043 if (IsNegative()) { |
20186 result = -result; | 19044 result = -result; |
20187 } | 19045 } |
20188 return result > 0 ? 1 : result < 0 ? -1 : 0; | 19046 return result > 0 ? 1 : result < 0 ? -1 : 0; |
20189 } | 19047 } |
20190 return this->IsNegative() ? -1 : 1; | 19048 return this->IsNegative() ? -1 : 1; |
20191 } | 19049 } |
20192 | 19050 |
20193 | |
20194 const char* Bigint::ToDecCString(Zone* zone) const { | 19051 const char* Bigint::ToDecCString(Zone* zone) const { |
20195 // log10(2) ~= 0.30102999566398114. | 19052 // log10(2) ~= 0.30102999566398114. |
20196 const intptr_t kLog2Dividend = 30103; | 19053 const intptr_t kLog2Dividend = 30103; |
20197 const intptr_t kLog2Divisor = 100000; | 19054 const intptr_t kLog2Divisor = 100000; |
20198 intptr_t used = Used(); | 19055 intptr_t used = Used(); |
20199 const intptr_t kMaxUsed = | 19056 const intptr_t kMaxUsed = |
20200 kIntptrMax / kBitsPerDigit / kLog2Dividend * kLog2Divisor; | 19057 kIntptrMax / kBitsPerDigit / kLog2Dividend * kLog2Divisor; |
20201 if (used > kMaxUsed) { | 19058 if (used > kMaxUsed) { |
20202 Exceptions::ThrowOOM(); | 19059 Exceptions::ThrowOOM(); |
20203 UNREACHABLE(); | 19060 UNREACHABLE(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20255 char tmp = chars[i]; | 19112 char tmp = chars[i]; |
20256 chars[i] = chars[j]; | 19113 chars[i] = chars[j]; |
20257 chars[j] = tmp; | 19114 chars[j] = tmp; |
20258 i++; | 19115 i++; |
20259 j--; | 19116 j--; |
20260 } | 19117 } |
20261 chars[pos] = '\0'; | 19118 chars[pos] = '\0'; |
20262 return chars; | 19119 return chars; |
20263 } | 19120 } |
20264 | 19121 |
20265 | |
20266 const char* Bigint::ToHexCString(Zone* zone) const { | 19122 const char* Bigint::ToHexCString(Zone* zone) const { |
20267 const intptr_t used = Used(); | 19123 const intptr_t used = Used(); |
20268 if (used == 0) { | 19124 if (used == 0) { |
20269 const char* zero = "0x0"; | 19125 const char* zero = "0x0"; |
20270 const size_t len = strlen(zero) + 1; | 19126 const size_t len = strlen(zero) + 1; |
20271 char* chars = zone->Alloc<char>(len); | 19127 char* chars = zone->Alloc<char>(len); |
20272 strncpy(chars, zero, len); | 19128 strncpy(chars, zero, len); |
20273 return chars; | 19129 return chars; |
20274 } | 19130 } |
20275 const int kBitsPerHexDigit = 4; | 19131 const int kBitsPerHexDigit = 4; |
(...skipping 30 matching lines...) Expand all Loading... |
20306 } | 19162 } |
20307 chars[--pos] = 'x'; | 19163 chars[--pos] = 'x'; |
20308 chars[--pos] = '0'; | 19164 chars[--pos] = '0'; |
20309 if (Neg()) { | 19165 if (Neg()) { |
20310 chars[--pos] = '-'; | 19166 chars[--pos] = '-'; |
20311 } | 19167 } |
20312 ASSERT(pos == 0); | 19168 ASSERT(pos == 0); |
20313 return chars; | 19169 return chars; |
20314 } | 19170 } |
20315 | 19171 |
20316 | |
20317 const char* Bigint::ToCString() const { | 19172 const char* Bigint::ToCString() const { |
20318 return ToDecCString(Thread::Current()->zone()); | 19173 return ToDecCString(Thread::Current()->zone()); |
20319 } | 19174 } |
20320 | 19175 |
20321 | |
20322 // Synchronize with implementation in compiler (intrinsifier). | 19176 // Synchronize with implementation in compiler (intrinsifier). |
20323 class StringHasher : ValueObject { | 19177 class StringHasher : ValueObject { |
20324 public: | 19178 public: |
20325 StringHasher() : hash_(0) {} | 19179 StringHasher() : hash_(0) {} |
20326 void Add(int32_t ch) { hash_ = CombineHashes(hash_, ch); } | 19180 void Add(int32_t ch) { hash_ = CombineHashes(hash_, ch); } |
20327 void Add(const String& str, intptr_t begin_index, intptr_t len); | 19181 void Add(const String& str, intptr_t begin_index, intptr_t len); |
20328 | 19182 |
20329 // Return a non-zero hash of at most 'bits' bits. | 19183 // Return a non-zero hash of at most 'bits' bits. |
20330 intptr_t Finalize(int bits) { | 19184 intptr_t Finalize(int bits) { |
20331 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); | 19185 ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); |
20332 hash_ = FinalizeHash(hash_, bits); | 19186 hash_ = FinalizeHash(hash_, bits); |
20333 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); | 19187 ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); |
20334 return hash_; | 19188 return hash_; |
20335 } | 19189 } |
20336 | 19190 |
20337 private: | 19191 private: |
20338 uint32_t hash_; | 19192 uint32_t hash_; |
20339 }; | 19193 }; |
20340 | 19194 |
20341 | |
20342 void StringHasher::Add(const String& str, intptr_t begin_index, intptr_t len) { | 19195 void StringHasher::Add(const String& str, intptr_t begin_index, intptr_t len) { |
20343 ASSERT(begin_index >= 0); | 19196 ASSERT(begin_index >= 0); |
20344 ASSERT(len >= 0); | 19197 ASSERT(len >= 0); |
20345 ASSERT((begin_index + len) <= str.Length()); | 19198 ASSERT((begin_index + len) <= str.Length()); |
20346 if (len == 0) { | 19199 if (len == 0) { |
20347 return; | 19200 return; |
20348 } | 19201 } |
20349 if (str.IsOneByteString()) { | 19202 if (str.IsOneByteString()) { |
20350 NoSafepointScope no_safepoint; | 19203 NoSafepointScope no_safepoint; |
20351 uint8_t* str_addr = OneByteString::CharAddr(str, begin_index); | 19204 uint8_t* str_addr = OneByteString::CharAddr(str, begin_index); |
20352 for (intptr_t i = 0; i < len; i++) { | 19205 for (intptr_t i = 0; i < len; i++) { |
20353 Add(*str_addr); | 19206 Add(*str_addr); |
20354 str_addr++; | 19207 str_addr++; |
20355 } | 19208 } |
20356 } else { | 19209 } else { |
20357 String::CodePointIterator it(str, begin_index, len); | 19210 String::CodePointIterator it(str, begin_index, len); |
20358 while (it.Next()) { | 19211 while (it.Next()) { |
20359 Add(it.Current()); | 19212 Add(it.Current()); |
20360 } | 19213 } |
20361 } | 19214 } |
20362 } | 19215 } |
20363 | 19216 |
20364 | |
20365 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { | 19217 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { |
20366 StringHasher hasher; | 19218 StringHasher hasher; |
20367 hasher.Add(str, begin_index, len); | 19219 hasher.Add(str, begin_index, len); |
20368 return hasher.Finalize(kHashBits); | 19220 return hasher.Finalize(kHashBits); |
20369 } | 19221 } |
20370 | 19222 |
20371 | |
20372 intptr_t String::HashConcat(const String& str1, const String& str2) { | 19223 intptr_t String::HashConcat(const String& str1, const String& str2) { |
20373 intptr_t len1 = str1.Length(); | 19224 intptr_t len1 = str1.Length(); |
20374 // Since String::Hash works at the code point (rune) level, a surrogate pair | 19225 // Since String::Hash works at the code point (rune) level, a surrogate pair |
20375 // that crosses the boundary between str1 and str2 must be composed. | 19226 // that crosses the boundary between str1 and str2 must be composed. |
20376 if (str1.IsTwoByteString() && Utf16::IsLeadSurrogate(str1.CharAt(len1 - 1))) { | 19227 if (str1.IsTwoByteString() && Utf16::IsLeadSurrogate(str1.CharAt(len1 - 1))) { |
20377 const String& temp = String::Handle(String::Concat(str1, str2)); | 19228 const String& temp = String::Handle(String::Concat(str1, str2)); |
20378 return temp.Hash(); | 19229 return temp.Hash(); |
20379 } else { | 19230 } else { |
20380 StringHasher hasher; | 19231 StringHasher hasher; |
20381 hasher.Add(str1, 0, len1); | 19232 hasher.Add(str1, 0, len1); |
20382 hasher.Add(str2, 0, str2.Length()); | 19233 hasher.Add(str2, 0, str2.Length()); |
20383 return hasher.Finalize(kHashBits); | 19234 return hasher.Finalize(kHashBits); |
20384 } | 19235 } |
20385 } | 19236 } |
20386 | 19237 |
20387 | |
20388 template <typename T> | 19238 template <typename T> |
20389 static intptr_t HashImpl(const T* characters, intptr_t len) { | 19239 static intptr_t HashImpl(const T* characters, intptr_t len) { |
20390 ASSERT(len >= 0); | 19240 ASSERT(len >= 0); |
20391 StringHasher hasher; | 19241 StringHasher hasher; |
20392 for (intptr_t i = 0; i < len; i++) { | 19242 for (intptr_t i = 0; i < len; i++) { |
20393 hasher.Add(characters[i]); | 19243 hasher.Add(characters[i]); |
20394 } | 19244 } |
20395 return hasher.Finalize(String::kHashBits); | 19245 return hasher.Finalize(String::kHashBits); |
20396 } | 19246 } |
20397 | 19247 |
20398 | |
20399 intptr_t String::Hash(RawString* raw) { | 19248 intptr_t String::Hash(RawString* raw) { |
20400 StringHasher hasher; | 19249 StringHasher hasher; |
20401 uword length = Smi::Value(raw->ptr()->length_); | 19250 uword length = Smi::Value(raw->ptr()->length_); |
20402 if (raw->IsOneByteString() || raw->IsExternalOneByteString()) { | 19251 if (raw->IsOneByteString() || raw->IsExternalOneByteString()) { |
20403 const uint8_t* data; | 19252 const uint8_t* data; |
20404 if (raw->IsOneByteString()) { | 19253 if (raw->IsOneByteString()) { |
20405 data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data(); | 19254 data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data(); |
20406 } else { | 19255 } else { |
20407 ASSERT(raw->IsExternalOneByteString()); | 19256 ASSERT(raw->IsExternalOneByteString()); |
20408 RawExternalOneByteString* str = | 19257 RawExternalOneByteString* str = |
20409 reinterpret_cast<RawExternalOneByteString*>(raw); | 19258 reinterpret_cast<RawExternalOneByteString*>(raw); |
20410 data = str->ptr()->external_data_->data(); | 19259 data = str->ptr()->external_data_->data(); |
20411 } | 19260 } |
20412 return String::Hash(data, length); | 19261 return String::Hash(data, length); |
20413 } else { | 19262 } else { |
20414 const uint16_t* data; | 19263 const uint16_t* data; |
20415 if (raw->IsTwoByteString()) { | 19264 if (raw->IsTwoByteString()) { |
20416 data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data(); | 19265 data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data(); |
20417 } else { | 19266 } else { |
20418 ASSERT(raw->IsExternalTwoByteString()); | 19267 ASSERT(raw->IsExternalTwoByteString()); |
20419 RawExternalTwoByteString* str = | 19268 RawExternalTwoByteString* str = |
20420 reinterpret_cast<RawExternalTwoByteString*>(raw); | 19269 reinterpret_cast<RawExternalTwoByteString*>(raw); |
20421 data = str->ptr()->external_data_->data(); | 19270 data = str->ptr()->external_data_->data(); |
20422 } | 19271 } |
20423 return String::Hash(data, length); | 19272 return String::Hash(data, length); |
20424 } | 19273 } |
20425 } | 19274 } |
20426 | 19275 |
20427 | |
20428 intptr_t String::Hash(const char* characters, intptr_t len) { | 19276 intptr_t String::Hash(const char* characters, intptr_t len) { |
20429 return HashImpl(characters, len); | 19277 return HashImpl(characters, len); |
20430 } | 19278 } |
20431 | 19279 |
20432 | |
20433 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { | 19280 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { |
20434 return HashImpl(characters, len); | 19281 return HashImpl(characters, len); |
20435 } | 19282 } |
20436 | 19283 |
20437 | |
20438 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { | 19284 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { |
20439 StringHasher hasher; | 19285 StringHasher hasher; |
20440 intptr_t i = 0; | 19286 intptr_t i = 0; |
20441 while (i < len) { | 19287 while (i < len) { |
20442 hasher.Add(Utf16::Next(characters, &i, len)); | 19288 hasher.Add(Utf16::Next(characters, &i, len)); |
20443 } | 19289 } |
20444 return hasher.Finalize(kHashBits); | 19290 return hasher.Finalize(kHashBits); |
20445 } | 19291 } |
20446 | 19292 |
20447 | |
20448 intptr_t String::Hash(const int32_t* characters, intptr_t len) { | 19293 intptr_t String::Hash(const int32_t* characters, intptr_t len) { |
20449 return HashImpl(characters, len); | 19294 return HashImpl(characters, len); |
20450 } | 19295 } |
20451 | 19296 |
20452 | |
20453 uint16_t String::CharAt(intptr_t index) const { | 19297 uint16_t String::CharAt(intptr_t index) const { |
20454 intptr_t class_id = raw()->GetClassId(); | 19298 intptr_t class_id = raw()->GetClassId(); |
20455 ASSERT(RawObject::IsStringClassId(class_id)); | 19299 ASSERT(RawObject::IsStringClassId(class_id)); |
20456 if (class_id == kOneByteStringCid) { | 19300 if (class_id == kOneByteStringCid) { |
20457 return OneByteString::CharAt(*this, index); | 19301 return OneByteString::CharAt(*this, index); |
20458 } | 19302 } |
20459 if (class_id == kTwoByteStringCid) { | 19303 if (class_id == kTwoByteStringCid) { |
20460 return TwoByteString::CharAt(*this, index); | 19304 return TwoByteString::CharAt(*this, index); |
20461 } | 19305 } |
20462 if (class_id == kExternalOneByteStringCid) { | 19306 if (class_id == kExternalOneByteStringCid) { |
20463 return ExternalOneByteString::CharAt(*this, index); | 19307 return ExternalOneByteString::CharAt(*this, index); |
20464 } | 19308 } |
20465 ASSERT(class_id == kExternalTwoByteStringCid); | 19309 ASSERT(class_id == kExternalTwoByteStringCid); |
20466 return ExternalTwoByteString::CharAt(*this, index); | 19310 return ExternalTwoByteString::CharAt(*this, index); |
20467 } | 19311 } |
20468 | 19312 |
20469 | |
20470 Scanner::CharAtFunc String::CharAtFunc() const { | 19313 Scanner::CharAtFunc String::CharAtFunc() const { |
20471 intptr_t class_id = raw()->GetClassId(); | 19314 intptr_t class_id = raw()->GetClassId(); |
20472 ASSERT(RawObject::IsStringClassId(class_id)); | 19315 ASSERT(RawObject::IsStringClassId(class_id)); |
20473 if (class_id == kOneByteStringCid) { | 19316 if (class_id == kOneByteStringCid) { |
20474 return &OneByteString::CharAt; | 19317 return &OneByteString::CharAt; |
20475 } | 19318 } |
20476 if (class_id == kTwoByteStringCid) { | 19319 if (class_id == kTwoByteStringCid) { |
20477 return &TwoByteString::CharAt; | 19320 return &TwoByteString::CharAt; |
20478 } | 19321 } |
20479 if (class_id == kExternalOneByteStringCid) { | 19322 if (class_id == kExternalOneByteStringCid) { |
20480 return &ExternalOneByteString::CharAt; | 19323 return &ExternalOneByteString::CharAt; |
20481 } | 19324 } |
20482 ASSERT(class_id == kExternalTwoByteStringCid); | 19325 ASSERT(class_id == kExternalTwoByteStringCid); |
20483 return &ExternalTwoByteString::CharAt; | 19326 return &ExternalTwoByteString::CharAt; |
20484 } | 19327 } |
20485 | 19328 |
20486 | |
20487 intptr_t String::CharSize() const { | 19329 intptr_t String::CharSize() const { |
20488 intptr_t class_id = raw()->GetClassId(); | 19330 intptr_t class_id = raw()->GetClassId(); |
20489 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { | 19331 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { |
20490 return kOneByteChar; | 19332 return kOneByteChar; |
20491 } | 19333 } |
20492 ASSERT(class_id == kTwoByteStringCid || | 19334 ASSERT(class_id == kTwoByteStringCid || |
20493 class_id == kExternalTwoByteStringCid); | 19335 class_id == kExternalTwoByteStringCid); |
20494 return kTwoByteChar; | 19336 return kTwoByteChar; |
20495 } | 19337 } |
20496 | 19338 |
20497 | |
20498 void* String::GetPeer() const { | 19339 void* String::GetPeer() const { |
20499 intptr_t class_id = raw()->GetClassId(); | 19340 intptr_t class_id = raw()->GetClassId(); |
20500 if (class_id == kExternalOneByteStringCid) { | 19341 if (class_id == kExternalOneByteStringCid) { |
20501 return ExternalOneByteString::GetPeer(*this); | 19342 return ExternalOneByteString::GetPeer(*this); |
20502 } | 19343 } |
20503 ASSERT(class_id == kExternalTwoByteStringCid); | 19344 ASSERT(class_id == kExternalTwoByteStringCid); |
20504 return ExternalTwoByteString::GetPeer(*this); | 19345 return ExternalTwoByteString::GetPeer(*this); |
20505 } | 19346 } |
20506 | 19347 |
20507 | |
20508 bool String::Equals(const Instance& other) const { | 19348 bool String::Equals(const Instance& other) const { |
20509 if (this->raw() == other.raw()) { | 19349 if (this->raw() == other.raw()) { |
20510 // Both handles point to the same raw instance. | 19350 // Both handles point to the same raw instance. |
20511 return true; | 19351 return true; |
20512 } | 19352 } |
20513 | 19353 |
20514 if (!other.IsString()) { | 19354 if (!other.IsString()) { |
20515 return false; | 19355 return false; |
20516 } | 19356 } |
20517 | 19357 |
20518 const String& other_string = String::Cast(other); | 19358 const String& other_string = String::Cast(other); |
20519 return Equals(other_string); | 19359 return Equals(other_string); |
20520 } | 19360 } |
20521 | 19361 |
20522 | |
20523 bool String::Equals(const String& str, | 19362 bool String::Equals(const String& str, |
20524 intptr_t begin_index, | 19363 intptr_t begin_index, |
20525 intptr_t len) const { | 19364 intptr_t len) const { |
20526 ASSERT(begin_index >= 0); | 19365 ASSERT(begin_index >= 0); |
20527 ASSERT((begin_index == 0) || (begin_index < str.Length())); | 19366 ASSERT((begin_index == 0) || (begin_index < str.Length())); |
20528 ASSERT(len >= 0); | 19367 ASSERT(len >= 0); |
20529 ASSERT(len <= str.Length()); | 19368 ASSERT(len <= str.Length()); |
20530 if (len != this->Length()) { | 19369 if (len != this->Length()) { |
20531 return false; // Lengths don't match. | 19370 return false; // Lengths don't match. |
20532 } | 19371 } |
20533 | 19372 |
20534 Scanner::CharAtFunc this_char_at_func = this->CharAtFunc(); | 19373 Scanner::CharAtFunc this_char_at_func = this->CharAtFunc(); |
20535 Scanner::CharAtFunc str_char_at_func = str.CharAtFunc(); | 19374 Scanner::CharAtFunc str_char_at_func = str.CharAtFunc(); |
20536 for (intptr_t i = 0; i < len; i++) { | 19375 for (intptr_t i = 0; i < len; i++) { |
20537 if (this_char_at_func(*this, i) != str_char_at_func(str, begin_index + i)) { | 19376 if (this_char_at_func(*this, i) != str_char_at_func(str, begin_index + i)) { |
20538 return false; | 19377 return false; |
20539 } | 19378 } |
20540 } | 19379 } |
20541 | 19380 |
20542 return true; | 19381 return true; |
20543 } | 19382 } |
20544 | 19383 |
20545 | |
20546 bool String::Equals(const char* cstr) const { | 19384 bool String::Equals(const char* cstr) const { |
20547 ASSERT(cstr != NULL); | 19385 ASSERT(cstr != NULL); |
20548 CodePointIterator it(*this); | 19386 CodePointIterator it(*this); |
20549 intptr_t len = strlen(cstr); | 19387 intptr_t len = strlen(cstr); |
20550 while (it.Next()) { | 19388 while (it.Next()) { |
20551 if (*cstr == '\0') { | 19389 if (*cstr == '\0') { |
20552 // Lengths don't match. | 19390 // Lengths don't match. |
20553 return false; | 19391 return false; |
20554 } | 19392 } |
20555 int32_t ch; | 19393 int32_t ch; |
20556 intptr_t consumed = | 19394 intptr_t consumed = |
20557 Utf8::Decode(reinterpret_cast<const uint8_t*>(cstr), len, &ch); | 19395 Utf8::Decode(reinterpret_cast<const uint8_t*>(cstr), len, &ch); |
20558 if (consumed == 0 || it.Current() != ch) { | 19396 if (consumed == 0 || it.Current() != ch) { |
20559 return false; | 19397 return false; |
20560 } | 19398 } |
20561 cstr += consumed; | 19399 cstr += consumed; |
20562 len -= consumed; | 19400 len -= consumed; |
20563 } | 19401 } |
20564 return *cstr == '\0'; | 19402 return *cstr == '\0'; |
20565 } | 19403 } |
20566 | 19404 |
20567 | |
20568 bool String::Equals(const uint8_t* latin1_array, intptr_t len) const { | 19405 bool String::Equals(const uint8_t* latin1_array, intptr_t len) const { |
20569 if (len != this->Length()) { | 19406 if (len != this->Length()) { |
20570 // Lengths don't match. | 19407 // Lengths don't match. |
20571 return false; | 19408 return false; |
20572 } | 19409 } |
20573 | 19410 |
20574 for (intptr_t i = 0; i < len; i++) { | 19411 for (intptr_t i = 0; i < len; i++) { |
20575 if (this->CharAt(i) != latin1_array[i]) { | 19412 if (this->CharAt(i) != latin1_array[i]) { |
20576 return false; | 19413 return false; |
20577 } | 19414 } |
20578 } | 19415 } |
20579 return true; | 19416 return true; |
20580 } | 19417 } |
20581 | 19418 |
20582 | |
20583 bool String::Equals(const uint16_t* utf16_array, intptr_t len) const { | 19419 bool String::Equals(const uint16_t* utf16_array, intptr_t len) const { |
20584 if (len != this->Length()) { | 19420 if (len != this->Length()) { |
20585 // Lengths don't match. | 19421 // Lengths don't match. |
20586 return false; | 19422 return false; |
20587 } | 19423 } |
20588 | 19424 |
20589 for (intptr_t i = 0; i < len; i++) { | 19425 for (intptr_t i = 0; i < len; i++) { |
20590 if (this->CharAt(i) != utf16_array[i]) { | 19426 if (this->CharAt(i) != utf16_array[i]) { |
20591 return false; | 19427 return false; |
20592 } | 19428 } |
20593 } | 19429 } |
20594 return true; | 19430 return true; |
20595 } | 19431 } |
20596 | 19432 |
20597 | |
20598 bool String::Equals(const int32_t* utf32_array, intptr_t len) const { | 19433 bool String::Equals(const int32_t* utf32_array, intptr_t len) const { |
20599 if (len < 0) return false; | 19434 if (len < 0) return false; |
20600 intptr_t j = 0; | 19435 intptr_t j = 0; |
20601 for (intptr_t i = 0; i < len; ++i) { | 19436 for (intptr_t i = 0; i < len; ++i) { |
20602 if (Utf::IsSupplementary(utf32_array[i])) { | 19437 if (Utf::IsSupplementary(utf32_array[i])) { |
20603 uint16_t encoded[2]; | 19438 uint16_t encoded[2]; |
20604 Utf16::Encode(utf32_array[i], &encoded[0]); | 19439 Utf16::Encode(utf32_array[i], &encoded[0]); |
20605 if (j + 1 >= Length()) return false; | 19440 if (j + 1 >= Length()) return false; |
20606 if (CharAt(j++) != encoded[0]) return false; | 19441 if (CharAt(j++) != encoded[0]) return false; |
20607 if (CharAt(j++) != encoded[1]) return false; | 19442 if (CharAt(j++) != encoded[1]) return false; |
20608 } else { | 19443 } else { |
20609 if (j >= Length()) return false; | 19444 if (j >= Length()) return false; |
20610 if (CharAt(j++) != utf32_array[i]) return false; | 19445 if (CharAt(j++) != utf32_array[i]) return false; |
20611 } | 19446 } |
20612 } | 19447 } |
20613 return j == Length(); | 19448 return j == Length(); |
20614 } | 19449 } |
20615 | 19450 |
20616 | |
20617 bool String::EqualsConcat(const String& str1, const String& str2) const { | 19451 bool String::EqualsConcat(const String& str1, const String& str2) const { |
20618 return (Length() == str1.Length() + str2.Length()) && | 19452 return (Length() == str1.Length() + str2.Length()) && |
20619 str1.Equals(*this, 0, str1.Length()) && | 19453 str1.Equals(*this, 0, str1.Length()) && |
20620 str2.Equals(*this, str1.Length(), str2.Length()); | 19454 str2.Equals(*this, str1.Length(), str2.Length()); |
20621 } | 19455 } |
20622 | 19456 |
20623 | |
20624 intptr_t String::CompareTo(const String& other) const { | 19457 intptr_t String::CompareTo(const String& other) const { |
20625 const intptr_t this_len = this->Length(); | 19458 const intptr_t this_len = this->Length(); |
20626 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); | 19459 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); |
20627 const intptr_t len = (this_len < other_len) ? this_len : other_len; | 19460 const intptr_t len = (this_len < other_len) ? this_len : other_len; |
20628 for (intptr_t i = 0; i < len; i++) { | 19461 for (intptr_t i = 0; i < len; i++) { |
20629 uint16_t this_code_unit = this->CharAt(i); | 19462 uint16_t this_code_unit = this->CharAt(i); |
20630 uint16_t other_code_unit = other.CharAt(i); | 19463 uint16_t other_code_unit = other.CharAt(i); |
20631 if (this_code_unit < other_code_unit) { | 19464 if (this_code_unit < other_code_unit) { |
20632 return -1; | 19465 return -1; |
20633 } | 19466 } |
20634 if (this_code_unit > other_code_unit) { | 19467 if (this_code_unit > other_code_unit) { |
20635 return 1; | 19468 return 1; |
20636 } | 19469 } |
20637 } | 19470 } |
20638 if (this_len < other_len) return -1; | 19471 if (this_len < other_len) return -1; |
20639 if (this_len > other_len) return 1; | 19472 if (this_len > other_len) return 1; |
20640 return 0; | 19473 return 0; |
20641 } | 19474 } |
20642 | 19475 |
20643 | |
20644 bool String::StartsWith(const String& other) const { | 19476 bool String::StartsWith(const String& other) const { |
20645 if (other.IsNull() || (other.Length() > this->Length())) { | 19477 if (other.IsNull() || (other.Length() > this->Length())) { |
20646 return false; | 19478 return false; |
20647 } | 19479 } |
20648 intptr_t slen = other.Length(); | 19480 intptr_t slen = other.Length(); |
20649 for (int i = 0; i < slen; i++) { | 19481 for (int i = 0; i < slen; i++) { |
20650 if (this->CharAt(i) != other.CharAt(i)) { | 19482 if (this->CharAt(i) != other.CharAt(i)) { |
20651 return false; | 19483 return false; |
20652 } | 19484 } |
20653 } | 19485 } |
20654 return true; | 19486 return true; |
20655 } | 19487 } |
20656 | 19488 |
20657 | |
20658 RawInstance* String::CheckAndCanonicalize(Thread* thread, | 19489 RawInstance* String::CheckAndCanonicalize(Thread* thread, |
20659 const char** error_str) const { | 19490 const char** error_str) const { |
20660 if (IsCanonical()) { | 19491 if (IsCanonical()) { |
20661 return this->raw(); | 19492 return this->raw(); |
20662 } | 19493 } |
20663 return Symbols::New(Thread::Current(), *this); | 19494 return Symbols::New(Thread::Current(), *this); |
20664 } | 19495 } |
20665 | 19496 |
20666 | |
20667 #if defined(DEBUG) | 19497 #if defined(DEBUG) |
20668 bool String::CheckIsCanonical(Thread* thread) const { | 19498 bool String::CheckIsCanonical(Thread* thread) const { |
20669 Zone* zone = thread->zone(); | 19499 Zone* zone = thread->zone(); |
20670 const String& str = String::Handle(zone, Symbols::Lookup(thread, *this)); | 19500 const String& str = String::Handle(zone, Symbols::Lookup(thread, *this)); |
20671 return (str.raw() == this->raw()); | 19501 return (str.raw() == this->raw()); |
20672 } | 19502 } |
20673 #endif // DEBUG | 19503 #endif // DEBUG |
20674 | 19504 |
20675 | |
20676 RawString* String::New(const char* cstr, Heap::Space space) { | 19505 RawString* String::New(const char* cstr, Heap::Space space) { |
20677 ASSERT(cstr != NULL); | 19506 ASSERT(cstr != NULL); |
20678 intptr_t array_len = strlen(cstr); | 19507 intptr_t array_len = strlen(cstr); |
20679 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); | 19508 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); |
20680 return String::FromUTF8(utf8_array, array_len, space); | 19509 return String::FromUTF8(utf8_array, array_len, space); |
20681 } | 19510 } |
20682 | 19511 |
20683 | |
20684 RawString* String::FromUTF8(const uint8_t* utf8_array, | 19512 RawString* String::FromUTF8(const uint8_t* utf8_array, |
20685 intptr_t array_len, | 19513 intptr_t array_len, |
20686 Heap::Space space) { | 19514 Heap::Space space) { |
20687 Utf8::Type type; | 19515 Utf8::Type type; |
20688 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); | 19516 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); |
20689 if (type == Utf8::kLatin1) { | 19517 if (type == Utf8::kLatin1) { |
20690 const String& strobj = String::Handle(OneByteString::New(len, space)); | 19518 const String& strobj = String::Handle(OneByteString::New(len, space)); |
20691 if (len > 0) { | 19519 if (len > 0) { |
20692 NoSafepointScope no_safepoint; | 19520 NoSafepointScope no_safepoint; |
20693 Utf8::DecodeToLatin1(utf8_array, array_len, | 19521 Utf8::DecodeToLatin1(utf8_array, array_len, |
20694 OneByteString::CharAddr(strobj, 0), len); | 19522 OneByteString::CharAddr(strobj, 0), len); |
20695 } | 19523 } |
20696 return strobj.raw(); | 19524 return strobj.raw(); |
20697 } | 19525 } |
20698 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); | 19526 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); |
20699 const String& strobj = String::Handle(TwoByteString::New(len, space)); | 19527 const String& strobj = String::Handle(TwoByteString::New(len, space)); |
20700 NoSafepointScope no_safepoint; | 19528 NoSafepointScope no_safepoint; |
20701 Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::CharAddr(strobj, 0), | 19529 Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::CharAddr(strobj, 0), |
20702 len); | 19530 len); |
20703 return strobj.raw(); | 19531 return strobj.raw(); |
20704 } | 19532 } |
20705 | 19533 |
20706 | |
20707 RawString* String::FromLatin1(const uint8_t* latin1_array, | 19534 RawString* String::FromLatin1(const uint8_t* latin1_array, |
20708 intptr_t array_len, | 19535 intptr_t array_len, |
20709 Heap::Space space) { | 19536 Heap::Space space) { |
20710 return OneByteString::New(latin1_array, array_len, space); | 19537 return OneByteString::New(latin1_array, array_len, space); |
20711 } | 19538 } |
20712 | 19539 |
20713 | |
20714 RawString* String::FromUTF16(const uint16_t* utf16_array, | 19540 RawString* String::FromUTF16(const uint16_t* utf16_array, |
20715 intptr_t array_len, | 19541 intptr_t array_len, |
20716 Heap::Space space) { | 19542 Heap::Space space) { |
20717 bool is_one_byte_string = true; | 19543 bool is_one_byte_string = true; |
20718 for (intptr_t i = 0; i < array_len; ++i) { | 19544 for (intptr_t i = 0; i < array_len; ++i) { |
20719 if (!Utf::IsLatin1(utf16_array[i])) { | 19545 if (!Utf::IsLatin1(utf16_array[i])) { |
20720 is_one_byte_string = false; | 19546 is_one_byte_string = false; |
20721 break; | 19547 break; |
20722 } | 19548 } |
20723 } | 19549 } |
20724 if (is_one_byte_string) { | 19550 if (is_one_byte_string) { |
20725 return OneByteString::New(utf16_array, array_len, space); | 19551 return OneByteString::New(utf16_array, array_len, space); |
20726 } | 19552 } |
20727 return TwoByteString::New(utf16_array, array_len, space); | 19553 return TwoByteString::New(utf16_array, array_len, space); |
20728 } | 19554 } |
20729 | 19555 |
20730 | |
20731 RawString* String::FromUTF32(const int32_t* utf32_array, | 19556 RawString* String::FromUTF32(const int32_t* utf32_array, |
20732 intptr_t array_len, | 19557 intptr_t array_len, |
20733 Heap::Space space) { | 19558 Heap::Space space) { |
20734 bool is_one_byte_string = true; | 19559 bool is_one_byte_string = true; |
20735 intptr_t utf16_len = array_len; | 19560 intptr_t utf16_len = array_len; |
20736 for (intptr_t i = 0; i < array_len; ++i) { | 19561 for (intptr_t i = 0; i < array_len; ++i) { |
20737 if (!Utf::IsLatin1(utf32_array[i])) { | 19562 if (!Utf::IsLatin1(utf32_array[i])) { |
20738 is_one_byte_string = false; | 19563 is_one_byte_string = false; |
20739 if (Utf::IsSupplementary(utf32_array[i])) { | 19564 if (Utf::IsSupplementary(utf32_array[i])) { |
20740 utf16_len += 1; | 19565 utf16_len += 1; |
20741 } | 19566 } |
20742 } | 19567 } |
20743 } | 19568 } |
20744 if (is_one_byte_string) { | 19569 if (is_one_byte_string) { |
20745 return OneByteString::New(utf32_array, array_len, space); | 19570 return OneByteString::New(utf32_array, array_len, space); |
20746 } | 19571 } |
20747 return TwoByteString::New(utf16_len, utf32_array, array_len, space); | 19572 return TwoByteString::New(utf16_len, utf32_array, array_len, space); |
20748 } | 19573 } |
20749 | 19574 |
20750 | |
20751 RawString* String::New(const String& str, Heap::Space space) { | 19575 RawString* String::New(const String& str, Heap::Space space) { |
20752 // Currently this just creates a copy of the string in the correct space. | 19576 // Currently this just creates a copy of the string in the correct space. |
20753 // Once we have external string support, this will also create a heap copy of | 19577 // Once we have external string support, this will also create a heap copy of |
20754 // the string if necessary. Some optimizations are possible, such as not | 19578 // the string if necessary. Some optimizations are possible, such as not |
20755 // copying internal strings into the same space. | 19579 // copying internal strings into the same space. |
20756 intptr_t len = str.Length(); | 19580 intptr_t len = str.Length(); |
20757 String& result = String::Handle(); | 19581 String& result = String::Handle(); |
20758 intptr_t char_size = str.CharSize(); | 19582 intptr_t char_size = str.CharSize(); |
20759 if (char_size == kOneByteChar) { | 19583 if (char_size == kOneByteChar) { |
20760 result = OneByteString::New(len, space); | 19584 result = OneByteString::New(len, space); |
20761 } else { | 19585 } else { |
20762 ASSERT(char_size == kTwoByteChar); | 19586 ASSERT(char_size == kTwoByteChar); |
20763 result = TwoByteString::New(len, space); | 19587 result = TwoByteString::New(len, space); |
20764 } | 19588 } |
20765 String::Copy(result, 0, str, 0, len); | 19589 String::Copy(result, 0, str, 0, len); |
20766 return result.raw(); | 19590 return result.raw(); |
20767 } | 19591 } |
20768 | 19592 |
20769 | |
20770 RawString* String::NewExternal(const uint8_t* characters, | 19593 RawString* String::NewExternal(const uint8_t* characters, |
20771 intptr_t len, | 19594 intptr_t len, |
20772 void* peer, | 19595 void* peer, |
20773 Dart_PeerFinalizer callback, | 19596 Dart_PeerFinalizer callback, |
20774 Heap::Space space) { | 19597 Heap::Space space) { |
20775 return ExternalOneByteString::New(characters, len, peer, callback, space); | 19598 return ExternalOneByteString::New(characters, len, peer, callback, space); |
20776 } | 19599 } |
20777 | 19600 |
20778 | |
20779 RawString* String::NewExternal(const uint16_t* characters, | 19601 RawString* String::NewExternal(const uint16_t* characters, |
20780 intptr_t len, | 19602 intptr_t len, |
20781 void* peer, | 19603 void* peer, |
20782 Dart_PeerFinalizer callback, | 19604 Dart_PeerFinalizer callback, |
20783 Heap::Space space) { | 19605 Heap::Space space) { |
20784 return ExternalTwoByteString::New(characters, len, peer, callback, space); | 19606 return ExternalTwoByteString::New(characters, len, peer, callback, space); |
20785 } | 19607 } |
20786 | 19608 |
20787 | |
20788 void String::Copy(const String& dst, | 19609 void String::Copy(const String& dst, |
20789 intptr_t dst_offset, | 19610 intptr_t dst_offset, |
20790 const uint8_t* characters, | 19611 const uint8_t* characters, |
20791 intptr_t len) { | 19612 intptr_t len) { |
20792 ASSERT(dst_offset >= 0); | 19613 ASSERT(dst_offset >= 0); |
20793 ASSERT(len >= 0); | 19614 ASSERT(len >= 0); |
20794 ASSERT(len <= (dst.Length() - dst_offset)); | 19615 ASSERT(len <= (dst.Length() - dst_offset)); |
20795 if (dst.IsOneByteString()) { | 19616 if (dst.IsOneByteString()) { |
20796 NoSafepointScope no_safepoint; | 19617 NoSafepointScope no_safepoint; |
20797 if (len > 0) { | 19618 if (len > 0) { |
20798 memmove(OneByteString::CharAddr(dst, dst_offset), characters, len); | 19619 memmove(OneByteString::CharAddr(dst, dst_offset), characters, len); |
20799 } | 19620 } |
20800 } else if (dst.IsTwoByteString()) { | 19621 } else if (dst.IsTwoByteString()) { |
20801 for (intptr_t i = 0; i < len; ++i) { | 19622 for (intptr_t i = 0; i < len; ++i) { |
20802 *TwoByteString::CharAddr(dst, i + dst_offset) = characters[i]; | 19623 *TwoByteString::CharAddr(dst, i + dst_offset) = characters[i]; |
20803 } | 19624 } |
20804 } | 19625 } |
20805 } | 19626 } |
20806 | 19627 |
20807 | |
20808 void String::Copy(const String& dst, | 19628 void String::Copy(const String& dst, |
20809 intptr_t dst_offset, | 19629 intptr_t dst_offset, |
20810 const uint16_t* utf16_array, | 19630 const uint16_t* utf16_array, |
20811 intptr_t array_len) { | 19631 intptr_t array_len) { |
20812 ASSERT(dst_offset >= 0); | 19632 ASSERT(dst_offset >= 0); |
20813 ASSERT(array_len >= 0); | 19633 ASSERT(array_len >= 0); |
20814 ASSERT(array_len <= (dst.Length() - dst_offset)); | 19634 ASSERT(array_len <= (dst.Length() - dst_offset)); |
20815 if (dst.IsOneByteString()) { | 19635 if (dst.IsOneByteString()) { |
20816 NoSafepointScope no_safepoint; | 19636 NoSafepointScope no_safepoint; |
20817 for (intptr_t i = 0; i < array_len; ++i) { | 19637 for (intptr_t i = 0; i < array_len; ++i) { |
20818 ASSERT(Utf::IsLatin1(utf16_array[i])); | 19638 ASSERT(Utf::IsLatin1(utf16_array[i])); |
20819 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; | 19639 *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; |
20820 } | 19640 } |
20821 } else { | 19641 } else { |
20822 ASSERT(dst.IsTwoByteString()); | 19642 ASSERT(dst.IsTwoByteString()); |
20823 NoSafepointScope no_safepoint; | 19643 NoSafepointScope no_safepoint; |
20824 if (array_len > 0) { | 19644 if (array_len > 0) { |
20825 memmove(TwoByteString::CharAddr(dst, dst_offset), utf16_array, | 19645 memmove(TwoByteString::CharAddr(dst, dst_offset), utf16_array, |
20826 array_len * 2); | 19646 array_len * 2); |
20827 } | 19647 } |
20828 } | 19648 } |
20829 } | 19649 } |
20830 | 19650 |
20831 | |
20832 void String::Copy(const String& dst, | 19651 void String::Copy(const String& dst, |
20833 intptr_t dst_offset, | 19652 intptr_t dst_offset, |
20834 const String& src, | 19653 const String& src, |
20835 intptr_t src_offset, | 19654 intptr_t src_offset, |
20836 intptr_t len) { | 19655 intptr_t len) { |
20837 ASSERT(dst_offset >= 0); | 19656 ASSERT(dst_offset >= 0); |
20838 ASSERT(src_offset >= 0); | 19657 ASSERT(src_offset >= 0); |
20839 ASSERT(len >= 0); | 19658 ASSERT(len >= 0); |
20840 ASSERT(len <= (dst.Length() - dst_offset)); | 19659 ASSERT(len <= (dst.Length() - dst_offset)); |
20841 ASSERT(len <= (src.Length() - src_offset)); | 19660 ASSERT(len <= (src.Length() - src_offset)); |
(...skipping 19 matching lines...) Expand all Loading... |
20861 } else { | 19680 } else { |
20862 ASSERT(src.IsExternalTwoByteString()); | 19681 ASSERT(src.IsExternalTwoByteString()); |
20863 NoSafepointScope no_safepoint; | 19682 NoSafepointScope no_safepoint; |
20864 String::Copy(dst, dst_offset, | 19683 String::Copy(dst, dst_offset, |
20865 ExternalTwoByteString::CharAddr(src, src_offset), len); | 19684 ExternalTwoByteString::CharAddr(src, src_offset), len); |
20866 } | 19685 } |
20867 } | 19686 } |
20868 } | 19687 } |
20869 } | 19688 } |
20870 | 19689 |
20871 | |
20872 RawString* String::EscapeSpecialCharacters(const String& str) { | 19690 RawString* String::EscapeSpecialCharacters(const String& str) { |
20873 if (str.IsOneByteString()) { | 19691 if (str.IsOneByteString()) { |
20874 return OneByteString::EscapeSpecialCharacters(str); | 19692 return OneByteString::EscapeSpecialCharacters(str); |
20875 } | 19693 } |
20876 if (str.IsTwoByteString()) { | 19694 if (str.IsTwoByteString()) { |
20877 return TwoByteString::EscapeSpecialCharacters(str); | 19695 return TwoByteString::EscapeSpecialCharacters(str); |
20878 } | 19696 } |
20879 if (str.IsExternalOneByteString()) { | 19697 if (str.IsExternalOneByteString()) { |
20880 return ExternalOneByteString::EscapeSpecialCharacters(str); | 19698 return ExternalOneByteString::EscapeSpecialCharacters(str); |
20881 } | 19699 } |
20882 ASSERT(str.IsExternalTwoByteString()); | 19700 ASSERT(str.IsExternalTwoByteString()); |
20883 // If EscapeSpecialCharacters is frequently called on external two byte | 19701 // If EscapeSpecialCharacters is frequently called on external two byte |
20884 // strings, we should implement it directly on ExternalTwoByteString rather | 19702 // strings, we should implement it directly on ExternalTwoByteString rather |
20885 // than first converting to a TwoByteString. | 19703 // than first converting to a TwoByteString. |
20886 return TwoByteString::EscapeSpecialCharacters( | 19704 return TwoByteString::EscapeSpecialCharacters( |
20887 String::Handle(TwoByteString::New(str, Heap::kNew))); | 19705 String::Handle(TwoByteString::New(str, Heap::kNew))); |
20888 } | 19706 } |
20889 | 19707 |
20890 | |
20891 static bool IsPercent(int32_t c) { | 19708 static bool IsPercent(int32_t c) { |
20892 return c == '%'; | 19709 return c == '%'; |
20893 } | 19710 } |
20894 | 19711 |
20895 | |
20896 static bool IsHexCharacter(int32_t c) { | 19712 static bool IsHexCharacter(int32_t c) { |
20897 if (c >= '0' && c <= '9') { | 19713 if (c >= '0' && c <= '9') { |
20898 return true; | 19714 return true; |
20899 } | 19715 } |
20900 if (c >= 'A' && c <= 'F') { | 19716 if (c >= 'A' && c <= 'F') { |
20901 return true; | 19717 return true; |
20902 } | 19718 } |
20903 return false; | 19719 return false; |
20904 } | 19720 } |
20905 | 19721 |
20906 | |
20907 static bool IsURISafeCharacter(int32_t c) { | 19722 static bool IsURISafeCharacter(int32_t c) { |
20908 if ((c >= '0') && (c <= '9')) { | 19723 if ((c >= '0') && (c <= '9')) { |
20909 return true; | 19724 return true; |
20910 } | 19725 } |
20911 if ((c >= 'a') && (c <= 'z')) { | 19726 if ((c >= 'a') && (c <= 'z')) { |
20912 return true; | 19727 return true; |
20913 } | 19728 } |
20914 if ((c >= 'A') && (c <= 'Z')) { | 19729 if ((c >= 'A') && (c <= 'Z')) { |
20915 return true; | 19730 return true; |
20916 } | 19731 } |
20917 return (c == '-') || (c == '_') || (c == '.') || (c == '~'); | 19732 return (c == '-') || (c == '_') || (c == '.') || (c == '~'); |
20918 } | 19733 } |
20919 | 19734 |
20920 | |
20921 static int32_t GetHexCharacter(int32_t c) { | 19735 static int32_t GetHexCharacter(int32_t c) { |
20922 ASSERT(c >= 0); | 19736 ASSERT(c >= 0); |
20923 ASSERT(c < 16); | 19737 ASSERT(c < 16); |
20924 const char* hex = "0123456789ABCDEF"; | 19738 const char* hex = "0123456789ABCDEF"; |
20925 return hex[c]; | 19739 return hex[c]; |
20926 } | 19740 } |
20927 | 19741 |
20928 | |
20929 static int32_t GetHexValue(int32_t c) { | 19742 static int32_t GetHexValue(int32_t c) { |
20930 if (c >= '0' && c <= '9') { | 19743 if (c >= '0' && c <= '9') { |
20931 return c - '0'; | 19744 return c - '0'; |
20932 } | 19745 } |
20933 if (c >= 'A' && c <= 'F') { | 19746 if (c >= 'A' && c <= 'F') { |
20934 return c - 'A' + 10; | 19747 return c - 'A' + 10; |
20935 } | 19748 } |
20936 UNREACHABLE(); | 19749 UNREACHABLE(); |
20937 return 0; | 19750 return 0; |
20938 } | 19751 } |
20939 | 19752 |
20940 | |
20941 static int32_t MergeHexCharacters(int32_t c1, int32_t c2) { | 19753 static int32_t MergeHexCharacters(int32_t c1, int32_t c2) { |
20942 return GetHexValue(c1) << 4 | GetHexValue(c2); | 19754 return GetHexValue(c1) << 4 | GetHexValue(c2); |
20943 } | 19755 } |
20944 | 19756 |
20945 | |
20946 const char* String::EncodeIRI(const String& str) { | 19757 const char* String::EncodeIRI(const String& str) { |
20947 const intptr_t len = Utf8::Length(str); | 19758 const intptr_t len = Utf8::Length(str); |
20948 Zone* zone = Thread::Current()->zone(); | 19759 Zone* zone = Thread::Current()->zone(); |
20949 uint8_t* utf8 = zone->Alloc<uint8_t>(len); | 19760 uint8_t* utf8 = zone->Alloc<uint8_t>(len); |
20950 str.ToUTF8(utf8, len); | 19761 str.ToUTF8(utf8, len); |
20951 intptr_t num_escapes = 0; | 19762 intptr_t num_escapes = 0; |
20952 for (int i = 0; i < len; ++i) { | 19763 for (int i = 0; i < len; ++i) { |
20953 uint8_t byte = utf8[i]; | 19764 uint8_t byte = utf8[i]; |
20954 if (!IsURISafeCharacter(byte)) { | 19765 if (!IsURISafeCharacter(byte)) { |
20955 num_escapes += 2; | 19766 num_escapes += 2; |
(...skipping 10 matching lines...) Expand all Loading... |
20966 cstr[index++] = GetHexCharacter(byte & 0xF); | 19777 cstr[index++] = GetHexCharacter(byte & 0xF); |
20967 } else { | 19778 } else { |
20968 ASSERT(byte <= 127); | 19779 ASSERT(byte <= 127); |
20969 cstr[index++] = byte; | 19780 cstr[index++] = byte; |
20970 } | 19781 } |
20971 } | 19782 } |
20972 cstr[index] = '\0'; | 19783 cstr[index] = '\0'; |
20973 return cstr; | 19784 return cstr; |
20974 } | 19785 } |
20975 | 19786 |
20976 | |
20977 RawString* String::DecodeIRI(const String& str) { | 19787 RawString* String::DecodeIRI(const String& str) { |
20978 CodePointIterator cpi(str); | 19788 CodePointIterator cpi(str); |
20979 intptr_t num_escapes = 0; | 19789 intptr_t num_escapes = 0; |
20980 intptr_t len = str.Length(); | 19790 intptr_t len = str.Length(); |
20981 { | 19791 { |
20982 CodePointIterator cpi(str); | 19792 CodePointIterator cpi(str); |
20983 while (cpi.Next()) { | 19793 while (cpi.Next()) { |
20984 int32_t code_point = cpi.Current(); | 19794 int32_t code_point = cpi.Current(); |
20985 if (IsPercent(code_point)) { | 19795 if (IsPercent(code_point)) { |
20986 // Verify that the two characters following the % are hex digits. | 19796 // Verify that the two characters following the % are hex digits. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21023 } else { | 19833 } else { |
21024 ASSERT(code_point >= 0 && code_point < 256); | 19834 ASSERT(code_point >= 0 && code_point < 256); |
21025 utf8[index] = static_cast<uint8_t>(code_point); | 19835 utf8[index] = static_cast<uint8_t>(code_point); |
21026 } | 19836 } |
21027 index++; | 19837 index++; |
21028 } | 19838 } |
21029 } | 19839 } |
21030 return FromUTF8(utf8, utf8_len); | 19840 return FromUTF8(utf8, utf8_len); |
21031 } | 19841 } |
21032 | 19842 |
21033 | |
21034 RawString* String::NewFormatted(const char* format, ...) { | 19843 RawString* String::NewFormatted(const char* format, ...) { |
21035 va_list args; | 19844 va_list args; |
21036 va_start(args, format); | 19845 va_start(args, format); |
21037 RawString* result = NewFormattedV(format, args); | 19846 RawString* result = NewFormattedV(format, args); |
21038 NoSafepointScope no_safepoint; | 19847 NoSafepointScope no_safepoint; |
21039 va_end(args); | 19848 va_end(args); |
21040 return result; | 19849 return result; |
21041 } | 19850 } |
21042 | 19851 |
21043 | |
21044 RawString* String::NewFormatted(Heap::Space space, const char* format, ...) { | 19852 RawString* String::NewFormatted(Heap::Space space, const char* format, ...) { |
21045 va_list args; | 19853 va_list args; |
21046 va_start(args, format); | 19854 va_start(args, format); |
21047 RawString* result = NewFormattedV(format, args, space); | 19855 RawString* result = NewFormattedV(format, args, space); |
21048 NoSafepointScope no_safepoint; | 19856 NoSafepointScope no_safepoint; |
21049 va_end(args); | 19857 va_end(args); |
21050 return result; | 19858 return result; |
21051 } | 19859 } |
21052 | 19860 |
21053 | |
21054 RawString* String::NewFormattedV(const char* format, | 19861 RawString* String::NewFormattedV(const char* format, |
21055 va_list args, | 19862 va_list args, |
21056 Heap::Space space) { | 19863 Heap::Space space) { |
21057 va_list args_copy; | 19864 va_list args_copy; |
21058 va_copy(args_copy, args); | 19865 va_copy(args_copy, args); |
21059 intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); | 19866 intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); |
21060 va_end(args_copy); | 19867 va_end(args_copy); |
21061 | 19868 |
21062 Zone* zone = Thread::Current()->zone(); | 19869 Zone* zone = Thread::Current()->zone(); |
21063 char* buffer = zone->Alloc<char>(len + 1); | 19870 char* buffer = zone->Alloc<char>(len + 1); |
21064 OS::VSNPrint(buffer, (len + 1), format, args); | 19871 OS::VSNPrint(buffer, (len + 1), format, args); |
21065 | 19872 |
21066 return String::New(buffer, space); | 19873 return String::New(buffer, space); |
21067 } | 19874 } |
21068 | 19875 |
21069 | |
21070 RawString* String::Concat(const String& str1, | 19876 RawString* String::Concat(const String& str1, |
21071 const String& str2, | 19877 const String& str2, |
21072 Heap::Space space) { | 19878 Heap::Space space) { |
21073 ASSERT(!str1.IsNull() && !str2.IsNull()); | 19879 ASSERT(!str1.IsNull() && !str2.IsNull()); |
21074 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); | 19880 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
21075 if (char_size == kTwoByteChar) { | 19881 if (char_size == kTwoByteChar) { |
21076 return TwoByteString::Concat(str1, str2, space); | 19882 return TwoByteString::Concat(str1, str2, space); |
21077 } | 19883 } |
21078 return OneByteString::Concat(str1, str2, space); | 19884 return OneByteString::Concat(str1, str2, space); |
21079 } | 19885 } |
21080 | 19886 |
21081 | |
21082 RawString* String::ConcatAll(const Array& strings, Heap::Space space) { | 19887 RawString* String::ConcatAll(const Array& strings, Heap::Space space) { |
21083 return ConcatAllRange(strings, 0, strings.Length(), space); | 19888 return ConcatAllRange(strings, 0, strings.Length(), space); |
21084 } | 19889 } |
21085 | 19890 |
21086 | |
21087 RawString* String::ConcatAllRange(const Array& strings, | 19891 RawString* String::ConcatAllRange(const Array& strings, |
21088 intptr_t start, | 19892 intptr_t start, |
21089 intptr_t end, | 19893 intptr_t end, |
21090 Heap::Space space) { | 19894 Heap::Space space) { |
21091 ASSERT(!strings.IsNull()); | 19895 ASSERT(!strings.IsNull()); |
21092 ASSERT(start >= 0); | 19896 ASSERT(start >= 0); |
21093 ASSERT(end <= strings.Length()); | 19897 ASSERT(end <= strings.Length()); |
21094 intptr_t result_len = 0; | 19898 intptr_t result_len = 0; |
21095 String& str = String::Handle(); | 19899 String& str = String::Handle(); |
21096 intptr_t char_size = kOneByteChar; | 19900 intptr_t char_size = kOneByteChar; |
21097 // Compute 'char_size' and 'result_len'. | 19901 // Compute 'char_size' and 'result_len'. |
21098 for (intptr_t i = start; i < end; i++) { | 19902 for (intptr_t i = start; i < end; i++) { |
21099 str ^= strings.At(i); | 19903 str ^= strings.At(i); |
21100 const intptr_t str_len = str.Length(); | 19904 const intptr_t str_len = str.Length(); |
21101 if ((kMaxElements - result_len) < str_len) { | 19905 if ((kMaxElements - result_len) < str_len) { |
21102 Exceptions::ThrowOOM(); | 19906 Exceptions::ThrowOOM(); |
21103 UNREACHABLE(); | 19907 UNREACHABLE(); |
21104 } | 19908 } |
21105 result_len += str_len; | 19909 result_len += str_len; |
21106 char_size = Utils::Maximum(char_size, str.CharSize()); | 19910 char_size = Utils::Maximum(char_size, str.CharSize()); |
21107 } | 19911 } |
21108 if (char_size == kOneByteChar) { | 19912 if (char_size == kOneByteChar) { |
21109 return OneByteString::ConcatAll(strings, start, end, result_len, space); | 19913 return OneByteString::ConcatAll(strings, start, end, result_len, space); |
21110 } | 19914 } |
21111 ASSERT(char_size == kTwoByteChar); | 19915 ASSERT(char_size == kTwoByteChar); |
21112 return TwoByteString::ConcatAll(strings, start, end, result_len, space); | 19916 return TwoByteString::ConcatAll(strings, start, end, result_len, space); |
21113 } | 19917 } |
21114 | 19918 |
21115 | |
21116 RawString* String::SubString(const String& str, | 19919 RawString* String::SubString(const String& str, |
21117 intptr_t begin_index, | 19920 intptr_t begin_index, |
21118 Heap::Space space) { | 19921 Heap::Space space) { |
21119 ASSERT(!str.IsNull()); | 19922 ASSERT(!str.IsNull()); |
21120 if (begin_index >= str.Length()) { | 19923 if (begin_index >= str.Length()) { |
21121 return String::null(); | 19924 return String::null(); |
21122 } | 19925 } |
21123 return String::SubString(str, begin_index, (str.Length() - begin_index), | 19926 return String::SubString(str, begin_index, (str.Length() - begin_index), |
21124 space); | 19927 space); |
21125 } | 19928 } |
21126 | 19929 |
21127 | |
21128 RawString* String::SubString(Thread* thread, | 19930 RawString* String::SubString(Thread* thread, |
21129 const String& str, | 19931 const String& str, |
21130 intptr_t begin_index, | 19932 intptr_t begin_index, |
21131 intptr_t length, | 19933 intptr_t length, |
21132 Heap::Space space) { | 19934 Heap::Space space) { |
21133 ASSERT(!str.IsNull()); | 19935 ASSERT(!str.IsNull()); |
21134 ASSERT(begin_index >= 0); | 19936 ASSERT(begin_index >= 0); |
21135 ASSERT(length >= 0); | 19937 ASSERT(length >= 0); |
21136 if (begin_index <= str.Length() && length == 0) { | 19938 if (begin_index <= str.Length() && length == 0) { |
21137 return Symbols::Empty().raw(); | 19939 return Symbols::Empty().raw(); |
(...skipping 15 matching lines...) Expand all Loading... |
21153 String& result = thread->StringHandle(); | 19955 String& result = thread->StringHandle(); |
21154 if (is_one_byte_string) { | 19956 if (is_one_byte_string) { |
21155 result = OneByteString::New(length, space); | 19957 result = OneByteString::New(length, space); |
21156 } else { | 19958 } else { |
21157 result = TwoByteString::New(length, space); | 19959 result = TwoByteString::New(length, space); |
21158 } | 19960 } |
21159 String::Copy(result, 0, str, begin_index, length); | 19961 String::Copy(result, 0, str, begin_index, length); |
21160 return result.raw(); | 19962 return result.raw(); |
21161 } | 19963 } |
21162 | 19964 |
21163 | |
21164 const char* String::ToCString() const { | 19965 const char* String::ToCString() const { |
21165 if (IsOneByteString()) { | 19966 if (IsOneByteString()) { |
21166 // Quick conversion if OneByteString contains only ASCII characters. | 19967 // Quick conversion if OneByteString contains only ASCII characters. |
21167 intptr_t len = Length(); | 19968 intptr_t len = Length(); |
21168 if (len == 0) { | 19969 if (len == 0) { |
21169 return ""; | 19970 return ""; |
21170 } | 19971 } |
21171 Zone* zone = Thread::Current()->zone(); | 19972 Zone* zone = Thread::Current()->zone(); |
21172 uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 19973 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
21173 NoSafepointScope no_safepoint; | 19974 NoSafepointScope no_safepoint; |
(...skipping 12 matching lines...) Expand all Loading... |
21186 } | 19987 } |
21187 } | 19988 } |
21188 const intptr_t len = Utf8::Length(*this); | 19989 const intptr_t len = Utf8::Length(*this); |
21189 Zone* zone = Thread::Current()->zone(); | 19990 Zone* zone = Thread::Current()->zone(); |
21190 uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 19991 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
21191 ToUTF8(result, len); | 19992 ToUTF8(result, len); |
21192 result[len] = 0; | 19993 result[len] = 0; |
21193 return reinterpret_cast<const char*>(result); | 19994 return reinterpret_cast<const char*>(result); |
21194 } | 19995 } |
21195 | 19996 |
21196 | |
21197 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { | 19997 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |
21198 ASSERT(array_len >= Utf8::Length(*this)); | 19998 ASSERT(array_len >= Utf8::Length(*this)); |
21199 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); | 19999 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
21200 } | 20000 } |
21201 | 20001 |
21202 | |
21203 static FinalizablePersistentHandle* AddFinalizer( | 20002 static FinalizablePersistentHandle* AddFinalizer( |
21204 const Object& referent, | 20003 const Object& referent, |
21205 void* peer, | 20004 void* peer, |
21206 Dart_WeakPersistentHandleFinalizer callback, | 20005 Dart_WeakPersistentHandleFinalizer callback, |
21207 intptr_t external_size) { | 20006 intptr_t external_size) { |
21208 ASSERT((callback != NULL && peer != NULL) || | 20007 ASSERT((callback != NULL && peer != NULL) || |
21209 (callback == NULL && peer == NULL)); | 20008 (callback == NULL && peer == NULL)); |
21210 return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, | 20009 return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, |
21211 callback, external_size); | 20010 callback, external_size); |
21212 } | 20011 } |
21213 | 20012 |
21214 | |
21215 RawString* String::MakeExternal(void* array, | 20013 RawString* String::MakeExternal(void* array, |
21216 intptr_t external_size, | 20014 intptr_t external_size, |
21217 void* peer, | 20015 void* peer, |
21218 Dart_PeerFinalizer cback) const { | 20016 Dart_PeerFinalizer cback) const { |
21219 ASSERT(FLAG_support_externalizable_strings); | 20017 ASSERT(FLAG_support_externalizable_strings); |
21220 String& result = String::Handle(); | 20018 String& result = String::Handle(); |
21221 void* external_data; | 20019 void* external_data; |
21222 Dart_WeakPersistentHandleFinalizer finalizer; | 20020 Dart_WeakPersistentHandleFinalizer finalizer; |
21223 { | 20021 { |
21224 NoSafepointScope no_safepoint; | 20022 NoSafepointScope no_safepoint; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21299 (result.Hash() == String::Hash(ext_array, str_length))); | 20097 (result.Hash() == String::Hash(ext_array, str_length))); |
21300 ExternalTwoByteString::SetExternalData(result, ext_data); | 20098 ExternalTwoByteString::SetExternalData(result, ext_data); |
21301 external_data = ext_data; | 20099 external_data = ext_data; |
21302 finalizer = ExternalTwoByteString::Finalize; | 20100 finalizer = ExternalTwoByteString::Finalize; |
21303 } | 20101 } |
21304 } // NoSafepointScope | 20102 } // NoSafepointScope |
21305 AddFinalizer(result, external_data, finalizer, external_size); | 20103 AddFinalizer(result, external_data, finalizer, external_size); |
21306 return this->raw(); | 20104 return this->raw(); |
21307 } | 20105 } |
21308 | 20106 |
21309 | |
21310 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 20107 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
21311 const String& str, | 20108 const String& str, |
21312 Heap::Space space) { | 20109 Heap::Space space) { |
21313 ASSERT(!str.IsNull()); | 20110 ASSERT(!str.IsNull()); |
21314 bool has_mapping = false; | 20111 bool has_mapping = false; |
21315 int32_t dst_max = 0; | 20112 int32_t dst_max = 0; |
21316 CodePointIterator it(str); | 20113 CodePointIterator it(str); |
21317 while (it.Next()) { | 20114 while (it.Next()) { |
21318 int32_t src = it.Current(); | 20115 int32_t src = it.Current(); |
21319 int32_t dst = mapping(src); | 20116 int32_t dst = mapping(src); |
21320 if (src != dst) { | 20117 if (src != dst) { |
21321 has_mapping = true; | 20118 has_mapping = true; |
21322 } | 20119 } |
21323 dst_max = Utils::Maximum(dst_max, dst); | 20120 dst_max = Utils::Maximum(dst_max, dst); |
21324 } | 20121 } |
21325 if (!has_mapping) { | 20122 if (!has_mapping) { |
21326 return str.raw(); | 20123 return str.raw(); |
21327 } | 20124 } |
21328 if (Utf::IsLatin1(dst_max)) { | 20125 if (Utf::IsLatin1(dst_max)) { |
21329 return OneByteString::Transform(mapping, str, space); | 20126 return OneByteString::Transform(mapping, str, space); |
21330 } | 20127 } |
21331 ASSERT(Utf::IsBmp(dst_max) || Utf::IsSupplementary(dst_max)); | 20128 ASSERT(Utf::IsBmp(dst_max) || Utf::IsSupplementary(dst_max)); |
21332 return TwoByteString::Transform(mapping, str, space); | 20129 return TwoByteString::Transform(mapping, str, space); |
21333 } | 20130 } |
21334 | 20131 |
21335 | |
21336 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 20132 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
21337 // TODO(cshapiro): create a fast-path for OneByteString instances. | 20133 // TODO(cshapiro): create a fast-path for OneByteString instances. |
21338 return Transform(CaseMapping::ToUpper, str, space); | 20134 return Transform(CaseMapping::ToUpper, str, space); |
21339 } | 20135 } |
21340 | 20136 |
21341 | |
21342 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 20137 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
21343 // TODO(cshapiro): create a fast-path for OneByteString instances. | 20138 // TODO(cshapiro): create a fast-path for OneByteString instances. |
21344 return Transform(CaseMapping::ToLower, str, space); | 20139 return Transform(CaseMapping::ToLower, str, space); |
21345 } | 20140 } |
21346 | 20141 |
21347 bool String::ParseDouble(const String& str, | 20142 bool String::ParseDouble(const String& str, |
21348 intptr_t start, | 20143 intptr_t start, |
21349 intptr_t end, | 20144 intptr_t end, |
21350 double* result) { | 20145 double* result) { |
21351 ASSERT(0 <= start); | 20146 ASSERT(0 <= start); |
(...skipping 16 matching lines...) Expand all Loading... |
21368 } else { | 20163 } else { |
21369 return false; // Not ASCII, so definitely not valid double numeral. | 20164 return false; // Not ASCII, so definitely not valid double numeral. |
21370 } | 20165 } |
21371 } | 20166 } |
21372 startChar = chars; | 20167 startChar = chars; |
21373 } | 20168 } |
21374 return CStringToDouble(reinterpret_cast<const char*>(startChar), length, | 20169 return CStringToDouble(reinterpret_cast<const char*>(startChar), length, |
21375 result); | 20170 result); |
21376 } | 20171 } |
21377 | 20172 |
21378 | |
21379 // Check to see if 'str1' matches 'str2' as is or | 20173 // Check to see if 'str1' matches 'str2' as is or |
21380 // once the private key separator is stripped from str2. | 20174 // once the private key separator is stripped from str2. |
21381 // | 20175 // |
21382 // Things are made more complicated by the fact that constructors are | 20176 // Things are made more complicated by the fact that constructors are |
21383 // added *after* the private suffix, so "foo@123.named" should match | 20177 // added *after* the private suffix, so "foo@123.named" should match |
21384 // "foo.named". | 20178 // "foo.named". |
21385 // | 20179 // |
21386 // Also, the private suffix can occur more than once in the name, as in: | 20180 // Also, the private suffix can occur more than once in the name, as in: |
21387 // | 20181 // |
21388 // _ReceivePortImpl@6be832b._internal@6be832b | 20182 // _ReceivePortImpl@6be832b._internal@6be832b |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21421 return false; | 20215 return false; |
21422 } | 20216 } |
21423 str2_pos++; | 20217 str2_pos++; |
21424 } | 20218 } |
21425 | 20219 |
21426 // We have reached the end of mangled_name string. | 20220 // We have reached the end of mangled_name string. |
21427 ASSERT(pos == len); | 20221 ASSERT(pos == len); |
21428 return (str2_pos == str2_len); | 20222 return (str2_pos == str2_len); |
21429 } | 20223 } |
21430 | 20224 |
21431 | |
21432 #define EQUALS_IGNORING_PRIVATE_KEY(class_id, type, str1, str2) \ | 20225 #define EQUALS_IGNORING_PRIVATE_KEY(class_id, type, str1, str2) \ |
21433 switch (class_id) { \ | 20226 switch (class_id) { \ |
21434 case kOneByteStringCid: \ | 20227 case kOneByteStringCid: \ |
21435 return dart::EqualsIgnoringPrivateKey<type, OneByteString>(str1, str2); \ | 20228 return dart::EqualsIgnoringPrivateKey<type, OneByteString>(str1, str2); \ |
21436 case kTwoByteStringCid: \ | 20229 case kTwoByteStringCid: \ |
21437 return dart::EqualsIgnoringPrivateKey<type, TwoByteString>(str1, str2); \ | 20230 return dart::EqualsIgnoringPrivateKey<type, TwoByteString>(str1, str2); \ |
21438 case kExternalOneByteStringCid: \ | 20231 case kExternalOneByteStringCid: \ |
21439 return dart::EqualsIgnoringPrivateKey<type, ExternalOneByteString>( \ | 20232 return dart::EqualsIgnoringPrivateKey<type, ExternalOneByteString>( \ |
21440 str1, str2); \ | 20233 str1, str2); \ |
21441 case kExternalTwoByteStringCid: \ | 20234 case kExternalTwoByteStringCid: \ |
21442 return dart::EqualsIgnoringPrivateKey<type, ExternalTwoByteString>( \ | 20235 return dart::EqualsIgnoringPrivateKey<type, ExternalTwoByteString>( \ |
21443 str1, str2); \ | 20236 str1, str2); \ |
21444 } \ | 20237 } \ |
21445 UNREACHABLE(); | 20238 UNREACHABLE(); |
21446 | 20239 |
21447 | |
21448 bool String::EqualsIgnoringPrivateKey(const String& str1, const String& str2) { | 20240 bool String::EqualsIgnoringPrivateKey(const String& str1, const String& str2) { |
21449 if (str1.raw() == str2.raw()) { | 20241 if (str1.raw() == str2.raw()) { |
21450 return true; // Both handles point to the same raw instance. | 20242 return true; // Both handles point to the same raw instance. |
21451 } | 20243 } |
21452 NoSafepointScope no_safepoint; | 20244 NoSafepointScope no_safepoint; |
21453 intptr_t str1_class_id = str1.raw()->GetClassId(); | 20245 intptr_t str1_class_id = str1.raw()->GetClassId(); |
21454 intptr_t str2_class_id = str2.raw()->GetClassId(); | 20246 intptr_t str2_class_id = str2.raw()->GetClassId(); |
21455 switch (str1_class_id) { | 20247 switch (str1_class_id) { |
21456 case kOneByteStringCid: | 20248 case kOneByteStringCid: |
21457 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2); | 20249 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2); |
21458 break; | 20250 break; |
21459 case kTwoByteStringCid: | 20251 case kTwoByteStringCid: |
21460 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, TwoByteString, str1, str2); | 20252 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, TwoByteString, str1, str2); |
21461 break; | 20253 break; |
21462 case kExternalOneByteStringCid: | 20254 case kExternalOneByteStringCid: |
21463 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalOneByteString, str1, | 20255 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalOneByteString, str1, |
21464 str2); | 20256 str2); |
21465 break; | 20257 break; |
21466 case kExternalTwoByteStringCid: | 20258 case kExternalTwoByteStringCid: |
21467 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalTwoByteString, str1, | 20259 EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalTwoByteString, str1, |
21468 str2); | 20260 str2); |
21469 break; | 20261 break; |
21470 } | 20262 } |
21471 UNREACHABLE(); | 20263 UNREACHABLE(); |
21472 return false; | 20264 return false; |
21473 } | 20265 } |
21474 | 20266 |
21475 | |
21476 bool String::CodePointIterator::Next() { | 20267 bool String::CodePointIterator::Next() { |
21477 ASSERT(index_ >= -1); | 20268 ASSERT(index_ >= -1); |
21478 intptr_t length = Utf16::Length(ch_); | 20269 intptr_t length = Utf16::Length(ch_); |
21479 if (index_ < (end_ - length)) { | 20270 if (index_ < (end_ - length)) { |
21480 index_ += length; | 20271 index_ += length; |
21481 ch_ = str_.CharAt(index_); | 20272 ch_ = str_.CharAt(index_); |
21482 if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) { | 20273 if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) { |
21483 int32_t ch2 = str_.CharAt(index_ + 1); | 20274 int32_t ch2 = str_.CharAt(index_ + 1); |
21484 if (Utf16::IsTrailSurrogate(ch2)) { | 20275 if (Utf16::IsTrailSurrogate(ch2)) { |
21485 ch_ = Utf16::Decode(ch_, ch2); | 20276 ch_ = Utf16::Decode(ch_, ch2); |
21486 } | 20277 } |
21487 } | 20278 } |
21488 return true; | 20279 return true; |
21489 } | 20280 } |
21490 index_ = end_; | 20281 index_ = end_; |
21491 return false; | 20282 return false; |
21492 } | 20283 } |
21493 | 20284 |
21494 | |
21495 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { | 20285 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { |
21496 intptr_t len = str.Length(); | 20286 intptr_t len = str.Length(); |
21497 if (len > 0) { | 20287 if (len > 0) { |
21498 intptr_t num_escapes = 0; | 20288 intptr_t num_escapes = 0; |
21499 for (intptr_t i = 0; i < len; i++) { | 20289 for (intptr_t i = 0; i < len; i++) { |
21500 num_escapes += EscapeOverhead(CharAt(str, i)); | 20290 num_escapes += EscapeOverhead(CharAt(str, i)); |
21501 } | 20291 } |
21502 const String& dststr = | 20292 const String& dststr = |
21503 String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); | 20293 String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); |
21504 intptr_t index = 0; | 20294 intptr_t index = 0; |
(...skipping 12 matching lines...) Expand all Loading... |
21517 } else { | 20307 } else { |
21518 SetCharAt(dststr, index, ch); | 20308 SetCharAt(dststr, index, ch); |
21519 index += 1; | 20309 index += 1; |
21520 } | 20310 } |
21521 } | 20311 } |
21522 return OneByteString::raw(dststr); | 20312 return OneByteString::raw(dststr); |
21523 } | 20313 } |
21524 return OneByteString::raw(Symbols::Empty()); | 20314 return OneByteString::raw(Symbols::Empty()); |
21525 } | 20315 } |
21526 | 20316 |
21527 | |
21528 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( | 20317 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( |
21529 const String& str) { | 20318 const String& str) { |
21530 intptr_t len = str.Length(); | 20319 intptr_t len = str.Length(); |
21531 if (len > 0) { | 20320 if (len > 0) { |
21532 intptr_t num_escapes = 0; | 20321 intptr_t num_escapes = 0; |
21533 for (intptr_t i = 0; i < len; i++) { | 20322 for (intptr_t i = 0; i < len; i++) { |
21534 num_escapes += EscapeOverhead(CharAt(str, i)); | 20323 num_escapes += EscapeOverhead(CharAt(str, i)); |
21535 } | 20324 } |
21536 const String& dststr = | 20325 const String& dststr = |
21537 String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); | 20326 String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); |
(...skipping 13 matching lines...) Expand all Loading... |
21551 } else { | 20340 } else { |
21552 OneByteString::SetCharAt(dststr, index, ch); | 20341 OneByteString::SetCharAt(dststr, index, ch); |
21553 index += 1; | 20342 index += 1; |
21554 } | 20343 } |
21555 } | 20344 } |
21556 return OneByteString::raw(dststr); | 20345 return OneByteString::raw(dststr); |
21557 } | 20346 } |
21558 return OneByteString::raw(Symbols::Empty()); | 20347 return OneByteString::raw(Symbols::Empty()); |
21559 } | 20348 } |
21560 | 20349 |
21561 | |
21562 RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) { | 20350 RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) { |
21563 ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 20351 ASSERT((Isolate::Current() == Dart::vm_isolate()) || |
21564 ((Isolate::Current()->object_store() != NULL) && | 20352 ((Isolate::Current()->object_store() != NULL) && |
21565 (Isolate::Current()->object_store()->one_byte_string_class() != | 20353 (Isolate::Current()->object_store()->one_byte_string_class() != |
21566 Class::null()))); | 20354 Class::null()))); |
21567 if (len < 0 || len > kMaxElements) { | 20355 if (len < 0 || len > kMaxElements) { |
21568 // This should be caught before we reach here. | 20356 // This should be caught before we reach here. |
21569 FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len); | 20357 FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len); |
21570 } | 20358 } |
21571 { | 20359 { |
21572 RawObject* raw = Object::Allocate(OneByteString::kClassId, | 20360 RawObject* raw = Object::Allocate(OneByteString::kClassId, |
21573 OneByteString::InstanceSize(len), space); | 20361 OneByteString::InstanceSize(len), space); |
21574 NoSafepointScope no_safepoint; | 20362 NoSafepointScope no_safepoint; |
21575 RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw); | 20363 RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw); |
21576 result->StoreSmi(&(result->ptr()->length_), Smi::New(len)); | 20364 result->StoreSmi(&(result->ptr()->length_), Smi::New(len)); |
21577 #if !defined(HASH_IN_OBJECT_HEADER) | 20365 #if !defined(HASH_IN_OBJECT_HEADER) |
21578 result->StoreSmi(&(result->ptr()->hash_), Smi::New(0)); | 20366 result->StoreSmi(&(result->ptr()->hash_), Smi::New(0)); |
21579 #endif | 20367 #endif |
21580 return result; | 20368 return result; |
21581 } | 20369 } |
21582 } | 20370 } |
21583 | 20371 |
21584 | |
21585 RawOneByteString* OneByteString::New(const uint8_t* characters, | 20372 RawOneByteString* OneByteString::New(const uint8_t* characters, |
21586 intptr_t len, | 20373 intptr_t len, |
21587 Heap::Space space) { | 20374 Heap::Space space) { |
21588 const String& result = String::Handle(OneByteString::New(len, space)); | 20375 const String& result = String::Handle(OneByteString::New(len, space)); |
21589 if (len > 0) { | 20376 if (len > 0) { |
21590 NoSafepointScope no_safepoint; | 20377 NoSafepointScope no_safepoint; |
21591 memmove(CharAddr(result, 0), characters, len); | 20378 memmove(CharAddr(result, 0), characters, len); |
21592 } | 20379 } |
21593 return OneByteString::raw(result); | 20380 return OneByteString::raw(result); |
21594 } | 20381 } |
21595 | 20382 |
21596 | |
21597 RawOneByteString* OneByteString::New(const uint16_t* characters, | 20383 RawOneByteString* OneByteString::New(const uint16_t* characters, |
21598 intptr_t len, | 20384 intptr_t len, |
21599 Heap::Space space) { | 20385 Heap::Space space) { |
21600 const String& result = String::Handle(OneByteString::New(len, space)); | 20386 const String& result = String::Handle(OneByteString::New(len, space)); |
21601 NoSafepointScope no_safepoint; | 20387 NoSafepointScope no_safepoint; |
21602 for (intptr_t i = 0; i < len; ++i) { | 20388 for (intptr_t i = 0; i < len; ++i) { |
21603 ASSERT(Utf::IsLatin1(characters[i])); | 20389 ASSERT(Utf::IsLatin1(characters[i])); |
21604 *CharAddr(result, i) = characters[i]; | 20390 *CharAddr(result, i) = characters[i]; |
21605 } | 20391 } |
21606 return OneByteString::raw(result); | 20392 return OneByteString::raw(result); |
21607 } | 20393 } |
21608 | 20394 |
21609 | |
21610 RawOneByteString* OneByteString::New(const int32_t* characters, | 20395 RawOneByteString* OneByteString::New(const int32_t* characters, |
21611 intptr_t len, | 20396 intptr_t len, |
21612 Heap::Space space) { | 20397 Heap::Space space) { |
21613 const String& result = String::Handle(OneByteString::New(len, space)); | 20398 const String& result = String::Handle(OneByteString::New(len, space)); |
21614 NoSafepointScope no_safepoint; | 20399 NoSafepointScope no_safepoint; |
21615 for (intptr_t i = 0; i < len; ++i) { | 20400 for (intptr_t i = 0; i < len; ++i) { |
21616 ASSERT(Utf::IsLatin1(characters[i])); | 20401 ASSERT(Utf::IsLatin1(characters[i])); |
21617 *CharAddr(result, i) = characters[i]; | 20402 *CharAddr(result, i) = characters[i]; |
21618 } | 20403 } |
21619 return OneByteString::raw(result); | 20404 return OneByteString::raw(result); |
21620 } | 20405 } |
21621 | 20406 |
21622 | |
21623 RawOneByteString* OneByteString::New(const String& str, Heap::Space space) { | 20407 RawOneByteString* OneByteString::New(const String& str, Heap::Space space) { |
21624 intptr_t len = str.Length(); | 20408 intptr_t len = str.Length(); |
21625 const String& result = String::Handle(OneByteString::New(len, space)); | 20409 const String& result = String::Handle(OneByteString::New(len, space)); |
21626 String::Copy(result, 0, str, 0, len); | 20410 String::Copy(result, 0, str, 0, len); |
21627 return OneByteString::raw(result); | 20411 return OneByteString::raw(result); |
21628 } | 20412 } |
21629 | 20413 |
21630 | |
21631 RawOneByteString* OneByteString::New(const String& other_one_byte_string, | 20414 RawOneByteString* OneByteString::New(const String& other_one_byte_string, |
21632 intptr_t other_start_index, | 20415 intptr_t other_start_index, |
21633 intptr_t other_len, | 20416 intptr_t other_len, |
21634 Heap::Space space) { | 20417 Heap::Space space) { |
21635 const String& result = String::Handle(OneByteString::New(other_len, space)); | 20418 const String& result = String::Handle(OneByteString::New(other_len, space)); |
21636 ASSERT(other_one_byte_string.IsOneByteString()); | 20419 ASSERT(other_one_byte_string.IsOneByteString()); |
21637 if (other_len > 0) { | 20420 if (other_len > 0) { |
21638 NoSafepointScope no_safepoint; | 20421 NoSafepointScope no_safepoint; |
21639 memmove(OneByteString::CharAddr(result, 0), | 20422 memmove(OneByteString::CharAddr(result, 0), |
21640 OneByteString::CharAddr(other_one_byte_string, other_start_index), | 20423 OneByteString::CharAddr(other_one_byte_string, other_start_index), |
21641 other_len); | 20424 other_len); |
21642 } | 20425 } |
21643 return OneByteString::raw(result); | 20426 return OneByteString::raw(result); |
21644 } | 20427 } |
21645 | 20428 |
21646 | |
21647 RawOneByteString* OneByteString::New(const TypedData& other_typed_data, | 20429 RawOneByteString* OneByteString::New(const TypedData& other_typed_data, |
21648 intptr_t other_start_index, | 20430 intptr_t other_start_index, |
21649 intptr_t other_len, | 20431 intptr_t other_len, |
21650 Heap::Space space) { | 20432 Heap::Space space) { |
21651 const String& result = String::Handle(OneByteString::New(other_len, space)); | 20433 const String& result = String::Handle(OneByteString::New(other_len, space)); |
21652 ASSERT(other_typed_data.ElementSizeInBytes() == 1); | 20434 ASSERT(other_typed_data.ElementSizeInBytes() == 1); |
21653 if (other_len > 0) { | 20435 if (other_len > 0) { |
21654 NoSafepointScope no_safepoint; | 20436 NoSafepointScope no_safepoint; |
21655 memmove(OneByteString::CharAddr(result, 0), | 20437 memmove(OneByteString::CharAddr(result, 0), |
21656 other_typed_data.DataAddr(other_start_index), other_len); | 20438 other_typed_data.DataAddr(other_start_index), other_len); |
21657 } | 20439 } |
21658 return OneByteString::raw(result); | 20440 return OneByteString::raw(result); |
21659 } | 20441 } |
21660 | 20442 |
21661 | |
21662 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data, | 20443 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data, |
21663 intptr_t other_start_index, | 20444 intptr_t other_start_index, |
21664 intptr_t other_len, | 20445 intptr_t other_len, |
21665 Heap::Space space) { | 20446 Heap::Space space) { |
21666 const String& result = String::Handle(OneByteString::New(other_len, space)); | 20447 const String& result = String::Handle(OneByteString::New(other_len, space)); |
21667 ASSERT(other_typed_data.ElementSizeInBytes() == 1); | 20448 ASSERT(other_typed_data.ElementSizeInBytes() == 1); |
21668 if (other_len > 0) { | 20449 if (other_len > 0) { |
21669 NoSafepointScope no_safepoint; | 20450 NoSafepointScope no_safepoint; |
21670 memmove(OneByteString::CharAddr(result, 0), | 20451 memmove(OneByteString::CharAddr(result, 0), |
21671 other_typed_data.DataAddr(other_start_index), other_len); | 20452 other_typed_data.DataAddr(other_start_index), other_len); |
21672 } | 20453 } |
21673 return OneByteString::raw(result); | 20454 return OneByteString::raw(result); |
21674 } | 20455 } |
21675 | 20456 |
21676 | |
21677 RawOneByteString* OneByteString::Concat(const String& str1, | 20457 RawOneByteString* OneByteString::Concat(const String& str1, |
21678 const String& str2, | 20458 const String& str2, |
21679 Heap::Space space) { | 20459 Heap::Space space) { |
21680 intptr_t len1 = str1.Length(); | 20460 intptr_t len1 = str1.Length(); |
21681 intptr_t len2 = str2.Length(); | 20461 intptr_t len2 = str2.Length(); |
21682 intptr_t len = len1 + len2; | 20462 intptr_t len = len1 + len2; |
21683 const String& result = String::Handle(OneByteString::New(len, space)); | 20463 const String& result = String::Handle(OneByteString::New(len, space)); |
21684 String::Copy(result, 0, str1, 0, len1); | 20464 String::Copy(result, 0, str1, 0, len1); |
21685 String::Copy(result, len1, str2, 0, len2); | 20465 String::Copy(result, len1, str2, 0, len2); |
21686 return OneByteString::raw(result); | 20466 return OneByteString::raw(result); |
21687 } | 20467 } |
21688 | 20468 |
21689 | |
21690 RawOneByteString* OneByteString::ConcatAll(const Array& strings, | 20469 RawOneByteString* OneByteString::ConcatAll(const Array& strings, |
21691 intptr_t start, | 20470 intptr_t start, |
21692 intptr_t end, | 20471 intptr_t end, |
21693 intptr_t len, | 20472 intptr_t len, |
21694 Heap::Space space) { | 20473 Heap::Space space) { |
21695 ASSERT(!strings.IsNull()); | 20474 ASSERT(!strings.IsNull()); |
21696 ASSERT(start >= 0); | 20475 ASSERT(start >= 0); |
21697 ASSERT(end <= strings.Length()); | 20476 ASSERT(end <= strings.Length()); |
21698 const String& result = String::Handle(OneByteString::New(len, space)); | 20477 const String& result = String::Handle(OneByteString::New(len, space)); |
21699 String& str = String::Handle(); | 20478 String& str = String::Handle(); |
21700 intptr_t pos = 0; | 20479 intptr_t pos = 0; |
21701 for (intptr_t i = start; i < end; i++) { | 20480 for (intptr_t i = start; i < end; i++) { |
21702 str ^= strings.At(i); | 20481 str ^= strings.At(i); |
21703 const intptr_t str_len = str.Length(); | 20482 const intptr_t str_len = str.Length(); |
21704 String::Copy(result, pos, str, 0, str_len); | 20483 String::Copy(result, pos, str, 0, str_len); |
21705 ASSERT((kMaxElements - pos) >= str_len); | 20484 ASSERT((kMaxElements - pos) >= str_len); |
21706 pos += str_len; | 20485 pos += str_len; |
21707 } | 20486 } |
21708 return OneByteString::raw(result); | 20487 return OneByteString::raw(result); |
21709 } | 20488 } |
21710 | 20489 |
21711 | |
21712 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 20490 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
21713 const String& str, | 20491 const String& str, |
21714 Heap::Space space) { | 20492 Heap::Space space) { |
21715 ASSERT(!str.IsNull()); | 20493 ASSERT(!str.IsNull()); |
21716 intptr_t len = str.Length(); | 20494 intptr_t len = str.Length(); |
21717 const String& result = String::Handle(OneByteString::New(len, space)); | 20495 const String& result = String::Handle(OneByteString::New(len, space)); |
21718 NoSafepointScope no_safepoint; | 20496 NoSafepointScope no_safepoint; |
21719 for (intptr_t i = 0; i < len; ++i) { | 20497 for (intptr_t i = 0; i < len; ++i) { |
21720 int32_t ch = mapping(str.CharAt(i)); | 20498 int32_t ch = mapping(str.CharAt(i)); |
21721 ASSERT(Utf::IsLatin1(ch)); | 20499 ASSERT(Utf::IsLatin1(ch)); |
21722 *CharAddr(result, i) = ch; | 20500 *CharAddr(result, i) = ch; |
21723 } | 20501 } |
21724 return OneByteString::raw(result); | 20502 return OneByteString::raw(result); |
21725 } | 20503 } |
21726 | 20504 |
21727 | |
21728 RawOneByteString* OneByteString::SubStringUnchecked(const String& str, | 20505 RawOneByteString* OneByteString::SubStringUnchecked(const String& str, |
21729 intptr_t begin_index, | 20506 intptr_t begin_index, |
21730 intptr_t length, | 20507 intptr_t length, |
21731 Heap::Space space) { | 20508 Heap::Space space) { |
21732 ASSERT(!str.IsNull() && str.IsOneByteString()); | 20509 ASSERT(!str.IsNull() && str.IsOneByteString()); |
21733 ASSERT(begin_index >= 0); | 20510 ASSERT(begin_index >= 0); |
21734 ASSERT(length >= 0); | 20511 ASSERT(length >= 0); |
21735 if (begin_index <= str.Length() && length == 0) { | 20512 if (begin_index <= str.Length() && length == 0) { |
21736 return OneByteString::raw(Symbols::Empty()); | 20513 return OneByteString::raw(Symbols::Empty()); |
21737 } | 20514 } |
21738 ASSERT(begin_index < str.Length()); | 20515 ASSERT(begin_index < str.Length()); |
21739 RawOneByteString* result = OneByteString::New(length, space); | 20516 RawOneByteString* result = OneByteString::New(length, space); |
21740 NoSafepointScope no_safepoint; | 20517 NoSafepointScope no_safepoint; |
21741 if (length > 0) { | 20518 if (length > 0) { |
21742 uint8_t* dest = &result->ptr()->data()[0]; | 20519 uint8_t* dest = &result->ptr()->data()[0]; |
21743 const uint8_t* src = &raw_ptr(str)->data()[begin_index]; | 20520 const uint8_t* src = &raw_ptr(str)->data()[begin_index]; |
21744 memmove(dest, src, length); | 20521 memmove(dest, src, length); |
21745 } | 20522 } |
21746 return result; | 20523 return result; |
21747 } | 20524 } |
21748 | 20525 |
21749 | |
21750 void OneByteString::SetPeer(const String& str, | 20526 void OneByteString::SetPeer(const String& str, |
21751 intptr_t external_size, | 20527 intptr_t external_size, |
21752 void* peer, | 20528 void* peer, |
21753 Dart_PeerFinalizer cback) { | 20529 Dart_PeerFinalizer cback) { |
21754 ASSERT(!str.IsNull() && str.IsOneByteString()); | 20530 ASSERT(!str.IsNull() && str.IsOneByteString()); |
21755 ASSERT(peer != NULL); | 20531 ASSERT(peer != NULL); |
21756 ExternalStringData<uint8_t>* ext_data = | 20532 ExternalStringData<uint8_t>* ext_data = |
21757 new ExternalStringData<uint8_t>(NULL, peer, cback); | 20533 new ExternalStringData<uint8_t>(NULL, peer, cback); |
21758 AddFinalizer(str, ext_data, OneByteString::Finalize, external_size); | 20534 AddFinalizer(str, ext_data, OneByteString::Finalize, external_size); |
21759 Isolate::Current()->heap()->SetPeer(str.raw(), peer); | 20535 Isolate::Current()->heap()->SetPeer(str.raw(), peer); |
21760 } | 20536 } |
21761 | 20537 |
21762 | |
21763 void OneByteString::Finalize(void* isolate_callback_data, | 20538 void OneByteString::Finalize(void* isolate_callback_data, |
21764 Dart_WeakPersistentHandle handle, | 20539 Dart_WeakPersistentHandle handle, |
21765 void* peer) { | 20540 void* peer) { |
21766 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); | 20541 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); |
21767 } | 20542 } |
21768 | 20543 |
21769 | |
21770 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { | 20544 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { |
21771 intptr_t len = str.Length(); | 20545 intptr_t len = str.Length(); |
21772 if (len > 0) { | 20546 if (len > 0) { |
21773 intptr_t num_escapes = 0; | 20547 intptr_t num_escapes = 0; |
21774 for (intptr_t i = 0; i < len; i++) { | 20548 for (intptr_t i = 0; i < len; i++) { |
21775 num_escapes += EscapeOverhead(CharAt(str, i)); | 20549 num_escapes += EscapeOverhead(CharAt(str, i)); |
21776 } | 20550 } |
21777 const String& dststr = | 20551 const String& dststr = |
21778 String::Handle(TwoByteString::New(len + num_escapes, Heap::kNew)); | 20552 String::Handle(TwoByteString::New(len + num_escapes, Heap::kNew)); |
21779 intptr_t index = 0; | 20553 intptr_t index = 0; |
(...skipping 12 matching lines...) Expand all Loading... |
21792 } else { | 20566 } else { |
21793 SetCharAt(dststr, index, ch); | 20567 SetCharAt(dststr, index, ch); |
21794 index += 1; | 20568 index += 1; |
21795 } | 20569 } |
21796 } | 20570 } |
21797 return TwoByteString::raw(dststr); | 20571 return TwoByteString::raw(dststr); |
21798 } | 20572 } |
21799 return TwoByteString::New(0, Heap::kNew); | 20573 return TwoByteString::New(0, Heap::kNew); |
21800 } | 20574 } |
21801 | 20575 |
21802 | |
21803 RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) { | 20576 RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) { |
21804 ASSERT(Isolate::Current()->object_store()->two_byte_string_class()); | 20577 ASSERT(Isolate::Current()->object_store()->two_byte_string_class()); |
21805 if (len < 0 || len > kMaxElements) { | 20578 if (len < 0 || len > kMaxElements) { |
21806 // This should be caught before we reach here. | 20579 // This should be caught before we reach here. |
21807 FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len); | 20580 FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len); |
21808 } | 20581 } |
21809 String& result = String::Handle(); | 20582 String& result = String::Handle(); |
21810 { | 20583 { |
21811 RawObject* raw = Object::Allocate(TwoByteString::kClassId, | 20584 RawObject* raw = Object::Allocate(TwoByteString::kClassId, |
21812 TwoByteString::InstanceSize(len), space); | 20585 TwoByteString::InstanceSize(len), space); |
21813 NoSafepointScope no_safepoint; | 20586 NoSafepointScope no_safepoint; |
21814 result ^= raw; | 20587 result ^= raw; |
21815 result.SetLength(len); | 20588 result.SetLength(len); |
21816 result.SetHash(0); | 20589 result.SetHash(0); |
21817 } | 20590 } |
21818 return TwoByteString::raw(result); | 20591 return TwoByteString::raw(result); |
21819 } | 20592 } |
21820 | 20593 |
21821 | |
21822 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, | 20594 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, |
21823 intptr_t array_len, | 20595 intptr_t array_len, |
21824 Heap::Space space) { | 20596 Heap::Space space) { |
21825 ASSERT(array_len > 0); | 20597 ASSERT(array_len > 0); |
21826 const String& result = String::Handle(TwoByteString::New(array_len, space)); | 20598 const String& result = String::Handle(TwoByteString::New(array_len, space)); |
21827 { | 20599 { |
21828 NoSafepointScope no_safepoint; | 20600 NoSafepointScope no_safepoint; |
21829 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); | 20601 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); |
21830 } | 20602 } |
21831 return TwoByteString::raw(result); | 20603 return TwoByteString::raw(result); |
21832 } | 20604 } |
21833 | 20605 |
21834 | |
21835 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, | 20606 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |
21836 const int32_t* utf32_array, | 20607 const int32_t* utf32_array, |
21837 intptr_t array_len, | 20608 intptr_t array_len, |
21838 Heap::Space space) { | 20609 Heap::Space space) { |
21839 ASSERT((array_len > 0) && (utf16_len >= array_len)); | 20610 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
21840 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); | 20611 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); |
21841 { | 20612 { |
21842 NoSafepointScope no_safepoint; | 20613 NoSafepointScope no_safepoint; |
21843 intptr_t j = 0; | 20614 intptr_t j = 0; |
21844 for (intptr_t i = 0; i < array_len; ++i) { | 20615 for (intptr_t i = 0; i < array_len; ++i) { |
21845 if (Utf::IsSupplementary(utf32_array[i])) { | 20616 if (Utf::IsSupplementary(utf32_array[i])) { |
21846 ASSERT(j < (utf16_len - 1)); | 20617 ASSERT(j < (utf16_len - 1)); |
21847 Utf16::Encode(utf32_array[i], CharAddr(result, j)); | 20618 Utf16::Encode(utf32_array[i], CharAddr(result, j)); |
21848 j += 2; | 20619 j += 2; |
21849 } else { | 20620 } else { |
21850 ASSERT(j < utf16_len); | 20621 ASSERT(j < utf16_len); |
21851 *CharAddr(result, j) = utf32_array[i]; | 20622 *CharAddr(result, j) = utf32_array[i]; |
21852 j += 1; | 20623 j += 1; |
21853 } | 20624 } |
21854 } | 20625 } |
21855 } | 20626 } |
21856 return TwoByteString::raw(result); | 20627 return TwoByteString::raw(result); |
21857 } | 20628 } |
21858 | 20629 |
21859 | |
21860 RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) { | 20630 RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) { |
21861 intptr_t len = str.Length(); | 20631 intptr_t len = str.Length(); |
21862 const String& result = String::Handle(TwoByteString::New(len, space)); | 20632 const String& result = String::Handle(TwoByteString::New(len, space)); |
21863 String::Copy(result, 0, str, 0, len); | 20633 String::Copy(result, 0, str, 0, len); |
21864 return TwoByteString::raw(result); | 20634 return TwoByteString::raw(result); |
21865 } | 20635 } |
21866 | 20636 |
21867 | |
21868 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data, | 20637 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data, |
21869 intptr_t other_start_index, | 20638 intptr_t other_start_index, |
21870 intptr_t other_len, | 20639 intptr_t other_len, |
21871 Heap::Space space) { | 20640 Heap::Space space) { |
21872 const String& result = String::Handle(TwoByteString::New(other_len, space)); | 20641 const String& result = String::Handle(TwoByteString::New(other_len, space)); |
21873 if (other_len > 0) { | 20642 if (other_len > 0) { |
21874 NoSafepointScope no_safepoint; | 20643 NoSafepointScope no_safepoint; |
21875 memmove(TwoByteString::CharAddr(result, 0), | 20644 memmove(TwoByteString::CharAddr(result, 0), |
21876 other_typed_data.DataAddr(other_start_index), | 20645 other_typed_data.DataAddr(other_start_index), |
21877 other_len * sizeof(uint16_t)); | 20646 other_len * sizeof(uint16_t)); |
21878 } | 20647 } |
21879 return TwoByteString::raw(result); | 20648 return TwoByteString::raw(result); |
21880 } | 20649 } |
21881 | 20650 |
21882 | |
21883 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data, | 20651 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data, |
21884 intptr_t other_start_index, | 20652 intptr_t other_start_index, |
21885 intptr_t other_len, | 20653 intptr_t other_len, |
21886 Heap::Space space) { | 20654 Heap::Space space) { |
21887 const String& result = String::Handle(TwoByteString::New(other_len, space)); | 20655 const String& result = String::Handle(TwoByteString::New(other_len, space)); |
21888 if (other_len > 0) { | 20656 if (other_len > 0) { |
21889 NoSafepointScope no_safepoint; | 20657 NoSafepointScope no_safepoint; |
21890 memmove(TwoByteString::CharAddr(result, 0), | 20658 memmove(TwoByteString::CharAddr(result, 0), |
21891 other_typed_data.DataAddr(other_start_index), | 20659 other_typed_data.DataAddr(other_start_index), |
21892 other_len * sizeof(uint16_t)); | 20660 other_len * sizeof(uint16_t)); |
21893 } | 20661 } |
21894 return TwoByteString::raw(result); | 20662 return TwoByteString::raw(result); |
21895 } | 20663 } |
21896 | 20664 |
21897 | |
21898 RawTwoByteString* TwoByteString::Concat(const String& str1, | 20665 RawTwoByteString* TwoByteString::Concat(const String& str1, |
21899 const String& str2, | 20666 const String& str2, |
21900 Heap::Space space) { | 20667 Heap::Space space) { |
21901 intptr_t len1 = str1.Length(); | 20668 intptr_t len1 = str1.Length(); |
21902 intptr_t len2 = str2.Length(); | 20669 intptr_t len2 = str2.Length(); |
21903 intptr_t len = len1 + len2; | 20670 intptr_t len = len1 + len2; |
21904 const String& result = String::Handle(TwoByteString::New(len, space)); | 20671 const String& result = String::Handle(TwoByteString::New(len, space)); |
21905 String::Copy(result, 0, str1, 0, len1); | 20672 String::Copy(result, 0, str1, 0, len1); |
21906 String::Copy(result, len1, str2, 0, len2); | 20673 String::Copy(result, len1, str2, 0, len2); |
21907 return TwoByteString::raw(result); | 20674 return TwoByteString::raw(result); |
21908 } | 20675 } |
21909 | 20676 |
21910 | |
21911 RawTwoByteString* TwoByteString::ConcatAll(const Array& strings, | 20677 RawTwoByteString* TwoByteString::ConcatAll(const Array& strings, |
21912 intptr_t start, | 20678 intptr_t start, |
21913 intptr_t end, | 20679 intptr_t end, |
21914 intptr_t len, | 20680 intptr_t len, |
21915 Heap::Space space) { | 20681 Heap::Space space) { |
21916 ASSERT(!strings.IsNull()); | 20682 ASSERT(!strings.IsNull()); |
21917 ASSERT(start >= 0); | 20683 ASSERT(start >= 0); |
21918 ASSERT(end <= strings.Length()); | 20684 ASSERT(end <= strings.Length()); |
21919 const String& result = String::Handle(TwoByteString::New(len, space)); | 20685 const String& result = String::Handle(TwoByteString::New(len, space)); |
21920 String& str = String::Handle(); | 20686 String& str = String::Handle(); |
21921 intptr_t pos = 0; | 20687 intptr_t pos = 0; |
21922 for (intptr_t i = start; i < end; i++) { | 20688 for (intptr_t i = start; i < end; i++) { |
21923 str ^= strings.At(i); | 20689 str ^= strings.At(i); |
21924 const intptr_t str_len = str.Length(); | 20690 const intptr_t str_len = str.Length(); |
21925 String::Copy(result, pos, str, 0, str_len); | 20691 String::Copy(result, pos, str, 0, str_len); |
21926 ASSERT((kMaxElements - pos) >= str_len); | 20692 ASSERT((kMaxElements - pos) >= str_len); |
21927 pos += str_len; | 20693 pos += str_len; |
21928 } | 20694 } |
21929 return TwoByteString::raw(result); | 20695 return TwoByteString::raw(result); |
21930 } | 20696 } |
21931 | 20697 |
21932 | |
21933 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 20698 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
21934 const String& str, | 20699 const String& str, |
21935 Heap::Space space) { | 20700 Heap::Space space) { |
21936 ASSERT(!str.IsNull()); | 20701 ASSERT(!str.IsNull()); |
21937 intptr_t len = str.Length(); | 20702 intptr_t len = str.Length(); |
21938 const String& result = String::Handle(TwoByteString::New(len, space)); | 20703 const String& result = String::Handle(TwoByteString::New(len, space)); |
21939 String::CodePointIterator it(str); | 20704 String::CodePointIterator it(str); |
21940 intptr_t i = 0; | 20705 intptr_t i = 0; |
21941 NoSafepointScope no_safepoint; | 20706 NoSafepointScope no_safepoint; |
21942 while (it.Next()) { | 20707 while (it.Next()) { |
21943 int32_t src = it.Current(); | 20708 int32_t src = it.Current(); |
21944 int32_t dst = mapping(src); | 20709 int32_t dst = mapping(src); |
21945 ASSERT(dst >= 0 && dst <= 0x10FFFF); | 20710 ASSERT(dst >= 0 && dst <= 0x10FFFF); |
21946 intptr_t len = Utf16::Length(dst); | 20711 intptr_t len = Utf16::Length(dst); |
21947 if (len == 1) { | 20712 if (len == 1) { |
21948 *CharAddr(result, i) = dst; | 20713 *CharAddr(result, i) = dst; |
21949 } else { | 20714 } else { |
21950 ASSERT(len == 2); | 20715 ASSERT(len == 2); |
21951 Utf16::Encode(dst, CharAddr(result, i)); | 20716 Utf16::Encode(dst, CharAddr(result, i)); |
21952 } | 20717 } |
21953 i += len; | 20718 i += len; |
21954 } | 20719 } |
21955 return TwoByteString::raw(result); | 20720 return TwoByteString::raw(result); |
21956 } | 20721 } |
21957 | 20722 |
21958 | |
21959 void TwoByteString::SetPeer(const String& str, | 20723 void TwoByteString::SetPeer(const String& str, |
21960 intptr_t external_size, | 20724 intptr_t external_size, |
21961 void* peer, | 20725 void* peer, |
21962 Dart_PeerFinalizer cback) { | 20726 Dart_PeerFinalizer cback) { |
21963 ASSERT(!str.IsNull() && str.IsTwoByteString()); | 20727 ASSERT(!str.IsNull() && str.IsTwoByteString()); |
21964 ASSERT(peer != NULL); | 20728 ASSERT(peer != NULL); |
21965 ExternalStringData<uint16_t>* ext_data = | 20729 ExternalStringData<uint16_t>* ext_data = |
21966 new ExternalStringData<uint16_t>(NULL, peer, cback); | 20730 new ExternalStringData<uint16_t>(NULL, peer, cback); |
21967 AddFinalizer(str, ext_data, TwoByteString::Finalize, external_size); | 20731 AddFinalizer(str, ext_data, TwoByteString::Finalize, external_size); |
21968 Isolate::Current()->heap()->SetPeer(str.raw(), peer); | 20732 Isolate::Current()->heap()->SetPeer(str.raw(), peer); |
21969 } | 20733 } |
21970 | 20734 |
21971 | |
21972 void TwoByteString::Finalize(void* isolate_callback_data, | 20735 void TwoByteString::Finalize(void* isolate_callback_data, |
21973 Dart_WeakPersistentHandle handle, | 20736 Dart_WeakPersistentHandle handle, |
21974 void* peer) { | 20737 void* peer) { |
21975 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 20738 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |
21976 } | 20739 } |
21977 | 20740 |
21978 | |
21979 RawExternalOneByteString* ExternalOneByteString::New( | 20741 RawExternalOneByteString* ExternalOneByteString::New( |
21980 const uint8_t* data, | 20742 const uint8_t* data, |
21981 intptr_t len, | 20743 intptr_t len, |
21982 void* peer, | 20744 void* peer, |
21983 Dart_PeerFinalizer callback, | 20745 Dart_PeerFinalizer callback, |
21984 Heap::Space space) { | 20746 Heap::Space space) { |
21985 ASSERT(Isolate::Current()->object_store()->external_one_byte_string_class() != | 20747 ASSERT(Isolate::Current()->object_store()->external_one_byte_string_class() != |
21986 Class::null()); | 20748 Class::null()); |
21987 if (len < 0 || len > kMaxElements) { | 20749 if (len < 0 || len > kMaxElements) { |
21988 // This should be caught before we reach here. | 20750 // This should be caught before we reach here. |
(...skipping 12 matching lines...) Expand all Loading... |
22001 result.SetLength(len); | 20763 result.SetLength(len); |
22002 result.SetHash(0); | 20764 result.SetHash(0); |
22003 SetExternalData(result, external_data); | 20765 SetExternalData(result, external_data); |
22004 } | 20766 } |
22005 intptr_t external_size = len; | 20767 intptr_t external_size = len; |
22006 AddFinalizer(result, external_data, ExternalOneByteString::Finalize, | 20768 AddFinalizer(result, external_data, ExternalOneByteString::Finalize, |
22007 external_size); | 20769 external_size); |
22008 return ExternalOneByteString::raw(result); | 20770 return ExternalOneByteString::raw(result); |
22009 } | 20771 } |
22010 | 20772 |
22011 | |
22012 void ExternalOneByteString::Finalize(void* isolate_callback_data, | 20773 void ExternalOneByteString::Finalize(void* isolate_callback_data, |
22013 Dart_WeakPersistentHandle handle, | 20774 Dart_WeakPersistentHandle handle, |
22014 void* peer) { | 20775 void* peer) { |
22015 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); | 20776 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); |
22016 } | 20777 } |
22017 | 20778 |
22018 | |
22019 RawExternalTwoByteString* ExternalTwoByteString::New( | 20779 RawExternalTwoByteString* ExternalTwoByteString::New( |
22020 const uint16_t* data, | 20780 const uint16_t* data, |
22021 intptr_t len, | 20781 intptr_t len, |
22022 void* peer, | 20782 void* peer, |
22023 Dart_PeerFinalizer callback, | 20783 Dart_PeerFinalizer callback, |
22024 Heap::Space space) { | 20784 Heap::Space space) { |
22025 ASSERT(Isolate::Current()->object_store()->external_two_byte_string_class() != | 20785 ASSERT(Isolate::Current()->object_store()->external_two_byte_string_class() != |
22026 Class::null()); | 20786 Class::null()); |
22027 if (len < 0 || len > kMaxElements) { | 20787 if (len < 0 || len > kMaxElements) { |
22028 // This should be caught before we reach here. | 20788 // This should be caught before we reach here. |
(...skipping 12 matching lines...) Expand all Loading... |
22041 result.SetLength(len); | 20801 result.SetLength(len); |
22042 result.SetHash(0); | 20802 result.SetHash(0); |
22043 SetExternalData(result, external_data); | 20803 SetExternalData(result, external_data); |
22044 } | 20804 } |
22045 intptr_t external_size = len * 2; | 20805 intptr_t external_size = len * 2; |
22046 AddFinalizer(result, external_data, ExternalTwoByteString::Finalize, | 20806 AddFinalizer(result, external_data, ExternalTwoByteString::Finalize, |
22047 external_size); | 20807 external_size); |
22048 return ExternalTwoByteString::raw(result); | 20808 return ExternalTwoByteString::raw(result); |
22049 } | 20809 } |
22050 | 20810 |
22051 | |
22052 void ExternalTwoByteString::Finalize(void* isolate_callback_data, | 20811 void ExternalTwoByteString::Finalize(void* isolate_callback_data, |
22053 Dart_WeakPersistentHandle handle, | 20812 Dart_WeakPersistentHandle handle, |
22054 void* peer) { | 20813 void* peer) { |
22055 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 20814 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |
22056 } | 20815 } |
22057 | 20816 |
22058 | |
22059 RawBool* Bool::New(bool value) { | 20817 RawBool* Bool::New(bool value) { |
22060 ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null()); | 20818 ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null()); |
22061 Bool& result = Bool::Handle(); | 20819 Bool& result = Bool::Handle(); |
22062 { | 20820 { |
22063 // Since the two boolean instances are singletons we allocate them straight | 20821 // Since the two boolean instances are singletons we allocate them straight |
22064 // in the old generation. | 20822 // in the old generation. |
22065 RawObject* raw = | 20823 RawObject* raw = |
22066 Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld); | 20824 Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld); |
22067 NoSafepointScope no_safepoint; | 20825 NoSafepointScope no_safepoint; |
22068 result ^= raw; | 20826 result ^= raw; |
22069 } | 20827 } |
22070 result.set_value(value); | 20828 result.set_value(value); |
22071 result.SetCanonical(); | 20829 result.SetCanonical(); |
22072 return result.raw(); | 20830 return result.raw(); |
22073 } | 20831 } |
22074 | 20832 |
22075 | |
22076 const char* Bool::ToCString() const { | 20833 const char* Bool::ToCString() const { |
22077 return value() ? "true" : "false"; | 20834 return value() ? "true" : "false"; |
22078 } | 20835 } |
22079 | 20836 |
22080 | |
22081 bool Array::CanonicalizeEquals(const Instance& other) const { | 20837 bool Array::CanonicalizeEquals(const Instance& other) const { |
22082 if (this->raw() == other.raw()) { | 20838 if (this->raw() == other.raw()) { |
22083 // Both handles point to the same raw instance. | 20839 // Both handles point to the same raw instance. |
22084 return true; | 20840 return true; |
22085 } | 20841 } |
22086 | 20842 |
22087 // An Array may be compared to an ImmutableArray. | 20843 // An Array may be compared to an ImmutableArray. |
22088 if (!other.IsArray() || other.IsNull()) { | 20844 if (!other.IsArray() || other.IsNull()) { |
22089 return false; | 20845 return false; |
22090 } | 20846 } |
(...skipping 18 matching lines...) Expand all Loading... |
22109 } | 20865 } |
22110 const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); | 20866 const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); |
22111 const TypeArguments& other_type_args = | 20867 const TypeArguments& other_type_args = |
22112 TypeArguments::Handle(other.GetTypeArguments()); | 20868 TypeArguments::Handle(other.GetTypeArguments()); |
22113 if (!type_args.Equals(other_type_args)) { | 20869 if (!type_args.Equals(other_type_args)) { |
22114 return false; | 20870 return false; |
22115 } | 20871 } |
22116 return true; | 20872 return true; |
22117 } | 20873 } |
22118 | 20874 |
22119 | |
22120 uword Array::ComputeCanonicalTableHash() const { | 20875 uword Array::ComputeCanonicalTableHash() const { |
22121 ASSERT(!IsNull()); | 20876 ASSERT(!IsNull()); |
22122 NoSafepointScope no_safepoint; | 20877 NoSafepointScope no_safepoint; |
22123 intptr_t len = Length(); | 20878 intptr_t len = Length(); |
22124 uword hash = len; | 20879 uword hash = len; |
22125 uword value = reinterpret_cast<uword>(GetTypeArguments()); | 20880 uword value = reinterpret_cast<uword>(GetTypeArguments()); |
22126 hash = CombineHashes(hash, value); | 20881 hash = CombineHashes(hash, value); |
22127 for (intptr_t i = 0; i < len; i++) { | 20882 for (intptr_t i = 0; i < len; i++) { |
22128 value = reinterpret_cast<uword>(At(i)); | 20883 value = reinterpret_cast<uword>(At(i)); |
22129 hash = CombineHashes(hash, value); | 20884 hash = CombineHashes(hash, value); |
22130 } | 20885 } |
22131 return FinalizeHash(hash, kHashBits); | 20886 return FinalizeHash(hash, kHashBits); |
22132 } | 20887 } |
22133 | 20888 |
22134 | |
22135 RawArray* Array::New(intptr_t len, Heap::Space space) { | 20889 RawArray* Array::New(intptr_t len, Heap::Space space) { |
22136 ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); | 20890 ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); |
22137 return New(kClassId, len, space); | 20891 return New(kClassId, len, space); |
22138 } | 20892 } |
22139 | 20893 |
22140 | |
22141 RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) { | 20894 RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) { |
22142 if ((len < 0) || (len > Array::kMaxElements)) { | 20895 if ((len < 0) || (len > Array::kMaxElements)) { |
22143 // This should be caught before we reach here. | 20896 // This should be caught before we reach here. |
22144 FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); | 20897 FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); |
22145 } | 20898 } |
22146 { | 20899 { |
22147 RawArray* raw = reinterpret_cast<RawArray*>( | 20900 RawArray* raw = reinterpret_cast<RawArray*>( |
22148 Object::Allocate(class_id, Array::InstanceSize(len), space)); | 20901 Object::Allocate(class_id, Array::InstanceSize(len), space)); |
22149 NoSafepointScope no_safepoint; | 20902 NoSafepointScope no_safepoint; |
22150 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); | 20903 raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); |
22151 return raw; | 20904 return raw; |
22152 } | 20905 } |
22153 } | 20906 } |
22154 | 20907 |
22155 | |
22156 RawArray* Array::Slice(intptr_t start, | 20908 RawArray* Array::Slice(intptr_t start, |
22157 intptr_t count, | 20909 intptr_t count, |
22158 bool with_type_argument) const { | 20910 bool with_type_argument) const { |
22159 // TODO(vegorov) introduce an array allocation method that fills newly | 20911 // TODO(vegorov) introduce an array allocation method that fills newly |
22160 // allocated array with values from the given source array instead of | 20912 // allocated array with values from the given source array instead of |
22161 // null-initializing all elements. | 20913 // null-initializing all elements. |
22162 Array& dest = Array::Handle(Array::New(count)); | 20914 Array& dest = Array::Handle(Array::New(count)); |
22163 dest.StorePointers(dest.ObjectAddr(0), ObjectAddr(start), count); | 20915 dest.StorePointers(dest.ObjectAddr(0), ObjectAddr(start), count); |
22164 | 20916 |
22165 if (with_type_argument) { | 20917 if (with_type_argument) { |
22166 dest.SetTypeArguments(TypeArguments::Handle(GetTypeArguments())); | 20918 dest.SetTypeArguments(TypeArguments::Handle(GetTypeArguments())); |
22167 } | 20919 } |
22168 | 20920 |
22169 return dest.raw(); | 20921 return dest.raw(); |
22170 } | 20922 } |
22171 | 20923 |
22172 | |
22173 void Array::MakeImmutable() const { | 20924 void Array::MakeImmutable() const { |
22174 if (IsImmutable()) return; | 20925 if (IsImmutable()) return; |
22175 ASSERT(!IsCanonical()); | 20926 ASSERT(!IsCanonical()); |
22176 NoSafepointScope no_safepoint; | 20927 NoSafepointScope no_safepoint; |
22177 uint32_t tags = raw_ptr()->tags_; | 20928 uint32_t tags = raw_ptr()->tags_; |
22178 uint32_t old_tags; | 20929 uint32_t old_tags; |
22179 do { | 20930 do { |
22180 old_tags = tags; | 20931 old_tags = tags; |
22181 uint32_t new_tags = | 20932 uint32_t new_tags = |
22182 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); | 20933 RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); |
22183 tags = CompareAndSwapTags(old_tags, new_tags); | 20934 tags = CompareAndSwapTags(old_tags, new_tags); |
22184 } while (tags != old_tags); | 20935 } while (tags != old_tags); |
22185 } | 20936 } |
22186 | 20937 |
22187 | |
22188 const char* Array::ToCString() const { | 20938 const char* Array::ToCString() const { |
22189 if (IsNull()) { | 20939 if (IsNull()) { |
22190 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; | 20940 return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; |
22191 } | 20941 } |
22192 Zone* zone = Thread::Current()->zone(); | 20942 Zone* zone = Thread::Current()->zone(); |
22193 const char* format = | 20943 const char* format = |
22194 IsImmutable() ? "_ImmutableList len:%" Pd : "_List len:%" Pd; | 20944 IsImmutable() ? "_ImmutableList len:%" Pd : "_List len:%" Pd; |
22195 return zone->PrintToString(format, Length()); | 20945 return zone->PrintToString(format, Length()); |
22196 } | 20946 } |
22197 | 20947 |
22198 | |
22199 RawArray* Array::Grow(const Array& source, | 20948 RawArray* Array::Grow(const Array& source, |
22200 intptr_t new_length, | 20949 intptr_t new_length, |
22201 Heap::Space space) { | 20950 Heap::Space space) { |
22202 Zone* zone = Thread::Current()->zone(); | 20951 Zone* zone = Thread::Current()->zone(); |
22203 const Array& result = Array::Handle(zone, Array::New(new_length, space)); | 20952 const Array& result = Array::Handle(zone, Array::New(new_length, space)); |
22204 intptr_t len = 0; | 20953 intptr_t len = 0; |
22205 if (!source.IsNull()) { | 20954 if (!source.IsNull()) { |
22206 len = source.Length(); | 20955 len = source.Length(); |
22207 result.SetTypeArguments( | 20956 result.SetTypeArguments( |
22208 TypeArguments::Handle(zone, source.GetTypeArguments())); | 20957 TypeArguments::Handle(zone, source.GetTypeArguments())); |
22209 } | 20958 } |
22210 ASSERT(new_length >= len); // Cannot copy 'source' into new array. | 20959 ASSERT(new_length >= len); // Cannot copy 'source' into new array. |
22211 ASSERT(new_length != len); // Unnecessary copying of array. | 20960 ASSERT(new_length != len); // Unnecessary copying of array. |
22212 PassiveObject& obj = PassiveObject::Handle(zone); | 20961 PassiveObject& obj = PassiveObject::Handle(zone); |
22213 for (int i = 0; i < len; i++) { | 20962 for (int i = 0; i < len; i++) { |
22214 obj = source.At(i); | 20963 obj = source.At(i); |
22215 result.SetAt(i, obj); | 20964 result.SetAt(i, obj); |
22216 } | 20965 } |
22217 return result.raw(); | 20966 return result.raw(); |
22218 } | 20967 } |
22219 | 20968 |
22220 | |
22221 RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array, | 20969 RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array, |
22222 bool unique) { | 20970 bool unique) { |
22223 ASSERT(!growable_array.IsNull()); | 20971 ASSERT(!growable_array.IsNull()); |
22224 Thread* thread = Thread::Current(); | 20972 Thread* thread = Thread::Current(); |
22225 Zone* zone = thread->zone(); | 20973 Zone* zone = thread->zone(); |
22226 intptr_t used_len = growable_array.Length(); | 20974 intptr_t used_len = growable_array.Length(); |
22227 // Get the type arguments and prepare to copy them. | 20975 // Get the type arguments and prepare to copy them. |
22228 const TypeArguments& type_arguments = | 20976 const TypeArguments& type_arguments = |
22229 TypeArguments::Handle(growable_array.GetTypeArguments()); | 20977 TypeArguments::Handle(growable_array.GetTypeArguments()); |
22230 if (used_len == 0) { | 20978 if (used_len == 0) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22274 // in RawObject::SizeFromClass must handle this special case. | 21022 // in RawObject::SizeFromClass must handle this special case. |
22275 array.SetLength(used_len); | 21023 array.SetLength(used_len); |
22276 | 21024 |
22277 // Null the GrowableObjectArray, we are removing its backing array. | 21025 // Null the GrowableObjectArray, we are removing its backing array. |
22278 growable_array.SetLength(0); | 21026 growable_array.SetLength(0); |
22279 growable_array.SetData(Object::empty_array()); | 21027 growable_array.SetData(Object::empty_array()); |
22280 | 21028 |
22281 return array.raw(); | 21029 return array.raw(); |
22282 } | 21030 } |
22283 | 21031 |
22284 | |
22285 bool Array::CheckAndCanonicalizeFields(Thread* thread, | 21032 bool Array::CheckAndCanonicalizeFields(Thread* thread, |
22286 const char** error_str) const { | 21033 const char** error_str) const { |
22287 intptr_t len = Length(); | 21034 intptr_t len = Length(); |
22288 if (len > 0) { | 21035 if (len > 0) { |
22289 Zone* zone = thread->zone(); | 21036 Zone* zone = thread->zone(); |
22290 Object& obj = Object::Handle(zone); | 21037 Object& obj = Object::Handle(zone); |
22291 // Iterate over all elements, canonicalize numbers and strings, expect all | 21038 // Iterate over all elements, canonicalize numbers and strings, expect all |
22292 // other instances to be canonical otherwise report error (return false). | 21039 // other instances to be canonical otherwise report error (return false). |
22293 for (intptr_t i = 0; i < len; i++) { | 21040 for (intptr_t i = 0; i < len; i++) { |
22294 obj = At(i); | 21041 obj = At(i); |
22295 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | 21042 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
22296 if (obj.IsNumber() || obj.IsString()) { | 21043 if (obj.IsNumber() || obj.IsString()) { |
22297 obj = Instance::Cast(obj).CheckAndCanonicalize(thread, NULL); | 21044 obj = Instance::Cast(obj).CheckAndCanonicalize(thread, NULL); |
22298 ASSERT(!obj.IsNull()); | 21045 ASSERT(!obj.IsNull()); |
22299 this->SetAt(i, obj); | 21046 this->SetAt(i, obj); |
22300 } else { | 21047 } else { |
22301 ASSERT(error_str != NULL); | 21048 ASSERT(error_str != NULL); |
22302 char* chars = OS::SCreate(zone, "element at index %" Pd ": %s\n", i, | 21049 char* chars = OS::SCreate(zone, "element at index %" Pd ": %s\n", i, |
22303 obj.ToCString()); | 21050 obj.ToCString()); |
22304 *error_str = chars; | 21051 *error_str = chars; |
22305 return false; | 21052 return false; |
22306 } | 21053 } |
22307 } | 21054 } |
22308 } | 21055 } |
22309 } | 21056 } |
22310 return true; | 21057 return true; |
22311 } | 21058 } |
22312 | 21059 |
22313 | |
22314 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) { | 21060 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) { |
22315 ASSERT(Isolate::Current()->object_store()->immutable_array_class() != | 21061 ASSERT(Isolate::Current()->object_store()->immutable_array_class() != |
22316 Class::null()); | 21062 Class::null()); |
22317 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); | 21063 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); |
22318 } | 21064 } |
22319 | 21065 |
22320 | |
22321 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { | 21066 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { |
22322 ASSERT(!IsNull()); | 21067 ASSERT(!IsNull()); |
22323 if (Length() == Capacity()) { | 21068 if (Length() == Capacity()) { |
22324 // Grow from 0 to 3, and then double + 1. | 21069 // Grow from 0 to 3, and then double + 1. |
22325 intptr_t new_capacity = (Capacity() * 2) | 3; | 21070 intptr_t new_capacity = (Capacity() * 2) | 3; |
22326 if (new_capacity <= Capacity()) { | 21071 if (new_capacity <= Capacity()) { |
22327 Exceptions::ThrowOOM(); | 21072 Exceptions::ThrowOOM(); |
22328 UNREACHABLE(); | 21073 UNREACHABLE(); |
22329 } | 21074 } |
22330 Grow(new_capacity, space); | 21075 Grow(new_capacity, space); |
22331 } | 21076 } |
22332 ASSERT(Length() < Capacity()); | 21077 ASSERT(Length() < Capacity()); |
22333 intptr_t index = Length(); | 21078 intptr_t index = Length(); |
22334 SetLength(index + 1); | 21079 SetLength(index + 1); |
22335 SetAt(index, value); | 21080 SetAt(index, value); |
22336 } | 21081 } |
22337 | 21082 |
22338 | |
22339 void GrowableObjectArray::Grow(intptr_t new_capacity, Heap::Space space) const { | 21083 void GrowableObjectArray::Grow(intptr_t new_capacity, Heap::Space space) const { |
22340 ASSERT(new_capacity > Capacity()); | 21084 ASSERT(new_capacity > Capacity()); |
22341 const Array& contents = Array::Handle(data()); | 21085 const Array& contents = Array::Handle(data()); |
22342 const Array& new_contents = | 21086 const Array& new_contents = |
22343 Array::Handle(Array::Grow(contents, new_capacity, space)); | 21087 Array::Handle(Array::Grow(contents, new_capacity, space)); |
22344 StorePointer(&(raw_ptr()->data_), new_contents.raw()); | 21088 StorePointer(&(raw_ptr()->data_), new_contents.raw()); |
22345 } | 21089 } |
22346 | 21090 |
22347 | |
22348 RawObject* GrowableObjectArray::RemoveLast() const { | 21091 RawObject* GrowableObjectArray::RemoveLast() const { |
22349 ASSERT(!IsNull()); | 21092 ASSERT(!IsNull()); |
22350 ASSERT(Length() > 0); | 21093 ASSERT(Length() > 0); |
22351 intptr_t index = Length() - 1; | 21094 intptr_t index = Length() - 1; |
22352 const Array& contents = Array::Handle(data()); | 21095 const Array& contents = Array::Handle(data()); |
22353 const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); | 21096 const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); |
22354 contents.SetAt(index, Object::null_object()); | 21097 contents.SetAt(index, Object::null_object()); |
22355 SetLength(index); | 21098 SetLength(index); |
22356 return obj.raw(); | 21099 return obj.raw(); |
22357 } | 21100 } |
22358 | 21101 |
22359 | |
22360 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, | 21102 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, |
22361 Heap::Space space) { | 21103 Heap::Space space) { |
22362 RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw() | 21104 RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw() |
22363 : Array::New(capacity, space); | 21105 : Array::New(capacity, space); |
22364 const Array& data = Array::Handle(raw_data); | 21106 const Array& data = Array::Handle(raw_data); |
22365 return New(data, space); | 21107 return New(data, space); |
22366 } | 21108 } |
22367 | 21109 |
22368 | |
22369 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, | 21110 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, |
22370 Heap::Space space) { | 21111 Heap::Space space) { |
22371 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() != | 21112 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() != |
22372 Class::null()); | 21113 Class::null()); |
22373 GrowableObjectArray& result = GrowableObjectArray::Handle(); | 21114 GrowableObjectArray& result = GrowableObjectArray::Handle(); |
22374 { | 21115 { |
22375 RawObject* raw = | 21116 RawObject* raw = |
22376 Object::Allocate(GrowableObjectArray::kClassId, | 21117 Object::Allocate(GrowableObjectArray::kClassId, |
22377 GrowableObjectArray::InstanceSize(), space); | 21118 GrowableObjectArray::InstanceSize(), space); |
22378 NoSafepointScope no_safepoint; | 21119 NoSafepointScope no_safepoint; |
22379 result ^= raw; | 21120 result ^= raw; |
22380 result.SetLength(0); | 21121 result.SetLength(0); |
22381 result.SetData(array); | 21122 result.SetData(array); |
22382 } | 21123 } |
22383 return result.raw(); | 21124 return result.raw(); |
22384 } | 21125 } |
22385 | 21126 |
22386 | |
22387 const char* GrowableObjectArray::ToCString() const { | 21127 const char* GrowableObjectArray::ToCString() const { |
22388 if (IsNull()) { | 21128 if (IsNull()) { |
22389 return "_GrowableList: null"; | 21129 return "_GrowableList: null"; |
22390 } | 21130 } |
22391 return OS::SCreate(Thread::Current()->zone(), | 21131 return OS::SCreate(Thread::Current()->zone(), |
22392 "Instance(length:%" Pd ") of '_GrowableList'", Length()); | 21132 "Instance(length:%" Pd ") of '_GrowableList'", Length()); |
22393 } | 21133 } |
22394 | 21134 |
22395 | |
22396 // Equivalent to Dart's operator "==" and hashCode. | 21135 // Equivalent to Dart's operator "==" and hashCode. |
22397 class DefaultHashTraits { | 21136 class DefaultHashTraits { |
22398 public: | 21137 public: |
22399 static const char* Name() { return "DefaultHashTraits"; } | 21138 static const char* Name() { return "DefaultHashTraits"; } |
22400 static bool ReportStats() { return false; } | 21139 static bool ReportStats() { return false; } |
22401 | 21140 |
22402 static bool IsMatch(const Object& a, const Object& b) { | 21141 static bool IsMatch(const Object& a, const Object& b) { |
22403 if (a.IsNull() || b.IsNull()) { | 21142 if (a.IsNull() || b.IsNull()) { |
22404 return (a.IsNull() && b.IsNull()); | 21143 return (a.IsNull() && b.IsNull()); |
22405 } else { | 21144 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
22421 return static_cast<uword>(Smi::Cast(hash_code).AsTruncatedUint32Value()); | 21160 return static_cast<uword>(Smi::Cast(hash_code).AsTruncatedUint32Value()); |
22422 } else if (hash_code.IsInteger()) { | 21161 } else if (hash_code.IsInteger()) { |
22423 return static_cast<uword>( | 21162 return static_cast<uword>( |
22424 Integer::Cast(hash_code).AsTruncatedUint32Value()); | 21163 Integer::Cast(hash_code).AsTruncatedUint32Value()); |
22425 } else { | 21164 } else { |
22426 return 0; | 21165 return 0; |
22427 } | 21166 } |
22428 } | 21167 } |
22429 }; | 21168 }; |
22430 | 21169 |
22431 | |
22432 RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) { | 21170 RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) { |
22433 const Array& data = Array::Handle(Array::New(kInitialIndexSize, space)); | 21171 const Array& data = Array::Handle(Array::New(kInitialIndexSize, space)); |
22434 const TypedData& index = TypedData::Handle( | 21172 const TypedData& index = TypedData::Handle( |
22435 TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space)); | 21173 TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space)); |
22436 // On 32-bit, the top bits are wasted to avoid Mint allocation. | 21174 // On 32-bit, the top bits are wasted to avoid Mint allocation. |
22437 static const intptr_t kAvailableBits = (kSmiBits >= 32) ? 32 : kSmiBits; | 21175 static const intptr_t kAvailableBits = (kSmiBits >= 32) ? 32 : kSmiBits; |
22438 static const intptr_t kInitialHashMask = | 21176 static const intptr_t kInitialHashMask = |
22439 (1 << (kAvailableBits - kInitialIndexBits)) - 1; | 21177 (1 << (kAvailableBits - kInitialIndexBits)) - 1; |
22440 return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space); | 21178 return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space); |
22441 } | 21179 } |
22442 | 21180 |
22443 | |
22444 RawLinkedHashMap* LinkedHashMap::New(const Array& data, | 21181 RawLinkedHashMap* LinkedHashMap::New(const Array& data, |
22445 const TypedData& index, | 21182 const TypedData& index, |
22446 intptr_t hash_mask, | 21183 intptr_t hash_mask, |
22447 intptr_t used_data, | 21184 intptr_t used_data, |
22448 intptr_t deleted_keys, | 21185 intptr_t deleted_keys, |
22449 Heap::Space space) { | 21186 Heap::Space space) { |
22450 ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != | 21187 ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != |
22451 Class::null()); | 21188 Class::null()); |
22452 LinkedHashMap& result = | 21189 LinkedHashMap& result = |
22453 LinkedHashMap::Handle(LinkedHashMap::NewUninitialized(space)); | 21190 LinkedHashMap::Handle(LinkedHashMap::NewUninitialized(space)); |
22454 result.SetData(data); | 21191 result.SetData(data); |
22455 result.SetIndex(index); | 21192 result.SetIndex(index); |
22456 result.SetHashMask(hash_mask); | 21193 result.SetHashMask(hash_mask); |
22457 result.SetUsedData(used_data); | 21194 result.SetUsedData(used_data); |
22458 result.SetDeletedKeys(deleted_keys); | 21195 result.SetDeletedKeys(deleted_keys); |
22459 return result.raw(); | 21196 return result.raw(); |
22460 } | 21197 } |
22461 | 21198 |
22462 | |
22463 RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) { | 21199 RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) { |
22464 ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != | 21200 ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != |
22465 Class::null()); | 21201 Class::null()); |
22466 LinkedHashMap& result = LinkedHashMap::Handle(); | 21202 LinkedHashMap& result = LinkedHashMap::Handle(); |
22467 { | 21203 { |
22468 RawObject* raw = Object::Allocate(LinkedHashMap::kClassId, | 21204 RawObject* raw = Object::Allocate(LinkedHashMap::kClassId, |
22469 LinkedHashMap::InstanceSize(), space); | 21205 LinkedHashMap::InstanceSize(), space); |
22470 NoSafepointScope no_safepoint; | 21206 NoSafepointScope no_safepoint; |
22471 result ^= raw; | 21207 result ^= raw; |
22472 } | 21208 } |
22473 return result.raw(); | 21209 return result.raw(); |
22474 } | 21210 } |
22475 | 21211 |
22476 | |
22477 const char* LinkedHashMap::ToCString() const { | 21212 const char* LinkedHashMap::ToCString() const { |
22478 Zone* zone = Thread::Current()->zone(); | 21213 Zone* zone = Thread::Current()->zone(); |
22479 return zone->PrintToString("_LinkedHashMap len:%" Pd, Length()); | 21214 return zone->PrintToString("_LinkedHashMap len:%" Pd, Length()); |
22480 } | 21215 } |
22481 | 21216 |
22482 | |
22483 RawFloat32x4* Float32x4::New(float v0, | 21217 RawFloat32x4* Float32x4::New(float v0, |
22484 float v1, | 21218 float v1, |
22485 float v2, | 21219 float v2, |
22486 float v3, | 21220 float v3, |
22487 Heap::Space space) { | 21221 Heap::Space space) { |
22488 ASSERT(Isolate::Current()->object_store()->float32x4_class() != | 21222 ASSERT(Isolate::Current()->object_store()->float32x4_class() != |
22489 Class::null()); | 21223 Class::null()); |
22490 Float32x4& result = Float32x4::Handle(); | 21224 Float32x4& result = Float32x4::Handle(); |
22491 { | 21225 { |
22492 RawObject* raw = | 21226 RawObject* raw = |
22493 Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); | 21227 Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); |
22494 NoSafepointScope no_safepoint; | 21228 NoSafepointScope no_safepoint; |
22495 result ^= raw; | 21229 result ^= raw; |
22496 } | 21230 } |
22497 result.set_x(v0); | 21231 result.set_x(v0); |
22498 result.set_y(v1); | 21232 result.set_y(v1); |
22499 result.set_z(v2); | 21233 result.set_z(v2); |
22500 result.set_w(v3); | 21234 result.set_w(v3); |
22501 return result.raw(); | 21235 return result.raw(); |
22502 } | 21236 } |
22503 | 21237 |
22504 | |
22505 RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) { | 21238 RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) { |
22506 ASSERT(Isolate::Current()->object_store()->float32x4_class() != | 21239 ASSERT(Isolate::Current()->object_store()->float32x4_class() != |
22507 Class::null()); | 21240 Class::null()); |
22508 Float32x4& result = Float32x4::Handle(); | 21241 Float32x4& result = Float32x4::Handle(); |
22509 { | 21242 { |
22510 RawObject* raw = | 21243 RawObject* raw = |
22511 Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); | 21244 Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); |
22512 NoSafepointScope no_safepoint; | 21245 NoSafepointScope no_safepoint; |
22513 result ^= raw; | 21246 result ^= raw; |
22514 } | 21247 } |
22515 result.set_value(value); | 21248 result.set_value(value); |
22516 return result.raw(); | 21249 return result.raw(); |
22517 } | 21250 } |
22518 | 21251 |
22519 | |
22520 simd128_value_t Float32x4::value() const { | 21252 simd128_value_t Float32x4::value() const { |
22521 return ReadUnaligned( | 21253 return ReadUnaligned( |
22522 reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); | 21254 reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); |
22523 } | 21255 } |
22524 | 21256 |
22525 | |
22526 void Float32x4::set_value(simd128_value_t value) const { | 21257 void Float32x4::set_value(simd128_value_t value) const { |
22527 StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), | 21258 StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), |
22528 value); | 21259 value); |
22529 } | 21260 } |
22530 | 21261 |
22531 | |
22532 void Float32x4::set_x(float value) const { | 21262 void Float32x4::set_x(float value) const { |
22533 StoreNonPointer(&raw_ptr()->value_[0], value); | 21263 StoreNonPointer(&raw_ptr()->value_[0], value); |
22534 } | 21264 } |
22535 | 21265 |
22536 | |
22537 void Float32x4::set_y(float value) const { | 21266 void Float32x4::set_y(float value) const { |
22538 StoreNonPointer(&raw_ptr()->value_[1], value); | 21267 StoreNonPointer(&raw_ptr()->value_[1], value); |
22539 } | 21268 } |
22540 | 21269 |
22541 | |
22542 void Float32x4::set_z(float value) const { | 21270 void Float32x4::set_z(float value) const { |
22543 StoreNonPointer(&raw_ptr()->value_[2], value); | 21271 StoreNonPointer(&raw_ptr()->value_[2], value); |
22544 } | 21272 } |
22545 | 21273 |
22546 | |
22547 void Float32x4::set_w(float value) const { | 21274 void Float32x4::set_w(float value) const { |
22548 StoreNonPointer(&raw_ptr()->value_[3], value); | 21275 StoreNonPointer(&raw_ptr()->value_[3], value); |
22549 } | 21276 } |
22550 | 21277 |
22551 | |
22552 float Float32x4::x() const { | 21278 float Float32x4::x() const { |
22553 return raw_ptr()->value_[0]; | 21279 return raw_ptr()->value_[0]; |
22554 } | 21280 } |
22555 | 21281 |
22556 | |
22557 float Float32x4::y() const { | 21282 float Float32x4::y() const { |
22558 return raw_ptr()->value_[1]; | 21283 return raw_ptr()->value_[1]; |
22559 } | 21284 } |
22560 | 21285 |
22561 | |
22562 float Float32x4::z() const { | 21286 float Float32x4::z() const { |
22563 return raw_ptr()->value_[2]; | 21287 return raw_ptr()->value_[2]; |
22564 } | 21288 } |
22565 | 21289 |
22566 | |
22567 float Float32x4::w() const { | 21290 float Float32x4::w() const { |
22568 return raw_ptr()->value_[3]; | 21291 return raw_ptr()->value_[3]; |
22569 } | 21292 } |
22570 | 21293 |
22571 | |
22572 const char* Float32x4::ToCString() const { | 21294 const char* Float32x4::ToCString() const { |
22573 float _x = x(); | 21295 float _x = x(); |
22574 float _y = y(); | 21296 float _y = y(); |
22575 float _z = z(); | 21297 float _z = z(); |
22576 float _w = w(); | 21298 float _w = w(); |
22577 return OS::SCreate(Thread::Current()->zone(), "[%f, %f, %f, %f]", _x, _y, _z, | 21299 return OS::SCreate(Thread::Current()->zone(), "[%f, %f, %f, %f]", _x, _y, _z, |
22578 _w); | 21300 _w); |
22579 } | 21301 } |
22580 | 21302 |
22581 | |
22582 RawInt32x4* Int32x4::New(int32_t v0, | 21303 RawInt32x4* Int32x4::New(int32_t v0, |
22583 int32_t v1, | 21304 int32_t v1, |
22584 int32_t v2, | 21305 int32_t v2, |
22585 int32_t v3, | 21306 int32_t v3, |
22586 Heap::Space space) { | 21307 Heap::Space space) { |
22587 ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); | 21308 ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); |
22588 Int32x4& result = Int32x4::Handle(); | 21309 Int32x4& result = Int32x4::Handle(); |
22589 { | 21310 { |
22590 RawObject* raw = | 21311 RawObject* raw = |
22591 Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); | 21312 Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); |
22592 NoSafepointScope no_safepoint; | 21313 NoSafepointScope no_safepoint; |
22593 result ^= raw; | 21314 result ^= raw; |
22594 } | 21315 } |
22595 result.set_x(v0); | 21316 result.set_x(v0); |
22596 result.set_y(v1); | 21317 result.set_y(v1); |
22597 result.set_z(v2); | 21318 result.set_z(v2); |
22598 result.set_w(v3); | 21319 result.set_w(v3); |
22599 return result.raw(); | 21320 return result.raw(); |
22600 } | 21321 } |
22601 | 21322 |
22602 | |
22603 RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) { | 21323 RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) { |
22604 ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); | 21324 ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); |
22605 Int32x4& result = Int32x4::Handle(); | 21325 Int32x4& result = Int32x4::Handle(); |
22606 { | 21326 { |
22607 RawObject* raw = | 21327 RawObject* raw = |
22608 Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); | 21328 Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); |
22609 NoSafepointScope no_safepoint; | 21329 NoSafepointScope no_safepoint; |
22610 result ^= raw; | 21330 result ^= raw; |
22611 } | 21331 } |
22612 result.set_value(value); | 21332 result.set_value(value); |
22613 return result.raw(); | 21333 return result.raw(); |
22614 } | 21334 } |
22615 | 21335 |
22616 | |
22617 void Int32x4::set_x(int32_t value) const { | 21336 void Int32x4::set_x(int32_t value) const { |
22618 StoreNonPointer(&raw_ptr()->value_[0], value); | 21337 StoreNonPointer(&raw_ptr()->value_[0], value); |
22619 } | 21338 } |
22620 | 21339 |
22621 | |
22622 void Int32x4::set_y(int32_t value) const { | 21340 void Int32x4::set_y(int32_t value) const { |
22623 StoreNonPointer(&raw_ptr()->value_[1], value); | 21341 StoreNonPointer(&raw_ptr()->value_[1], value); |
22624 } | 21342 } |
22625 | 21343 |
22626 | |
22627 void Int32x4::set_z(int32_t value) const { | 21344 void Int32x4::set_z(int32_t value) const { |
22628 StoreNonPointer(&raw_ptr()->value_[2], value); | 21345 StoreNonPointer(&raw_ptr()->value_[2], value); |
22629 } | 21346 } |
22630 | 21347 |
22631 | |
22632 void Int32x4::set_w(int32_t value) const { | 21348 void Int32x4::set_w(int32_t value) const { |
22633 StoreNonPointer(&raw_ptr()->value_[3], value); | 21349 StoreNonPointer(&raw_ptr()->value_[3], value); |
22634 } | 21350 } |
22635 | 21351 |
22636 | |
22637 int32_t Int32x4::x() const { | 21352 int32_t Int32x4::x() const { |
22638 return raw_ptr()->value_[0]; | 21353 return raw_ptr()->value_[0]; |
22639 } | 21354 } |
22640 | 21355 |
22641 | |
22642 int32_t Int32x4::y() const { | 21356 int32_t Int32x4::y() const { |
22643 return raw_ptr()->value_[1]; | 21357 return raw_ptr()->value_[1]; |
22644 } | 21358 } |
22645 | 21359 |
22646 | |
22647 int32_t Int32x4::z() const { | 21360 int32_t Int32x4::z() const { |
22648 return raw_ptr()->value_[2]; | 21361 return raw_ptr()->value_[2]; |
22649 } | 21362 } |
22650 | 21363 |
22651 | |
22652 int32_t Int32x4::w() const { | 21364 int32_t Int32x4::w() const { |
22653 return raw_ptr()->value_[3]; | 21365 return raw_ptr()->value_[3]; |
22654 } | 21366 } |
22655 | 21367 |
22656 | |
22657 simd128_value_t Int32x4::value() const { | 21368 simd128_value_t Int32x4::value() const { |
22658 return ReadUnaligned( | 21369 return ReadUnaligned( |
22659 reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); | 21370 reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); |
22660 } | 21371 } |
22661 | 21372 |
22662 | |
22663 void Int32x4::set_value(simd128_value_t value) const { | 21373 void Int32x4::set_value(simd128_value_t value) const { |
22664 StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), | 21374 StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), |
22665 value); | 21375 value); |
22666 } | 21376 } |
22667 | 21377 |
22668 | |
22669 const char* Int32x4::ToCString() const { | 21378 const char* Int32x4::ToCString() const { |
22670 int32_t _x = x(); | 21379 int32_t _x = x(); |
22671 int32_t _y = y(); | 21380 int32_t _y = y(); |
22672 int32_t _z = z(); | 21381 int32_t _z = z(); |
22673 int32_t _w = w(); | 21382 int32_t _w = w(); |
22674 return OS::SCreate(Thread::Current()->zone(), "[%08x, %08x, %08x, %08x]", _x, | 21383 return OS::SCreate(Thread::Current()->zone(), "[%08x, %08x, %08x, %08x]", _x, |
22675 _y, _z, _w); | 21384 _y, _z, _w); |
22676 } | 21385 } |
22677 | 21386 |
22678 | |
22679 RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) { | 21387 RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) { |
22680 ASSERT(Isolate::Current()->object_store()->float64x2_class() != | 21388 ASSERT(Isolate::Current()->object_store()->float64x2_class() != |
22681 Class::null()); | 21389 Class::null()); |
22682 Float64x2& result = Float64x2::Handle(); | 21390 Float64x2& result = Float64x2::Handle(); |
22683 { | 21391 { |
22684 RawObject* raw = | 21392 RawObject* raw = |
22685 Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); | 21393 Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); |
22686 NoSafepointScope no_safepoint; | 21394 NoSafepointScope no_safepoint; |
22687 result ^= raw; | 21395 result ^= raw; |
22688 } | 21396 } |
22689 result.set_x(value0); | 21397 result.set_x(value0); |
22690 result.set_y(value1); | 21398 result.set_y(value1); |
22691 return result.raw(); | 21399 return result.raw(); |
22692 } | 21400 } |
22693 | 21401 |
22694 | |
22695 RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) { | 21402 RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) { |
22696 ASSERT(Isolate::Current()->object_store()->float64x2_class() != | 21403 ASSERT(Isolate::Current()->object_store()->float64x2_class() != |
22697 Class::null()); | 21404 Class::null()); |
22698 Float64x2& result = Float64x2::Handle(); | 21405 Float64x2& result = Float64x2::Handle(); |
22699 { | 21406 { |
22700 RawObject* raw = | 21407 RawObject* raw = |
22701 Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); | 21408 Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); |
22702 NoSafepointScope no_safepoint; | 21409 NoSafepointScope no_safepoint; |
22703 result ^= raw; | 21410 result ^= raw; |
22704 } | 21411 } |
22705 result.set_value(value); | 21412 result.set_value(value); |
22706 return result.raw(); | 21413 return result.raw(); |
22707 } | 21414 } |
22708 | 21415 |
22709 | |
22710 double Float64x2::x() const { | 21416 double Float64x2::x() const { |
22711 return raw_ptr()->value_[0]; | 21417 return raw_ptr()->value_[0]; |
22712 } | 21418 } |
22713 | 21419 |
22714 | |
22715 double Float64x2::y() const { | 21420 double Float64x2::y() const { |
22716 return raw_ptr()->value_[1]; | 21421 return raw_ptr()->value_[1]; |
22717 } | 21422 } |
22718 | 21423 |
22719 | |
22720 void Float64x2::set_x(double x) const { | 21424 void Float64x2::set_x(double x) const { |
22721 StoreNonPointer(&raw_ptr()->value_[0], x); | 21425 StoreNonPointer(&raw_ptr()->value_[0], x); |
22722 } | 21426 } |
22723 | 21427 |
22724 | |
22725 void Float64x2::set_y(double y) const { | 21428 void Float64x2::set_y(double y) const { |
22726 StoreNonPointer(&raw_ptr()->value_[1], y); | 21429 StoreNonPointer(&raw_ptr()->value_[1], y); |
22727 } | 21430 } |
22728 | 21431 |
22729 | |
22730 simd128_value_t Float64x2::value() const { | 21432 simd128_value_t Float64x2::value() const { |
22731 return simd128_value_t().readFrom(&raw_ptr()->value_[0]); | 21433 return simd128_value_t().readFrom(&raw_ptr()->value_[0]); |
22732 } | 21434 } |
22733 | 21435 |
22734 | |
22735 void Float64x2::set_value(simd128_value_t value) const { | 21436 void Float64x2::set_value(simd128_value_t value) const { |
22736 StoreSimd128(&raw_ptr()->value_[0], value); | 21437 StoreSimd128(&raw_ptr()->value_[0], value); |
22737 } | 21438 } |
22738 | 21439 |
22739 | |
22740 const char* Float64x2::ToCString() const { | 21440 const char* Float64x2::ToCString() const { |
22741 double _x = x(); | 21441 double _x = x(); |
22742 double _y = y(); | 21442 double _y = y(); |
22743 return OS::SCreate(Thread::Current()->zone(), "[%f, %f]", _x, _y); | 21443 return OS::SCreate(Thread::Current()->zone(), "[%f, %f]", _x, _y); |
22744 } | 21444 } |
22745 | 21445 |
22746 | |
22747 const intptr_t TypedData::element_size_table[TypedData::kNumElementSizes] = { | 21446 const intptr_t TypedData::element_size_table[TypedData::kNumElementSizes] = { |
22748 1, // kTypedDataInt8ArrayCid. | 21447 1, // kTypedDataInt8ArrayCid. |
22749 1, // kTypedDataUint8ArrayCid. | 21448 1, // kTypedDataUint8ArrayCid. |
22750 1, // kTypedDataUint8ClampedArrayCid. | 21449 1, // kTypedDataUint8ClampedArrayCid. |
22751 2, // kTypedDataInt16ArrayCid. | 21450 2, // kTypedDataInt16ArrayCid. |
22752 2, // kTypedDataUint16ArrayCid. | 21451 2, // kTypedDataUint16ArrayCid. |
22753 4, // kTypedDataInt32ArrayCid. | 21452 4, // kTypedDataInt32ArrayCid. |
22754 4, // kTypedDataUint32ArrayCid. | 21453 4, // kTypedDataUint32ArrayCid. |
22755 8, // kTypedDataInt64ArrayCid. | 21454 8, // kTypedDataInt64ArrayCid. |
22756 8, // kTypedDataUint64ArrayCid. | 21455 8, // kTypedDataUint64ArrayCid. |
22757 4, // kTypedDataFloat32ArrayCid. | 21456 4, // kTypedDataFloat32ArrayCid. |
22758 8, // kTypedDataFloat64ArrayCid. | 21457 8, // kTypedDataFloat64ArrayCid. |
22759 16, // kTypedDataFloat32x4ArrayCid. | 21458 16, // kTypedDataFloat32x4ArrayCid. |
22760 16, // kTypedDataInt32x4ArrayCid. | 21459 16, // kTypedDataInt32x4ArrayCid. |
22761 16, // kTypedDataFloat64x2ArrayCid, | 21460 16, // kTypedDataFloat64x2ArrayCid, |
22762 }; | 21461 }; |
22763 | 21462 |
22764 | |
22765 bool TypedData::CanonicalizeEquals(const Instance& other) const { | 21463 bool TypedData::CanonicalizeEquals(const Instance& other) const { |
22766 if (this->raw() == other.raw()) { | 21464 if (this->raw() == other.raw()) { |
22767 // Both handles point to the same raw instance. | 21465 // Both handles point to the same raw instance. |
22768 return true; | 21466 return true; |
22769 } | 21467 } |
22770 | 21468 |
22771 if (!other.IsTypedData() || other.IsNull()) { | 21469 if (!other.IsTypedData() || other.IsNull()) { |
22772 return false; | 21470 return false; |
22773 } | 21471 } |
22774 | 21472 |
22775 const TypedData& other_typed_data = TypedData::Cast(other); | 21473 const TypedData& other_typed_data = TypedData::Cast(other); |
22776 | 21474 |
22777 if (this->ElementType() != other_typed_data.ElementType()) { | 21475 if (this->ElementType() != other_typed_data.ElementType()) { |
22778 return false; | 21476 return false; |
22779 } | 21477 } |
22780 | 21478 |
22781 const intptr_t len = this->LengthInBytes(); | 21479 const intptr_t len = this->LengthInBytes(); |
22782 if (len != other_typed_data.LengthInBytes()) { | 21480 if (len != other_typed_data.LengthInBytes()) { |
22783 return false; | 21481 return false; |
22784 } | 21482 } |
22785 NoSafepointScope no_safepoint; | 21483 NoSafepointScope no_safepoint; |
22786 return (len == 0) || | 21484 return (len == 0) || |
22787 (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0); | 21485 (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0); |
22788 } | 21486 } |
22789 | 21487 |
22790 | |
22791 uword TypedData::ComputeCanonicalTableHash() const { | 21488 uword TypedData::ComputeCanonicalTableHash() const { |
22792 const intptr_t len = this->LengthInBytes(); | 21489 const intptr_t len = this->LengthInBytes(); |
22793 ASSERT(len != 0); | 21490 ASSERT(len != 0); |
22794 uword hash = len; | 21491 uword hash = len; |
22795 for (intptr_t i = 0; i < len; i++) { | 21492 for (intptr_t i = 0; i < len; i++) { |
22796 hash = CombineHashes(len, GetUint8(i)); | 21493 hash = CombineHashes(len, GetUint8(i)); |
22797 } | 21494 } |
22798 return FinalizeHash(hash, kHashBits); | 21495 return FinalizeHash(hash, kHashBits); |
22799 } | 21496 } |
22800 | 21497 |
22801 | |
22802 RawTypedData* TypedData::New(intptr_t class_id, | 21498 RawTypedData* TypedData::New(intptr_t class_id, |
22803 intptr_t len, | 21499 intptr_t len, |
22804 Heap::Space space) { | 21500 Heap::Space space) { |
22805 if (len < 0 || len > TypedData::MaxElements(class_id)) { | 21501 if (len < 0 || len > TypedData::MaxElements(class_id)) { |
22806 FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len); | 21502 FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len); |
22807 } | 21503 } |
22808 TypedData& result = TypedData::Handle(); | 21504 TypedData& result = TypedData::Handle(); |
22809 { | 21505 { |
22810 const intptr_t lengthInBytes = len * ElementSizeInBytes(class_id); | 21506 const intptr_t lengthInBytes = len * ElementSizeInBytes(class_id); |
22811 RawObject* raw = Object::Allocate( | 21507 RawObject* raw = Object::Allocate( |
22812 class_id, TypedData::InstanceSize(lengthInBytes), space); | 21508 class_id, TypedData::InstanceSize(lengthInBytes), space); |
22813 NoSafepointScope no_safepoint; | 21509 NoSafepointScope no_safepoint; |
22814 result ^= raw; | 21510 result ^= raw; |
22815 result.SetLength(len); | 21511 result.SetLength(len); |
22816 if (len > 0) { | 21512 if (len > 0) { |
22817 memset(result.DataAddr(0), 0, lengthInBytes); | 21513 memset(result.DataAddr(0), 0, lengthInBytes); |
22818 } | 21514 } |
22819 } | 21515 } |
22820 return result.raw(); | 21516 return result.raw(); |
22821 } | 21517 } |
22822 | 21518 |
22823 | |
22824 RawTypedData* TypedData::EmptyUint32Array(Thread* thread) { | 21519 RawTypedData* TypedData::EmptyUint32Array(Thread* thread) { |
22825 ASSERT(thread != NULL); | 21520 ASSERT(thread != NULL); |
22826 Isolate* isolate = thread->isolate(); | 21521 Isolate* isolate = thread->isolate(); |
22827 ASSERT(isolate != NULL); | 21522 ASSERT(isolate != NULL); |
22828 ASSERT(isolate->object_store() != NULL); | 21523 ASSERT(isolate->object_store() != NULL); |
22829 if (isolate->object_store()->empty_uint32_array() != TypedData::null()) { | 21524 if (isolate->object_store()->empty_uint32_array() != TypedData::null()) { |
22830 // Already created. | 21525 // Already created. |
22831 return isolate->object_store()->empty_uint32_array(); | 21526 return isolate->object_store()->empty_uint32_array(); |
22832 } | 21527 } |
22833 const TypedData& array = TypedData::Handle( | 21528 const TypedData& array = TypedData::Handle( |
22834 thread->zone(), TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld)); | 21529 thread->zone(), TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld)); |
22835 isolate->object_store()->set_empty_uint32_array(array); | 21530 isolate->object_store()->set_empty_uint32_array(array); |
22836 return array.raw(); | 21531 return array.raw(); |
22837 } | 21532 } |
22838 | 21533 |
22839 | |
22840 const char* TypedData::ToCString() const { | 21534 const char* TypedData::ToCString() const { |
22841 switch (GetClassId()) { | 21535 switch (GetClassId()) { |
22842 #define CASE_TYPED_DATA_CLASS(clazz) \ | 21536 #define CASE_TYPED_DATA_CLASS(clazz) \ |
22843 case kTypedData##clazz##Cid: \ | 21537 case kTypedData##clazz##Cid: \ |
22844 return #clazz; | 21538 return #clazz; |
22845 CLASS_LIST_TYPED_DATA(CASE_TYPED_DATA_CLASS); | 21539 CLASS_LIST_TYPED_DATA(CASE_TYPED_DATA_CLASS); |
22846 #undef CASE_TYPED_DATA_CLASS | 21540 #undef CASE_TYPED_DATA_CLASS |
22847 } | 21541 } |
22848 return "TypedData"; | 21542 return "TypedData"; |
22849 } | 21543 } |
22850 | 21544 |
22851 | |
22852 FinalizablePersistentHandle* ExternalTypedData::AddFinalizer( | 21545 FinalizablePersistentHandle* ExternalTypedData::AddFinalizer( |
22853 void* peer, | 21546 void* peer, |
22854 Dart_WeakPersistentHandleFinalizer callback, | 21547 Dart_WeakPersistentHandleFinalizer callback, |
22855 intptr_t external_size) const { | 21548 intptr_t external_size) const { |
22856 return dart::AddFinalizer(*this, peer, callback, external_size); | 21549 return dart::AddFinalizer(*this, peer, callback, external_size); |
22857 } | 21550 } |
22858 | 21551 |
22859 | |
22860 RawExternalTypedData* ExternalTypedData::New(intptr_t class_id, | 21552 RawExternalTypedData* ExternalTypedData::New(intptr_t class_id, |
22861 uint8_t* data, | 21553 uint8_t* data, |
22862 intptr_t len, | 21554 intptr_t len, |
22863 Heap::Space space) { | 21555 Heap::Space space) { |
22864 ExternalTypedData& result = ExternalTypedData::Handle(); | 21556 ExternalTypedData& result = ExternalTypedData::Handle(); |
22865 { | 21557 { |
22866 RawObject* raw = | 21558 RawObject* raw = |
22867 Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space); | 21559 Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space); |
22868 NoSafepointScope no_safepoint; | 21560 NoSafepointScope no_safepoint; |
22869 result ^= raw; | 21561 result ^= raw; |
22870 result.SetLength(len); | 21562 result.SetLength(len); |
22871 result.SetData(data); | 21563 result.SetData(data); |
22872 } | 21564 } |
22873 return result.raw(); | 21565 return result.raw(); |
22874 } | 21566 } |
22875 | 21567 |
22876 | |
22877 const char* ExternalTypedData::ToCString() const { | 21568 const char* ExternalTypedData::ToCString() const { |
22878 return "ExternalTypedData"; | 21569 return "ExternalTypedData"; |
22879 } | 21570 } |
22880 | 21571 |
22881 | |
22882 RawCapability* Capability::New(uint64_t id, Heap::Space space) { | 21572 RawCapability* Capability::New(uint64_t id, Heap::Space space) { |
22883 Capability& result = Capability::Handle(); | 21573 Capability& result = Capability::Handle(); |
22884 { | 21574 { |
22885 RawObject* raw = Object::Allocate(Capability::kClassId, | 21575 RawObject* raw = Object::Allocate(Capability::kClassId, |
22886 Capability::InstanceSize(), space); | 21576 Capability::InstanceSize(), space); |
22887 NoSafepointScope no_safepoint; | 21577 NoSafepointScope no_safepoint; |
22888 result ^= raw; | 21578 result ^= raw; |
22889 result.StoreNonPointer(&result.raw_ptr()->id_, id); | 21579 result.StoreNonPointer(&result.raw_ptr()->id_, id); |
22890 } | 21580 } |
22891 return result.raw(); | 21581 return result.raw(); |
22892 } | 21582 } |
22893 | 21583 |
22894 | |
22895 const char* Capability::ToCString() const { | 21584 const char* Capability::ToCString() const { |
22896 return "Capability"; | 21585 return "Capability"; |
22897 } | 21586 } |
22898 | 21587 |
22899 | |
22900 RawReceivePort* ReceivePort::New(Dart_Port id, | 21588 RawReceivePort* ReceivePort::New(Dart_Port id, |
22901 bool is_control_port, | 21589 bool is_control_port, |
22902 Heap::Space space) { | 21590 Heap::Space space) { |
22903 ASSERT(id != ILLEGAL_PORT); | 21591 ASSERT(id != ILLEGAL_PORT); |
22904 Thread* thread = Thread::Current(); | 21592 Thread* thread = Thread::Current(); |
22905 Zone* zone = thread->zone(); | 21593 Zone* zone = thread->zone(); |
22906 const SendPort& send_port = | 21594 const SendPort& send_port = |
22907 SendPort::Handle(zone, SendPort::New(id, thread->isolate()->origin_id())); | 21595 SendPort::Handle(zone, SendPort::New(id, thread->isolate()->origin_id())); |
22908 | 21596 |
22909 ReceivePort& result = ReceivePort::Handle(zone); | 21597 ReceivePort& result = ReceivePort::Handle(zone); |
22910 { | 21598 { |
22911 RawObject* raw = Object::Allocate(ReceivePort::kClassId, | 21599 RawObject* raw = Object::Allocate(ReceivePort::kClassId, |
22912 ReceivePort::InstanceSize(), space); | 21600 ReceivePort::InstanceSize(), space); |
22913 NoSafepointScope no_safepoint; | 21601 NoSafepointScope no_safepoint; |
22914 result ^= raw; | 21602 result ^= raw; |
22915 result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw()); | 21603 result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw()); |
22916 } | 21604 } |
22917 if (is_control_port) { | 21605 if (is_control_port) { |
22918 PortMap::SetPortState(id, PortMap::kControlPort); | 21606 PortMap::SetPortState(id, PortMap::kControlPort); |
22919 } else { | 21607 } else { |
22920 PortMap::SetPortState(id, PortMap::kLivePort); | 21608 PortMap::SetPortState(id, PortMap::kLivePort); |
22921 } | 21609 } |
22922 return result.raw(); | 21610 return result.raw(); |
22923 } | 21611 } |
22924 | 21612 |
22925 | |
22926 const char* ReceivePort::ToCString() const { | 21613 const char* ReceivePort::ToCString() const { |
22927 return "ReceivePort"; | 21614 return "ReceivePort"; |
22928 } | 21615 } |
22929 | 21616 |
22930 | |
22931 RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) { | 21617 RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) { |
22932 return New(id, Isolate::Current()->origin_id(), space); | 21618 return New(id, Isolate::Current()->origin_id(), space); |
22933 } | 21619 } |
22934 | 21620 |
22935 | |
22936 RawSendPort* SendPort::New(Dart_Port id, | 21621 RawSendPort* SendPort::New(Dart_Port id, |
22937 Dart_Port origin_id, | 21622 Dart_Port origin_id, |
22938 Heap::Space space) { | 21623 Heap::Space space) { |
22939 ASSERT(id != ILLEGAL_PORT); | 21624 ASSERT(id != ILLEGAL_PORT); |
22940 SendPort& result = SendPort::Handle(); | 21625 SendPort& result = SendPort::Handle(); |
22941 { | 21626 { |
22942 RawObject* raw = | 21627 RawObject* raw = |
22943 Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space); | 21628 Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space); |
22944 NoSafepointScope no_safepoint; | 21629 NoSafepointScope no_safepoint; |
22945 result ^= raw; | 21630 result ^= raw; |
22946 result.StoreNonPointer(&result.raw_ptr()->id_, id); | 21631 result.StoreNonPointer(&result.raw_ptr()->id_, id); |
22947 result.StoreNonPointer(&result.raw_ptr()->origin_id_, origin_id); | 21632 result.StoreNonPointer(&result.raw_ptr()->origin_id_, origin_id); |
22948 } | 21633 } |
22949 return result.raw(); | 21634 return result.raw(); |
22950 } | 21635 } |
22951 | 21636 |
22952 | |
22953 const char* SendPort::ToCString() const { | 21637 const char* SendPort::ToCString() const { |
22954 return "SendPort"; | 21638 return "SendPort"; |
22955 } | 21639 } |
22956 | 21640 |
22957 | |
22958 const char* Closure::ToCString() const { | 21641 const char* Closure::ToCString() const { |
22959 const Function& fun = Function::Handle(function()); | 21642 const Function& fun = Function::Handle(function()); |
22960 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); | 21643 const bool is_implicit_closure = fun.IsImplicitClosureFunction(); |
22961 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); | 21644 const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); |
22962 const char* from = is_implicit_closure ? " from " : ""; | 21645 const char* from = is_implicit_closure ? " from " : ""; |
22963 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; | 21646 const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; |
22964 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, | 21647 return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, |
22965 from, fun_desc); | 21648 from, fun_desc); |
22966 } | 21649 } |
22967 | 21650 |
22968 | |
22969 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, | 21651 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, |
22970 const TypeArguments& function_type_arguments, | 21652 const TypeArguments& function_type_arguments, |
22971 const Function& function, | 21653 const Function& function, |
22972 const Context& context, | 21654 const Context& context, |
22973 Heap::Space space) { | 21655 Heap::Space space) { |
22974 Closure& result = Closure::Handle(); | 21656 Closure& result = Closure::Handle(); |
22975 { | 21657 { |
22976 RawObject* raw = | 21658 RawObject* raw = |
22977 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); | 21659 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); |
22978 NoSafepointScope no_safepoint; | 21660 NoSafepointScope no_safepoint; |
22979 result ^= raw; | 21661 result ^= raw; |
22980 result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_, | 21662 result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_, |
22981 instantiator_type_arguments.raw()); | 21663 instantiator_type_arguments.raw()); |
22982 result.StorePointer(&result.raw_ptr()->function_type_arguments_, | 21664 result.StorePointer(&result.raw_ptr()->function_type_arguments_, |
22983 function_type_arguments.raw()); | 21665 function_type_arguments.raw()); |
22984 result.StorePointer(&result.raw_ptr()->function_, function.raw()); | 21666 result.StorePointer(&result.raw_ptr()->function_, function.raw()); |
22985 result.StorePointer(&result.raw_ptr()->context_, context.raw()); | 21667 result.StorePointer(&result.raw_ptr()->context_, context.raw()); |
22986 } | 21668 } |
22987 return result.raw(); | 21669 return result.raw(); |
22988 } | 21670 } |
22989 | 21671 |
22990 | |
22991 RawClosure* Closure::New() { | 21672 RawClosure* Closure::New() { |
22992 RawObject* raw = | 21673 RawObject* raw = |
22993 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); | 21674 Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); |
22994 return reinterpret_cast<RawClosure*>(raw); | 21675 return reinterpret_cast<RawClosure*>(raw); |
22995 } | 21676 } |
22996 | 21677 |
22997 | |
22998 intptr_t StackTrace::Length() const { | 21678 intptr_t StackTrace::Length() const { |
22999 const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 21679 const Array& code_array = Array::Handle(raw_ptr()->code_array_); |
23000 return code_array.Length(); | 21680 return code_array.Length(); |
23001 } | 21681 } |
23002 | 21682 |
23003 | |
23004 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const { | 21683 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const { |
23005 const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 21684 const Array& code_array = Array::Handle(raw_ptr()->code_array_); |
23006 return reinterpret_cast<RawCode*>(code_array.At(frame_index)); | 21685 return reinterpret_cast<RawCode*>(code_array.At(frame_index)); |
23007 } | 21686 } |
23008 | 21687 |
23009 | |
23010 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { | 21688 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { |
23011 const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 21689 const Array& code_array = Array::Handle(raw_ptr()->code_array_); |
23012 code_array.SetAt(frame_index, code); | 21690 code_array.SetAt(frame_index, code); |
23013 } | 21691 } |
23014 | 21692 |
23015 | |
23016 RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const { | 21693 RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const { |
23017 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 21694 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |
23018 return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index)); | 21695 return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index)); |
23019 } | 21696 } |
23020 | 21697 |
23021 | |
23022 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index, | 21698 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index, |
23023 const Smi& pc_offset) const { | 21699 const Smi& pc_offset) const { |
23024 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 21700 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |
23025 pc_offset_array.SetAt(frame_index, pc_offset); | 21701 pc_offset_array.SetAt(frame_index, pc_offset); |
23026 } | 21702 } |
23027 | 21703 |
23028 | |
23029 void StackTrace::set_async_link(const StackTrace& async_link) const { | 21704 void StackTrace::set_async_link(const StackTrace& async_link) const { |
23030 StorePointer(&raw_ptr()->async_link_, async_link.raw()); | 21705 StorePointer(&raw_ptr()->async_link_, async_link.raw()); |
23031 } | 21706 } |
23032 | 21707 |
23033 | |
23034 void StackTrace::set_code_array(const Array& code_array) const { | 21708 void StackTrace::set_code_array(const Array& code_array) const { |
23035 StorePointer(&raw_ptr()->code_array_, code_array.raw()); | 21709 StorePointer(&raw_ptr()->code_array_, code_array.raw()); |
23036 } | 21710 } |
23037 | 21711 |
23038 | |
23039 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const { | 21712 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const { |
23040 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); | 21713 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); |
23041 } | 21714 } |
23042 | 21715 |
23043 | |
23044 void StackTrace::set_expand_inlined(bool value) const { | 21716 void StackTrace::set_expand_inlined(bool value) const { |
23045 StoreNonPointer(&raw_ptr()->expand_inlined_, value); | 21717 StoreNonPointer(&raw_ptr()->expand_inlined_, value); |
23046 } | 21718 } |
23047 | 21719 |
23048 | |
23049 bool StackTrace::expand_inlined() const { | 21720 bool StackTrace::expand_inlined() const { |
23050 return raw_ptr()->expand_inlined_; | 21721 return raw_ptr()->expand_inlined_; |
23051 } | 21722 } |
23052 | 21723 |
23053 | |
23054 RawStackTrace* StackTrace::New(const Array& code_array, | 21724 RawStackTrace* StackTrace::New(const Array& code_array, |
23055 const Array& pc_offset_array, | 21725 const Array& pc_offset_array, |
23056 Heap::Space space) { | 21726 Heap::Space space) { |
23057 StackTrace& result = StackTrace::Handle(); | 21727 StackTrace& result = StackTrace::Handle(); |
23058 { | 21728 { |
23059 RawObject* raw = Object::Allocate(StackTrace::kClassId, | 21729 RawObject* raw = Object::Allocate(StackTrace::kClassId, |
23060 StackTrace::InstanceSize(), space); | 21730 StackTrace::InstanceSize(), space); |
23061 NoSafepointScope no_safepoint; | 21731 NoSafepointScope no_safepoint; |
23062 result ^= raw; | 21732 result ^= raw; |
23063 } | 21733 } |
23064 result.set_code_array(code_array); | 21734 result.set_code_array(code_array); |
23065 result.set_pc_offset_array(pc_offset_array); | 21735 result.set_pc_offset_array(pc_offset_array); |
23066 result.set_expand_inlined(true); // default. | 21736 result.set_expand_inlined(true); // default. |
23067 return result.raw(); | 21737 return result.raw(); |
23068 } | 21738 } |
23069 | 21739 |
23070 | |
23071 RawStackTrace* StackTrace::New(const Array& code_array, | 21740 RawStackTrace* StackTrace::New(const Array& code_array, |
23072 const Array& pc_offset_array, | 21741 const Array& pc_offset_array, |
23073 const StackTrace& async_link, | 21742 const StackTrace& async_link, |
23074 Heap::Space space) { | 21743 Heap::Space space) { |
23075 StackTrace& result = StackTrace::Handle(); | 21744 StackTrace& result = StackTrace::Handle(); |
23076 { | 21745 { |
23077 RawObject* raw = Object::Allocate(StackTrace::kClassId, | 21746 RawObject* raw = Object::Allocate(StackTrace::kClassId, |
23078 StackTrace::InstanceSize(), space); | 21747 StackTrace::InstanceSize(), space); |
23079 NoSafepointScope no_safepoint; | 21748 NoSafepointScope no_safepoint; |
23080 result ^= raw; | 21749 result ^= raw; |
23081 } | 21750 } |
23082 result.set_async_link(async_link); | 21751 result.set_async_link(async_link); |
23083 result.set_code_array(code_array); | 21752 result.set_code_array(code_array); |
23084 result.set_pc_offset_array(pc_offset_array); | 21753 result.set_pc_offset_array(pc_offset_array); |
23085 result.set_expand_inlined(true); // default. | 21754 result.set_expand_inlined(true); // default. |
23086 return result.raw(); | 21755 return result.raw(); |
23087 } | 21756 } |
23088 | 21757 |
23089 | |
23090 static void PrintStackTraceFrame(Zone* zone, | 21758 static void PrintStackTraceFrame(Zone* zone, |
23091 ZoneTextBuffer* buffer, | 21759 ZoneTextBuffer* buffer, |
23092 const Function& function, | 21760 const Function& function, |
23093 TokenPosition token_pos, | 21761 TokenPosition token_pos, |
23094 intptr_t frame_index) { | 21762 intptr_t frame_index) { |
23095 const Script& script = Script::Handle(zone, function.script()); | 21763 const Script& script = Script::Handle(zone, function.script()); |
23096 const String& function_name = | 21764 const String& function_name = |
23097 String::Handle(zone, function.QualifiedUserVisibleName()); | 21765 String::Handle(zone, function.QualifiedUserVisibleName()); |
23098 const String& url = String::Handle( | 21766 const String& url = String::Handle( |
23099 zone, script.IsNull() ? String::New("Kernel") : script.url()); | 21767 zone, script.IsNull() ? String::New("Kernel") : script.url()); |
(...skipping 15 matching lines...) Expand all Loading... |
23115 function_name.ToCString(), url.ToCString(), line, column); | 21783 function_name.ToCString(), url.ToCString(), line, column); |
23116 } else if (line >= 0) { | 21784 } else if (line >= 0) { |
23117 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, | 21785 buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, |
23118 function_name.ToCString(), url.ToCString(), line); | 21786 function_name.ToCString(), url.ToCString(), line); |
23119 } else { | 21787 } else { |
23120 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, | 21788 buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, |
23121 function_name.ToCString(), url.ToCString()); | 21789 function_name.ToCString(), url.ToCString()); |
23122 } | 21790 } |
23123 } | 21791 } |
23124 | 21792 |
23125 | |
23126 const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) { | 21793 const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) { |
23127 Zone* zone = Thread::Current()->zone(); | 21794 Zone* zone = Thread::Current()->zone(); |
23128 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); | 21795 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); |
23129 Function& function = Function::Handle(zone); | 21796 Function& function = Function::Handle(zone); |
23130 Code& code = Code::Handle(zone); | 21797 Code& code = Code::Handle(zone); |
23131 | 21798 |
23132 GrowableArray<const Function*> inlined_functions; | 21799 GrowableArray<const Function*> inlined_functions; |
23133 GrowableArray<TokenPosition> inlined_token_positions; | 21800 GrowableArray<TokenPosition> inlined_token_positions; |
23134 ZoneTextBuffer buffer(zone, 1024); | 21801 ZoneTextBuffer buffer(zone, 1024); |
23135 | 21802 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23183 } | 21850 } |
23184 } | 21851 } |
23185 } | 21852 } |
23186 // Follow the link. | 21853 // Follow the link. |
23187 stack_trace ^= stack_trace.async_link(); | 21854 stack_trace ^= stack_trace.async_link(); |
23188 } while (!stack_trace.IsNull()); | 21855 } while (!stack_trace.IsNull()); |
23189 | 21856 |
23190 return buffer.buffer(); | 21857 return buffer.buffer(); |
23191 } | 21858 } |
23192 | 21859 |
23193 | |
23194 const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) { | 21860 const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) { |
23195 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 21861 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |
23196 Zone* zone = Thread::Current()->zone(); | 21862 Zone* zone = Thread::Current()->zone(); |
23197 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); | 21863 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); |
23198 Code& code = Code::Handle(zone); | 21864 Code& code = Code::Handle(zone); |
23199 ZoneTextBuffer buffer(zone, 1024); | 21865 ZoneTextBuffer buffer(zone, 1024); |
23200 | 21866 |
23201 // The Dart standard requires the output of StackTrace.toString to include | 21867 // The Dart standard requires the output of StackTrace.toString to include |
23202 // all pending activations with precise source locations (i.e., to expand | 21868 // all pending activations with precise source locations (i.e., to expand |
23203 // inlined frames and provide line and column numbers). | 21869 // inlined frames and provide line and column numbers). |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23257 stack_trace ^= stack_trace.async_link(); | 21923 stack_trace ^= stack_trace.async_link(); |
23258 } while (!stack_trace.IsNull()); | 21924 } while (!stack_trace.IsNull()); |
23259 | 21925 |
23260 return buffer.buffer(); | 21926 return buffer.buffer(); |
23261 #else | 21927 #else |
23262 UNREACHABLE(); | 21928 UNREACHABLE(); |
23263 return NULL; | 21929 return NULL; |
23264 #endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 21930 #endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |
23265 } | 21931 } |
23266 | 21932 |
23267 | |
23268 const char* StackTrace::ToCString() const { | 21933 const char* StackTrace::ToCString() const { |
23269 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 21934 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |
23270 if (FLAG_dwarf_stack_traces) { | 21935 if (FLAG_dwarf_stack_traces) { |
23271 return ToDwarfCString(*this); | 21936 return ToDwarfCString(*this); |
23272 } | 21937 } |
23273 #endif | 21938 #endif |
23274 return ToDartCString(*this); | 21939 return ToDartCString(*this); |
23275 } | 21940 } |
23276 | 21941 |
23277 | |
23278 void RegExp::set_pattern(const String& pattern) const { | 21942 void RegExp::set_pattern(const String& pattern) const { |
23279 StorePointer(&raw_ptr()->pattern_, pattern.raw()); | 21943 StorePointer(&raw_ptr()->pattern_, pattern.raw()); |
23280 } | 21944 } |
23281 | 21945 |
23282 | |
23283 void RegExp::set_function(intptr_t cid, | 21946 void RegExp::set_function(intptr_t cid, |
23284 bool sticky, | 21947 bool sticky, |
23285 const Function& value) const { | 21948 const Function& value) const { |
23286 StorePointer(FunctionAddr(cid, sticky), value.raw()); | 21949 StorePointer(FunctionAddr(cid, sticky), value.raw()); |
23287 } | 21950 } |
23288 | 21951 |
23289 | |
23290 void RegExp::set_bytecode(bool is_one_byte, | 21952 void RegExp::set_bytecode(bool is_one_byte, |
23291 bool sticky, | 21953 bool sticky, |
23292 const TypedData& bytecode) const { | 21954 const TypedData& bytecode) const { |
23293 if (sticky) { | 21955 if (sticky) { |
23294 if (is_one_byte) { | 21956 if (is_one_byte) { |
23295 StorePointer(&raw_ptr()->one_byte_sticky_.bytecode_, bytecode.raw()); | 21957 StorePointer(&raw_ptr()->one_byte_sticky_.bytecode_, bytecode.raw()); |
23296 } else { | 21958 } else { |
23297 StorePointer(&raw_ptr()->two_byte_sticky_.bytecode_, bytecode.raw()); | 21959 StorePointer(&raw_ptr()->two_byte_sticky_.bytecode_, bytecode.raw()); |
23298 } | 21960 } |
23299 } else { | 21961 } else { |
23300 if (is_one_byte) { | 21962 if (is_one_byte) { |
23301 StorePointer(&raw_ptr()->one_byte_.bytecode_, bytecode.raw()); | 21963 StorePointer(&raw_ptr()->one_byte_.bytecode_, bytecode.raw()); |
23302 } else { | 21964 } else { |
23303 StorePointer(&raw_ptr()->two_byte_.bytecode_, bytecode.raw()); | 21965 StorePointer(&raw_ptr()->two_byte_.bytecode_, bytecode.raw()); |
23304 } | 21966 } |
23305 } | 21967 } |
23306 } | 21968 } |
23307 | 21969 |
23308 | |
23309 void RegExp::set_num_bracket_expressions(intptr_t value) const { | 21970 void RegExp::set_num_bracket_expressions(intptr_t value) const { |
23310 StoreSmi(&raw_ptr()->num_bracket_expressions_, Smi::New(value)); | 21971 StoreSmi(&raw_ptr()->num_bracket_expressions_, Smi::New(value)); |
23311 } | 21972 } |
23312 | 21973 |
23313 | |
23314 RawRegExp* RegExp::New(Heap::Space space) { | 21974 RawRegExp* RegExp::New(Heap::Space space) { |
23315 RegExp& result = RegExp::Handle(); | 21975 RegExp& result = RegExp::Handle(); |
23316 { | 21976 { |
23317 RawObject* raw = | 21977 RawObject* raw = |
23318 Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space); | 21978 Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space); |
23319 NoSafepointScope no_safepoint; | 21979 NoSafepointScope no_safepoint; |
23320 result ^= raw; | 21980 result ^= raw; |
23321 result.set_type(kUnitialized); | 21981 result.set_type(kUnitialized); |
23322 result.set_flags(0); | 21982 result.set_flags(0); |
23323 result.set_num_registers(-1); | 21983 result.set_num_registers(-1); |
23324 } | 21984 } |
23325 return result.raw(); | 21985 return result.raw(); |
23326 } | 21986 } |
23327 | 21987 |
23328 | |
23329 void* RegExp::GetDataStartAddress() const { | 21988 void* RegExp::GetDataStartAddress() const { |
23330 intptr_t addr = reinterpret_cast<intptr_t>(raw_ptr()); | 21989 intptr_t addr = reinterpret_cast<intptr_t>(raw_ptr()); |
23331 return reinterpret_cast<void*>(addr + sizeof(RawRegExp)); | 21990 return reinterpret_cast<void*>(addr + sizeof(RawRegExp)); |
23332 } | 21991 } |
23333 | 21992 |
23334 | |
23335 RawRegExp* RegExp::FromDataStartAddress(void* data) { | 21993 RawRegExp* RegExp::FromDataStartAddress(void* data) { |
23336 RegExp& regexp = RegExp::Handle(); | 21994 RegExp& regexp = RegExp::Handle(); |
23337 intptr_t addr = reinterpret_cast<intptr_t>(data) - sizeof(RawRegExp); | 21995 intptr_t addr = reinterpret_cast<intptr_t>(data) - sizeof(RawRegExp); |
23338 regexp ^= RawObject::FromAddr(addr); | 21996 regexp ^= RawObject::FromAddr(addr); |
23339 return regexp.raw(); | 21997 return regexp.raw(); |
23340 } | 21998 } |
23341 | 21999 |
23342 | |
23343 const char* RegExp::Flags() const { | 22000 const char* RegExp::Flags() const { |
23344 switch (flags()) { | 22001 switch (flags()) { |
23345 case kGlobal | kIgnoreCase | kMultiLine: | 22002 case kGlobal | kIgnoreCase | kMultiLine: |
23346 case kIgnoreCase | kMultiLine: | 22003 case kIgnoreCase | kMultiLine: |
23347 return "im"; | 22004 return "im"; |
23348 case kGlobal | kIgnoreCase: | 22005 case kGlobal | kIgnoreCase: |
23349 case kIgnoreCase: | 22006 case kIgnoreCase: |
23350 return "i"; | 22007 return "i"; |
23351 case kGlobal | kMultiLine: | 22008 case kGlobal | kMultiLine: |
23352 case kMultiLine: | 22009 case kMultiLine: |
23353 return "m"; | 22010 return "m"; |
23354 default: | 22011 default: |
23355 break; | 22012 break; |
23356 } | 22013 } |
23357 return ""; | 22014 return ""; |
23358 } | 22015 } |
23359 | 22016 |
23360 | |
23361 bool RegExp::CanonicalizeEquals(const Instance& other) const { | 22017 bool RegExp::CanonicalizeEquals(const Instance& other) const { |
23362 if (this->raw() == other.raw()) { | 22018 if (this->raw() == other.raw()) { |
23363 return true; // "===". | 22019 return true; // "===". |
23364 } | 22020 } |
23365 if (other.IsNull() || !other.IsRegExp()) { | 22021 if (other.IsNull() || !other.IsRegExp()) { |
23366 return false; | 22022 return false; |
23367 } | 22023 } |
23368 const RegExp& other_js = RegExp::Cast(other); | 22024 const RegExp& other_js = RegExp::Cast(other); |
23369 // Match the pattern. | 22025 // Match the pattern. |
23370 const String& str1 = String::Handle(pattern()); | 22026 const String& str1 = String::Handle(pattern()); |
23371 const String& str2 = String::Handle(other_js.pattern()); | 22027 const String& str2 = String::Handle(other_js.pattern()); |
23372 if (!str1.Equals(str2)) { | 22028 if (!str1.Equals(str2)) { |
23373 return false; | 22029 return false; |
23374 } | 22030 } |
23375 // Match the flags. | 22031 // Match the flags. |
23376 if ((is_global() != other_js.is_global()) || | 22032 if ((is_global() != other_js.is_global()) || |
23377 (is_ignore_case() != other_js.is_ignore_case()) || | 22033 (is_ignore_case() != other_js.is_ignore_case()) || |
23378 (is_multi_line() != other_js.is_multi_line())) { | 22034 (is_multi_line() != other_js.is_multi_line())) { |
23379 return false; | 22035 return false; |
23380 } | 22036 } |
23381 return true; | 22037 return true; |
23382 } | 22038 } |
23383 | 22039 |
23384 | |
23385 const char* RegExp::ToCString() const { | 22040 const char* RegExp::ToCString() const { |
23386 const String& str = String::Handle(pattern()); | 22041 const String& str = String::Handle(pattern()); |
23387 return OS::SCreate(Thread::Current()->zone(), "RegExp: pattern=%s flags=%s", | 22042 return OS::SCreate(Thread::Current()->zone(), "RegExp: pattern=%s flags=%s", |
23388 str.ToCString(), Flags()); | 22043 str.ToCString(), Flags()); |
23389 } | 22044 } |
23390 | 22045 |
23391 | |
23392 RawWeakProperty* WeakProperty::New(Heap::Space space) { | 22046 RawWeakProperty* WeakProperty::New(Heap::Space space) { |
23393 ASSERT(Isolate::Current()->object_store()->weak_property_class() != | 22047 ASSERT(Isolate::Current()->object_store()->weak_property_class() != |
23394 Class::null()); | 22048 Class::null()); |
23395 RawObject* raw = Object::Allocate(WeakProperty::kClassId, | 22049 RawObject* raw = Object::Allocate(WeakProperty::kClassId, |
23396 WeakProperty::InstanceSize(), space); | 22050 WeakProperty::InstanceSize(), space); |
23397 RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw); | 22051 RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw); |
23398 result->ptr()->next_ = 0; // Init the list to NULL. | 22052 result->ptr()->next_ = 0; // Init the list to NULL. |
23399 return result; | 22053 return result; |
23400 } | 22054 } |
23401 | 22055 |
23402 | |
23403 const char* WeakProperty::ToCString() const { | 22056 const char* WeakProperty::ToCString() const { |
23404 return "_WeakProperty"; | 22057 return "_WeakProperty"; |
23405 } | 22058 } |
23406 | 22059 |
23407 | |
23408 RawAbstractType* MirrorReference::GetAbstractTypeReferent() const { | 22060 RawAbstractType* MirrorReference::GetAbstractTypeReferent() const { |
23409 ASSERT(Object::Handle(referent()).IsAbstractType()); | 22061 ASSERT(Object::Handle(referent()).IsAbstractType()); |
23410 return AbstractType::Cast(Object::Handle(referent())).raw(); | 22062 return AbstractType::Cast(Object::Handle(referent())).raw(); |
23411 } | 22063 } |
23412 | 22064 |
23413 | |
23414 RawClass* MirrorReference::GetClassReferent() const { | 22065 RawClass* MirrorReference::GetClassReferent() const { |
23415 ASSERT(Object::Handle(referent()).IsClass()); | 22066 ASSERT(Object::Handle(referent()).IsClass()); |
23416 return Class::Cast(Object::Handle(referent())).raw(); | 22067 return Class::Cast(Object::Handle(referent())).raw(); |
23417 } | 22068 } |
23418 | 22069 |
23419 | |
23420 RawField* MirrorReference::GetFieldReferent() const { | 22070 RawField* MirrorReference::GetFieldReferent() const { |
23421 ASSERT(Object::Handle(referent()).IsField()); | 22071 ASSERT(Object::Handle(referent()).IsField()); |
23422 return Field::Cast(Object::Handle(referent())).raw(); | 22072 return Field::Cast(Object::Handle(referent())).raw(); |
23423 } | 22073 } |
23424 | 22074 |
23425 | |
23426 RawFunction* MirrorReference::GetFunctionReferent() const { | 22075 RawFunction* MirrorReference::GetFunctionReferent() const { |
23427 ASSERT(Object::Handle(referent()).IsFunction()); | 22076 ASSERT(Object::Handle(referent()).IsFunction()); |
23428 return Function::Cast(Object::Handle(referent())).raw(); | 22077 return Function::Cast(Object::Handle(referent())).raw(); |
23429 } | 22078 } |
23430 | 22079 |
23431 | |
23432 RawLibrary* MirrorReference::GetLibraryReferent() const { | 22080 RawLibrary* MirrorReference::GetLibraryReferent() const { |
23433 ASSERT(Object::Handle(referent()).IsLibrary()); | 22081 ASSERT(Object::Handle(referent()).IsLibrary()); |
23434 return Library::Cast(Object::Handle(referent())).raw(); | 22082 return Library::Cast(Object::Handle(referent())).raw(); |
23435 } | 22083 } |
23436 | 22084 |
23437 | |
23438 RawTypeParameter* MirrorReference::GetTypeParameterReferent() const { | 22085 RawTypeParameter* MirrorReference::GetTypeParameterReferent() const { |
23439 ASSERT(Object::Handle(referent()).IsTypeParameter()); | 22086 ASSERT(Object::Handle(referent()).IsTypeParameter()); |
23440 return TypeParameter::Cast(Object::Handle(referent())).raw(); | 22087 return TypeParameter::Cast(Object::Handle(referent())).raw(); |
23441 } | 22088 } |
23442 | 22089 |
23443 | |
23444 RawMirrorReference* MirrorReference::New(const Object& referent, | 22090 RawMirrorReference* MirrorReference::New(const Object& referent, |
23445 Heap::Space space) { | 22091 Heap::Space space) { |
23446 MirrorReference& result = MirrorReference::Handle(); | 22092 MirrorReference& result = MirrorReference::Handle(); |
23447 { | 22093 { |
23448 RawObject* raw = Object::Allocate(MirrorReference::kClassId, | 22094 RawObject* raw = Object::Allocate(MirrorReference::kClassId, |
23449 MirrorReference::InstanceSize(), space); | 22095 MirrorReference::InstanceSize(), space); |
23450 NoSafepointScope no_safepoint; | 22096 NoSafepointScope no_safepoint; |
23451 result ^= raw; | 22097 result ^= raw; |
23452 } | 22098 } |
23453 result.set_referent(referent); | 22099 result.set_referent(referent); |
23454 return result.raw(); | 22100 return result.raw(); |
23455 } | 22101 } |
23456 | 22102 |
23457 | |
23458 const char* MirrorReference::ToCString() const { | 22103 const char* MirrorReference::ToCString() const { |
23459 return "_MirrorReference"; | 22104 return "_MirrorReference"; |
23460 } | 22105 } |
23461 | 22106 |
23462 | |
23463 void UserTag::MakeActive() const { | 22107 void UserTag::MakeActive() const { |
23464 Isolate* isolate = Isolate::Current(); | 22108 Isolate* isolate = Isolate::Current(); |
23465 ASSERT(isolate != NULL); | 22109 ASSERT(isolate != NULL); |
23466 isolate->set_current_tag(*this); | 22110 isolate->set_current_tag(*this); |
23467 } | 22111 } |
23468 | 22112 |
23469 | |
23470 RawUserTag* UserTag::New(const String& label, Heap::Space space) { | 22113 RawUserTag* UserTag::New(const String& label, Heap::Space space) { |
23471 Thread* thread = Thread::Current(); | 22114 Thread* thread = Thread::Current(); |
23472 Isolate* isolate = thread->isolate(); | 22115 Isolate* isolate = thread->isolate(); |
23473 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 22116 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |
23474 // Canonicalize by name. | 22117 // Canonicalize by name. |
23475 UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label)); | 22118 UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label)); |
23476 if (!result.IsNull()) { | 22119 if (!result.IsNull()) { |
23477 // Tag already exists, return existing instance. | 22120 // Tag already exists, return existing instance. |
23478 return result.raw(); | 22121 return result.raw(); |
23479 } | 22122 } |
23480 if (TagTableIsFull(thread)) { | 22123 if (TagTableIsFull(thread)) { |
23481 const String& error = String::Handle(String::NewFormatted( | 22124 const String& error = String::Handle(String::NewFormatted( |
23482 "UserTag instance limit (%" Pd ") reached.", UserTags::kMaxUserTags)); | 22125 "UserTag instance limit (%" Pd ") reached.", UserTags::kMaxUserTags)); |
23483 const Array& args = Array::Handle(Array::New(1)); | 22126 const Array& args = Array::Handle(Array::New(1)); |
23484 args.SetAt(0, error); | 22127 args.SetAt(0, error); |
23485 Exceptions::ThrowByType(Exceptions::kUnsupported, args); | 22128 Exceptions::ThrowByType(Exceptions::kUnsupported, args); |
23486 } | 22129 } |
23487 // No tag with label exists, create and register with isolate tag table. | 22130 // No tag with label exists, create and register with isolate tag table. |
23488 { | 22131 { |
23489 RawObject* raw = | 22132 RawObject* raw = |
23490 Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space); | 22133 Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space); |
23491 NoSafepointScope no_safepoint; | 22134 NoSafepointScope no_safepoint; |
23492 result ^= raw; | 22135 result ^= raw; |
23493 } | 22136 } |
23494 result.set_label(label); | 22137 result.set_label(label); |
23495 AddTagToIsolate(thread, result); | 22138 AddTagToIsolate(thread, result); |
23496 return result.raw(); | 22139 return result.raw(); |
23497 } | 22140 } |
23498 | 22141 |
23499 | |
23500 RawUserTag* UserTag::DefaultTag() { | 22142 RawUserTag* UserTag::DefaultTag() { |
23501 Thread* thread = Thread::Current(); | 22143 Thread* thread = Thread::Current(); |
23502 Zone* zone = thread->zone(); | 22144 Zone* zone = thread->zone(); |
23503 Isolate* isolate = thread->isolate(); | 22145 Isolate* isolate = thread->isolate(); |
23504 ASSERT(isolate != NULL); | 22146 ASSERT(isolate != NULL); |
23505 if (isolate->default_tag() != UserTag::null()) { | 22147 if (isolate->default_tag() != UserTag::null()) { |
23506 // Already created. | 22148 // Already created. |
23507 return isolate->default_tag(); | 22149 return isolate->default_tag(); |
23508 } | 22150 } |
23509 // Create default tag. | 22151 // Create default tag. |
23510 const UserTag& result = | 22152 const UserTag& result = |
23511 UserTag::Handle(zone, UserTag::New(Symbols::Default())); | 22153 UserTag::Handle(zone, UserTag::New(Symbols::Default())); |
23512 ASSERT(result.tag() == UserTags::kDefaultUserTag); | 22154 ASSERT(result.tag() == UserTags::kDefaultUserTag); |
23513 isolate->set_default_tag(result); | 22155 isolate->set_default_tag(result); |
23514 return result.raw(); | 22156 return result.raw(); |
23515 } | 22157 } |
23516 | 22158 |
23517 | |
23518 RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) { | 22159 RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) { |
23519 Isolate* isolate = thread->isolate(); | 22160 Isolate* isolate = thread->isolate(); |
23520 Zone* zone = thread->zone(); | 22161 Zone* zone = thread->zone(); |
23521 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 22162 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |
23522 const GrowableObjectArray& tag_table = | 22163 const GrowableObjectArray& tag_table = |
23523 GrowableObjectArray::Handle(zone, isolate->tag_table()); | 22164 GrowableObjectArray::Handle(zone, isolate->tag_table()); |
23524 UserTag& other = UserTag::Handle(zone); | 22165 UserTag& other = UserTag::Handle(zone); |
23525 String& tag_label = String::Handle(zone); | 22166 String& tag_label = String::Handle(zone); |
23526 for (intptr_t i = 0; i < tag_table.Length(); i++) { | 22167 for (intptr_t i = 0; i < tag_table.Length(); i++) { |
23527 other ^= tag_table.At(i); | 22168 other ^= tag_table.At(i); |
23528 ASSERT(!other.IsNull()); | 22169 ASSERT(!other.IsNull()); |
23529 tag_label ^= other.label(); | 22170 tag_label ^= other.label(); |
23530 ASSERT(!tag_label.IsNull()); | 22171 ASSERT(!tag_label.IsNull()); |
23531 if (tag_label.Equals(label)) { | 22172 if (tag_label.Equals(label)) { |
23532 return other.raw(); | 22173 return other.raw(); |
23533 } | 22174 } |
23534 } | 22175 } |
23535 return UserTag::null(); | 22176 return UserTag::null(); |
23536 } | 22177 } |
23537 | 22178 |
23538 | |
23539 void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) { | 22179 void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) { |
23540 Isolate* isolate = thread->isolate(); | 22180 Isolate* isolate = thread->isolate(); |
23541 Zone* zone = thread->zone(); | 22181 Zone* zone = thread->zone(); |
23542 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 22182 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |
23543 const GrowableObjectArray& tag_table = | 22183 const GrowableObjectArray& tag_table = |
23544 GrowableObjectArray::Handle(zone, isolate->tag_table()); | 22184 GrowableObjectArray::Handle(zone, isolate->tag_table()); |
23545 ASSERT(!TagTableIsFull(thread)); | 22185 ASSERT(!TagTableIsFull(thread)); |
23546 #if defined(DEBUG) | 22186 #if defined(DEBUG) |
23547 // Verify that no existing tag has the same tag id. | 22187 // Verify that no existing tag has the same tag id. |
23548 UserTag& other = UserTag::Handle(thread->zone()); | 22188 UserTag& other = UserTag::Handle(thread->zone()); |
23549 for (intptr_t i = 0; i < tag_table.Length(); i++) { | 22189 for (intptr_t i = 0; i < tag_table.Length(); i++) { |
23550 other ^= tag_table.At(i); | 22190 other ^= tag_table.At(i); |
23551 ASSERT(!other.IsNull()); | 22191 ASSERT(!other.IsNull()); |
23552 ASSERT(tag.tag() != other.tag()); | 22192 ASSERT(tag.tag() != other.tag()); |
23553 } | 22193 } |
23554 #endif | 22194 #endif |
23555 // Generate the UserTag tag id by taking the length of the isolate's | 22195 // Generate the UserTag tag id by taking the length of the isolate's |
23556 // tag table + kUserTagIdOffset. | 22196 // tag table + kUserTagIdOffset. |
23557 uword tag_id = tag_table.Length() + UserTags::kUserTagIdOffset; | 22197 uword tag_id = tag_table.Length() + UserTags::kUserTagIdOffset; |
23558 ASSERT(tag_id >= UserTags::kUserTagIdOffset); | 22198 ASSERT(tag_id >= UserTags::kUserTagIdOffset); |
23559 ASSERT(tag_id < (UserTags::kUserTagIdOffset + UserTags::kMaxUserTags)); | 22199 ASSERT(tag_id < (UserTags::kUserTagIdOffset + UserTags::kMaxUserTags)); |
23560 tag.set_tag(tag_id); | 22200 tag.set_tag(tag_id); |
23561 tag_table.Add(tag); | 22201 tag_table.Add(tag); |
23562 } | 22202 } |
23563 | 22203 |
23564 | |
23565 bool UserTag::TagTableIsFull(Thread* thread) { | 22204 bool UserTag::TagTableIsFull(Thread* thread) { |
23566 Isolate* isolate = thread->isolate(); | 22205 Isolate* isolate = thread->isolate(); |
23567 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 22206 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |
23568 const GrowableObjectArray& tag_table = | 22207 const GrowableObjectArray& tag_table = |
23569 GrowableObjectArray::Handle(thread->zone(), isolate->tag_table()); | 22208 GrowableObjectArray::Handle(thread->zone(), isolate->tag_table()); |
23570 ASSERT(tag_table.Length() <= UserTags::kMaxUserTags); | 22209 ASSERT(tag_table.Length() <= UserTags::kMaxUserTags); |
23571 return tag_table.Length() == UserTags::kMaxUserTags; | 22210 return tag_table.Length() == UserTags::kMaxUserTags; |
23572 } | 22211 } |
23573 | 22212 |
23574 | |
23575 RawUserTag* UserTag::FindTagById(uword tag_id) { | 22213 RawUserTag* UserTag::FindTagById(uword tag_id) { |
23576 Thread* thread = Thread::Current(); | 22214 Thread* thread = Thread::Current(); |
23577 Zone* zone = thread->zone(); | 22215 Zone* zone = thread->zone(); |
23578 Isolate* isolate = thread->isolate(); | 22216 Isolate* isolate = thread->isolate(); |
23579 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 22217 ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |
23580 const GrowableObjectArray& tag_table = | 22218 const GrowableObjectArray& tag_table = |
23581 GrowableObjectArray::Handle(zone, isolate->tag_table()); | 22219 GrowableObjectArray::Handle(zone, isolate->tag_table()); |
23582 UserTag& tag = UserTag::Handle(zone); | 22220 UserTag& tag = UserTag::Handle(zone); |
23583 for (intptr_t i = 0; i < tag_table.Length(); i++) { | 22221 for (intptr_t i = 0; i < tag_table.Length(); i++) { |
23584 tag ^= tag_table.At(i); | 22222 tag ^= tag_table.At(i); |
23585 if (tag.tag() == tag_id) { | 22223 if (tag.tag() == tag_id) { |
23586 return tag.raw(); | 22224 return tag.raw(); |
23587 } | 22225 } |
23588 } | 22226 } |
23589 return UserTag::null(); | 22227 return UserTag::null(); |
23590 } | 22228 } |
23591 | 22229 |
23592 | |
23593 const char* UserTag::ToCString() const { | 22230 const char* UserTag::ToCString() const { |
23594 const String& tag_label = String::Handle(label()); | 22231 const String& tag_label = String::Handle(label()); |
23595 return tag_label.ToCString(); | 22232 return tag_label.ToCString(); |
23596 } | 22233 } |
23597 | 22234 |
23598 } // namespace dart | 22235 } // namespace dart |
OLD | NEW |