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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_arm64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698