| OLD | NEW | 
|      1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |      1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|      2 // for details. All rights reserved. Use of this source code is governed by a |      2 // for details. All rights reserved. Use of this source code is governed by a | 
|      3 // BSD-style license that can be found in the LICENSE file. |      3 // BSD-style license that can be found in the LICENSE file. | 
|      4  |      4  | 
|      5 #include "vm/object.h" |      5 #include "vm/object.h" | 
|      6  |      6  | 
|      7 #include "include/dart_api.h" |      7 #include "include/dart_api.h" | 
|      8 #include "platform/assert.h" |      8 #include "platform/assert.h" | 
|      9 #include "vm/assembler.h" |      9 #include "vm/assembler.h" | 
|     10 #include "vm/become.h" |     10 #include "vm/become.h" | 
|     11 #include "vm/cpu.h" |  | 
|     12 #include "vm/bit_vector.h" |     11 #include "vm/bit_vector.h" | 
|     13 #include "vm/bootstrap.h" |     12 #include "vm/bootstrap.h" | 
|     14 #include "vm/class_finalizer.h" |     13 #include "vm/class_finalizer.h" | 
|     15 #include "vm/code_observers.h" |     14 #include "vm/code_observers.h" | 
|     16 #include "vm/compiler.h" |     15 #include "vm/compiler.h" | 
|     17 #include "vm/compiler_stats.h" |     16 #include "vm/compiler_stats.h" | 
 |     17 #include "vm/cpu.h" | 
|     18 #include "vm/dart.h" |     18 #include "vm/dart.h" | 
|     19 #include "vm/dart_api_state.h" |     19 #include "vm/dart_api_state.h" | 
|     20 #include "vm/dart_entry.h" |     20 #include "vm/dart_entry.h" | 
|     21 #include "vm/datastream.h" |     21 #include "vm/datastream.h" | 
|     22 #include "vm/debugger.h" |     22 #include "vm/debugger.h" | 
|     23 #include "vm/deopt_instructions.h" |     23 #include "vm/deopt_instructions.h" | 
|     24 #include "vm/disassembler.h" |     24 #include "vm/disassembler.h" | 
|     25 #include "vm/double_conversion.h" |     25 #include "vm/double_conversion.h" | 
|     26 #include "vm/exceptions.h" |     26 #include "vm/exceptions.h" | 
|     27 #include "vm/growable_array.h" |     27 #include "vm/growable_array.h" | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|     85 DECLARE_FLAG(bool, trace_deoptimization_verbose); |     85 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 
|     86 DECLARE_FLAG(bool, trace_reload); |     86 DECLARE_FLAG(bool, trace_reload); | 
|     87 DECLARE_FLAG(bool, write_protect_code); |     87 DECLARE_FLAG(bool, write_protect_code); | 
|     88 DECLARE_FLAG(bool, support_externalizable_strings); |     88 DECLARE_FLAG(bool, support_externalizable_strings); | 
|     89  |     89  | 
|     90 static const char* const kGetterPrefix = "get:"; |     90 static const char* const kGetterPrefix = "get:"; | 
|     91 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |     91 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 
|     92 static const char* const kSetterPrefix = "set:"; |     92 static const char* const kSetterPrefix = "set:"; | 
|     93 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |     93 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 
|     94  |     94  | 
|     95  |  | 
|     96 // A cache of VM heap allocated preinitialized empty ic data entry arrays. |     95 // A cache of VM heap allocated preinitialized empty ic data entry arrays. | 
|     97 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; |     96 RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; | 
|     98  |     97  | 
|     99 cpp_vtable Object::handle_vtable_ = 0; |     98 cpp_vtable Object::handle_vtable_ = 0; | 
|    100 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {0}; |     99 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = {0}; | 
|    101 cpp_vtable Smi::handle_vtable_ = 0; |    100 cpp_vtable Smi::handle_vtable_ = 0; | 
|    102  |    101  | 
|    103 // These are initialized to a value that will force a illegal memory access if |    102 // These are initialized to a value that will force a illegal memory access if | 
|    104 // they are being used. |    103 // they are being used. | 
|    105 #if defined(RAW_NULL) |    104 #if defined(RAW_NULL) | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    176 RawClass* Object::megamorphic_cache_class_ = |    175 RawClass* Object::megamorphic_cache_class_ = | 
|    177     reinterpret_cast<RawClass*>(RAW_NULL); |    176     reinterpret_cast<RawClass*>(RAW_NULL); | 
|    178 RawClass* Object::subtypetestcache_class_ = |    177 RawClass* Object::subtypetestcache_class_ = | 
|    179     reinterpret_cast<RawClass*>(RAW_NULL); |    178     reinterpret_cast<RawClass*>(RAW_NULL); | 
|    180 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |    179 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 
|    181 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |    180 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 
|    182 RawClass* Object::unhandled_exception_class_ = |    181 RawClass* Object::unhandled_exception_class_ = | 
|    183     reinterpret_cast<RawClass*>(RAW_NULL); |    182     reinterpret_cast<RawClass*>(RAW_NULL); | 
|    184 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |    183 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 
|    185  |    184  | 
|    186  |  | 
|    187 const double MegamorphicCache::kLoadFactor = 0.50; |    185 const double MegamorphicCache::kLoadFactor = 0.50; | 
|    188  |    186  | 
|    189  |  | 
|    190 static void AppendSubString(Zone* zone, |    187 static void AppendSubString(Zone* zone, | 
|    191                             GrowableArray<const char*>* segments, |    188                             GrowableArray<const char*>* segments, | 
|    192                             const char* name, |    189                             const char* name, | 
|    193                             intptr_t start_pos, |    190                             intptr_t start_pos, | 
|    194                             intptr_t len) { |    191                             intptr_t len) { | 
|    195   char* segment = zone->Alloc<char>(len + 1);  // '\0'-terminated. |    192   char* segment = zone->Alloc<char>(len + 1);  // '\0'-terminated. | 
|    196   memmove(segment, name + start_pos, len); |    193   memmove(segment, name + start_pos, len); | 
|    197   segment[len] = '\0'; |    194   segment[len] = '\0'; | 
|    198   segments->Add(segment); |    195   segments->Add(segment); | 
|    199 } |    196 } | 
|    200  |    197  | 
|    201  |  | 
|    202 static const char* MergeSubStrings(Zone* zone, |    198 static const char* MergeSubStrings(Zone* zone, | 
|    203                                    const GrowableArray<const char*>& segments, |    199                                    const GrowableArray<const char*>& segments, | 
|    204                                    intptr_t alloc_len) { |    200                                    intptr_t alloc_len) { | 
|    205   char* result = zone->Alloc<char>(alloc_len + 1);  // '\0'-terminated |    201   char* result = zone->Alloc<char>(alloc_len + 1);  // '\0'-terminated | 
|    206   intptr_t pos = 0; |    202   intptr_t pos = 0; | 
|    207   for (intptr_t k = 0; k < segments.length(); k++) { |    203   for (intptr_t k = 0; k < segments.length(); k++) { | 
|    208     const char* piece = segments[k]; |    204     const char* piece = segments[k]; | 
|    209     const intptr_t piece_len = strlen(segments[k]); |    205     const intptr_t piece_len = strlen(segments[k]); | 
|    210     memmove(result + pos, piece, piece_len); |    206     memmove(result + pos, piece, piece_len); | 
|    211     pos += piece_len; |    207     pos += piece_len; | 
|    212     ASSERT(pos <= alloc_len); |    208     ASSERT(pos <= alloc_len); | 
|    213   } |    209   } | 
|    214   result[pos] = '\0'; |    210   result[pos] = '\0'; | 
|    215   return result; |    211   return result; | 
|    216 } |    212 } | 
|    217  |    213  | 
|    218  |  | 
|    219 // Remove private keys, but retain getter/setter/constructor/mixin manglings. |    214 // Remove private keys, but retain getter/setter/constructor/mixin manglings. | 
|    220 RawString* String::RemovePrivateKey(const String& name) { |    215 RawString* String::RemovePrivateKey(const String& name) { | 
|    221   ASSERT(name.IsOneByteString()); |    216   ASSERT(name.IsOneByteString()); | 
|    222   GrowableArray<uint8_t> without_key(name.Length()); |    217   GrowableArray<uint8_t> without_key(name.Length()); | 
|    223   intptr_t i = 0; |    218   intptr_t i = 0; | 
|    224   while (i < name.Length()) { |    219   while (i < name.Length()) { | 
|    225     while (i < name.Length()) { |    220     while (i < name.Length()) { | 
|    226       uint8_t c = name.CharAt(i++); |    221       uint8_t c = name.CharAt(i++); | 
|    227       if (c == '@') break; |    222       if (c == '@') break; | 
|    228       without_key.Add(c); |    223       without_key.Add(c); | 
|    229     } |    224     } | 
|    230     while (i < name.Length()) { |    225     while (i < name.Length()) { | 
|    231       uint8_t c = name.CharAt(i); |    226       uint8_t c = name.CharAt(i); | 
|    232       if ((c < '0') || (c > '9')) break; |    227       if ((c < '0') || (c > '9')) break; | 
|    233       i++; |    228       i++; | 
|    234     } |    229     } | 
|    235   } |    230   } | 
|    236  |    231  | 
|    237   return String::FromLatin1(without_key.data(), without_key.length()); |    232   return String::FromLatin1(without_key.data(), without_key.length()); | 
|    238 } |    233 } | 
|    239  |    234  | 
|    240  |  | 
|    241 // Takes a vm internal name and makes it suitable for external user. |    235 // Takes a vm internal name and makes it suitable for external user. | 
|    242 // |    236 // | 
|    243 // Examples: |    237 // Examples: | 
|    244 // |    238 // | 
|    245 // Internal getter and setter prefixes are changed: |    239 // Internal getter and setter prefixes are changed: | 
|    246 // |    240 // | 
|    247 //   get:foo -> foo |    241 //   get:foo -> foo | 
|    248 //   set:foo -> foo= |    242 //   set:foo -> foo= | 
|    249 // |    243 // | 
|    250 // Private name mangling is removed, possibly multiple times: |    244 // Private name mangling is removed, possibly multiple times: | 
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    364     AppendSubString(zone, &unmangled_segments, equals, 0, equals_len); |    358     AppendSubString(zone, &unmangled_segments, equals, 0, equals_len); | 
|    365     final_len += equals_len; |    359     final_len += equals_len; | 
|    366   } |    360   } | 
|    367  |    361  | 
|    368   unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len); |    362   unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len); | 
|    369 #endif  // !defined(PRODUCT) |    363 #endif  // !defined(PRODUCT) | 
|    370  |    364  | 
|    371   return Symbols::New(thread, unmangled_name); |    365   return Symbols::New(thread, unmangled_name); | 
|    372 } |    366 } | 
|    373  |    367  | 
|    374  |  | 
|    375 RawString* String::ScrubNameRetainPrivate(const String& name) { |    368 RawString* String::ScrubNameRetainPrivate(const String& name) { | 
|    376 #if !defined(PRODUCT) |    369 #if !defined(PRODUCT) | 
|    377   intptr_t len = name.Length(); |    370   intptr_t len = name.Length(); | 
|    378   intptr_t start = 0; |    371   intptr_t start = 0; | 
|    379   intptr_t at_pos = -1;  // Position of '@' in the name, if any. |    372   intptr_t at_pos = -1;  // Position of '@' in the name, if any. | 
|    380   bool is_setter = false; |    373   bool is_setter = false; | 
|    381  |    374  | 
|    382   for (intptr_t i = start; i < len; i++) { |    375   for (intptr_t i = start; i < len; i++) { | 
|    383     if (name.CharAt(i) == ':') { |    376     if (name.CharAt(i) == ':') { | 
|    384       ASSERT(start == 0);  // Only one : is possible in getters or setters. |    377       ASSERT(start == 0);  // Only one : is possible in getters or setters. | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|    413       result = String::Concat(pre_at, Symbols::Equals()); |    406       result = String::Concat(pre_at, Symbols::Equals()); | 
|    414       result = String::Concat(result, post_at); |    407       result = String::Concat(result, post_at); | 
|    415     } |    408     } | 
|    416   } |    409   } | 
|    417  |    410  | 
|    418   return result.raw(); |    411   return result.raw(); | 
|    419 #endif                // !defined(PRODUCT) |    412 #endif                // !defined(PRODUCT) | 
|    420   return name.raw();  // In PRODUCT, return argument unchanged. |    413   return name.raw();  // In PRODUCT, return argument unchanged. | 
|    421 } |    414 } | 
|    422  |    415  | 
|    423  |  | 
|    424 template <typename type> |    416 template <typename type> | 
|    425 static bool IsSpecialCharacter(type value) { |    417 static bool IsSpecialCharacter(type value) { | 
|    426   return ((value == '"') || (value == '\n') || (value == '\f') || |    418   return ((value == '"') || (value == '\n') || (value == '\f') || | 
|    427           (value == '\b') || (value == '\t') || (value == '\v') || |    419           (value == '\b') || (value == '\t') || (value == '\v') || | 
|    428           (value == '\r') || (value == '\\') || (value == '$')); |    420           (value == '\r') || (value == '\\') || (value == '$')); | 
|    429 } |    421 } | 
|    430  |    422  | 
|    431  |  | 
|    432 static inline bool IsAsciiNonprintable(int32_t c) { |    423 static inline bool IsAsciiNonprintable(int32_t c) { | 
|    433   return ((0 <= c) && (c < 32)) || (c == 127); |    424   return ((0 <= c) && (c < 32)) || (c == 127); | 
|    434 } |    425 } | 
|    435  |    426  | 
|    436  |  | 
|    437 static inline bool NeedsEscapeSequence(int32_t c) { |    427 static inline bool NeedsEscapeSequence(int32_t c) { | 
|    438   return (c == '"') || (c == '\\') || (c == '$') || IsAsciiNonprintable(c); |    428   return (c == '"') || (c == '\\') || (c == '$') || IsAsciiNonprintable(c); | 
|    439 } |    429 } | 
|    440  |    430  | 
|    441  |  | 
|    442 static int32_t EscapeOverhead(int32_t c) { |    431 static int32_t EscapeOverhead(int32_t c) { | 
|    443   if (IsSpecialCharacter(c)) { |    432   if (IsSpecialCharacter(c)) { | 
|    444     return 1;  // 1 additional byte for the backslash. |    433     return 1;  // 1 additional byte for the backslash. | 
|    445   } else if (IsAsciiNonprintable(c)) { |    434   } else if (IsAsciiNonprintable(c)) { | 
|    446     return 3;  // 3 additional bytes to encode c as \x00. |    435     return 3;  // 3 additional bytes to encode c as \x00. | 
|    447   } |    436   } | 
|    448   return 0; |    437   return 0; | 
|    449 } |    438 } | 
|    450  |    439  | 
|    451  |  | 
|    452 template <typename type> |    440 template <typename type> | 
|    453 static type SpecialCharacter(type value) { |    441 static type SpecialCharacter(type value) { | 
|    454   if (value == '"') { |    442   if (value == '"') { | 
|    455     return '"'; |    443     return '"'; | 
|    456   } else if (value == '\n') { |    444   } else if (value == '\n') { | 
|    457     return 'n'; |    445     return 'n'; | 
|    458   } else if (value == '\f') { |    446   } else if (value == '\f') { | 
|    459     return 'f'; |    447     return 'f'; | 
|    460   } else if (value == '\b') { |    448   } else if (value == '\b') { | 
|    461     return 'b'; |    449     return 'b'; | 
|    462   } else if (value == '\t') { |    450   } else if (value == '\t') { | 
|    463     return 't'; |    451     return 't'; | 
|    464   } else if (value == '\v') { |    452   } else if (value == '\v') { | 
|    465     return 'v'; |    453     return 'v'; | 
|    466   } else if (value == '\r') { |    454   } else if (value == '\r') { | 
|    467     return 'r'; |    455     return 'r'; | 
|    468   } else if (value == '\\') { |    456   } else if (value == '\\') { | 
|    469     return '\\'; |    457     return '\\'; | 
|    470   } else if (value == '$') { |    458   } else if (value == '$') { | 
|    471     return '$'; |    459     return '$'; | 
|    472   } |    460   } | 
|    473   UNREACHABLE(); |    461   UNREACHABLE(); | 
|    474   return '\0'; |    462   return '\0'; | 
|    475 } |    463 } | 
|    476  |    464  | 
|    477  |  | 
|    478 void Object::InitNull(Isolate* isolate) { |    465 void Object::InitNull(Isolate* isolate) { | 
|    479   // Should only be run by the vm isolate. |    466   // Should only be run by the vm isolate. | 
|    480   ASSERT(isolate == Dart::vm_isolate()); |    467   ASSERT(isolate == Dart::vm_isolate()); | 
|    481  |    468  | 
|    482   // TODO(iposva): NoSafepointScope needs to be added here. |    469   // TODO(iposva): NoSafepointScope needs to be added here. | 
|    483   ASSERT(class_class() == null_); |    470   ASSERT(class_class() == null_); | 
|    484  |    471  | 
|    485   Heap* heap = isolate->heap(); |    472   Heap* heap = isolate->heap(); | 
|    486  |    473  | 
|    487   // Allocate and initialize the null instance. |    474   // Allocate and initialize the null instance. | 
|    488   // 'null_' must be the first object allocated as it is used in allocation to |    475   // 'null_' must be the first object allocated as it is used in allocation to | 
|    489   // clear the object. |    476   // clear the object. | 
|    490   { |    477   { | 
|    491     uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); |    478     uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld); | 
|    492     null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); |    479     null_ = reinterpret_cast<RawInstance*>(address + kHeapObjectTag); | 
|    493     // The call below is using 'null_' to initialize itself. |    480     // The call below is using 'null_' to initialize itself. | 
|    494     InitializeObject(address, kNullCid, Instance::InstanceSize(), true); |    481     InitializeObject(address, kNullCid, Instance::InstanceSize(), true); | 
|    495   } |    482   } | 
|    496 } |    483 } | 
|    497  |    484  | 
|    498  |  | 
|    499 void Object::InitOnce(Isolate* isolate) { |    485 void Object::InitOnce(Isolate* isolate) { | 
|    500   // Should only be run by the vm isolate. |    486   // Should only be run by the vm isolate. | 
|    501   ASSERT(isolate == Dart::vm_isolate()); |    487   ASSERT(isolate == Dart::vm_isolate()); | 
|    502  |    488  | 
|    503   // Initialize the static vtable values. |    489   // Initialize the static vtable values. | 
|    504   { |    490   { | 
|    505     Object fake_object; |    491     Object fake_object; | 
|    506     Smi fake_smi; |    492     Smi fake_smi; | 
|    507     Object::handle_vtable_ = fake_object.vtable(); |    493     Object::handle_vtable_ = fake_object.vtable(); | 
|    508     Smi::handle_vtable_ = fake_smi.vtable(); |    494     Smi::handle_vtable_ = fake_smi.vtable(); | 
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    983   ASSERT(!branch_offset_error_->IsSmi()); |    969   ASSERT(!branch_offset_error_->IsSmi()); | 
|    984   ASSERT(branch_offset_error_->IsLanguageError()); |    970   ASSERT(branch_offset_error_->IsLanguageError()); | 
|    985   ASSERT(!speculative_inlining_error_->IsSmi()); |    971   ASSERT(!speculative_inlining_error_->IsSmi()); | 
|    986   ASSERT(speculative_inlining_error_->IsLanguageError()); |    972   ASSERT(speculative_inlining_error_->IsLanguageError()); | 
|    987   ASSERT(!background_compilation_error_->IsSmi()); |    973   ASSERT(!background_compilation_error_->IsSmi()); | 
|    988   ASSERT(background_compilation_error_->IsLanguageError()); |    974   ASSERT(background_compilation_error_->IsLanguageError()); | 
|    989   ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); |    975   ASSERT(!vm_isolate_snapshot_object_table_->IsSmi()); | 
|    990   ASSERT(vm_isolate_snapshot_object_table_->IsArray()); |    976   ASSERT(vm_isolate_snapshot_object_table_->IsArray()); | 
|    991 } |    977 } | 
|    992  |    978  | 
|    993  |  | 
|    994 // An object visitor which will mark all visited objects. This is used to |    979 // An object visitor which will mark all visited objects. This is used to | 
|    995 // premark all objects in the vm_isolate_ heap.  Also precalculates hash |    980 // premark all objects in the vm_isolate_ heap.  Also precalculates hash | 
|    996 // codes so that we can get the identity hash code of objects in the read- |    981 // codes so that we can get the identity hash code of objects in the read- | 
|    997 // only VM isolate. |    982 // only VM isolate. | 
|    998 class FinalizeVMIsolateVisitor : public ObjectVisitor { |    983 class FinalizeVMIsolateVisitor : public ObjectVisitor { | 
|    999  public: |    984  public: | 
|   1000   FinalizeVMIsolateVisitor() |    985   FinalizeVMIsolateVisitor() | 
|   1001 #if defined(HASH_IN_OBJECT_HEADER) |    986 #if defined(HASH_IN_OBJECT_HEADER) | 
|   1002       : counter_(1337) |    987       : counter_(1337) | 
|   1003 #endif |    988 #endif | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1036 #endif |   1021 #endif | 
|   1037     } |   1022     } | 
|   1038   } |   1023   } | 
|   1039  |   1024  | 
|   1040  private: |   1025  private: | 
|   1041 #if defined(HASH_IN_OBJECT_HEADER) |   1026 #if defined(HASH_IN_OBJECT_HEADER) | 
|   1042   int32_t counter_; |   1027   int32_t counter_; | 
|   1043 #endif |   1028 #endif | 
|   1044 }; |   1029 }; | 
|   1045  |   1030  | 
|   1046  |  | 
|   1047 #define SET_CLASS_NAME(class_name, name)                                       \ |   1031 #define SET_CLASS_NAME(class_name, name)                                       \ | 
|   1048   cls = class_name##_class();                                                  \ |   1032   cls = class_name##_class();                                                  \ | 
|   1049   cls.set_name(Symbols::name()); |   1033   cls.set_name(Symbols::name()); | 
|   1050  |   1034  | 
|   1051 void Object::FinalizeVMIsolate(Isolate* isolate) { |   1035 void Object::FinalizeVMIsolate(Isolate* isolate) { | 
|   1052   // Should only be run by the vm isolate. |   1036   // Should only be run by the vm isolate. | 
|   1053   ASSERT(isolate == Dart::vm_isolate()); |   1037   ASSERT(isolate == Dart::vm_isolate()); | 
|   1054  |   1038  | 
|   1055   // Allocate the parameter arrays for method extractor types and names. |   1039   // Allocate the parameter arrays for method extractor types and names. | 
|   1056   *extractor_parameter_types_ = Array::New(1, Heap::kOld); |   1040   *extractor_parameter_types_ = Array::New(1, Heap::kOld); | 
|   1057   extractor_parameter_types_->SetAt(0, Object::dynamic_type()); |   1041   extractor_parameter_types_->SetAt(0, Object::dynamic_type()); | 
|   1058   *extractor_parameter_names_ = Array::New(1, Heap::kOld); |   1042   *extractor_parameter_names_ = Array::New(1, Heap::kOld); | 
|   1059   extractor_parameter_names_->SetAt(0, Symbols::This()); |   1043   extractor_parameter_names_->SetAt(0, Symbols::This()); | 
|   1060  |   1044  | 
|   1061   ASSERT(!extractor_parameter_types_->IsSmi()); |   1045   ASSERT(!extractor_parameter_types_->IsSmi()); | 
|   1062   ASSERT(extractor_parameter_types_->IsArray()); |   1046   ASSERT(extractor_parameter_types_->IsArray()); | 
|   1063   ASSERT(!extractor_parameter_names_->IsSmi()); |   1047   ASSERT(!extractor_parameter_names_->IsSmi()); | 
|   1064   ASSERT(extractor_parameter_names_->IsArray()); |   1048   ASSERT(extractor_parameter_names_->IsArray()); | 
|   1065  |   1049  | 
|   1066  |  | 
|   1067   // Set up names for all VM singleton classes. |   1050   // Set up names for all VM singleton classes. | 
|   1068   Class& cls = Class::Handle(); |   1051   Class& cls = Class::Handle(); | 
|   1069  |   1052  | 
|   1070   SET_CLASS_NAME(class, Class); |   1053   SET_CLASS_NAME(class, Class); | 
|   1071   SET_CLASS_NAME(dynamic, Dynamic); |   1054   SET_CLASS_NAME(dynamic, Dynamic); | 
|   1072   SET_CLASS_NAME(void, Void); |   1055   SET_CLASS_NAME(void, Void); | 
|   1073   SET_CLASS_NAME(unresolved_class, UnresolvedClass); |   1056   SET_CLASS_NAME(unresolved_class, UnresolvedClass); | 
|   1074   SET_CLASS_NAME(type_arguments, TypeArguments); |   1057   SET_CLASS_NAME(type_arguments, TypeArguments); | 
|   1075   SET_CLASS_NAME(patch_class, PatchClass); |   1058   SET_CLASS_NAME(patch_class, PatchClass); | 
|   1076   SET_CLASS_NAME(function, Function); |   1059   SET_CLASS_NAME(function, Function); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1121     ASSERT(isolate == Dart::vm_isolate()); |   1104     ASSERT(isolate == Dart::vm_isolate()); | 
|   1122     WritableVMIsolateScope scope(Thread::Current()); |   1105     WritableVMIsolateScope scope(Thread::Current()); | 
|   1123     FinalizeVMIsolateVisitor premarker; |   1106     FinalizeVMIsolateVisitor premarker; | 
|   1124     ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); |   1107     ASSERT(isolate->heap()->UsedInWords(Heap::kNew) == 0); | 
|   1125     isolate->heap()->IterateOldObjectsNoImagePages(&premarker); |   1108     isolate->heap()->IterateOldObjectsNoImagePages(&premarker); | 
|   1126     // Make the VM isolate read-only again after setting all objects as marked. |   1109     // Make the VM isolate read-only again after setting all objects as marked. | 
|   1127     // Note objects in image pages are already pre-marked. |   1110     // Note objects in image pages are already pre-marked. | 
|   1128   } |   1111   } | 
|   1129 } |   1112 } | 
|   1130  |   1113  | 
|   1131  |  | 
|   1132 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { |   1114 void Object::set_vm_isolate_snapshot_object_table(const Array& table) { | 
|   1133   ASSERT(Isolate::Current() == Dart::vm_isolate()); |   1115   ASSERT(Isolate::Current() == Dart::vm_isolate()); | 
|   1134   *vm_isolate_snapshot_object_table_ = table.raw(); |   1116   *vm_isolate_snapshot_object_table_ = table.raw(); | 
|   1135 } |   1117 } | 
|   1136  |   1118  | 
|   1137  |  | 
|   1138 // Make unused space in an object whose type has been transformed safe |   1119 // Make unused space in an object whose type has been transformed safe | 
|   1139 // for traversing during GC. |   1120 // for traversing during GC. | 
|   1140 // The unused part of the transformed object is marked as an TypedDataInt8Array |   1121 // The unused part of the transformed object is marked as an TypedDataInt8Array | 
|   1141 // object. |   1122 // object. | 
|   1142 void Object::MakeUnusedSpaceTraversable(const Object& obj, |   1123 void Object::MakeUnusedSpaceTraversable(const Object& obj, | 
|   1143                                         intptr_t original_size, |   1124                                         intptr_t original_size, | 
|   1144                                         intptr_t used_size) { |   1125                                         intptr_t used_size) { | 
|   1145   ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |   1126   ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); | 
|   1146   ASSERT(!obj.IsNull()); |   1127   ASSERT(!obj.IsNull()); | 
|   1147   ASSERT(original_size >= used_size); |   1128   ASSERT(original_size >= used_size); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1179       uint32_t old_tags; |   1160       uint32_t old_tags; | 
|   1180       // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. |   1161       // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. | 
|   1181       do { |   1162       do { | 
|   1182         old_tags = tags; |   1163         old_tags = tags; | 
|   1183         tags = obj.CompareAndSwapTags(old_tags, new_tags); |   1164         tags = obj.CompareAndSwapTags(old_tags, new_tags); | 
|   1184       } while (tags != old_tags); |   1165       } while (tags != old_tags); | 
|   1185     } |   1166     } | 
|   1186   } |   1167   } | 
|   1187 } |   1168 } | 
|   1188  |   1169  | 
|   1189  |  | 
|   1190 void Object::VerifyBuiltinVtables() { |   1170 void Object::VerifyBuiltinVtables() { | 
|   1191 #if defined(DEBUG) |   1171 #if defined(DEBUG) | 
|   1192   Thread* thread = Thread::Current(); |   1172   Thread* thread = Thread::Current(); | 
|   1193   Isolate* isolate = thread->isolate(); |   1173   Isolate* isolate = thread->isolate(); | 
|   1194   Class& cls = Class::Handle(thread->zone(), Class::null()); |   1174   Class& cls = Class::Handle(thread->zone(), Class::null()); | 
|   1195   for (intptr_t cid = (kIllegalCid + 1); cid < kNumPredefinedCids; cid++) { |   1175   for (intptr_t cid = (kIllegalCid + 1); cid < kNumPredefinedCids; cid++) { | 
|   1196     if (isolate->class_table()->HasValidClassAt(cid)) { |   1176     if (isolate->class_table()->HasValidClassAt(cid)) { | 
|   1197       cls ^= isolate->class_table()->At(cid); |   1177       cls ^= isolate->class_table()->At(cid); | 
|   1198       ASSERT(builtin_vtables_[cid] == cls.raw_ptr()->handle_vtable_); |   1178       ASSERT(builtin_vtables_[cid] == cls.raw_ptr()->handle_vtable_); | 
|   1199     } |   1179     } | 
|   1200   } |   1180   } | 
|   1201   ASSERT(builtin_vtables_[kFreeListElement] == 0); |   1181   ASSERT(builtin_vtables_[kFreeListElement] == 0); | 
|   1202   ASSERT(builtin_vtables_[kForwardingCorpse] == 0); |   1182   ASSERT(builtin_vtables_[kForwardingCorpse] == 0); | 
|   1203 #endif |   1183 #endif | 
|   1204 } |   1184 } | 
|   1205  |   1185  | 
|   1206  |  | 
|   1207 void Object::RegisterClass(const Class& cls, |   1186 void Object::RegisterClass(const Class& cls, | 
|   1208                            const String& name, |   1187                            const String& name, | 
|   1209                            const Library& lib) { |   1188                            const Library& lib) { | 
|   1210   ASSERT(name.Length() > 0); |   1189   ASSERT(name.Length() > 0); | 
|   1211   ASSERT(name.CharAt(0) != '_'); |   1190   ASSERT(name.CharAt(0) != '_'); | 
|   1212   cls.set_name(name); |   1191   cls.set_name(name); | 
|   1213   lib.AddClass(cls); |   1192   lib.AddClass(cls); | 
|   1214 } |   1193 } | 
|   1215  |   1194  | 
|   1216  |  | 
|   1217 void Object::RegisterPrivateClass(const Class& cls, |   1195 void Object::RegisterPrivateClass(const Class& cls, | 
|   1218                                   const String& public_class_name, |   1196                                   const String& public_class_name, | 
|   1219                                   const Library& lib) { |   1197                                   const Library& lib) { | 
|   1220   ASSERT(public_class_name.Length() > 0); |   1198   ASSERT(public_class_name.Length() > 0); | 
|   1221   ASSERT(public_class_name.CharAt(0) == '_'); |   1199   ASSERT(public_class_name.CharAt(0) == '_'); | 
|   1222   String& str = String::Handle(); |   1200   String& str = String::Handle(); | 
|   1223   str = lib.PrivateName(public_class_name); |   1201   str = lib.PrivateName(public_class_name); | 
|   1224   cls.set_name(str); |   1202   cls.set_name(str); | 
|   1225   lib.AddClass(cls); |   1203   lib.AddClass(cls); | 
|   1226 } |   1204 } | 
|   1227  |   1205  | 
|   1228  |  | 
|   1229 // Initialize a new isolate from source or from a snapshot. |   1206 // Initialize a new isolate from source or from a snapshot. | 
|   1230 // |   1207 // | 
|   1231 // There are three possibilities: |   1208 // There are three possibilities: | 
|   1232 //   1. Running a Kernel binary.  This function will bootstrap from the KERNEL |   1209 //   1. Running a Kernel binary.  This function will bootstrap from the KERNEL | 
|   1233 //      file. |   1210 //      file. | 
|   1234 //   2. There is no snapshot.  This function will bootstrap from source. |   1211 //   2. There is no snapshot.  This function will bootstrap from source. | 
|   1235 //   3. There is a snapshot.  The caller should initialize from the snapshot. |   1212 //   3. There is a snapshot.  The caller should initialize from the snapshot. | 
|   1236 // |   1213 // | 
|   1237 // A non-NULL kernel argument indicates (1).  A NULL kernel indicates (2) or |   1214 // A non-NULL kernel argument indicates (1).  A NULL kernel indicates (2) or | 
|   1238 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or |   1215 // (3), depending on whether the VM is compiled with DART_NO_SNAPSHOT defined or | 
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1860  |   1837  | 
|   1861     cls = Class::New<WeakProperty>(); |   1838     cls = Class::New<WeakProperty>(); | 
|   1862     object_store->set_weak_property_class(cls); |   1839     object_store->set_weak_property_class(cls); | 
|   1863  |   1840  | 
|   1864     cls = Class::New<MirrorReference>(); |   1841     cls = Class::New<MirrorReference>(); | 
|   1865     cls = Class::New<UserTag>(); |   1842     cls = Class::New<UserTag>(); | 
|   1866   } |   1843   } | 
|   1867   return Error::null(); |   1844   return Error::null(); | 
|   1868 } |   1845 } | 
|   1869  |   1846  | 
|   1870  |  | 
|   1871 #if defined(DEBUG) |   1847 #if defined(DEBUG) | 
|   1872 bool Object::InVMHeap() const { |   1848 bool Object::InVMHeap() const { | 
|   1873   if (FLAG_verify_handles && raw()->IsVMHeapObject()) { |   1849   if (FLAG_verify_handles && raw()->IsVMHeapObject()) { | 
|   1874     Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); |   1850     Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); | 
|   1875     ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw()))); |   1851     ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw()))); | 
|   1876   } |   1852   } | 
|   1877   return raw()->IsVMHeapObject(); |   1853   return raw()->IsVMHeapObject(); | 
|   1878 } |   1854 } | 
|   1879 #endif  // DEBUG |   1855 #endif  // DEBUG | 
|   1880  |   1856  | 
|   1881  |  | 
|   1882 void Object::Print() const { |   1857 void Object::Print() const { | 
|   1883   THR_Print("%s\n", ToCString()); |   1858   THR_Print("%s\n", ToCString()); | 
|   1884 } |   1859 } | 
|   1885  |   1860  | 
|   1886  |  | 
|   1887 RawString* Object::DictionaryName() const { |   1861 RawString* Object::DictionaryName() const { | 
|   1888   return String::null(); |   1862   return String::null(); | 
|   1889 } |   1863 } | 
|   1890  |   1864  | 
|   1891  |  | 
|   1892 void Object::InitializeObject(uword address, |   1865 void Object::InitializeObject(uword address, | 
|   1893                               intptr_t class_id, |   1866                               intptr_t class_id, | 
|   1894                               intptr_t size, |   1867                               intptr_t size, | 
|   1895                               bool is_vm_object) { |   1868                               bool is_vm_object) { | 
|   1896   uword initial_value = (class_id == kInstructionsCid) |   1869   uword initial_value = (class_id == kInstructionsCid) | 
|   1897                             ? Assembler::GetBreakInstructionFiller() |   1870                             ? Assembler::GetBreakInstructionFiller() | 
|   1898                             : reinterpret_cast<uword>(null_); |   1871                             : reinterpret_cast<uword>(null_); | 
|   1899   uword cur = address; |   1872   uword cur = address; | 
|   1900   uword end = address + size; |   1873   uword end = address + size; | 
|   1901   while (cur < end) { |   1874   while (cur < end) { | 
|   1902     *reinterpret_cast<uword*>(cur) = initial_value; |   1875     *reinterpret_cast<uword*>(cur) = initial_value; | 
|   1903     cur += kWordSize; |   1876     cur += kWordSize; | 
|   1904   } |   1877   } | 
|   1905   uint32_t tags = 0; |   1878   uint32_t tags = 0; | 
|   1906   ASSERT(class_id != kIllegalCid); |   1879   ASSERT(class_id != kIllegalCid); | 
|   1907   tags = RawObject::ClassIdTag::update(class_id, tags); |   1880   tags = RawObject::ClassIdTag::update(class_id, tags); | 
|   1908   tags = RawObject::SizeTag::update(size, tags); |   1881   tags = RawObject::SizeTag::update(size, tags); | 
|   1909   tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); |   1882   tags = RawObject::VMHeapObjectTag::update(is_vm_object, tags); | 
|   1910   reinterpret_cast<RawObject*>(address)->tags_ = tags; |   1883   reinterpret_cast<RawObject*>(address)->tags_ = tags; | 
|   1911 #if defined(HASH_IN_OBJECT_HEADER) |   1884 #if defined(HASH_IN_OBJECT_HEADER) | 
|   1912   reinterpret_cast<RawObject*>(address)->hash_ = 0; |   1885   reinterpret_cast<RawObject*>(address)->hash_ = 0; | 
|   1913 #endif |   1886 #endif | 
|   1914   ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); |   1887   ASSERT(is_vm_object == RawObject::IsVMHeapObject(tags)); | 
|   1915 } |   1888 } | 
|   1916  |   1889  | 
|   1917  |  | 
|   1918 void Object::CheckHandle() const { |   1890 void Object::CheckHandle() const { | 
|   1919 #if defined(DEBUG) |   1891 #if defined(DEBUG) | 
|   1920   if (raw_ != Object::null()) { |   1892   if (raw_ != Object::null()) { | 
|   1921     if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { |   1893     if ((reinterpret_cast<uword>(raw_) & kSmiTagMask) == kSmiTag) { | 
|   1922       ASSERT(vtable() == Smi::handle_vtable_); |   1894       ASSERT(vtable() == Smi::handle_vtable_); | 
|   1923       return; |   1895       return; | 
|   1924     } |   1896     } | 
|   1925     intptr_t cid = raw_->GetClassId(); |   1897     intptr_t cid = raw_->GetClassId(); | 
|   1926     if (cid >= kNumPredefinedCids) { |   1898     if (cid >= kNumPredefinedCids) { | 
|   1927       cid = kInstanceCid; |   1899       cid = kInstanceCid; | 
|   1928     } |   1900     } | 
|   1929     ASSERT(vtable() == builtin_vtables_[cid]); |   1901     ASSERT(vtable() == builtin_vtables_[cid]); | 
|   1930     if (FLAG_verify_handles) { |   1902     if (FLAG_verify_handles) { | 
|   1931       Isolate* isolate = Isolate::Current(); |   1903       Isolate* isolate = Isolate::Current(); | 
|   1932       Heap* isolate_heap = isolate->heap(); |   1904       Heap* isolate_heap = isolate->heap(); | 
|   1933       Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); |   1905       Heap* vm_isolate_heap = Dart::vm_isolate()->heap(); | 
|   1934       ASSERT(isolate_heap->Contains(RawObject::ToAddr(raw_)) || |   1906       ASSERT(isolate_heap->Contains(RawObject::ToAddr(raw_)) || | 
|   1935              vm_isolate_heap->Contains(RawObject::ToAddr(raw_))); |   1907              vm_isolate_heap->Contains(RawObject::ToAddr(raw_))); | 
|   1936     } |   1908     } | 
|   1937   } |   1909   } | 
|   1938 #endif |   1910 #endif | 
|   1939 } |   1911 } | 
|   1940  |   1912  | 
|   1941  |  | 
|   1942 RawObject* Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) { |   1913 RawObject* Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) { | 
|   1943   ASSERT(Utils::IsAligned(size, kObjectAlignment)); |   1914   ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 
|   1944   Thread* thread = Thread::Current(); |   1915   Thread* thread = Thread::Current(); | 
|   1945   Isolate* isolate = thread->isolate(); |   1916   Isolate* isolate = thread->isolate(); | 
|   1946   // New space allocation allowed only in mutator thread (Dart thread); |   1917   // New space allocation allowed only in mutator thread (Dart thread); | 
|   1947   ASSERT(thread->IsMutatorThread() || (space != Heap::kNew)); |   1918   ASSERT(thread->IsMutatorThread() || (space != Heap::kNew)); | 
|   1948   ASSERT(thread->no_callback_scope_depth() == 0); |   1919   ASSERT(thread->no_callback_scope_depth() == 0); | 
|   1949   Heap* heap = isolate->heap(); |   1920   Heap* heap = isolate->heap(); | 
|   1950  |   1921  | 
|   1951   uword address = heap->Allocate(size, space); |   1922   uword address = heap->Allocate(size, space); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|   1969     Profiler::SampleAllocation(thread, cls_id); |   1940     Profiler::SampleAllocation(thread, cls_id); | 
|   1970   } |   1941   } | 
|   1971 #endif  // !PRODUCT |   1942 #endif  // !PRODUCT | 
|   1972   NoSafepointScope no_safepoint; |   1943   NoSafepointScope no_safepoint; | 
|   1973   InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate())); |   1944   InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate())); | 
|   1974   RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |   1945   RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 
|   1975   ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); |   1946   ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); | 
|   1976   return raw_obj; |   1947   return raw_obj; | 
|   1977 } |   1948 } | 
|   1978  |   1949  | 
|   1979  |  | 
|   1980 class StoreBufferUpdateVisitor : public ObjectPointerVisitor { |   1950 class StoreBufferUpdateVisitor : public ObjectPointerVisitor { | 
|   1981  public: |   1951  public: | 
|   1982   explicit StoreBufferUpdateVisitor(Thread* thread, RawObject* obj) |   1952   explicit StoreBufferUpdateVisitor(Thread* thread, RawObject* obj) | 
|   1983       : ObjectPointerVisitor(thread->isolate()), |   1953       : ObjectPointerVisitor(thread->isolate()), | 
|   1984         thread_(thread), |   1954         thread_(thread), | 
|   1985         old_obj_(obj) { |   1955         old_obj_(obj) { | 
|   1986     ASSERT(old_obj_->IsOldObject()); |   1956     ASSERT(old_obj_->IsOldObject()); | 
|   1987   } |   1957   } | 
|   1988  |   1958  | 
|   1989   void VisitPointers(RawObject** first, RawObject** last) { |   1959   void VisitPointers(RawObject** first, RawObject** last) { | 
|   1990     for (RawObject** curr = first; curr <= last; ++curr) { |   1960     for (RawObject** curr = first; curr <= last; ++curr) { | 
|   1991       RawObject* raw_obj = *curr; |   1961       RawObject* raw_obj = *curr; | 
|   1992       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) { |   1962       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) { | 
|   1993         old_obj_->SetRememberedBit(); |   1963         old_obj_->SetRememberedBit(); | 
|   1994         thread_->StoreBufferAddObject(old_obj_); |   1964         thread_->StoreBufferAddObject(old_obj_); | 
|   1995         // Remembered this object. There is no need to continue searching. |   1965         // Remembered this object. There is no need to continue searching. | 
|   1996         return; |   1966         return; | 
|   1997       } |   1967       } | 
|   1998     } |   1968     } | 
|   1999   } |   1969   } | 
|   2000  |   1970  | 
|   2001  private: |   1971  private: | 
|   2002   Thread* thread_; |   1972   Thread* thread_; | 
|   2003   RawObject* old_obj_; |   1973   RawObject* old_obj_; | 
|   2004  |   1974  | 
|   2005   DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor); |   1975   DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor); | 
|   2006 }; |   1976 }; | 
|   2007  |   1977  | 
|   2008  |  | 
|   2009 bool Object::IsReadOnlyHandle() const { |   1978 bool Object::IsReadOnlyHandle() const { | 
|   2010   return Dart::IsReadOnlyHandle(reinterpret_cast<uword>(this)); |   1979   return Dart::IsReadOnlyHandle(reinterpret_cast<uword>(this)); | 
|   2011 } |   1980 } | 
|   2012  |   1981  | 
|   2013  |  | 
|   2014 bool Object::IsNotTemporaryScopedHandle() const { |   1982 bool Object::IsNotTemporaryScopedHandle() const { | 
|   2015   return (IsZoneHandle() || IsReadOnlyHandle()); |   1983   return (IsZoneHandle() || IsReadOnlyHandle()); | 
|   2016 } |   1984 } | 
|   2017  |   1985  | 
|   2018  |  | 
|   2019 RawObject* Object::Clone(const Object& orig, Heap::Space space) { |   1986 RawObject* Object::Clone(const Object& orig, Heap::Space space) { | 
|   2020   const Class& cls = Class::Handle(orig.clazz()); |   1987   const Class& cls = Class::Handle(orig.clazz()); | 
|   2021   intptr_t size = orig.raw()->Size(); |   1988   intptr_t size = orig.raw()->Size(); | 
|   2022   RawObject* raw_clone = Object::Allocate(cls.id(), size, space); |   1989   RawObject* raw_clone = Object::Allocate(cls.id(), size, space); | 
|   2023   NoSafepointScope no_safepoint; |   1990   NoSafepointScope no_safepoint; | 
|   2024   // TODO(koda): This will trip when we start allocating black. |   1991   // TODO(koda): This will trip when we start allocating black. | 
|   2025   // Revisit code below at that point, to account for the new write barrier. |   1992   // Revisit code below at that point, to account for the new write barrier. | 
|   2026   ASSERT(!raw_clone->IsMarked()); |   1993   ASSERT(!raw_clone->IsMarked()); | 
|   2027   // Copy the body of the original into the clone. |   1994   // Copy the body of the original into the clone. | 
|   2028   uword orig_addr = RawObject::ToAddr(orig.raw()); |   1995   uword orig_addr = RawObject::ToAddr(orig.raw()); | 
|   2029   uword clone_addr = RawObject::ToAddr(raw_clone); |   1996   uword clone_addr = RawObject::ToAddr(raw_clone); | 
|   2030   static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); |   1997   static const intptr_t kHeaderSizeInBytes = sizeof(RawObject); | 
|   2031   memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), |   1998   memmove(reinterpret_cast<uint8_t*>(clone_addr + kHeaderSizeInBytes), | 
|   2032           reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), |   1999           reinterpret_cast<uint8_t*>(orig_addr + kHeaderSizeInBytes), | 
|   2033           size - kHeaderSizeInBytes); |   2000           size - kHeaderSizeInBytes); | 
|   2034   // Add clone to store buffer, if needed. |   2001   // Add clone to store buffer, if needed. | 
|   2035   if (!raw_clone->IsOldObject()) { |   2002   if (!raw_clone->IsOldObject()) { | 
|   2036     // No need to remember an object in new space. |   2003     // No need to remember an object in new space. | 
|   2037     return raw_clone; |   2004     return raw_clone; | 
|   2038   } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { |   2005   } else if (orig.raw()->IsOldObject() && !orig.raw()->IsRemembered()) { | 
|   2039     // Old original doesn't need to be remembered, so neither does the clone. |   2006     // Old original doesn't need to be remembered, so neither does the clone. | 
|   2040     return raw_clone; |   2007     return raw_clone; | 
|   2041   } |   2008   } | 
|   2042   StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); |   2009   StoreBufferUpdateVisitor visitor(Thread::Current(), raw_clone); | 
|   2043   raw_clone->VisitPointers(&visitor); |   2010   raw_clone->VisitPointers(&visitor); | 
|   2044   return raw_clone; |   2011   return raw_clone; | 
|   2045 } |   2012 } | 
|   2046  |   2013  | 
|   2047  |  | 
|   2048 RawString* Class::Name() const { |   2014 RawString* Class::Name() const { | 
|   2049   return raw_ptr()->name_; |   2015   return raw_ptr()->name_; | 
|   2050 } |   2016 } | 
|   2051  |   2017  | 
|   2052  |  | 
|   2053 RawString* Class::ScrubbedName() const { |   2018 RawString* Class::ScrubbedName() const { | 
|   2054   return String::ScrubName(String::Handle(Name())); |   2019   return String::ScrubName(String::Handle(Name())); | 
|   2055 } |   2020 } | 
|   2056  |   2021  | 
|   2057  |  | 
|   2058 RawString* Class::UserVisibleName() const { |   2022 RawString* Class::UserVisibleName() const { | 
|   2059 #if !defined(PRODUCT) |   2023 #if !defined(PRODUCT) | 
|   2060   ASSERT(raw_ptr()->user_name_ != String::null()); |   2024   ASSERT(raw_ptr()->user_name_ != String::null()); | 
|   2061   return raw_ptr()->user_name_; |   2025   return raw_ptr()->user_name_; | 
|   2062 #endif                               // !defined(PRODUCT) |   2026 #endif                               // !defined(PRODUCT) | 
|   2063   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate. |   2027   return GenerateUserVisibleName();  // No caching in PRODUCT, regenerate. | 
|   2064 } |   2028 } | 
|   2065  |   2029  | 
|   2066  |  | 
|   2067 bool Class::IsInFullSnapshot() const { |   2030 bool Class::IsInFullSnapshot() const { | 
|   2068   NoSafepointScope no_safepoint; |   2031   NoSafepointScope no_safepoint; | 
|   2069   return raw_ptr()->library_->ptr()->is_in_fullsnapshot_; |   2032   return raw_ptr()->library_->ptr()->is_in_fullsnapshot_; | 
|   2070 } |   2033 } | 
|   2071  |   2034  | 
|   2072  |  | 
|   2073 RawAbstractType* Class::RareType() const { |   2035 RawAbstractType* Class::RareType() const { | 
|   2074   const Type& type = Type::Handle(Type::New( |   2036   const Type& type = Type::Handle(Type::New( | 
|   2075       *this, Object::null_type_arguments(), TokenPosition::kNoSource)); |   2037       *this, Object::null_type_arguments(), TokenPosition::kNoSource)); | 
|   2076   return ClassFinalizer::FinalizeType(*this, type); |   2038   return ClassFinalizer::FinalizeType(*this, type); | 
|   2077 } |   2039 } | 
|   2078  |   2040  | 
|   2079  |  | 
|   2080 RawAbstractType* Class::DeclarationType() const { |   2041 RawAbstractType* Class::DeclarationType() const { | 
|   2081   const TypeArguments& args = TypeArguments::Handle(type_parameters()); |   2042   const TypeArguments& args = TypeArguments::Handle(type_parameters()); | 
|   2082   const Type& type = |   2043   const Type& type = | 
|   2083       Type::Handle(Type::New(*this, args, TokenPosition::kNoSource)); |   2044       Type::Handle(Type::New(*this, args, TokenPosition::kNoSource)); | 
|   2084   return ClassFinalizer::FinalizeType(*this, type); |   2045   return ClassFinalizer::FinalizeType(*this, type); | 
|   2085 } |   2046 } | 
|   2086  |   2047  | 
|   2087  |  | 
|   2088 template <class FakeObject> |   2048 template <class FakeObject> | 
|   2089 RawClass* Class::New() { |   2049 RawClass* Class::New() { | 
|   2090   ASSERT(Object::class_class() != Class::null()); |   2050   ASSERT(Object::class_class() != Class::null()); | 
|   2091   Class& result = Class::Handle(); |   2051   Class& result = Class::Handle(); | 
|   2092   { |   2052   { | 
|   2093     RawObject* raw = |   2053     RawObject* raw = | 
|   2094         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); |   2054         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); | 
|   2095     NoSafepointScope no_safepoint; |   2055     NoSafepointScope no_safepoint; | 
|   2096     result ^= raw; |   2056     result ^= raw; | 
|   2097   } |   2057   } | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|   2114   result.set_type_arguments_field_offset_in_words(kNoTypeArguments); |   2074   result.set_type_arguments_field_offset_in_words(kNoTypeArguments); | 
|   2115   result.set_num_type_arguments(0); |   2075   result.set_num_type_arguments(0); | 
|   2116   result.set_num_own_type_arguments(0); |   2076   result.set_num_own_type_arguments(0); | 
|   2117   result.set_num_native_fields(0); |   2077   result.set_num_native_fields(0); | 
|   2118   result.set_token_pos(TokenPosition::kNoSource); |   2078   result.set_token_pos(TokenPosition::kNoSource); | 
|   2119   result.InitEmptyFields(); |   2079   result.InitEmptyFields(); | 
|   2120   Isolate::Current()->RegisterClass(result); |   2080   Isolate::Current()->RegisterClass(result); | 
|   2121   return result.raw(); |   2081   return result.raw(); | 
|   2122 } |   2082 } | 
|   2123  |   2083  | 
|   2124  |  | 
|   2125 static void ReportTooManyTypeArguments(const Class& cls) { |   2084 static void ReportTooManyTypeArguments(const Class& cls) { | 
|   2126   Report::MessageF(Report::kError, Script::Handle(cls.script()), |   2085   Report::MessageF(Report::kError, Script::Handle(cls.script()), | 
|   2127                    cls.token_pos(), Report::AtLocation, |   2086                    cls.token_pos(), Report::AtLocation, | 
|   2128                    "too many type parameters declared in class '%s' or in its " |   2087                    "too many type parameters declared in class '%s' or in its " | 
|   2129                    "super classes", |   2088                    "super classes", | 
|   2130                    String::Handle(cls.Name()).ToCString()); |   2089                    String::Handle(cls.Name()).ToCString()); | 
|   2131   UNREACHABLE(); |   2090   UNREACHABLE(); | 
|   2132 } |   2091 } | 
|   2133  |   2092  | 
|   2134  |  | 
|   2135 void Class::set_num_type_arguments(intptr_t value) const { |   2093 void Class::set_num_type_arguments(intptr_t value) const { | 
|   2136   if (!Utils::IsInt(16, value)) { |   2094   if (!Utils::IsInt(16, value)) { | 
|   2137     ReportTooManyTypeArguments(*this); |   2095     ReportTooManyTypeArguments(*this); | 
|   2138   } |   2096   } | 
|   2139   StoreNonPointer(&raw_ptr()->num_type_arguments_, value); |   2097   StoreNonPointer(&raw_ptr()->num_type_arguments_, value); | 
|   2140 } |   2098 } | 
|   2141  |   2099  | 
|   2142  |  | 
|   2143 void Class::set_num_own_type_arguments(intptr_t value) const { |   2100 void Class::set_num_own_type_arguments(intptr_t value) const { | 
|   2144   if (!Utils::IsInt(16, value)) { |   2101   if (!Utils::IsInt(16, value)) { | 
|   2145     ReportTooManyTypeArguments(*this); |   2102     ReportTooManyTypeArguments(*this); | 
|   2146   } |   2103   } | 
|   2147   StoreNonPointer(&raw_ptr()->num_own_type_arguments_, value); |   2104   StoreNonPointer(&raw_ptr()->num_own_type_arguments_, value); | 
|   2148 } |   2105 } | 
|   2149  |   2106  | 
|   2150  |  | 
|   2151 // Initialize class fields of type Array with empty array. |   2107 // Initialize class fields of type Array with empty array. | 
|   2152 void Class::InitEmptyFields() { |   2108 void Class::InitEmptyFields() { | 
|   2153   if (Object::empty_array().raw() == Array::null()) { |   2109   if (Object::empty_array().raw() == Array::null()) { | 
|   2154     // The empty array has not been initialized yet. |   2110     // The empty array has not been initialized yet. | 
|   2155     return; |   2111     return; | 
|   2156   } |   2112   } | 
|   2157   StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); |   2113   StorePointer(&raw_ptr()->interfaces_, Object::empty_array().raw()); | 
|   2158   StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); |   2114   StorePointer(&raw_ptr()->constants_, Object::empty_array().raw()); | 
|   2159   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |   2115   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); | 
|   2160   StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); |   2116   StorePointer(&raw_ptr()->fields_, Object::empty_array().raw()); | 
|   2161   StorePointer(&raw_ptr()->invocation_dispatcher_cache_, |   2117   StorePointer(&raw_ptr()->invocation_dispatcher_cache_, | 
|   2162                Object::empty_array().raw()); |   2118                Object::empty_array().raw()); | 
|   2163 } |   2119 } | 
|   2164  |   2120  | 
|   2165  |  | 
|   2166 RawArray* Class::OffsetToFieldMap(bool original_classes) const { |   2121 RawArray* Class::OffsetToFieldMap(bool original_classes) const { | 
|   2167   Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); |   2122   Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_); | 
|   2168   if (array.IsNull()) { |   2123   if (array.IsNull()) { | 
|   2169     ASSERT(is_finalized()); |   2124     ASSERT(is_finalized()); | 
|   2170     const intptr_t length = raw_ptr()->instance_size_in_words_; |   2125     const intptr_t length = raw_ptr()->instance_size_in_words_; | 
|   2171     array = Array::New(length, Heap::kOld); |   2126     array = Array::New(length, Heap::kOld); | 
|   2172     Class& cls = Class::Handle(this->raw()); |   2127     Class& cls = Class::Handle(this->raw()); | 
|   2173     Array& fields = Array::Handle(); |   2128     Array& fields = Array::Handle(); | 
|   2174     Field& f = Field::Handle(); |   2129     Field& f = Field::Handle(); | 
|   2175     while (!cls.IsNull()) { |   2130     while (!cls.IsNull()) { | 
|   2176       fields = cls.fields(); |   2131       fields = cls.fields(); | 
|   2177       for (intptr_t i = 0; i < fields.Length(); ++i) { |   2132       for (intptr_t i = 0; i < fields.Length(); ++i) { | 
|   2178         f ^= fields.At(i); |   2133         f ^= fields.At(i); | 
|   2179         if (f.is_instance()) { |   2134         if (f.is_instance()) { | 
|   2180           array.SetAt(f.Offset() >> kWordSizeLog2, f); |   2135           array.SetAt(f.Offset() >> kWordSizeLog2, f); | 
|   2181         } |   2136         } | 
|   2182       } |   2137       } | 
|   2183       cls = cls.SuperClass(original_classes); |   2138       cls = cls.SuperClass(original_classes); | 
|   2184     } |   2139     } | 
|   2185     StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw()); |   2140     StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw()); | 
|   2186   } |   2141   } | 
|   2187   return array.raw(); |   2142   return array.raw(); | 
|   2188 } |   2143 } | 
|   2189  |   2144  | 
|   2190  |  | 
|   2191 bool Class::HasInstanceFields() const { |   2145 bool Class::HasInstanceFields() const { | 
|   2192   const Array& field_array = Array::Handle(fields()); |   2146   const Array& field_array = Array::Handle(fields()); | 
|   2193   Field& field = Field::Handle(); |   2147   Field& field = Field::Handle(); | 
|   2194   for (intptr_t i = 0; i < field_array.Length(); ++i) { |   2148   for (intptr_t i = 0; i < field_array.Length(); ++i) { | 
|   2195     field ^= field_array.At(i); |   2149     field ^= field_array.At(i); | 
|   2196     if (!field.is_static()) { |   2150     if (!field.is_static()) { | 
|   2197       return true; |   2151       return true; | 
|   2198     } |   2152     } | 
|   2199   } |   2153   } | 
|   2200   return false; |   2154   return false; | 
|   2201 } |   2155 } | 
|   2202  |   2156  | 
|   2203  |  | 
|   2204 class FunctionName { |   2157 class FunctionName { | 
|   2205  public: |   2158  public: | 
|   2206   FunctionName(const String& name, String* tmp_string) |   2159   FunctionName(const String& name, String* tmp_string) | 
|   2207       : name_(name), tmp_string_(tmp_string) {} |   2160       : name_(name), tmp_string_(tmp_string) {} | 
|   2208   bool Matches(const Function& function) const { |   2161   bool Matches(const Function& function) const { | 
|   2209     if (name_.IsSymbol()) { |   2162     if (name_.IsSymbol()) { | 
|   2210       return name_.raw() == function.name(); |   2163       return name_.raw() == function.name(); | 
|   2211     } else { |   2164     } else { | 
|   2212       *tmp_string_ = function.name(); |   2165       *tmp_string_ = function.name(); | 
|   2213       return name_.Equals(*tmp_string_); |   2166       return name_.Equals(*tmp_string_); | 
|   2214     } |   2167     } | 
|   2215   } |   2168   } | 
|   2216   intptr_t Hash() const { return name_.Hash(); } |   2169   intptr_t Hash() const { return name_.Hash(); } | 
|   2217  |   2170  | 
|   2218  private: |   2171  private: | 
|   2219   const String& name_; |   2172   const String& name_; | 
|   2220   String* tmp_string_; |   2173   String* tmp_string_; | 
|   2221 }; |   2174 }; | 
|   2222  |   2175  | 
|   2223  |  | 
|   2224 // Traits for looking up Functions by name. |   2176 // Traits for looking up Functions by name. | 
|   2225 class ClassFunctionsTraits { |   2177 class ClassFunctionsTraits { | 
|   2226  public: |   2178  public: | 
|   2227   static const char* Name() { return "ClassFunctionsTraits"; } |   2179   static const char* Name() { return "ClassFunctionsTraits"; } | 
|   2228   static bool ReportStats() { return false; } |   2180   static bool ReportStats() { return false; } | 
|   2229  |   2181  | 
|   2230   // Called when growing the table. |   2182   // Called when growing the table. | 
|   2231   static bool IsMatch(const Object& a, const Object& b) { |   2183   static bool IsMatch(const Object& a, const Object& b) { | 
|   2232     ASSERT(a.IsFunction() && b.IsFunction()); |   2184     ASSERT(a.IsFunction() && b.IsFunction()); | 
|   2233     // Function objects are always canonical. |   2185     // Function objects are always canonical. | 
|   2234     return a.raw() == b.raw(); |   2186     return a.raw() == b.raw(); | 
|   2235   } |   2187   } | 
|   2236   static bool IsMatch(const FunctionName& name, const Object& obj) { |   2188   static bool IsMatch(const FunctionName& name, const Object& obj) { | 
|   2237     return name.Matches(Function::Cast(obj)); |   2189     return name.Matches(Function::Cast(obj)); | 
|   2238   } |   2190   } | 
|   2239   static uword Hash(const Object& key) { |   2191   static uword Hash(const Object& key) { | 
|   2240     return String::HashRawSymbol(Function::Cast(key).name()); |   2192     return String::HashRawSymbol(Function::Cast(key).name()); | 
|   2241   } |   2193   } | 
|   2242   static uword Hash(const FunctionName& name) { return name.Hash(); } |   2194   static uword Hash(const FunctionName& name) { return name.Hash(); } | 
|   2243 }; |   2195 }; | 
|   2244 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; |   2196 typedef UnorderedHashSet<ClassFunctionsTraits> ClassFunctionsSet; | 
|   2245  |   2197  | 
|   2246  |  | 
|   2247 void Class::SetFunctions(const Array& value) const { |   2198 void Class::SetFunctions(const Array& value) const { | 
|   2248   ASSERT(Thread::Current()->IsMutatorThread()); |   2199   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   2249   ASSERT(!value.IsNull()); |   2200   ASSERT(!value.IsNull()); | 
|   2250   StorePointer(&raw_ptr()->functions_, value.raw()); |   2201   StorePointer(&raw_ptr()->functions_, value.raw()); | 
|   2251   const intptr_t len = value.Length(); |   2202   const intptr_t len = value.Length(); | 
|   2252   if (len >= kFunctionLookupHashTreshold) { |   2203   if (len >= kFunctionLookupHashTreshold) { | 
|   2253     ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld)); |   2204     ClassFunctionsSet set(HashTables::New<ClassFunctionsSet>(len, Heap::kOld)); | 
|   2254     Function& func = Function::Handle(); |   2205     Function& func = Function::Handle(); | 
|   2255     for (intptr_t i = 0; i < len; ++i) { |   2206     for (intptr_t i = 0; i < len; ++i) { | 
|   2256       func ^= value.At(i); |   2207       func ^= value.At(i); | 
|   2257       // Verify that all the functions in the array have this class as owner. |   2208       // Verify that all the functions in the array have this class as owner. | 
|   2258       ASSERT(func.Owner() == raw()); |   2209       ASSERT(func.Owner() == raw()); | 
|   2259       set.Insert(func); |   2210       set.Insert(func); | 
|   2260     } |   2211     } | 
|   2261     StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); |   2212     StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); | 
|   2262   } else { |   2213   } else { | 
|   2263     StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); |   2214     StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); | 
|   2264   } |   2215   } | 
|   2265 } |   2216 } | 
|   2266  |   2217  | 
|   2267  |  | 
|   2268 void Class::AddFunction(const Function& function) const { |   2218 void Class::AddFunction(const Function& function) const { | 
|   2269   ASSERT(Thread::Current()->IsMutatorThread()); |   2219   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   2270   const Array& arr = Array::Handle(functions()); |   2220   const Array& arr = Array::Handle(functions()); | 
|   2271   const Array& new_arr = |   2221   const Array& new_arr = | 
|   2272       Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); |   2222       Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld)); | 
|   2273   new_arr.SetAt(arr.Length(), function); |   2223   new_arr.SetAt(arr.Length(), function); | 
|   2274   StorePointer(&raw_ptr()->functions_, new_arr.raw()); |   2224   StorePointer(&raw_ptr()->functions_, new_arr.raw()); | 
|   2275   // Add to hash table, if any. |   2225   // Add to hash table, if any. | 
|   2276   const intptr_t new_len = new_arr.Length(); |   2226   const intptr_t new_len = new_arr.Length(); | 
|   2277   if (new_len == kFunctionLookupHashTreshold) { |   2227   if (new_len == kFunctionLookupHashTreshold) { | 
|   2278     // Transition to using hash table. |   2228     // Transition to using hash table. | 
|   2279     SetFunctions(new_arr); |   2229     SetFunctions(new_arr); | 
|   2280   } else if (new_len > kFunctionLookupHashTreshold) { |   2230   } else if (new_len > kFunctionLookupHashTreshold) { | 
|   2281     ClassFunctionsSet set(raw_ptr()->functions_hash_table_); |   2231     ClassFunctionsSet set(raw_ptr()->functions_hash_table_); | 
|   2282     set.Insert(function); |   2232     set.Insert(function); | 
|   2283     StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); |   2233     StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw()); | 
|   2284   } |   2234   } | 
|   2285 } |   2235 } | 
|   2286  |   2236  | 
|   2287  |  | 
|   2288 void Class::RemoveFunction(const Function& function) const { |   2237 void Class::RemoveFunction(const Function& function) const { | 
|   2289   ASSERT(Thread::Current()->IsMutatorThread()); |   2238   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   2290   const Array& arr = Array::Handle(functions()); |   2239   const Array& arr = Array::Handle(functions()); | 
|   2291   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); |   2240   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw()); | 
|   2292   StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); |   2241   StorePointer(&raw_ptr()->functions_hash_table_, Array::null()); | 
|   2293   Function& entry = Function::Handle(); |   2242   Function& entry = Function::Handle(); | 
|   2294   for (intptr_t i = 0; i < arr.Length(); i++) { |   2243   for (intptr_t i = 0; i < arr.Length(); i++) { | 
|   2295     entry ^= arr.At(i); |   2244     entry ^= arr.At(i); | 
|   2296     if (function.raw() != entry.raw()) { |   2245     if (function.raw() != entry.raw()) { | 
|   2297       AddFunction(entry); |   2246       AddFunction(entry); | 
|   2298     } |   2247     } | 
|   2299   } |   2248   } | 
|   2300 } |   2249 } | 
|   2301  |   2250  | 
|   2302  |  | 
|   2303 RawFunction* Class::FunctionFromIndex(intptr_t idx) const { |   2251 RawFunction* Class::FunctionFromIndex(intptr_t idx) const { | 
|   2304   const Array& funcs = Array::Handle(functions()); |   2252   const Array& funcs = Array::Handle(functions()); | 
|   2305   if ((idx < 0) || (idx >= funcs.Length())) { |   2253   if ((idx < 0) || (idx >= funcs.Length())) { | 
|   2306     return Function::null(); |   2254     return Function::null(); | 
|   2307   } |   2255   } | 
|   2308   Function& func = Function::Handle(); |   2256   Function& func = Function::Handle(); | 
|   2309   func ^= funcs.At(idx); |   2257   func ^= funcs.At(idx); | 
|   2310   ASSERT(!func.IsNull()); |   2258   ASSERT(!func.IsNull()); | 
|   2311   return func.raw(); |   2259   return func.raw(); | 
|   2312 } |   2260 } | 
|   2313  |   2261  | 
|   2314  |  | 
|   2315 RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const { |   2262 RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const { | 
|   2316   const Array& funcs = Array::Handle(functions()); |   2263   const Array& funcs = Array::Handle(functions()); | 
|   2317   if ((idx < 0) || (idx >= funcs.Length())) { |   2264   if ((idx < 0) || (idx >= funcs.Length())) { | 
|   2318     return Function::null(); |   2265     return Function::null(); | 
|   2319   } |   2266   } | 
|   2320   Function& func = Function::Handle(); |   2267   Function& func = Function::Handle(); | 
|   2321   func ^= funcs.At(idx); |   2268   func ^= funcs.At(idx); | 
|   2322   ASSERT(!func.IsNull()); |   2269   ASSERT(!func.IsNull()); | 
|   2323   if (!func.HasImplicitClosureFunction()) { |   2270   if (!func.HasImplicitClosureFunction()) { | 
|   2324     return Function::null(); |   2271     return Function::null(); | 
|   2325   } |   2272   } | 
|   2326   const Function& closure_func = |   2273   const Function& closure_func = | 
|   2327       Function::Handle(func.ImplicitClosureFunction()); |   2274       Function::Handle(func.ImplicitClosureFunction()); | 
|   2328   ASSERT(!closure_func.IsNull()); |   2275   ASSERT(!closure_func.IsNull()); | 
|   2329   return closure_func.raw(); |   2276   return closure_func.raw(); | 
|   2330 } |   2277 } | 
|   2331  |   2278  | 
|   2332  |  | 
|   2333 intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const { |   2279 intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const { | 
|   2334   Thread* thread = Thread::Current(); |   2280   Thread* thread = Thread::Current(); | 
|   2335   if (EnsureIsFinalized(thread) != Error::null()) { |   2281   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   2336     return -1; |   2282     return -1; | 
|   2337   } |   2283   } | 
|   2338   REUSABLE_ARRAY_HANDLESCOPE(thread); |   2284   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   2339   REUSABLE_FUNCTION_HANDLESCOPE(thread); |   2285   REUSABLE_FUNCTION_HANDLESCOPE(thread); | 
|   2340   Array& funcs = thread->ArrayHandle(); |   2286   Array& funcs = thread->ArrayHandle(); | 
|   2341   Function& function = thread->FunctionHandle(); |   2287   Function& function = thread->FunctionHandle(); | 
|   2342   funcs ^= functions(); |   2288   funcs ^= functions(); | 
|   2343   ASSERT(!funcs.IsNull()); |   2289   ASSERT(!funcs.IsNull()); | 
|   2344   Function& implicit_closure = Function::Handle(thread->zone()); |   2290   Function& implicit_closure = Function::Handle(thread->zone()); | 
|   2345   const intptr_t len = funcs.Length(); |   2291   const intptr_t len = funcs.Length(); | 
|   2346   for (intptr_t i = 0; i < len; i++) { |   2292   for (intptr_t i = 0; i < len; i++) { | 
|   2347     function ^= funcs.At(i); |   2293     function ^= funcs.At(i); | 
|   2348     implicit_closure ^= function.implicit_closure_function(); |   2294     implicit_closure ^= function.implicit_closure_function(); | 
|   2349     if (implicit_closure.IsNull()) { |   2295     if (implicit_closure.IsNull()) { | 
|   2350       // Skip non-implicit closure functions. |   2296       // Skip non-implicit closure functions. | 
|   2351       continue; |   2297       continue; | 
|   2352     } |   2298     } | 
|   2353     if (needle.raw() == implicit_closure.raw()) { |   2299     if (needle.raw() == implicit_closure.raw()) { | 
|   2354       return i; |   2300       return i; | 
|   2355     } |   2301     } | 
|   2356   } |   2302   } | 
|   2357   // No function found. |   2303   // No function found. | 
|   2358   return -1; |   2304   return -1; | 
|   2359 } |   2305 } | 
|   2360  |   2306  | 
|   2361  |  | 
|   2362 intptr_t Class::FindInvocationDispatcherFunctionIndex( |   2307 intptr_t Class::FindInvocationDispatcherFunctionIndex( | 
|   2363     const Function& needle) const { |   2308     const Function& needle) const { | 
|   2364   Thread* thread = Thread::Current(); |   2309   Thread* thread = Thread::Current(); | 
|   2365   if (EnsureIsFinalized(thread) != Error::null()) { |   2310   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   2366     return -1; |   2311     return -1; | 
|   2367   } |   2312   } | 
|   2368   REUSABLE_ARRAY_HANDLESCOPE(thread); |   2313   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   2369   REUSABLE_OBJECT_HANDLESCOPE(thread); |   2314   REUSABLE_OBJECT_HANDLESCOPE(thread); | 
|   2370   Array& funcs = thread->ArrayHandle(); |   2315   Array& funcs = thread->ArrayHandle(); | 
|   2371   Object& object = thread->ObjectHandle(); |   2316   Object& object = thread->ObjectHandle(); | 
|   2372   funcs ^= invocation_dispatcher_cache(); |   2317   funcs ^= invocation_dispatcher_cache(); | 
|   2373   ASSERT(!funcs.IsNull()); |   2318   ASSERT(!funcs.IsNull()); | 
|   2374   const intptr_t len = funcs.Length(); |   2319   const intptr_t len = funcs.Length(); | 
|   2375   for (intptr_t i = 0; i < len; i++) { |   2320   for (intptr_t i = 0; i < len; i++) { | 
|   2376     object = funcs.At(i); |   2321     object = funcs.At(i); | 
|   2377     // The invocation_dispatcher_cache is a table with some entries that |   2322     // The invocation_dispatcher_cache is a table with some entries that | 
|   2378     // are functions. |   2323     // are functions. | 
|   2379     if (object.IsFunction()) { |   2324     if (object.IsFunction()) { | 
|   2380       if (Function::Cast(object).raw() == needle.raw()) { |   2325       if (Function::Cast(object).raw() == needle.raw()) { | 
|   2381         return i; |   2326         return i; | 
|   2382       } |   2327       } | 
|   2383     } |   2328     } | 
|   2384   } |   2329   } | 
|   2385   // No function found. |   2330   // No function found. | 
|   2386   return -1; |   2331   return -1; | 
|   2387 } |   2332 } | 
|   2388  |   2333  | 
|   2389  |  | 
|   2390 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const { |   2334 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const { | 
|   2391   Thread* thread = Thread::Current(); |   2335   Thread* thread = Thread::Current(); | 
|   2392   REUSABLE_ARRAY_HANDLESCOPE(thread); |   2336   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   2393   REUSABLE_OBJECT_HANDLESCOPE(thread); |   2337   REUSABLE_OBJECT_HANDLESCOPE(thread); | 
|   2394   Array& dispatcher_cache = thread->ArrayHandle(); |   2338   Array& dispatcher_cache = thread->ArrayHandle(); | 
|   2395   Object& object = thread->ObjectHandle(); |   2339   Object& object = thread->ObjectHandle(); | 
|   2396   dispatcher_cache ^= invocation_dispatcher_cache(); |   2340   dispatcher_cache ^= invocation_dispatcher_cache(); | 
|   2397   object = dispatcher_cache.At(idx); |   2341   object = dispatcher_cache.At(idx); | 
|   2398   if (!object.IsFunction()) { |   2342   if (!object.IsFunction()) { | 
|   2399     return Function::null(); |   2343     return Function::null(); | 
|   2400   } |   2344   } | 
|   2401   return Function::Cast(object).raw(); |   2345   return Function::Cast(object).raw(); | 
|   2402 } |   2346 } | 
|   2403  |   2347  | 
|   2404  |  | 
|   2405 void Class::set_signature_function(const Function& value) const { |   2348 void Class::set_signature_function(const Function& value) const { | 
|   2406   ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); |   2349   ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); | 
|   2407   StorePointer(&raw_ptr()->signature_function_, value.raw()); |   2350   StorePointer(&raw_ptr()->signature_function_, value.raw()); | 
|   2408 } |   2351 } | 
|   2409  |   2352  | 
|   2410  |  | 
|   2411 void Class::set_state_bits(intptr_t bits) const { |   2353 void Class::set_state_bits(intptr_t bits) const { | 
|   2412   StoreNonPointer(&raw_ptr()->state_bits_, static_cast<uint16_t>(bits)); |   2354   StoreNonPointer(&raw_ptr()->state_bits_, static_cast<uint16_t>(bits)); | 
|   2413 } |   2355 } | 
|   2414  |   2356  | 
|   2415  |  | 
|   2416 void Class::set_library(const Library& value) const { |   2357 void Class::set_library(const Library& value) const { | 
|   2417   StorePointer(&raw_ptr()->library_, value.raw()); |   2358   StorePointer(&raw_ptr()->library_, value.raw()); | 
|   2418 } |   2359 } | 
|   2419  |   2360  | 
|   2420  |  | 
|   2421 void Class::set_type_parameters(const TypeArguments& value) const { |   2361 void Class::set_type_parameters(const TypeArguments& value) const { | 
|   2422   StorePointer(&raw_ptr()->type_parameters_, value.raw()); |   2362   StorePointer(&raw_ptr()->type_parameters_, value.raw()); | 
|   2423 } |   2363 } | 
|   2424  |   2364  | 
|   2425  |  | 
|   2426 intptr_t Class::NumTypeParameters(Thread* thread) const { |   2365 intptr_t Class::NumTypeParameters(Thread* thread) const { | 
|   2427   if (IsMixinApplication() && !is_mixin_type_applied()) { |   2366   if (IsMixinApplication() && !is_mixin_type_applied()) { | 
|   2428     ClassFinalizer::ApplyMixinType(*this); |   2367     ClassFinalizer::ApplyMixinType(*this); | 
|   2429   } |   2368   } | 
|   2430   if (type_parameters() == TypeArguments::null()) { |   2369   if (type_parameters() == TypeArguments::null()) { | 
|   2431     const intptr_t cid = id(); |   2370     const intptr_t cid = id(); | 
|   2432     if ((cid == kArrayCid) || (cid == kImmutableArrayCid) || |   2371     if ((cid == kArrayCid) || (cid == kImmutableArrayCid) || | 
|   2433         (cid == kGrowableObjectArrayCid)) { |   2372         (cid == kGrowableObjectArrayCid)) { | 
|   2434       return 1;  // List's type parameter may not have been parsed yet. |   2373       return 1;  // List's type parameter may not have been parsed yet. | 
|   2435     } |   2374     } | 
|   2436     return 0; |   2375     return 0; | 
|   2437   } |   2376   } | 
|   2438   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |   2377   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 
|   2439   TypeArguments& type_params = thread->TypeArgumentsHandle(); |   2378   TypeArguments& type_params = thread->TypeArgumentsHandle(); | 
|   2440   type_params = type_parameters(); |   2379   type_params = type_parameters(); | 
|   2441   return type_params.Length(); |   2380   return type_params.Length(); | 
|   2442 } |   2381 } | 
|   2443  |   2382  | 
|   2444  |  | 
|   2445 intptr_t Class::NumOwnTypeArguments() const { |   2383 intptr_t Class::NumOwnTypeArguments() const { | 
|   2446   // Return cached value if already calculated. |   2384   // Return cached value if already calculated. | 
|   2447   if (num_own_type_arguments() != kUnknownNumTypeArguments) { |   2385   if (num_own_type_arguments() != kUnknownNumTypeArguments) { | 
|   2448     return num_own_type_arguments(); |   2386     return num_own_type_arguments(); | 
|   2449   } |   2387   } | 
|   2450   Thread* thread = Thread::Current(); |   2388   Thread* thread = Thread::Current(); | 
|   2451   Isolate* isolate = thread->isolate(); |   2389   Isolate* isolate = thread->isolate(); | 
|   2452   Zone* zone = thread->zone(); |   2390   Zone* zone = thread->zone(); | 
|   2453   const intptr_t num_type_params = NumTypeParameters(); |   2391   const intptr_t num_type_params = NumTypeParameters(); | 
|   2454   if (!FLAG_overlap_type_arguments || (num_type_params == 0) || |   2392   if (!FLAG_overlap_type_arguments || (num_type_params == 0) || | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   2508       // Overlap found. |   2446       // Overlap found. | 
|   2509       set_num_own_type_arguments(num_type_params - num_overlapping_type_args); |   2447       set_num_own_type_arguments(num_type_params - num_overlapping_type_args); | 
|   2510       return num_type_params - num_overlapping_type_args; |   2448       return num_type_params - num_overlapping_type_args; | 
|   2511     } |   2449     } | 
|   2512   } |   2450   } | 
|   2513   // No overlap found. |   2451   // No overlap found. | 
|   2514   set_num_own_type_arguments(num_type_params); |   2452   set_num_own_type_arguments(num_type_params); | 
|   2515   return num_type_params; |   2453   return num_type_params; | 
|   2516 } |   2454 } | 
|   2517  |   2455  | 
|   2518  |  | 
|   2519 intptr_t Class::NumTypeArguments() const { |   2456 intptr_t Class::NumTypeArguments() const { | 
|   2520   // Return cached value if already calculated. |   2457   // Return cached value if already calculated. | 
|   2521   if (num_type_arguments() != kUnknownNumTypeArguments) { |   2458   if (num_type_arguments() != kUnknownNumTypeArguments) { | 
|   2522     return num_type_arguments(); |   2459     return num_type_arguments(); | 
|   2523   } |   2460   } | 
|   2524   // To work properly, this call requires the super class of this class to be |   2461   // To work properly, this call requires the super class of this class to be | 
|   2525   // resolved, which is checked by the type_class() call on the super type. |   2462   // resolved, which is checked by the type_class() call on the super type. | 
|   2526   // Note that calling type_class() on a MixinAppType fails. |   2463   // Note that calling type_class() on a MixinAppType fails. | 
|   2527   Thread* thread = Thread::Current(); |   2464   Thread* thread = Thread::Current(); | 
|   2528   Zone* zone = thread->zone(); |   2465   Zone* zone = thread->zone(); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|   2545     // sup_type, but not as sup_type itself. |   2482     // sup_type, but not as sup_type itself. | 
|   2546     ASSERT(sup_type.IsType()); |   2483     ASSERT(sup_type.IsType()); | 
|   2547     ClassFinalizer::ResolveTypeClass(cls, Type::Cast(sup_type)); |   2484     ClassFinalizer::ResolveTypeClass(cls, Type::Cast(sup_type)); | 
|   2548     cls = sup_type.type_class(); |   2485     cls = sup_type.type_class(); | 
|   2549     ASSERT(!cls.IsTypedefClass()); |   2486     ASSERT(!cls.IsTypedefClass()); | 
|   2550   } while (true); |   2487   } while (true); | 
|   2551   set_num_type_arguments(num_type_args); |   2488   set_num_type_arguments(num_type_args); | 
|   2552   return num_type_args; |   2489   return num_type_args; | 
|   2553 } |   2490 } | 
|   2554  |   2491  | 
|   2555  |  | 
|   2556 RawClass* Class::SuperClass(bool original_classes) const { |   2492 RawClass* Class::SuperClass(bool original_classes) const { | 
|   2557   Thread* thread = Thread::Current(); |   2493   Thread* thread = Thread::Current(); | 
|   2558   Zone* zone = thread->zone(); |   2494   Zone* zone = thread->zone(); | 
|   2559   Isolate* isolate = thread->isolate(); |   2495   Isolate* isolate = thread->isolate(); | 
|   2560   if (super_type() == AbstractType::null()) { |   2496   if (super_type() == AbstractType::null()) { | 
|   2561     return Class::null(); |   2497     return Class::null(); | 
|   2562   } |   2498   } | 
|   2563   const AbstractType& sup_type = AbstractType::Handle(zone, super_type()); |   2499   const AbstractType& sup_type = AbstractType::Handle(zone, super_type()); | 
|   2564   const intptr_t type_class_id = sup_type.type_class_id(); |   2500   const intptr_t type_class_id = sup_type.type_class_id(); | 
|   2565   if (original_classes) { |   2501   if (original_classes) { | 
|   2566     return isolate->GetClassForHeapWalkAt(type_class_id); |   2502     return isolate->GetClassForHeapWalkAt(type_class_id); | 
|   2567   } else { |   2503   } else { | 
|   2568     return isolate->class_table()->At(type_class_id); |   2504     return isolate->class_table()->At(type_class_id); | 
|   2569   } |   2505   } | 
|   2570 } |   2506 } | 
|   2571  |   2507  | 
|   2572  |  | 
|   2573 void Class::set_super_type(const AbstractType& value) const { |   2508 void Class::set_super_type(const AbstractType& value) const { | 
|   2574   ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()) || |   2509   ASSERT(value.IsNull() || (value.IsType() && !value.IsDynamicType()) || | 
|   2575          value.IsMixinAppType()); |   2510          value.IsMixinAppType()); | 
|   2576   StorePointer(&raw_ptr()->super_type_, value.raw()); |   2511   StorePointer(&raw_ptr()->super_type_, value.raw()); | 
|   2577 } |   2512 } | 
|   2578  |   2513  | 
|   2579  |  | 
|   2580 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { |   2514 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { | 
|   2581   ASSERT(!type_name.IsNull()); |   2515   ASSERT(!type_name.IsNull()); | 
|   2582   Thread* thread = Thread::Current(); |   2516   Thread* thread = Thread::Current(); | 
|   2583   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |   2517   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 
|   2584   REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |   2518   REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); | 
|   2585   REUSABLE_STRING_HANDLESCOPE(thread); |   2519   REUSABLE_STRING_HANDLESCOPE(thread); | 
|   2586   TypeArguments& type_params = thread->TypeArgumentsHandle(); |   2520   TypeArguments& type_params = thread->TypeArgumentsHandle(); | 
|   2587   TypeParameter& type_param = thread->TypeParameterHandle(); |   2521   TypeParameter& type_param = thread->TypeParameterHandle(); | 
|   2588   String& type_param_name = thread->StringHandle(); |   2522   String& type_param_name = thread->StringHandle(); | 
|   2589  |   2523  | 
|   2590   type_params ^= type_parameters(); |   2524   type_params ^= type_parameters(); | 
|   2591   if (!type_params.IsNull()) { |   2525   if (!type_params.IsNull()) { | 
|   2592     const intptr_t num_type_params = type_params.Length(); |   2526     const intptr_t num_type_params = type_params.Length(); | 
|   2593     for (intptr_t i = 0; i < num_type_params; i++) { |   2527     for (intptr_t i = 0; i < num_type_params; i++) { | 
|   2594       type_param ^= type_params.TypeAt(i); |   2528       type_param ^= type_params.TypeAt(i); | 
|   2595       type_param_name = type_param.name(); |   2529       type_param_name = type_param.name(); | 
|   2596       if (type_param_name.Equals(type_name)) { |   2530       if (type_param_name.Equals(type_name)) { | 
|   2597         return type_param.raw(); |   2531         return type_param.raw(); | 
|   2598       } |   2532       } | 
|   2599     } |   2533     } | 
|   2600   } |   2534   } | 
|   2601   return TypeParameter::null(); |   2535   return TypeParameter::null(); | 
|   2602 } |   2536 } | 
|   2603  |   2537  | 
|   2604  |  | 
|   2605 void Class::CalculateFieldOffsets() const { |   2538 void Class::CalculateFieldOffsets() const { | 
|   2606   Array& flds = Array::Handle(fields()); |   2539   Array& flds = Array::Handle(fields()); | 
|   2607   const Class& super = Class::Handle(SuperClass()); |   2540   const Class& super = Class::Handle(SuperClass()); | 
|   2608   intptr_t offset = 0; |   2541   intptr_t offset = 0; | 
|   2609   intptr_t type_args_field_offset = kNoTypeArguments; |   2542   intptr_t type_args_field_offset = kNoTypeArguments; | 
|   2610   if (super.IsNull()) { |   2543   if (super.IsNull()) { | 
|   2611     offset = Instance::NextFieldOffset(); |   2544     offset = Instance::NextFieldOffset(); | 
|   2612     ASSERT(offset > 0); |   2545     ASSERT(offset > 0); | 
|   2613   } else { |   2546   } else { | 
|   2614     ASSERT(super.is_finalized() || super.is_prefinalized()); |   2547     ASSERT(super.is_finalized() || super.is_prefinalized()); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   2642     if (!field.is_static()) { |   2575     if (!field.is_static()) { | 
|   2643       ASSERT(field.Offset() == 0); |   2576       ASSERT(field.Offset() == 0); | 
|   2644       field.SetOffset(offset); |   2577       field.SetOffset(offset); | 
|   2645       offset += kWordSize; |   2578       offset += kWordSize; | 
|   2646     } |   2579     } | 
|   2647   } |   2580   } | 
|   2648   set_instance_size(RoundedAllocationSize(offset)); |   2581   set_instance_size(RoundedAllocationSize(offset)); | 
|   2649   set_next_field_offset(offset); |   2582   set_next_field_offset(offset); | 
|   2650 } |   2583 } | 
|   2651  |   2584  | 
|   2652  |  | 
|   2653 RawFunction* Class::GetInvocationDispatcher(const String& target_name, |   2585 RawFunction* Class::GetInvocationDispatcher(const String& target_name, | 
|   2654                                             const Array& args_desc, |   2586                                             const Array& args_desc, | 
|   2655                                             RawFunction::Kind kind, |   2587                                             RawFunction::Kind kind, | 
|   2656                                             bool create_if_absent) const { |   2588                                             bool create_if_absent) const { | 
|   2657   enum { kNameIndex = 0, kArgsDescIndex, kFunctionIndex, kEntrySize }; |   2589   enum { kNameIndex = 0, kArgsDescIndex, kFunctionIndex, kEntrySize }; | 
|   2658  |   2590  | 
|   2659   ASSERT(kind == RawFunction::kNoSuchMethodDispatcher || |   2591   ASSERT(kind == RawFunction::kNoSuchMethodDispatcher || | 
|   2660          kind == RawFunction::kInvokeFieldDispatcher); |   2592          kind == RawFunction::kInvokeFieldDispatcher); | 
|   2661   Function& dispatcher = Function::Handle(); |   2593   Function& dispatcher = Function::Handle(); | 
|   2662   Array& cache = Array::Handle(invocation_dispatcher_cache()); |   2594   Array& cache = Array::Handle(invocation_dispatcher_cache()); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|   2688       set_invocation_dispatcher_cache(cache); |   2620       set_invocation_dispatcher_cache(cache); | 
|   2689     } |   2621     } | 
|   2690     dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind); |   2622     dispatcher ^= CreateInvocationDispatcher(target_name, args_desc, kind); | 
|   2691     cache.SetAt(i + kNameIndex, target_name); |   2623     cache.SetAt(i + kNameIndex, target_name); | 
|   2692     cache.SetAt(i + kArgsDescIndex, args_desc); |   2624     cache.SetAt(i + kArgsDescIndex, args_desc); | 
|   2693     cache.SetAt(i + kFunctionIndex, dispatcher); |   2625     cache.SetAt(i + kFunctionIndex, dispatcher); | 
|   2694   } |   2626   } | 
|   2695   return dispatcher.raw(); |   2627   return dispatcher.raw(); | 
|   2696 } |   2628 } | 
|   2697  |   2629  | 
|   2698  |  | 
|   2699 RawFunction* Class::CreateInvocationDispatcher(const String& target_name, |   2630 RawFunction* Class::CreateInvocationDispatcher(const String& target_name, | 
|   2700                                                const Array& args_desc, |   2631                                                const Array& args_desc, | 
|   2701                                                RawFunction::Kind kind) const { |   2632                                                RawFunction::Kind kind) const { | 
|   2702   Thread* thread = Thread::Current(); |   2633   Thread* thread = Thread::Current(); | 
|   2703   Zone* zone = thread->zone(); |   2634   Zone* zone = thread->zone(); | 
|   2704   Function& invocation = Function::Handle( |   2635   Function& invocation = Function::Handle( | 
|   2705       zone, Function::New( |   2636       zone, Function::New( | 
|   2706                 String::Handle(zone, Symbols::New(thread, target_name)), kind, |   2637                 String::Handle(zone, Symbols::New(thread, target_name)), kind, | 
|   2707                 false,  // Not static. |   2638                 false,  // Not static. | 
|   2708                 false,  // Not const. |   2639                 false,  // Not const. | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   2747   } |   2678   } | 
|   2748   invocation.set_result_type(Object::dynamic_type()); |   2679   invocation.set_result_type(Object::dynamic_type()); | 
|   2749   invocation.set_is_debuggable(false); |   2680   invocation.set_is_debuggable(false); | 
|   2750   invocation.set_is_visible(false); |   2681   invocation.set_is_visible(false); | 
|   2751   invocation.set_is_reflectable(false); |   2682   invocation.set_is_reflectable(false); | 
|   2752   invocation.set_saved_args_desc(args_desc); |   2683   invocation.set_saved_args_desc(args_desc); | 
|   2753  |   2684  | 
|   2754   return invocation.raw(); |   2685   return invocation.raw(); | 
|   2755 } |   2686 } | 
|   2756  |   2687  | 
|   2757  |  | 
|   2758 // Method extractors are used to create implicit closures from methods. |   2688 // Method extractors are used to create implicit closures from methods. | 
|   2759 // When an expression obj.M is evaluated for the first time and receiver obj |   2689 // When an expression obj.M is evaluated for the first time and receiver obj | 
|   2760 // does not have a getter called M but has a method called M then an extractor |   2690 // does not have a getter called M but has a method called M then an extractor | 
|   2761 // is created and injected as a getter (under the name get:M) into the class |   2691 // is created and injected as a getter (under the name get:M) into the class | 
|   2762 // owning method M. |   2692 // owning method M. | 
|   2763 RawFunction* Function::CreateMethodExtractor(const String& getter_name) const { |   2693 RawFunction* Function::CreateMethodExtractor(const String& getter_name) const { | 
|   2764   Thread* thread = Thread::Current(); |   2694   Thread* thread = Thread::Current(); | 
|   2765   Zone* zone = thread->zone(); |   2695   Zone* zone = thread->zone(); | 
|   2766   ASSERT(Field::IsGetterName(getter_name)); |   2696   ASSERT(Field::IsGetterName(getter_name)); | 
|   2767   const Function& closure_function = |   2697   const Function& closure_function = | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|   2790  |   2720  | 
|   2791   extractor.set_extracted_method_closure(closure_function); |   2721   extractor.set_extracted_method_closure(closure_function); | 
|   2792   extractor.set_is_debuggable(false); |   2722   extractor.set_is_debuggable(false); | 
|   2793   extractor.set_is_visible(false); |   2723   extractor.set_is_visible(false); | 
|   2794  |   2724  | 
|   2795   owner.AddFunction(extractor); |   2725   owner.AddFunction(extractor); | 
|   2796  |   2726  | 
|   2797   return extractor.raw(); |   2727   return extractor.raw(); | 
|   2798 } |   2728 } | 
|   2799  |   2729  | 
|   2800  |  | 
|   2801 RawFunction* Function::GetMethodExtractor(const String& getter_name) const { |   2730 RawFunction* Function::GetMethodExtractor(const String& getter_name) const { | 
|   2802   ASSERT(Field::IsGetterName(getter_name)); |   2731   ASSERT(Field::IsGetterName(getter_name)); | 
|   2803   const Function& closure_function = |   2732   const Function& closure_function = | 
|   2804       Function::Handle(ImplicitClosureFunction()); |   2733       Function::Handle(ImplicitClosureFunction()); | 
|   2805   const Class& owner = Class::Handle(closure_function.Owner()); |   2734   const Class& owner = Class::Handle(closure_function.Owner()); | 
|   2806   Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name)); |   2735   Function& result = Function::Handle(owner.LookupDynamicFunction(getter_name)); | 
|   2807   if (result.IsNull()) { |   2736   if (result.IsNull()) { | 
|   2808     result ^= CreateMethodExtractor(getter_name); |   2737     result ^= CreateMethodExtractor(getter_name); | 
|   2809   } |   2738   } | 
|   2810   ASSERT(result.kind() == RawFunction::kMethodExtractor); |   2739   ASSERT(result.kind() == RawFunction::kMethodExtractor); | 
|   2811   return result.raw(); |   2740   return result.raw(); | 
|   2812 } |   2741 } | 
|   2813  |   2742  | 
|   2814  |  | 
|   2815 RawArray* Class::invocation_dispatcher_cache() const { |   2743 RawArray* Class::invocation_dispatcher_cache() const { | 
|   2816   return raw_ptr()->invocation_dispatcher_cache_; |   2744   return raw_ptr()->invocation_dispatcher_cache_; | 
|   2817 } |   2745 } | 
|   2818  |   2746  | 
|   2819  |  | 
|   2820 void Class::set_invocation_dispatcher_cache(const Array& cache) const { |   2747 void Class::set_invocation_dispatcher_cache(const Array& cache) const { | 
|   2821   StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw()); |   2748   StorePointer(&raw_ptr()->invocation_dispatcher_cache_, cache.raw()); | 
|   2822 } |   2749 } | 
|   2823  |   2750  | 
|   2824  |  | 
|   2825 void Class::Finalize() const { |   2751 void Class::Finalize() const { | 
|   2826   ASSERT(Thread::Current()->IsMutatorThread()); |   2752   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   2827   ASSERT(!Isolate::Current()->all_classes_finalized()); |   2753   ASSERT(!Isolate::Current()->all_classes_finalized()); | 
|   2828   ASSERT(!is_finalized()); |   2754   ASSERT(!is_finalized()); | 
|   2829   // Prefinalized classes have a VM internal representation and no Dart fields. |   2755   // Prefinalized classes have a VM internal representation and no Dart fields. | 
|   2830   // Their instance size  is precomputed and field offsets are known. |   2756   // Their instance size  is precomputed and field offsets are known. | 
|   2831   if (!is_prefinalized()) { |   2757   if (!is_prefinalized()) { | 
|   2832     // Compute offsets of instance fields and instance size. |   2758     // Compute offsets of instance fields and instance size. | 
|   2833     CalculateFieldOffsets(); |   2759     CalculateFieldOffsets(); | 
|   2834   } |   2760   } | 
|   2835   set_is_finalized(); |   2761   set_is_finalized(); | 
|   2836 } |   2762 } | 
|   2837  |   2763  | 
|   2838  |  | 
|   2839 class CHACodeArray : public WeakCodeReferences { |   2764 class CHACodeArray : public WeakCodeReferences { | 
|   2840  public: |   2765  public: | 
|   2841   explicit CHACodeArray(const Class& cls) |   2766   explicit CHACodeArray(const Class& cls) | 
|   2842       : WeakCodeReferences(Array::Handle(cls.dependent_code())), cls_(cls) {} |   2767       : WeakCodeReferences(Array::Handle(cls.dependent_code())), cls_(cls) {} | 
|   2843  |   2768  | 
|   2844   virtual void UpdateArrayTo(const Array& value) { |   2769   virtual void UpdateArrayTo(const Array& value) { | 
|   2845     // TODO(fschneider): Fails for classes in the VM isolate. |   2770     // TODO(fschneider): Fails for classes in the VM isolate. | 
|   2846     cls_.set_dependent_code(value); |   2771     cls_.set_dependent_code(value); | 
|   2847   } |   2772   } | 
|   2848  |   2773  | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   2862           " (%s)\n", |   2787           " (%s)\n", | 
|   2863           function.ToFullyQualifiedCString(), cls_.ToCString()); |   2788           function.ToFullyQualifiedCString(), cls_.ToCString()); | 
|   2864     } |   2789     } | 
|   2865   } |   2790   } | 
|   2866  |   2791  | 
|   2867  private: |   2792  private: | 
|   2868   const Class& cls_; |   2793   const Class& cls_; | 
|   2869   DISALLOW_COPY_AND_ASSIGN(CHACodeArray); |   2794   DISALLOW_COPY_AND_ASSIGN(CHACodeArray); | 
|   2870 }; |   2795 }; | 
|   2871  |   2796  | 
|   2872  |  | 
|   2873 #if defined(DEBUG) |   2797 #if defined(DEBUG) | 
|   2874 static bool IsMutatorOrAtSafepoint() { |   2798 static bool IsMutatorOrAtSafepoint() { | 
|   2875   Thread* thread = Thread::Current(); |   2799   Thread* thread = Thread::Current(); | 
|   2876   return thread->IsMutatorThread() || thread->IsAtSafepoint(); |   2800   return thread->IsMutatorThread() || thread->IsAtSafepoint(); | 
|   2877 } |   2801 } | 
|   2878 #endif |   2802 #endif | 
|   2879  |   2803  | 
|   2880  |  | 
|   2881 void Class::RegisterCHACode(const Code& code) { |   2804 void Class::RegisterCHACode(const Code& code) { | 
|   2882   if (FLAG_trace_cha) { |   2805   if (FLAG_trace_cha) { | 
|   2883     THR_Print("RegisterCHACode '%s' depends on class '%s'\n", |   2806     THR_Print("RegisterCHACode '%s' depends on class '%s'\n", | 
|   2884               Function::Handle(code.function()).ToQualifiedCString(), |   2807               Function::Handle(code.function()).ToQualifiedCString(), | 
|   2885               ToCString()); |   2808               ToCString()); | 
|   2886   } |   2809   } | 
|   2887   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |   2810   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|   2888   ASSERT(code.is_optimized()); |   2811   ASSERT(code.is_optimized()); | 
|   2889   CHACodeArray a(*this); |   2812   CHACodeArray a(*this); | 
|   2890   a.Register(code); |   2813   a.Register(code); | 
|   2891 } |   2814 } | 
|   2892  |   2815  | 
|   2893  |  | 
|   2894 void Class::DisableCHAOptimizedCode(const Class& subclass) { |   2816 void Class::DisableCHAOptimizedCode(const Class& subclass) { | 
|   2895   ASSERT(Thread::Current()->IsMutatorThread()); |   2817   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   2896   CHACodeArray a(*this); |   2818   CHACodeArray a(*this); | 
|   2897   if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) { |   2819   if (FLAG_trace_deoptimization && a.HasCodes() && !subclass.IsNull()) { | 
|   2898     THR_Print("Adding subclass %s\n", subclass.ToCString()); |   2820     THR_Print("Adding subclass %s\n", subclass.ToCString()); | 
|   2899   } |   2821   } | 
|   2900   a.DisableCode(); |   2822   a.DisableCode(); | 
|   2901 } |   2823 } | 
|   2902  |   2824  | 
|   2903  |  | 
|   2904 void Class::DisableAllCHAOptimizedCode() { |   2825 void Class::DisableAllCHAOptimizedCode() { | 
|   2905   DisableCHAOptimizedCode(Class::Handle()); |   2826   DisableCHAOptimizedCode(Class::Handle()); | 
|   2906 } |   2827 } | 
|   2907  |   2828  | 
|   2908  |  | 
|   2909 bool Class::TraceAllocation(Isolate* isolate) const { |   2829 bool Class::TraceAllocation(Isolate* isolate) const { | 
|   2910 #ifndef PRODUCT |   2830 #ifndef PRODUCT | 
|   2911   ClassTable* class_table = isolate->class_table(); |   2831   ClassTable* class_table = isolate->class_table(); | 
|   2912   return class_table->TraceAllocationFor(id()); |   2832   return class_table->TraceAllocationFor(id()); | 
|   2913 #else |   2833 #else | 
|   2914   return false; |   2834   return false; | 
|   2915 #endif |   2835 #endif | 
|   2916 } |   2836 } | 
|   2917  |   2837  | 
|   2918  |  | 
|   2919 void Class::SetTraceAllocation(bool trace_allocation) const { |   2838 void Class::SetTraceAllocation(bool trace_allocation) const { | 
|   2920 #ifndef PRODUCT |   2839 #ifndef PRODUCT | 
|   2921   Isolate* isolate = Isolate::Current(); |   2840   Isolate* isolate = Isolate::Current(); | 
|   2922   const bool changed = trace_allocation != this->TraceAllocation(isolate); |   2841   const bool changed = trace_allocation != this->TraceAllocation(isolate); | 
|   2923   if (changed) { |   2842   if (changed) { | 
|   2924     ClassTable* class_table = isolate->class_table(); |   2843     ClassTable* class_table = isolate->class_table(); | 
|   2925     class_table->SetTraceAllocationFor(id(), trace_allocation); |   2844     class_table->SetTraceAllocationFor(id(), trace_allocation); | 
|   2926     DisableAllocationStub(); |   2845     DisableAllocationStub(); | 
|   2927   } |   2846   } | 
|   2928 #else |   2847 #else | 
|   2929   UNREACHABLE(); |   2848   UNREACHABLE(); | 
|   2930 #endif |   2849 #endif | 
|   2931 } |   2850 } | 
|   2932  |   2851  | 
|   2933  |  | 
|   2934 bool Class::ValidatePostFinalizePatch(const Class& orig_class, |   2852 bool Class::ValidatePostFinalizePatch(const Class& orig_class, | 
|   2935                                       Error* error) const { |   2853                                       Error* error) const { | 
|   2936   ASSERT(error != NULL); |   2854   ASSERT(error != NULL); | 
|   2937   // Not allowed to add new fields in a post finalization patch. |   2855   // Not allowed to add new fields in a post finalization patch. | 
|   2938   if (fields() != Object::empty_array().raw()) { |   2856   if (fields() != Object::empty_array().raw()) { | 
|   2939     *error = LanguageError::NewFormatted( |   2857     *error = LanguageError::NewFormatted( | 
|   2940         *error,  // No previous error. |   2858         *error,  // No previous error. | 
|   2941         Script::Handle(script()), token_pos(), Report::AtLocation, |   2859         Script::Handle(script()), token_pos(), Report::AtLocation, | 
|   2942         Report::kError, Heap::kNew, |   2860         Report::kError, Heap::kNew, | 
|   2943         "new fields are not allowed for this patch"); |   2861         "new fields are not allowed for this patch"); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   2985           Script::Handle(script()), token_pos(), Report::AtLocation, |   2903           Script::Handle(script()), token_pos(), Report::AtLocation, | 
|   2986           Report::kError, Heap::kNew, |   2904           Report::kError, Heap::kNew, | 
|   2987           "'%s' is not private and therefore cannot be patched", |   2905           "'%s' is not private and therefore cannot be patched", | 
|   2988           name.ToCString()); |   2906           name.ToCString()); | 
|   2989       return false; |   2907       return false; | 
|   2990     } |   2908     } | 
|   2991   } |   2909   } | 
|   2992   return true; |   2910   return true; | 
|   2993 } |   2911 } | 
|   2994  |   2912  | 
|   2995  |  | 
|   2996 void Class::set_dependent_code(const Array& array) const { |   2913 void Class::set_dependent_code(const Array& array) const { | 
|   2997   StorePointer(&raw_ptr()->dependent_code_, array.raw()); |   2914   StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 
|   2998 } |   2915 } | 
|   2999  |   2916  | 
|   3000  |  | 
|   3001 // Apply the members from the patch class to the original class. |   2917 // Apply the members from the patch class to the original class. | 
|   3002 bool Class::ApplyPatch(const Class& patch, Error* error) const { |   2918 bool Class::ApplyPatch(const Class& patch, Error* error) const { | 
|   3003   ASSERT(error != NULL); |   2919   ASSERT(error != NULL); | 
|   3004   ASSERT(!is_finalized()); |   2920   ASSERT(!is_finalized()); | 
|   3005   // Shared handles used during the iteration. |   2921   // Shared handles used during the iteration. | 
|   3006   String& member_name = String::Handle(); |   2922   String& member_name = String::Handle(); | 
|   3007  |   2923  | 
|   3008   const PatchClass& patch_class = PatchClass::Handle( |   2924   const PatchClass& patch_class = PatchClass::Handle( | 
|   3009       PatchClass::New(*this, Script::Handle(patch.script()))); |   2925       PatchClass::New(*this, Script::Handle(patch.script()))); | 
|   3010  |   2926  | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3104   SetFields(new_list); |   3020   SetFields(new_list); | 
|   3105  |   3021  | 
|   3106   // The functions and fields in the patch class are no longer needed. |   3022   // The functions and fields in the patch class are no longer needed. | 
|   3107   // The patch class itself is also no longer needed. |   3023   // The patch class itself is also no longer needed. | 
|   3108   patch.SetFunctions(Object::empty_array()); |   3024   patch.SetFunctions(Object::empty_array()); | 
|   3109   patch.SetFields(Object::empty_array()); |   3025   patch.SetFields(Object::empty_array()); | 
|   3110   Library::Handle(patch.library()).RemovePatchClass(patch); |   3026   Library::Handle(patch.library()).RemovePatchClass(patch); | 
|   3111   return true; |   3027   return true; | 
|   3112 } |   3028 } | 
|   3113  |   3029  | 
|   3114  |  | 
|   3115 static RawString* BuildClosureSource(const Array& formal_params, |   3030 static RawString* BuildClosureSource(const Array& formal_params, | 
|   3116                                      const String& expr) { |   3031                                      const String& expr) { | 
|   3117   const GrowableObjectArray& src_pieces = |   3032   const GrowableObjectArray& src_pieces = | 
|   3118       GrowableObjectArray::Handle(GrowableObjectArray::New()); |   3033       GrowableObjectArray::Handle(GrowableObjectArray::New()); | 
|   3119   String& piece = String::Handle(); |   3034   String& piece = String::Handle(); | 
|   3120   src_pieces.Add(Symbols::LParen()); |   3035   src_pieces.Add(Symbols::LParen()); | 
|   3121   // Add formal parameters. |   3036   // Add formal parameters. | 
|   3122   intptr_t num_formals = formal_params.Length(); |   3037   intptr_t num_formals = formal_params.Length(); | 
|   3123   for (intptr_t i = 0; i < num_formals; i++) { |   3038   for (intptr_t i = 0; i < num_formals; i++) { | 
|   3124     if (i > 0) { |   3039     if (i > 0) { | 
|   3125       src_pieces.Add(Symbols::CommaSpace()); |   3040       src_pieces.Add(Symbols::CommaSpace()); | 
|   3126     } |   3041     } | 
|   3127     piece ^= formal_params.At(i); |   3042     piece ^= formal_params.At(i); | 
|   3128     src_pieces.Add(piece); |   3043     src_pieces.Add(piece); | 
|   3129   } |   3044   } | 
|   3130   src_pieces.Add(Symbols::RParenArrow()); |   3045   src_pieces.Add(Symbols::RParenArrow()); | 
|   3131   src_pieces.Add(expr); |   3046   src_pieces.Add(expr); | 
|   3132   src_pieces.Add(Symbols::Semicolon()); |   3047   src_pieces.Add(Symbols::Semicolon()); | 
|   3133   return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces))); |   3048   return String::ConcatAll(Array::Handle(Array::MakeFixedLength(src_pieces))); | 
|   3134 } |   3049 } | 
|   3135  |   3050  | 
|   3136  |  | 
|   3137 RawFunction* Function::EvaluateHelper(const Class& cls, |   3051 RawFunction* Function::EvaluateHelper(const Class& cls, | 
|   3138                                       const String& expr, |   3052                                       const String& expr, | 
|   3139                                       const Array& param_names, |   3053                                       const Array& param_names, | 
|   3140                                       bool is_static) { |   3054                                       bool is_static) { | 
|   3141   const String& func_src = |   3055   const String& func_src = | 
|   3142       String::Handle(BuildClosureSource(param_names, expr)); |   3056       String::Handle(BuildClosureSource(param_names, expr)); | 
|   3143   Script& script = Script::Handle(); |   3057   Script& script = Script::Handle(); | 
|   3144   script = |   3058   script = | 
|   3145       Script::New(Symbols::EvalSourceUri(), func_src, RawScript::kEvaluateTag); |   3059       Script::New(Symbols::EvalSourceUri(), func_src, RawScript::kEvaluateTag); | 
|   3146   // In order to tokenize the source, we need to get the key to mangle |   3060   // In order to tokenize the source, we need to get the key to mangle | 
|   3147   // private names from the library from which the class originates. |   3061   // private names from the library from which the class originates. | 
|   3148   const Library& lib = Library::Handle(cls.library()); |   3062   const Library& lib = Library::Handle(cls.library()); | 
|   3149   ASSERT(!lib.IsNull()); |   3063   ASSERT(!lib.IsNull()); | 
|   3150   const String& lib_key = String::Handle(lib.private_key()); |   3064   const String& lib_key = String::Handle(lib.private_key()); | 
|   3151   script.Tokenize(lib_key, false); |   3065   script.Tokenize(lib_key, false); | 
|   3152  |   3066  | 
|   3153   const Function& func = |   3067   const Function& func = | 
|   3154       Function::Handle(Function::NewEvalFunction(cls, script, is_static)); |   3068       Function::Handle(Function::NewEvalFunction(cls, script, is_static)); | 
|   3155   func.set_result_type(Object::dynamic_type()); |   3069   func.set_result_type(Object::dynamic_type()); | 
|   3156   const intptr_t num_implicit_params = is_static ? 0 : 1; |   3070   const intptr_t num_implicit_params = is_static ? 0 : 1; | 
|   3157   func.set_num_fixed_parameters(num_implicit_params + param_names.Length()); |   3071   func.set_num_fixed_parameters(num_implicit_params + param_names.Length()); | 
|   3158   func.SetNumOptionalParameters(0, true); |   3072   func.SetNumOptionalParameters(0, true); | 
|   3159   func.SetIsOptimizable(false); |   3073   func.SetIsOptimizable(false); | 
|   3160   return func.raw(); |   3074   return func.raw(); | 
|   3161 } |   3075 } | 
|   3162  |   3076  | 
|   3163  |  | 
|   3164 RawObject* Class::Evaluate(const String& expr, |   3077 RawObject* Class::Evaluate(const String& expr, | 
|   3165                            const Array& param_names, |   3078                            const Array& param_names, | 
|   3166                            const Array& param_values) const { |   3079                            const Array& param_values) const { | 
|   3167   ASSERT(Thread::Current()->IsMutatorThread()); |   3080   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   3168   if (id() < kInstanceCid) { |   3081   if (id() < kInstanceCid) { | 
|   3169     const Instance& exception = Instance::Handle( |   3082     const Instance& exception = Instance::Handle( | 
|   3170         String::New("Cannot evaluate against a VM internal class")); |   3083         String::New("Cannot evaluate against a VM internal class")); | 
|   3171     const Instance& stacktrace = Instance::Handle(); |   3084     const Instance& stacktrace = Instance::Handle(); | 
|   3172     return UnhandledException::New(exception, stacktrace); |   3085     return UnhandledException::New(exception, stacktrace); | 
|   3173   } |   3086   } | 
|   3174  |   3087  | 
|   3175   const Function& eval_func = Function::Handle( |   3088   const Function& eval_func = Function::Handle( | 
|   3176       Function::EvaluateHelper(*this, expr, param_names, true)); |   3089       Function::EvaluateHelper(*this, expr, param_names, true)); | 
|   3177   const Object& result = |   3090   const Object& result = | 
|   3178       Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); |   3091       Object::Handle(DartEntry::InvokeFunction(eval_func, param_values)); | 
|   3179   return result.raw(); |   3092   return result.raw(); | 
|   3180 } |   3093 } | 
|   3181  |   3094  | 
|   3182  |  | 
|   3183 // Ensure that top level parsing of the class has been done. |   3095 // Ensure that top level parsing of the class has been done. | 
|   3184 RawError* Class::EnsureIsFinalized(Thread* thread) const { |   3096 RawError* Class::EnsureIsFinalized(Thread* thread) const { | 
|   3185   // Finalized classes have already been parsed. |   3097   // Finalized classes have already been parsed. | 
|   3186   if (is_finalized()) { |   3098   if (is_finalized()) { | 
|   3187     return Error::null(); |   3099     return Error::null(); | 
|   3188   } |   3100   } | 
|   3189   if (Compiler::IsBackgroundCompilation()) { |   3101   if (Compiler::IsBackgroundCompilation()) { | 
|   3190     Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, |   3102     Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId, | 
|   3191                                          "Class finalization while compiling"); |   3103                                          "Class finalization while compiling"); | 
|   3192   } |   3104   } | 
|   3193   ASSERT(thread->IsMutatorThread()); |   3105   ASSERT(thread->IsMutatorThread()); | 
|   3194   ASSERT(thread != NULL); |   3106   ASSERT(thread != NULL); | 
|   3195   const Error& error = |   3107   const Error& error = | 
|   3196       Error::Handle(thread->zone(), Compiler::CompileClass(*this)); |   3108       Error::Handle(thread->zone(), Compiler::CompileClass(*this)); | 
|   3197   if (!error.IsNull()) { |   3109   if (!error.IsNull()) { | 
|   3198     ASSERT(thread == Thread::Current()); |   3110     ASSERT(thread == Thread::Current()); | 
|   3199     if (thread->long_jump_base() != NULL) { |   3111     if (thread->long_jump_base() != NULL) { | 
|   3200       Report::LongJump(error); |   3112       Report::LongJump(error); | 
|   3201       UNREACHABLE(); |   3113       UNREACHABLE(); | 
|   3202     } |   3114     } | 
|   3203   } |   3115   } | 
|   3204   return error.raw(); |   3116   return error.raw(); | 
|   3205 } |   3117 } | 
|   3206  |   3118  | 
|   3207  |  | 
|   3208 void Class::SetFields(const Array& value) const { |   3119 void Class::SetFields(const Array& value) const { | 
|   3209   ASSERT(!value.IsNull()); |   3120   ASSERT(!value.IsNull()); | 
|   3210 #if defined(DEBUG) |   3121 #if defined(DEBUG) | 
|   3211   // Verify that all the fields in the array have this class as owner. |   3122   // Verify that all the fields in the array have this class as owner. | 
|   3212   Field& field = Field::Handle(); |   3123   Field& field = Field::Handle(); | 
|   3213   intptr_t len = value.Length(); |   3124   intptr_t len = value.Length(); | 
|   3214   for (intptr_t i = 0; i < len; i++) { |   3125   for (intptr_t i = 0; i < len; i++) { | 
|   3215     field ^= value.At(i); |   3126     field ^= value.At(i); | 
|   3216     ASSERT(field.IsOriginal()); |   3127     ASSERT(field.IsOriginal()); | 
|   3217     ASSERT(field.Owner() == raw()); |   3128     ASSERT(field.Owner() == raw()); | 
|   3218   } |   3129   } | 
|   3219 #endif |   3130 #endif | 
|   3220   // The value of static fields is already initialized to null. |   3131   // The value of static fields is already initialized to null. | 
|   3221   StorePointer(&raw_ptr()->fields_, value.raw()); |   3132   StorePointer(&raw_ptr()->fields_, value.raw()); | 
|   3222 } |   3133 } | 
|   3223  |   3134  | 
|   3224  |  | 
|   3225 void Class::AddField(const Field& field) const { |   3135 void Class::AddField(const Field& field) const { | 
|   3226   const Array& arr = Array::Handle(fields()); |   3136   const Array& arr = Array::Handle(fields()); | 
|   3227   const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); |   3137   const Array& new_arr = Array::Handle(Array::Grow(arr, arr.Length() + 1)); | 
|   3228   new_arr.SetAt(arr.Length(), field); |   3138   new_arr.SetAt(arr.Length(), field); | 
|   3229   SetFields(new_arr); |   3139   SetFields(new_arr); | 
|   3230 } |   3140 } | 
|   3231  |   3141  | 
|   3232  |  | 
|   3233 void Class::AddFields(const GrowableArray<const Field*>& new_fields) const { |   3142 void Class::AddFields(const GrowableArray<const Field*>& new_fields) const { | 
|   3234   const intptr_t num_new_fields = new_fields.length(); |   3143   const intptr_t num_new_fields = new_fields.length(); | 
|   3235   if (num_new_fields == 0) return; |   3144   if (num_new_fields == 0) return; | 
|   3236   const Array& arr = Array::Handle(fields()); |   3145   const Array& arr = Array::Handle(fields()); | 
|   3237   const intptr_t num_old_fields = arr.Length(); |   3146   const intptr_t num_old_fields = arr.Length(); | 
|   3238   const Array& new_arr = Array::Handle( |   3147   const Array& new_arr = Array::Handle( | 
|   3239       Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld)); |   3148       Array::Grow(arr, num_old_fields + num_new_fields, Heap::kOld)); | 
|   3240   for (intptr_t i = 0; i < num_new_fields; i++) { |   3149   for (intptr_t i = 0; i < num_new_fields; i++) { | 
|   3241     new_arr.SetAt(i + num_old_fields, *new_fields.At(i)); |   3150     new_arr.SetAt(i + num_old_fields, *new_fields.At(i)); | 
|   3242   } |   3151   } | 
|   3243   SetFields(new_arr); |   3152   SetFields(new_arr); | 
|   3244 } |   3153 } | 
|   3245  |   3154  | 
|   3246  |  | 
|   3247 void Class::InjectCIDFields() const { |   3155 void Class::InjectCIDFields() const { | 
|   3248   Thread* thread = Thread::Current(); |   3156   Thread* thread = Thread::Current(); | 
|   3249   Zone* zone = thread->zone(); |   3157   Zone* zone = thread->zone(); | 
|   3250   Field& field = Field::Handle(zone); |   3158   Field& field = Field::Handle(zone); | 
|   3251   Smi& value = Smi::Handle(zone); |   3159   Smi& value = Smi::Handle(zone); | 
|   3252   String& field_name = String::Handle(zone); |   3160   String& field_name = String::Handle(zone); | 
|   3253  |   3161  | 
|   3254 #define CLASS_LIST_WITH_NULL(V)                                                \ |   3162 #define CLASS_LIST_WITH_NULL(V)                                                \ | 
|   3255   V(Null)                                                                      \ |   3163   V(Null)                                                                      \ | 
|   3256   CLASS_LIST_NO_OBJECT(V) |   3164   CLASS_LIST_NO_OBJECT(V) | 
|   3257  |   3165  | 
|   3258 #define ADD_SET_FIELD(clazz)                                                   \ |   3166 #define ADD_SET_FIELD(clazz)                                                   \ | 
|   3259   field_name = Symbols::New(thread, "cid" #clazz);                             \ |   3167   field_name = Symbols::New(thread, "cid" #clazz);                             \ | 
|   3260   field =                                                                      \ |   3168   field =                                                                      \ | 
|   3261       Field::New(field_name, true, false, true, false, *this,                  \ |   3169       Field::New(field_name, true, false, true, false, *this,                  \ | 
|   3262                  Type::Handle(Type::IntType()), TokenPosition::kMinSource);    \ |   3170                  Type::Handle(Type::IntType()), TokenPosition::kMinSource);    \ | 
|   3263   value = Smi::New(k##clazz##Cid);                                             \ |   3171   value = Smi::New(k##clazz##Cid);                                             \ | 
|   3264   field.SetStaticValue(value, true);                                           \ |   3172   field.SetStaticValue(value, true);                                           \ | 
|   3265   AddField(field); |   3173   AddField(field); | 
|   3266  |   3174  | 
|   3267   CLASS_LIST_WITH_NULL(ADD_SET_FIELD) |   3175   CLASS_LIST_WITH_NULL(ADD_SET_FIELD) | 
|   3268 #undef ADD_SET_FIELD |   3176 #undef ADD_SET_FIELD | 
|   3269 #undef CLASS_LIST_WITH_NULL |   3177 #undef CLASS_LIST_WITH_NULL | 
|   3270 } |   3178 } | 
|   3271  |   3179  | 
|   3272  |  | 
|   3273 template <class FakeInstance> |   3180 template <class FakeInstance> | 
|   3274 RawClass* Class::NewCommon(intptr_t index) { |   3181 RawClass* Class::NewCommon(intptr_t index) { | 
|   3275   ASSERT(Object::class_class() != Class::null()); |   3182   ASSERT(Object::class_class() != Class::null()); | 
|   3276   Class& result = Class::Handle(); |   3183   Class& result = Class::Handle(); | 
|   3277   { |   3184   { | 
|   3278     RawObject* raw = |   3185     RawObject* raw = | 
|   3279         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); |   3186         Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld); | 
|   3280     NoSafepointScope no_safepoint; |   3187     NoSafepointScope no_safepoint; | 
|   3281     result ^= raw; |   3188     result ^= raw; | 
|   3282   } |   3189   } | 
|   3283   FakeInstance fake; |   3190   FakeInstance fake; | 
|   3284   ASSERT(fake.IsInstance()); |   3191   ASSERT(fake.IsInstance()); | 
|   3285   result.set_handle_vtable(fake.vtable()); |   3192   result.set_handle_vtable(fake.vtable()); | 
|   3286   result.set_instance_size(FakeInstance::InstanceSize()); |   3193   result.set_instance_size(FakeInstance::InstanceSize()); | 
|   3287   result.set_next_field_offset(FakeInstance::NextFieldOffset()); |   3194   result.set_next_field_offset(FakeInstance::NextFieldOffset()); | 
|   3288   result.set_id(index); |   3195   result.set_id(index); | 
|   3289   result.set_state_bits(0); |   3196   result.set_state_bits(0); | 
|   3290   result.set_type_arguments_field_offset_in_words(kNoTypeArguments); |   3197   result.set_type_arguments_field_offset_in_words(kNoTypeArguments); | 
|   3291   result.set_num_type_arguments(kUnknownNumTypeArguments); |   3198   result.set_num_type_arguments(kUnknownNumTypeArguments); | 
|   3292   result.set_num_own_type_arguments(kUnknownNumTypeArguments); |   3199   result.set_num_own_type_arguments(kUnknownNumTypeArguments); | 
|   3293   result.set_num_native_fields(0); |   3200   result.set_num_native_fields(0); | 
|   3294   result.set_token_pos(TokenPosition::kNoSource); |   3201   result.set_token_pos(TokenPosition::kNoSource); | 
|   3295   result.InitEmptyFields(); |   3202   result.InitEmptyFields(); | 
|   3296   return result.raw(); |   3203   return result.raw(); | 
|   3297 } |   3204 } | 
|   3298  |   3205  | 
|   3299  |  | 
|   3300 template <class FakeInstance> |   3206 template <class FakeInstance> | 
|   3301 RawClass* Class::New(intptr_t index) { |   3207 RawClass* Class::New(intptr_t index) { | 
|   3302   Class& result = Class::Handle(NewCommon<FakeInstance>(index)); |   3208   Class& result = Class::Handle(NewCommon<FakeInstance>(index)); | 
|   3303   Isolate::Current()->RegisterClass(result); |   3209   Isolate::Current()->RegisterClass(result); | 
|   3304   return result.raw(); |   3210   return result.raw(); | 
|   3305 } |   3211 } | 
|   3306  |   3212  | 
|   3307  |  | 
|   3308 RawClass* Class::New(const Library& lib, |   3213 RawClass* Class::New(const Library& lib, | 
|   3309                      const String& name, |   3214                      const String& name, | 
|   3310                      const Script& script, |   3215                      const Script& script, | 
|   3311                      TokenPosition token_pos) { |   3216                      TokenPosition token_pos) { | 
|   3312   Class& result = Class::Handle(NewCommon<Instance>(kIllegalCid)); |   3217   Class& result = Class::Handle(NewCommon<Instance>(kIllegalCid)); | 
|   3313   result.set_library(lib); |   3218   result.set_library(lib); | 
|   3314   result.set_name(name); |   3219   result.set_name(name); | 
|   3315   result.set_script(script); |   3220   result.set_script(script); | 
|   3316   result.set_token_pos(token_pos); |   3221   result.set_token_pos(token_pos); | 
|   3317   Isolate::Current()->RegisterClass(result); |   3222   Isolate::Current()->RegisterClass(result); | 
|   3318   return result.raw(); |   3223   return result.raw(); | 
|   3319 } |   3224 } | 
|   3320  |   3225  | 
|   3321  |  | 
|   3322 RawClass* Class::NewInstanceClass() { |   3226 RawClass* Class::NewInstanceClass() { | 
|   3323   return Class::New<Instance>(kIllegalCid); |   3227   return Class::New<Instance>(kIllegalCid); | 
|   3324 } |   3228 } | 
|   3325  |   3229  | 
|   3326  |  | 
|   3327 RawClass* Class::NewNativeWrapper(const Library& library, |   3230 RawClass* Class::NewNativeWrapper(const Library& library, | 
|   3328                                   const String& name, |   3231                                   const String& name, | 
|   3329                                   int field_count) { |   3232                                   int field_count) { | 
|   3330   Class& cls = Class::Handle(library.LookupClass(name)); |   3233   Class& cls = Class::Handle(library.LookupClass(name)); | 
|   3331   if (cls.IsNull()) { |   3234   if (cls.IsNull()) { | 
|   3332     cls = New(library, name, Script::Handle(), TokenPosition::kNoSource); |   3235     cls = New(library, name, Script::Handle(), TokenPosition::kNoSource); | 
|   3333     cls.SetFields(Object::empty_array()); |   3236     cls.SetFields(Object::empty_array()); | 
|   3334     cls.SetFunctions(Object::empty_array()); |   3237     cls.SetFunctions(Object::empty_array()); | 
|   3335     // Set super class to Object. |   3238     // Set super class to Object. | 
|   3336     cls.set_super_type(Type::Handle(Type::ObjectType())); |   3239     cls.set_super_type(Type::Handle(Type::ObjectType())); | 
|   3337     // Compute instance size. First word contains a pointer to a properly |   3240     // Compute instance size. First word contains a pointer to a properly | 
|   3338     // sized typed array once the first native field has been set. |   3241     // sized typed array once the first native field has been set. | 
|   3339     intptr_t instance_size = sizeof(RawInstance) + kWordSize; |   3242     intptr_t instance_size = sizeof(RawInstance) + kWordSize; | 
|   3340     cls.set_instance_size(RoundedAllocationSize(instance_size)); |   3243     cls.set_instance_size(RoundedAllocationSize(instance_size)); | 
|   3341     cls.set_next_field_offset(instance_size); |   3244     cls.set_next_field_offset(instance_size); | 
|   3342     cls.set_num_native_fields(field_count); |   3245     cls.set_num_native_fields(field_count); | 
|   3343     cls.set_is_finalized(); |   3246     cls.set_is_finalized(); | 
|   3344     cls.set_is_type_finalized(); |   3247     cls.set_is_type_finalized(); | 
|   3345     cls.set_is_synthesized_class(); |   3248     cls.set_is_synthesized_class(); | 
|   3346     cls.set_is_cycle_free(); |   3249     cls.set_is_cycle_free(); | 
|   3347     library.AddClass(cls); |   3250     library.AddClass(cls); | 
|   3348     return cls.raw(); |   3251     return cls.raw(); | 
|   3349   } else { |   3252   } else { | 
|   3350     return Class::null(); |   3253     return Class::null(); | 
|   3351   } |   3254   } | 
|   3352 } |   3255 } | 
|   3353  |   3256  | 
|   3354  |  | 
|   3355 RawClass* Class::NewStringClass(intptr_t class_id) { |   3257 RawClass* Class::NewStringClass(intptr_t class_id) { | 
|   3356   intptr_t instance_size; |   3258   intptr_t instance_size; | 
|   3357   if (class_id == kOneByteStringCid) { |   3259   if (class_id == kOneByteStringCid) { | 
|   3358     instance_size = OneByteString::InstanceSize(); |   3260     instance_size = OneByteString::InstanceSize(); | 
|   3359   } else if (class_id == kTwoByteStringCid) { |   3261   } else if (class_id == kTwoByteStringCid) { | 
|   3360     instance_size = TwoByteString::InstanceSize(); |   3262     instance_size = TwoByteString::InstanceSize(); | 
|   3361   } else if (class_id == kExternalOneByteStringCid) { |   3263   } else if (class_id == kExternalOneByteStringCid) { | 
|   3362     instance_size = ExternalOneByteString::InstanceSize(); |   3264     instance_size = ExternalOneByteString::InstanceSize(); | 
|   3363   } else { |   3265   } else { | 
|   3364     ASSERT(class_id == kExternalTwoByteStringCid); |   3266     ASSERT(class_id == kExternalTwoByteStringCid); | 
|   3365     instance_size = ExternalTwoByteString::InstanceSize(); |   3267     instance_size = ExternalTwoByteString::InstanceSize(); | 
|   3366   } |   3268   } | 
|   3367   Class& result = Class::Handle(New<String>(class_id)); |   3269   Class& result = Class::Handle(New<String>(class_id)); | 
|   3368   result.set_instance_size(instance_size); |   3270   result.set_instance_size(instance_size); | 
|   3369   result.set_next_field_offset(String::NextFieldOffset()); |   3271   result.set_next_field_offset(String::NextFieldOffset()); | 
|   3370   result.set_is_prefinalized(); |   3272   result.set_is_prefinalized(); | 
|   3371   return result.raw(); |   3273   return result.raw(); | 
|   3372 } |   3274 } | 
|   3373  |   3275  | 
|   3374  |  | 
|   3375 RawClass* Class::NewTypedDataClass(intptr_t class_id) { |   3276 RawClass* Class::NewTypedDataClass(intptr_t class_id) { | 
|   3376   ASSERT(RawObject::IsTypedDataClassId(class_id)); |   3277   ASSERT(RawObject::IsTypedDataClassId(class_id)); | 
|   3377   intptr_t instance_size = TypedData::InstanceSize(); |   3278   intptr_t instance_size = TypedData::InstanceSize(); | 
|   3378   Class& result = Class::Handle(New<TypedData>(class_id)); |   3279   Class& result = Class::Handle(New<TypedData>(class_id)); | 
|   3379   result.set_instance_size(instance_size); |   3280   result.set_instance_size(instance_size); | 
|   3380   result.set_next_field_offset(TypedData::NextFieldOffset()); |   3281   result.set_next_field_offset(TypedData::NextFieldOffset()); | 
|   3381   result.set_is_prefinalized(); |   3282   result.set_is_prefinalized(); | 
|   3382   return result.raw(); |   3283   return result.raw(); | 
|   3383 } |   3284 } | 
|   3384  |   3285  | 
|   3385  |  | 
|   3386 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) { |   3286 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) { | 
|   3387   ASSERT(RawObject::IsTypedDataViewClassId(class_id)); |   3287   ASSERT(RawObject::IsTypedDataViewClassId(class_id)); | 
|   3388   Class& result = Class::Handle(New<Instance>(class_id)); |   3288   Class& result = Class::Handle(New<Instance>(class_id)); | 
|   3389   result.set_instance_size(0); |   3289   result.set_instance_size(0); | 
|   3390   result.set_next_field_offset(-kWordSize); |   3290   result.set_next_field_offset(-kWordSize); | 
|   3391   return result.raw(); |   3291   return result.raw(); | 
|   3392 } |   3292 } | 
|   3393  |   3293  | 
|   3394  |  | 
|   3395 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) { |   3294 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) { | 
|   3396   ASSERT(RawObject::IsExternalTypedDataClassId(class_id)); |   3295   ASSERT(RawObject::IsExternalTypedDataClassId(class_id)); | 
|   3397   intptr_t instance_size = ExternalTypedData::InstanceSize(); |   3296   intptr_t instance_size = ExternalTypedData::InstanceSize(); | 
|   3398   Class& result = Class::Handle(New<ExternalTypedData>(class_id)); |   3297   Class& result = Class::Handle(New<ExternalTypedData>(class_id)); | 
|   3399   result.set_instance_size(instance_size); |   3298   result.set_instance_size(instance_size); | 
|   3400   result.set_next_field_offset(ExternalTypedData::NextFieldOffset()); |   3299   result.set_next_field_offset(ExternalTypedData::NextFieldOffset()); | 
|   3401   result.set_is_prefinalized(); |   3300   result.set_is_prefinalized(); | 
|   3402   return result.raw(); |   3301   return result.raw(); | 
|   3403 } |   3302 } | 
|   3404  |   3303  | 
|   3405  |  | 
|   3406 void Class::set_name(const String& value) const { |   3304 void Class::set_name(const String& value) const { | 
|   3407   ASSERT(raw_ptr()->name_ == String::null()); |   3305   ASSERT(raw_ptr()->name_ == String::null()); | 
|   3408   ASSERT(value.IsSymbol()); |   3306   ASSERT(value.IsSymbol()); | 
|   3409   StorePointer(&raw_ptr()->name_, value.raw()); |   3307   StorePointer(&raw_ptr()->name_, value.raw()); | 
|   3410 #if !defined(PRODUCT) |   3308 #if !defined(PRODUCT) | 
|   3411   if (raw_ptr()->user_name_ == String::null()) { |   3309   if (raw_ptr()->user_name_ == String::null()) { | 
|   3412     // TODO(johnmccutchan): Eagerly set user name for VM isolate classes, |   3310     // TODO(johnmccutchan): Eagerly set user name for VM isolate classes, | 
|   3413     // lazily set user name for the other classes. |   3311     // lazily set user name for the other classes. | 
|   3414     // Generate and set user_name. |   3312     // Generate and set user_name. | 
|   3415     const String& user_name = String::Handle(GenerateUserVisibleName()); |   3313     const String& user_name = String::Handle(GenerateUserVisibleName()); | 
|   3416     set_user_name(user_name); |   3314     set_user_name(user_name); | 
|   3417   } |   3315   } | 
|   3418 #endif  // !defined(PRODUCT) |   3316 #endif  // !defined(PRODUCT) | 
|   3419 } |   3317 } | 
|   3420  |   3318  | 
|   3421  |  | 
|   3422 #if !defined(PRODUCT) |   3319 #if !defined(PRODUCT) | 
|   3423 void Class::set_user_name(const String& value) const { |   3320 void Class::set_user_name(const String& value) const { | 
|   3424   StorePointer(&raw_ptr()->user_name_, value.raw()); |   3321   StorePointer(&raw_ptr()->user_name_, value.raw()); | 
|   3425 } |   3322 } | 
|   3426 #endif  // !defined(PRODUCT) |   3323 #endif  // !defined(PRODUCT) | 
|   3427  |   3324  | 
|   3428  |  | 
|   3429 RawString* Class::GenerateUserVisibleName() const { |   3325 RawString* Class::GenerateUserVisibleName() const { | 
|   3430   if (FLAG_show_internal_names) { |   3326   if (FLAG_show_internal_names) { | 
|   3431     return Name(); |   3327     return Name(); | 
|   3432   } |   3328   } | 
|   3433   switch (id()) { |   3329   switch (id()) { | 
|   3434     case kFloat32x4Cid: |   3330     case kFloat32x4Cid: | 
|   3435       return Symbols::Float32x4().raw(); |   3331       return Symbols::Float32x4().raw(); | 
|   3436     case kInt32x4Cid: |   3332     case kInt32x4Cid: | 
|   3437       return Symbols::Int32x4().raw(); |   3333       return Symbols::Int32x4().raw(); | 
|   3438     case kTypedDataInt8ArrayCid: |   3334     case kTypedDataInt8ArrayCid: | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3566     case kArrayCid: |   3462     case kArrayCid: | 
|   3567     case kImmutableArrayCid: |   3463     case kImmutableArrayCid: | 
|   3568     case kGrowableObjectArrayCid: |   3464     case kGrowableObjectArrayCid: | 
|   3569       return Symbols::List().raw(); |   3465       return Symbols::List().raw(); | 
|   3570 #endif  // !defined(PRODUCT) |   3466 #endif  // !defined(PRODUCT) | 
|   3571   } |   3467   } | 
|   3572   const String& name = String::Handle(Name()); |   3468   const String& name = String::Handle(Name()); | 
|   3573   return String::ScrubName(name); |   3469   return String::ScrubName(name); | 
|   3574 } |   3470 } | 
|   3575  |   3471  | 
|   3576  |  | 
|   3577 void Class::set_script(const Script& value) const { |   3472 void Class::set_script(const Script& value) const { | 
|   3578   StorePointer(&raw_ptr()->script_, value.raw()); |   3473   StorePointer(&raw_ptr()->script_, value.raw()); | 
|   3579 } |   3474 } | 
|   3580  |   3475  | 
|   3581  |  | 
|   3582 void Class::set_token_pos(TokenPosition token_pos) const { |   3476 void Class::set_token_pos(TokenPosition token_pos) const { | 
|   3583   ASSERT(!token_pos.IsClassifying()); |   3477   ASSERT(!token_pos.IsClassifying()); | 
|   3584   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |   3478   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|   3585 } |   3479 } | 
|   3586  |   3480  | 
|   3587  |  | 
|   3588 TokenPosition Class::ComputeEndTokenPos() const { |   3481 TokenPosition Class::ComputeEndTokenPos() const { | 
|   3589   // Return the begin token for synthetic classes. |   3482   // Return the begin token for synthetic classes. | 
|   3590   if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) { |   3483   if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) { | 
|   3591     return token_pos(); |   3484     return token_pos(); | 
|   3592   } |   3485   } | 
|   3593  |   3486  | 
|   3594   Zone* zone = Thread::Current()->zone(); |   3487   Zone* zone = Thread::Current()->zone(); | 
|   3595   const Script& scr = Script::Handle(zone, script()); |   3488   const Script& scr = Script::Handle(zone, script()); | 
|   3596   ASSERT(!scr.IsNull()); |   3489   ASSERT(!scr.IsNull()); | 
|   3597  |   3490  | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3629       if (--level == 0) { |   3522       if (--level == 0) { | 
|   3630         return tkit.CurrentPosition(); |   3523         return tkit.CurrentPosition(); | 
|   3631       } |   3524       } | 
|   3632     } |   3525     } | 
|   3633     tkit.Advance(); |   3526     tkit.Advance(); | 
|   3634   } |   3527   } | 
|   3635   UNREACHABLE(); |   3528   UNREACHABLE(); | 
|   3636   return TokenPosition::kNoSource; |   3529   return TokenPosition::kNoSource; | 
|   3637 } |   3530 } | 
|   3638  |   3531  | 
|   3639  |  | 
|   3640 void Class::set_is_implemented() const { |   3532 void Class::set_is_implemented() const { | 
|   3641   set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_)); |   3533   set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_)); | 
|   3642 } |   3534 } | 
|   3643  |   3535  | 
|   3644  |  | 
|   3645 void Class::set_is_abstract() const { |   3536 void Class::set_is_abstract() const { | 
|   3646   set_state_bits(AbstractBit::update(true, raw_ptr()->state_bits_)); |   3537   set_state_bits(AbstractBit::update(true, raw_ptr()->state_bits_)); | 
|   3647 } |   3538 } | 
|   3648  |   3539  | 
|   3649  |  | 
|   3650 void Class::set_is_type_finalized() const { |   3540 void Class::set_is_type_finalized() const { | 
|   3651   set_state_bits(TypeFinalizedBit::update(true, raw_ptr()->state_bits_)); |   3541   set_state_bits(TypeFinalizedBit::update(true, raw_ptr()->state_bits_)); | 
|   3652 } |   3542 } | 
|   3653  |   3543  | 
|   3654  |  | 
|   3655 void Class::set_is_patch() const { |   3544 void Class::set_is_patch() const { | 
|   3656   set_state_bits(PatchBit::update(true, raw_ptr()->state_bits_)); |   3545   set_state_bits(PatchBit::update(true, raw_ptr()->state_bits_)); | 
|   3657 } |   3546 } | 
|   3658  |   3547  | 
|   3659  |  | 
|   3660 void Class::set_is_synthesized_class() const { |   3548 void Class::set_is_synthesized_class() const { | 
|   3661   set_state_bits(SynthesizedClassBit::update(true, raw_ptr()->state_bits_)); |   3549   set_state_bits(SynthesizedClassBit::update(true, raw_ptr()->state_bits_)); | 
|   3662 } |   3550 } | 
|   3663  |   3551  | 
|   3664  |  | 
|   3665 void Class::set_is_enum_class() const { |   3552 void Class::set_is_enum_class() const { | 
|   3666   set_state_bits(EnumBit::update(true, raw_ptr()->state_bits_)); |   3553   set_state_bits(EnumBit::update(true, raw_ptr()->state_bits_)); | 
|   3667 } |   3554 } | 
|   3668  |   3555  | 
|   3669  |  | 
|   3670 void Class::set_is_const() const { |   3556 void Class::set_is_const() const { | 
|   3671   set_state_bits(ConstBit::update(true, raw_ptr()->state_bits_)); |   3557   set_state_bits(ConstBit::update(true, raw_ptr()->state_bits_)); | 
|   3672 } |   3558 } | 
|   3673  |   3559  | 
|   3674  |  | 
|   3675 void Class::set_is_mixin_app_alias() const { |   3560 void Class::set_is_mixin_app_alias() const { | 
|   3676   set_state_bits(MixinAppAliasBit::update(true, raw_ptr()->state_bits_)); |   3561   set_state_bits(MixinAppAliasBit::update(true, raw_ptr()->state_bits_)); | 
|   3677 } |   3562 } | 
|   3678  |   3563  | 
|   3679  |  | 
|   3680 void Class::set_is_mixin_type_applied() const { |   3564 void Class::set_is_mixin_type_applied() const { | 
|   3681   set_state_bits(MixinTypeAppliedBit::update(true, raw_ptr()->state_bits_)); |   3565   set_state_bits(MixinTypeAppliedBit::update(true, raw_ptr()->state_bits_)); | 
|   3682 } |   3566 } | 
|   3683  |   3567  | 
|   3684  |  | 
|   3685 void Class::set_is_fields_marked_nullable() const { |   3568 void Class::set_is_fields_marked_nullable() const { | 
|   3686   set_state_bits(FieldsMarkedNullableBit::update(true, raw_ptr()->state_bits_)); |   3569   set_state_bits(FieldsMarkedNullableBit::update(true, raw_ptr()->state_bits_)); | 
|   3687 } |   3570 } | 
|   3688  |   3571  | 
|   3689  |  | 
|   3690 void Class::set_is_cycle_free() const { |   3572 void Class::set_is_cycle_free() const { | 
|   3691   ASSERT(!is_cycle_free()); |   3573   ASSERT(!is_cycle_free()); | 
|   3692   set_state_bits(CycleFreeBit::update(true, raw_ptr()->state_bits_)); |   3574   set_state_bits(CycleFreeBit::update(true, raw_ptr()->state_bits_)); | 
|   3693 } |   3575 } | 
|   3694  |   3576  | 
|   3695  |  | 
|   3696 void Class::set_is_allocated(bool value) const { |   3577 void Class::set_is_allocated(bool value) const { | 
|   3697   set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_)); |   3578   set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_)); | 
|   3698 } |   3579 } | 
|   3699  |   3580  | 
|   3700  |  | 
|   3701 void Class::set_is_finalized() const { |   3581 void Class::set_is_finalized() const { | 
|   3702   ASSERT(!is_finalized()); |   3582   ASSERT(!is_finalized()); | 
|   3703   set_state_bits( |   3583   set_state_bits( | 
|   3704       ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_)); |   3584       ClassFinalizedBits::update(RawClass::kFinalized, raw_ptr()->state_bits_)); | 
|   3705 } |   3585 } | 
|   3706  |   3586  | 
|   3707  |  | 
|   3708 void Class::SetRefinalizeAfterPatch() const { |   3587 void Class::SetRefinalizeAfterPatch() const { | 
|   3709   ASSERT(!IsTopLevel()); |   3588   ASSERT(!IsTopLevel()); | 
|   3710   set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch, |   3589   set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch, | 
|   3711                                             raw_ptr()->state_bits_)); |   3590                                             raw_ptr()->state_bits_)); | 
|   3712   set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); |   3591   set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); | 
|   3713 } |   3592 } | 
|   3714  |   3593  | 
|   3715  |  | 
|   3716 void Class::ResetFinalization() const { |   3594 void Class::ResetFinalization() const { | 
|   3717   ASSERT(IsTopLevel() || IsClosureClass()); |   3595   ASSERT(IsTopLevel() || IsClosureClass()); | 
|   3718   set_state_bits( |   3596   set_state_bits( | 
|   3719       ClassFinalizedBits::update(RawClass::kAllocated, raw_ptr()->state_bits_)); |   3597       ClassFinalizedBits::update(RawClass::kAllocated, raw_ptr()->state_bits_)); | 
|   3720   set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); |   3598   set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); | 
|   3721 } |   3599 } | 
|   3722  |   3600  | 
|   3723  |  | 
|   3724 void Class::set_is_prefinalized() const { |   3601 void Class::set_is_prefinalized() const { | 
|   3725   ASSERT(!is_finalized()); |   3602   ASSERT(!is_finalized()); | 
|   3726   set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized, |   3603   set_state_bits(ClassFinalizedBits::update(RawClass::kPreFinalized, | 
|   3727                                             raw_ptr()->state_bits_)); |   3604                                             raw_ptr()->state_bits_)); | 
|   3728 } |   3605 } | 
|   3729  |   3606  | 
|   3730  |  | 
|   3731 void Class::set_is_marked_for_parsing() const { |   3607 void Class::set_is_marked_for_parsing() const { | 
|   3732   set_state_bits(MarkedForParsingBit::update(true, raw_ptr()->state_bits_)); |   3608   set_state_bits(MarkedForParsingBit::update(true, raw_ptr()->state_bits_)); | 
|   3733 } |   3609 } | 
|   3734  |   3610  | 
|   3735  |  | 
|   3736 void Class::reset_is_marked_for_parsing() const { |   3611 void Class::reset_is_marked_for_parsing() const { | 
|   3737   set_state_bits(MarkedForParsingBit::update(false, raw_ptr()->state_bits_)); |   3612   set_state_bits(MarkedForParsingBit::update(false, raw_ptr()->state_bits_)); | 
|   3738 } |   3613 } | 
|   3739  |   3614  | 
|   3740  |  | 
|   3741 void Class::set_interfaces(const Array& value) const { |   3615 void Class::set_interfaces(const Array& value) const { | 
|   3742   ASSERT(!value.IsNull()); |   3616   ASSERT(!value.IsNull()); | 
|   3743   StorePointer(&raw_ptr()->interfaces_, value.raw()); |   3617   StorePointer(&raw_ptr()->interfaces_, value.raw()); | 
|   3744 } |   3618 } | 
|   3745  |   3619  | 
|   3746  |  | 
|   3747 void Class::set_mixin(const Type& value) const { |   3620 void Class::set_mixin(const Type& value) const { | 
|   3748   ASSERT(!value.IsNull()); |   3621   ASSERT(!value.IsNull()); | 
|   3749   StorePointer(&raw_ptr()->mixin_, value.raw()); |   3622   StorePointer(&raw_ptr()->mixin_, value.raw()); | 
|   3750 } |   3623 } | 
|   3751  |   3624  | 
|   3752  |  | 
|   3753 bool Class::IsMixinApplication() const { |   3625 bool Class::IsMixinApplication() const { | 
|   3754   return mixin() != Type::null(); |   3626   return mixin() != Type::null(); | 
|   3755 } |   3627 } | 
|   3756  |   3628  | 
|   3757  |  | 
|   3758 RawClass* Class::GetPatchClass() const { |   3629 RawClass* Class::GetPatchClass() const { | 
|   3759   const Library& lib = Library::Handle(library()); |   3630   const Library& lib = Library::Handle(library()); | 
|   3760   return lib.GetPatchClass(String::Handle(Name())); |   3631   return lib.GetPatchClass(String::Handle(Name())); | 
|   3761 } |   3632 } | 
|   3762  |   3633  | 
|   3763  |  | 
|   3764 void Class::AddDirectSubclass(const Class& subclass) const { |   3634 void Class::AddDirectSubclass(const Class& subclass) const { | 
|   3765   ASSERT(!subclass.IsNull()); |   3635   ASSERT(!subclass.IsNull()); | 
|   3766   ASSERT(subclass.SuperClass() == raw()); |   3636   ASSERT(subclass.SuperClass() == raw()); | 
|   3767   // Do not keep track of the direct subclasses of class Object. |   3637   // Do not keep track of the direct subclasses of class Object. | 
|   3768   ASSERT(!IsObjectClass()); |   3638   ASSERT(!IsObjectClass()); | 
|   3769   GrowableObjectArray& direct_subclasses = |   3639   GrowableObjectArray& direct_subclasses = | 
|   3770       GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); |   3640       GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); | 
|   3771   if (direct_subclasses.IsNull()) { |   3641   if (direct_subclasses.IsNull()) { | 
|   3772     direct_subclasses = GrowableObjectArray::New(4, Heap::kOld); |   3642     direct_subclasses = GrowableObjectArray::New(4, Heap::kOld); | 
|   3773     StorePointer(&raw_ptr()->direct_subclasses_, direct_subclasses.raw()); |   3643     StorePointer(&raw_ptr()->direct_subclasses_, direct_subclasses.raw()); | 
|   3774   } |   3644   } | 
|   3775 #if defined(DEBUG) |   3645 #if defined(DEBUG) | 
|   3776   // Verify that the same class is not added twice. |   3646   // Verify that the same class is not added twice. | 
|   3777   for (intptr_t i = 0; i < direct_subclasses.Length(); i++) { |   3647   for (intptr_t i = 0; i < direct_subclasses.Length(); i++) { | 
|   3778     ASSERT(direct_subclasses.At(i) != subclass.raw()); |   3648     ASSERT(direct_subclasses.At(i) != subclass.raw()); | 
|   3779   } |   3649   } | 
|   3780 #endif |   3650 #endif | 
|   3781   direct_subclasses.Add(subclass, Heap::kOld); |   3651   direct_subclasses.Add(subclass, Heap::kOld); | 
|   3782 } |   3652 } | 
|   3783  |   3653  | 
|   3784  |  | 
|   3785 void Class::ClearDirectSubclasses() const { |   3654 void Class::ClearDirectSubclasses() const { | 
|   3786   StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null()); |   3655   StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null()); | 
|   3787 } |   3656 } | 
|   3788  |   3657  | 
|   3789  |  | 
|   3790 RawArray* Class::constants() const { |   3658 RawArray* Class::constants() const { | 
|   3791   return raw_ptr()->constants_; |   3659   return raw_ptr()->constants_; | 
|   3792 } |   3660 } | 
|   3793  |   3661  | 
|   3794 void Class::set_constants(const Array& value) const { |   3662 void Class::set_constants(const Array& value) const { | 
|   3795   ASSERT(!value.IsNull()); |   3663   ASSERT(!value.IsNull()); | 
|   3796   StorePointer(&raw_ptr()->constants_, value.raw()); |   3664   StorePointer(&raw_ptr()->constants_, value.raw()); | 
|   3797 } |   3665 } | 
|   3798  |   3666  | 
|   3799  |  | 
|   3800 RawType* Class::canonical_type() const { |   3667 RawType* Class::canonical_type() const { | 
|   3801   return raw_ptr()->canonical_type_; |   3668   return raw_ptr()->canonical_type_; | 
|   3802 } |   3669 } | 
|   3803  |   3670  | 
|   3804  |  | 
|   3805 void Class::set_canonical_type(const Type& value) const { |   3671 void Class::set_canonical_type(const Type& value) const { | 
|   3806   ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld()); |   3672   ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld()); | 
|   3807   StorePointer(&raw_ptr()->canonical_type_, value.raw()); |   3673   StorePointer(&raw_ptr()->canonical_type_, value.raw()); | 
|   3808 } |   3674 } | 
|   3809  |   3675  | 
|   3810  |  | 
|   3811 RawType* Class::CanonicalType() const { |   3676 RawType* Class::CanonicalType() const { | 
|   3812   return raw_ptr()->canonical_type_; |   3677   return raw_ptr()->canonical_type_; | 
|   3813 } |   3678 } | 
|   3814  |   3679  | 
|   3815  |  | 
|   3816 void Class::SetCanonicalType(const Type& type) const { |   3680 void Class::SetCanonicalType(const Type& type) const { | 
|   3817   ASSERT((canonical_type() == Object::null()) || |   3681   ASSERT((canonical_type() == Object::null()) || | 
|   3818          (canonical_type() == type.raw()));  // Set during own finalization. |   3682          (canonical_type() == type.raw()));  // Set during own finalization. | 
|   3819   set_canonical_type(type); |   3683   set_canonical_type(type); | 
|   3820 } |   3684 } | 
|   3821  |   3685  | 
|   3822  |  | 
|   3823 void Class::set_allocation_stub(const Code& value) const { |   3686 void Class::set_allocation_stub(const Code& value) const { | 
|   3824   // Never clear the stub as it may still be a target, but will be GC-d if |   3687   // Never clear the stub as it may still be a target, but will be GC-d if | 
|   3825   // not referenced. |   3688   // not referenced. | 
|   3826   ASSERT(!value.IsNull()); |   3689   ASSERT(!value.IsNull()); | 
|   3827   ASSERT(raw_ptr()->allocation_stub_ == Code::null()); |   3690   ASSERT(raw_ptr()->allocation_stub_ == Code::null()); | 
|   3828   StorePointer(&raw_ptr()->allocation_stub_, value.raw()); |   3691   StorePointer(&raw_ptr()->allocation_stub_, value.raw()); | 
|   3829 } |   3692 } | 
|   3830  |   3693  | 
|   3831  |  | 
|   3832 void Class::DisableAllocationStub() const { |   3694 void Class::DisableAllocationStub() const { | 
|   3833   const Code& existing_stub = Code::Handle(allocation_stub()); |   3695   const Code& existing_stub = Code::Handle(allocation_stub()); | 
|   3834   if (existing_stub.IsNull()) { |   3696   if (existing_stub.IsNull()) { | 
|   3835     return; |   3697     return; | 
|   3836   } |   3698   } | 
|   3837   ASSERT(!existing_stub.IsDisabled()); |   3699   ASSERT(!existing_stub.IsDisabled()); | 
|   3838   // Change the stub so that the next caller will regenerate the stub. |   3700   // Change the stub so that the next caller will regenerate the stub. | 
|   3839   existing_stub.DisableStubCode(); |   3701   existing_stub.DisableStubCode(); | 
|   3840   // Disassociate the existing stub from class. |   3702   // Disassociate the existing stub from class. | 
|   3841   StorePointer(&raw_ptr()->allocation_stub_, Code::null()); |   3703   StorePointer(&raw_ptr()->allocation_stub_, Code::null()); | 
|   3842 } |   3704 } | 
|   3843  |   3705  | 
|   3844  |  | 
|   3845 bool Class::IsDartFunctionClass() const { |   3706 bool Class::IsDartFunctionClass() const { | 
|   3846   return raw() == Type::Handle(Type::DartFunctionType()).type_class(); |   3707   return raw() == Type::Handle(Type::DartFunctionType()).type_class(); | 
|   3847 } |   3708 } | 
|   3848  |   3709  | 
|   3849  |  | 
|   3850 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |   3710 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. | 
|   3851 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |   3711 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. | 
|   3852 // Type S is specified by this class parameterized with 'type_arguments', and |   3712 // Type S is specified by this class parameterized with 'type_arguments', and | 
|   3853 // type T by class 'other' parameterized with 'other_type_arguments'. |   3713 // type T by class 'other' parameterized with 'other_type_arguments'. | 
|   3854 // This class and class 'other' do not need to be finalized, however, they must |   3714 // This class and class 'other' do not need to be finalized, however, they must | 
|   3855 // be resolved as well as their interfaces. |   3715 // be resolved as well as their interfaces. | 
|   3856 bool Class::TypeTestNonRecursive(const Class& cls, |   3716 bool Class::TypeTestNonRecursive(const Class& cls, | 
|   3857                                  Class::TypeTestKind test_kind, |   3717                                  Class::TypeTestKind test_kind, | 
|   3858                                  const TypeArguments& type_arguments, |   3718                                  const TypeArguments& type_arguments, | 
|   3859                                  const Class& other, |   3719                                  const Class& other, | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3987     // "Recurse" up the class hierarchy until we have reached the top. |   3847     // "Recurse" up the class hierarchy until we have reached the top. | 
|   3988     thsi = thsi.SuperClass(); |   3848     thsi = thsi.SuperClass(); | 
|   3989     if (thsi.IsNull()) { |   3849     if (thsi.IsNull()) { | 
|   3990       return false; |   3850       return false; | 
|   3991     } |   3851     } | 
|   3992   } |   3852   } | 
|   3993   UNREACHABLE(); |   3853   UNREACHABLE(); | 
|   3994   return false; |   3854   return false; | 
|   3995 } |   3855 } | 
|   3996  |   3856  | 
|   3997  |  | 
|   3998 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. |   3857 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T. | 
|   3999 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. |   3858 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. | 
|   4000 // Type S is specified by this class parameterized with 'type_arguments', and |   3859 // Type S is specified by this class parameterized with 'type_arguments', and | 
|   4001 // type T by class 'other' parameterized with 'other_type_arguments'. |   3860 // type T by class 'other' parameterized with 'other_type_arguments'. | 
|   4002 // This class and class 'other' do not need to be finalized, however, they must |   3861 // This class and class 'other' do not need to be finalized, however, they must | 
|   4003 // be resolved as well as their interfaces. |   3862 // be resolved as well as their interfaces. | 
|   4004 bool Class::TypeTest(TypeTestKind test_kind, |   3863 bool Class::TypeTest(TypeTestKind test_kind, | 
|   4005                      const TypeArguments& type_arguments, |   3864                      const TypeArguments& type_arguments, | 
|   4006                      const Class& other, |   3865                      const Class& other, | 
|   4007                      const TypeArguments& other_type_arguments, |   3866                      const TypeArguments& other_type_arguments, | 
|   4008                      Error* bound_error, |   3867                      Error* bound_error, | 
|   4009                      TrailPtr bound_trail, |   3868                      TrailPtr bound_trail, | 
|   4010                      Heap::Space space) const { |   3869                      Heap::Space space) const { | 
|   4011   return TypeTestNonRecursive(*this, test_kind, type_arguments, other, |   3870   return TypeTestNonRecursive(*this, test_kind, type_arguments, other, | 
|   4012                               other_type_arguments, bound_error, bound_trail, |   3871                               other_type_arguments, bound_error, bound_trail, | 
|   4013                               space); |   3872                               space); | 
|   4014 } |   3873 } | 
|   4015  |   3874  | 
|   4016  |  | 
|   4017 bool Class::IsTopLevel() const { |   3875 bool Class::IsTopLevel() const { | 
|   4018   return Name() == Symbols::TopLevel().raw(); |   3876   return Name() == Symbols::TopLevel().raw(); | 
|   4019 } |   3877 } | 
|   4020  |   3878  | 
|   4021  |  | 
|   4022 bool Class::IsPrivate() const { |   3879 bool Class::IsPrivate() const { | 
|   4023   return Library::IsPrivate(String::Handle(Name())); |   3880   return Library::IsPrivate(String::Handle(Name())); | 
|   4024 } |   3881 } | 
|   4025  |   3882  | 
|   4026  |  | 
|   4027 RawFunction* Class::LookupDynamicFunction(const String& name) const { |   3883 RawFunction* Class::LookupDynamicFunction(const String& name) const { | 
|   4028   return LookupFunction(name, kInstance); |   3884   return LookupFunction(name, kInstance); | 
|   4029 } |   3885 } | 
|   4030  |   3886  | 
|   4031  |  | 
|   4032 RawFunction* Class::LookupDynamicFunctionAllowAbstract( |   3887 RawFunction* Class::LookupDynamicFunctionAllowAbstract( | 
|   4033     const String& name) const { |   3888     const String& name) const { | 
|   4034   return LookupFunction(name, kInstanceAllowAbstract); |   3889   return LookupFunction(name, kInstanceAllowAbstract); | 
|   4035 } |   3890 } | 
|   4036  |   3891  | 
|   4037  |  | 
|   4038 RawFunction* Class::LookupDynamicFunctionAllowPrivate( |   3892 RawFunction* Class::LookupDynamicFunctionAllowPrivate( | 
|   4039     const String& name) const { |   3893     const String& name) const { | 
|   4040   return LookupFunctionAllowPrivate(name, kInstance); |   3894   return LookupFunctionAllowPrivate(name, kInstance); | 
|   4041 } |   3895 } | 
|   4042  |   3896  | 
|   4043  |  | 
|   4044 RawFunction* Class::LookupStaticFunction(const String& name) const { |   3897 RawFunction* Class::LookupStaticFunction(const String& name) const { | 
|   4045   return LookupFunction(name, kStatic); |   3898   return LookupFunction(name, kStatic); | 
|   4046 } |   3899 } | 
|   4047  |   3900  | 
|   4048  |  | 
|   4049 RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const { |   3901 RawFunction* Class::LookupStaticFunctionAllowPrivate(const String& name) const { | 
|   4050   return LookupFunctionAllowPrivate(name, kStatic); |   3902   return LookupFunctionAllowPrivate(name, kStatic); | 
|   4051 } |   3903 } | 
|   4052  |   3904  | 
|   4053  |  | 
|   4054 RawFunction* Class::LookupConstructor(const String& name) const { |   3905 RawFunction* Class::LookupConstructor(const String& name) const { | 
|   4055   return LookupFunction(name, kConstructor); |   3906   return LookupFunction(name, kConstructor); | 
|   4056 } |   3907 } | 
|   4057  |   3908  | 
|   4058  |  | 
|   4059 RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const { |   3909 RawFunction* Class::LookupConstructorAllowPrivate(const String& name) const { | 
|   4060   return LookupFunctionAllowPrivate(name, kConstructor); |   3910   return LookupFunctionAllowPrivate(name, kConstructor); | 
|   4061 } |   3911 } | 
|   4062  |   3912  | 
|   4063  |  | 
|   4064 RawFunction* Class::LookupFactory(const String& name) const { |   3913 RawFunction* Class::LookupFactory(const String& name) const { | 
|   4065   return LookupFunction(name, kFactory); |   3914   return LookupFunction(name, kFactory); | 
|   4066 } |   3915 } | 
|   4067  |   3916  | 
|   4068  |  | 
|   4069 RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const { |   3917 RawFunction* Class::LookupFactoryAllowPrivate(const String& name) const { | 
|   4070   return LookupFunctionAllowPrivate(name, kFactory); |   3918   return LookupFunctionAllowPrivate(name, kFactory); | 
|   4071 } |   3919 } | 
|   4072  |   3920  | 
|   4073  |  | 
|   4074 RawFunction* Class::LookupFunction(const String& name) const { |   3921 RawFunction* Class::LookupFunction(const String& name) const { | 
|   4075   return LookupFunction(name, kAny); |   3922   return LookupFunction(name, kAny); | 
|   4076 } |   3923 } | 
|   4077  |   3924  | 
|   4078  |  | 
|   4079 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const { |   3925 RawFunction* Class::LookupFunctionAllowPrivate(const String& name) const { | 
|   4080   return LookupFunctionAllowPrivate(name, kAny); |   3926   return LookupFunctionAllowPrivate(name, kAny); | 
|   4081 } |   3927 } | 
|   4082  |   3928  | 
|   4083  |  | 
|   4084 RawFunction* Class::LookupCallFunctionForTypeTest() const { |   3929 RawFunction* Class::LookupCallFunctionForTypeTest() const { | 
|   4085   // If this class is not compiled yet, it is too early to lookup a call |   3930   // If this class is not compiled yet, it is too early to lookup a call | 
|   4086   // function. This case should only occur during bounds checking at compile |   3931   // function. This case should only occur during bounds checking at compile | 
|   4087   // time. Return null as if the call method did not exist, so the type test |   3932   // time. Return null as if the call method did not exist, so the type test | 
|   4088   // may return false, but without a bound error, and the bound check will get |   3933   // may return false, but without a bound error, and the bound check will get | 
|   4089   // postponed to runtime. |   3934   // postponed to runtime. | 
|   4090   if (!is_finalized()) { |   3935   if (!is_finalized()) { | 
|   4091     return Function::null(); |   3936     return Function::null(); | 
|   4092   } |   3937   } | 
|   4093   Zone* zone = Thread::Current()->zone(); |   3938   Zone* zone = Thread::Current()->zone(); | 
|   4094   Class& cls = Class::Handle(zone, raw()); |   3939   Class& cls = Class::Handle(zone, raw()); | 
|   4095   Function& call_function = Function::Handle(zone); |   3940   Function& call_function = Function::Handle(zone); | 
|   4096   do { |   3941   do { | 
|   4097     ASSERT(cls.is_finalized()); |   3942     ASSERT(cls.is_finalized()); | 
|   4098     call_function = cls.LookupDynamicFunctionAllowAbstract(Symbols::Call()); |   3943     call_function = cls.LookupDynamicFunctionAllowAbstract(Symbols::Call()); | 
|   4099     cls = cls.SuperClass(); |   3944     cls = cls.SuperClass(); | 
|   4100   } while (call_function.IsNull() && !cls.IsNull()); |   3945   } while (call_function.IsNull() && !cls.IsNull()); | 
|   4101   if (!call_function.IsNull()) { |   3946   if (!call_function.IsNull()) { | 
|   4102     // Make sure the signature is finalized before using it in a type test. |   3947     // Make sure the signature is finalized before using it in a type test. | 
|   4103     ClassFinalizer::FinalizeSignature( |   3948     ClassFinalizer::FinalizeSignature( | 
|   4104         cls, call_function, ClassFinalizer::kFinalize);  // No bounds checking. |   3949         cls, call_function, ClassFinalizer::kFinalize);  // No bounds checking. | 
|   4105   } |   3950   } | 
|   4106   return call_function.raw(); |   3951   return call_function.raw(); | 
|   4107 } |   3952 } | 
|   4108  |   3953  | 
|   4109  |  | 
|   4110 // Returns true if 'prefix' and 'accessor_name' match 'name'. |   3954 // Returns true if 'prefix' and 'accessor_name' match 'name'. | 
|   4111 static bool MatchesAccessorName(const String& name, |   3955 static bool MatchesAccessorName(const String& name, | 
|   4112                                 const char* prefix, |   3956                                 const char* prefix, | 
|   4113                                 intptr_t prefix_length, |   3957                                 intptr_t prefix_length, | 
|   4114                                 const String& accessor_name) { |   3958                                 const String& accessor_name) { | 
|   4115   intptr_t name_len = name.Length(); |   3959   intptr_t name_len = name.Length(); | 
|   4116   intptr_t accessor_name_len = accessor_name.Length(); |   3960   intptr_t accessor_name_len = accessor_name.Length(); | 
|   4117  |   3961  | 
|   4118   if (name_len != (accessor_name_len + prefix_length)) { |   3962   if (name_len != (accessor_name_len + prefix_length)) { | 
|   4119     return false; |   3963     return false; | 
|   4120   } |   3964   } | 
|   4121   for (intptr_t i = 0; i < prefix_length; i++) { |   3965   for (intptr_t i = 0; i < prefix_length; i++) { | 
|   4122     if (name.CharAt(i) != prefix[i]) { |   3966     if (name.CharAt(i) != prefix[i]) { | 
|   4123       return false; |   3967       return false; | 
|   4124     } |   3968     } | 
|   4125   } |   3969   } | 
|   4126   for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { |   3970   for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { | 
|   4127     if (name.CharAt(j) != accessor_name.CharAt(i)) { |   3971     if (name.CharAt(j) != accessor_name.CharAt(i)) { | 
|   4128       return false; |   3972       return false; | 
|   4129     } |   3973     } | 
|   4130   } |   3974   } | 
|   4131   return true; |   3975   return true; | 
|   4132 } |   3976 } | 
|   4133  |   3977  | 
|   4134  |  | 
|   4135 RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) { |   3978 RawFunction* Class::CheckFunctionType(const Function& func, MemberKind kind) { | 
|   4136   if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) { |   3979   if ((kind == kInstance) || (kind == kInstanceAllowAbstract)) { | 
|   4137     if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) { |   3980     if (func.IsDynamicFunction(kind == kInstanceAllowAbstract)) { | 
|   4138       return func.raw(); |   3981       return func.raw(); | 
|   4139     } |   3982     } | 
|   4140   } else if (kind == kStatic) { |   3983   } else if (kind == kStatic) { | 
|   4141     if (func.IsStaticFunction()) { |   3984     if (func.IsStaticFunction()) { | 
|   4142       return func.raw(); |   3985       return func.raw(); | 
|   4143     } |   3986     } | 
|   4144   } else if (kind == kConstructor) { |   3987   } else if (kind == kConstructor) { | 
|   4145     if (func.IsGenerativeConstructor()) { |   3988     if (func.IsGenerativeConstructor()) { | 
|   4146       ASSERT(!func.is_static()); |   3989       ASSERT(!func.is_static()); | 
|   4147       return func.raw(); |   3990       return func.raw(); | 
|   4148     } |   3991     } | 
|   4149   } else if (kind == kFactory) { |   3992   } else if (kind == kFactory) { | 
|   4150     if (func.IsFactory()) { |   3993     if (func.IsFactory()) { | 
|   4151       ASSERT(func.is_static()); |   3994       ASSERT(func.is_static()); | 
|   4152       return func.raw(); |   3995       return func.raw(); | 
|   4153     } |   3996     } | 
|   4154   } else if (kind == kAny) { |   3997   } else if (kind == kAny) { | 
|   4155     return func.raw(); |   3998     return func.raw(); | 
|   4156   } |   3999   } | 
|   4157   return Function::null(); |   4000   return Function::null(); | 
|   4158 } |   4001 } | 
|   4159  |   4002  | 
|   4160  |  | 
|   4161 RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { |   4003 RawFunction* Class::LookupFunction(const String& name, MemberKind kind) const { | 
|   4162   Thread* thread = Thread::Current(); |   4004   Thread* thread = Thread::Current(); | 
|   4163   if (EnsureIsFinalized(thread) != Error::null()) { |   4005   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   4164     return Function::null(); |   4006     return Function::null(); | 
|   4165   } |   4007   } | 
|   4166   REUSABLE_ARRAY_HANDLESCOPE(thread); |   4008   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   4167   REUSABLE_FUNCTION_HANDLESCOPE(thread); |   4009   REUSABLE_FUNCTION_HANDLESCOPE(thread); | 
|   4168   Array& funcs = thread->ArrayHandle(); |   4010   Array& funcs = thread->ArrayHandle(); | 
|   4169   funcs ^= functions(); |   4011   funcs ^= functions(); | 
|   4170   ASSERT(!funcs.IsNull()); |   4012   ASSERT(!funcs.IsNull()); | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|   4201       function_name ^= function.name(); |   4043       function_name ^= function.name(); | 
|   4202       if (function_name.Equals(name)) { |   4044       if (function_name.Equals(name)) { | 
|   4203         return CheckFunctionType(function, kind); |   4045         return CheckFunctionType(function, kind); | 
|   4204       } |   4046       } | 
|   4205     } |   4047     } | 
|   4206   } |   4048   } | 
|   4207   // No function found. |   4049   // No function found. | 
|   4208   return Function::null(); |   4050   return Function::null(); | 
|   4209 } |   4051 } | 
|   4210  |   4052  | 
|   4211  |  | 
|   4212 RawFunction* Class::LookupFunctionAllowPrivate(const String& name, |   4053 RawFunction* Class::LookupFunctionAllowPrivate(const String& name, | 
|   4213                                                MemberKind kind) const { |   4054                                                MemberKind kind) const { | 
|   4214   Thread* thread = Thread::Current(); |   4055   Thread* thread = Thread::Current(); | 
|   4215   if (EnsureIsFinalized(thread) != Error::null()) { |   4056   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   4216     return Function::null(); |   4057     return Function::null(); | 
|   4217   } |   4058   } | 
|   4218   REUSABLE_ARRAY_HANDLESCOPE(thread); |   4059   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   4219   REUSABLE_FUNCTION_HANDLESCOPE(thread); |   4060   REUSABLE_FUNCTION_HANDLESCOPE(thread); | 
|   4220   REUSABLE_STRING_HANDLESCOPE(thread); |   4061   REUSABLE_STRING_HANDLESCOPE(thread); | 
|   4221   Array& funcs = thread->ArrayHandle(); |   4062   Array& funcs = thread->ArrayHandle(); | 
|   4222   funcs ^= functions(); |   4063   funcs ^= functions(); | 
|   4223   ASSERT(!funcs.IsNull()); |   4064   ASSERT(!funcs.IsNull()); | 
|   4224   const intptr_t len = funcs.Length(); |   4065   const intptr_t len = funcs.Length(); | 
|   4225   Function& function = thread->FunctionHandle(); |   4066   Function& function = thread->FunctionHandle(); | 
|   4226   String& function_name = thread->StringHandle(); |   4067   String& function_name = thread->StringHandle(); | 
|   4227   for (intptr_t i = 0; i < len; i++) { |   4068   for (intptr_t i = 0; i < len; i++) { | 
|   4228     function ^= funcs.At(i); |   4069     function ^= funcs.At(i); | 
|   4229     function_name ^= function.name(); |   4070     function_name ^= function.name(); | 
|   4230     if (String::EqualsIgnoringPrivateKey(function_name, name)) { |   4071     if (String::EqualsIgnoringPrivateKey(function_name, name)) { | 
|   4231       return CheckFunctionType(function, kind); |   4072       return CheckFunctionType(function, kind); | 
|   4232     } |   4073     } | 
|   4233   } |   4074   } | 
|   4234   // No function found. |   4075   // No function found. | 
|   4235   return Function::null(); |   4076   return Function::null(); | 
|   4236 } |   4077 } | 
|   4237  |   4078  | 
|   4238  |  | 
|   4239 RawFunction* Class::LookupGetterFunction(const String& name) const { |   4079 RawFunction* Class::LookupGetterFunction(const String& name) const { | 
|   4240   return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name); |   4080   return LookupAccessorFunction(kGetterPrefix, kGetterPrefixLength, name); | 
|   4241 } |   4081 } | 
|   4242  |   4082  | 
|   4243  |  | 
|   4244 RawFunction* Class::LookupSetterFunction(const String& name) const { |   4083 RawFunction* Class::LookupSetterFunction(const String& name) const { | 
|   4245   return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name); |   4084   return LookupAccessorFunction(kSetterPrefix, kSetterPrefixLength, name); | 
|   4246 } |   4085 } | 
|   4247  |   4086  | 
|   4248  |  | 
|   4249 RawFunction* Class::LookupAccessorFunction(const char* prefix, |   4087 RawFunction* Class::LookupAccessorFunction(const char* prefix, | 
|   4250                                            intptr_t prefix_length, |   4088                                            intptr_t prefix_length, | 
|   4251                                            const String& name) const { |   4089                                            const String& name) const { | 
|   4252   Thread* thread = Thread::Current(); |   4090   Thread* thread = Thread::Current(); | 
|   4253   if (EnsureIsFinalized(thread) != Error::null()) { |   4091   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   4254     return Function::null(); |   4092     return Function::null(); | 
|   4255   } |   4093   } | 
|   4256   REUSABLE_ARRAY_HANDLESCOPE(thread); |   4094   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   4257   REUSABLE_FUNCTION_HANDLESCOPE(thread); |   4095   REUSABLE_FUNCTION_HANDLESCOPE(thread); | 
|   4258   REUSABLE_STRING_HANDLESCOPE(thread); |   4096   REUSABLE_STRING_HANDLESCOPE(thread); | 
|   4259   Array& funcs = thread->ArrayHandle(); |   4097   Array& funcs = thread->ArrayHandle(); | 
|   4260   funcs ^= functions(); |   4098   funcs ^= functions(); | 
|   4261   intptr_t len = funcs.Length(); |   4099   intptr_t len = funcs.Length(); | 
|   4262   Function& function = thread->FunctionHandle(); |   4100   Function& function = thread->FunctionHandle(); | 
|   4263   String& function_name = thread->StringHandle(); |   4101   String& function_name = thread->StringHandle(); | 
|   4264   for (intptr_t i = 0; i < len; i++) { |   4102   for (intptr_t i = 0; i < len; i++) { | 
|   4265     function ^= funcs.At(i); |   4103     function ^= funcs.At(i); | 
|   4266     function_name ^= function.name(); |   4104     function_name ^= function.name(); | 
|   4267     if (MatchesAccessorName(function_name, prefix, prefix_length, name)) { |   4105     if (MatchesAccessorName(function_name, prefix, prefix_length, name)) { | 
|   4268       return function.raw(); |   4106       return function.raw(); | 
|   4269     } |   4107     } | 
|   4270   } |   4108   } | 
|   4271  |   4109  | 
|   4272   // No function found. |   4110   // No function found. | 
|   4273   return Function::null(); |   4111   return Function::null(); | 
|   4274 } |   4112 } | 
|   4275  |   4113  | 
|   4276  |  | 
|   4277 RawField* Class::LookupInstanceField(const String& name) const { |   4114 RawField* Class::LookupInstanceField(const String& name) const { | 
|   4278   return LookupField(name, kInstance); |   4115   return LookupField(name, kInstance); | 
|   4279 } |   4116 } | 
|   4280  |   4117  | 
|   4281  |  | 
|   4282 RawField* Class::LookupStaticField(const String& name) const { |   4118 RawField* Class::LookupStaticField(const String& name) const { | 
|   4283   return LookupField(name, kStatic); |   4119   return LookupField(name, kStatic); | 
|   4284 } |   4120 } | 
|   4285  |   4121  | 
|   4286  |  | 
|   4287 RawField* Class::LookupField(const String& name) const { |   4122 RawField* Class::LookupField(const String& name) const { | 
|   4288   return LookupField(name, kAny); |   4123   return LookupField(name, kAny); | 
|   4289 } |   4124 } | 
|   4290  |   4125  | 
|   4291  |  | 
|   4292 RawField* Class::LookupField(const String& name, MemberKind kind) const { |   4126 RawField* Class::LookupField(const String& name, MemberKind kind) const { | 
|   4293   Thread* thread = Thread::Current(); |   4127   Thread* thread = Thread::Current(); | 
|   4294   if (EnsureIsFinalized(thread) != Error::null()) { |   4128   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   4295     return Field::null(); |   4129     return Field::null(); | 
|   4296   } |   4130   } | 
|   4297   REUSABLE_ARRAY_HANDLESCOPE(thread); |   4131   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   4298   REUSABLE_FIELD_HANDLESCOPE(thread); |   4132   REUSABLE_FIELD_HANDLESCOPE(thread); | 
|   4299   REUSABLE_STRING_HANDLESCOPE(thread); |   4133   REUSABLE_STRING_HANDLESCOPE(thread); | 
|   4300   Array& flds = thread->ArrayHandle(); |   4134   Array& flds = thread->ArrayHandle(); | 
|   4301   flds ^= fields(); |   4135   flds ^= fields(); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|   4328           return field.is_static() ? field.raw() : Field::null(); |   4162           return field.is_static() ? field.raw() : Field::null(); | 
|   4329         } |   4163         } | 
|   4330         ASSERT(kind == kAny); |   4164         ASSERT(kind == kAny); | 
|   4331         return field.raw(); |   4165         return field.raw(); | 
|   4332       } |   4166       } | 
|   4333     } |   4167     } | 
|   4334   } |   4168   } | 
|   4335   return Field::null(); |   4169   return Field::null(); | 
|   4336 } |   4170 } | 
|   4337  |   4171  | 
|   4338  |  | 
|   4339 RawField* Class::LookupFieldAllowPrivate(const String& name, |   4172 RawField* Class::LookupFieldAllowPrivate(const String& name, | 
|   4340                                          bool instance_only) const { |   4173                                          bool instance_only) const { | 
|   4341   // Use slow string compare, ignoring privacy name mangling. |   4174   // Use slow string compare, ignoring privacy name mangling. | 
|   4342   Thread* thread = Thread::Current(); |   4175   Thread* thread = Thread::Current(); | 
|   4343   if (EnsureIsFinalized(thread) != Error::null()) { |   4176   if (EnsureIsFinalized(thread) != Error::null()) { | 
|   4344     return Field::null(); |   4177     return Field::null(); | 
|   4345   } |   4178   } | 
|   4346   REUSABLE_ARRAY_HANDLESCOPE(thread); |   4179   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|   4347   REUSABLE_FIELD_HANDLESCOPE(thread); |   4180   REUSABLE_FIELD_HANDLESCOPE(thread); | 
|   4348   REUSABLE_STRING_HANDLESCOPE(thread); |   4181   REUSABLE_STRING_HANDLESCOPE(thread); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   4359       // If we only care about instance fields, skip statics. |   4192       // If we only care about instance fields, skip statics. | 
|   4360       continue; |   4193       continue; | 
|   4361     } |   4194     } | 
|   4362     if (String::EqualsIgnoringPrivateKey(field_name, name)) { |   4195     if (String::EqualsIgnoringPrivateKey(field_name, name)) { | 
|   4363       return field.raw(); |   4196       return field.raw(); | 
|   4364     } |   4197     } | 
|   4365   } |   4198   } | 
|   4366   return Field::null(); |   4199   return Field::null(); | 
|   4367 } |   4200 } | 
|   4368  |   4201  | 
|   4369  |  | 
|   4370 RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const { |   4202 RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const { | 
|   4371   Field& field = Field::Handle(LookupFieldAllowPrivate(name, true)); |   4203   Field& field = Field::Handle(LookupFieldAllowPrivate(name, true)); | 
|   4372   if (!field.IsNull() && !field.is_static()) { |   4204   if (!field.IsNull() && !field.is_static()) { | 
|   4373     return field.raw(); |   4205     return field.raw(); | 
|   4374   } |   4206   } | 
|   4375   return Field::null(); |   4207   return Field::null(); | 
|   4376 } |   4208 } | 
|   4377  |   4209  | 
|   4378  |  | 
|   4379 RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const { |   4210 RawField* Class::LookupStaticFieldAllowPrivate(const String& name) const { | 
|   4380   Field& field = Field::Handle(LookupFieldAllowPrivate(name)); |   4211   Field& field = Field::Handle(LookupFieldAllowPrivate(name)); | 
|   4381   if (!field.IsNull() && field.is_static()) { |   4212   if (!field.IsNull() && field.is_static()) { | 
|   4382     return field.raw(); |   4213     return field.raw(); | 
|   4383   } |   4214   } | 
|   4384   return Field::null(); |   4215   return Field::null(); | 
|   4385 } |   4216 } | 
|   4386  |   4217  | 
|   4387  |  | 
|   4388 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const { |   4218 RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const { | 
|   4389   Zone* zone = Thread::Current()->zone(); |   4219   Zone* zone = Thread::Current()->zone(); | 
|   4390   const Library& lib = Library::Handle(zone, library()); |   4220   const Library& lib = Library::Handle(zone, library()); | 
|   4391   const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); |   4221   const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name)); | 
|   4392   if (!obj.IsNull() && obj.IsLibraryPrefix()) { |   4222   if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 
|   4393     return LibraryPrefix::Cast(obj).raw(); |   4223     return LibraryPrefix::Cast(obj).raw(); | 
|   4394   } |   4224   } | 
|   4395   return LibraryPrefix::null(); |   4225   return LibraryPrefix::null(); | 
|   4396 } |   4226 } | 
|   4397  |   4227  | 
|   4398  |  | 
|   4399 const char* Class::ToCString() const { |   4228 const char* Class::ToCString() const { | 
|   4400   const Library& lib = Library::Handle(library()); |   4229   const Library& lib = Library::Handle(library()); | 
|   4401   const char* library_name = lib.IsNull() ? "" : lib.ToCString(); |   4230   const char* library_name = lib.IsNull() ? "" : lib.ToCString(); | 
|   4402   const char* patch_prefix = is_patch() ? "Patch " : ""; |   4231   const char* patch_prefix = is_patch() ? "Patch " : ""; | 
|   4403   const char* class_name = String::Handle(Name()).ToCString(); |   4232   const char* class_name = String::Handle(Name()).ToCString(); | 
|   4404   return OS::SCreate(Thread::Current()->zone(), "%s %sClass: %s", library_name, |   4233   return OS::SCreate(Thread::Current()->zone(), "%s %sClass: %s", library_name, | 
|   4405                      patch_prefix, class_name); |   4234                      patch_prefix, class_name); | 
|   4406 } |   4235 } | 
|   4407  |   4236  | 
|   4408  |  | 
|   4409 // Returns an instance of Double or Double::null(). |   4237 // Returns an instance of Double or Double::null(). | 
|   4410 // 'index' points to either: |   4238 // 'index' points to either: | 
|   4411 // - constants_list_ position of found element, or |   4239 // - constants_list_ position of found element, or | 
|   4412 // - constants_list_ position where new canonical can be inserted. |   4240 // - constants_list_ position where new canonical can be inserted. | 
|   4413 RawDouble* Class::LookupCanonicalDouble(Zone* zone, |   4241 RawDouble* Class::LookupCanonicalDouble(Zone* zone, | 
|   4414                                         double value, |   4242                                         double value, | 
|   4415                                         intptr_t* index) const { |   4243                                         intptr_t* index) const { | 
|   4416   ASSERT(this->raw() == Isolate::Current()->object_store()->double_class()); |   4244   ASSERT(this->raw() == Isolate::Current()->object_store()->double_class()); | 
|   4417   const Array& constants = Array::Handle(zone, this->constants()); |   4245   const Array& constants = Array::Handle(zone, this->constants()); | 
|   4418   const intptr_t constants_len = constants.Length(); |   4246   const intptr_t constants_len = constants.Length(); | 
|   4419   // Linear search to see whether this value is already present in the |   4247   // Linear search to see whether this value is already present in the | 
|   4420   // list of canonicalized constants. |   4248   // list of canonicalized constants. | 
|   4421   Double& canonical_value = Double::Handle(zone); |   4249   Double& canonical_value = Double::Handle(zone); | 
|   4422   while (*index < constants_len) { |   4250   while (*index < constants_len) { | 
|   4423     canonical_value ^= constants.At(*index); |   4251     canonical_value ^= constants.At(*index); | 
|   4424     if (canonical_value.IsNull()) { |   4252     if (canonical_value.IsNull()) { | 
|   4425       break; |   4253       break; | 
|   4426     } |   4254     } | 
|   4427     if (canonical_value.BitwiseEqualsToDouble(value)) { |   4255     if (canonical_value.BitwiseEqualsToDouble(value)) { | 
|   4428       ASSERT(canonical_value.IsCanonical()); |   4256       ASSERT(canonical_value.IsCanonical()); | 
|   4429       return canonical_value.raw(); |   4257       return canonical_value.raw(); | 
|   4430     } |   4258     } | 
|   4431     *index = *index + 1; |   4259     *index = *index + 1; | 
|   4432   } |   4260   } | 
|   4433   return Double::null(); |   4261   return Double::null(); | 
|   4434 } |   4262 } | 
|   4435  |   4263  | 
|   4436  |  | 
|   4437 RawMint* Class::LookupCanonicalMint(Zone* zone, |   4264 RawMint* Class::LookupCanonicalMint(Zone* zone, | 
|   4438                                     int64_t value, |   4265                                     int64_t value, | 
|   4439                                     intptr_t* index) const { |   4266                                     intptr_t* index) const { | 
|   4440   ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class()); |   4267   ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class()); | 
|   4441   const Array& constants = Array::Handle(zone, this->constants()); |   4268   const Array& constants = Array::Handle(zone, this->constants()); | 
|   4442   const intptr_t constants_len = constants.Length(); |   4269   const intptr_t constants_len = constants.Length(); | 
|   4443   // Linear search to see whether this value is already present in the |   4270   // Linear search to see whether this value is already present in the | 
|   4444   // list of canonicalized constants. |   4271   // list of canonicalized constants. | 
|   4445   Mint& canonical_value = Mint::Handle(zone); |   4272   Mint& canonical_value = Mint::Handle(zone); | 
|   4446   while (*index < constants_len) { |   4273   while (*index < constants_len) { | 
|   4447     canonical_value ^= constants.At(*index); |   4274     canonical_value ^= constants.At(*index); | 
|   4448     if (canonical_value.IsNull()) { |   4275     if (canonical_value.IsNull()) { | 
|   4449       break; |   4276       break; | 
|   4450     } |   4277     } | 
|   4451     if (canonical_value.value() == value) { |   4278     if (canonical_value.value() == value) { | 
|   4452       ASSERT(canonical_value.IsCanonical()); |   4279       ASSERT(canonical_value.IsCanonical()); | 
|   4453       return canonical_value.raw(); |   4280       return canonical_value.raw(); | 
|   4454     } |   4281     } | 
|   4455     *index = *index + 1; |   4282     *index = *index + 1; | 
|   4456   } |   4283   } | 
|   4457   return Mint::null(); |   4284   return Mint::null(); | 
|   4458 } |   4285 } | 
|   4459  |   4286  | 
|   4460  |  | 
|   4461 RawBigint* Class::LookupCanonicalBigint(Zone* zone, |   4287 RawBigint* Class::LookupCanonicalBigint(Zone* zone, | 
|   4462                                         const Bigint& value, |   4288                                         const Bigint& value, | 
|   4463                                         intptr_t* index) const { |   4289                                         intptr_t* index) const { | 
|   4464   ASSERT(this->raw() == Isolate::Current()->object_store()->bigint_class()); |   4290   ASSERT(this->raw() == Isolate::Current()->object_store()->bigint_class()); | 
|   4465   const Array& constants = Array::Handle(zone, this->constants()); |   4291   const Array& constants = Array::Handle(zone, this->constants()); | 
|   4466   const intptr_t constants_len = constants.Length(); |   4292   const intptr_t constants_len = constants.Length(); | 
|   4467   // Linear search to see whether this value is already present in the |   4293   // Linear search to see whether this value is already present in the | 
|   4468   // list of canonicalized constants. |   4294   // list of canonicalized constants. | 
|   4469   Bigint& canonical_value = Bigint::Handle(zone); |   4295   Bigint& canonical_value = Bigint::Handle(zone); | 
|   4470   while (*index < constants_len) { |   4296   while (*index < constants_len) { | 
|   4471     canonical_value ^= constants.At(*index); |   4297     canonical_value ^= constants.At(*index); | 
|   4472     if (canonical_value.IsNull()) { |   4298     if (canonical_value.IsNull()) { | 
|   4473       break; |   4299       break; | 
|   4474     } |   4300     } | 
|   4475     if (canonical_value.Equals(value)) { |   4301     if (canonical_value.Equals(value)) { | 
|   4476       ASSERT(canonical_value.IsCanonical()); |   4302       ASSERT(canonical_value.IsCanonical()); | 
|   4477       return canonical_value.raw(); |   4303       return canonical_value.raw(); | 
|   4478     } |   4304     } | 
|   4479     *index = *index + 1; |   4305     *index = *index + 1; | 
|   4480   } |   4306   } | 
|   4481   return Bigint::null(); |   4307   return Bigint::null(); | 
|   4482 } |   4308 } | 
|   4483  |   4309  | 
|   4484  |  | 
|   4485 class CanonicalInstanceKey { |   4310 class CanonicalInstanceKey { | 
|   4486  public: |   4311  public: | 
|   4487   explicit CanonicalInstanceKey(const Instance& key) : key_(key) { |   4312   explicit CanonicalInstanceKey(const Instance& key) : key_(key) { | 
|   4488     ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType())); |   4313     ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType())); | 
|   4489   } |   4314   } | 
|   4490   bool Matches(const Instance& obj) const { |   4315   bool Matches(const Instance& obj) const { | 
|   4491     ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType())); |   4316     ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType())); | 
|   4492     if (key_.CanonicalizeEquals(obj)) { |   4317     if (key_.CanonicalizeEquals(obj)) { | 
|   4493       ASSERT(obj.IsCanonical()); |   4318       ASSERT(obj.IsCanonical()); | 
|   4494       return true; |   4319       return true; | 
|   4495     } |   4320     } | 
|   4496     return false; |   4321     return false; | 
|   4497   } |   4322   } | 
|   4498   uword Hash() const { return key_.ComputeCanonicalTableHash(); } |   4323   uword Hash() const { return key_.ComputeCanonicalTableHash(); } | 
|   4499   const Instance& key_; |   4324   const Instance& key_; | 
|   4500  |   4325  | 
|   4501  private: |   4326  private: | 
|   4502   DISALLOW_ALLOCATION(); |   4327   DISALLOW_ALLOCATION(); | 
|   4503 }; |   4328 }; | 
|   4504  |   4329  | 
|   4505  |  | 
|   4506 // Traits for looking up Canonical Instances based on a hash of the fields. |   4330 // Traits for looking up Canonical Instances based on a hash of the fields. | 
|   4507 class CanonicalInstanceTraits { |   4331 class CanonicalInstanceTraits { | 
|   4508  public: |   4332  public: | 
|   4509   static const char* Name() { return "CanonicalInstanceTraits"; } |   4333   static const char* Name() { return "CanonicalInstanceTraits"; } | 
|   4510   static bool ReportStats() { return false; } |   4334   static bool ReportStats() { return false; } | 
|   4511  |   4335  | 
|   4512   // Called when growing the table. |   4336   // Called when growing the table. | 
|   4513   static bool IsMatch(const Object& a, const Object& b) { |   4337   static bool IsMatch(const Object& a, const Object& b) { | 
|   4514     ASSERT(!(a.IsString() || a.IsInteger() || a.IsAbstractType())); |   4338     ASSERT(!(a.IsString() || a.IsInteger() || a.IsAbstractType())); | 
|   4515     ASSERT(!(b.IsString() || b.IsInteger() || b.IsAbstractType())); |   4339     ASSERT(!(b.IsString() || b.IsInteger() || b.IsAbstractType())); | 
|   4516     return a.raw() == b.raw(); |   4340     return a.raw() == b.raw(); | 
|   4517   } |   4341   } | 
|   4518   static bool IsMatch(const CanonicalInstanceKey& a, const Object& b) { |   4342   static bool IsMatch(const CanonicalInstanceKey& a, const Object& b) { | 
|   4519     return a.Matches(Instance::Cast(b)); |   4343     return a.Matches(Instance::Cast(b)); | 
|   4520   } |   4344   } | 
|   4521   static uword Hash(const Object& key) { |   4345   static uword Hash(const Object& key) { | 
|   4522     ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType())); |   4346     ASSERT(!(key.IsString() || key.IsNumber() || key.IsAbstractType())); | 
|   4523     ASSERT(key.IsInstance()); |   4347     ASSERT(key.IsInstance()); | 
|   4524     return Instance::Cast(key).ComputeCanonicalTableHash(); |   4348     return Instance::Cast(key).ComputeCanonicalTableHash(); | 
|   4525   } |   4349   } | 
|   4526   static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); } |   4350   static uword Hash(const CanonicalInstanceKey& key) { return key.Hash(); } | 
|   4527   static RawObject* NewKey(const CanonicalInstanceKey& obj) { |   4351   static RawObject* NewKey(const CanonicalInstanceKey& obj) { | 
|   4528     return obj.key_.raw(); |   4352     return obj.key_.raw(); | 
|   4529   } |   4353   } | 
|   4530 }; |   4354 }; | 
|   4531 typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet; |   4355 typedef UnorderedHashSet<CanonicalInstanceTraits> CanonicalInstancesSet; | 
|   4532  |   4356  | 
|   4533  |  | 
|   4534 RawInstance* Class::LookupCanonicalInstance(Zone* zone, |   4357 RawInstance* Class::LookupCanonicalInstance(Zone* zone, | 
|   4535                                             const Instance& value) const { |   4358                                             const Instance& value) const { | 
|   4536   ASSERT(this->raw() == value.clazz()); |   4359   ASSERT(this->raw() == value.clazz()); | 
|   4537   ASSERT(is_finalized()); |   4360   ASSERT(is_finalized()); | 
|   4538   Instance& canonical_value = Instance::Handle(zone); |   4361   Instance& canonical_value = Instance::Handle(zone); | 
|   4539   if (this->constants() != Object::empty_array().raw()) { |   4362   if (this->constants() != Object::empty_array().raw()) { | 
|   4540     CanonicalInstancesSet constants(zone, this->constants()); |   4363     CanonicalInstancesSet constants(zone, this->constants()); | 
|   4541     canonical_value ^= constants.GetOrNull(CanonicalInstanceKey(value)); |   4364     canonical_value ^= constants.GetOrNull(CanonicalInstanceKey(value)); | 
|   4542     this->set_constants(constants.Release()); |   4365     this->set_constants(constants.Release()); | 
|   4543   } |   4366   } | 
|   4544   return canonical_value.raw(); |   4367   return canonical_value.raw(); | 
|   4545 } |   4368 } | 
|   4546  |   4369  | 
|   4547  |  | 
|   4548 RawInstance* Class::InsertCanonicalConstant(Zone* zone, |   4370 RawInstance* Class::InsertCanonicalConstant(Zone* zone, | 
|   4549                                             const Instance& constant) const { |   4371                                             const Instance& constant) const { | 
|   4550   ASSERT(this->raw() == constant.clazz()); |   4372   ASSERT(this->raw() == constant.clazz()); | 
|   4551   Instance& canonical_value = Instance::Handle(zone); |   4373   Instance& canonical_value = Instance::Handle(zone); | 
|   4552   if (this->constants() == Object::empty_array().raw()) { |   4374   if (this->constants() == Object::empty_array().raw()) { | 
|   4553     CanonicalInstancesSet constants( |   4375     CanonicalInstancesSet constants( | 
|   4554         HashTables::New<CanonicalInstancesSet>(128, Heap::kOld)); |   4376         HashTables::New<CanonicalInstancesSet>(128, Heap::kOld)); | 
|   4555     canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); |   4377     canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); | 
|   4556     this->set_constants(constants.Release()); |   4378     this->set_constants(constants.Release()); | 
|   4557   } else { |   4379   } else { | 
|   4558     CanonicalInstancesSet constants(Thread::Current()->zone(), |   4380     CanonicalInstancesSet constants(Thread::Current()->zone(), | 
|   4559                                     this->constants()); |   4381                                     this->constants()); | 
|   4560     canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); |   4382     canonical_value ^= constants.InsertNewOrGet(CanonicalInstanceKey(constant)); | 
|   4561     this->set_constants(constants.Release()); |   4383     this->set_constants(constants.Release()); | 
|   4562   } |   4384   } | 
|   4563   return canonical_value.raw(); |   4385   return canonical_value.raw(); | 
|   4564 } |   4386 } | 
|   4565  |   4387  | 
|   4566  |  | 
|   4567 void Class::InsertCanonicalNumber(Zone* zone, |   4388 void Class::InsertCanonicalNumber(Zone* zone, | 
|   4568                                   intptr_t index, |   4389                                   intptr_t index, | 
|   4569                                   const Number& constant) const { |   4390                                   const Number& constant) const { | 
|   4570   // The constant needs to be added to the list. Grow the list if it is full. |   4391   // The constant needs to be added to the list. Grow the list if it is full. | 
|   4571   Array& canonical_list = Array::Handle(zone, constants()); |   4392   Array& canonical_list = Array::Handle(zone, constants()); | 
|   4572   const intptr_t list_len = canonical_list.Length(); |   4393   const intptr_t list_len = canonical_list.Length(); | 
|   4573   if (index >= list_len) { |   4394   if (index >= list_len) { | 
|   4574     const intptr_t new_length = list_len + 4 + (list_len >> 2); |   4395     const intptr_t new_length = list_len + 4 + (list_len >> 2); | 
|   4575     canonical_list ^= Array::Grow(canonical_list, new_length, Heap::kOld); |   4396     canonical_list ^= Array::Grow(canonical_list, new_length, Heap::kOld); | 
|   4576     set_constants(canonical_list); |   4397     set_constants(canonical_list); | 
|   4577   } |   4398   } | 
|   4578   canonical_list.SetAt(index, constant); |   4399   canonical_list.SetAt(index, constant); | 
|   4579 } |   4400 } | 
|   4580  |   4401  | 
|   4581  |  | 
|   4582 void Class::RehashConstants(Zone* zone) const { |   4402 void Class::RehashConstants(Zone* zone) const { | 
|   4583   intptr_t cid = id(); |   4403   intptr_t cid = id(); | 
|   4584   if ((cid == kMintCid) || (cid == kBigintCid) || (cid == kDoubleCid)) { |   4404   if ((cid == kMintCid) || (cid == kBigintCid) || (cid == kDoubleCid)) { | 
|   4585     // Constants stored as a plain list, no rehashing needed. |   4405     // Constants stored as a plain list, no rehashing needed. | 
|   4586     return; |   4406     return; | 
|   4587   } |   4407   } | 
|   4588  |   4408  | 
|   4589   const Array& old_constants = Array::Handle(zone, constants()); |   4409   const Array& old_constants = Array::Handle(zone, constants()); | 
|   4590   if (old_constants.Length() == 0) return; |   4410   if (old_constants.Length() == 0) return; | 
|   4591  |   4411  | 
|   4592   set_constants(Object::empty_array()); |   4412   set_constants(Object::empty_array()); | 
|   4593   CanonicalInstancesSet set(zone, old_constants.raw()); |   4413   CanonicalInstancesSet set(zone, old_constants.raw()); | 
|   4594   Instance& constant = Instance::Handle(zone); |   4414   Instance& constant = Instance::Handle(zone); | 
|   4595   CanonicalInstancesSet::Iterator it(&set); |   4415   CanonicalInstancesSet::Iterator it(&set); | 
|   4596   while (it.MoveNext()) { |   4416   while (it.MoveNext()) { | 
|   4597     constant ^= set.GetKey(it.Current()); |   4417     constant ^= set.GetKey(it.Current()); | 
|   4598     ASSERT(!constant.IsNull()); |   4418     ASSERT(!constant.IsNull()); | 
|   4599     ASSERT(constant.IsCanonical()); |   4419     ASSERT(constant.IsCanonical()); | 
|   4600     InsertCanonicalConstant(zone, constant); |   4420     InsertCanonicalConstant(zone, constant); | 
|   4601   } |   4421   } | 
|   4602   set.Release(); |   4422   set.Release(); | 
|   4603 } |   4423 } | 
|   4604  |   4424  | 
|   4605  |  | 
|   4606 RawUnresolvedClass* UnresolvedClass::New(const Object& library_prefix, |   4425 RawUnresolvedClass* UnresolvedClass::New(const Object& library_prefix, | 
|   4607                                          const String& ident, |   4426                                          const String& ident, | 
|   4608                                          TokenPosition token_pos) { |   4427                                          TokenPosition token_pos) { | 
|   4609   const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); |   4428   const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); | 
|   4610   type.set_library_or_library_prefix(library_prefix); |   4429   type.set_library_or_library_prefix(library_prefix); | 
|   4611   type.set_ident(ident); |   4430   type.set_ident(ident); | 
|   4612   type.set_token_pos(token_pos); |   4431   type.set_token_pos(token_pos); | 
|   4613   return type.raw(); |   4432   return type.raw(); | 
|   4614 } |   4433 } | 
|   4615  |   4434  | 
|   4616  |  | 
|   4617 RawUnresolvedClass* UnresolvedClass::New() { |   4435 RawUnresolvedClass* UnresolvedClass::New() { | 
|   4618   ASSERT(Object::unresolved_class_class() != Class::null()); |   4436   ASSERT(Object::unresolved_class_class() != Class::null()); | 
|   4619   RawObject* raw = Object::Allocate( |   4437   RawObject* raw = Object::Allocate( | 
|   4620       UnresolvedClass::kClassId, UnresolvedClass::InstanceSize(), Heap::kOld); |   4438       UnresolvedClass::kClassId, UnresolvedClass::InstanceSize(), Heap::kOld); | 
|   4621   return reinterpret_cast<RawUnresolvedClass*>(raw); |   4439   return reinterpret_cast<RawUnresolvedClass*>(raw); | 
|   4622 } |   4440 } | 
|   4623  |   4441  | 
|   4624  |  | 
|   4625 void UnresolvedClass::set_token_pos(TokenPosition token_pos) const { |   4442 void UnresolvedClass::set_token_pos(TokenPosition token_pos) const { | 
|   4626   ASSERT(!token_pos.IsClassifying()); |   4443   ASSERT(!token_pos.IsClassifying()); | 
|   4627   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |   4444   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|   4628 } |   4445 } | 
|   4629  |   4446  | 
|   4630  |  | 
|   4631 void UnresolvedClass::set_ident(const String& ident) const { |   4447 void UnresolvedClass::set_ident(const String& ident) const { | 
|   4632   StorePointer(&raw_ptr()->ident_, ident.raw()); |   4448   StorePointer(&raw_ptr()->ident_, ident.raw()); | 
|   4633 } |   4449 } | 
|   4634  |   4450  | 
|   4635  |  | 
|   4636 void UnresolvedClass::set_library_or_library_prefix( |   4451 void UnresolvedClass::set_library_or_library_prefix( | 
|   4637     const Object& library_prefix) const { |   4452     const Object& library_prefix) const { | 
|   4638   StorePointer(&raw_ptr()->library_or_library_prefix_, library_prefix.raw()); |   4453   StorePointer(&raw_ptr()->library_or_library_prefix_, library_prefix.raw()); | 
|   4639 } |   4454 } | 
|   4640  |   4455  | 
|   4641  |  | 
|   4642 RawString* UnresolvedClass::Name() const { |   4456 RawString* UnresolvedClass::Name() const { | 
|   4643   if (library_or_library_prefix() != Object::null()) { |   4457   if (library_or_library_prefix() != Object::null()) { | 
|   4644     Thread* thread = Thread::Current(); |   4458     Thread* thread = Thread::Current(); | 
|   4645     Zone* zone = thread->zone(); |   4459     Zone* zone = thread->zone(); | 
|   4646     const Object& lib_prefix = |   4460     const Object& lib_prefix = | 
|   4647         Object::Handle(zone, library_or_library_prefix()); |   4461         Object::Handle(zone, library_or_library_prefix()); | 
|   4648     String& name = String::Handle(zone);  // Qualifier. |   4462     String& name = String::Handle(zone);  // Qualifier. | 
|   4649     if (lib_prefix.IsLibraryPrefix()) { |   4463     if (lib_prefix.IsLibraryPrefix()) { | 
|   4650       name = LibraryPrefix::Cast(lib_prefix).name(); |   4464       name = LibraryPrefix::Cast(lib_prefix).name(); | 
|   4651     } else { |   4465     } else { | 
|   4652       name = Library::Cast(lib_prefix).name(); |   4466       name = Library::Cast(lib_prefix).name(); | 
|   4653     } |   4467     } | 
|   4654     GrowableHandlePtrArray<const String> strs(zone, 3); |   4468     GrowableHandlePtrArray<const String> strs(zone, 3); | 
|   4655     strs.Add(name); |   4469     strs.Add(name); | 
|   4656     strs.Add(Symbols::Dot()); |   4470     strs.Add(Symbols::Dot()); | 
|   4657     strs.Add(String::Handle(zone, ident())); |   4471     strs.Add(String::Handle(zone, ident())); | 
|   4658     return Symbols::FromConcatAll(thread, strs); |   4472     return Symbols::FromConcatAll(thread, strs); | 
|   4659   } else { |   4473   } else { | 
|   4660     return ident(); |   4474     return ident(); | 
|   4661   } |   4475   } | 
|   4662 } |   4476 } | 
|   4663  |   4477  | 
|   4664  |  | 
|   4665 const char* UnresolvedClass::ToCString() const { |   4478 const char* UnresolvedClass::ToCString() const { | 
|   4666   const char* cname = String::Handle(Name()).ToCString(); |   4479   const char* cname = String::Handle(Name()).ToCString(); | 
|   4667   return OS::SCreate(Thread::Current()->zone(), "unresolved class '%s'", cname); |   4480   return OS::SCreate(Thread::Current()->zone(), "unresolved class '%s'", cname); | 
|   4668 } |   4481 } | 
|   4669  |   4482  | 
|   4670  |  | 
|   4671 static uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) { |   4483 static uint32_t CombineHashes(uint32_t hash, uint32_t other_hash) { | 
|   4672   hash += other_hash; |   4484   hash += other_hash; | 
|   4673   hash += hash << 10; |   4485   hash += hash << 10; | 
|   4674   hash ^= hash >> 6;  // Logical shift, unsigned hash. |   4486   hash ^= hash >> 6;  // Logical shift, unsigned hash. | 
|   4675   return hash; |   4487   return hash; | 
|   4676 } |   4488 } | 
|   4677  |   4489  | 
|   4678  |  | 
|   4679 static uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) { |   4490 static uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits) { | 
|   4680   hash += hash << 3; |   4491   hash += hash << 3; | 
|   4681   hash ^= hash >> 11;  // Logical shift, unsigned hash. |   4492   hash ^= hash >> 11;  // Logical shift, unsigned hash. | 
|   4682   hash += hash << 15; |   4493   hash += hash << 15; | 
|   4683   // FinalizeHash gets called with values for hashbits that are bigger than 31 |   4494   // FinalizeHash gets called with values for hashbits that are bigger than 31 | 
|   4684   // (like kBitsPerWord - 1).  Therefore we are careful to use a type |   4495   // (like kBitsPerWord - 1).  Therefore we are careful to use a type | 
|   4685   // (uintptr_t) big enough to avoid undefined behavior with the left shift. |   4496   // (uintptr_t) big enough to avoid undefined behavior with the left shift. | 
|   4686   hash &= (static_cast<uintptr_t>(1) << hashbits) - 1; |   4497   hash &= (static_cast<uintptr_t>(1) << hashbits) - 1; | 
|   4687   return (hash == 0) ? 1 : hash; |   4498   return (hash == 0) ? 1 : hash; | 
|   4688 } |   4499 } | 
|   4689  |   4500  | 
|   4690  |  | 
|   4691 intptr_t TypeArguments::ComputeHash() const { |   4501 intptr_t TypeArguments::ComputeHash() const { | 
|   4692   if (IsNull()) return 0; |   4502   if (IsNull()) return 0; | 
|   4693   const intptr_t num_types = Length(); |   4503   const intptr_t num_types = Length(); | 
|   4694   if (IsRaw(0, num_types)) return 0; |   4504   if (IsRaw(0, num_types)) return 0; | 
|   4695   uint32_t result = 0; |   4505   uint32_t result = 0; | 
|   4696   AbstractType& type = AbstractType::Handle(); |   4506   AbstractType& type = AbstractType::Handle(); | 
|   4697   for (intptr_t i = 0; i < num_types; i++) { |   4507   for (intptr_t i = 0; i < num_types; i++) { | 
|   4698     type = TypeAt(i); |   4508     type = TypeAt(i); | 
|   4699     // The hash may be calculated during type finalization (for debugging |   4509     // The hash may be calculated during type finalization (for debugging | 
|   4700     // purposes only) while a type argument is still temporarily null. |   4510     // purposes only) while a type argument is still temporarily null. | 
|   4701     result = CombineHashes(result, type.IsNull() ? 0 : type.Hash()); |   4511     result = CombineHashes(result, type.IsNull() ? 0 : type.Hash()); | 
|   4702   } |   4512   } | 
|   4703   result = FinalizeHash(result, kHashBits); |   4513   result = FinalizeHash(result, kHashBits); | 
|   4704   SetHash(result); |   4514   SetHash(result); | 
|   4705   return result; |   4515   return result; | 
|   4706 } |   4516 } | 
|   4707  |   4517  | 
|   4708  |  | 
|   4709 RawString* TypeArguments::SubvectorName(intptr_t from_index, |   4518 RawString* TypeArguments::SubvectorName(intptr_t from_index, | 
|   4710                                         intptr_t len, |   4519                                         intptr_t len, | 
|   4711                                         NameVisibility name_visibility) const { |   4520                                         NameVisibility name_visibility) const { | 
|   4712   Thread* thread = Thread::Current(); |   4521   Thread* thread = Thread::Current(); | 
|   4713   Zone* zone = thread->zone(); |   4522   Zone* zone = thread->zone(); | 
|   4714   ASSERT(from_index + len <= Length()); |   4523   ASSERT(from_index + len <= Length()); | 
|   4715   String& name = String::Handle(zone); |   4524   String& name = String::Handle(zone); | 
|   4716   const intptr_t num_strings = |   4525   const intptr_t num_strings = | 
|   4717       (len == 0) ? 2 : 2 * len + 1;  // "<""T"", ""T"">". |   4526       (len == 0) ? 2 : 2 * len + 1;  // "<""T"", ""T"">". | 
|   4718   GrowableHandlePtrArray<const String> pieces(zone, num_strings); |   4527   GrowableHandlePtrArray<const String> pieces(zone, num_strings); | 
|   4719   pieces.Add(Symbols::LAngleBracket()); |   4528   pieces.Add(Symbols::LAngleBracket()); | 
|   4720   AbstractType& type = AbstractType::Handle(zone); |   4529   AbstractType& type = AbstractType::Handle(zone); | 
|   4721   for (intptr_t i = 0; i < len; i++) { |   4530   for (intptr_t i = 0; i < len; i++) { | 
|   4722     type = TypeAt(from_index + i); |   4531     type = TypeAt(from_index + i); | 
|   4723     name = type.BuildName(name_visibility); |   4532     name = type.BuildName(name_visibility); | 
|   4724     pieces.Add(name); |   4533     pieces.Add(name); | 
|   4725     if (i < len - 1) { |   4534     if (i < len - 1) { | 
|   4726       pieces.Add(Symbols::CommaSpace()); |   4535       pieces.Add(Symbols::CommaSpace()); | 
|   4727     } |   4536     } | 
|   4728   } |   4537   } | 
|   4729   pieces.Add(Symbols::RAngleBracket()); |   4538   pieces.Add(Symbols::RAngleBracket()); | 
|   4730   ASSERT(pieces.length() == num_strings); |   4539   ASSERT(pieces.length() == num_strings); | 
|   4731   return Symbols::FromConcatAll(thread, pieces); |   4540   return Symbols::FromConcatAll(thread, pieces); | 
|   4732 } |   4541 } | 
|   4733  |   4542  | 
|   4734  |  | 
|   4735 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other, |   4543 bool TypeArguments::IsSubvectorEquivalent(const TypeArguments& other, | 
|   4736                                           intptr_t from_index, |   4544                                           intptr_t from_index, | 
|   4737                                           intptr_t len, |   4545                                           intptr_t len, | 
|   4738                                           TrailPtr trail) const { |   4546                                           TrailPtr trail) const { | 
|   4739   if (this->raw() == other.raw()) { |   4547   if (this->raw() == other.raw()) { | 
|   4740     return true; |   4548     return true; | 
|   4741   } |   4549   } | 
|   4742   if (IsNull() || other.IsNull()) { |   4550   if (IsNull() || other.IsNull()) { | 
|   4743     return false; |   4551     return false; | 
|   4744   } |   4552   } | 
|   4745   const intptr_t num_types = Length(); |   4553   const intptr_t num_types = Length(); | 
|   4746   if (num_types != other.Length()) { |   4554   if (num_types != other.Length()) { | 
|   4747     return false; |   4555     return false; | 
|   4748   } |   4556   } | 
|   4749   AbstractType& type = AbstractType::Handle(); |   4557   AbstractType& type = AbstractType::Handle(); | 
|   4750   AbstractType& other_type = AbstractType::Handle(); |   4558   AbstractType& other_type = AbstractType::Handle(); | 
|   4751   for (intptr_t i = from_index; i < from_index + len; i++) { |   4559   for (intptr_t i = from_index; i < from_index + len; i++) { | 
|   4752     type = TypeAt(i); |   4560     type = TypeAt(i); | 
|   4753     other_type = other.TypeAt(i); |   4561     other_type = other.TypeAt(i); | 
|   4754     if (!type.IsNull() && !type.IsEquivalent(other_type, trail)) { |   4562     if (!type.IsNull() && !type.IsEquivalent(other_type, trail)) { | 
|   4755       return false; |   4563       return false; | 
|   4756     } |   4564     } | 
|   4757   } |   4565   } | 
|   4758   return true; |   4566   return true; | 
|   4759 } |   4567 } | 
|   4760  |   4568  | 
|   4761  |  | 
|   4762 bool TypeArguments::IsRecursive() const { |   4569 bool TypeArguments::IsRecursive() const { | 
|   4763   if (IsNull()) return false; |   4570   if (IsNull()) return false; | 
|   4764   const intptr_t num_types = Length(); |   4571   const intptr_t num_types = Length(); | 
|   4765   AbstractType& type = AbstractType::Handle(); |   4572   AbstractType& type = AbstractType::Handle(); | 
|   4766   for (intptr_t i = 0; i < num_types; i++) { |   4573   for (intptr_t i = 0; i < num_types; i++) { | 
|   4767     type = TypeAt(i); |   4574     type = TypeAt(i); | 
|   4768     // If this type argument is null, the type parameterized with this type |   4575     // If this type argument is null, the type parameterized with this type | 
|   4769     // argument is still being finalized and is definitely recursive. The null |   4576     // argument is still being finalized and is definitely recursive. The null | 
|   4770     // type argument will be replaced by a non-null type before the type is |   4577     // type argument will be replaced by a non-null type before the type is | 
|   4771     // marked as finalized. |   4578     // marked as finalized. | 
|   4772     if (type.IsNull() || type.IsRecursive()) { |   4579     if (type.IsNull() || type.IsRecursive()) { | 
|   4773       return true; |   4580       return true; | 
|   4774     } |   4581     } | 
|   4775   } |   4582   } | 
|   4776   return false; |   4583   return false; | 
|   4777 } |   4584 } | 
|   4778  |   4585  | 
|   4779  |  | 
|   4780 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, |   4586 bool TypeArguments::IsDynamicTypes(bool raw_instantiated, | 
|   4781                                    intptr_t from_index, |   4587                                    intptr_t from_index, | 
|   4782                                    intptr_t len) const { |   4588                                    intptr_t len) const { | 
|   4783   ASSERT(Length() >= (from_index + len)); |   4589   ASSERT(Length() >= (from_index + len)); | 
|   4784   AbstractType& type = AbstractType::Handle(); |   4590   AbstractType& type = AbstractType::Handle(); | 
|   4785   Class& type_class = Class::Handle(); |   4591   Class& type_class = Class::Handle(); | 
|   4786   for (intptr_t i = 0; i < len; i++) { |   4592   for (intptr_t i = 0; i < len; i++) { | 
|   4787     type = TypeAt(from_index + i); |   4593     type = TypeAt(from_index + i); | 
|   4788     if (type.IsNull()) { |   4594     if (type.IsNull()) { | 
|   4789       return false; |   4595       return false; | 
|   4790     } |   4596     } | 
|   4791     if (!type.HasResolvedTypeClass()) { |   4597     if (!type.HasResolvedTypeClass()) { | 
|   4792       if (raw_instantiated && type.IsTypeParameter()) { |   4598       if (raw_instantiated && type.IsTypeParameter()) { | 
|   4793         // An uninstantiated type parameter is equivalent to dynamic (even in |   4599         // An uninstantiated type parameter is equivalent to dynamic (even in | 
|   4794         // the presence of a malformed bound in checked mode). |   4600         // the presence of a malformed bound in checked mode). | 
|   4795         continue; |   4601         continue; | 
|   4796       } |   4602       } | 
|   4797       return false; |   4603       return false; | 
|   4798     } |   4604     } | 
|   4799     type_class = type.type_class(); |   4605     type_class = type.type_class(); | 
|   4800     if (!type_class.IsDynamicClass()) { |   4606     if (!type_class.IsDynamicClass()) { | 
|   4801       return false; |   4607       return false; | 
|   4802     } |   4608     } | 
|   4803   } |   4609   } | 
|   4804   return true; |   4610   return true; | 
|   4805 } |   4611 } | 
|   4806  |   4612  | 
|   4807  |  | 
|   4808 bool TypeArguments::TypeTest(TypeTestKind test_kind, |   4613 bool TypeArguments::TypeTest(TypeTestKind test_kind, | 
|   4809                              const TypeArguments& other, |   4614                              const TypeArguments& other, | 
|   4810                              intptr_t from_index, |   4615                              intptr_t from_index, | 
|   4811                              intptr_t len, |   4616                              intptr_t len, | 
|   4812                              Error* bound_error, |   4617                              Error* bound_error, | 
|   4813                              TrailPtr bound_trail, |   4618                              TrailPtr bound_trail, | 
|   4814                              Heap::Space space) const { |   4619                              Heap::Space space) const { | 
|   4815   ASSERT(Length() >= (from_index + len)); |   4620   ASSERT(Length() >= (from_index + len)); | 
|   4816   ASSERT(!other.IsNull()); |   4621   ASSERT(!other.IsNull()); | 
|   4817   ASSERT(other.Length() >= (from_index + len)); |   4622   ASSERT(other.Length() >= (from_index + len)); | 
|   4818   AbstractType& type = AbstractType::Handle(); |   4623   AbstractType& type = AbstractType::Handle(); | 
|   4819   AbstractType& other_type = AbstractType::Handle(); |   4624   AbstractType& other_type = AbstractType::Handle(); | 
|   4820   for (intptr_t i = 0; i < len; i++) { |   4625   for (intptr_t i = 0; i < len; i++) { | 
|   4821     type = TypeAt(from_index + i); |   4626     type = TypeAt(from_index + i); | 
|   4822     other_type = other.TypeAt(from_index + i); |   4627     other_type = other.TypeAt(from_index + i); | 
|   4823     if (type.IsNull() || other_type.IsNull() || |   4628     if (type.IsNull() || other_type.IsNull() || | 
|   4824         !type.TypeTest(test_kind, other_type, bound_error, bound_trail, |   4629         !type.TypeTest(test_kind, other_type, bound_error, bound_trail, | 
|   4825                        space)) { |   4630                        space)) { | 
|   4826       return false; |   4631       return false; | 
|   4827     } |   4632     } | 
|   4828   } |   4633   } | 
|   4829   return true; |   4634   return true; | 
|   4830 } |   4635 } | 
|   4831  |   4636  | 
|   4832  |  | 
|   4833 bool TypeArguments::HasInstantiations() const { |   4637 bool TypeArguments::HasInstantiations() const { | 
|   4834   const Array& prior_instantiations = Array::Handle(instantiations()); |   4638   const Array& prior_instantiations = Array::Handle(instantiations()); | 
|   4835   ASSERT(prior_instantiations.Length() > 0);  // Always at least a sentinel. |   4639   ASSERT(prior_instantiations.Length() > 0);  // Always at least a sentinel. | 
|   4836   return prior_instantiations.Length() > 1; |   4640   return prior_instantiations.Length() > 1; | 
|   4837 } |   4641 } | 
|   4838  |   4642  | 
|   4839  |  | 
|   4840 intptr_t TypeArguments::NumInstantiations() const { |   4643 intptr_t TypeArguments::NumInstantiations() const { | 
|   4841   const Array& prior_instantiations = Array::Handle(instantiations()); |   4644   const Array& prior_instantiations = Array::Handle(instantiations()); | 
|   4842   ASSERT(prior_instantiations.Length() > 0);  // Always at least a sentinel. |   4645   ASSERT(prior_instantiations.Length() > 0);  // Always at least a sentinel. | 
|   4843   intptr_t num = 0; |   4646   intptr_t num = 0; | 
|   4844   intptr_t i = 0; |   4647   intptr_t i = 0; | 
|   4845   while (prior_instantiations.At(i) != Smi::New(StubCode::kNoInstantiator)) { |   4648   while (prior_instantiations.At(i) != Smi::New(StubCode::kNoInstantiator)) { | 
|   4846     i += StubCode::kInstantiationSizeInWords; |   4649     i += StubCode::kInstantiationSizeInWords; | 
|   4847     num++; |   4650     num++; | 
|   4848   } |   4651   } | 
|   4849   return num; |   4652   return num; | 
|   4850 } |   4653 } | 
|   4851  |   4654  | 
|   4852  |  | 
|   4853 RawArray* TypeArguments::instantiations() const { |   4655 RawArray* TypeArguments::instantiations() const { | 
|   4854   return raw_ptr()->instantiations_; |   4656   return raw_ptr()->instantiations_; | 
|   4855 } |   4657 } | 
|   4856  |   4658  | 
|   4857  |  | 
|   4858 void TypeArguments::set_instantiations(const Array& value) const { |   4659 void TypeArguments::set_instantiations(const Array& value) const { | 
|   4859   ASSERT(!value.IsNull()); |   4660   ASSERT(!value.IsNull()); | 
|   4860   StorePointer(&raw_ptr()->instantiations_, value.raw()); |   4661   StorePointer(&raw_ptr()->instantiations_, value.raw()); | 
|   4861 } |   4662 } | 
|   4862  |   4663  | 
|   4863  |  | 
|   4864 intptr_t TypeArguments::Length() const { |   4664 intptr_t TypeArguments::Length() const { | 
|   4865   if (IsNull()) { |   4665   if (IsNull()) { | 
|   4866     return 0; |   4666     return 0; | 
|   4867   } |   4667   } | 
|   4868   return Smi::Value(raw_ptr()->length_); |   4668   return Smi::Value(raw_ptr()->length_); | 
|   4869 } |   4669 } | 
|   4870  |   4670  | 
|   4871  |  | 
|   4872 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |   4671 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 
|   4873   return *TypeAddr(index); |   4672   return *TypeAddr(index); | 
|   4874 } |   4673 } | 
|   4875  |   4674  | 
|   4876  |  | 
|   4877 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { |   4675 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | 
|   4878   ASSERT(!IsCanonical()); |   4676   ASSERT(!IsCanonical()); | 
|   4879   StorePointer(TypeAddr(index), value.raw()); |   4677   StorePointer(TypeAddr(index), value.raw()); | 
|   4880 } |   4678 } | 
|   4881  |   4679  | 
|   4882  |  | 
|   4883 bool TypeArguments::IsResolved() const { |   4680 bool TypeArguments::IsResolved() const { | 
|   4884   if (IsCanonical()) { |   4681   if (IsCanonical()) { | 
|   4885     return true; |   4682     return true; | 
|   4886   } |   4683   } | 
|   4887   AbstractType& type = AbstractType::Handle(); |   4684   AbstractType& type = AbstractType::Handle(); | 
|   4888   const intptr_t num_types = Length(); |   4685   const intptr_t num_types = Length(); | 
|   4889   for (intptr_t i = 0; i < num_types; i++) { |   4686   for (intptr_t i = 0; i < num_types; i++) { | 
|   4890     type = TypeAt(i); |   4687     type = TypeAt(i); | 
|   4891     if (!type.IsResolved()) { |   4688     if (!type.IsResolved()) { | 
|   4892       return false; |   4689       return false; | 
|   4893     } |   4690     } | 
|   4894   } |   4691   } | 
|   4895   return true; |   4692   return true; | 
|   4896 } |   4693 } | 
|   4897  |   4694  | 
|   4898  |  | 
|   4899 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, |   4695 bool TypeArguments::IsSubvectorInstantiated(intptr_t from_index, | 
|   4900                                             intptr_t len, |   4696                                             intptr_t len, | 
|   4901                                             Genericity genericity, |   4697                                             Genericity genericity, | 
|   4902                                             intptr_t num_free_fun_type_params, |   4698                                             intptr_t num_free_fun_type_params, | 
|   4903                                             TrailPtr trail) const { |   4699                                             TrailPtr trail) const { | 
|   4904   ASSERT(!IsNull()); |   4700   ASSERT(!IsNull()); | 
|   4905   AbstractType& type = AbstractType::Handle(); |   4701   AbstractType& type = AbstractType::Handle(); | 
|   4906   for (intptr_t i = 0; i < len; i++) { |   4702   for (intptr_t i = 0; i < len; i++) { | 
|   4907     type = TypeAt(from_index + i); |   4703     type = TypeAt(from_index + i); | 
|   4908     // If this type argument T is null, the type A containing T in its flattened |   4704     // If this type argument T is null, the type A containing T in its flattened | 
|   4909     // type argument vector V is recursive and is still being finalized. |   4705     // type argument vector V is recursive and is still being finalized. | 
|   4910     // T is the type argument of a super type of A. T is being instantiated |   4706     // T is the type argument of a super type of A. T is being instantiated | 
|   4911     // during finalization of V, which is also the instantiator. T depends |   4707     // during finalization of V, which is also the instantiator. T depends | 
|   4912     // solely on the type parameters of A and will be replaced by a non-null |   4708     // solely on the type parameters of A and will be replaced by a non-null | 
|   4913     // type before A is marked as finalized. |   4709     // type before A is marked as finalized. | 
|   4914     if (!type.IsNull() && |   4710     if (!type.IsNull() && | 
|   4915         !type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |   4711         !type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 
|   4916       return false; |   4712       return false; | 
|   4917     } |   4713     } | 
|   4918   } |   4714   } | 
|   4919   return true; |   4715   return true; | 
|   4920 } |   4716 } | 
|   4921  |   4717  | 
|   4922  |  | 
|   4923 bool TypeArguments::IsUninstantiatedIdentity() const { |   4718 bool TypeArguments::IsUninstantiatedIdentity() const { | 
|   4924   AbstractType& type = AbstractType::Handle(); |   4719   AbstractType& type = AbstractType::Handle(); | 
|   4925   const intptr_t num_types = Length(); |   4720   const intptr_t num_types = Length(); | 
|   4926   for (intptr_t i = 0; i < num_types; i++) { |   4721   for (intptr_t i = 0; i < num_types; i++) { | 
|   4927     type = TypeAt(i); |   4722     type = TypeAt(i); | 
|   4928     if (type.IsNull()) { |   4723     if (type.IsNull()) { | 
|   4929       continue; |   4724       continue; | 
|   4930     } |   4725     } | 
|   4931     if (!type.IsTypeParameter()) { |   4726     if (!type.IsTypeParameter()) { | 
|   4932       return false; |   4727       return false; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   4948     if (!bound.IsObjectType() && !bound.IsDynamicType()) { |   4743     if (!bound.IsObjectType() && !bound.IsDynamicType()) { | 
|   4949       return false; |   4744       return false; | 
|   4950     } |   4745     } | 
|   4951   } |   4746   } | 
|   4952   return true; |   4747   return true; | 
|   4953   // Note that it is not necessary to verify at runtime that the instantiator |   4748   // Note that it is not necessary to verify at runtime that the instantiator | 
|   4954   // type vector is long enough, since this uninstantiated vector contains as |   4749   // type vector is long enough, since this uninstantiated vector contains as | 
|   4955   // many different type parameters as it is long. |   4750   // many different type parameters as it is long. | 
|   4956 } |   4751 } | 
|   4957  |   4752  | 
|   4958  |  | 
|   4959 // Return true if this uninstantiated type argument vector, once instantiated |   4753 // Return true if this uninstantiated type argument vector, once instantiated | 
|   4960 // at runtime, is a prefix of the type argument vector of its instantiator. |   4754 // at runtime, is a prefix of the type argument vector of its instantiator. | 
|   4961 bool TypeArguments::CanShareInstantiatorTypeArguments( |   4755 bool TypeArguments::CanShareInstantiatorTypeArguments( | 
|   4962     const Class& instantiator_class) const { |   4756     const Class& instantiator_class) const { | 
|   4963   ASSERT(!IsInstantiated()); |   4757   ASSERT(!IsInstantiated()); | 
|   4964   const intptr_t num_type_args = Length(); |   4758   const intptr_t num_type_args = Length(); | 
|   4965   const intptr_t num_instantiator_type_args = |   4759   const intptr_t num_instantiator_type_args = | 
|   4966       instantiator_class.NumTypeArguments(); |   4760       instantiator_class.NumTypeArguments(); | 
|   4967   if (num_type_args > num_instantiator_type_args) { |   4761   if (num_type_args > num_instantiator_type_args) { | 
|   4968     // This vector cannot be a prefix of a shorter vector. |   4762     // This vector cannot be a prefix of a shorter vector. | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5017        i++) { |   4811        i++) { | 
|   5018     type_arg = TypeAt(i); |   4812     type_arg = TypeAt(i); | 
|   5019     super_type_arg = super_type_args.TypeAt(i); |   4813     super_type_arg = super_type_args.TypeAt(i); | 
|   5020     if (!type_arg.Equals(super_type_arg)) { |   4814     if (!type_arg.Equals(super_type_arg)) { | 
|   5021       return false; |   4815       return false; | 
|   5022     } |   4816     } | 
|   5023   } |   4817   } | 
|   5024   return true; |   4818   return true; | 
|   5025 } |   4819 } | 
|   5026  |   4820  | 
|   5027  |  | 
|   5028 bool TypeArguments::IsFinalized() const { |   4821 bool TypeArguments::IsFinalized() const { | 
|   5029   ASSERT(!IsNull()); |   4822   ASSERT(!IsNull()); | 
|   5030   AbstractType& type = AbstractType::Handle(); |   4823   AbstractType& type = AbstractType::Handle(); | 
|   5031   const intptr_t num_types = Length(); |   4824   const intptr_t num_types = Length(); | 
|   5032   for (intptr_t i = 0; i < num_types; i++) { |   4825   for (intptr_t i = 0; i < num_types; i++) { | 
|   5033     type = TypeAt(i); |   4826     type = TypeAt(i); | 
|   5034     if (!type.IsFinalized()) { |   4827     if (!type.IsFinalized()) { | 
|   5035       return false; |   4828       return false; | 
|   5036     } |   4829     } | 
|   5037   } |   4830   } | 
|   5038   return true; |   4831   return true; | 
|   5039 } |   4832 } | 
|   5040  |   4833  | 
|   5041  |  | 
|   5042 bool TypeArguments::IsBounded() const { |   4834 bool TypeArguments::IsBounded() const { | 
|   5043   AbstractType& type = AbstractType::Handle(); |   4835   AbstractType& type = AbstractType::Handle(); | 
|   5044   const intptr_t num_types = Length(); |   4836   const intptr_t num_types = Length(); | 
|   5045   for (intptr_t i = 0; i < num_types; i++) { |   4837   for (intptr_t i = 0; i < num_types; i++) { | 
|   5046     type = TypeAt(i); |   4838     type = TypeAt(i); | 
|   5047     if (type.IsBoundedType()) { |   4839     if (type.IsBoundedType()) { | 
|   5048       return true; |   4840       return true; | 
|   5049     } |   4841     } | 
|   5050     if (type.IsTypeParameter()) { |   4842     if (type.IsTypeParameter()) { | 
|   5051       const AbstractType& bound = |   4843       const AbstractType& bound = | 
|   5052           AbstractType::Handle(TypeParameter::Cast(type).bound()); |   4844           AbstractType::Handle(TypeParameter::Cast(type).bound()); | 
|   5053       if (!bound.IsObjectType() && !bound.IsDynamicType()) { |   4845       if (!bound.IsObjectType() && !bound.IsDynamicType()) { | 
|   5054         return true; |   4846         return true; | 
|   5055       } |   4847       } | 
|   5056       continue; |   4848       continue; | 
|   5057     } |   4849     } | 
|   5058     const TypeArguments& type_args = |   4850     const TypeArguments& type_args = | 
|   5059         TypeArguments::Handle(Type::Cast(type).arguments()); |   4851         TypeArguments::Handle(Type::Cast(type).arguments()); | 
|   5060     if (!type_args.IsNull() && type_args.IsBounded()) { |   4852     if (!type_args.IsNull() && type_args.IsBounded()) { | 
|   5061       return true; |   4853       return true; | 
|   5062     } |   4854     } | 
|   5063   } |   4855   } | 
|   5064   return false; |   4856   return false; | 
|   5065 } |   4857 } | 
|   5066  |   4858  | 
|   5067  |  | 
|   5068 RawTypeArguments* TypeArguments::InstantiateFrom( |   4859 RawTypeArguments* TypeArguments::InstantiateFrom( | 
|   5069     const TypeArguments& instantiator_type_arguments, |   4860     const TypeArguments& instantiator_type_arguments, | 
|   5070     const TypeArguments& function_type_arguments, |   4861     const TypeArguments& function_type_arguments, | 
|   5071     Error* bound_error, |   4862     Error* bound_error, | 
|   5072     TrailPtr instantiation_trail, |   4863     TrailPtr instantiation_trail, | 
|   5073     TrailPtr bound_trail, |   4864     TrailPtr bound_trail, | 
|   5074     Heap::Space space) const { |   4865     Heap::Space space) const { | 
|   5075   ASSERT(!IsInstantiated()); |   4866   ASSERT(!IsInstantiated()); | 
|   5076   if (!instantiator_type_arguments.IsNull() && IsUninstantiatedIdentity() && |   4867   if (!instantiator_type_arguments.IsNull() && IsUninstantiatedIdentity() && | 
|   5077       (instantiator_type_arguments.Length() == Length())) { |   4868       (instantiator_type_arguments.Length() == Length())) { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|   5092     if (!type.IsNull() && !type.IsInstantiated()) { |   4883     if (!type.IsNull() && !type.IsInstantiated()) { | 
|   5093       type = type.InstantiateFrom(instantiator_type_arguments, |   4884       type = type.InstantiateFrom(instantiator_type_arguments, | 
|   5094                                   function_type_arguments, bound_error, |   4885                                   function_type_arguments, bound_error, | 
|   5095                                   instantiation_trail, bound_trail, space); |   4886                                   instantiation_trail, bound_trail, space); | 
|   5096     } |   4887     } | 
|   5097     instantiated_array.SetTypeAt(i, type); |   4888     instantiated_array.SetTypeAt(i, type); | 
|   5098   } |   4889   } | 
|   5099   return instantiated_array.raw(); |   4890   return instantiated_array.raw(); | 
|   5100 } |   4891 } | 
|   5101  |   4892  | 
|   5102  |  | 
|   5103 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( |   4893 RawTypeArguments* TypeArguments::InstantiateAndCanonicalizeFrom( | 
|   5104     const TypeArguments& instantiator_type_arguments, |   4894     const TypeArguments& instantiator_type_arguments, | 
|   5105     const TypeArguments& function_type_arguments, |   4895     const TypeArguments& function_type_arguments, | 
|   5106     Error* bound_error) const { |   4896     Error* bound_error) const { | 
|   5107   ASSERT(!IsInstantiated()); |   4897   ASSERT(!IsInstantiated()); | 
|   5108   ASSERT(instantiator_type_arguments.IsNull() || |   4898   ASSERT(instantiator_type_arguments.IsNull() || | 
|   5109          instantiator_type_arguments.IsCanonical()); |   4899          instantiator_type_arguments.IsCanonical()); | 
|   5110   // TODO(regis): It is not clear yet whether we will canonicalize the result |   4900   // TODO(regis): It is not clear yet whether we will canonicalize the result | 
|   5111   // of the concatenation of function_type_arguments in a nested generic |   4901   // of the concatenation of function_type_arguments in a nested generic | 
|   5112   // function. Leave the assert for now to be safe, but plan on revisiting. |   4902   // function. Leave the assert for now to be safe, but plan on revisiting. | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5156     ASSERT((index + StubCode::kInstantiationSizeInWords) < length); |   4946     ASSERT((index + StubCode::kInstantiationSizeInWords) < length); | 
|   5157   } |   4947   } | 
|   5158   prior_instantiations.SetAt(index + 0, instantiator_type_arguments); |   4948   prior_instantiations.SetAt(index + 0, instantiator_type_arguments); | 
|   5159   prior_instantiations.SetAt(index + 1, function_type_arguments); |   4949   prior_instantiations.SetAt(index + 1, function_type_arguments); | 
|   5160   prior_instantiations.SetAt(index + 2, result); |   4950   prior_instantiations.SetAt(index + 2, result); | 
|   5161   prior_instantiations.SetAt(index + 3, |   4951   prior_instantiations.SetAt(index + 3, | 
|   5162                              Smi::Handle(Smi::New(StubCode::kNoInstantiator))); |   4952                              Smi::Handle(Smi::New(StubCode::kNoInstantiator))); | 
|   5163   return result.raw(); |   4953   return result.raw(); | 
|   5164 } |   4954 } | 
|   5165  |   4955  | 
|   5166  |  | 
|   5167 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |   4956 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { | 
|   5168   if (len < 0 || len > kMaxElements) { |   4957   if (len < 0 || len > kMaxElements) { | 
|   5169     // This should be caught before we reach here. |   4958     // This should be caught before we reach here. | 
|   5170     FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len); |   4959     FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len); | 
|   5171   } |   4960   } | 
|   5172   TypeArguments& result = TypeArguments::Handle(); |   4961   TypeArguments& result = TypeArguments::Handle(); | 
|   5173   { |   4962   { | 
|   5174     RawObject* raw = Object::Allocate(TypeArguments::kClassId, |   4963     RawObject* raw = Object::Allocate(TypeArguments::kClassId, | 
|   5175                                       TypeArguments::InstanceSize(len), space); |   4964                                       TypeArguments::InstanceSize(len), space); | 
|   5176     NoSafepointScope no_safepoint; |   4965     NoSafepointScope no_safepoint; | 
|   5177     result ^= raw; |   4966     result ^= raw; | 
|   5178     // Length must be set before we start storing into the array. |   4967     // Length must be set before we start storing into the array. | 
|   5179     result.SetLength(len); |   4968     result.SetLength(len); | 
|   5180     result.SetHash(0); |   4969     result.SetHash(0); | 
|   5181   } |   4970   } | 
|   5182   // The zero array should have been initialized. |   4971   // The zero array should have been initialized. | 
|   5183   ASSERT(Object::zero_array().raw() != Array::null()); |   4972   ASSERT(Object::zero_array().raw() != Array::null()); | 
|   5184   COMPILE_ASSERT(StubCode::kNoInstantiator == 0); |   4973   COMPILE_ASSERT(StubCode::kNoInstantiator == 0); | 
|   5185   result.set_instantiations(Object::zero_array()); |   4974   result.set_instantiations(Object::zero_array()); | 
|   5186   return result.raw(); |   4975   return result.raw(); | 
|   5187 } |   4976 } | 
|   5188  |   4977  | 
|   5189  |  | 
|   5190 RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const { |   4978 RawAbstractType* const* TypeArguments::TypeAddr(intptr_t index) const { | 
|   5191   ASSERT((index >= 0) && (index < Length())); |   4979   ASSERT((index >= 0) && (index < Length())); | 
|   5192   return &raw_ptr()->types()[index]; |   4980   return &raw_ptr()->types()[index]; | 
|   5193 } |   4981 } | 
|   5194  |   4982  | 
|   5195  |  | 
|   5196 void TypeArguments::SetLength(intptr_t value) const { |   4983 void TypeArguments::SetLength(intptr_t value) const { | 
|   5197   ASSERT(!IsCanonical()); |   4984   ASSERT(!IsCanonical()); | 
|   5198   // This is only safe because we create a new Smi, which does not cause |   4985   // This is only safe because we create a new Smi, which does not cause | 
|   5199   // heap allocation. |   4986   // heap allocation. | 
|   5200   StoreSmi(&raw_ptr()->length_, Smi::New(value)); |   4987   StoreSmi(&raw_ptr()->length_, Smi::New(value)); | 
|   5201 } |   4988 } | 
|   5202  |   4989  | 
|   5203  |  | 
|   5204 RawTypeArguments* TypeArguments::CloneUnfinalized() const { |   4990 RawTypeArguments* TypeArguments::CloneUnfinalized() const { | 
|   5205   if (IsNull() || IsFinalized()) { |   4991   if (IsNull() || IsFinalized()) { | 
|   5206     return raw(); |   4992     return raw(); | 
|   5207   } |   4993   } | 
|   5208   ASSERT(IsResolved()); |   4994   ASSERT(IsResolved()); | 
|   5209   AbstractType& type = AbstractType::Handle(); |   4995   AbstractType& type = AbstractType::Handle(); | 
|   5210   const intptr_t num_types = Length(); |   4996   const intptr_t num_types = Length(); | 
|   5211   const TypeArguments& clone = |   4997   const TypeArguments& clone = | 
|   5212       TypeArguments::Handle(TypeArguments::New(num_types)); |   4998       TypeArguments::Handle(TypeArguments::New(num_types)); | 
|   5213   for (intptr_t i = 0; i < num_types; i++) { |   4999   for (intptr_t i = 0; i < num_types; i++) { | 
|   5214     type = TypeAt(i); |   5000     type = TypeAt(i); | 
|   5215     type = type.CloneUnfinalized(); |   5001     type = type.CloneUnfinalized(); | 
|   5216     clone.SetTypeAt(i, type); |   5002     clone.SetTypeAt(i, type); | 
|   5217   } |   5003   } | 
|   5218   ASSERT(clone.IsResolved()); |   5004   ASSERT(clone.IsResolved()); | 
|   5219   return clone.raw(); |   5005   return clone.raw(); | 
|   5220 } |   5006 } | 
|   5221  |   5007  | 
|   5222  |  | 
|   5223 RawTypeArguments* TypeArguments::CloneUninstantiated(const Class& new_owner, |   5008 RawTypeArguments* TypeArguments::CloneUninstantiated(const Class& new_owner, | 
|   5224                                                      TrailPtr trail) const { |   5009                                                      TrailPtr trail) const { | 
|   5225   ASSERT(!IsNull()); |   5010   ASSERT(!IsNull()); | 
|   5226   ASSERT(IsFinalized()); |   5011   ASSERT(IsFinalized()); | 
|   5227   ASSERT(!IsInstantiated()); |   5012   ASSERT(!IsInstantiated()); | 
|   5228   AbstractType& type = AbstractType::Handle(); |   5013   AbstractType& type = AbstractType::Handle(); | 
|   5229   const intptr_t num_types = Length(); |   5014   const intptr_t num_types = Length(); | 
|   5230   const TypeArguments& clone = |   5015   const TypeArguments& clone = | 
|   5231       TypeArguments::Handle(TypeArguments::New(num_types)); |   5016       TypeArguments::Handle(TypeArguments::New(num_types)); | 
|   5232   for (intptr_t i = 0; i < num_types; i++) { |   5017   for (intptr_t i = 0; i < num_types; i++) { | 
|   5233     type = TypeAt(i); |   5018     type = TypeAt(i); | 
|   5234     if (!type.IsInstantiated()) { |   5019     if (!type.IsInstantiated()) { | 
|   5235       type = type.CloneUninstantiated(new_owner, trail); |   5020       type = type.CloneUninstantiated(new_owner, trail); | 
|   5236     } |   5021     } | 
|   5237     clone.SetTypeAt(i, type); |   5022     clone.SetTypeAt(i, type); | 
|   5238   } |   5023   } | 
|   5239   ASSERT(clone.IsFinalized()); |   5024   ASSERT(clone.IsFinalized()); | 
|   5240   return clone.raw(); |   5025   return clone.raw(); | 
|   5241 } |   5026 } | 
|   5242  |   5027  | 
|   5243  |  | 
|   5244 RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const { |   5028 RawTypeArguments* TypeArguments::Canonicalize(TrailPtr trail) const { | 
|   5245   if (IsNull() || IsCanonical()) { |   5029   if (IsNull() || IsCanonical()) { | 
|   5246     ASSERT(IsOld()); |   5030     ASSERT(IsOld()); | 
|   5247     return this->raw(); |   5031     return this->raw(); | 
|   5248   } |   5032   } | 
|   5249   const intptr_t num_types = Length(); |   5033   const intptr_t num_types = Length(); | 
|   5250   if (IsRaw(0, num_types)) { |   5034   if (IsRaw(0, num_types)) { | 
|   5251     return TypeArguments::null(); |   5035     return TypeArguments::null(); | 
|   5252   } |   5036   } | 
|   5253   Thread* thread = Thread::Current(); |   5037   Thread* thread = Thread::Current(); | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5302     } |   5086     } | 
|   5303     object_store->set_canonical_type_arguments(table.Release()); |   5087     object_store->set_canonical_type_arguments(table.Release()); | 
|   5304   } |   5088   } | 
|   5305   ASSERT(result.Equals(*this)); |   5089   ASSERT(result.Equals(*this)); | 
|   5306   ASSERT(!result.IsNull()); |   5090   ASSERT(!result.IsNull()); | 
|   5307   ASSERT(result.IsTypeArguments()); |   5091   ASSERT(result.IsTypeArguments()); | 
|   5308   ASSERT(result.IsCanonical()); |   5092   ASSERT(result.IsCanonical()); | 
|   5309   return result.raw(); |   5093   return result.raw(); | 
|   5310 } |   5094 } | 
|   5311  |   5095  | 
|   5312  |  | 
|   5313 RawString* TypeArguments::EnumerateURIs() const { |   5096 RawString* TypeArguments::EnumerateURIs() const { | 
|   5314   if (IsNull()) { |   5097   if (IsNull()) { | 
|   5315     return Symbols::Empty().raw(); |   5098     return Symbols::Empty().raw(); | 
|   5316   } |   5099   } | 
|   5317   Thread* thread = Thread::Current(); |   5100   Thread* thread = Thread::Current(); | 
|   5318   Zone* zone = thread->zone(); |   5101   Zone* zone = thread->zone(); | 
|   5319   AbstractType& type = AbstractType::Handle(zone); |   5102   AbstractType& type = AbstractType::Handle(zone); | 
|   5320   const intptr_t num_types = Length(); |   5103   const intptr_t num_types = Length(); | 
|   5321   const Array& pieces = Array::Handle(zone, Array::New(num_types)); |   5104   const Array& pieces = Array::Handle(zone, Array::New(num_types)); | 
|   5322   for (intptr_t i = 0; i < num_types; i++) { |   5105   for (intptr_t i = 0; i < num_types; i++) { | 
|   5323     type = TypeAt(i); |   5106     type = TypeAt(i); | 
|   5324     pieces.SetAt(i, String::Handle(zone, type.EnumerateURIs())); |   5107     pieces.SetAt(i, String::Handle(zone, type.EnumerateURIs())); | 
|   5325   } |   5108   } | 
|   5326   return String::ConcatAll(pieces); |   5109   return String::ConcatAll(pieces); | 
|   5327 } |   5110 } | 
|   5328  |   5111  | 
|   5329  |  | 
|   5330 const char* TypeArguments::ToCString() const { |   5112 const char* TypeArguments::ToCString() const { | 
|   5331   if (IsNull()) { |   5113   if (IsNull()) { | 
|   5332     return "TypeArguments: null"; |   5114     return "TypeArguments: null"; | 
|   5333   } |   5115   } | 
|   5334   Zone* zone = Thread::Current()->zone(); |   5116   Zone* zone = Thread::Current()->zone(); | 
|   5335   const char* prev_cstr = OS::SCreate(zone, "TypeArguments: (%" Pd ")", |   5117   const char* prev_cstr = OS::SCreate(zone, "TypeArguments: (%" Pd ")", | 
|   5336                                       Smi::Value(raw_ptr()->hash_)); |   5118                                       Smi::Value(raw_ptr()->hash_)); | 
|   5337   for (int i = 0; i < Length(); i++) { |   5119   for (int i = 0; i < Length(); i++) { | 
|   5338     const AbstractType& type_at = AbstractType::Handle(zone, TypeAt(i)); |   5120     const AbstractType& type_at = AbstractType::Handle(zone, TypeAt(i)); | 
|   5339     const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); |   5121     const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); | 
|   5340     char* chars = OS::SCreate(zone, "%s [%s]", prev_cstr, type_cstr); |   5122     char* chars = OS::SCreate(zone, "%s [%s]", prev_cstr, type_cstr); | 
|   5341     prev_cstr = chars; |   5123     prev_cstr = chars; | 
|   5342   } |   5124   } | 
|   5343   return prev_cstr; |   5125   return prev_cstr; | 
|   5344 } |   5126 } | 
|   5345  |   5127  | 
|   5346  |  | 
|   5347 const char* PatchClass::ToCString() const { |   5128 const char* PatchClass::ToCString() const { | 
|   5348   const Class& cls = Class::Handle(patched_class()); |   5129   const Class& cls = Class::Handle(patched_class()); | 
|   5349   const char* cls_name = cls.ToCString(); |   5130   const char* cls_name = cls.ToCString(); | 
|   5350   return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name); |   5131   return OS::SCreate(Thread::Current()->zone(), "PatchClass for %s", cls_name); | 
|   5351 } |   5132 } | 
|   5352  |   5133  | 
|   5353  |  | 
|   5354 RawPatchClass* PatchClass::New(const Class& patched_class, |   5134 RawPatchClass* PatchClass::New(const Class& patched_class, | 
|   5355                                const Class& origin_class) { |   5135                                const Class& origin_class) { | 
|   5356   const PatchClass& result = PatchClass::Handle(PatchClass::New()); |   5136   const PatchClass& result = PatchClass::Handle(PatchClass::New()); | 
|   5357   result.set_patched_class(patched_class); |   5137   result.set_patched_class(patched_class); | 
|   5358   result.set_origin_class(origin_class); |   5138   result.set_origin_class(origin_class); | 
|   5359   result.set_script(Script::Handle(origin_class.script())); |   5139   result.set_script(Script::Handle(origin_class.script())); | 
|   5360   return result.raw(); |   5140   return result.raw(); | 
|   5361 } |   5141 } | 
|   5362  |   5142  | 
|   5363  |  | 
|   5364 RawPatchClass* PatchClass::New(const Class& patched_class, |   5143 RawPatchClass* PatchClass::New(const Class& patched_class, | 
|   5365                                const Script& script) { |   5144                                const Script& script) { | 
|   5366   const PatchClass& result = PatchClass::Handle(PatchClass::New()); |   5145   const PatchClass& result = PatchClass::Handle(PatchClass::New()); | 
|   5367   result.set_patched_class(patched_class); |   5146   result.set_patched_class(patched_class); | 
|   5368   result.set_origin_class(patched_class); |   5147   result.set_origin_class(patched_class); | 
|   5369   result.set_script(script); |   5148   result.set_script(script); | 
|   5370   return result.raw(); |   5149   return result.raw(); | 
|   5371 } |   5150 } | 
|   5372  |   5151  | 
|   5373  |  | 
|   5374 RawPatchClass* PatchClass::New() { |   5152 RawPatchClass* PatchClass::New() { | 
|   5375   ASSERT(Object::patch_class_class() != Class::null()); |   5153   ASSERT(Object::patch_class_class() != Class::null()); | 
|   5376   RawObject* raw = Object::Allocate(PatchClass::kClassId, |   5154   RawObject* raw = Object::Allocate(PatchClass::kClassId, | 
|   5377                                     PatchClass::InstanceSize(), Heap::kOld); |   5155                                     PatchClass::InstanceSize(), Heap::kOld); | 
|   5378   return reinterpret_cast<RawPatchClass*>(raw); |   5156   return reinterpret_cast<RawPatchClass*>(raw); | 
|   5379 } |   5157 } | 
|   5380  |   5158  | 
|   5381  |  | 
|   5382 void PatchClass::set_patched_class(const Class& value) const { |   5159 void PatchClass::set_patched_class(const Class& value) const { | 
|   5383   StorePointer(&raw_ptr()->patched_class_, value.raw()); |   5160   StorePointer(&raw_ptr()->patched_class_, value.raw()); | 
|   5384 } |   5161 } | 
|   5385  |   5162  | 
|   5386  |  | 
|   5387 void PatchClass::set_origin_class(const Class& value) const { |   5163 void PatchClass::set_origin_class(const Class& value) const { | 
|   5388   StorePointer(&raw_ptr()->origin_class_, value.raw()); |   5164   StorePointer(&raw_ptr()->origin_class_, value.raw()); | 
|   5389 } |   5165 } | 
|   5390  |   5166  | 
|   5391  |  | 
|   5392 void PatchClass::set_script(const Script& value) const { |   5167 void PatchClass::set_script(const Script& value) const { | 
|   5393   StorePointer(&raw_ptr()->script_, value.raw()); |   5168   StorePointer(&raw_ptr()->script_, value.raw()); | 
|   5394 } |   5169 } | 
|   5395  |   5170  | 
|   5396  |  | 
|   5397 intptr_t Function::Hash() const { |   5171 intptr_t Function::Hash() const { | 
|   5398   return String::HashRawSymbol(name()); |   5172   return String::HashRawSymbol(name()); | 
|   5399 } |   5173 } | 
|   5400  |   5174  | 
|   5401  |  | 
|   5402 bool Function::HasBreakpoint() const { |   5175 bool Function::HasBreakpoint() const { | 
|   5403   if (!FLAG_support_debugger) { |   5176   if (!FLAG_support_debugger) { | 
|   5404     return false; |   5177     return false; | 
|   5405   } |   5178   } | 
|   5406   Thread* thread = Thread::Current(); |   5179   Thread* thread = Thread::Current(); | 
|   5407   return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); |   5180   return thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); | 
|   5408 } |   5181 } | 
|   5409  |   5182  | 
|   5410  |  | 
|   5411 void Function::InstallOptimizedCode(const Code& code) const { |   5183 void Function::InstallOptimizedCode(const Code& code) const { | 
|   5412   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |   5184   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|   5413   // We may not have previous code if FLAG_precompile is set. |   5185   // We may not have previous code if FLAG_precompile is set. | 
|   5414   // Hot-reload may have already disabled the current code. |   5186   // Hot-reload may have already disabled the current code. | 
|   5415   if (HasCode() && !Code::Handle(CurrentCode()).IsDisabled()) { |   5187   if (HasCode() && !Code::Handle(CurrentCode()).IsDisabled()) { | 
|   5416     Code::Handle(CurrentCode()).DisableDartCode(); |   5188     Code::Handle(CurrentCode()).DisableDartCode(); | 
|   5417   } |   5189   } | 
|   5418   AttachCode(code); |   5190   AttachCode(code); | 
|   5419 } |   5191 } | 
|   5420  |   5192  | 
|   5421  |  | 
|   5422 void Function::SetInstructions(const Code& value) const { |   5193 void Function::SetInstructions(const Code& value) const { | 
|   5423   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |   5194   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|   5424   SetInstructionsSafe(value); |   5195   SetInstructionsSafe(value); | 
|   5425 } |   5196 } | 
|   5426  |   5197  | 
|   5427  |  | 
|   5428 void Function::SetInstructionsSafe(const Code& value) const { |   5198 void Function::SetInstructionsSafe(const Code& value) const { | 
|   5429   StorePointer(&raw_ptr()->code_, value.raw()); |   5199   StorePointer(&raw_ptr()->code_, value.raw()); | 
|   5430   StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint()); |   5200   StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint()); | 
|   5431 } |   5201 } | 
|   5432  |   5202  | 
|   5433  |  | 
|   5434 void Function::AttachCode(const Code& value) const { |   5203 void Function::AttachCode(const Code& value) const { | 
|   5435   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |   5204   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|   5436   // Finish setting up code before activating it. |   5205   // Finish setting up code before activating it. | 
|   5437   value.set_owner(*this); |   5206   value.set_owner(*this); | 
|   5438   SetInstructions(value); |   5207   SetInstructions(value); | 
|   5439   ASSERT(Function::Handle(value.function()).IsNull() || |   5208   ASSERT(Function::Handle(value.function()).IsNull() || | 
|   5440          (value.function() == this->raw())); |   5209          (value.function() == this->raw())); | 
|   5441 } |   5210 } | 
|   5442  |   5211  | 
|   5443  |  | 
|   5444 bool Function::HasCode() const { |   5212 bool Function::HasCode() const { | 
|   5445   ASSERT(raw_ptr()->code_ != Code::null()); |   5213   ASSERT(raw_ptr()->code_ != Code::null()); | 
|   5446   return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); |   5214   return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); | 
|   5447 } |   5215 } | 
|   5448  |   5216  | 
|   5449  |  | 
|   5450 void Function::ClearCode() const { |   5217 void Function::ClearCode() const { | 
|   5451 #if defined(DART_PRECOMPILED_RUNTIME) |   5218 #if defined(DART_PRECOMPILED_RUNTIME) | 
|   5452   UNREACHABLE(); |   5219   UNREACHABLE(); | 
|   5453 #else |   5220 #else | 
|   5454   ASSERT(Thread::Current()->IsMutatorThread()); |   5221   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   5455   StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); |   5222   StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); | 
|   5456   SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); |   5223   SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 
|   5457 #endif |   5224 #endif | 
|   5458 } |   5225 } | 
|   5459  |   5226  | 
|   5460  |  | 
|   5461 void Function::EnsureHasCompiledUnoptimizedCode() const { |   5227 void Function::EnsureHasCompiledUnoptimizedCode() const { | 
|   5462   Thread* thread = Thread::Current(); |   5228   Thread* thread = Thread::Current(); | 
|   5463   Zone* zone = thread->zone(); |   5229   Zone* zone = thread->zone(); | 
|   5464   ASSERT(thread->IsMutatorThread()); |   5230   ASSERT(thread->IsMutatorThread()); | 
|   5465  |   5231  | 
|   5466   const Error& error = |   5232   const Error& error = | 
|   5467       Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); |   5233       Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); | 
|   5468   if (!error.IsNull()) { |   5234   if (!error.IsNull()) { | 
|   5469     Exceptions::PropagateError(error); |   5235     Exceptions::PropagateError(error); | 
|   5470   } |   5236   } | 
|   5471 } |   5237 } | 
|   5472  |   5238  | 
|   5473  |  | 
|   5474 void Function::SwitchToUnoptimizedCode() const { |   5239 void Function::SwitchToUnoptimizedCode() const { | 
|   5475   ASSERT(HasOptimizedCode()); |   5240   ASSERT(HasOptimizedCode()); | 
|   5476   Thread* thread = Thread::Current(); |   5241   Thread* thread = Thread::Current(); | 
|   5477   Isolate* isolate = thread->isolate(); |   5242   Isolate* isolate = thread->isolate(); | 
|   5478   Zone* zone = thread->zone(); |   5243   Zone* zone = thread->zone(); | 
|   5479   ASSERT(thread->IsMutatorThread()); |   5244   ASSERT(thread->IsMutatorThread()); | 
|   5480   const Code& current_code = Code::Handle(zone, CurrentCode()); |   5245   const Code& current_code = Code::Handle(zone, CurrentCode()); | 
|   5481  |   5246  | 
|   5482   if (FLAG_trace_deoptimization_verbose) { |   5247   if (FLAG_trace_deoptimization_verbose) { | 
|   5483     THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", |   5248     THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n", | 
|   5484               ToFullyQualifiedCString(), current_code.UncheckedEntryPoint()); |   5249               ToFullyQualifiedCString(), current_code.UncheckedEntryPoint()); | 
|   5485   } |   5250   } | 
|   5486   current_code.DisableDartCode(); |   5251   current_code.DisableDartCode(); | 
|   5487   const Error& error = |   5252   const Error& error = | 
|   5488       Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); |   5253       Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, *this)); | 
|   5489   if (!error.IsNull()) { |   5254   if (!error.IsNull()) { | 
|   5490     Exceptions::PropagateError(error); |   5255     Exceptions::PropagateError(error); | 
|   5491   } |   5256   } | 
|   5492   const Code& unopt_code = Code::Handle(zone, unoptimized_code()); |   5257   const Code& unopt_code = Code::Handle(zone, unoptimized_code()); | 
|   5493   AttachCode(unopt_code); |   5258   AttachCode(unopt_code); | 
|   5494   unopt_code.Enable(); |   5259   unopt_code.Enable(); | 
|   5495   isolate->TrackDeoptimizedCode(current_code); |   5260   isolate->TrackDeoptimizedCode(current_code); | 
|   5496 } |   5261 } | 
|   5497  |   5262  | 
|   5498  |  | 
|   5499 void Function::SwitchToLazyCompiledUnoptimizedCode() const { |   5263 void Function::SwitchToLazyCompiledUnoptimizedCode() const { | 
|   5500   if (!HasOptimizedCode()) { |   5264   if (!HasOptimizedCode()) { | 
|   5501     return; |   5265     return; | 
|   5502   } |   5266   } | 
|   5503  |   5267  | 
|   5504   Thread* thread = Thread::Current(); |   5268   Thread* thread = Thread::Current(); | 
|   5505   Zone* zone = thread->zone(); |   5269   Zone* zone = thread->zone(); | 
|   5506   ASSERT(thread->IsMutatorThread()); |   5270   ASSERT(thread->IsMutatorThread()); | 
|   5507  |   5271  | 
|   5508   const Code& current_code = Code::Handle(zone, CurrentCode()); |   5272   const Code& current_code = Code::Handle(zone, CurrentCode()); | 
|   5509   TIR_Print("Disabling optimized code for %s\n", ToCString()); |   5273   TIR_Print("Disabling optimized code for %s\n", ToCString()); | 
|   5510   current_code.DisableDartCode(); |   5274   current_code.DisableDartCode(); | 
|   5511  |   5275  | 
|   5512   const Code& unopt_code = Code::Handle(zone, unoptimized_code()); |   5276   const Code& unopt_code = Code::Handle(zone, unoptimized_code()); | 
|   5513   if (unopt_code.IsNull()) { |   5277   if (unopt_code.IsNull()) { | 
|   5514     // Set the lazy compile code. |   5278     // Set the lazy compile code. | 
|   5515     TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); |   5279     TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); | 
|   5516     SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); |   5280     SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); | 
|   5517     return; |   5281     return; | 
|   5518   } |   5282   } | 
|   5519  |   5283  | 
|   5520   TIR_Print("Switched to unoptimized code for %s\n", ToCString()); |   5284   TIR_Print("Switched to unoptimized code for %s\n", ToCString()); | 
|   5521  |   5285  | 
|   5522   AttachCode(unopt_code); |   5286   AttachCode(unopt_code); | 
|   5523   unopt_code.Enable(); |   5287   unopt_code.Enable(); | 
|   5524 } |   5288 } | 
|   5525  |   5289  | 
|   5526  |  | 
|   5527 void Function::set_unoptimized_code(const Code& value) const { |   5290 void Function::set_unoptimized_code(const Code& value) const { | 
|   5528 #if defined(DART_PRECOMPILED_RUNTIME) |   5291 #if defined(DART_PRECOMPILED_RUNTIME) | 
|   5529   UNREACHABLE(); |   5292   UNREACHABLE(); | 
|   5530 #else |   5293 #else | 
|   5531   ASSERT(Thread::Current()->IsMutatorThread()); |   5294   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   5532   ASSERT(value.IsNull() || !value.is_optimized()); |   5295   ASSERT(value.IsNull() || !value.is_optimized()); | 
|   5533   StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); |   5296   StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); | 
|   5534 #endif |   5297 #endif | 
|   5535 } |   5298 } | 
|   5536  |   5299  | 
|   5537  |  | 
|   5538 RawContextScope* Function::context_scope() const { |   5300 RawContextScope* Function::context_scope() const { | 
|   5539   if (IsClosureFunction()) { |   5301   if (IsClosureFunction()) { | 
|   5540     const Object& obj = Object::Handle(raw_ptr()->data_); |   5302     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5541     ASSERT(!obj.IsNull()); |   5303     ASSERT(!obj.IsNull()); | 
|   5542     return ClosureData::Cast(obj).context_scope(); |   5304     return ClosureData::Cast(obj).context_scope(); | 
|   5543   } |   5305   } | 
|   5544   return ContextScope::null(); |   5306   return ContextScope::null(); | 
|   5545 } |   5307 } | 
|   5546  |   5308  | 
|   5547  |  | 
|   5548 void Function::set_context_scope(const ContextScope& value) const { |   5309 void Function::set_context_scope(const ContextScope& value) const { | 
|   5549   if (IsClosureFunction()) { |   5310   if (IsClosureFunction()) { | 
|   5550     const Object& obj = Object::Handle(raw_ptr()->data_); |   5311     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5551     ASSERT(!obj.IsNull()); |   5312     ASSERT(!obj.IsNull()); | 
|   5552     ClosureData::Cast(obj).set_context_scope(value); |   5313     ClosureData::Cast(obj).set_context_scope(value); | 
|   5553     return; |   5314     return; | 
|   5554   } |   5315   } | 
|   5555   UNREACHABLE(); |   5316   UNREACHABLE(); | 
|   5556 } |   5317 } | 
|   5557  |   5318  | 
|   5558  |  | 
|   5559 RawInstance* Function::implicit_static_closure() const { |   5319 RawInstance* Function::implicit_static_closure() const { | 
|   5560   if (IsImplicitStaticClosureFunction()) { |   5320   if (IsImplicitStaticClosureFunction()) { | 
|   5561     const Object& obj = Object::Handle(raw_ptr()->data_); |   5321     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5562     ASSERT(!obj.IsNull()); |   5322     ASSERT(!obj.IsNull()); | 
|   5563     return ClosureData::Cast(obj).implicit_static_closure(); |   5323     return ClosureData::Cast(obj).implicit_static_closure(); | 
|   5564   } |   5324   } | 
|   5565   return Instance::null(); |   5325   return Instance::null(); | 
|   5566 } |   5326 } | 
|   5567  |   5327  | 
|   5568  |  | 
|   5569 void Function::set_implicit_static_closure(const Instance& closure) const { |   5328 void Function::set_implicit_static_closure(const Instance& closure) const { | 
|   5570   if (IsImplicitStaticClosureFunction()) { |   5329   if (IsImplicitStaticClosureFunction()) { | 
|   5571     const Object& obj = Object::Handle(raw_ptr()->data_); |   5330     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5572     ASSERT(!obj.IsNull()); |   5331     ASSERT(!obj.IsNull()); | 
|   5573     ClosureData::Cast(obj).set_implicit_static_closure(closure); |   5332     ClosureData::Cast(obj).set_implicit_static_closure(closure); | 
|   5574     return; |   5333     return; | 
|   5575   } |   5334   } | 
|   5576   UNREACHABLE(); |   5335   UNREACHABLE(); | 
|   5577 } |   5336 } | 
|   5578  |   5337  | 
|   5579  |  | 
|   5580 RawScript* Function::eval_script() const { |   5338 RawScript* Function::eval_script() const { | 
|   5581   const Object& obj = Object::Handle(raw_ptr()->data_); |   5339   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5582   if (obj.IsScript()) { |   5340   if (obj.IsScript()) { | 
|   5583     return Script::Cast(obj).raw(); |   5341     return Script::Cast(obj).raw(); | 
|   5584   } |   5342   } | 
|   5585   return Script::null(); |   5343   return Script::null(); | 
|   5586 } |   5344 } | 
|   5587  |   5345  | 
|   5588  |  | 
|   5589 void Function::set_eval_script(const Script& script) const { |   5346 void Function::set_eval_script(const Script& script) const { | 
|   5590   ASSERT(token_pos() == TokenPosition::kMinSource); |   5347   ASSERT(token_pos() == TokenPosition::kMinSource); | 
|   5591   ASSERT(raw_ptr()->data_ == Object::null()); |   5348   ASSERT(raw_ptr()->data_ == Object::null()); | 
|   5592   set_data(script); |   5349   set_data(script); | 
|   5593 } |   5350 } | 
|   5594  |   5351  | 
|   5595  |  | 
|   5596 RawFunction* Function::extracted_method_closure() const { |   5352 RawFunction* Function::extracted_method_closure() const { | 
|   5597   ASSERT(kind() == RawFunction::kMethodExtractor); |   5353   ASSERT(kind() == RawFunction::kMethodExtractor); | 
|   5598   const Object& obj = Object::Handle(raw_ptr()->data_); |   5354   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5599   ASSERT(obj.IsFunction()); |   5355   ASSERT(obj.IsFunction()); | 
|   5600   return Function::Cast(obj).raw(); |   5356   return Function::Cast(obj).raw(); | 
|   5601 } |   5357 } | 
|   5602  |   5358  | 
|   5603  |  | 
|   5604 void Function::set_extracted_method_closure(const Function& value) const { |   5359 void Function::set_extracted_method_closure(const Function& value) const { | 
|   5605   ASSERT(kind() == RawFunction::kMethodExtractor); |   5360   ASSERT(kind() == RawFunction::kMethodExtractor); | 
|   5606   ASSERT(raw_ptr()->data_ == Object::null()); |   5361   ASSERT(raw_ptr()->data_ == Object::null()); | 
|   5607   set_data(value); |   5362   set_data(value); | 
|   5608 } |   5363 } | 
|   5609  |   5364  | 
|   5610  |  | 
|   5611 RawArray* Function::saved_args_desc() const { |   5365 RawArray* Function::saved_args_desc() const { | 
|   5612   ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |   5366   ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || | 
|   5613          kind() == RawFunction::kInvokeFieldDispatcher); |   5367          kind() == RawFunction::kInvokeFieldDispatcher); | 
|   5614   const Object& obj = Object::Handle(raw_ptr()->data_); |   5368   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5615   ASSERT(obj.IsArray()); |   5369   ASSERT(obj.IsArray()); | 
|   5616   return Array::Cast(obj).raw(); |   5370   return Array::Cast(obj).raw(); | 
|   5617 } |   5371 } | 
|   5618  |   5372  | 
|   5619  |  | 
|   5620 void Function::set_saved_args_desc(const Array& value) const { |   5373 void Function::set_saved_args_desc(const Array& value) const { | 
|   5621   ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || |   5374   ASSERT(kind() == RawFunction::kNoSuchMethodDispatcher || | 
|   5622          kind() == RawFunction::kInvokeFieldDispatcher); |   5375          kind() == RawFunction::kInvokeFieldDispatcher); | 
|   5623   ASSERT(raw_ptr()->data_ == Object::null()); |   5376   ASSERT(raw_ptr()->data_ == Object::null()); | 
|   5624   set_data(value); |   5377   set_data(value); | 
|   5625 } |   5378 } | 
|   5626  |   5379  | 
|   5627  |  | 
|   5628 RawField* Function::LookupImplicitGetterSetterField() const { |   5380 RawField* Function::LookupImplicitGetterSetterField() const { | 
|   5629   ASSERT((kind() == RawFunction::kImplicitGetter) || |   5381   ASSERT((kind() == RawFunction::kImplicitGetter) || | 
|   5630          (kind() == RawFunction::kImplicitSetter) || |   5382          (kind() == RawFunction::kImplicitSetter) || | 
|   5631          (kind() == RawFunction::kImplicitStaticFinalGetter)); |   5383          (kind() == RawFunction::kImplicitStaticFinalGetter)); | 
|   5632   const Class& owner = Class::Handle(Owner()); |   5384   const Class& owner = Class::Handle(Owner()); | 
|   5633   ASSERT(!owner.IsNull()); |   5385   ASSERT(!owner.IsNull()); | 
|   5634   const Array& fields = Array::Handle(owner.fields()); |   5386   const Array& fields = Array::Handle(owner.fields()); | 
|   5635   ASSERT(!fields.IsNull()); |   5387   ASSERT(!fields.IsNull()); | 
|   5636   Field& field = Field::Handle(); |   5388   Field& field = Field::Handle(); | 
|   5637   for (intptr_t i = 0; i < fields.Length(); i++) { |   5389   for (intptr_t i = 0; i < fields.Length(); i++) { | 
|   5638     field ^= fields.At(i); |   5390     field ^= fields.At(i); | 
|   5639     ASSERT(!field.IsNull()); |   5391     ASSERT(!field.IsNull()); | 
|   5640     if (field.token_pos() == token_pos()) { |   5392     if (field.token_pos() == token_pos()) { | 
|   5641       return field.raw(); |   5393       return field.raw(); | 
|   5642     } |   5394     } | 
|   5643   } |   5395   } | 
|   5644   return Field::null(); |   5396   return Field::null(); | 
|   5645 } |   5397 } | 
|   5646  |   5398  | 
|   5647  |  | 
|   5648 RawFunction* Function::parent_function() const { |   5399 RawFunction* Function::parent_function() const { | 
|   5649   if (IsClosureFunction() || IsSignatureFunction()) { |   5400   if (IsClosureFunction() || IsSignatureFunction()) { | 
|   5650     const Object& obj = Object::Handle(raw_ptr()->data_); |   5401     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5651     ASSERT(!obj.IsNull()); |   5402     ASSERT(!obj.IsNull()); | 
|   5652     if (IsClosureFunction()) { |   5403     if (IsClosureFunction()) { | 
|   5653       return ClosureData::Cast(obj).parent_function(); |   5404       return ClosureData::Cast(obj).parent_function(); | 
|   5654     } else { |   5405     } else { | 
|   5655       return SignatureData::Cast(obj).parent_function(); |   5406       return SignatureData::Cast(obj).parent_function(); | 
|   5656     } |   5407     } | 
|   5657   } |   5408   } | 
|   5658   return Function::null(); |   5409   return Function::null(); | 
|   5659 } |   5410 } | 
|   5660  |   5411  | 
|   5661  |  | 
|   5662 void Function::set_parent_function(const Function& value) const { |   5412 void Function::set_parent_function(const Function& value) const { | 
|   5663   const Object& obj = Object::Handle(raw_ptr()->data_); |   5413   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5664   ASSERT(!obj.IsNull()); |   5414   ASSERT(!obj.IsNull()); | 
|   5665   if (IsClosureFunction()) { |   5415   if (IsClosureFunction()) { | 
|   5666     ClosureData::Cast(obj).set_parent_function(value); |   5416     ClosureData::Cast(obj).set_parent_function(value); | 
|   5667   } else { |   5417   } else { | 
|   5668     ASSERT(IsSignatureFunction()); |   5418     ASSERT(IsSignatureFunction()); | 
|   5669     SignatureData::Cast(obj).set_parent_function(value); |   5419     SignatureData::Cast(obj).set_parent_function(value); | 
|   5670   } |   5420   } | 
|   5671 } |   5421 } | 
|   5672  |   5422  | 
|   5673  |  | 
|   5674 bool Function::HasGenericParent() const { |   5423 bool Function::HasGenericParent() const { | 
|   5675   if (IsImplicitClosureFunction()) { |   5424   if (IsImplicitClosureFunction()) { | 
|   5676     // The parent function of an implicit closure function is not the enclosing |   5425     // The parent function of an implicit closure function is not the enclosing | 
|   5677     // function we are asking about here. |   5426     // function we are asking about here. | 
|   5678     return false; |   5427     return false; | 
|   5679   } |   5428   } | 
|   5680   Function& parent = Function::Handle(parent_function()); |   5429   Function& parent = Function::Handle(parent_function()); | 
|   5681   while (!parent.IsNull()) { |   5430   while (!parent.IsNull()) { | 
|   5682     if (parent.IsGeneric()) { |   5431     if (parent.IsGeneric()) { | 
|   5683       return true; |   5432       return true; | 
|   5684     } |   5433     } | 
|   5685     parent = parent.parent_function(); |   5434     parent = parent.parent_function(); | 
|   5686   } |   5435   } | 
|   5687   return false; |   5436   return false; | 
|   5688 } |   5437 } | 
|   5689  |   5438  | 
|   5690  |  | 
|   5691 RawFunction* Function::implicit_closure_function() const { |   5439 RawFunction* Function::implicit_closure_function() const { | 
|   5692   if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) { |   5440   if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) { | 
|   5693     return Function::null(); |   5441     return Function::null(); | 
|   5694   } |   5442   } | 
|   5695   const Object& obj = Object::Handle(raw_ptr()->data_); |   5443   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5696   ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray()); |   5444   ASSERT(obj.IsNull() || obj.IsScript() || obj.IsFunction() || obj.IsArray()); | 
|   5697   if (obj.IsNull() || obj.IsScript()) { |   5445   if (obj.IsNull() || obj.IsScript()) { | 
|   5698     return Function::null(); |   5446     return Function::null(); | 
|   5699   } |   5447   } | 
|   5700   if (obj.IsFunction()) { |   5448   if (obj.IsFunction()) { | 
|   5701     return Function::Cast(obj).raw(); |   5449     return Function::Cast(obj).raw(); | 
|   5702   } |   5450   } | 
|   5703   ASSERT(is_native()); |   5451   ASSERT(is_native()); | 
|   5704   ASSERT(obj.IsArray()); |   5452   ASSERT(obj.IsArray()); | 
|   5705   const Object& res = Object::Handle(Array::Cast(obj).At(1)); |   5453   const Object& res = Object::Handle(Array::Cast(obj).At(1)); | 
|   5706   return res.IsNull() ? Function::null() : Function::Cast(res).raw(); |   5454   return res.IsNull() ? Function::null() : Function::Cast(res).raw(); | 
|   5707 } |   5455 } | 
|   5708  |   5456  | 
|   5709  |  | 
|   5710 void Function::set_implicit_closure_function(const Function& value) const { |   5457 void Function::set_implicit_closure_function(const Function& value) const { | 
|   5711   ASSERT(!IsClosureFunction() && !IsSignatureFunction()); |   5458   ASSERT(!IsClosureFunction() && !IsSignatureFunction()); | 
|   5712   if (is_native()) { |   5459   if (is_native()) { | 
|   5713     const Object& obj = Object::Handle(raw_ptr()->data_); |   5460     const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5714     ASSERT(obj.IsArray()); |   5461     ASSERT(obj.IsArray()); | 
|   5715     ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); |   5462     ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); | 
|   5716     Array::Cast(obj).SetAt(1, value); |   5463     Array::Cast(obj).SetAt(1, value); | 
|   5717   } else { |   5464   } else { | 
|   5718     ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); |   5465     ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); | 
|   5719     set_data(value); |   5466     set_data(value); | 
|   5720   } |   5467   } | 
|   5721 } |   5468 } | 
|   5722  |   5469  | 
|   5723  |  | 
|   5724 RawType* Function::ExistingSignatureType() const { |   5470 RawType* Function::ExistingSignatureType() const { | 
|   5725   const Object& obj = Object::Handle(raw_ptr()->data_); |   5471   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5726   ASSERT(!obj.IsNull()); |   5472   ASSERT(!obj.IsNull()); | 
|   5727   if (IsSignatureFunction()) { |   5473   if (IsSignatureFunction()) { | 
|   5728     return SignatureData::Cast(obj).signature_type(); |   5474     return SignatureData::Cast(obj).signature_type(); | 
|   5729   } else { |   5475   } else { | 
|   5730     ASSERT(IsClosureFunction()); |   5476     ASSERT(IsClosureFunction()); | 
|   5731     return ClosureData::Cast(obj).signature_type(); |   5477     return ClosureData::Cast(obj).signature_type(); | 
|   5732   } |   5478   } | 
|   5733 } |   5479 } | 
|   5734  |   5480  | 
|   5735  |  | 
|   5736 RawFunction* Function::CanonicalSignatureFunction(TrailPtr trail) const { |   5481 RawFunction* Function::CanonicalSignatureFunction(TrailPtr trail) const { | 
|   5737   ASSERT(!IsSignatureFunction()); |   5482   ASSERT(!IsSignatureFunction()); | 
|   5738   Zone* zone = Thread::Current()->zone(); |   5483   Zone* zone = Thread::Current()->zone(); | 
|   5739   Function& parent = Function::Handle(zone, parent_function()); |   5484   Function& parent = Function::Handle(zone, parent_function()); | 
|   5740   if (!parent.IsNull() && !parent.IsSignatureFunction()) { |   5485   if (!parent.IsNull() && !parent.IsSignatureFunction()) { | 
|   5741     // Make sure the parent function is also a signature function. |   5486     // Make sure the parent function is also a signature function. | 
|   5742     parent = parent.CanonicalSignatureFunction(trail); |   5487     parent = parent.CanonicalSignatureFunction(trail); | 
|   5743   } |   5488   } | 
|   5744   const Class& owner = Class::Handle(zone, Owner()); |   5489   const Class& owner = Class::Handle(zone, Owner()); | 
|   5745   const Function& sig_fun = Function::Handle( |   5490   const Function& sig_fun = Function::Handle( | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|   5763       Array::Handle(Array::New(num_params, Heap::kOld))); |   5508       Array::Handle(Array::New(num_params, Heap::kOld))); | 
|   5764   for (intptr_t i = 0; i < num_params; i++) { |   5509   for (intptr_t i = 0; i < num_params; i++) { | 
|   5765     type = ParameterTypeAt(i); |   5510     type = ParameterTypeAt(i); | 
|   5766     type = type.Canonicalize(trail); |   5511     type = type.Canonicalize(trail); | 
|   5767     sig_fun.SetParameterTypeAt(i, type); |   5512     sig_fun.SetParameterTypeAt(i, type); | 
|   5768   } |   5513   } | 
|   5769   sig_fun.set_parameter_names(Array::Handle(zone, parameter_names())); |   5514   sig_fun.set_parameter_names(Array::Handle(zone, parameter_names())); | 
|   5770   return sig_fun.raw(); |   5515   return sig_fun.raw(); | 
|   5771 } |   5516 } | 
|   5772  |   5517  | 
|   5773  |  | 
|   5774 RawType* Function::SignatureType() const { |   5518 RawType* Function::SignatureType() const { | 
|   5775   Type& type = Type::Handle(ExistingSignatureType()); |   5519   Type& type = Type::Handle(ExistingSignatureType()); | 
|   5776   if (type.IsNull()) { |   5520   if (type.IsNull()) { | 
|   5777     // The function type of this function is not yet cached and needs to be |   5521     // The function type of this function is not yet cached and needs to be | 
|   5778     // constructed and cached here. |   5522     // constructed and cached here. | 
|   5779     // A function type is type parameterized in the same way as the owner class |   5523     // A function type is type parameterized in the same way as the owner class | 
|   5780     // of its non-static signature function. |   5524     // of its non-static signature function. | 
|   5781     // It is not type parameterized if its signature function is static, or if |   5525     // It is not type parameterized if its signature function is static, or if | 
|   5782     // none of its result type or formal parameter types are type parameterized. |   5526     // none of its result type or formal parameter types are type parameterized. | 
|   5783     // Unless the function type is a generic typedef, the type arguments of the |   5527     // Unless the function type is a generic typedef, the type arguments of the | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   5805     const TypeArguments& signature_type_arguments = |   5549     const TypeArguments& signature_type_arguments = | 
|   5806         TypeArguments::Handle(scope_class.type_parameters()); |   5550         TypeArguments::Handle(scope_class.type_parameters()); | 
|   5807     // Return the still unfinalized signature type. |   5551     // Return the still unfinalized signature type. | 
|   5808     type = Type::New(scope_class, signature_type_arguments, token_pos()); |   5552     type = Type::New(scope_class, signature_type_arguments, token_pos()); | 
|   5809     type.set_signature(*this); |   5553     type.set_signature(*this); | 
|   5810     SetSignatureType(type); |   5554     SetSignatureType(type); | 
|   5811   } |   5555   } | 
|   5812   return type.raw(); |   5556   return type.raw(); | 
|   5813 } |   5557 } | 
|   5814  |   5558  | 
|   5815  |  | 
|   5816 void Function::SetSignatureType(const Type& value) const { |   5559 void Function::SetSignatureType(const Type& value) const { | 
|   5817   const Object& obj = Object::Handle(raw_ptr()->data_); |   5560   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5818   ASSERT(!obj.IsNull()); |   5561   ASSERT(!obj.IsNull()); | 
|   5819   if (IsSignatureFunction()) { |   5562   if (IsSignatureFunction()) { | 
|   5820     SignatureData::Cast(obj).set_signature_type(value); |   5563     SignatureData::Cast(obj).set_signature_type(value); | 
|   5821     ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); |   5564     ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); | 
|   5822   } else { |   5565   } else { | 
|   5823     ASSERT(IsClosureFunction()); |   5566     ASSERT(IsClosureFunction()); | 
|   5824     ClosureData::Cast(obj).set_signature_type(value); |   5567     ClosureData::Cast(obj).set_signature_type(value); | 
|   5825   } |   5568   } | 
|   5826 } |   5569 } | 
|   5827  |   5570  | 
|   5828  |  | 
|   5829 bool Function::IsRedirectingFactory() const { |   5571 bool Function::IsRedirectingFactory() const { | 
|   5830   if (!IsFactory() || !is_redirecting()) { |   5572   if (!IsFactory() || !is_redirecting()) { | 
|   5831     return false; |   5573     return false; | 
|   5832   } |   5574   } | 
|   5833   ASSERT(!IsClosureFunction());  // A factory cannot also be a closure. |   5575   ASSERT(!IsClosureFunction());  // A factory cannot also be a closure. | 
|   5834   return true; |   5576   return true; | 
|   5835 } |   5577 } | 
|   5836  |   5578  | 
|   5837  |  | 
|   5838 RawType* Function::RedirectionType() const { |   5579 RawType* Function::RedirectionType() const { | 
|   5839   ASSERT(IsRedirectingFactory()); |   5580   ASSERT(IsRedirectingFactory()); | 
|   5840   ASSERT(!is_native()); |   5581   ASSERT(!is_native()); | 
|   5841   const Object& obj = Object::Handle(raw_ptr()->data_); |   5582   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5842   ASSERT(!obj.IsNull()); |   5583   ASSERT(!obj.IsNull()); | 
|   5843   return RedirectionData::Cast(obj).type(); |   5584   return RedirectionData::Cast(obj).type(); | 
|   5844 } |   5585 } | 
|   5845  |   5586  | 
|   5846  |  | 
|   5847 const char* Function::KindToCString(RawFunction::Kind kind) { |   5587 const char* Function::KindToCString(RawFunction::Kind kind) { | 
|   5848   switch (kind) { |   5588   switch (kind) { | 
|   5849     case RawFunction::kRegularFunction: |   5589     case RawFunction::kRegularFunction: | 
|   5850       return "RegularFunction"; |   5590       return "RegularFunction"; | 
|   5851       break; |   5591       break; | 
|   5852     case RawFunction::kClosureFunction: |   5592     case RawFunction::kClosureFunction: | 
|   5853       return "ClosureFunction"; |   5593       return "ClosureFunction"; | 
|   5854       break; |   5594       break; | 
|   5855     case RawFunction::kSignatureFunction: |   5595     case RawFunction::kSignatureFunction: | 
|   5856       return "SignatureFunction"; |   5596       return "SignatureFunction"; | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   5884       break; |   5624       break; | 
|   5885     case RawFunction::kIrregexpFunction: |   5625     case RawFunction::kIrregexpFunction: | 
|   5886       return "IrregexpFunction"; |   5626       return "IrregexpFunction"; | 
|   5887       break; |   5627       break; | 
|   5888     default: |   5628     default: | 
|   5889       UNREACHABLE(); |   5629       UNREACHABLE(); | 
|   5890       return NULL; |   5630       return NULL; | 
|   5891   } |   5631   } | 
|   5892 } |   5632 } | 
|   5893  |   5633  | 
|   5894  |  | 
|   5895 void Function::SetRedirectionType(const Type& type) const { |   5634 void Function::SetRedirectionType(const Type& type) const { | 
|   5896   ASSERT(IsFactory()); |   5635   ASSERT(IsFactory()); | 
|   5897   Object& obj = Object::Handle(raw_ptr()->data_); |   5636   Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5898   if (obj.IsNull()) { |   5637   if (obj.IsNull()) { | 
|   5899     obj = RedirectionData::New(); |   5638     obj = RedirectionData::New(); | 
|   5900     set_data(obj); |   5639     set_data(obj); | 
|   5901   } |   5640   } | 
|   5902   RedirectionData::Cast(obj).set_type(type); |   5641   RedirectionData::Cast(obj).set_type(type); | 
|   5903 } |   5642 } | 
|   5904  |   5643  | 
|   5905  |  | 
|   5906 RawString* Function::RedirectionIdentifier() const { |   5644 RawString* Function::RedirectionIdentifier() const { | 
|   5907   ASSERT(IsRedirectingFactory()); |   5645   ASSERT(IsRedirectingFactory()); | 
|   5908   const Object& obj = Object::Handle(raw_ptr()->data_); |   5646   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5909   ASSERT(!obj.IsNull()); |   5647   ASSERT(!obj.IsNull()); | 
|   5910   return RedirectionData::Cast(obj).identifier(); |   5648   return RedirectionData::Cast(obj).identifier(); | 
|   5911 } |   5649 } | 
|   5912  |   5650  | 
|   5913  |  | 
|   5914 void Function::SetRedirectionIdentifier(const String& identifier) const { |   5651 void Function::SetRedirectionIdentifier(const String& identifier) const { | 
|   5915   ASSERT(IsFactory()); |   5652   ASSERT(IsFactory()); | 
|   5916   Object& obj = Object::Handle(raw_ptr()->data_); |   5653   Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5917   if (obj.IsNull()) { |   5654   if (obj.IsNull()) { | 
|   5918     obj = RedirectionData::New(); |   5655     obj = RedirectionData::New(); | 
|   5919     set_data(obj); |   5656     set_data(obj); | 
|   5920   } |   5657   } | 
|   5921   RedirectionData::Cast(obj).set_identifier(identifier); |   5658   RedirectionData::Cast(obj).set_identifier(identifier); | 
|   5922 } |   5659 } | 
|   5923  |   5660  | 
|   5924  |  | 
|   5925 RawFunction* Function::RedirectionTarget() const { |   5661 RawFunction* Function::RedirectionTarget() const { | 
|   5926   ASSERT(IsRedirectingFactory()); |   5662   ASSERT(IsRedirectingFactory()); | 
|   5927   const Object& obj = Object::Handle(raw_ptr()->data_); |   5663   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5928   ASSERT(!obj.IsNull()); |   5664   ASSERT(!obj.IsNull()); | 
|   5929   return RedirectionData::Cast(obj).target(); |   5665   return RedirectionData::Cast(obj).target(); | 
|   5930 } |   5666 } | 
|   5931  |   5667  | 
|   5932  |  | 
|   5933 void Function::SetRedirectionTarget(const Function& target) const { |   5668 void Function::SetRedirectionTarget(const Function& target) const { | 
|   5934   ASSERT(IsFactory()); |   5669   ASSERT(IsFactory()); | 
|   5935   Object& obj = Object::Handle(raw_ptr()->data_); |   5670   Object& obj = Object::Handle(raw_ptr()->data_); | 
|   5936   if (obj.IsNull()) { |   5671   if (obj.IsNull()) { | 
|   5937     obj = RedirectionData::New(); |   5672     obj = RedirectionData::New(); | 
|   5938     set_data(obj); |   5673     set_data(obj); | 
|   5939   } |   5674   } | 
|   5940   RedirectionData::Cast(obj).set_target(target); |   5675   RedirectionData::Cast(obj).set_target(target); | 
|   5941 } |   5676 } | 
|   5942  |   5677  | 
|   5943  |  | 
|   5944 // This field is heavily overloaded: |   5678 // This field is heavily overloaded: | 
|   5945 //   eval function:           Script expression source |   5679 //   eval function:           Script expression source | 
|   5946 //   signature function:      SignatureData |   5680 //   signature function:      SignatureData | 
|   5947 //   method extractor:        Function extracted closure function |   5681 //   method extractor:        Function extracted closure function | 
|   5948 //   noSuchMethod dispatcher: Array arguments descriptor |   5682 //   noSuchMethod dispatcher: Array arguments descriptor | 
|   5949 //   invoke-field dispatcher: Array arguments descriptor |   5683 //   invoke-field dispatcher: Array arguments descriptor | 
|   5950 //   redirecting constructor: RedirectionData |   5684 //   redirecting constructor: RedirectionData | 
|   5951 //   closure function:        ClosureData |   5685 //   closure function:        ClosureData | 
|   5952 //   irregexp function:       Array[0] = RegExp |   5686 //   irregexp function:       Array[0] = RegExp | 
|   5953 //                            Array[1] = Smi string specialization cid |   5687 //                            Array[1] = Smi string specialization cid | 
|   5954 //   native function:         Array[0] = String native name |   5688 //   native function:         Array[0] = String native name | 
|   5955 //                            Array[1] = Function implicit closure function |   5689 //                            Array[1] = Function implicit closure function | 
|   5956 //   regular function:        Function for implicit closure function |   5690 //   regular function:        Function for implicit closure function | 
|   5957 void Function::set_data(const Object& value) const { |   5691 void Function::set_data(const Object& value) const { | 
|   5958   StorePointer(&raw_ptr()->data_, value.raw()); |   5692   StorePointer(&raw_ptr()->data_, value.raw()); | 
|   5959 } |   5693 } | 
|   5960  |   5694  | 
|   5961  |  | 
|   5962 bool Function::IsInFactoryScope() const { |   5695 bool Function::IsInFactoryScope() const { | 
|   5963   if (!IsLocalFunction()) { |   5696   if (!IsLocalFunction()) { | 
|   5964     return IsFactory(); |   5697     return IsFactory(); | 
|   5965   } |   5698   } | 
|   5966   Function& outer_function = Function::Handle(parent_function()); |   5699   Function& outer_function = Function::Handle(parent_function()); | 
|   5967   while (outer_function.IsLocalFunction()) { |   5700   while (outer_function.IsLocalFunction()) { | 
|   5968     outer_function = outer_function.parent_function(); |   5701     outer_function = outer_function.parent_function(); | 
|   5969   } |   5702   } | 
|   5970   return outer_function.IsFactory(); |   5703   return outer_function.IsFactory(); | 
|   5971 } |   5704 } | 
|   5972  |   5705  | 
|   5973  |  | 
|   5974 void Function::set_name(const String& value) const { |   5706 void Function::set_name(const String& value) const { | 
|   5975   ASSERT(value.IsSymbol()); |   5707   ASSERT(value.IsSymbol()); | 
|   5976   StorePointer(&raw_ptr()->name_, value.raw()); |   5708   StorePointer(&raw_ptr()->name_, value.raw()); | 
|   5977 } |   5709 } | 
|   5978  |   5710  | 
|   5979  |  | 
|   5980 void Function::set_owner(const Object& value) const { |   5711 void Function::set_owner(const Object& value) const { | 
|   5981   ASSERT(!value.IsNull() || IsSignatureFunction()); |   5712   ASSERT(!value.IsNull() || IsSignatureFunction()); | 
|   5982   StorePointer(&raw_ptr()->owner_, value.raw()); |   5713   StorePointer(&raw_ptr()->owner_, value.raw()); | 
|   5983 } |   5714 } | 
|   5984  |   5715  | 
|   5985  |  | 
|   5986 RawRegExp* Function::regexp() const { |   5716 RawRegExp* Function::regexp() const { | 
|   5987   ASSERT(kind() == RawFunction::kIrregexpFunction); |   5717   ASSERT(kind() == RawFunction::kIrregexpFunction); | 
|   5988   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |   5718   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 
|   5989   return RegExp::RawCast(pair.At(0)); |   5719   return RegExp::RawCast(pair.At(0)); | 
|   5990 } |   5720 } | 
|   5991  |   5721  | 
|   5992  |  | 
|   5993 class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {}; |   5722 class StickySpecialization : public BitField<intptr_t, bool, 0, 1> {}; | 
|   5994 class StringSpecializationCid |   5723 class StringSpecializationCid | 
|   5995     : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {}; |   5724     : public BitField<intptr_t, intptr_t, 1, RawObject::kClassIdTagSize> {}; | 
|   5996  |   5725  | 
|   5997  |  | 
|   5998 intptr_t Function::string_specialization_cid() const { |   5726 intptr_t Function::string_specialization_cid() const { | 
|   5999   ASSERT(kind() == RawFunction::kIrregexpFunction); |   5727   ASSERT(kind() == RawFunction::kIrregexpFunction); | 
|   6000   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |   5728   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 
|   6001   return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1)))); |   5729   return StringSpecializationCid::decode(Smi::Value(Smi::RawCast(pair.At(1)))); | 
|   6002 } |   5730 } | 
|   6003  |   5731  | 
|   6004  |  | 
|   6005 bool Function::is_sticky_specialization() const { |   5732 bool Function::is_sticky_specialization() const { | 
|   6006   ASSERT(kind() == RawFunction::kIrregexpFunction); |   5733   ASSERT(kind() == RawFunction::kIrregexpFunction); | 
|   6007   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |   5734   const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 
|   6008   return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1)))); |   5735   return StickySpecialization::decode(Smi::Value(Smi::RawCast(pair.At(1)))); | 
|   6009 } |   5736 } | 
|   6010  |   5737  | 
|   6011  |  | 
|   6012 void Function::SetRegExpData(const RegExp& regexp, |   5738 void Function::SetRegExpData(const RegExp& regexp, | 
|   6013                              intptr_t string_specialization_cid, |   5739                              intptr_t string_specialization_cid, | 
|   6014                              bool sticky) const { |   5740                              bool sticky) const { | 
|   6015   ASSERT(kind() == RawFunction::kIrregexpFunction); |   5741   ASSERT(kind() == RawFunction::kIrregexpFunction); | 
|   6016   ASSERT(RawObject::IsStringClassId(string_specialization_cid)); |   5742   ASSERT(RawObject::IsStringClassId(string_specialization_cid)); | 
|   6017   ASSERT(raw_ptr()->data_ == Object::null()); |   5743   ASSERT(raw_ptr()->data_ == Object::null()); | 
|   6018   const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); |   5744   const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); | 
|   6019   pair.SetAt(0, regexp); |   5745   pair.SetAt(0, regexp); | 
|   6020   pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) | |   5746   pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) | | 
|   6021                                      StringSpecializationCid::encode( |   5747                                      StringSpecializationCid::encode( | 
|   6022                                          string_specialization_cid)))); |   5748                                          string_specialization_cid)))); | 
|   6023   set_data(pair); |   5749   set_data(pair); | 
|   6024 } |   5750 } | 
|   6025  |   5751  | 
|   6026  |  | 
|   6027 RawString* Function::native_name() const { |   5752 RawString* Function::native_name() const { | 
|   6028   ASSERT(is_native()); |   5753   ASSERT(is_native()); | 
|   6029   const Object& obj = Object::Handle(raw_ptr()->data_); |   5754   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   6030   ASSERT(obj.IsArray()); |   5755   ASSERT(obj.IsArray()); | 
|   6031   return String::RawCast(Array::Cast(obj).At(0)); |   5756   return String::RawCast(Array::Cast(obj).At(0)); | 
|   6032 } |   5757 } | 
|   6033  |   5758  | 
|   6034  |  | 
|   6035 void Function::set_native_name(const String& value) const { |   5759 void Function::set_native_name(const String& value) const { | 
|   6036   ASSERT(is_native()); |   5760   ASSERT(is_native()); | 
|   6037   ASSERT(raw_ptr()->data_ == Object::null()); |   5761   ASSERT(raw_ptr()->data_ == Object::null()); | 
|   6038   const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); |   5762   const Array& pair = Array::Handle(Array::New(2, Heap::kOld)); | 
|   6039   pair.SetAt(0, value); |   5763   pair.SetAt(0, value); | 
|   6040   // pair[1] will be the implicit closure function if needed. |   5764   // pair[1] will be the implicit closure function if needed. | 
|   6041   set_data(pair); |   5765   set_data(pair); | 
|   6042 } |   5766 } | 
|   6043  |   5767  | 
|   6044  |  | 
|   6045 void Function::set_result_type(const AbstractType& value) const { |   5768 void Function::set_result_type(const AbstractType& value) const { | 
|   6046   ASSERT(!value.IsNull()); |   5769   ASSERT(!value.IsNull()); | 
|   6047   StorePointer(&raw_ptr()->result_type_, value.raw()); |   5770   StorePointer(&raw_ptr()->result_type_, value.raw()); | 
|   6048   if (value.IsFunctionType()) { |   5771   if (value.IsFunctionType()) { | 
|   6049     // The function result type may refer to this function's type parameters. |   5772     // The function result type may refer to this function's type parameters. | 
|   6050     // Change its parent function. |   5773     // Change its parent function. | 
|   6051     const Function& result_signature_function = |   5774     const Function& result_signature_function = | 
|   6052         Function::Handle(Type::Cast(value).signature()); |   5775         Function::Handle(Type::Cast(value).signature()); | 
|   6053     result_signature_function.set_parent_function(*this); |   5776     result_signature_function.set_parent_function(*this); | 
|   6054   } |   5777   } | 
|   6055 } |   5778 } | 
|   6056  |   5779  | 
|   6057  |  | 
|   6058 RawAbstractType* Function::ParameterTypeAt(intptr_t index) const { |   5780 RawAbstractType* Function::ParameterTypeAt(intptr_t index) const { | 
|   6059   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); |   5781   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); | 
|   6060   return AbstractType::RawCast(parameter_types.At(index)); |   5782   return AbstractType::RawCast(parameter_types.At(index)); | 
|   6061 } |   5783 } | 
|   6062  |   5784  | 
|   6063  |  | 
|   6064 void Function::SetParameterTypeAt(intptr_t index, |   5785 void Function::SetParameterTypeAt(intptr_t index, | 
|   6065                                   const AbstractType& value) const { |   5786                                   const AbstractType& value) const { | 
|   6066   ASSERT(!value.IsNull()); |   5787   ASSERT(!value.IsNull()); | 
|   6067   // Method extractor parameters are shared and are in the VM heap. |   5788   // Method extractor parameters are shared and are in the VM heap. | 
|   6068   ASSERT(kind() != RawFunction::kMethodExtractor); |   5789   ASSERT(kind() != RawFunction::kMethodExtractor); | 
|   6069   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); |   5790   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_); | 
|   6070   parameter_types.SetAt(index, value); |   5791   parameter_types.SetAt(index, value); | 
|   6071 } |   5792 } | 
|   6072  |   5793  | 
|   6073  |  | 
|   6074 void Function::set_parameter_types(const Array& value) const { |   5794 void Function::set_parameter_types(const Array& value) const { | 
|   6075   StorePointer(&raw_ptr()->parameter_types_, value.raw()); |   5795   StorePointer(&raw_ptr()->parameter_types_, value.raw()); | 
|   6076 } |   5796 } | 
|   6077  |   5797  | 
|   6078  |  | 
|   6079 RawString* Function::ParameterNameAt(intptr_t index) const { |   5798 RawString* Function::ParameterNameAt(intptr_t index) const { | 
|   6080   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); |   5799   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); | 
|   6081   return String::RawCast(parameter_names.At(index)); |   5800   return String::RawCast(parameter_names.At(index)); | 
|   6082 } |   5801 } | 
|   6083  |   5802  | 
|   6084  |  | 
|   6085 void Function::SetParameterNameAt(intptr_t index, const String& value) const { |   5803 void Function::SetParameterNameAt(intptr_t index, const String& value) const { | 
|   6086   ASSERT(!value.IsNull() && value.IsSymbol()); |   5804   ASSERT(!value.IsNull() && value.IsSymbol()); | 
|   6087   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); |   5805   const Array& parameter_names = Array::Handle(raw_ptr()->parameter_names_); | 
|   6088   parameter_names.SetAt(index, value); |   5806   parameter_names.SetAt(index, value); | 
|   6089 } |   5807 } | 
|   6090  |   5808  | 
|   6091  |  | 
|   6092 void Function::set_parameter_names(const Array& value) const { |   5809 void Function::set_parameter_names(const Array& value) const { | 
|   6093   StorePointer(&raw_ptr()->parameter_names_, value.raw()); |   5810   StorePointer(&raw_ptr()->parameter_names_, value.raw()); | 
|   6094 } |   5811 } | 
|   6095  |   5812  | 
|   6096  |  | 
|   6097 void Function::set_type_parameters(const TypeArguments& value) const { |   5813 void Function::set_type_parameters(const TypeArguments& value) const { | 
|   6098   StorePointer(&raw_ptr()->type_parameters_, value.raw()); |   5814   StorePointer(&raw_ptr()->type_parameters_, value.raw()); | 
|   6099 } |   5815 } | 
|   6100  |   5816  | 
|   6101  |  | 
|   6102 intptr_t Function::NumTypeParameters(Thread* thread) const { |   5817 intptr_t Function::NumTypeParameters(Thread* thread) const { | 
|   6103   if (type_parameters() == TypeArguments::null()) { |   5818   if (type_parameters() == TypeArguments::null()) { | 
|   6104     return 0; |   5819     return 0; | 
|   6105   } |   5820   } | 
|   6106   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |   5821   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 
|   6107   TypeArguments& type_params = thread->TypeArgumentsHandle(); |   5822   TypeArguments& type_params = thread->TypeArgumentsHandle(); | 
|   6108   type_params = type_parameters(); |   5823   type_params = type_parameters(); | 
|   6109   // We require null to represent a non-generic function. |   5824   // We require null to represent a non-generic function. | 
|   6110   ASSERT(type_params.Length() != 0); |   5825   ASSERT(type_params.Length() != 0); | 
|   6111   return type_params.Length(); |   5826   return type_params.Length(); | 
|   6112 } |   5827 } | 
|   6113  |   5828  | 
|   6114  |  | 
|   6115 intptr_t Function::NumParentTypeParameters() const { |   5829 intptr_t Function::NumParentTypeParameters() const { | 
|   6116   if (IsImplicitClosureFunction()) { |   5830   if (IsImplicitClosureFunction()) { | 
|   6117     return 0; |   5831     return 0; | 
|   6118   } |   5832   } | 
|   6119   Thread* thread = Thread::Current(); |   5833   Thread* thread = Thread::Current(); | 
|   6120   Function& parent = Function::Handle(parent_function()); |   5834   Function& parent = Function::Handle(parent_function()); | 
|   6121   intptr_t num_parent_type_params = 0; |   5835   intptr_t num_parent_type_params = 0; | 
|   6122   while (!parent.IsNull()) { |   5836   while (!parent.IsNull()) { | 
|   6123     num_parent_type_params += parent.NumTypeParameters(thread); |   5837     num_parent_type_params += parent.NumTypeParameters(thread); | 
|   6124     parent ^= parent.parent_function(); |   5838     parent ^= parent.parent_function(); | 
|   6125   } |   5839   } | 
|   6126   return num_parent_type_params; |   5840   return num_parent_type_params; | 
|   6127 } |   5841 } | 
|   6128  |   5842  | 
|   6129  |  | 
|   6130 RawTypeParameter* Function::LookupTypeParameter( |   5843 RawTypeParameter* Function::LookupTypeParameter( | 
|   6131     const String& type_name, |   5844     const String& type_name, | 
|   6132     intptr_t* function_level) const { |   5845     intptr_t* function_level) const { | 
|   6133   ASSERT(!type_name.IsNull()); |   5846   ASSERT(!type_name.IsNull()); | 
|   6134   Thread* thread = Thread::Current(); |   5847   Thread* thread = Thread::Current(); | 
|   6135   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); |   5848   REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread); | 
|   6136   REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); |   5849   REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread); | 
|   6137   REUSABLE_STRING_HANDLESCOPE(thread); |   5850   REUSABLE_STRING_HANDLESCOPE(thread); | 
|   6138   REUSABLE_FUNCTION_HANDLESCOPE(thread); |   5851   REUSABLE_FUNCTION_HANDLESCOPE(thread); | 
|   6139   TypeArguments& type_params = thread->TypeArgumentsHandle(); |   5852   TypeArguments& type_params = thread->TypeArgumentsHandle(); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|   6160       break; |   5873       break; | 
|   6161     } |   5874     } | 
|   6162     function ^= function.parent_function(); |   5875     function ^= function.parent_function(); | 
|   6163     if (function_level != NULL) { |   5876     if (function_level != NULL) { | 
|   6164       (*function_level)--; |   5877       (*function_level)--; | 
|   6165     } |   5878     } | 
|   6166   } |   5879   } | 
|   6167   return TypeParameter::null(); |   5880   return TypeParameter::null(); | 
|   6168 } |   5881 } | 
|   6169  |   5882  | 
|   6170  |  | 
|   6171 void Function::set_kind(RawFunction::Kind value) const { |   5883 void Function::set_kind(RawFunction::Kind value) const { | 
|   6172   set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); |   5884   set_kind_tag(KindBits::update(value, raw_ptr()->kind_tag_)); | 
|   6173 } |   5885 } | 
|   6174  |   5886  | 
|   6175  |  | 
|   6176 void Function::set_modifier(RawFunction::AsyncModifier value) const { |   5887 void Function::set_modifier(RawFunction::AsyncModifier value) const { | 
|   6177   set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); |   5888   set_kind_tag(ModifierBits::update(value, raw_ptr()->kind_tag_)); | 
|   6178 } |   5889 } | 
|   6179  |   5890  | 
|   6180  |  | 
|   6181 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { |   5891 void Function::set_recognized_kind(MethodRecognizer::Kind value) const { | 
|   6182   // Prevent multiple settings of kind. |   5892   // Prevent multiple settings of kind. | 
|   6183   ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); |   5893   ASSERT((value == MethodRecognizer::kUnknown) || !IsRecognized()); | 
|   6184   set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); |   5894   set_kind_tag(RecognizedBits::update(value, raw_ptr()->kind_tag_)); | 
|   6185 } |   5895 } | 
|   6186  |   5896  | 
|   6187  |  | 
|   6188 void Function::set_token_pos(TokenPosition token_pos) const { |   5897 void Function::set_token_pos(TokenPosition token_pos) const { | 
|   6189 #if defined(DART_PRECOMPILED_RUNTIME) |   5898 #if defined(DART_PRECOMPILED_RUNTIME) | 
|   6190   UNREACHABLE(); |   5899   UNREACHABLE(); | 
|   6191 #else |   5900 #else | 
|   6192   ASSERT(!token_pos.IsClassifying() || IsMethodExtractor()); |   5901   ASSERT(!token_pos.IsClassifying() || IsMethodExtractor()); | 
|   6193   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |   5902   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|   6194 #endif |   5903 #endif | 
|   6195 } |   5904 } | 
|   6196  |   5905  | 
|   6197  |  | 
|   6198 void Function::set_kind_tag(uint32_t value) const { |   5906 void Function::set_kind_tag(uint32_t value) const { | 
|   6199   StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); |   5907   StoreNonPointer(&raw_ptr()->kind_tag_, static_cast<uint32_t>(value)); | 
|   6200 } |   5908 } | 
|   6201  |   5909  | 
|   6202  |  | 
|   6203 void Function::set_num_fixed_parameters(intptr_t value) const { |   5910 void Function::set_num_fixed_parameters(intptr_t value) const { | 
|   6204   ASSERT(value >= 0); |   5911   ASSERT(value >= 0); | 
|   6205   ASSERT(Utils::IsInt(16, value)); |   5912   ASSERT(Utils::IsInt(16, value)); | 
|   6206   StoreNonPointer(&raw_ptr()->num_fixed_parameters_, |   5913   StoreNonPointer(&raw_ptr()->num_fixed_parameters_, | 
|   6207                   static_cast<int16_t>(value)); |   5914                   static_cast<int16_t>(value)); | 
|   6208 } |   5915 } | 
|   6209  |   5916  | 
|   6210  |  | 
|   6211 void Function::set_num_optional_parameters(intptr_t value) const { |   5917 void Function::set_num_optional_parameters(intptr_t value) const { | 
|   6212   // A positive value indicates positional params, a negative one named params. |   5918   // A positive value indicates positional params, a negative one named params. | 
|   6213   ASSERT(Utils::IsInt(16, value)); |   5919   ASSERT(Utils::IsInt(16, value)); | 
|   6214   StoreNonPointer(&raw_ptr()->num_optional_parameters_, |   5920   StoreNonPointer(&raw_ptr()->num_optional_parameters_, | 
|   6215                   static_cast<int16_t>(value)); |   5921                   static_cast<int16_t>(value)); | 
|   6216 } |   5922 } | 
|   6217  |   5923  | 
|   6218  |  | 
|   6219 void Function::SetNumOptionalParameters(intptr_t num_optional_parameters, |   5924 void Function::SetNumOptionalParameters(intptr_t num_optional_parameters, | 
|   6220                                         bool are_optional_positional) const { |   5925                                         bool are_optional_positional) const { | 
|   6221   ASSERT(num_optional_parameters >= 0); |   5926   ASSERT(num_optional_parameters >= 0); | 
|   6222   set_num_optional_parameters(are_optional_positional |   5927   set_num_optional_parameters(are_optional_positional | 
|   6223                                   ? num_optional_parameters |   5928                                   ? num_optional_parameters | 
|   6224                                   : -num_optional_parameters); |   5929                                   : -num_optional_parameters); | 
|   6225 } |   5930 } | 
|   6226  |   5931  | 
|   6227  |  | 
|   6228 bool Function::IsOptimizable() const { |   5932 bool Function::IsOptimizable() const { | 
|   6229   if (FLAG_precompiled_mode) { |   5933   if (FLAG_precompiled_mode) { | 
|   6230     return true; |   5934     return true; | 
|   6231   } |   5935   } | 
|   6232   if (is_native()) { |   5936   if (is_native()) { | 
|   6233     // Native methods don't need to be optimized. |   5937     // Native methods don't need to be optimized. | 
|   6234     return false; |   5938     return false; | 
|   6235   } |   5939   } | 
|   6236   const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos(); |   5940   const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos(); | 
|   6237   if (is_optimizable() && (script() != Script::null()) && |   5941   if (is_optimizable() && (script() != Script::null()) && | 
|   6238       (function_length < FLAG_huge_method_cutoff_in_tokens)) { |   5942       (function_length < FLAG_huge_method_cutoff_in_tokens)) { | 
|   6239     // Additional check needed for implicit getters. |   5943     // Additional check needed for implicit getters. | 
|   6240     return (unoptimized_code() == Object::null()) || |   5944     return (unoptimized_code() == Object::null()) || | 
|   6241            (Code::Handle(unoptimized_code()).Size() < |   5945            (Code::Handle(unoptimized_code()).Size() < | 
|   6242             FLAG_huge_method_cutoff_in_code_size); |   5946             FLAG_huge_method_cutoff_in_code_size); | 
|   6243   } |   5947   } | 
|   6244   return false; |   5948   return false; | 
|   6245 } |   5949 } | 
|   6246  |   5950  | 
|   6247  |  | 
|   6248 void Function::SetIsOptimizable(bool value) const { |   5951 void Function::SetIsOptimizable(bool value) const { | 
|   6249   ASSERT(!is_native()); |   5952   ASSERT(!is_native()); | 
|   6250   set_is_optimizable(value); |   5953   set_is_optimizable(value); | 
|   6251   if (!value) { |   5954   if (!value) { | 
|   6252     set_is_inlinable(false); |   5955     set_is_inlinable(false); | 
|   6253     set_usage_counter(INT_MIN); |   5956     set_usage_counter(INT_MIN); | 
|   6254   } |   5957   } | 
|   6255 } |   5958 } | 
|   6256  |   5959  | 
|   6257  |  | 
|   6258 bool Function::CanBeInlined() const { |   5960 bool Function::CanBeInlined() const { | 
|   6259   Thread* thread = Thread::Current(); |   5961   Thread* thread = Thread::Current(); | 
|   6260   return is_inlinable() && !is_external() && !is_generated_body() && |   5962   return is_inlinable() && !is_external() && !is_generated_body() && | 
|   6261          (!FLAG_support_debugger || |   5963          (!FLAG_support_debugger || | 
|   6262           !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); |   5964           !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone())); | 
|   6263 } |   5965 } | 
|   6264  |   5966  | 
|   6265  |  | 
|   6266 intptr_t Function::NumParameters() const { |   5967 intptr_t Function::NumParameters() const { | 
|   6267   return num_fixed_parameters() + NumOptionalParameters(); |   5968   return num_fixed_parameters() + NumOptionalParameters(); | 
|   6268 } |   5969 } | 
|   6269  |   5970  | 
|   6270  |  | 
|   6271 intptr_t Function::NumImplicitParameters() const { |   5971 intptr_t Function::NumImplicitParameters() const { | 
|   6272   if (kind() == RawFunction::kConstructor) { |   5972   if (kind() == RawFunction::kConstructor) { | 
|   6273     // Type arguments for factory; instance for generative constructor. |   5973     // Type arguments for factory; instance for generative constructor. | 
|   6274     return 1; |   5974     return 1; | 
|   6275   } |   5975   } | 
|   6276   if ((kind() == RawFunction::kClosureFunction) || |   5976   if ((kind() == RawFunction::kClosureFunction) || | 
|   6277       (kind() == RawFunction::kSignatureFunction)) { |   5977       (kind() == RawFunction::kSignatureFunction)) { | 
|   6278     return 1;  // Closure object. |   5978     return 1;  // Closure object. | 
|   6279   } |   5979   } | 
|   6280   if (!is_static()) { |   5980   if (!is_static()) { | 
|   6281     // Closure functions defined inside instance (i.e. non-static) functions are |   5981     // Closure functions defined inside instance (i.e. non-static) functions are | 
|   6282     // marked as non-static, but they do not have a receiver. |   5982     // marked as non-static, but they do not have a receiver. | 
|   6283     // Closures are handled above. |   5983     // Closures are handled above. | 
|   6284     ASSERT((kind() != RawFunction::kClosureFunction) && |   5984     ASSERT((kind() != RawFunction::kClosureFunction) && | 
|   6285            (kind() != RawFunction::kSignatureFunction)); |   5985            (kind() != RawFunction::kSignatureFunction)); | 
|   6286     return 1;  // Receiver. |   5986     return 1;  // Receiver. | 
|   6287   } |   5987   } | 
|   6288   return 0;  // No implicit parameters. |   5988   return 0;  // No implicit parameters. | 
|   6289 } |   5989 } | 
|   6290  |   5990  | 
|   6291  |  | 
|   6292 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments, |   5991 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments, | 
|   6293                                       intptr_t num_arguments, |   5992                                       intptr_t num_arguments, | 
|   6294                                       intptr_t num_named_arguments, |   5993                                       intptr_t num_named_arguments, | 
|   6295                                       String* error_message) const { |   5994                                       String* error_message) const { | 
|   6296   if ((num_type_arguments != 0) && |   5995   if ((num_type_arguments != 0) && | 
|   6297       (num_type_arguments != NumTypeParameters())) { |   5996       (num_type_arguments != NumTypeParameters())) { | 
|   6298     if (error_message != NULL) { |   5997     if (error_message != NULL) { | 
|   6299       const intptr_t kMessageBufferSize = 64; |   5998       const intptr_t kMessageBufferSize = 64; | 
|   6300       char message_buffer[kMessageBufferSize]; |   5999       char message_buffer[kMessageBufferSize]; | 
|   6301       OS::SNPrint(message_buffer, kMessageBufferSize, |   6000       OS::SNPrint(message_buffer, kMessageBufferSize, | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   6355                   num_fixed_parameters() - num_hidden_params); |   6054                   num_fixed_parameters() - num_hidden_params); | 
|   6356       // Allocate in old space because it can be invoked in background |   6055       // Allocate in old space because it can be invoked in background | 
|   6357       // optimizing compilation. |   6056       // optimizing compilation. | 
|   6358       *error_message = String::New(message_buffer, Heap::kOld); |   6057       *error_message = String::New(message_buffer, Heap::kOld); | 
|   6359     } |   6058     } | 
|   6360     return false;  // Too few fixed and/or positional arguments. |   6059     return false;  // Too few fixed and/or positional arguments. | 
|   6361   } |   6060   } | 
|   6362   return true; |   6061   return true; | 
|   6363 } |   6062 } | 
|   6364  |   6063  | 
|   6365  |  | 
|   6366 bool Function::AreValidArguments(intptr_t num_type_arguments, |   6064 bool Function::AreValidArguments(intptr_t num_type_arguments, | 
|   6367                                  intptr_t num_arguments, |   6065                                  intptr_t num_arguments, | 
|   6368                                  const Array& argument_names, |   6066                                  const Array& argument_names, | 
|   6369                                  String* error_message) const { |   6067                                  String* error_message) const { | 
|   6370   const intptr_t num_named_arguments = |   6068   const intptr_t num_named_arguments = | 
|   6371       argument_names.IsNull() ? 0 : argument_names.Length(); |   6069       argument_names.IsNull() ? 0 : argument_names.Length(); | 
|   6372   if (!AreValidArgumentCounts(num_type_arguments, num_arguments, |   6070   if (!AreValidArgumentCounts(num_type_arguments, num_arguments, | 
|   6373                               num_named_arguments, error_message)) { |   6071                               num_named_arguments, error_message)) { | 
|   6374     return false; |   6072     return false; | 
|   6375   } |   6073   } | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|   6401         // Allocate in old space because it can be invoked in background |   6099         // Allocate in old space because it can be invoked in background | 
|   6402         // optimizing compilation. |   6100         // optimizing compilation. | 
|   6403         *error_message = String::New(message_buffer, Heap::kOld); |   6101         *error_message = String::New(message_buffer, Heap::kOld); | 
|   6404       } |   6102       } | 
|   6405       return false; |   6103       return false; | 
|   6406     } |   6104     } | 
|   6407   } |   6105   } | 
|   6408   return true; |   6106   return true; | 
|   6409 } |   6107 } | 
|   6410  |   6108  | 
|   6411  |  | 
|   6412 bool Function::AreValidArguments(const ArgumentsDescriptor& args_desc, |   6109 bool Function::AreValidArguments(const ArgumentsDescriptor& args_desc, | 
|   6413                                  String* error_message) const { |   6110                                  String* error_message) const { | 
|   6414   const intptr_t num_type_arguments = args_desc.TypeArgsLen(); |   6111   const intptr_t num_type_arguments = args_desc.TypeArgsLen(); | 
|   6415   const intptr_t num_arguments = args_desc.Count(); |   6112   const intptr_t num_arguments = args_desc.Count(); | 
|   6416   const intptr_t num_named_arguments = args_desc.NamedCount(); |   6113   const intptr_t num_named_arguments = args_desc.NamedCount(); | 
|   6417  |   6114  | 
|   6418   if (!AreValidArgumentCounts(num_type_arguments, num_arguments, |   6115   if (!AreValidArgumentCounts(num_type_arguments, num_arguments, | 
|   6419                               num_named_arguments, error_message)) { |   6116                               num_named_arguments, error_message)) { | 
|   6420     return false; |   6117     return false; | 
|   6421   } |   6118   } | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|   6447         // Allocate in old space because it can be invoked in background |   6144         // Allocate in old space because it can be invoked in background | 
|   6448         // optimizing compilation. |   6145         // optimizing compilation. | 
|   6449         *error_message = String::New(message_buffer, Heap::kOld); |   6146         *error_message = String::New(message_buffer, Heap::kOld); | 
|   6450       } |   6147       } | 
|   6451       return false; |   6148       return false; | 
|   6452     } |   6149     } | 
|   6453   } |   6150   } | 
|   6454   return true; |   6151   return true; | 
|   6455 } |   6152 } | 
|   6456  |   6153  | 
|   6457  |  | 
|   6458 // Helper allocating a C string buffer in the zone, printing the fully qualified |   6154 // Helper allocating a C string buffer in the zone, printing the fully qualified | 
|   6459 // name of a function in it, and replacing ':' by '_' to make sure the |   6155 // name of a function in it, and replacing ':' by '_' to make sure the | 
|   6460 // constructed name is a valid C++ identifier for debugging purpose. |   6156 // constructed name is a valid C++ identifier for debugging purpose. | 
|   6461 // Set 'chars' to allocated buffer and return number of written characters. |   6157 // Set 'chars' to allocated buffer and return number of written characters. | 
|   6462  |   6158  | 
|   6463 enum QualifiedFunctionLibKind { |   6159 enum QualifiedFunctionLibKind { | 
|   6464   kQualifiedFunctionLibKindLibUrl, |   6160   kQualifiedFunctionLibKindLibUrl, | 
|   6465   kQualifiedFunctionLibKindLibName |   6161   kQualifiedFunctionLibKindLibName | 
|   6466 }; |   6162 }; | 
|   6467  |   6163  | 
|   6468  |  | 
|   6469 static intptr_t ConstructFunctionFullyQualifiedCString( |   6164 static intptr_t ConstructFunctionFullyQualifiedCString( | 
|   6470     const Function& function, |   6165     const Function& function, | 
|   6471     char** chars, |   6166     char** chars, | 
|   6472     intptr_t reserve_len, |   6167     intptr_t reserve_len, | 
|   6473     bool with_lib, |   6168     bool with_lib, | 
|   6474     QualifiedFunctionLibKind lib_kind) { |   6169     QualifiedFunctionLibKind lib_kind) { | 
|   6475   const char* name = String::Handle(function.name()).ToCString(); |   6170   const char* name = String::Handle(function.name()).ToCString(); | 
|   6476   const char* function_format = (reserve_len == 0) ? "%s" : "%s_"; |   6171   const char* function_format = (reserve_len == 0) ? "%s" : "%s_"; | 
|   6477   reserve_len += OS::SNPrint(NULL, 0, function_format, name); |   6172   reserve_len += OS::SNPrint(NULL, 0, function_format, name); | 
|   6478   const Function& parent = Function::Handle(function.parent_function()); |   6173   const Function& parent = Function::Handle(function.parent_function()); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   6518   written += OS::SNPrint(next, reserve_len + 1, function_format, name); |   6213   written += OS::SNPrint(next, reserve_len + 1, function_format, name); | 
|   6519   // Replace ":" with "_". |   6214   // Replace ":" with "_". | 
|   6520   while (true) { |   6215   while (true) { | 
|   6521     next = strchr(next, ':'); |   6216     next = strchr(next, ':'); | 
|   6522     if (next == NULL) break; |   6217     if (next == NULL) break; | 
|   6523     *next = '_'; |   6218     *next = '_'; | 
|   6524   } |   6219   } | 
|   6525   return written; |   6220   return written; | 
|   6526 } |   6221 } | 
|   6527  |   6222  | 
|   6528  |  | 
|   6529 const char* Function::ToFullyQualifiedCString() const { |   6223 const char* Function::ToFullyQualifiedCString() const { | 
|   6530   char* chars = NULL; |   6224   char* chars = NULL; | 
|   6531   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, |   6225   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, | 
|   6532                                          kQualifiedFunctionLibKindLibUrl); |   6226                                          kQualifiedFunctionLibKindLibUrl); | 
|   6533   return chars; |   6227   return chars; | 
|   6534 } |   6228 } | 
|   6535  |   6229  | 
|   6536  |  | 
|   6537 const char* Function::ToLibNamePrefixedQualifiedCString() const { |   6230 const char* Function::ToLibNamePrefixedQualifiedCString() const { | 
|   6538   char* chars = NULL; |   6231   char* chars = NULL; | 
|   6539   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, |   6232   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, true, | 
|   6540                                          kQualifiedFunctionLibKindLibName); |   6233                                          kQualifiedFunctionLibKindLibName); | 
|   6541   return chars; |   6234   return chars; | 
|   6542 } |   6235 } | 
|   6543  |   6236  | 
|   6544  |  | 
|   6545 const char* Function::ToQualifiedCString() const { |   6237 const char* Function::ToQualifiedCString() const { | 
|   6546   char* chars = NULL; |   6238   char* chars = NULL; | 
|   6547   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, false, |   6239   ConstructFunctionFullyQualifiedCString(*this, &chars, 0, false, | 
|   6548                                          kQualifiedFunctionLibKindLibUrl); |   6240                                          kQualifiedFunctionLibKindLibUrl); | 
|   6549   return chars; |   6241   return chars; | 
|   6550 } |   6242 } | 
|   6551  |   6243  | 
|   6552  |  | 
|   6553 bool Function::HasCompatibleParametersWith(const Function& other, |   6244 bool Function::HasCompatibleParametersWith(const Function& other, | 
|   6554                                            Error* bound_error) const { |   6245                                            Error* bound_error) const { | 
|   6555   ASSERT(Isolate::Current()->error_on_bad_override()); |   6246   ASSERT(Isolate::Current()->error_on_bad_override()); | 
|   6556   ASSERT((bound_error != NULL) && bound_error->IsNull()); |   6247   ASSERT((bound_error != NULL) && bound_error->IsNull()); | 
|   6557   // Check that this function's signature type is a subtype of the other |   6248   // Check that this function's signature type is a subtype of the other | 
|   6558   // function's signature type. |   6249   // function's signature type. | 
|   6559   // Map type parameters referred to by formal parameter types and result type |   6250   // Map type parameters referred to by formal parameter types and result type | 
|   6560   // in the signature to dynamic before the test. |   6251   // in the signature to dynamic before the test. | 
|   6561   // Note that type parameters declared by a generic signature are preserved. |   6252   // Note that type parameters declared by a generic signature are preserved. | 
|   6562   Function& this_fun = Function::Handle(raw()); |   6253   Function& this_fun = Function::Handle(raw()); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|   6589   } |   6280   } | 
|   6590   // We should also check that if the other function explicitly specifies a |   6281   // We should also check that if the other function explicitly specifies a | 
|   6591   // default value for a formal parameter, this function does not specify a |   6282   // default value for a formal parameter, this function does not specify a | 
|   6592   // different default value for the same parameter. However, this check is not |   6283   // different default value for the same parameter. However, this check is not | 
|   6593   // possible in the current implementation, because the default parameter |   6284   // possible in the current implementation, because the default parameter | 
|   6594   // values are not stored in the Function object, but discarded after a |   6285   // values are not stored in the Function object, but discarded after a | 
|   6595   // function is compiled. |   6286   // function is compiled. | 
|   6596   return true; |   6287   return true; | 
|   6597 } |   6288 } | 
|   6598  |   6289  | 
|   6599  |  | 
|   6600 RawFunction* Function::InstantiateSignatureFrom( |   6290 RawFunction* Function::InstantiateSignatureFrom( | 
|   6601     const TypeArguments& instantiator_type_arguments, |   6291     const TypeArguments& instantiator_type_arguments, | 
|   6602     const TypeArguments& function_type_arguments, |   6292     const TypeArguments& function_type_arguments, | 
|   6603     Heap::Space space) const { |   6293     Heap::Space space) const { | 
|   6604   Zone* zone = Thread::Current()->zone(); |   6294   Zone* zone = Thread::Current()->zone(); | 
|   6605   const Object& owner = Object::Handle(zone, RawOwner()); |   6295   const Object& owner = Object::Handle(zone, RawOwner()); | 
|   6606   const Function& parent = Function::Handle(zone, parent_function()); |   6296   const Function& parent = Function::Handle(zone, parent_function()); | 
|   6607   ASSERT(!HasInstantiatedSignature()); |   6297   ASSERT(!HasInstantiatedSignature()); | 
|   6608   Function& sig = Function::Handle( |   6298   Function& sig = Function::Handle( | 
|   6609       zone, Function::NewSignatureFunction(owner, parent, |   6299       zone, Function::NewSignatureFunction(owner, parent, | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|   6627       type = type.InstantiateFrom(instantiator_type_arguments, |   6317       type = type.InstantiateFrom(instantiator_type_arguments, | 
|   6628                                   function_type_arguments, NULL, NULL, NULL, |   6318                                   function_type_arguments, NULL, NULL, NULL, | 
|   6629                                   space); |   6319                                   space); | 
|   6630     } |   6320     } | 
|   6631     sig.SetParameterTypeAt(i, type); |   6321     sig.SetParameterTypeAt(i, type); | 
|   6632   } |   6322   } | 
|   6633   sig.set_parameter_names(Array::Handle(zone, parameter_names())); |   6323   sig.set_parameter_names(Array::Handle(zone, parameter_names())); | 
|   6634   return sig.raw(); |   6324   return sig.raw(); | 
|   6635 } |   6325 } | 
|   6636  |   6326  | 
|   6637  |  | 
|   6638 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter |   6327 // If test_kind == kIsSubtypeOf, checks if the type of the specified parameter | 
|   6639 // of this function is a subtype or a supertype of the type of the specified |   6328 // of this function is a subtype or a supertype of the type of the specified | 
|   6640 // parameter of the other function. |   6329 // parameter of the other function. | 
|   6641 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified |   6330 // If test_kind == kIsMoreSpecificThan, checks if the type of the specified | 
|   6642 // parameter of this function is more specific than the type of the specified |   6331 // parameter of this function is more specific than the type of the specified | 
|   6643 // parameter of the other function. |   6332 // parameter of the other function. | 
|   6644 // Note that we do not apply contravariance of parameter types, but covariance |   6333 // Note that we do not apply contravariance of parameter types, but covariance | 
|   6645 // of both parameter types and result type. |   6334 // of both parameter types and result type. | 
|   6646 bool Function::TestParameterType(TypeTestKind test_kind, |   6335 bool Function::TestParameterType(TypeTestKind test_kind, | 
|   6647                                  intptr_t parameter_position, |   6336                                  intptr_t parameter_position, | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|   6670   } else { |   6359   } else { | 
|   6671     ASSERT(test_kind == kIsMoreSpecificThan); |   6360     ASSERT(test_kind == kIsMoreSpecificThan); | 
|   6672     if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, |   6361     if (!param_type.IsMoreSpecificThan(other_param_type, bound_error, | 
|   6673                                        bound_trail, space)) { |   6362                                        bound_trail, space)) { | 
|   6674       return false; |   6363       return false; | 
|   6675     } |   6364     } | 
|   6676   } |   6365   } | 
|   6677   return true; |   6366   return true; | 
|   6678 } |   6367 } | 
|   6679  |   6368  | 
|   6680  |  | 
|   6681 bool Function::HasSameTypeParametersAndBounds(const Function& other) const { |   6369 bool Function::HasSameTypeParametersAndBounds(const Function& other) const { | 
|   6682   Thread* thread = Thread::Current(); |   6370   Thread* thread = Thread::Current(); | 
|   6683   Zone* zone = thread->zone(); |   6371   Zone* zone = thread->zone(); | 
|   6684   const intptr_t num_type_params = NumTypeParameters(thread); |   6372   const intptr_t num_type_params = NumTypeParameters(thread); | 
|   6685   if (num_type_params != other.NumTypeParameters(thread)) { |   6373   if (num_type_params != other.NumTypeParameters(thread)) { | 
|   6686     return false; |   6374     return false; | 
|   6687   } |   6375   } | 
|   6688   if (num_type_params > 0) { |   6376   if (num_type_params > 0) { | 
|   6689     const TypeArguments& type_params = |   6377     const TypeArguments& type_params = | 
|   6690         TypeArguments::Handle(zone, type_parameters()); |   6378         TypeArguments::Handle(zone, type_parameters()); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   6704       other_bound = other_type_param.bound(); |   6392       other_bound = other_type_param.bound(); | 
|   6705       ASSERT(other_bound.IsFinalized()); |   6393       ASSERT(other_bound.IsFinalized()); | 
|   6706       if (!bound.Equals(other_bound)) { |   6394       if (!bound.Equals(other_bound)) { | 
|   6707         return false; |   6395         return false; | 
|   6708       } |   6396       } | 
|   6709     } |   6397     } | 
|   6710   } |   6398   } | 
|   6711   return true; |   6399   return true; | 
|   6712 } |   6400 } | 
|   6713  |   6401  | 
|   6714  |  | 
|   6715 bool Function::TypeTest(TypeTestKind test_kind, |   6402 bool Function::TypeTest(TypeTestKind test_kind, | 
|   6716                         const Function& other, |   6403                         const Function& other, | 
|   6717                         Error* bound_error, |   6404                         Error* bound_error, | 
|   6718                         TrailPtr bound_trail, |   6405                         TrailPtr bound_trail, | 
|   6719                         Heap::Space space) const { |   6406                         Heap::Space space) const { | 
|   6720   const intptr_t num_fixed_params = num_fixed_parameters(); |   6407   const intptr_t num_fixed_params = num_fixed_parameters(); | 
|   6721   const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |   6408   const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 
|   6722   const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |   6409   const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 
|   6723   const intptr_t other_num_fixed_params = other.num_fixed_parameters(); |   6410   const intptr_t other_num_fixed_params = other.num_fixed_parameters(); | 
|   6724   const intptr_t other_num_opt_pos_params = |   6411   const intptr_t other_num_opt_pos_params = | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   6809         break; |   6496         break; | 
|   6810       } |   6497       } | 
|   6811     } |   6498     } | 
|   6812     if (!found_param_name) { |   6499     if (!found_param_name) { | 
|   6813       return false; |   6500       return false; | 
|   6814     } |   6501     } | 
|   6815   } |   6502   } | 
|   6816   return true; |   6503   return true; | 
|   6817 } |   6504 } | 
|   6818  |   6505  | 
|   6819  |  | 
|   6820 // The compiler generates an implicit constructor if a class definition |   6506 // The compiler generates an implicit constructor if a class definition | 
|   6821 // does not contain an explicit constructor or factory. The implicit |   6507 // does not contain an explicit constructor or factory. The implicit | 
|   6822 // constructor has the same token position as the owner class. |   6508 // constructor has the same token position as the owner class. | 
|   6823 bool Function::IsImplicitConstructor() const { |   6509 bool Function::IsImplicitConstructor() const { | 
|   6824   return IsGenerativeConstructor() && (token_pos() == end_token_pos()); |   6510   return IsGenerativeConstructor() && (token_pos() == end_token_pos()); | 
|   6825 } |   6511 } | 
|   6826  |   6512  | 
|   6827  |  | 
|   6828 bool Function::IsImplicitClosureFunction() const { |   6513 bool Function::IsImplicitClosureFunction() const { | 
|   6829   if (!IsClosureFunction()) { |   6514   if (!IsClosureFunction()) { | 
|   6830     return false; |   6515     return false; | 
|   6831   } |   6516   } | 
|   6832   const Function& parent = Function::Handle(parent_function()); |   6517   const Function& parent = Function::Handle(parent_function()); | 
|   6833   return (parent.implicit_closure_function() == raw()); |   6518   return (parent.implicit_closure_function() == raw()); | 
|   6834 } |   6519 } | 
|   6835  |   6520  | 
|   6836  |  | 
|   6837 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) { |   6521 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) { | 
|   6838   NoSafepointScope no_safepoint; |   6522   NoSafepointScope no_safepoint; | 
|   6839   uint32_t kind_tag = func->ptr()->kind_tag_; |   6523   uint32_t kind_tag = func->ptr()->kind_tag_; | 
|   6840   if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) { |   6524   if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) { | 
|   6841     return false; |   6525     return false; | 
|   6842   } |   6526   } | 
|   6843   if (!StaticBit::decode(kind_tag)) { |   6527   if (!StaticBit::decode(kind_tag)) { | 
|   6844     return false; |   6528     return false; | 
|   6845   } |   6529   } | 
|   6846   RawClosureData* data = reinterpret_cast<RawClosureData*>(func->ptr()->data_); |   6530   RawClosureData* data = reinterpret_cast<RawClosureData*>(func->ptr()->data_); | 
|   6847   RawFunction* parent_function = data->ptr()->parent_function_; |   6531   RawFunction* parent_function = data->ptr()->parent_function_; | 
|   6848   return (parent_function->ptr()->data_ == reinterpret_cast<RawObject*>(func)); |   6532   return (parent_function->ptr()->data_ == reinterpret_cast<RawObject*>(func)); | 
|   6849 } |   6533 } | 
|   6850  |   6534  | 
|   6851  |  | 
|   6852 bool Function::IsConstructorClosureFunction() const { |   6535 bool Function::IsConstructorClosureFunction() const { | 
|   6853   return IsClosureFunction() && |   6536   return IsClosureFunction() && | 
|   6854          String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix()); |   6537          String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix()); | 
|   6855 } |   6538 } | 
|   6856  |   6539  | 
|   6857  |  | 
|   6858 RawFunction* Function::New(Heap::Space space) { |   6540 RawFunction* Function::New(Heap::Space space) { | 
|   6859   ASSERT(Object::function_class() != Class::null()); |   6541   ASSERT(Object::function_class() != Class::null()); | 
|   6860   RawObject* raw = |   6542   RawObject* raw = | 
|   6861       Object::Allocate(Function::kClassId, Function::InstanceSize(), space); |   6543       Object::Allocate(Function::kClassId, Function::InstanceSize(), space); | 
|   6862   return reinterpret_cast<RawFunction*>(raw); |   6544   return reinterpret_cast<RawFunction*>(raw); | 
|   6863 } |   6545 } | 
|   6864  |   6546  | 
|   6865  |  | 
|   6866 RawFunction* Function::New(const String& name, |   6547 RawFunction* Function::New(const String& name, | 
|   6867                            RawFunction::Kind kind, |   6548                            RawFunction::Kind kind, | 
|   6868                            bool is_static, |   6549                            bool is_static, | 
|   6869                            bool is_const, |   6550                            bool is_const, | 
|   6870                            bool is_abstract, |   6551                            bool is_abstract, | 
|   6871                            bool is_external, |   6552                            bool is_external, | 
|   6872                            bool is_native, |   6553                            bool is_native, | 
|   6873                            const Object& owner, |   6554                            const Object& owner, | 
|   6874                            TokenPosition token_pos, |   6555                            TokenPosition token_pos, | 
|   6875                            Heap::Space space) { |   6556                            Heap::Space space) { | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   6920         SignatureData::Handle(SignatureData::New(space)); |   6601         SignatureData::Handle(SignatureData::New(space)); | 
|   6921     result.set_data(data); |   6602     result.set_data(data); | 
|   6922   } else { |   6603   } else { | 
|   6923     // Functions other than signature functions have no reason to be allocated |   6604     // Functions other than signature functions have no reason to be allocated | 
|   6924     // in new space. |   6605     // in new space. | 
|   6925     ASSERT(space == Heap::kOld); |   6606     ASSERT(space == Heap::kOld); | 
|   6926   } |   6607   } | 
|   6927   return result.raw(); |   6608   return result.raw(); | 
|   6928 } |   6609 } | 
|   6929  |   6610  | 
|   6930  |  | 
|   6931 RawFunction* Function::Clone(const Class& new_owner) const { |   6611 RawFunction* Function::Clone(const Class& new_owner) const { | 
|   6932   ASSERT(!IsGenerativeConstructor()); |   6612   ASSERT(!IsGenerativeConstructor()); | 
|   6933   Thread* thread = Thread::Current(); |   6613   Thread* thread = Thread::Current(); | 
|   6934   Zone* zone = thread->zone(); |   6614   Zone* zone = thread->zone(); | 
|   6935   Function& clone = Function::Handle(zone); |   6615   Function& clone = Function::Handle(zone); | 
|   6936   clone ^= Object::Clone(*this, Heap::kOld); |   6616   clone ^= Object::Clone(*this, Heap::kOld); | 
|   6937   const Class& origin = Class::Handle(zone, this->origin()); |   6617   const Class& origin = Class::Handle(zone, this->origin()); | 
|   6938   const PatchClass& clone_owner = |   6618   const PatchClass& clone_owner = | 
|   6939       PatchClass::Handle(zone, PatchClass::New(new_owner, origin)); |   6619       PatchClass::Handle(zone, PatchClass::New(new_owner, origin)); | 
|   6940   clone.set_owner(clone_owner); |   6620   clone.set_owner(clone_owner); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|   6970     clone.set_parameter_types(array); |   6650     clone.set_parameter_types(array); | 
|   6971     for (intptr_t i = 0; i < num_params; i++) { |   6651     for (intptr_t i = 0; i < num_params; i++) { | 
|   6972       type = clone.ParameterTypeAt(i); |   6652       type = clone.ParameterTypeAt(i); | 
|   6973       type ^= type.CloneUninstantiated(new_owner); |   6653       type ^= type.CloneUninstantiated(new_owner); | 
|   6974       clone.SetParameterTypeAt(i, type); |   6654       clone.SetParameterTypeAt(i, type); | 
|   6975     } |   6655     } | 
|   6976   } |   6656   } | 
|   6977   return clone.raw(); |   6657   return clone.raw(); | 
|   6978 } |   6658 } | 
|   6979  |   6659  | 
|   6980  |  | 
|   6981 RawFunction* Function::NewClosureFunction(const String& name, |   6660 RawFunction* Function::NewClosureFunction(const String& name, | 
|   6982                                           const Function& parent, |   6661                                           const Function& parent, | 
|   6983                                           TokenPosition token_pos) { |   6662                                           TokenPosition token_pos) { | 
|   6984   ASSERT(!parent.IsNull()); |   6663   ASSERT(!parent.IsNull()); | 
|   6985   // Use the owner defining the parent function and not the class containing it. |   6664   // Use the owner defining the parent function and not the class containing it. | 
|   6986   const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); |   6665   const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); | 
|   6987   ASSERT(!parent_owner.IsNull()); |   6666   ASSERT(!parent_owner.IsNull()); | 
|   6988   const Function& result = Function::Handle( |   6667   const Function& result = Function::Handle( | 
|   6989       Function::New(name, RawFunction::kClosureFunction, |   6668       Function::New(name, RawFunction::kClosureFunction, | 
|   6990                     /* is_static = */ parent.is_static(), |   6669                     /* is_static = */ parent.is_static(), | 
|   6991                     /* is_const = */ false, |   6670                     /* is_const = */ false, | 
|   6992                     /* is_abstract = */ false, |   6671                     /* is_abstract = */ false, | 
|   6993                     /* is_external = */ false, |   6672                     /* is_external = */ false, | 
|   6994                     /* is_native = */ false, parent_owner, token_pos)); |   6673                     /* is_native = */ false, parent_owner, token_pos)); | 
|   6995   result.set_parent_function(parent); |   6674   result.set_parent_function(parent); | 
|   6996   return result.raw(); |   6675   return result.raw(); | 
|   6997 } |   6676 } | 
|   6998  |   6677  | 
|   6999  |  | 
|   7000 RawFunction* Function::NewSignatureFunction(const Object& owner, |   6678 RawFunction* Function::NewSignatureFunction(const Object& owner, | 
|   7001                                             const Function& parent, |   6679                                             const Function& parent, | 
|   7002                                             TokenPosition token_pos, |   6680                                             TokenPosition token_pos, | 
|   7003                                             Heap::Space space) { |   6681                                             Heap::Space space) { | 
|   7004   const Function& result = Function::Handle(Function::New( |   6682   const Function& result = Function::Handle(Function::New( | 
|   7005       Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, |   6683       Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, | 
|   7006       /* is_static = */ false, |   6684       /* is_static = */ false, | 
|   7007       /* is_const = */ false, |   6685       /* is_const = */ false, | 
|   7008       /* is_abstract = */ false, |   6686       /* is_abstract = */ false, | 
|   7009       /* is_external = */ false, |   6687       /* is_external = */ false, | 
|   7010       /* is_native = */ false, |   6688       /* is_native = */ false, | 
|   7011       owner,  // Same as function type scope class. |   6689       owner,  // Same as function type scope class. | 
|   7012       token_pos, space)); |   6690       token_pos, space)); | 
|   7013   result.set_parent_function(parent); |   6691   result.set_parent_function(parent); | 
|   7014   result.set_is_reflectable(false); |   6692   result.set_is_reflectable(false); | 
|   7015   result.set_is_visible(false); |   6693   result.set_is_visible(false); | 
|   7016   result.set_is_debuggable(false); |   6694   result.set_is_debuggable(false); | 
|   7017   return result.raw(); |   6695   return result.raw(); | 
|   7018 } |   6696 } | 
|   7019  |   6697  | 
|   7020  |  | 
|   7021 RawFunction* Function::NewEvalFunction(const Class& owner, |   6698 RawFunction* Function::NewEvalFunction(const Class& owner, | 
|   7022                                        const Script& script, |   6699                                        const Script& script, | 
|   7023                                        bool is_static) { |   6700                                        bool is_static) { | 
|   7024   Thread* thread = Thread::Current(); |   6701   Thread* thread = Thread::Current(); | 
|   7025   Zone* zone = thread->zone(); |   6702   Zone* zone = thread->zone(); | 
|   7026   const Function& result = Function::Handle( |   6703   const Function& result = Function::Handle( | 
|   7027       zone, |   6704       zone, | 
|   7028       Function::New(String::Handle(Symbols::New(thread, ":Eval")), |   6705       Function::New(String::Handle(Symbols::New(thread, ":Eval")), | 
|   7029                     RawFunction::kRegularFunction, is_static, |   6706                     RawFunction::kRegularFunction, is_static, | 
|   7030                     /* is_const = */ false, |   6707                     /* is_const = */ false, | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   7107   const Type& signature_type = |   6784   const Type& signature_type = | 
|   7108       Type::Handle(zone, closure_function.SignatureType()); |   6785       Type::Handle(zone, closure_function.SignatureType()); | 
|   7109   if (!signature_type.IsFinalized()) { |   6786   if (!signature_type.IsFinalized()) { | 
|   7110     ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type); |   6787     ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type); | 
|   7111   } |   6788   } | 
|   7112   set_implicit_closure_function(closure_function); |   6789   set_implicit_closure_function(closure_function); | 
|   7113   ASSERT(closure_function.IsImplicitClosureFunction()); |   6790   ASSERT(closure_function.IsImplicitClosureFunction()); | 
|   7114   return closure_function.raw(); |   6791   return closure_function.raw(); | 
|   7115 } |   6792 } | 
|   7116  |   6793  | 
|   7117  |  | 
|   7118 void Function::DropUncompiledImplicitClosureFunction() const { |   6794 void Function::DropUncompiledImplicitClosureFunction() const { | 
|   7119   if (implicit_closure_function() != Function::null()) { |   6795   if (implicit_closure_function() != Function::null()) { | 
|   7120     const Function& func = Function::Handle(implicit_closure_function()); |   6796     const Function& func = Function::Handle(implicit_closure_function()); | 
|   7121     if (!func.HasCode()) { |   6797     if (!func.HasCode()) { | 
|   7122       set_implicit_closure_function(Function::Handle()); |   6798       set_implicit_closure_function(Function::Handle()); | 
|   7123     } |   6799     } | 
|   7124   } |   6800   } | 
|   7125 } |   6801 } | 
|   7126  |   6802  | 
|   7127  |  | 
|   7128 RawString* Function::UserVisibleFormalParameters() const { |   6803 RawString* Function::UserVisibleFormalParameters() const { | 
|   7129   Thread* thread = Thread::Current(); |   6804   Thread* thread = Thread::Current(); | 
|   7130   Zone* zone = thread->zone(); |   6805   Zone* zone = thread->zone(); | 
|   7131   // Typically 3, 5,.. elements in 'pieces', e.g.: |   6806   // Typically 3, 5,.. elements in 'pieces', e.g.: | 
|   7132   // '_LoadRequest', CommaSpace, '_LoadError'. |   6807   // '_LoadRequest', CommaSpace, '_LoadError'. | 
|   7133   GrowableHandlePtrArray<const String> pieces(zone, 5); |   6808   GrowableHandlePtrArray<const String> pieces(zone, 5); | 
|   7134   BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); |   6809   BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); | 
|   7135   return Symbols::FromConcatAll(thread, pieces); |   6810   return Symbols::FromConcatAll(thread, pieces); | 
|   7136 } |   6811 } | 
|   7137  |   6812  | 
|   7138  |  | 
|   7139 void Function::BuildSignatureParameters( |   6813 void Function::BuildSignatureParameters( | 
|   7140     Thread* thread, |   6814     Thread* thread, | 
|   7141     Zone* zone, |   6815     Zone* zone, | 
|   7142     NameVisibility name_visibility, |   6816     NameVisibility name_visibility, | 
|   7143     GrowableHandlePtrArray<const String>* pieces) const { |   6817     GrowableHandlePtrArray<const String>* pieces) const { | 
|   7144   AbstractType& param_type = AbstractType::Handle(zone); |   6818   AbstractType& param_type = AbstractType::Handle(zone); | 
|   7145   const intptr_t num_params = NumParameters(); |   6819   const intptr_t num_params = NumParameters(); | 
|   7146   const intptr_t num_fixed_params = num_fixed_parameters(); |   6820   const intptr_t num_fixed_params = num_fixed_parameters(); | 
|   7147   const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); |   6821   const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); | 
|   7148   const intptr_t num_opt_named_params = NumOptionalNamedParameters(); |   6822   const intptr_t num_opt_named_params = NumOptionalNamedParameters(); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   7187       } |   6861       } | 
|   7188     } |   6862     } | 
|   7189     if (num_opt_pos_params > 0) { |   6863     if (num_opt_pos_params > 0) { | 
|   7190       pieces->Add(Symbols::RBracket()); |   6864       pieces->Add(Symbols::RBracket()); | 
|   7191     } else { |   6865     } else { | 
|   7192       pieces->Add(Symbols::RBrace()); |   6866       pieces->Add(Symbols::RBrace()); | 
|   7193     } |   6867     } | 
|   7194   } |   6868   } | 
|   7195 } |   6869 } | 
|   7196  |   6870  | 
|   7197  |  | 
|   7198 RawInstance* Function::ImplicitStaticClosure() const { |   6871 RawInstance* Function::ImplicitStaticClosure() const { | 
|   7199   if (implicit_static_closure() == Instance::null()) { |   6872   if (implicit_static_closure() == Instance::null()) { | 
|   7200     Zone* zone = Thread::Current()->zone(); |   6873     Zone* zone = Thread::Current()->zone(); | 
|   7201     const Context& context = Object::empty_context(); |   6874     const Context& context = Object::empty_context(); | 
|   7202     TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |   6875     TypeArguments& function_type_arguments = TypeArguments::Handle(zone); | 
|   7203     if (!HasInstantiatedSignature(kFunctions)) { |   6876     if (!HasInstantiatedSignature(kFunctions)) { | 
|   7204       function_type_arguments = Object::empty_type_arguments().raw(); |   6877       function_type_arguments = Object::empty_type_arguments().raw(); | 
|   7205     } |   6878     } | 
|   7206     Instance& closure = |   6879     Instance& closure = | 
|   7207         Instance::Handle(zone, Closure::New(Object::null_type_arguments(), |   6880         Instance::Handle(zone, Closure::New(Object::null_type_arguments(), | 
|   7208                                             function_type_arguments, *this, |   6881                                             function_type_arguments, *this, | 
|   7209                                             context, Heap::kOld)); |   6882                                             context, Heap::kOld)); | 
|   7210     set_implicit_static_closure(closure); |   6883     set_implicit_static_closure(closure); | 
|   7211   } |   6884   } | 
|   7212   return implicit_static_closure(); |   6885   return implicit_static_closure(); | 
|   7213 } |   6886 } | 
|   7214  |   6887  | 
|   7215  |  | 
|   7216 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { |   6888 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const { | 
|   7217   ASSERT(IsImplicitClosureFunction()); |   6889   ASSERT(IsImplicitClosureFunction()); | 
|   7218   Zone* zone = Thread::Current()->zone(); |   6890   Zone* zone = Thread::Current()->zone(); | 
|   7219   const Context& context = Context::Handle(zone, Context::New(1)); |   6891   const Context& context = Context::Handle(zone, Context::New(1)); | 
|   7220   context.SetAt(0, receiver); |   6892   context.SetAt(0, receiver); | 
|   7221   TypeArguments& instantiator_type_arguments = TypeArguments::Handle(zone); |   6893   TypeArguments& instantiator_type_arguments = TypeArguments::Handle(zone); | 
|   7222   TypeArguments& function_type_arguments = TypeArguments::Handle(zone); |   6894   TypeArguments& function_type_arguments = TypeArguments::Handle(zone); | 
|   7223   if (!HasInstantiatedSignature(kCurrentClass)) { |   6895   if (!HasInstantiatedSignature(kCurrentClass)) { | 
|   7224     instantiator_type_arguments = receiver.GetTypeArguments(); |   6896     instantiator_type_arguments = receiver.GetTypeArguments(); | 
|   7225   } |   6897   } | 
|   7226   if (!HasInstantiatedSignature(kFunctions)) { |   6898   if (!HasInstantiatedSignature(kFunctions)) { | 
|   7227     function_type_arguments = Object::empty_type_arguments().raw(); |   6899     function_type_arguments = Object::empty_type_arguments().raw(); | 
|   7228   } |   6900   } | 
|   7229   return Closure::New(instantiator_type_arguments, function_type_arguments, |   6901   return Closure::New(instantiator_type_arguments, function_type_arguments, | 
|   7230                       *this, context); |   6902                       *this, context); | 
|   7231 } |   6903 } | 
|   7232  |   6904  | 
|   7233  |  | 
|   7234 RawSmi* Function::GetClosureHashCode() const { |   6905 RawSmi* Function::GetClosureHashCode() const { | 
|   7235   ASSERT(IsClosureFunction()); |   6906   ASSERT(IsClosureFunction()); | 
|   7236   const Object& obj = Object::Handle(raw_ptr()->data_); |   6907   const Object& obj = Object::Handle(raw_ptr()->data_); | 
|   7237   ASSERT(!obj.IsNull()); |   6908   ASSERT(!obj.IsNull()); | 
|   7238   if (ClosureData::Cast(obj).hash() != Object::null()) { |   6909   if (ClosureData::Cast(obj).hash() != Object::null()) { | 
|   7239     return Smi::RawCast(ClosureData::Cast(obj).hash()); |   6910     return Smi::RawCast(ClosureData::Cast(obj).hash()); | 
|   7240   } |   6911   } | 
|   7241   // Hash not yet computed. Compute and cache it. |   6912   // Hash not yet computed. Compute and cache it. | 
|   7242   const Class& cls = Class::Handle(Owner()); |   6913   const Class& cls = Class::Handle(Owner()); | 
|   7243   intptr_t result = String::Handle(name()).Hash(); |   6914   intptr_t result = String::Handle(name()).Hash(); | 
|   7244   result += String::Handle(Signature()).Hash(); |   6915   result += String::Handle(Signature()).Hash(); | 
|   7245   result += String::Handle(cls.Name()).Hash(); |   6916   result += String::Handle(cls.Name()).Hash(); | 
|   7246   // Finalize hash value like for strings so that it fits into a smi. |   6917   // Finalize hash value like for strings so that it fits into a smi. | 
|   7247   result += result << 3; |   6918   result += result << 3; | 
|   7248   result ^= result >> 11; |   6919   result ^= result >> 11; | 
|   7249   result += result << 15; |   6920   result += result << 15; | 
|   7250   result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); |   6921   result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1); | 
|   7251   ClosureData::Cast(obj).set_hash(result); |   6922   ClosureData::Cast(obj).set_hash(result); | 
|   7252   return Smi::New(result); |   6923   return Smi::New(result); | 
|   7253 } |   6924 } | 
|   7254  |   6925  | 
|   7255  |  | 
|   7256 RawString* Function::BuildSignature(NameVisibility name_visibility) const { |   6926 RawString* Function::BuildSignature(NameVisibility name_visibility) const { | 
|   7257   Thread* thread = Thread::Current(); |   6927   Thread* thread = Thread::Current(); | 
|   7258   Zone* zone = thread->zone(); |   6928   Zone* zone = thread->zone(); | 
|   7259   GrowableHandlePtrArray<const String> pieces(zone, 4); |   6929   GrowableHandlePtrArray<const String> pieces(zone, 4); | 
|   7260   String& name = String::Handle(zone); |   6930   String& name = String::Handle(zone); | 
|   7261   if (FLAG_reify_generic_functions) { |   6931   if (FLAG_reify_generic_functions) { | 
|   7262     const TypeArguments& type_params = |   6932     const TypeArguments& type_params = | 
|   7263         TypeArguments::Handle(zone, type_parameters()); |   6933         TypeArguments::Handle(zone, type_parameters()); | 
|   7264     if (!type_params.IsNull()) { |   6934     if (!type_params.IsNull()) { | 
|   7265       const intptr_t num_type_params = type_params.Length(); |   6935       const intptr_t num_type_params = type_params.Length(); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|   7286   } |   6956   } | 
|   7287   pieces.Add(Symbols::LParen()); |   6957   pieces.Add(Symbols::LParen()); | 
|   7288   BuildSignatureParameters(thread, zone, name_visibility, &pieces); |   6958   BuildSignatureParameters(thread, zone, name_visibility, &pieces); | 
|   7289   pieces.Add(Symbols::RParenArrow()); |   6959   pieces.Add(Symbols::RParenArrow()); | 
|   7290   const AbstractType& res_type = AbstractType::Handle(zone, result_type()); |   6960   const AbstractType& res_type = AbstractType::Handle(zone, result_type()); | 
|   7291   name = res_type.BuildName(name_visibility); |   6961   name = res_type.BuildName(name_visibility); | 
|   7292   pieces.Add(name); |   6962   pieces.Add(name); | 
|   7293   return Symbols::FromConcatAll(thread, pieces); |   6963   return Symbols::FromConcatAll(thread, pieces); | 
|   7294 } |   6964 } | 
|   7295  |   6965  | 
|   7296  |  | 
|   7297 bool Function::HasInstantiatedSignature(Genericity genericity, |   6966 bool Function::HasInstantiatedSignature(Genericity genericity, | 
|   7298                                         intptr_t num_free_fun_type_params, |   6967                                         intptr_t num_free_fun_type_params, | 
|   7299                                         TrailPtr trail) const { |   6968                                         TrailPtr trail) const { | 
|   7300   if (genericity != kCurrentClass) { |   6969   if (genericity != kCurrentClass) { | 
|   7301     // We only consider the function type parameters declared by the parents of |   6970     // We only consider the function type parameters declared by the parents of | 
|   7302     // this signature function. |   6971     // this signature function. | 
|   7303     const int num_parent_type_params = NumParentTypeParameters(); |   6972     const int num_parent_type_params = NumParentTypeParameters(); | 
|   7304     if (num_parent_type_params < num_free_fun_type_params) { |   6973     if (num_parent_type_params < num_free_fun_type_params) { | 
|   7305       num_free_fun_type_params = num_parent_type_params; |   6974       num_free_fun_type_params = num_parent_type_params; | 
|   7306     } |   6975     } | 
|   7307   } |   6976   } | 
|   7308   AbstractType& type = AbstractType::Handle(result_type()); |   6977   AbstractType& type = AbstractType::Handle(result_type()); | 
|   7309   if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |   6978   if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 
|   7310     return false; |   6979     return false; | 
|   7311   } |   6980   } | 
|   7312   const intptr_t num_parameters = NumParameters(); |   6981   const intptr_t num_parameters = NumParameters(); | 
|   7313   for (intptr_t i = 0; i < num_parameters; i++) { |   6982   for (intptr_t i = 0; i < num_parameters; i++) { | 
|   7314     type = ParameterTypeAt(i); |   6983     type = ParameterTypeAt(i); | 
|   7315     if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { |   6984     if (!type.IsInstantiated(genericity, num_free_fun_type_params, trail)) { | 
|   7316       return false; |   6985       return false; | 
|   7317     } |   6986     } | 
|   7318   } |   6987   } | 
|   7319   return true; |   6988   return true; | 
|   7320 } |   6989 } | 
|   7321  |   6990  | 
|   7322  |  | 
|   7323 RawClass* Function::Owner() const { |   6991 RawClass* Function::Owner() const { | 
|   7324   if (raw_ptr()->owner_ == Object::null()) { |   6992   if (raw_ptr()->owner_ == Object::null()) { | 
|   7325     ASSERT(IsSignatureFunction()); |   6993     ASSERT(IsSignatureFunction()); | 
|   7326     return Class::null(); |   6994     return Class::null(); | 
|   7327   } |   6995   } | 
|   7328   if (raw_ptr()->owner_->IsClass()) { |   6996   if (raw_ptr()->owner_->IsClass()) { | 
|   7329     return Class::RawCast(raw_ptr()->owner_); |   6997     return Class::RawCast(raw_ptr()->owner_); | 
|   7330   } |   6998   } | 
|   7331   const Object& obj = Object::Handle(raw_ptr()->owner_); |   6999   const Object& obj = Object::Handle(raw_ptr()->owner_); | 
|   7332   ASSERT(obj.IsPatchClass()); |   7000   ASSERT(obj.IsPatchClass()); | 
|   7333   return PatchClass::Cast(obj).patched_class(); |   7001   return PatchClass::Cast(obj).patched_class(); | 
|   7334 } |   7002 } | 
|   7335  |   7003  | 
|   7336  |  | 
|   7337 RawClass* Function::origin() const { |   7004 RawClass* Function::origin() const { | 
|   7338   if (raw_ptr()->owner_ == Object::null()) { |   7005   if (raw_ptr()->owner_ == Object::null()) { | 
|   7339     ASSERT(IsSignatureFunction()); |   7006     ASSERT(IsSignatureFunction()); | 
|   7340     return Class::null(); |   7007     return Class::null(); | 
|   7341   } |   7008   } | 
|   7342   if (raw_ptr()->owner_->IsClass()) { |   7009   if (raw_ptr()->owner_->IsClass()) { | 
|   7343     return Class::RawCast(raw_ptr()->owner_); |   7010     return Class::RawCast(raw_ptr()->owner_); | 
|   7344   } |   7011   } | 
|   7345   const Object& obj = Object::Handle(raw_ptr()->owner_); |   7012   const Object& obj = Object::Handle(raw_ptr()->owner_); | 
|   7346   ASSERT(obj.IsPatchClass()); |   7013   ASSERT(obj.IsPatchClass()); | 
|   7347   return PatchClass::Cast(obj).origin_class(); |   7014   return PatchClass::Cast(obj).origin_class(); | 
|   7348 } |   7015 } | 
|   7349  |   7016  | 
|   7350  |  | 
|   7351 RawScript* Function::script() const { |   7017 RawScript* Function::script() const { | 
|   7352   // NOTE(turnidge): If you update this function, you probably want to |   7018   // NOTE(turnidge): If you update this function, you probably want to | 
|   7353   // update Class::PatchFieldsAndFunctions() at the same time. |   7019   // update Class::PatchFieldsAndFunctions() at the same time. | 
|   7354   if (token_pos() == TokenPosition::kMinSource) { |   7020   if (token_pos() == TokenPosition::kMinSource) { | 
|   7355     // Testing for position 0 is an optimization that relies on temporary |   7021     // Testing for position 0 is an optimization that relies on temporary | 
|   7356     // eval functions having token position 0. |   7022     // eval functions having token position 0. | 
|   7357     const Script& script = Script::Handle(eval_script()); |   7023     const Script& script = Script::Handle(eval_script()); | 
|   7358     if (!script.IsNull()) { |   7024     if (!script.IsNull()) { | 
|   7359       return script.raw(); |   7025       return script.raw(); | 
|   7360     } |   7026     } | 
|   7361   } |   7027   } | 
|   7362   if (IsClosureFunction()) { |   7028   if (IsClosureFunction()) { | 
|   7363     return Function::Handle(parent_function()).script(); |   7029     return Function::Handle(parent_function()).script(); | 
|   7364   } |   7030   } | 
|   7365   const Object& obj = Object::Handle(raw_ptr()->owner_); |   7031   const Object& obj = Object::Handle(raw_ptr()->owner_); | 
|   7366   if (obj.IsNull()) { |   7032   if (obj.IsNull()) { | 
|   7367     ASSERT(IsSignatureFunction()); |   7033     ASSERT(IsSignatureFunction()); | 
|   7368     return Script::null(); |   7034     return Script::null(); | 
|   7369   } |   7035   } | 
|   7370   if (obj.IsClass()) { |   7036   if (obj.IsClass()) { | 
|   7371     return Class::Cast(obj).script(); |   7037     return Class::Cast(obj).script(); | 
|   7372   } |   7038   } | 
|   7373   ASSERT(obj.IsPatchClass()); |   7039   ASSERT(obj.IsPatchClass()); | 
|   7374   return PatchClass::Cast(obj).script(); |   7040   return PatchClass::Cast(obj).script(); | 
|   7375 } |   7041 } | 
|   7376  |   7042  | 
|   7377  |  | 
|   7378 bool Function::HasOptimizedCode() const { |   7043 bool Function::HasOptimizedCode() const { | 
|   7379   return HasCode() && Code::Handle(CurrentCode()).is_optimized(); |   7044   return HasCode() && Code::Handle(CurrentCode()).is_optimized(); | 
|   7380 } |   7045 } | 
|   7381  |   7046  | 
|   7382  |  | 
|   7383 RawString* Function::UserVisibleName() const { |   7047 RawString* Function::UserVisibleName() const { | 
|   7384   if (FLAG_show_internal_names) { |   7048   if (FLAG_show_internal_names) { | 
|   7385     return name(); |   7049     return name(); | 
|   7386   } |   7050   } | 
|   7387   return String::ScrubName(String::Handle(name())); |   7051   return String::ScrubName(String::Handle(name())); | 
|   7388 } |   7052 } | 
|   7389  |   7053  | 
|   7390  |  | 
|   7391 RawString* Function::QualifiedName(NameVisibility name_visibility) const { |   7054 RawString* Function::QualifiedName(NameVisibility name_visibility) const { | 
|   7392   ASSERT(name_visibility != kInternalName);  // We never request it. |   7055   ASSERT(name_visibility != kInternalName);  // We never request it. | 
|   7393   // If |this| is the generated asynchronous body closure, use the |   7056   // If |this| is the generated asynchronous body closure, use the | 
|   7394   // name of the parent function. |   7057   // name of the parent function. | 
|   7395   Function& fun = Function::Handle(raw()); |   7058   Function& fun = Function::Handle(raw()); | 
|   7396   if (fun.IsClosureFunction()) { |   7059   if (fun.IsClosureFunction()) { | 
|   7397     // Sniff the parent function. |   7060     // Sniff the parent function. | 
|   7398     fun = fun.parent_function(); |   7061     fun = fun.parent_function(); | 
|   7399     ASSERT(!fun.IsNull()); |   7062     ASSERT(!fun.IsNull()); | 
|   7400     if (!fun.IsAsyncGenerator() && !fun.IsAsyncFunction() && |   7063     if (!fun.IsAsyncGenerator() && !fun.IsAsyncFunction() && | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|   7429       result = String::Concat(Symbols::Dot(), result, Heap::kOld); |   7092       result = String::Concat(Symbols::Dot(), result, Heap::kOld); | 
|   7430       const String& cls_name = String::Handle(name_visibility == kScrubbedName |   7093       const String& cls_name = String::Handle(name_visibility == kScrubbedName | 
|   7431                                                   ? cls.ScrubbedName() |   7094                                                   ? cls.ScrubbedName() | 
|   7432                                                   : cls.UserVisibleName()); |   7095                                                   : cls.UserVisibleName()); | 
|   7433       result = String::Concat(cls_name, result, Heap::kOld); |   7096       result = String::Concat(cls_name, result, Heap::kOld); | 
|   7434     } |   7097     } | 
|   7435   } |   7098   } | 
|   7436   return result.raw(); |   7099   return result.raw(); | 
|   7437 } |   7100 } | 
|   7438  |   7101  | 
|   7439  |  | 
|   7440 RawString* Function::GetSource() const { |   7102 RawString* Function::GetSource() const { | 
|   7441   if (IsImplicitConstructor() || IsSignatureFunction()) { |   7103   if (IsImplicitConstructor() || IsSignatureFunction()) { | 
|   7442     // We may need to handle more cases when the restrictions on mixins are |   7104     // We may need to handle more cases when the restrictions on mixins are | 
|   7443     // relaxed. In particular we might start associating some source with the |   7105     // relaxed. In particular we might start associating some source with the | 
|   7444     // forwarding constructors when it becomes possible to specify a particular |   7106     // forwarding constructors when it becomes possible to specify a particular | 
|   7445     // constructor from the mixin to use. |   7107     // constructor from the mixin to use. | 
|   7446     return String::null(); |   7108     return String::null(); | 
|   7447   } |   7109   } | 
|   7448   Zone* zone = Thread::Current()->zone(); |   7110   Zone* zone = Thread::Current()->zone(); | 
|   7449   const Script& func_script = Script::Handle(zone, script()); |   7111   const Script& func_script = Script::Handle(zone, script()); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   7474        String::Handle(zone, name()).Equals("<anonymous closure>"))) {  // Cas 3. |   7136        String::Handle(zone, name()).Equals("<anonymous closure>"))) {  // Cas 3. | 
|   7475     last_tok_len = 0; |   7137     last_tok_len = 0; | 
|   7476   } |   7138   } | 
|   7477   const String& result = |   7139   const String& result = | 
|   7478       String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line, |   7140       String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line, | 
|   7479                                                   to_col + last_tok_len)); |   7141                                                   to_col + last_tok_len)); | 
|   7480   ASSERT(!result.IsNull()); |   7142   ASSERT(!result.IsNull()); | 
|   7481   return result.raw(); |   7143   return result.raw(); | 
|   7482 } |   7144 } | 
|   7483  |   7145  | 
|   7484  |  | 
|   7485 // Construct fingerprint from token stream. The token stream contains also |   7146 // Construct fingerprint from token stream. The token stream contains also | 
|   7486 // arguments. |   7147 // arguments. | 
|   7487 int32_t Function::SourceFingerprint() const { |   7148 int32_t Function::SourceFingerprint() const { | 
|   7488   return Script::Handle(script()).SourceFingerprint(token_pos(), |   7149   return Script::Handle(script()).SourceFingerprint(token_pos(), | 
|   7489                                                     end_token_pos()); |   7150                                                     end_token_pos()); | 
|   7490 } |   7151 } | 
|   7491  |   7152  | 
|   7492  |  | 
|   7493 void Function::SaveICDataMap( |   7153 void Function::SaveICDataMap( | 
|   7494     const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, |   7154     const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, | 
|   7495     const Array& edge_counters_array) const { |   7155     const Array& edge_counters_array) const { | 
|   7496   // Compute number of ICData objects to save. |   7156   // Compute number of ICData objects to save. | 
|   7497   // Store edge counter array in the first slot. |   7157   // Store edge counter array in the first slot. | 
|   7498   intptr_t count = 1; |   7158   intptr_t count = 1; | 
|   7499   for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |   7159   for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 
|   7500     if (deopt_id_to_ic_data[i] != NULL) { |   7160     if (deopt_id_to_ic_data[i] != NULL) { | 
|   7501       count++; |   7161       count++; | 
|   7502     } |   7162     } | 
|   7503   } |   7163   } | 
|   7504   const Array& array = Array::Handle(Array::New(count, Heap::kOld)); |   7164   const Array& array = Array::Handle(Array::New(count, Heap::kOld)); | 
|   7505   INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); |   7165   INC_STAT(Thread::Current(), total_code_size, count * sizeof(uword)); | 
|   7506   count = 1; |   7166   count = 1; | 
|   7507   for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { |   7167   for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { | 
|   7508     if (deopt_id_to_ic_data[i] != NULL) { |   7168     if (deopt_id_to_ic_data[i] != NULL) { | 
|   7509       array.SetAt(count++, *deopt_id_to_ic_data[i]); |   7169       array.SetAt(count++, *deopt_id_to_ic_data[i]); | 
|   7510     } |   7170     } | 
|   7511   } |   7171   } | 
|   7512   array.SetAt(0, edge_counters_array); |   7172   array.SetAt(0, edge_counters_array); | 
|   7513   set_ic_data_array(array); |   7173   set_ic_data_array(array); | 
|   7514 } |   7174 } | 
|   7515  |   7175  | 
|   7516  |  | 
|   7517 void Function::RestoreICDataMap( |   7176 void Function::RestoreICDataMap( | 
|   7518     ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data, |   7177     ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data, | 
|   7519     bool clone_ic_data) const { |   7178     bool clone_ic_data) const { | 
|   7520   if (FLAG_force_clone_compiler_objects) { |   7179   if (FLAG_force_clone_compiler_objects) { | 
|   7521     clone_ic_data = true; |   7180     clone_ic_data = true; | 
|   7522   } |   7181   } | 
|   7523   ASSERT(deopt_id_to_ic_data->is_empty()); |   7182   ASSERT(deopt_id_to_ic_data->is_empty()); | 
|   7524   Zone* zone = Thread::Current()->zone(); |   7183   Zone* zone = Thread::Current()->zone(); | 
|   7525   const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); |   7184   const Array& saved_ic_data = Array::Handle(zone, ic_data_array()); | 
|   7526   if (saved_ic_data.IsNull()) { |   7185   if (saved_ic_data.IsNull()) { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|   7544       if (clone_ic_data) { |   7203       if (clone_ic_data) { | 
|   7545         const ICData& original_ic_data = ICData::Handle(zone, ic_data.raw()); |   7204         const ICData& original_ic_data = ICData::Handle(zone, ic_data.raw()); | 
|   7546         ic_data = ICData::Clone(ic_data); |   7205         ic_data = ICData::Clone(ic_data); | 
|   7547         ic_data.SetOriginal(original_ic_data); |   7206         ic_data.SetOriginal(original_ic_data); | 
|   7548       } |   7207       } | 
|   7549       (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data; |   7208       (*deopt_id_to_ic_data)[ic_data.deopt_id()] = &ic_data; | 
|   7550     } |   7209     } | 
|   7551   } |   7210   } | 
|   7552 } |   7211 } | 
|   7553  |   7212  | 
|   7554  |  | 
|   7555 void Function::set_ic_data_array(const Array& value) const { |   7213 void Function::set_ic_data_array(const Array& value) const { | 
|   7556   StorePointer(&raw_ptr()->ic_data_array_, value.raw()); |   7214   StorePointer(&raw_ptr()->ic_data_array_, value.raw()); | 
|   7557 } |   7215 } | 
|   7558  |   7216  | 
|   7559  |  | 
|   7560 RawArray* Function::ic_data_array() const { |   7217 RawArray* Function::ic_data_array() const { | 
|   7561   return raw_ptr()->ic_data_array_; |   7218   return raw_ptr()->ic_data_array_; | 
|   7562 } |   7219 } | 
|   7563  |   7220  | 
|   7564  |  | 
|   7565 void Function::ClearICDataArray() const { |   7221 void Function::ClearICDataArray() const { | 
|   7566   set_ic_data_array(Array::null_array()); |   7222   set_ic_data_array(Array::null_array()); | 
|   7567 } |   7223 } | 
|   7568  |   7224  | 
|   7569  |  | 
|   7570 void Function::SetDeoptReasonForAll(intptr_t deopt_id, |   7225 void Function::SetDeoptReasonForAll(intptr_t deopt_id, | 
|   7571                                     ICData::DeoptReasonId reason) { |   7226                                     ICData::DeoptReasonId reason) { | 
|   7572   const Array& array = Array::Handle(ic_data_array()); |   7227   const Array& array = Array::Handle(ic_data_array()); | 
|   7573   ICData& ic_data = ICData::Handle(); |   7228   ICData& ic_data = ICData::Handle(); | 
|   7574   for (intptr_t i = 1; i < array.Length(); i++) { |   7229   for (intptr_t i = 1; i < array.Length(); i++) { | 
|   7575     ic_data ^= array.At(i); |   7230     ic_data ^= array.At(i); | 
|   7576     if (ic_data.deopt_id() == deopt_id) { |   7231     if (ic_data.deopt_id() == deopt_id) { | 
|   7577       ic_data.AddDeoptReason(reason); |   7232       ic_data.AddDeoptReason(reason); | 
|   7578     } |   7233     } | 
|   7579   } |   7234   } | 
|   7580 } |   7235 } | 
|   7581  |   7236  | 
|   7582  |  | 
|   7583 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { |   7237 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { | 
|   7584   if ((kernel_offset() <= 0) && (SourceFingerprint() != fp)) { |   7238   if ((kernel_offset() <= 0) && (SourceFingerprint() != fp)) { | 
|   7585     const bool recalculatingFingerprints = false; |   7239     const bool recalculatingFingerprints = false; | 
|   7586     if (recalculatingFingerprints) { |   7240     if (recalculatingFingerprints) { | 
|   7587       // This output can be copied into a file, then used with sed |   7241       // This output can be copied into a file, then used with sed | 
|   7588       // to replace the old values. |   7242       // to replace the old values. | 
|   7589       // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h |   7243       // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h | 
|   7590       THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); |   7244       THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); | 
|   7591     } else { |   7245     } else { | 
|   7592       THR_Print( |   7246       THR_Print( | 
|   7593           "FP mismatch while recognizing method %s:" |   7247           "FP mismatch while recognizing method %s:" | 
|   7594           " expecting 0x%08x found 0x%08x\n", |   7248           " expecting 0x%08x found 0x%08x\n", | 
|   7595           ToFullyQualifiedCString(), fp, SourceFingerprint()); |   7249           ToFullyQualifiedCString(), fp, SourceFingerprint()); | 
|   7596       return false; |   7250       return false; | 
|   7597     } |   7251     } | 
|   7598   } |   7252   } | 
|   7599   return true; |   7253   return true; | 
|   7600 } |   7254 } | 
|   7601  |   7255  | 
|   7602  |  | 
|   7603 RawCode* Function::EnsureHasCode() const { |   7256 RawCode* Function::EnsureHasCode() const { | 
|   7604   if (HasCode()) return CurrentCode(); |   7257   if (HasCode()) return CurrentCode(); | 
|   7605   Thread* thread = Thread::Current(); |   7258   Thread* thread = Thread::Current(); | 
|   7606   Zone* zone = thread->zone(); |   7259   Zone* zone = thread->zone(); | 
|   7607   const Object& result = |   7260   const Object& result = | 
|   7608       Object::Handle(zone, Compiler::CompileFunction(thread, *this)); |   7261       Object::Handle(zone, Compiler::CompileFunction(thread, *this)); | 
|   7609   if (result.IsError()) { |   7262   if (result.IsError()) { | 
|   7610     Exceptions::PropagateError(Error::Cast(result)); |   7263     Exceptions::PropagateError(Error::Cast(result)); | 
|   7611     UNREACHABLE(); |   7264     UNREACHABLE(); | 
|   7612   } |   7265   } | 
|   7613   // Compiling in unoptimized mode should never fail if there are no errors. |   7266   // Compiling in unoptimized mode should never fail if there are no errors. | 
|   7614   ASSERT(HasCode()); |   7267   ASSERT(HasCode()); | 
|   7615   ASSERT(unoptimized_code() == result.raw()); |   7268   ASSERT(unoptimized_code() == result.raw()); | 
|   7616   return CurrentCode(); |   7269   return CurrentCode(); | 
|   7617 } |   7270 } | 
|   7618  |   7271  | 
|   7619  |  | 
|   7620 const char* Function::ToCString() const { |   7272 const char* Function::ToCString() const { | 
|   7621   if (IsNull()) { |   7273   if (IsNull()) { | 
|   7622     return "Function: null"; |   7274     return "Function: null"; | 
|   7623   } |   7275   } | 
|   7624   const char* static_str = is_static() ? " static" : ""; |   7276   const char* static_str = is_static() ? " static" : ""; | 
|   7625   const char* abstract_str = is_abstract() ? " abstract" : ""; |   7277   const char* abstract_str = is_abstract() ? " abstract" : ""; | 
|   7626   const char* kind_str = NULL; |   7278   const char* kind_str = NULL; | 
|   7627   const char* const_str = is_const() ? " const" : ""; |   7279   const char* const_str = is_const() ? " const" : ""; | 
|   7628   switch (kind()) { |   7280   switch (kind()) { | 
|   7629     case RawFunction::kRegularFunction: |   7281     case RawFunction::kRegularFunction: | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   7661       break; |   7313       break; | 
|   7662     default: |   7314     default: | 
|   7663       UNREACHABLE(); |   7315       UNREACHABLE(); | 
|   7664   } |   7316   } | 
|   7665   const char* function_name = String::Handle(name()).ToCString(); |   7317   const char* function_name = String::Handle(name()).ToCString(); | 
|   7666   return OS::SCreate(Thread::Current()->zone(), "Function '%s':%s%s%s%s.", |   7318   return OS::SCreate(Thread::Current()->zone(), "Function '%s':%s%s%s%s.", | 
|   7667                      function_name, static_str, abstract_str, kind_str, |   7319                      function_name, static_str, abstract_str, kind_str, | 
|   7668                      const_str); |   7320                      const_str); | 
|   7669 } |   7321 } | 
|   7670  |   7322  | 
|   7671  |  | 
|   7672 void ClosureData::set_context_scope(const ContextScope& value) const { |   7323 void ClosureData::set_context_scope(const ContextScope& value) const { | 
|   7673   StorePointer(&raw_ptr()->context_scope_, value.raw()); |   7324   StorePointer(&raw_ptr()->context_scope_, value.raw()); | 
|   7674 } |   7325 } | 
|   7675  |   7326  | 
|   7676  |  | 
|   7677 void ClosureData::set_implicit_static_closure(const Instance& closure) const { |   7327 void ClosureData::set_implicit_static_closure(const Instance& closure) const { | 
|   7678   ASSERT(!closure.IsNull()); |   7328   ASSERT(!closure.IsNull()); | 
|   7679   ASSERT(raw_ptr()->closure_ == Instance::null()); |   7329   ASSERT(raw_ptr()->closure_ == Instance::null()); | 
|   7680   StorePointer(&raw_ptr()->closure_, closure.raw()); |   7330   StorePointer(&raw_ptr()->closure_, closure.raw()); | 
|   7681 } |   7331 } | 
|   7682  |   7332  | 
|   7683  |  | 
|   7684 void ClosureData::set_hash(intptr_t value) const { |   7333 void ClosureData::set_hash(intptr_t value) const { | 
|   7685   StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value))); |   7334   StorePointer(&raw_ptr()->hash_, static_cast<RawObject*>(Smi::New(value))); | 
|   7686 } |   7335 } | 
|   7687  |   7336  | 
|   7688  |  | 
|   7689 void ClosureData::set_parent_function(const Function& value) const { |   7337 void ClosureData::set_parent_function(const Function& value) const { | 
|   7690   StorePointer(&raw_ptr()->parent_function_, value.raw()); |   7338   StorePointer(&raw_ptr()->parent_function_, value.raw()); | 
|   7691 } |   7339 } | 
|   7692  |   7340  | 
|   7693  |  | 
|   7694 void ClosureData::set_signature_type(const Type& value) const { |   7341 void ClosureData::set_signature_type(const Type& value) const { | 
|   7695   StorePointer(&raw_ptr()->signature_type_, value.raw()); |   7342   StorePointer(&raw_ptr()->signature_type_, value.raw()); | 
|   7696 } |   7343 } | 
|   7697  |   7344  | 
|   7698  |  | 
|   7699 RawClosureData* ClosureData::New() { |   7345 RawClosureData* ClosureData::New() { | 
|   7700   ASSERT(Object::closure_data_class() != Class::null()); |   7346   ASSERT(Object::closure_data_class() != Class::null()); | 
|   7701   RawObject* raw = Object::Allocate(ClosureData::kClassId, |   7347   RawObject* raw = Object::Allocate(ClosureData::kClassId, | 
|   7702                                     ClosureData::InstanceSize(), Heap::kOld); |   7348                                     ClosureData::InstanceSize(), Heap::kOld); | 
|   7703   return reinterpret_cast<RawClosureData*>(raw); |   7349   return reinterpret_cast<RawClosureData*>(raw); | 
|   7704 } |   7350 } | 
|   7705  |   7351  | 
|   7706  |  | 
|   7707 const char* ClosureData::ToCString() const { |   7352 const char* ClosureData::ToCString() const { | 
|   7708   if (IsNull()) { |   7353   if (IsNull()) { | 
|   7709     return "ClosureData: null"; |   7354     return "ClosureData: null"; | 
|   7710   } |   7355   } | 
|   7711   const Function& parent = Function::Handle(parent_function()); |   7356   const Function& parent = Function::Handle(parent_function()); | 
|   7712   const Type& type = Type::Handle(signature_type()); |   7357   const Type& type = Type::Handle(signature_type()); | 
|   7713   return OS::SCreate(Thread::Current()->zone(), |   7358   return OS::SCreate(Thread::Current()->zone(), | 
|   7714                      "ClosureData: context_scope: 0x%" Px |   7359                      "ClosureData: context_scope: 0x%" Px | 
|   7715                      " parent_function: %s signature_type: %s" |   7360                      " parent_function: %s signature_type: %s" | 
|   7716                      " implicit_static_closure: 0x%" Px, |   7361                      " implicit_static_closure: 0x%" Px, | 
|   7717                      reinterpret_cast<uword>(context_scope()), |   7362                      reinterpret_cast<uword>(context_scope()), | 
|   7718                      parent.IsNull() ? "null" : parent.ToCString(), |   7363                      parent.IsNull() ? "null" : parent.ToCString(), | 
|   7719                      type.IsNull() ? "null" : type.ToCString(), |   7364                      type.IsNull() ? "null" : type.ToCString(), | 
|   7720                      reinterpret_cast<uword>(implicit_static_closure())); |   7365                      reinterpret_cast<uword>(implicit_static_closure())); | 
|   7721 } |   7366 } | 
|   7722  |   7367  | 
|   7723  |  | 
|   7724 void SignatureData::set_parent_function(const Function& value) const { |   7368 void SignatureData::set_parent_function(const Function& value) const { | 
|   7725   StorePointer(&raw_ptr()->parent_function_, value.raw()); |   7369   StorePointer(&raw_ptr()->parent_function_, value.raw()); | 
|   7726 } |   7370 } | 
|   7727  |   7371  | 
|   7728  |  | 
|   7729 void SignatureData::set_signature_type(const Type& value) const { |   7372 void SignatureData::set_signature_type(const Type& value) const { | 
|   7730   StorePointer(&raw_ptr()->signature_type_, value.raw()); |   7373   StorePointer(&raw_ptr()->signature_type_, value.raw()); | 
|   7731 } |   7374 } | 
|   7732  |   7375  | 
|   7733  |  | 
|   7734 RawSignatureData* SignatureData::New(Heap::Space space) { |   7376 RawSignatureData* SignatureData::New(Heap::Space space) { | 
|   7735   ASSERT(Object::signature_data_class() != Class::null()); |   7377   ASSERT(Object::signature_data_class() != Class::null()); | 
|   7736   RawObject* raw = Object::Allocate(SignatureData::kClassId, |   7378   RawObject* raw = Object::Allocate(SignatureData::kClassId, | 
|   7737                                     SignatureData::InstanceSize(), space); |   7379                                     SignatureData::InstanceSize(), space); | 
|   7738   return reinterpret_cast<RawSignatureData*>(raw); |   7380   return reinterpret_cast<RawSignatureData*>(raw); | 
|   7739 } |   7381 } | 
|   7740  |   7382  | 
|   7741  |  | 
|   7742 const char* SignatureData::ToCString() const { |   7383 const char* SignatureData::ToCString() const { | 
|   7743   if (IsNull()) { |   7384   if (IsNull()) { | 
|   7744     return "SignatureData: null"; |   7385     return "SignatureData: null"; | 
|   7745   } |   7386   } | 
|   7746   const Function& parent = Function::Handle(parent_function()); |   7387   const Function& parent = Function::Handle(parent_function()); | 
|   7747   const Type& type = Type::Handle(signature_type()); |   7388   const Type& type = Type::Handle(signature_type()); | 
|   7748   return OS::SCreate(Thread::Current()->zone(), |   7389   return OS::SCreate(Thread::Current()->zone(), | 
|   7749                      "SignatureData parent_function: %s signature_type: %s", |   7390                      "SignatureData parent_function: %s signature_type: %s", | 
|   7750                      parent.IsNull() ? "null" : parent.ToCString(), |   7391                      parent.IsNull() ? "null" : parent.ToCString(), | 
|   7751                      type.IsNull() ? "null" : type.ToCString()); |   7392                      type.IsNull() ? "null" : type.ToCString()); | 
|   7752 } |   7393 } | 
|   7753  |   7394  | 
|   7754  |  | 
|   7755 void RedirectionData::set_type(const Type& value) const { |   7395 void RedirectionData::set_type(const Type& value) const { | 
|   7756   ASSERT(!value.IsNull()); |   7396   ASSERT(!value.IsNull()); | 
|   7757   StorePointer(&raw_ptr()->type_, value.raw()); |   7397   StorePointer(&raw_ptr()->type_, value.raw()); | 
|   7758 } |   7398 } | 
|   7759  |   7399  | 
|   7760  |  | 
|   7761 void RedirectionData::set_identifier(const String& value) const { |   7400 void RedirectionData::set_identifier(const String& value) const { | 
|   7762   StorePointer(&raw_ptr()->identifier_, value.raw()); |   7401   StorePointer(&raw_ptr()->identifier_, value.raw()); | 
|   7763 } |   7402 } | 
|   7764  |   7403  | 
|   7765  |  | 
|   7766 void RedirectionData::set_target(const Function& value) const { |   7404 void RedirectionData::set_target(const Function& value) const { | 
|   7767   StorePointer(&raw_ptr()->target_, value.raw()); |   7405   StorePointer(&raw_ptr()->target_, value.raw()); | 
|   7768 } |   7406 } | 
|   7769  |   7407  | 
|   7770  |  | 
|   7771 RawRedirectionData* RedirectionData::New() { |   7408 RawRedirectionData* RedirectionData::New() { | 
|   7772   ASSERT(Object::redirection_data_class() != Class::null()); |   7409   ASSERT(Object::redirection_data_class() != Class::null()); | 
|   7773   RawObject* raw = Object::Allocate( |   7410   RawObject* raw = Object::Allocate( | 
|   7774       RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld); |   7411       RedirectionData::kClassId, RedirectionData::InstanceSize(), Heap::kOld); | 
|   7775   return reinterpret_cast<RawRedirectionData*>(raw); |   7412   return reinterpret_cast<RawRedirectionData*>(raw); | 
|   7776 } |   7413 } | 
|   7777  |   7414  | 
|   7778  |  | 
|   7779 const char* RedirectionData::ToCString() const { |   7415 const char* RedirectionData::ToCString() const { | 
|   7780   if (IsNull()) { |   7416   if (IsNull()) { | 
|   7781     return "RedirectionData: null"; |   7417     return "RedirectionData: null"; | 
|   7782   } |   7418   } | 
|   7783   const Type& redir_type = Type::Handle(type()); |   7419   const Type& redir_type = Type::Handle(type()); | 
|   7784   const String& ident = String::Handle(identifier()); |   7420   const String& ident = String::Handle(identifier()); | 
|   7785   const Function& target_fun = Function::Handle(target()); |   7421   const Function& target_fun = Function::Handle(target()); | 
|   7786   return OS::SCreate(Thread::Current()->zone(), |   7422   return OS::SCreate(Thread::Current()->zone(), | 
|   7787                      "RedirectionData: type: %s identifier: %s target: %s", |   7423                      "RedirectionData: type: %s identifier: %s target: %s", | 
|   7788                      redir_type.IsNull() ? "null" : redir_type.ToCString(), |   7424                      redir_type.IsNull() ? "null" : redir_type.ToCString(), | 
|   7789                      ident.IsNull() ? "null" : ident.ToCString(), |   7425                      ident.IsNull() ? "null" : ident.ToCString(), | 
|   7790                      target_fun.IsNull() ? "null" : target_fun.ToCString()); |   7426                      target_fun.IsNull() ? "null" : target_fun.ToCString()); | 
|   7791 } |   7427 } | 
|   7792  |   7428  | 
|   7793  |  | 
|   7794 RawField* Field::CloneFromOriginal() const { |   7429 RawField* Field::CloneFromOriginal() const { | 
|   7795   return this->Clone(*this); |   7430   return this->Clone(*this); | 
|   7796 } |   7431 } | 
|   7797  |   7432  | 
|   7798  |  | 
|   7799 RawField* Field::Original() const { |   7433 RawField* Field::Original() const { | 
|   7800   if (IsNull()) { |   7434   if (IsNull()) { | 
|   7801     return Field::null(); |   7435     return Field::null(); | 
|   7802   } |   7436   } | 
|   7803   Object& obj = Object::Handle(raw_ptr()->owner_); |   7437   Object& obj = Object::Handle(raw_ptr()->owner_); | 
|   7804   if (obj.IsField()) { |   7438   if (obj.IsField()) { | 
|   7805     return Field::RawCast(obj.raw()); |   7439     return Field::RawCast(obj.raw()); | 
|   7806   } else { |   7440   } else { | 
|   7807     return this->raw(); |   7441     return this->raw(); | 
|   7808   } |   7442   } | 
|   7809 } |   7443 } | 
|   7810  |   7444  | 
|   7811  |  | 
|   7812 void Field::SetOriginal(const Field& value) const { |   7445 void Field::SetOriginal(const Field& value) const { | 
|   7813   ASSERT(value.IsOriginal()); |   7446   ASSERT(value.IsOriginal()); | 
|   7814   ASSERT(!value.IsNull()); |   7447   ASSERT(!value.IsNull()); | 
|   7815   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |   7448   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 
|   7816 } |   7449 } | 
|   7817  |   7450  | 
|   7818  |  | 
|   7819 RawString* Field::GetterName(const String& field_name) { |   7451 RawString* Field::GetterName(const String& field_name) { | 
|   7820   return String::Concat(Symbols::GetterPrefix(), field_name); |   7452   return String::Concat(Symbols::GetterPrefix(), field_name); | 
|   7821 } |   7453 } | 
|   7822  |   7454  | 
|   7823  |  | 
|   7824 RawString* Field::GetterSymbol(const String& field_name) { |   7455 RawString* Field::GetterSymbol(const String& field_name) { | 
|   7825   return Symbols::FromGet(Thread::Current(), field_name); |   7456   return Symbols::FromGet(Thread::Current(), field_name); | 
|   7826 } |   7457 } | 
|   7827  |   7458  | 
|   7828  |  | 
|   7829 RawString* Field::LookupGetterSymbol(const String& field_name) { |   7459 RawString* Field::LookupGetterSymbol(const String& field_name) { | 
|   7830   return Symbols::LookupFromGet(Thread::Current(), field_name); |   7460   return Symbols::LookupFromGet(Thread::Current(), field_name); | 
|   7831 } |   7461 } | 
|   7832  |   7462  | 
|   7833  |  | 
|   7834 RawString* Field::SetterName(const String& field_name) { |   7463 RawString* Field::SetterName(const String& field_name) { | 
|   7835   return String::Concat(Symbols::SetterPrefix(), field_name); |   7464   return String::Concat(Symbols::SetterPrefix(), field_name); | 
|   7836 } |   7465 } | 
|   7837  |   7466  | 
|   7838  |  | 
|   7839 RawString* Field::SetterSymbol(const String& field_name) { |   7467 RawString* Field::SetterSymbol(const String& field_name) { | 
|   7840   return Symbols::FromSet(Thread::Current(), field_name); |   7468   return Symbols::FromSet(Thread::Current(), field_name); | 
|   7841 } |   7469 } | 
|   7842  |   7470  | 
|   7843  |  | 
|   7844 RawString* Field::LookupSetterSymbol(const String& field_name) { |   7471 RawString* Field::LookupSetterSymbol(const String& field_name) { | 
|   7845   return Symbols::LookupFromSet(Thread::Current(), field_name); |   7472   return Symbols::LookupFromSet(Thread::Current(), field_name); | 
|   7846 } |   7473 } | 
|   7847  |   7474  | 
|   7848  |  | 
|   7849 RawString* Field::NameFromGetter(const String& getter_name) { |   7475 RawString* Field::NameFromGetter(const String& getter_name) { | 
|   7850   return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength, |   7476   return Symbols::New(Thread::Current(), getter_name, kGetterPrefixLength, | 
|   7851                       getter_name.Length() - kGetterPrefixLength); |   7477                       getter_name.Length() - kGetterPrefixLength); | 
|   7852 } |   7478 } | 
|   7853  |   7479  | 
|   7854  |  | 
|   7855 RawString* Field::NameFromSetter(const String& setter_name) { |   7480 RawString* Field::NameFromSetter(const String& setter_name) { | 
|   7856   return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength, |   7481   return Symbols::New(Thread::Current(), setter_name, kSetterPrefixLength, | 
|   7857                       setter_name.Length() - kSetterPrefixLength); |   7482                       setter_name.Length() - kSetterPrefixLength); | 
|   7858 } |   7483 } | 
|   7859  |   7484  | 
|   7860  |  | 
|   7861 bool Field::IsGetterName(const String& function_name) { |   7485 bool Field::IsGetterName(const String& function_name) { | 
|   7862   return function_name.StartsWith(Symbols::GetterPrefix()); |   7486   return function_name.StartsWith(Symbols::GetterPrefix()); | 
|   7863 } |   7487 } | 
|   7864  |   7488  | 
|   7865  |  | 
|   7866 bool Field::IsSetterName(const String& function_name) { |   7489 bool Field::IsSetterName(const String& function_name) { | 
|   7867   return function_name.StartsWith(Symbols::SetterPrefix()); |   7490   return function_name.StartsWith(Symbols::SetterPrefix()); | 
|   7868 } |   7491 } | 
|   7869  |   7492  | 
|   7870  |  | 
|   7871 void Field::set_name(const String& value) const { |   7493 void Field::set_name(const String& value) const { | 
|   7872   ASSERT(value.IsSymbol()); |   7494   ASSERT(value.IsSymbol()); | 
|   7873   ASSERT(IsOriginal()); |   7495   ASSERT(IsOriginal()); | 
|   7874   StorePointer(&raw_ptr()->name_, value.raw()); |   7496   StorePointer(&raw_ptr()->name_, value.raw()); | 
|   7875 } |   7497 } | 
|   7876  |   7498  | 
|   7877  |  | 
|   7878 RawObject* Field::RawOwner() const { |   7499 RawObject* Field::RawOwner() const { | 
|   7879   if (IsOriginal()) { |   7500   if (IsOriginal()) { | 
|   7880     return raw_ptr()->owner_; |   7501     return raw_ptr()->owner_; | 
|   7881   } else { |   7502   } else { | 
|   7882     const Field& field = Field::Handle(Original()); |   7503     const Field& field = Field::Handle(Original()); | 
|   7883     ASSERT(field.IsOriginal()); |   7504     ASSERT(field.IsOriginal()); | 
|   7884     ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField()); |   7505     ASSERT(!Object::Handle(field.raw_ptr()->owner_).IsField()); | 
|   7885     return field.raw_ptr()->owner_; |   7506     return field.raw_ptr()->owner_; | 
|   7886   } |   7507   } | 
|   7887 } |   7508 } | 
|   7888  |   7509  | 
|   7889  |  | 
|   7890 RawClass* Field::Owner() const { |   7510 RawClass* Field::Owner() const { | 
|   7891   const Field& field = Field::Handle(Original()); |   7511   const Field& field = Field::Handle(Original()); | 
|   7892   ASSERT(field.IsOriginal()); |   7512   ASSERT(field.IsOriginal()); | 
|   7893   const Object& obj = Object::Handle(field.raw_ptr()->owner_); |   7513   const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 
|   7894   if (obj.IsClass()) { |   7514   if (obj.IsClass()) { | 
|   7895     return Class::Cast(obj).raw(); |   7515     return Class::Cast(obj).raw(); | 
|   7896   } |   7516   } | 
|   7897   ASSERT(obj.IsPatchClass()); |   7517   ASSERT(obj.IsPatchClass()); | 
|   7898   return PatchClass::Cast(obj).patched_class(); |   7518   return PatchClass::Cast(obj).patched_class(); | 
|   7899 } |   7519 } | 
|   7900  |   7520  | 
|   7901  |  | 
|   7902 RawClass* Field::Origin() const { |   7521 RawClass* Field::Origin() const { | 
|   7903   const Field& field = Field::Handle(Original()); |   7522   const Field& field = Field::Handle(Original()); | 
|   7904   ASSERT(field.IsOriginal()); |   7523   ASSERT(field.IsOriginal()); | 
|   7905   const Object& obj = Object::Handle(field.raw_ptr()->owner_); |   7524   const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 
|   7906   if (obj.IsClass()) { |   7525   if (obj.IsClass()) { | 
|   7907     return Class::Cast(obj).raw(); |   7526     return Class::Cast(obj).raw(); | 
|   7908   } |   7527   } | 
|   7909   ASSERT(obj.IsPatchClass()); |   7528   ASSERT(obj.IsPatchClass()); | 
|   7910   return PatchClass::Cast(obj).origin_class(); |   7529   return PatchClass::Cast(obj).origin_class(); | 
|   7911 } |   7530 } | 
|   7912  |   7531  | 
|   7913  |  | 
|   7914 RawScript* Field::Script() const { |   7532 RawScript* Field::Script() const { | 
|   7915   // NOTE(turnidge): If you update this function, you probably want to |   7533   // NOTE(turnidge): If you update this function, you probably want to | 
|   7916   // update Class::PatchFieldsAndFunctions() at the same time. |   7534   // update Class::PatchFieldsAndFunctions() at the same time. | 
|   7917   const Field& field = Field::Handle(Original()); |   7535   const Field& field = Field::Handle(Original()); | 
|   7918   ASSERT(field.IsOriginal()); |   7536   ASSERT(field.IsOriginal()); | 
|   7919   const Object& obj = Object::Handle(field.raw_ptr()->owner_); |   7537   const Object& obj = Object::Handle(field.raw_ptr()->owner_); | 
|   7920   if (obj.IsClass()) { |   7538   if (obj.IsClass()) { | 
|   7921     return Class::Cast(obj).script(); |   7539     return Class::Cast(obj).script(); | 
|   7922   } |   7540   } | 
|   7923   ASSERT(obj.IsPatchClass()); |   7541   ASSERT(obj.IsPatchClass()); | 
|   7924   return PatchClass::Cast(obj).script(); |   7542   return PatchClass::Cast(obj).script(); | 
|   7925 } |   7543 } | 
|   7926  |   7544  | 
|   7927  |  | 
|   7928 // Called at finalization time |   7545 // Called at finalization time | 
|   7929 void Field::SetFieldType(const AbstractType& value) const { |   7546 void Field::SetFieldType(const AbstractType& value) const { | 
|   7930   ASSERT(Thread::Current()->IsMutatorThread()); |   7547   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   7931   ASSERT(IsOriginal()); |   7548   ASSERT(IsOriginal()); | 
|   7932   ASSERT(!value.IsNull()); |   7549   ASSERT(!value.IsNull()); | 
|   7933   if (value.raw() != type()) { |   7550   if (value.raw() != type()) { | 
|   7934     StorePointer(&raw_ptr()->type_, value.raw()); |   7551     StorePointer(&raw_ptr()->type_, value.raw()); | 
|   7935   } |   7552   } | 
|   7936 } |   7553 } | 
|   7937  |   7554  | 
|   7938  |  | 
|   7939 RawField* Field::New() { |   7555 RawField* Field::New() { | 
|   7940   ASSERT(Object::field_class() != Class::null()); |   7556   ASSERT(Object::field_class() != Class::null()); | 
|   7941   RawObject* raw = |   7557   RawObject* raw = | 
|   7942       Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld); |   7558       Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld); | 
|   7943   return reinterpret_cast<RawField*>(raw); |   7559   return reinterpret_cast<RawField*>(raw); | 
|   7944 } |   7560 } | 
|   7945  |   7561  | 
|   7946  |  | 
|   7947 void Field::InitializeNew(const Field& result, |   7562 void Field::InitializeNew(const Field& result, | 
|   7948                           const String& name, |   7563                           const String& name, | 
|   7949                           bool is_static, |   7564                           bool is_static, | 
|   7950                           bool is_final, |   7565                           bool is_final, | 
|   7951                           bool is_const, |   7566                           bool is_const, | 
|   7952                           bool is_reflectable, |   7567                           bool is_reflectable, | 
|   7953                           const Object& owner, |   7568                           const Object& owner, | 
|   7954                           TokenPosition token_pos) { |   7569                           TokenPosition token_pos) { | 
|   7955   result.set_name(name); |   7570   result.set_name(name); | 
|   7956   result.set_is_static(is_static); |   7571   result.set_is_static(is_static); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   7978   result.set_is_nullable(use_guarded_cid ? false : true); |   7593   result.set_is_nullable(use_guarded_cid ? false : true); | 
|   7979   result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |   7594   result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 
|   7980   // Presently, we only attempt to remember the list length for final fields. |   7595   // Presently, we only attempt to remember the list length for final fields. | 
|   7981   if (is_final && use_guarded_cid) { |   7596   if (is_final && use_guarded_cid) { | 
|   7982     result.set_guarded_list_length(Field::kUnknownFixedLength); |   7597     result.set_guarded_list_length(Field::kUnknownFixedLength); | 
|   7983   } else { |   7598   } else { | 
|   7984     result.set_guarded_list_length(Field::kNoFixedLength); |   7599     result.set_guarded_list_length(Field::kNoFixedLength); | 
|   7985   } |   7600   } | 
|   7986 } |   7601 } | 
|   7987  |   7602  | 
|   7988  |  | 
|   7989 RawField* Field::New(const String& name, |   7603 RawField* Field::New(const String& name, | 
|   7990                      bool is_static, |   7604                      bool is_static, | 
|   7991                      bool is_final, |   7605                      bool is_final, | 
|   7992                      bool is_const, |   7606                      bool is_const, | 
|   7993                      bool is_reflectable, |   7607                      bool is_reflectable, | 
|   7994                      const Object& owner, |   7608                      const Object& owner, | 
|   7995                      const AbstractType& type, |   7609                      const AbstractType& type, | 
|   7996                      TokenPosition token_pos) { |   7610                      TokenPosition token_pos) { | 
|   7997   ASSERT(!owner.IsNull()); |   7611   ASSERT(!owner.IsNull()); | 
|   7998   const Field& result = Field::Handle(Field::New()); |   7612   const Field& result = Field::Handle(Field::New()); | 
|   7999   InitializeNew(result, name, is_static, is_final, is_const, is_reflectable, |   7613   InitializeNew(result, name, is_static, is_final, is_const, is_reflectable, | 
|   8000                 owner, token_pos); |   7614                 owner, token_pos); | 
|   8001   result.SetFieldType(type); |   7615   result.SetFieldType(type); | 
|   8002   return result.raw(); |   7616   return result.raw(); | 
|   8003 } |   7617 } | 
|   8004  |   7618  | 
|   8005  |  | 
|   8006 RawField* Field::NewTopLevel(const String& name, |   7619 RawField* Field::NewTopLevel(const String& name, | 
|   8007                              bool is_final, |   7620                              bool is_final, | 
|   8008                              bool is_const, |   7621                              bool is_const, | 
|   8009                              const Object& owner, |   7622                              const Object& owner, | 
|   8010                              TokenPosition token_pos) { |   7623                              TokenPosition token_pos) { | 
|   8011   ASSERT(!owner.IsNull()); |   7624   ASSERT(!owner.IsNull()); | 
|   8012   const Field& result = Field::Handle(Field::New()); |   7625   const Field& result = Field::Handle(Field::New()); | 
|   8013   InitializeNew(result, name, true,       /* is_static */ |   7626   InitializeNew(result, name, true,       /* is_static */ | 
|   8014                 is_final, is_const, true, /* is_reflectable */ |   7627                 is_final, is_const, true, /* is_reflectable */ | 
|   8015                 owner, token_pos); |   7628                 owner, token_pos); | 
|   8016   return result.raw(); |   7629   return result.raw(); | 
|   8017 } |   7630 } | 
|   8018  |   7631  | 
|   8019  |  | 
|   8020 RawField* Field::Clone(const Class& new_owner) const { |   7632 RawField* Field::Clone(const Class& new_owner) const { | 
|   8021   Field& clone = Field::Handle(); |   7633   Field& clone = Field::Handle(); | 
|   8022   clone ^= Object::Clone(*this, Heap::kOld); |   7634   clone ^= Object::Clone(*this, Heap::kOld); | 
|   8023   const Class& owner = Class::Handle(this->Owner()); |   7635   const Class& owner = Class::Handle(this->Owner()); | 
|   8024   const PatchClass& clone_owner = |   7636   const PatchClass& clone_owner = | 
|   8025       PatchClass::Handle(PatchClass::New(new_owner, owner)); |   7637       PatchClass::Handle(PatchClass::New(new_owner, owner)); | 
|   8026   clone.set_owner(clone_owner); |   7638   clone.set_owner(clone_owner); | 
|   8027   if (!clone.is_static()) { |   7639   if (!clone.is_static()) { | 
|   8028     clone.SetOffset(0); |   7640     clone.SetOffset(0); | 
|   8029   } |   7641   } | 
|   8030   if (new_owner.NumTypeParameters() > 0) { |   7642   if (new_owner.NumTypeParameters() > 0) { | 
|   8031     // Adjust the field type to refer to type parameters of the new owner. |   7643     // Adjust the field type to refer to type parameters of the new owner. | 
|   8032     AbstractType& type = AbstractType::Handle(clone.type()); |   7644     AbstractType& type = AbstractType::Handle(clone.type()); | 
|   8033     type ^= type.CloneUninstantiated(new_owner); |   7645     type ^= type.CloneUninstantiated(new_owner); | 
|   8034     clone.SetFieldType(type); |   7646     clone.SetFieldType(type); | 
|   8035   } |   7647   } | 
|   8036   return clone.raw(); |   7648   return clone.raw(); | 
|   8037 } |   7649 } | 
|   8038  |   7650  | 
|   8039  |  | 
|   8040 RawField* Field::Clone(const Field& original) const { |   7651 RawField* Field::Clone(const Field& original) const { | 
|   8041   if (original.IsNull()) { |   7652   if (original.IsNull()) { | 
|   8042     return Field::null(); |   7653     return Field::null(); | 
|   8043   } |   7654   } | 
|   8044   ASSERT(original.IsOriginal()); |   7655   ASSERT(original.IsOriginal()); | 
|   8045   Field& clone = Field::Handle(); |   7656   Field& clone = Field::Handle(); | 
|   8046   clone ^= Object::Clone(*this, Heap::kOld); |   7657   clone ^= Object::Clone(*this, Heap::kOld); | 
|   8047   clone.SetOriginal(original); |   7658   clone.SetOriginal(original); | 
|   8048   clone.set_kernel_offset(original.kernel_offset()); |   7659   clone.set_kernel_offset(original.kernel_offset()); | 
|   8049   return clone.raw(); |   7660   return clone.raw(); | 
|   8050 } |   7661 } | 
|   8051  |   7662  | 
|   8052  |  | 
|   8053 RawString* Field::InitializingExpression() const { |   7663 RawString* Field::InitializingExpression() const { | 
|   8054   Thread* thread = Thread::Current(); |   7664   Thread* thread = Thread::Current(); | 
|   8055   Zone* zone = thread->zone(); |   7665   Zone* zone = thread->zone(); | 
|   8056   const class Script& scr = Script::Handle(zone, Script()); |   7666   const class Script& scr = Script::Handle(zone, Script()); | 
|   8057   ASSERT(!scr.IsNull()); |   7667   ASSERT(!scr.IsNull()); | 
|   8058   const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens()); |   7668   const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens()); | 
|   8059   if (tkns.IsNull()) { |   7669   if (tkns.IsNull()) { | 
|   8060     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |   7670     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|   8061     return String::null(); |   7671     return String::null(); | 
|   8062   } |   7672   } | 
|   8063   TokenStream::Iterator tkit(zone, tkns, token_pos()); |   7673   TokenStream::Iterator tkit(zone, tkns, token_pos()); | 
|   8064   ASSERT(Token::IsIdentifier(tkit.CurrentTokenKind())); |   7674   ASSERT(Token::IsIdentifier(tkit.CurrentTokenKind())); | 
|   8065 #if defined(DEBUG) |   7675 #if defined(DEBUG) | 
|   8066   const String& literal = String::Handle(zone, tkit.CurrentLiteral()); |   7676   const String& literal = String::Handle(zone, tkit.CurrentLiteral()); | 
|   8067   ASSERT(literal.raw() == name()); |   7677   ASSERT(literal.raw() == name()); | 
|   8068 #endif |   7678 #endif | 
|   8069   tkit.Advance(); |   7679   tkit.Advance(); | 
|   8070   if (tkit.CurrentTokenKind() != Token::kASSIGN) { |   7680   if (tkit.CurrentTokenKind() != Token::kASSIGN) { | 
|   8071     return String::null(); |   7681     return String::null(); | 
|   8072   } |   7682   } | 
|   8073   tkit.Advance(); |   7683   tkit.Advance(); | 
|   8074   const TokenPosition start_of_expression = tkit.CurrentPosition(); |   7684   const TokenPosition start_of_expression = tkit.CurrentPosition(); | 
|   8075   while (tkit.CurrentTokenKind() != Token::kSEMICOLON) { |   7685   while (tkit.CurrentTokenKind() != Token::kSEMICOLON) { | 
|   8076     tkit.Advance(); |   7686     tkit.Advance(); | 
|   8077   } |   7687   } | 
|   8078   const TokenPosition end_of_expression = tkit.CurrentPosition(); |   7688   const TokenPosition end_of_expression = tkit.CurrentPosition(); | 
|   8079   return scr.GetSnippet(start_of_expression, end_of_expression); |   7689   return scr.GetSnippet(start_of_expression, end_of_expression); | 
|   8080 } |   7690 } | 
|   8081  |   7691  | 
|   8082  |  | 
|   8083 RawString* Field::UserVisibleName() const { |   7692 RawString* Field::UserVisibleName() const { | 
|   8084   if (FLAG_show_internal_names) { |   7693   if (FLAG_show_internal_names) { | 
|   8085     return name(); |   7694     return name(); | 
|   8086   } |   7695   } | 
|   8087   return String::ScrubName(String::Handle(name())); |   7696   return String::ScrubName(String::Handle(name())); | 
|   8088 } |   7697 } | 
|   8089  |   7698  | 
|   8090  |  | 
|   8091 intptr_t Field::guarded_list_length() const { |   7699 intptr_t Field::guarded_list_length() const { | 
|   8092   return Smi::Value(raw_ptr()->guarded_list_length_); |   7700   return Smi::Value(raw_ptr()->guarded_list_length_); | 
|   8093 } |   7701 } | 
|   8094  |   7702  | 
|   8095  |  | 
|   8096 void Field::set_guarded_list_length(intptr_t list_length) const { |   7703 void Field::set_guarded_list_length(intptr_t list_length) const { | 
|   8097   ASSERT(Thread::Current()->IsMutatorThread()); |   7704   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   8098   ASSERT(IsOriginal()); |   7705   ASSERT(IsOriginal()); | 
|   8099   StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length)); |   7706   StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length)); | 
|   8100 } |   7707 } | 
|   8101  |   7708  | 
|   8102  |  | 
|   8103 intptr_t Field::guarded_list_length_in_object_offset() const { |   7709 intptr_t Field::guarded_list_length_in_object_offset() const { | 
|   8104   return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag; |   7710   return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag; | 
|   8105 } |   7711 } | 
|   8106  |   7712  | 
|   8107  |  | 
|   8108 void Field::set_guarded_list_length_in_object_offset( |   7713 void Field::set_guarded_list_length_in_object_offset( | 
|   8109     intptr_t list_length_offset) const { |   7714     intptr_t list_length_offset) const { | 
|   8110   ASSERT(Thread::Current()->IsMutatorThread()); |   7715   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   8111   ASSERT(IsOriginal()); |   7716   ASSERT(IsOriginal()); | 
|   8112   StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_, |   7717   StoreNonPointer(&raw_ptr()->guarded_list_length_in_object_offset_, | 
|   8113                   static_cast<int8_t>(list_length_offset - kHeapObjectTag)); |   7718                   static_cast<int8_t>(list_length_offset - kHeapObjectTag)); | 
|   8114   ASSERT(guarded_list_length_in_object_offset() == list_length_offset); |   7719   ASSERT(guarded_list_length_in_object_offset() == list_length_offset); | 
|   8115 } |   7720 } | 
|   8116  |   7721  | 
|   8117  |  | 
|   8118 const char* Field::ToCString() const { |   7722 const char* Field::ToCString() const { | 
|   8119   if (IsNull()) { |   7723   if (IsNull()) { | 
|   8120     return "Field: null"; |   7724     return "Field: null"; | 
|   8121   } |   7725   } | 
|   8122   const char* kF0 = is_static() ? " static" : ""; |   7726   const char* kF0 = is_static() ? " static" : ""; | 
|   8123   const char* kF1 = is_final() ? " final" : ""; |   7727   const char* kF1 = is_final() ? " final" : ""; | 
|   8124   const char* kF2 = is_const() ? " const" : ""; |   7728   const char* kF2 = is_const() ? " const" : ""; | 
|   8125   const char* field_name = String::Handle(name()).ToCString(); |   7729   const char* field_name = String::Handle(name()).ToCString(); | 
|   8126   const Class& cls = Class::Handle(Owner()); |   7730   const Class& cls = Class::Handle(Owner()); | 
|   8127   const char* cls_name = String::Handle(cls.Name()).ToCString(); |   7731   const char* cls_name = String::Handle(cls.Name()).ToCString(); | 
|   8128   return OS::SCreate(Thread::Current()->zone(), "Field <%s.%s>:%s%s%s", |   7732   return OS::SCreate(Thread::Current()->zone(), "Field <%s.%s>:%s%s%s", | 
|   8129                      cls_name, field_name, kF0, kF1, kF2); |   7733                      cls_name, field_name, kF0, kF1, kF2); | 
|   8130 } |   7734 } | 
|   8131  |   7735  | 
|   8132  |  | 
|   8133 // Build a closure object that gets (or sets) the contents of a static |   7736 // Build a closure object that gets (or sets) the contents of a static | 
|   8134 // field f and cache the closure in a newly created static field |   7737 // field f and cache the closure in a newly created static field | 
|   8135 // named #f (or #f= in case of a setter). |   7738 // named #f (or #f= in case of a setter). | 
|   8136 RawInstance* Field::AccessorClosure(bool make_setter) const { |   7739 RawInstance* Field::AccessorClosure(bool make_setter) const { | 
|   8137   Thread* thread = Thread::Current(); |   7740   Thread* thread = Thread::Current(); | 
|   8138   Zone* zone = thread->zone(); |   7741   Zone* zone = thread->zone(); | 
|   8139   ASSERT(is_static()); |   7742   ASSERT(is_static()); | 
|   8140   const Class& field_owner = Class::Handle(zone, Owner()); |   7743   const Class& field_owner = Class::Handle(zone, Owner()); | 
|   8141  |   7744  | 
|   8142   String& closure_name = String::Handle(zone, this->name()); |   7745   String& closure_name = String::Handle(zone, this->name()); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8181                  true,   // is_final |   7784                  true,   // is_final | 
|   8182                  true,   // is_const |   7785                  true,   // is_const | 
|   8183                  false,  // is_reflectable |   7786                  false,  // is_reflectable | 
|   8184                  field_owner, Object::dynamic_type(), this->token_pos()); |   7787                  field_owner, Object::dynamic_type(), this->token_pos()); | 
|   8185   closure_field.SetStaticValue(Instance::Cast(result), true); |   7788   closure_field.SetStaticValue(Instance::Cast(result), true); | 
|   8186   field_owner.AddField(closure_field); |   7789   field_owner.AddField(closure_field); | 
|   8187  |   7790  | 
|   8188   return Instance::RawCast(result.raw()); |   7791   return Instance::RawCast(result.raw()); | 
|   8189 } |   7792 } | 
|   8190  |   7793  | 
|   8191  |  | 
|   8192 RawInstance* Field::GetterClosure() const { |   7794 RawInstance* Field::GetterClosure() const { | 
|   8193   return AccessorClosure(false); |   7795   return AccessorClosure(false); | 
|   8194 } |   7796 } | 
|   8195  |   7797  | 
|   8196  |  | 
|   8197 RawInstance* Field::SetterClosure() const { |   7798 RawInstance* Field::SetterClosure() const { | 
|   8198   return AccessorClosure(true); |   7799   return AccessorClosure(true); | 
|   8199 } |   7800 } | 
|   8200  |   7801  | 
|   8201  |  | 
|   8202 RawArray* Field::dependent_code() const { |   7802 RawArray* Field::dependent_code() const { | 
|   8203   return raw_ptr()->dependent_code_; |   7803   return raw_ptr()->dependent_code_; | 
|   8204 } |   7804 } | 
|   8205  |   7805  | 
|   8206  |  | 
|   8207 void Field::set_dependent_code(const Array& array) const { |   7806 void Field::set_dependent_code(const Array& array) const { | 
|   8208   ASSERT(IsOriginal()); |   7807   ASSERT(IsOriginal()); | 
|   8209   StorePointer(&raw_ptr()->dependent_code_, array.raw()); |   7808   StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 
|   8210 } |   7809 } | 
|   8211  |   7810  | 
|   8212  |  | 
|   8213 class FieldDependentArray : public WeakCodeReferences { |   7811 class FieldDependentArray : public WeakCodeReferences { | 
|   8214  public: |   7812  public: | 
|   8215   explicit FieldDependentArray(const Field& field) |   7813   explicit FieldDependentArray(const Field& field) | 
|   8216       : WeakCodeReferences(Array::Handle(field.dependent_code())), |   7814       : WeakCodeReferences(Array::Handle(field.dependent_code())), | 
|   8217         field_(field) {} |   7815         field_(field) {} | 
|   8218  |   7816  | 
|   8219   virtual void UpdateArrayTo(const Array& value) { |   7817   virtual void UpdateArrayTo(const Array& value) { | 
|   8220     field_.set_dependent_code(value); |   7818     field_.set_dependent_code(value); | 
|   8221   } |   7819   } | 
|   8222  |   7820  | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   8236           " on field '%s' was violated.\n", |   7834           " on field '%s' was violated.\n", | 
|   8237           function.ToFullyQualifiedCString(), field_.ToCString()); |   7835           function.ToFullyQualifiedCString(), field_.ToCString()); | 
|   8238     } |   7836     } | 
|   8239   } |   7837   } | 
|   8240  |   7838  | 
|   8241  private: |   7839  private: | 
|   8242   const Field& field_; |   7840   const Field& field_; | 
|   8243   DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); |   7841   DISALLOW_COPY_AND_ASSIGN(FieldDependentArray); | 
|   8244 }; |   7842 }; | 
|   8245  |   7843  | 
|   8246  |  | 
|   8247 void Field::RegisterDependentCode(const Code& code) const { |   7844 void Field::RegisterDependentCode(const Code& code) const { | 
|   8248   ASSERT(IsOriginal()); |   7845   ASSERT(IsOriginal()); | 
|   8249   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |   7846   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|   8250   ASSERT(code.is_optimized()); |   7847   ASSERT(code.is_optimized()); | 
|   8251   FieldDependentArray a(*this); |   7848   FieldDependentArray a(*this); | 
|   8252   a.Register(code); |   7849   a.Register(code); | 
|   8253 } |   7850 } | 
|   8254  |   7851  | 
|   8255  |  | 
|   8256 void Field::DeoptimizeDependentCode() const { |   7852 void Field::DeoptimizeDependentCode() const { | 
|   8257   ASSERT(Thread::Current()->IsMutatorThread()); |   7853   ASSERT(Thread::Current()->IsMutatorThread()); | 
|   8258   ASSERT(IsOriginal()); |   7854   ASSERT(IsOriginal()); | 
|   8259   FieldDependentArray a(*this); |   7855   FieldDependentArray a(*this); | 
|   8260   a.DisableCode(); |   7856   a.DisableCode(); | 
|   8261 } |   7857 } | 
|   8262  |   7858  | 
|   8263  |  | 
|   8264 bool Field::IsConsistentWith(const Field& other) const { |   7859 bool Field::IsConsistentWith(const Field& other) const { | 
|   8265   return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) && |   7860   return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) && | 
|   8266          (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) && |   7861          (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) && | 
|   8267          (raw_ptr()->guarded_list_length_ == |   7862          (raw_ptr()->guarded_list_length_ == | 
|   8268           other.raw_ptr()->guarded_list_length_) && |   7863           other.raw_ptr()->guarded_list_length_) && | 
|   8269          (is_unboxing_candidate() == other.is_unboxing_candidate()); |   7864          (is_unboxing_candidate() == other.is_unboxing_candidate()); | 
|   8270 } |   7865 } | 
|   8271  |   7866  | 
|   8272  |  | 
|   8273 bool Field::IsUninitialized() const { |   7867 bool Field::IsUninitialized() const { | 
|   8274   const Instance& value = Instance::Handle(raw_ptr()->value_.static_value_); |   7868   const Instance& value = Instance::Handle(raw_ptr()->value_.static_value_); | 
|   8275   ASSERT(value.raw() != Object::transition_sentinel().raw()); |   7869   ASSERT(value.raw() != Object::transition_sentinel().raw()); | 
|   8276   return value.raw() == Object::sentinel().raw(); |   7870   return value.raw() == Object::sentinel().raw(); | 
|   8277 } |   7871 } | 
|   8278  |   7872  | 
|   8279  |  | 
|   8280 void Field::SetPrecompiledInitializer(const Function& initializer) const { |   7873 void Field::SetPrecompiledInitializer(const Function& initializer) const { | 
|   8281   ASSERT(IsOriginal()); |   7874   ASSERT(IsOriginal()); | 
|   8282   StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw()); |   7875   StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw()); | 
|   8283 } |   7876 } | 
|   8284  |   7877  | 
|   8285  |  | 
|   8286 bool Field::HasPrecompiledInitializer() const { |   7878 bool Field::HasPrecompiledInitializer() const { | 
|   8287   return raw_ptr()->initializer_.precompiled_->IsHeapObject() && |   7879   return raw_ptr()->initializer_.precompiled_->IsHeapObject() && | 
|   8288          raw_ptr()->initializer_.precompiled_->IsFunction(); |   7880          raw_ptr()->initializer_.precompiled_->IsFunction(); | 
|   8289 } |   7881 } | 
|   8290  |   7882  | 
|   8291  |  | 
|   8292 void Field::SetSavedInitialStaticValue(const Instance& value) const { |   7883 void Field::SetSavedInitialStaticValue(const Instance& value) const { | 
|   8293   ASSERT(IsOriginal()); |   7884   ASSERT(IsOriginal()); | 
|   8294   ASSERT(!HasPrecompiledInitializer()); |   7885   ASSERT(!HasPrecompiledInitializer()); | 
|   8295   StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw()); |   7886   StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw()); | 
|   8296 } |   7887 } | 
|   8297  |   7888  | 
|   8298  |  | 
|   8299 void Field::EvaluateInitializer() const { |   7889 void Field::EvaluateInitializer() const { | 
|   8300   ASSERT(IsOriginal()); |   7890   ASSERT(IsOriginal()); | 
|   8301   ASSERT(is_static()); |   7891   ASSERT(is_static()); | 
|   8302   if (StaticValue() == Object::sentinel().raw()) { |   7892   if (StaticValue() == Object::sentinel().raw()) { | 
|   8303     SetStaticValue(Object::transition_sentinel()); |   7893     SetStaticValue(Object::transition_sentinel()); | 
|   8304     const Object& value = |   7894     const Object& value = | 
|   8305         Object::Handle(Compiler::EvaluateStaticInitializer(*this)); |   7895         Object::Handle(Compiler::EvaluateStaticInitializer(*this)); | 
|   8306     if (value.IsError()) { |   7896     if (value.IsError()) { | 
|   8307       SetStaticValue(Object::null_instance()); |   7897       SetStaticValue(Object::null_instance()); | 
|   8308       Exceptions::PropagateError(Error::Cast(value)); |   7898       Exceptions::PropagateError(Error::Cast(value)); | 
|   8309       UNREACHABLE(); |   7899       UNREACHABLE(); | 
|   8310     } |   7900     } | 
|   8311     ASSERT(value.IsNull() || value.IsInstance()); |   7901     ASSERT(value.IsNull() || value.IsInstance()); | 
|   8312     SetStaticValue(value.IsNull() ? Instance::null_instance() |   7902     SetStaticValue(value.IsNull() ? Instance::null_instance() | 
|   8313                                   : Instance::Cast(value)); |   7903                                   : Instance::Cast(value)); | 
|   8314     return; |   7904     return; | 
|   8315   } else if (StaticValue() == Object::transition_sentinel().raw()) { |   7905   } else if (StaticValue() == Object::transition_sentinel().raw()) { | 
|   8316     const Array& ctor_args = Array::Handle(Array::New(1)); |   7906     const Array& ctor_args = Array::Handle(Array::New(1)); | 
|   8317     const String& field_name = String::Handle(name()); |   7907     const String& field_name = String::Handle(name()); | 
|   8318     ctor_args.SetAt(0, field_name); |   7908     ctor_args.SetAt(0, field_name); | 
|   8319     Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args); |   7909     Exceptions::ThrowByType(Exceptions::kCyclicInitializationError, ctor_args); | 
|   8320     UNREACHABLE(); |   7910     UNREACHABLE(); | 
|   8321     return; |   7911     return; | 
|   8322   } |   7912   } | 
|   8323   UNREACHABLE(); |   7913   UNREACHABLE(); | 
|   8324 } |   7914 } | 
|   8325  |   7915  | 
|   8326  |  | 
|   8327 static intptr_t GetListLength(const Object& value) { |   7916 static intptr_t GetListLength(const Object& value) { | 
|   8328   if (value.IsTypedData()) { |   7917   if (value.IsTypedData()) { | 
|   8329     const TypedData& list = TypedData::Cast(value); |   7918     const TypedData& list = TypedData::Cast(value); | 
|   8330     return list.Length(); |   7919     return list.Length(); | 
|   8331   } else if (value.IsArray()) { |   7920   } else if (value.IsArray()) { | 
|   8332     const Array& list = Array::Cast(value); |   7921     const Array& list = Array::Cast(value); | 
|   8333     return list.Length(); |   7922     return list.Length(); | 
|   8334   } else if (value.IsGrowableObjectArray()) { |   7923   } else if (value.IsGrowableObjectArray()) { | 
|   8335     // List length is variable. |   7924     // List length is variable. | 
|   8336     return Field::kNoFixedLength; |   7925     return Field::kNoFixedLength; | 
|   8337   } else if (value.IsExternalTypedData()) { |   7926   } else if (value.IsExternalTypedData()) { | 
|   8338     // TODO(johnmccutchan): Enable for external typed data. |   7927     // TODO(johnmccutchan): Enable for external typed data. | 
|   8339     return Field::kNoFixedLength; |   7928     return Field::kNoFixedLength; | 
|   8340   } else if (RawObject::IsTypedDataViewClassId(value.GetClassId())) { |   7929   } else if (RawObject::IsTypedDataViewClassId(value.GetClassId())) { | 
|   8341     // TODO(johnmccutchan): Enable for typed data views. |   7930     // TODO(johnmccutchan): Enable for typed data views. | 
|   8342     return Field::kNoFixedLength; |   7931     return Field::kNoFixedLength; | 
|   8343   } |   7932   } | 
|   8344   return Field::kNoFixedLength; |   7933   return Field::kNoFixedLength; | 
|   8345 } |   7934 } | 
|   8346  |   7935  | 
|   8347  |  | 
|   8348 static intptr_t GetListLengthOffset(intptr_t cid) { |   7936 static intptr_t GetListLengthOffset(intptr_t cid) { | 
|   8349   if (RawObject::IsTypedDataClassId(cid)) { |   7937   if (RawObject::IsTypedDataClassId(cid)) { | 
|   8350     return TypedData::length_offset(); |   7938     return TypedData::length_offset(); | 
|   8351   } else if (cid == kArrayCid || cid == kImmutableArrayCid) { |   7939   } else if (cid == kArrayCid || cid == kImmutableArrayCid) { | 
|   8352     return Array::length_offset(); |   7940     return Array::length_offset(); | 
|   8353   } else if (cid == kGrowableObjectArrayCid) { |   7941   } else if (cid == kGrowableObjectArrayCid) { | 
|   8354     // List length is variable. |   7942     // List length is variable. | 
|   8355     return Field::kUnknownLengthOffset; |   7943     return Field::kUnknownLengthOffset; | 
|   8356   } else if (RawObject::IsExternalTypedDataClassId(cid)) { |   7944   } else if (RawObject::IsExternalTypedDataClassId(cid)) { | 
|   8357     // TODO(johnmccutchan): Enable for external typed data. |   7945     // TODO(johnmccutchan): Enable for external typed data. | 
|   8358     return Field::kUnknownLengthOffset; |   7946     return Field::kUnknownLengthOffset; | 
|   8359   } else if (RawObject::IsTypedDataViewClassId(cid)) { |   7947   } else if (RawObject::IsTypedDataViewClassId(cid)) { | 
|   8360     // TODO(johnmccutchan): Enable for typed data views. |   7948     // TODO(johnmccutchan): Enable for typed data views. | 
|   8361     return Field::kUnknownLengthOffset; |   7949     return Field::kUnknownLengthOffset; | 
|   8362   } |   7950   } | 
|   8363   return Field::kUnknownLengthOffset; |   7951   return Field::kUnknownLengthOffset; | 
|   8364 } |   7952 } | 
|   8365  |   7953  | 
|   8366  |  | 
|   8367 const char* Field::GuardedPropertiesAsCString() const { |   7954 const char* Field::GuardedPropertiesAsCString() const { | 
|   8368   if (guarded_cid() == kIllegalCid) { |   7955   if (guarded_cid() == kIllegalCid) { | 
|   8369     return "<?>"; |   7956     return "<?>"; | 
|   8370   } else if (guarded_cid() == kDynamicCid) { |   7957   } else if (guarded_cid() == kDynamicCid) { | 
|   8371     return "<*>"; |   7958     return "<*>"; | 
|   8372   } |   7959   } | 
|   8373  |   7960  | 
|   8374   const Class& cls = |   7961   const Class& cls = | 
|   8375       Class::Handle(Isolate::Current()->class_table()->At(guarded_cid())); |   7962       Class::Handle(Isolate::Current()->class_table()->At(guarded_cid())); | 
|   8376   const char* class_name = String::Handle(cls.Name()).ToCString(); |   7963   const char* class_name = String::Handle(cls.Name()).ToCString(); | 
|   8377  |   7964  | 
|   8378   if (RawObject::IsBuiltinListClassId(guarded_cid()) && !is_nullable() && |   7965   if (RawObject::IsBuiltinListClassId(guarded_cid()) && !is_nullable() && | 
|   8379       is_final()) { |   7966       is_final()) { | 
|   8380     ASSERT(guarded_list_length() != kUnknownFixedLength); |   7967     ASSERT(guarded_list_length() != kUnknownFixedLength); | 
|   8381     if (guarded_list_length() == kNoFixedLength) { |   7968     if (guarded_list_length() == kNoFixedLength) { | 
|   8382       return Thread::Current()->zone()->PrintToString("<%s [*]>", class_name); |   7969       return Thread::Current()->zone()->PrintToString("<%s [*]>", class_name); | 
|   8383     } else { |   7970     } else { | 
|   8384       return Thread::Current()->zone()->PrintToString( |   7971       return Thread::Current()->zone()->PrintToString( | 
|   8385           "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), |   7972           "<%s [%" Pd " @%" Pd "]>", class_name, guarded_list_length(), | 
|   8386           guarded_list_length_in_object_offset()); |   7973           guarded_list_length_in_object_offset()); | 
|   8387     } |   7974     } | 
|   8388   } |   7975   } | 
|   8389  |   7976  | 
|   8390   return Thread::Current()->zone()->PrintToString( |   7977   return Thread::Current()->zone()->PrintToString( | 
|   8391       "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); |   7978       "<%s %s>", is_nullable() ? "nullable" : "not-nullable", class_name); | 
|   8392 } |   7979 } | 
|   8393  |   7980  | 
|   8394  |  | 
|   8395 bool Field::IsExternalizableCid(intptr_t cid) { |   7981 bool Field::IsExternalizableCid(intptr_t cid) { | 
|   8396   if (FLAG_support_externalizable_strings) { |   7982   if (FLAG_support_externalizable_strings) { | 
|   8397     return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid); |   7983     return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid); | 
|   8398   } else { |   7984   } else { | 
|   8399     return false; |   7985     return false; | 
|   8400   } |   7986   } | 
|   8401 } |   7987 } | 
|   8402  |   7988  | 
|   8403  |  | 
|   8404 void Field::InitializeGuardedListLengthInObjectOffset() const { |   7989 void Field::InitializeGuardedListLengthInObjectOffset() const { | 
|   8405   ASSERT(IsOriginal()); |   7990   ASSERT(IsOriginal()); | 
|   8406   if (needs_length_check() && |   7991   if (needs_length_check() && | 
|   8407       (guarded_list_length() != Field::kUnknownFixedLength)) { |   7992       (guarded_list_length() != Field::kUnknownFixedLength)) { | 
|   8408     const intptr_t offset = GetListLengthOffset(guarded_cid()); |   7993     const intptr_t offset = GetListLengthOffset(guarded_cid()); | 
|   8409     set_guarded_list_length_in_object_offset(offset); |   7994     set_guarded_list_length_in_object_offset(offset); | 
|   8410     ASSERT(offset != Field::kUnknownLengthOffset); |   7995     ASSERT(offset != Field::kUnknownLengthOffset); | 
|   8411   } else { |   7996   } else { | 
|   8412     set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |   7997     set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 
|   8413   } |   7998   } | 
|   8414 } |   7999 } | 
|   8415  |   8000  | 
|   8416  |  | 
|   8417 bool Field::UpdateGuardedCidAndLength(const Object& value) const { |   8001 bool Field::UpdateGuardedCidAndLength(const Object& value) const { | 
|   8418   ASSERT(IsOriginal()); |   8002   ASSERT(IsOriginal()); | 
|   8419   const intptr_t cid = value.GetClassId(); |   8003   const intptr_t cid = value.GetClassId(); | 
|   8420  |   8004  | 
|   8421   if (guarded_cid() == kIllegalCid) { |   8005   if (guarded_cid() == kIllegalCid) { | 
|   8422     // Field is assigned first time. |   8006     // Field is assigned first time. | 
|   8423     set_guarded_cid(cid); |   8007     set_guarded_cid(cid); | 
|   8424     set_is_nullable(cid == kNullCid); |   8008     set_is_nullable(cid == kNullCid); | 
|   8425  |   8009  | 
|   8426     // Start tracking length if needed. |   8010     // Start tracking length if needed. | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8474   if (needs_length_check()) { |   8058   if (needs_length_check()) { | 
|   8475     ASSERT(guarded_list_length() != Field::kUnknownFixedLength); |   8059     ASSERT(guarded_list_length() != Field::kUnknownFixedLength); | 
|   8476     set_guarded_list_length(Field::kNoFixedLength); |   8060     set_guarded_list_length(Field::kNoFixedLength); | 
|   8477     set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |   8061     set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 
|   8478   } |   8062   } | 
|   8479  |   8063  | 
|   8480   // Expected class id or nullability of the field changed. |   8064   // Expected class id or nullability of the field changed. | 
|   8481   return true; |   8065   return true; | 
|   8482 } |   8066 } | 
|   8483  |   8067  | 
|   8484  |  | 
|   8485 void Field::RecordStore(const Object& value) const { |   8068 void Field::RecordStore(const Object& value) const { | 
|   8486   ASSERT(IsOriginal()); |   8069   ASSERT(IsOriginal()); | 
|   8487   if (!Isolate::Current()->use_field_guards()) { |   8070   if (!Isolate::Current()->use_field_guards()) { | 
|   8488     return; |   8071     return; | 
|   8489   } |   8072   } | 
|   8490  |   8073  | 
|   8491   if (FLAG_trace_field_guards) { |   8074   if (FLAG_trace_field_guards) { | 
|   8492     THR_Print("Store %s %s <- %s\n", ToCString(), GuardedPropertiesAsCString(), |   8075     THR_Print("Store %s %s <- %s\n", ToCString(), GuardedPropertiesAsCString(), | 
|   8493               value.ToCString()); |   8076               value.ToCString()); | 
|   8494   } |   8077   } | 
|   8495  |   8078  | 
|   8496   if (UpdateGuardedCidAndLength(value)) { |   8079   if (UpdateGuardedCidAndLength(value)) { | 
|   8497     if (FLAG_trace_field_guards) { |   8080     if (FLAG_trace_field_guards) { | 
|   8498       THR_Print("    => %s\n", GuardedPropertiesAsCString()); |   8081       THR_Print("    => %s\n", GuardedPropertiesAsCString()); | 
|   8499     } |   8082     } | 
|   8500  |   8083  | 
|   8501     DeoptimizeDependentCode(); |   8084     DeoptimizeDependentCode(); | 
|   8502   } |   8085   } | 
|   8503 } |   8086 } | 
|   8504  |   8087  | 
|   8505  |  | 
|   8506 void Field::ForceDynamicGuardedCidAndLength() const { |   8088 void Field::ForceDynamicGuardedCidAndLength() const { | 
|   8507   // Assume nothing about this field. |   8089   // Assume nothing about this field. | 
|   8508   set_is_unboxing_candidate(false); |   8090   set_is_unboxing_candidate(false); | 
|   8509   set_guarded_cid(kDynamicCid); |   8091   set_guarded_cid(kDynamicCid); | 
|   8510   set_is_nullable(true); |   8092   set_is_nullable(true); | 
|   8511   set_guarded_list_length(Field::kNoFixedLength); |   8093   set_guarded_list_length(Field::kNoFixedLength); | 
|   8512   set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); |   8094   set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset); | 
|   8513   // Drop any code that relied on the above assumptions. |   8095   // Drop any code that relied on the above assumptions. | 
|   8514   DeoptimizeDependentCode(); |   8096   DeoptimizeDependentCode(); | 
|   8515 } |   8097 } | 
|   8516  |   8098  | 
|   8517  |  | 
|   8518 void LiteralToken::set_literal(const String& literal) const { |   8099 void LiteralToken::set_literal(const String& literal) const { | 
|   8519   StorePointer(&raw_ptr()->literal_, literal.raw()); |   8100   StorePointer(&raw_ptr()->literal_, literal.raw()); | 
|   8520 } |   8101 } | 
|   8521  |   8102  | 
|   8522  |  | 
|   8523 void LiteralToken::set_value(const Object& value) const { |   8103 void LiteralToken::set_value(const Object& value) const { | 
|   8524   StorePointer(&raw_ptr()->value_, value.raw()); |   8104   StorePointer(&raw_ptr()->value_, value.raw()); | 
|   8525 } |   8105 } | 
|   8526  |   8106  | 
|   8527  |  | 
|   8528 RawLiteralToken* LiteralToken::New() { |   8107 RawLiteralToken* LiteralToken::New() { | 
|   8529   ASSERT(Object::literal_token_class() != Class::null()); |   8108   ASSERT(Object::literal_token_class() != Class::null()); | 
|   8530   RawObject* raw = Object::Allocate(LiteralToken::kClassId, |   8109   RawObject* raw = Object::Allocate(LiteralToken::kClassId, | 
|   8531                                     LiteralToken::InstanceSize(), Heap::kOld); |   8110                                     LiteralToken::InstanceSize(), Heap::kOld); | 
|   8532   return reinterpret_cast<RawLiteralToken*>(raw); |   8111   return reinterpret_cast<RawLiteralToken*>(raw); | 
|   8533 } |   8112 } | 
|   8534  |   8113  | 
|   8535  |  | 
|   8536 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { |   8114 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { | 
|   8537   const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); |   8115   const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); | 
|   8538   result.set_kind(kind); |   8116   result.set_kind(kind); | 
|   8539   result.set_literal(literal); |   8117   result.set_literal(literal); | 
|   8540   if (kind == Token::kINTEGER) { |   8118   if (kind == Token::kINTEGER) { | 
|   8541     const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); |   8119     const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); | 
|   8542     ASSERT(value.IsSmi() || value.IsOld()); |   8120     ASSERT(value.IsSmi() || value.IsOld()); | 
|   8543     result.set_value(value); |   8121     result.set_value(value); | 
|   8544   } else if (kind == Token::kDOUBLE) { |   8122   } else if (kind == Token::kDOUBLE) { | 
|   8545     const Double& value = Double::Handle(Double::NewCanonical(literal)); |   8123     const Double& value = Double::Handle(Double::NewCanonical(literal)); | 
|   8546     result.set_value(value); |   8124     result.set_value(value); | 
|   8547   } else { |   8125   } else { | 
|   8548     ASSERT(Token::NeedsLiteralToken(kind)); |   8126     ASSERT(Token::NeedsLiteralToken(kind)); | 
|   8549     result.set_value(literal); |   8127     result.set_value(literal); | 
|   8550   } |   8128   } | 
|   8551   return result.raw(); |   8129   return result.raw(); | 
|   8552 } |   8130 } | 
|   8553  |   8131  | 
|   8554  |  | 
|   8555 const char* LiteralToken::ToCString() const { |   8132 const char* LiteralToken::ToCString() const { | 
|   8556   const String& token = String::Handle(literal()); |   8133   const String& token = String::Handle(literal()); | 
|   8557   return token.ToCString(); |   8134   return token.ToCString(); | 
|   8558 } |   8135 } | 
|   8559  |   8136  | 
|   8560  |  | 
|   8561 RawGrowableObjectArray* TokenStream::TokenObjects() const { |   8137 RawGrowableObjectArray* TokenStream::TokenObjects() const { | 
|   8562   return raw_ptr()->token_objects_; |   8138   return raw_ptr()->token_objects_; | 
|   8563 } |   8139 } | 
|   8564  |   8140  | 
|   8565  |  | 
|   8566 void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const { |   8141 void TokenStream::SetTokenObjects(const GrowableObjectArray& value) const { | 
|   8567   StorePointer(&raw_ptr()->token_objects_, value.raw()); |   8142   StorePointer(&raw_ptr()->token_objects_, value.raw()); | 
|   8568 } |   8143 } | 
|   8569  |   8144  | 
|   8570  |  | 
|   8571 RawExternalTypedData* TokenStream::GetStream() const { |   8145 RawExternalTypedData* TokenStream::GetStream() const { | 
|   8572   return raw_ptr()->stream_; |   8146   return raw_ptr()->stream_; | 
|   8573 } |   8147 } | 
|   8574  |   8148  | 
|   8575  |  | 
|   8576 void TokenStream::SetStream(const ExternalTypedData& value) const { |   8149 void TokenStream::SetStream(const ExternalTypedData& value) const { | 
|   8577   StorePointer(&raw_ptr()->stream_, value.raw()); |   8150   StorePointer(&raw_ptr()->stream_, value.raw()); | 
|   8578 } |   8151 } | 
|   8579  |   8152  | 
|   8580  |  | 
|   8581 void TokenStream::DataFinalizer(void* isolate_callback_data, |   8153 void TokenStream::DataFinalizer(void* isolate_callback_data, | 
|   8582                                 Dart_WeakPersistentHandle handle, |   8154                                 Dart_WeakPersistentHandle handle, | 
|   8583                                 void* peer) { |   8155                                 void* peer) { | 
|   8584   ASSERT(peer != NULL); |   8156   ASSERT(peer != NULL); | 
|   8585   ::free(peer); |   8157   ::free(peer); | 
|   8586 } |   8158 } | 
|   8587  |   8159  | 
|   8588  |  | 
|   8589 RawString* TokenStream::PrivateKey() const { |   8160 RawString* TokenStream::PrivateKey() const { | 
|   8590   return raw_ptr()->private_key_; |   8161   return raw_ptr()->private_key_; | 
|   8591 } |   8162 } | 
|   8592  |   8163  | 
|   8593  |  | 
|   8594 void TokenStream::SetPrivateKey(const String& value) const { |   8164 void TokenStream::SetPrivateKey(const String& value) const { | 
|   8595   StorePointer(&raw_ptr()->private_key_, value.raw()); |   8165   StorePointer(&raw_ptr()->private_key_, value.raw()); | 
|   8596 } |   8166 } | 
|   8597  |   8167  | 
|   8598 RawString* TokenStream::GenerateSource() const { |   8168 RawString* TokenStream::GenerateSource() const { | 
|   8599   return GenerateSource(TokenPosition::kMinSource, TokenPosition::kMaxSource); |   8169   return GenerateSource(TokenPosition::kMinSource, TokenPosition::kMaxSource); | 
|   8600 } |   8170 } | 
|   8601  |   8171  | 
|   8602 RawString* TokenStream::GenerateSource(TokenPosition start_pos, |   8172 RawString* TokenStream::GenerateSource(TokenPosition start_pos, | 
|   8603                                        TokenPosition end_pos) const { |   8173                                        TokenPosition end_pos) const { | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8777     } |   8347     } | 
|   8778  |   8348  | 
|   8779     // Setup for next iteration. |   8349     // Setup for next iteration. | 
|   8780     prev = curr; |   8350     prev = curr; | 
|   8781     curr = next; |   8351     curr = next; | 
|   8782   } |   8352   } | 
|   8783   const Array& source = Array::Handle(Array::MakeFixedLength(literals)); |   8353   const Array& source = Array::Handle(Array::MakeFixedLength(literals)); | 
|   8784   return String::ConcatAll(source); |   8354   return String::ConcatAll(source); | 
|   8785 } |   8355 } | 
|   8786  |   8356  | 
|   8787  |  | 
|   8788 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const { |   8357 intptr_t TokenStream::ComputeSourcePosition(TokenPosition tok_pos) const { | 
|   8789   Zone* zone = Thread::Current()->zone(); |   8358   Zone* zone = Thread::Current()->zone(); | 
|   8790   Iterator iterator(zone, *this, TokenPosition::kMinSource, |   8359   Iterator iterator(zone, *this, TokenPosition::kMinSource, | 
|   8791                     Iterator::kAllTokens); |   8360                     Iterator::kAllTokens); | 
|   8792   intptr_t src_pos = 0; |   8361   intptr_t src_pos = 0; | 
|   8793   Token::Kind kind = iterator.CurrentTokenKind(); |   8362   Token::Kind kind = iterator.CurrentTokenKind(); | 
|   8794   while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) { |   8363   while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) { | 
|   8795     iterator.Advance(); |   8364     iterator.Advance(); | 
|   8796     kind = iterator.CurrentTokenKind(); |   8365     kind = iterator.CurrentTokenKind(); | 
|   8797     src_pos++; |   8366     src_pos++; | 
|   8798   } |   8367   } | 
|   8799   return src_pos; |   8368   return src_pos; | 
|   8800 } |   8369 } | 
|   8801  |   8370  | 
|   8802  |  | 
|   8803 RawTokenStream* TokenStream::New() { |   8371 RawTokenStream* TokenStream::New() { | 
|   8804   ASSERT(Object::token_stream_class() != Class::null()); |   8372   ASSERT(Object::token_stream_class() != Class::null()); | 
|   8805   RawObject* raw = Object::Allocate(TokenStream::kClassId, |   8373   RawObject* raw = Object::Allocate(TokenStream::kClassId, | 
|   8806                                     TokenStream::InstanceSize(), Heap::kOld); |   8374                                     TokenStream::InstanceSize(), Heap::kOld); | 
|   8807   return reinterpret_cast<RawTokenStream*>(raw); |   8375   return reinterpret_cast<RawTokenStream*>(raw); | 
|   8808 } |   8376 } | 
|   8809  |   8377  | 
|   8810  |  | 
|   8811 RawTokenStream* TokenStream::New(intptr_t len) { |   8378 RawTokenStream* TokenStream::New(intptr_t len) { | 
|   8812   if (len < 0 || len > kMaxElements) { |   8379   if (len < 0 || len > kMaxElements) { | 
|   8813     // This should be caught before we reach here. |   8380     // This should be caught before we reach here. | 
|   8814     FATAL1("Fatal error in TokenStream::New: invalid len %" Pd "\n", len); |   8381     FATAL1("Fatal error in TokenStream::New: invalid len %" Pd "\n", len); | 
|   8815   } |   8382   } | 
|   8816   uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len)); |   8383   uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len)); | 
|   8817   ASSERT(data != NULL); |   8384   ASSERT(data != NULL); | 
|   8818   Zone* zone = Thread::Current()->zone(); |   8385   Zone* zone = Thread::Current()->zone(); | 
|   8819   const ExternalTypedData& stream = ExternalTypedData::Handle( |   8386   const ExternalTypedData& stream = ExternalTypedData::Handle( | 
|   8820       zone, ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, len, |   8387       zone, ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, len, | 
|   8821                                    Heap::kOld)); |   8388                                    Heap::kOld)); | 
|   8822   stream.AddFinalizer(data, DataFinalizer, len); |   8389   stream.AddFinalizer(data, DataFinalizer, len); | 
|   8823   const TokenStream& result = TokenStream::Handle(zone, TokenStream::New()); |   8390   const TokenStream& result = TokenStream::Handle(zone, TokenStream::New()); | 
|   8824   result.SetStream(stream); |   8391   result.SetStream(stream); | 
|   8825   return result.raw(); |   8392   return result.raw(); | 
|   8826 } |   8393 } | 
|   8827  |   8394  | 
|   8828  |  | 
|   8829 // CompressedTokenMap maps String and LiteralToken keys to Smi values. |   8395 // CompressedTokenMap maps String and LiteralToken keys to Smi values. | 
|   8830 // It also supports lookup by TokenDescriptor. |   8396 // It also supports lookup by TokenDescriptor. | 
|   8831 class CompressedTokenTraits { |   8397 class CompressedTokenTraits { | 
|   8832  public: |   8398  public: | 
|   8833   static const char* Name() { return "CompressedTokenTraits"; } |   8399   static const char* Name() { return "CompressedTokenTraits"; } | 
|   8834   static bool ReportStats() { return false; } |   8400   static bool ReportStats() { return false; } | 
|   8835  |   8401  | 
|   8836   static bool IsMatch(const Scanner::TokenDescriptor& descriptor, |   8402   static bool IsMatch(const Scanner::TokenDescriptor& descriptor, | 
|   8837                       const Object& key) { |   8403                       const Object& key) { | 
|   8838     if (!key.IsLiteralToken()) { |   8404     if (!key.IsLiteralToken()) { | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|   8855   static uword Hash(const Object& key) { |   8421   static uword Hash(const Object& key) { | 
|   8856     if (key.IsLiteralToken()) { |   8422     if (key.IsLiteralToken()) { | 
|   8857       return String::HashRawSymbol(LiteralToken::Cast(key).literal()); |   8423       return String::HashRawSymbol(LiteralToken::Cast(key).literal()); | 
|   8858     } else { |   8424     } else { | 
|   8859       return String::Cast(key).Hash(); |   8425       return String::Cast(key).Hash(); | 
|   8860     } |   8426     } | 
|   8861   } |   8427   } | 
|   8862 }; |   8428 }; | 
|   8863 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap; |   8429 typedef UnorderedHashMap<CompressedTokenTraits> CompressedTokenMap; | 
|   8864  |   8430  | 
|   8865  |  | 
|   8866 // Helper class for creation of compressed token stream data. |   8431 // Helper class for creation of compressed token stream data. | 
|   8867 class CompressedTokenStreamData : public Scanner::TokenCollector { |   8432 class CompressedTokenStreamData : public Scanner::TokenCollector { | 
|   8868  public: |   8433  public: | 
|   8869   static const intptr_t kInitialBufferSize = 16 * KB; |   8434   static const intptr_t kInitialBufferSize = 16 * KB; | 
|   8870   static const bool kPrintTokenObjects = false; |   8435   static const bool kPrintTokenObjects = false; | 
|   8871  |   8436  | 
|   8872   CompressedTokenStreamData(const GrowableObjectArray& ta, |   8437   CompressedTokenStreamData(const GrowableObjectArray& ta, | 
|   8873                             CompressedTokenMap* map) |   8438                             CompressedTokenMap* map) | 
|   8874       : buffer_(NULL), |   8439       : buffer_(NULL), | 
|   8875         stream_(&buffer_, Reallocate, kInitialBufferSize), |   8440         stream_(&buffer_, Reallocate, kInitialBufferSize), | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8964   WriteStream stream_; |   8529   WriteStream stream_; | 
|   8965   const GrowableObjectArray& token_objects_; |   8530   const GrowableObjectArray& token_objects_; | 
|   8966   CompressedTokenMap* tokens_; |   8531   CompressedTokenMap* tokens_; | 
|   8967   Object& value_; |   8532   Object& value_; | 
|   8968   Smi& fresh_index_smi_; |   8533   Smi& fresh_index_smi_; | 
|   8969   intptr_t num_tokens_collected_; |   8534   intptr_t num_tokens_collected_; | 
|   8970  |   8535  | 
|   8971   DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); |   8536   DISALLOW_COPY_AND_ASSIGN(CompressedTokenStreamData); | 
|   8972 }; |   8537 }; | 
|   8973  |   8538  | 
|   8974  |  | 
|   8975 RawTokenStream* TokenStream::New(const String& source, |   8539 RawTokenStream* TokenStream::New(const String& source, | 
|   8976                                  const String& private_key, |   8540                                  const String& private_key, | 
|   8977                                  bool use_shared_tokens) { |   8541                                  bool use_shared_tokens) { | 
|   8978   Thread* thread = Thread::Current(); |   8542   Thread* thread = Thread::Current(); | 
|   8979   Zone* zone = thread->zone(); |   8543   Zone* zone = thread->zone(); | 
|   8980  |   8544  | 
|   8981   GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone); |   8545   GrowableObjectArray& token_objects = GrowableObjectArray::Handle(zone); | 
|   8982   Array& token_objects_map = Array::Handle(zone); |   8546   Array& token_objects_map = Array::Handle(zone); | 
|   8983   if (use_shared_tokens) { |   8547   if (use_shared_tokens) { | 
|   8984     // Use the shared token objects array in the object store. Allocate |   8548     // Use the shared token objects array in the object store. Allocate | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9018     result.SetTokenObjects(token_objects); |   8582     result.SetTokenObjects(token_objects); | 
|   9019   } |   8583   } | 
|   9020  |   8584  | 
|   9021   token_objects_map = map.Release().raw(); |   8585   token_objects_map = map.Release().raw(); | 
|   9022   if (use_shared_tokens) { |   8586   if (use_shared_tokens) { | 
|   9023     thread->isolate()->object_store()->set_token_objects_map(token_objects_map); |   8587     thread->isolate()->object_store()->set_token_objects_map(token_objects_map); | 
|   9024   } |   8588   } | 
|   9025   return result.raw(); |   8589   return result.raw(); | 
|   9026 } |   8590 } | 
|   9027  |   8591  | 
|   9028  |  | 
|   9029 void TokenStream::OpenSharedTokenList(Isolate* isolate) { |   8592 void TokenStream::OpenSharedTokenList(Isolate* isolate) { | 
|   9030   const int kInitialSharedCapacity = 5 * 1024; |   8593   const int kInitialSharedCapacity = 5 * 1024; | 
|   9031   ObjectStore* store = isolate->object_store(); |   8594   ObjectStore* store = isolate->object_store(); | 
|   9032   ASSERT(store->token_objects() == GrowableObjectArray::null()); |   8595   ASSERT(store->token_objects() == GrowableObjectArray::null()); | 
|   9033   const GrowableObjectArray& token_objects = GrowableObjectArray::Handle( |   8596   const GrowableObjectArray& token_objects = GrowableObjectArray::Handle( | 
|   9034       GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld)); |   8597       GrowableObjectArray::New(kInitialSharedCapacity, Heap::kOld)); | 
|   9035   store->set_token_objects(token_objects); |   8598   store->set_token_objects(token_objects); | 
|   9036   const Array& token_objects_map = Array::Handle( |   8599   const Array& token_objects_map = Array::Handle( | 
|   9037       HashTables::New<CompressedTokenMap>(kInitialSharedCapacity, Heap::kOld)); |   8600       HashTables::New<CompressedTokenMap>(kInitialSharedCapacity, Heap::kOld)); | 
|   9038   store->set_token_objects_map(token_objects_map); |   8601   store->set_token_objects_map(token_objects_map); | 
|   9039 } |   8602 } | 
|   9040  |   8603  | 
|   9041  |  | 
|   9042 void TokenStream::CloseSharedTokenList(Isolate* isolate) { |   8604 void TokenStream::CloseSharedTokenList(Isolate* isolate) { | 
|   9043   isolate->object_store()->set_token_objects(GrowableObjectArray::Handle()); |   8605   isolate->object_store()->set_token_objects(GrowableObjectArray::Handle()); | 
|   9044   isolate->object_store()->set_token_objects_map(Array::null_array()); |   8606   isolate->object_store()->set_token_objects_map(Array::null_array()); | 
|   9045 } |   8607 } | 
|   9046  |   8608  | 
|   9047  |  | 
|   9048 const char* TokenStream::ToCString() const { |   8609 const char* TokenStream::ToCString() const { | 
|   9049   return "TokenStream"; |   8610   return "TokenStream"; | 
|   9050 } |   8611 } | 
|   9051  |   8612  | 
|   9052  |  | 
|   9053 TokenStream::Iterator::Iterator(Zone* zone, |   8613 TokenStream::Iterator::Iterator(Zone* zone, | 
|   9054                                 const TokenStream& tokens, |   8614                                 const TokenStream& tokens, | 
|   9055                                 TokenPosition token_pos, |   8615                                 TokenPosition token_pos, | 
|   9056                                 Iterator::StreamType stream_type) |   8616                                 Iterator::StreamType stream_type) | 
|   9057     : tokens_(TokenStream::Handle(zone, tokens.raw())), |   8617     : tokens_(TokenStream::Handle(zone, tokens.raw())), | 
|   9058       data_(ExternalTypedData::Handle(zone, tokens.GetStream())), |   8618       data_(ExternalTypedData::Handle(zone, tokens.GetStream())), | 
|   9059       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()), |   8619       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()), | 
|   9060       token_objects_(Array::Handle( |   8620       token_objects_(Array::Handle( | 
|   9061           zone, |   8621           zone, | 
|   9062           GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())), |   8622           GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())), | 
|   9063       obj_(Object::Handle(zone)), |   8623       obj_(Object::Handle(zone)), | 
|   9064       cur_token_pos_(token_pos.Pos()), |   8624       cur_token_pos_(token_pos.Pos()), | 
|   9065       cur_token_kind_(Token::kILLEGAL), |   8625       cur_token_kind_(Token::kILLEGAL), | 
|   9066       cur_token_obj_index_(-1), |   8626       cur_token_obj_index_(-1), | 
|   9067       stream_type_(stream_type) { |   8627       stream_type_(stream_type) { | 
|   9068   ASSERT(token_pos != TokenPosition::kNoSource); |   8628   ASSERT(token_pos != TokenPosition::kNoSource); | 
|   9069   if (token_pos.IsReal()) { |   8629   if (token_pos.IsReal()) { | 
|   9070     SetCurrentPosition(token_pos); |   8630     SetCurrentPosition(token_pos); | 
|   9071   } |   8631   } | 
|   9072 } |   8632 } | 
|   9073  |   8633  | 
|   9074  |  | 
|   9075 void TokenStream::Iterator::SetStream(const TokenStream& tokens, |   8634 void TokenStream::Iterator::SetStream(const TokenStream& tokens, | 
|   9076                                       TokenPosition token_pos) { |   8635                                       TokenPosition token_pos) { | 
|   9077   tokens_ = tokens.raw(); |   8636   tokens_ = tokens.raw(); | 
|   9078   data_ = tokens.GetStream(); |   8637   data_ = tokens.GetStream(); | 
|   9079   stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), |   8638   stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), | 
|   9080                     data_.Length()); |   8639                     data_.Length()); | 
|   9081   token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data(); |   8640   token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data(); | 
|   9082   obj_ = Object::null(); |   8641   obj_ = Object::null(); | 
|   9083   cur_token_pos_ = token_pos.Pos(); |   8642   cur_token_pos_ = token_pos.Pos(); | 
|   9084   cur_token_kind_ = Token::kILLEGAL; |   8643   cur_token_kind_ = Token::kILLEGAL; | 
|   9085   cur_token_obj_index_ = -1; |   8644   cur_token_obj_index_ = -1; | 
|   9086   SetCurrentPosition(token_pos); |   8645   SetCurrentPosition(token_pos); | 
|   9087 } |   8646 } | 
|   9088  |   8647  | 
|   9089  |  | 
|   9090 bool TokenStream::Iterator::IsValid() const { |   8648 bool TokenStream::Iterator::IsValid() const { | 
|   9091   return !tokens_.IsNull(); |   8649   return !tokens_.IsNull(); | 
|   9092 } |   8650 } | 
|   9093  |   8651  | 
|   9094  |  | 
|   9095 Token::Kind TokenStream::Iterator::LookaheadTokenKind(intptr_t num_tokens) { |   8652 Token::Kind TokenStream::Iterator::LookaheadTokenKind(intptr_t num_tokens) { | 
|   9096   intptr_t saved_position = stream_.Position(); |   8653   intptr_t saved_position = stream_.Position(); | 
|   9097   Token::Kind kind = Token::kILLEGAL; |   8654   Token::Kind kind = Token::kILLEGAL; | 
|   9098   intptr_t value = -1; |   8655   intptr_t value = -1; | 
|   9099   intptr_t count = 0; |   8656   intptr_t count = 0; | 
|   9100   while (count < num_tokens && value != Token::kEOS) { |   8657   while (count < num_tokens && value != Token::kEOS) { | 
|   9101     value = ReadToken(); |   8658     value = ReadToken(); | 
|   9102     if ((stream_type_ == kAllTokens) || |   8659     if ((stream_type_ == kAllTokens) || | 
|   9103         (static_cast<Token::Kind>(value) != Token::kNEWLINE)) { |   8660         (static_cast<Token::Kind>(value) != Token::kNEWLINE)) { | 
|   9104       count += 1; |   8661       count += 1; | 
|   9105     } |   8662     } | 
|   9106   } |   8663   } | 
|   9107   if (value < Token::kNumTokens) { |   8664   if (value < Token::kNumTokens) { | 
|   9108     kind = static_cast<Token::Kind>(value); |   8665     kind = static_cast<Token::Kind>(value); | 
|   9109   } else { |   8666   } else { | 
|   9110     value = value - Token::kNumTokens; |   8667     value = value - Token::kNumTokens; | 
|   9111     obj_ = token_objects_.At(value); |   8668     obj_ = token_objects_.At(value); | 
|   9112     if (obj_.IsLiteralToken()) { |   8669     if (obj_.IsLiteralToken()) { | 
|   9113       const LiteralToken& literal_token = LiteralToken::Cast(obj_); |   8670       const LiteralToken& literal_token = LiteralToken::Cast(obj_); | 
|   9114       kind = literal_token.kind(); |   8671       kind = literal_token.kind(); | 
|   9115     } else { |   8672     } else { | 
|   9116       ASSERT(obj_.IsString());  // Must be an identifier. |   8673       ASSERT(obj_.IsString());  // Must be an identifier. | 
|   9117       kind = Token::kIDENT; |   8674       kind = Token::kIDENT; | 
|   9118     } |   8675     } | 
|   9119   } |   8676   } | 
|   9120   stream_.SetPosition(saved_position); |   8677   stream_.SetPosition(saved_position); | 
|   9121   return kind; |   8678   return kind; | 
|   9122 } |   8679 } | 
|   9123  |   8680  | 
|   9124  |  | 
|   9125 TokenPosition TokenStream::Iterator::CurrentPosition() const { |   8681 TokenPosition TokenStream::Iterator::CurrentPosition() const { | 
|   9126   return TokenPosition(cur_token_pos_); |   8682   return TokenPosition(cur_token_pos_); | 
|   9127 } |   8683 } | 
|   9128  |   8684  | 
|   9129  |  | 
|   9130 void TokenStream::Iterator::SetCurrentPosition(TokenPosition token_pos) { |   8685 void TokenStream::Iterator::SetCurrentPosition(TokenPosition token_pos) { | 
|   9131   stream_.SetPosition(token_pos.value()); |   8686   stream_.SetPosition(token_pos.value()); | 
|   9132   Advance(); |   8687   Advance(); | 
|   9133 } |   8688 } | 
|   9134  |   8689  | 
|   9135  |  | 
|   9136 void TokenStream::Iterator::Advance() { |   8690 void TokenStream::Iterator::Advance() { | 
|   9137   intptr_t value; |   8691   intptr_t value; | 
|   9138   do { |   8692   do { | 
|   9139     cur_token_pos_ = stream_.Position(); |   8693     cur_token_pos_ = stream_.Position(); | 
|   9140     value = ReadToken(); |   8694     value = ReadToken(); | 
|   9141   } while ((stream_type_ == kNoNewlines) && |   8695   } while ((stream_type_ == kNoNewlines) && | 
|   9142            (static_cast<Token::Kind>(value) == Token::kNEWLINE)); |   8696            (static_cast<Token::Kind>(value) == Token::kNEWLINE)); | 
|   9143   if (value < Token::kNumTokens) { |   8697   if (value < Token::kNumTokens) { | 
|   9144     cur_token_kind_ = static_cast<Token::Kind>(value); |   8698     cur_token_kind_ = static_cast<Token::Kind>(value); | 
|   9145     cur_token_obj_index_ = -1; |   8699     cur_token_obj_index_ = -1; | 
|   9146     return; |   8700     return; | 
|   9147   } |   8701   } | 
|   9148   cur_token_obj_index_ = value - Token::kNumTokens; |   8702   cur_token_obj_index_ = value - Token::kNumTokens; | 
|   9149   obj_ = token_objects_.At(cur_token_obj_index_); |   8703   obj_ = token_objects_.At(cur_token_obj_index_); | 
|   9150   if (obj_.IsLiteralToken()) { |   8704   if (obj_.IsLiteralToken()) { | 
|   9151     const LiteralToken& literal_token = LiteralToken::Cast(obj_); |   8705     const LiteralToken& literal_token = LiteralToken::Cast(obj_); | 
|   9152     cur_token_kind_ = literal_token.kind(); |   8706     cur_token_kind_ = literal_token.kind(); | 
|   9153     return; |   8707     return; | 
|   9154   } |   8708   } | 
|   9155   ASSERT(obj_.IsString());  // Must be an identifier. |   8709   ASSERT(obj_.IsString());  // Must be an identifier. | 
|   9156   cur_token_kind_ = Token::kIDENT; |   8710   cur_token_kind_ = Token::kIDENT; | 
|   9157 } |   8711 } | 
|   9158  |   8712  | 
|   9159  |  | 
|   9160 RawObject* TokenStream::Iterator::CurrentToken() const { |   8713 RawObject* TokenStream::Iterator::CurrentToken() const { | 
|   9161   if (cur_token_obj_index_ != -1) { |   8714   if (cur_token_obj_index_ != -1) { | 
|   9162     return token_objects_.At(cur_token_obj_index_); |   8715     return token_objects_.At(cur_token_obj_index_); | 
|   9163   } else { |   8716   } else { | 
|   9164     return Smi::New(cur_token_kind_); |   8717     return Smi::New(cur_token_kind_); | 
|   9165   } |   8718   } | 
|   9166 } |   8719 } | 
|   9167  |   8720  | 
|   9168  |  | 
|   9169 RawString* TokenStream::Iterator::CurrentLiteral() const { |   8721 RawString* TokenStream::Iterator::CurrentLiteral() const { | 
|   9170   obj_ = CurrentToken(); |   8722   obj_ = CurrentToken(); | 
|   9171   return MakeLiteralToken(obj_); |   8723   return MakeLiteralToken(obj_); | 
|   9172 } |   8724 } | 
|   9173  |   8725  | 
|   9174  |  | 
|   9175 RawString* TokenStream::Iterator::MakeLiteralToken(const Object& obj) const { |   8726 RawString* TokenStream::Iterator::MakeLiteralToken(const Object& obj) const { | 
|   9176   if (obj.IsString()) { |   8727   if (obj.IsString()) { | 
|   9177     return reinterpret_cast<RawString*>(obj.raw()); |   8728     return reinterpret_cast<RawString*>(obj.raw()); | 
|   9178   } else if (obj.IsSmi()) { |   8729   } else if (obj.IsSmi()) { | 
|   9179     Token::Kind kind = static_cast<Token::Kind>( |   8730     Token::Kind kind = static_cast<Token::Kind>( | 
|   9180         Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); |   8731         Smi::Value(reinterpret_cast<RawSmi*>(obj.raw()))); | 
|   9181     ASSERT(kind < Token::kNumTokens); |   8732     ASSERT(kind < Token::kNumTokens); | 
|   9182     return Symbols::Token(kind).raw(); |   8733     return Symbols::Token(kind).raw(); | 
|   9183   } else { |   8734   } else { | 
|   9184     ASSERT(obj.IsLiteralToken());  // Must be a literal token. |   8735     ASSERT(obj.IsLiteralToken());  // Must be a literal token. | 
|   9185     const LiteralToken& literal_token = LiteralToken::Cast(obj); |   8736     const LiteralToken& literal_token = LiteralToken::Cast(obj); | 
|   9186     return literal_token.literal(); |   8737     return literal_token.literal(); | 
|   9187   } |   8738   } | 
|   9188 } |   8739 } | 
|   9189  |   8740  | 
|   9190  |  | 
|   9191 bool Script::HasSource() const { |   8741 bool Script::HasSource() const { | 
|   9192 #if !defined(DART_PRECOMPILED_RUNTIME) |   8742 #if !defined(DART_PRECOMPILED_RUNTIME) | 
|   9193   return kind() == RawScript::kKernelTag || |   8743   return kind() == RawScript::kKernelTag || | 
|   9194          raw_ptr()->source_ != String::null(); |   8744          raw_ptr()->source_ != String::null(); | 
|   9195 #else   // !defined(DART_PRECOMPILED_RUNTIME) |   8745 #else   // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9196   return raw_ptr()->source_ != String::null(); |   8746   return raw_ptr()->source_ != String::null(); | 
|   9197 #endif  // !defined(DART_PRECOMPILED_RUNTIME) |   8747 #endif  // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9198 } |   8748 } | 
|   9199  |   8749  | 
|   9200  |  | 
|   9201 RawString* Script::Source() const { |   8750 RawString* Script::Source() const { | 
|   9202   String& source = String::Handle(raw_ptr()->source_); |   8751   String& source = String::Handle(raw_ptr()->source_); | 
|   9203   if (source.IsNull()) { |   8752   if (source.IsNull()) { | 
|   9204     return GenerateSource(); |   8753     return GenerateSource(); | 
|   9205   } |   8754   } | 
|   9206   return raw_ptr()->source_; |   8755   return raw_ptr()->source_; | 
|   9207 } |   8756 } | 
|   9208  |   8757  | 
|   9209  |  | 
|   9210 RawString* Script::GenerateSource() const { |   8758 RawString* Script::GenerateSource() const { | 
|   9211 #if !defined(DART_PRECOMPILED_RUNTIME) |   8759 #if !defined(DART_PRECOMPILED_RUNTIME) | 
|   9212   if (kind() == RawScript::kKernelTag) { |   8760   if (kind() == RawScript::kKernelTag) { | 
|   9213     String& source = String::Handle(raw_ptr()->source_); |   8761     String& source = String::Handle(raw_ptr()->source_); | 
|   9214     if (source.IsNull()) { |   8762     if (source.IsNull()) { | 
|   9215       // This is created lazily. Now we need it. |   8763       // This is created lazily. Now we need it. | 
|   9216       set_source(kernel::GetSourceFor(*this)); |   8764       set_source(kernel::GetSourceFor(*this)); | 
|   9217     } |   8765     } | 
|   9218     return raw_ptr()->source_; |   8766     return raw_ptr()->source_; | 
|   9219   } |   8767   } | 
|   9220 #endif  // !defined(DART_PRECOMPILED_RUNTIME) |   8768 #endif  // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9221  |   8769  | 
|   9222   const TokenStream& token_stream = TokenStream::Handle(tokens()); |   8770   const TokenStream& token_stream = TokenStream::Handle(tokens()); | 
|   9223   if (token_stream.IsNull()) { |   8771   if (token_stream.IsNull()) { | 
|   9224     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |   8772     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|   9225     return String::null(); |   8773     return String::null(); | 
|   9226   } |   8774   } | 
|   9227   return token_stream.GenerateSource(); |   8775   return token_stream.GenerateSource(); | 
|   9228 } |   8776 } | 
|   9229  |   8777  | 
|   9230  |  | 
|   9231 void Script::set_compile_time_constants(const Array& value) const { |   8778 void Script::set_compile_time_constants(const Array& value) const { | 
|   9232   StorePointer(&raw_ptr()->compile_time_constants_, value.raw()); |   8779   StorePointer(&raw_ptr()->compile_time_constants_, value.raw()); | 
|   9233 } |   8780 } | 
|   9234  |   8781  | 
|   9235  |  | 
|   9236 void Script::set_kernel_data(const uint8_t* kernel_data) const { |   8782 void Script::set_kernel_data(const uint8_t* kernel_data) const { | 
|   9237   StoreNonPointer(&raw_ptr()->kernel_data_, kernel_data); |   8783   StoreNonPointer(&raw_ptr()->kernel_data_, kernel_data); | 
|   9238 } |   8784 } | 
|   9239  |   8785  | 
|   9240  |  | 
|   9241 void Script::set_kernel_data_size(const intptr_t kernel_data_size) const { |   8786 void Script::set_kernel_data_size(const intptr_t kernel_data_size) const { | 
|   9242   StoreNonPointer(&raw_ptr()->kernel_data_size_, kernel_data_size); |   8787   StoreNonPointer(&raw_ptr()->kernel_data_size_, kernel_data_size); | 
|   9243 } |   8788 } | 
|   9244  |   8789  | 
|   9245  |  | 
|   9246 void Script::set_kernel_script_index(const intptr_t kernel_script_index) const { |   8790 void Script::set_kernel_script_index(const intptr_t kernel_script_index) const { | 
|   9247   StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index); |   8791   StoreNonPointer(&raw_ptr()->kernel_script_index_, kernel_script_index); | 
|   9248 } |   8792 } | 
|   9249  |   8793  | 
|   9250  |  | 
|   9251 void Script::set_kernel_string_offsets(const TypedData& offsets) const { |   8794 void Script::set_kernel_string_offsets(const TypedData& offsets) const { | 
|   9252   StorePointer(&raw_ptr()->kernel_string_offsets_, offsets.raw()); |   8795   StorePointer(&raw_ptr()->kernel_string_offsets_, offsets.raw()); | 
|   9253 } |   8796 } | 
|   9254  |   8797  | 
|   9255  |  | 
|   9256 void Script::set_kernel_string_data(const TypedData& data) const { |   8798 void Script::set_kernel_string_data(const TypedData& data) const { | 
|   9257   StorePointer(&raw_ptr()->kernel_string_data_, data.raw()); |   8799   StorePointer(&raw_ptr()->kernel_string_data_, data.raw()); | 
|   9258 } |   8800 } | 
|   9259  |   8801  | 
|   9260  |  | 
|   9261 void Script::set_kernel_canonical_names(const TypedData& names) const { |   8802 void Script::set_kernel_canonical_names(const TypedData& names) const { | 
|   9262   StorePointer(&raw_ptr()->kernel_canonical_names_, names.raw()); |   8803   StorePointer(&raw_ptr()->kernel_canonical_names_, names.raw()); | 
|   9263 } |   8804 } | 
|   9264  |   8805  | 
|   9265  |  | 
|   9266 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { |   8806 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { | 
|   9267   Zone* zone = Thread::Current()->zone(); |   8807   Zone* zone = Thread::Current()->zone(); | 
|   9268   const GrowableObjectArray& info = |   8808   const GrowableObjectArray& info = | 
|   9269       GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |   8809       GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 
|   9270   const String& source = String::Handle(zone, Source()); |   8810   const String& source = String::Handle(zone, Source()); | 
|   9271   const String& key = Symbols::Empty(); |   8811   const String& key = Symbols::Empty(); | 
|   9272   const Object& line_separator = Object::Handle(zone); |   8812   const Object& line_separator = Object::Handle(zone); | 
|   9273   Smi& value = Smi::Handle(zone); |   8813   Smi& value = Smi::Handle(zone); | 
|   9274  |   8814  | 
|   9275   if (kind() == RawScript::kKernelTag) { |   8815   if (kind() == RawScript::kKernelTag) { | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9385       column += col_offset(); |   8925       column += col_offset(); | 
|   9386     } |   8926     } | 
|   9387     value = Smi::New(column); |   8927     value = Smi::New(column); | 
|   9388     info.Add(value); |   8928     info.Add(value); | 
|   9389     tkit.Advance(); |   8929     tkit.Advance(); | 
|   9390     s.Scan(); |   8930     s.Scan(); | 
|   9391   } |   8931   } | 
|   9392   return info.raw(); |   8932   return info.raw(); | 
|   9393 } |   8933 } | 
|   9394  |   8934  | 
|   9395  |  | 
|   9396 const char* Script::GetKindAsCString() const { |   8935 const char* Script::GetKindAsCString() const { | 
|   9397   switch (kind()) { |   8936   switch (kind()) { | 
|   9398     case RawScript::kScriptTag: |   8937     case RawScript::kScriptTag: | 
|   9399       return "script"; |   8938       return "script"; | 
|   9400     case RawScript::kLibraryTag: |   8939     case RawScript::kLibraryTag: | 
|   9401       return "library"; |   8940       return "library"; | 
|   9402     case RawScript::kSourceTag: |   8941     case RawScript::kSourceTag: | 
|   9403       return "source"; |   8942       return "source"; | 
|   9404     case RawScript::kPatchTag: |   8943     case RawScript::kPatchTag: | 
|   9405       return "patch"; |   8944       return "patch"; | 
|   9406     case RawScript::kEvaluateTag: |   8945     case RawScript::kEvaluateTag: | 
|   9407       return "evaluate"; |   8946       return "evaluate"; | 
|   9408     case RawScript::kKernelTag: |   8947     case RawScript::kKernelTag: | 
|   9409       return "kernel"; |   8948       return "kernel"; | 
|   9410     default: |   8949     default: | 
|   9411       UNIMPLEMENTED(); |   8950       UNIMPLEMENTED(); | 
|   9412   } |   8951   } | 
|   9413   UNREACHABLE(); |   8952   UNREACHABLE(); | 
|   9414   return NULL; |   8953   return NULL; | 
|   9415 } |   8954 } | 
|   9416  |   8955  | 
|   9417  |  | 
|   9418 void Script::set_url(const String& value) const { |   8956 void Script::set_url(const String& value) const { | 
|   9419   StorePointer(&raw_ptr()->url_, value.raw()); |   8957   StorePointer(&raw_ptr()->url_, value.raw()); | 
|   9420 } |   8958 } | 
|   9421  |   8959  | 
|   9422  |  | 
|   9423 void Script::set_resolved_url(const String& value) const { |   8960 void Script::set_resolved_url(const String& value) const { | 
|   9424   StorePointer(&raw_ptr()->resolved_url_, value.raw()); |   8961   StorePointer(&raw_ptr()->resolved_url_, value.raw()); | 
|   9425 } |   8962 } | 
|   9426  |   8963  | 
|   9427  |  | 
|   9428 void Script::set_source(const String& value) const { |   8964 void Script::set_source(const String& value) const { | 
|   9429   StorePointer(&raw_ptr()->source_, value.raw()); |   8965   StorePointer(&raw_ptr()->source_, value.raw()); | 
|   9430 } |   8966 } | 
|   9431  |   8967  | 
|   9432 void Script::set_line_starts(const Array& value) const { |   8968 void Script::set_line_starts(const Array& value) const { | 
|   9433   StorePointer(&raw_ptr()->line_starts_, value.raw()); |   8969   StorePointer(&raw_ptr()->line_starts_, value.raw()); | 
|   9434 } |   8970 } | 
|   9435  |   8971  | 
|   9436  |  | 
|   9437 void Script::set_debug_positions(const Array& value) const { |   8972 void Script::set_debug_positions(const Array& value) const { | 
|   9438   StorePointer(&raw_ptr()->debug_positions_, value.raw()); |   8973   StorePointer(&raw_ptr()->debug_positions_, value.raw()); | 
|   9439 } |   8974 } | 
|   9440  |   8975  | 
|   9441 void Script::set_yield_positions(const Array& value) const { |   8976 void Script::set_yield_positions(const Array& value) const { | 
|   9442   StorePointer(&raw_ptr()->yield_positions_, value.raw()); |   8977   StorePointer(&raw_ptr()->yield_positions_, value.raw()); | 
|   9443 } |   8978 } | 
|   9444  |   8979  | 
|   9445 RawArray* Script::yield_positions() const { |   8980 RawArray* Script::yield_positions() const { | 
|   9446 #if !defined(DART_PRECOMPILED_RUNTIME) |   8981 #if !defined(DART_PRECOMPILED_RUNTIME) | 
|   9447   Array& yields = Array::Handle(raw_ptr()->yield_positions_); |   8982   Array& yields = Array::Handle(raw_ptr()->yield_positions_); | 
|   9448   if (yields.IsNull() && kind() == RawScript::kKernelTag) { |   8983   if (yields.IsNull() && kind() == RawScript::kKernelTag) { | 
|   9449     // This is created lazily. Now we need it. |   8984     // This is created lazily. Now we need it. | 
|   9450     kernel::CollectTokenPositionsFor(*this); |   8985     kernel::CollectTokenPositionsFor(*this); | 
|   9451   } |   8986   } | 
|   9452 #endif  // !defined(DART_PRECOMPILED_RUNTIME) |   8987 #endif  // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9453   return raw_ptr()->yield_positions_; |   8988   return raw_ptr()->yield_positions_; | 
|   9454 } |   8989 } | 
|   9455  |   8990  | 
|   9456  |  | 
|   9457 RawArray* Script::line_starts() const { |   8991 RawArray* Script::line_starts() const { | 
|   9458 #if !defined(DART_PRECOMPILED_RUNTIME) |   8992 #if !defined(DART_PRECOMPILED_RUNTIME) | 
|   9459   const Array& line_starts_array = Array::Handle(raw_ptr()->line_starts_); |   8993   const Array& line_starts_array = Array::Handle(raw_ptr()->line_starts_); | 
|   9460   if (line_starts_array.IsNull() && kind() == RawScript::kKernelTag) { |   8994   if (line_starts_array.IsNull() && kind() == RawScript::kKernelTag) { | 
|   9461     // This is created lazily. Now we need it. |   8995     // This is created lazily. Now we need it. | 
|   9462     set_line_starts(kernel::GetLineStartsFor(*this)); |   8996     set_line_starts(kernel::GetLineStartsFor(*this)); | 
|   9463   } |   8997   } | 
|   9464 #endif  // !defined(DART_PRECOMPILED_RUNTIME) |   8998 #endif  // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9465   return raw_ptr()->line_starts_; |   8999   return raw_ptr()->line_starts_; | 
|   9466 } |   9000 } | 
|   9467  |   9001  | 
|   9468  |  | 
|   9469 RawArray* Script::debug_positions() const { |   9002 RawArray* Script::debug_positions() const { | 
|   9470 #if !defined(DART_PRECOMPILED_RUNTIME) |   9003 #if !defined(DART_PRECOMPILED_RUNTIME) | 
|   9471   Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); |   9004   Array& debug_positions_array = Array::Handle(raw_ptr()->debug_positions_); | 
|   9472   if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { |   9005   if (debug_positions_array.IsNull() && kind() == RawScript::kKernelTag) { | 
|   9473     // This is created lazily. Now we need it. |   9006     // This is created lazily. Now we need it. | 
|   9474     kernel::CollectTokenPositionsFor(*this); |   9007     kernel::CollectTokenPositionsFor(*this); | 
|   9475   } |   9008   } | 
|   9476 #endif  // !defined(DART_PRECOMPILED_RUNTIME) |   9009 #endif  // !defined(DART_PRECOMPILED_RUNTIME) | 
|   9477   return raw_ptr()->debug_positions_; |   9010   return raw_ptr()->debug_positions_; | 
|   9478 } |   9011 } | 
|   9479  |   9012  | 
|   9480 void Script::set_kind(RawScript::Kind value) const { |   9013 void Script::set_kind(RawScript::Kind value) const { | 
|   9481   StoreNonPointer(&raw_ptr()->kind_, value); |   9014   StoreNonPointer(&raw_ptr()->kind_, value); | 
|   9482 } |   9015 } | 
|   9483  |   9016  | 
|   9484  |  | 
|   9485 void Script::set_load_timestamp(int64_t value) const { |   9017 void Script::set_load_timestamp(int64_t value) const { | 
|   9486   StoreNonPointer(&raw_ptr()->load_timestamp_, value); |   9018   StoreNonPointer(&raw_ptr()->load_timestamp_, value); | 
|   9487 } |   9019 } | 
|   9488  |   9020  | 
|   9489  |  | 
|   9490 void Script::set_tokens(const TokenStream& value) const { |   9021 void Script::set_tokens(const TokenStream& value) const { | 
|   9491   StorePointer(&raw_ptr()->tokens_, value.raw()); |   9022   StorePointer(&raw_ptr()->tokens_, value.raw()); | 
|   9492 } |   9023 } | 
|   9493  |   9024  | 
|   9494  |  | 
|   9495 void Script::Tokenize(const String& private_key, bool use_shared_tokens) const { |   9025 void Script::Tokenize(const String& private_key, bool use_shared_tokens) const { | 
|   9496   if (kind() == RawScript::kKernelTag) { |   9026   if (kind() == RawScript::kKernelTag) { | 
|   9497     return; |   9027     return; | 
|   9498   } |   9028   } | 
|   9499  |   9029  | 
|   9500   Thread* thread = Thread::Current(); |   9030   Thread* thread = Thread::Current(); | 
|   9501   Zone* zone = thread->zone(); |   9031   Zone* zone = thread->zone(); | 
|   9502   const TokenStream& tkns = TokenStream::Handle(zone, tokens()); |   9032   const TokenStream& tkns = TokenStream::Handle(zone, tokens()); | 
|   9503   if (!tkns.IsNull()) { |   9033   if (!tkns.IsNull()) { | 
|   9504     // Already tokenized. |   9034     // Already tokenized. | 
|   9505     return; |   9035     return; | 
|   9506   } |   9036   } | 
|   9507   // Get the source, scan and allocate the token stream. |   9037   // Get the source, scan and allocate the token stream. | 
|   9508   VMTagScope tagScope(thread, VMTag::kCompileScannerTagId); |   9038   VMTagScope tagScope(thread, VMTag::kCompileScannerTagId); | 
|   9509   CSTAT_TIMER_SCOPE(thread, scanner_timer); |   9039   CSTAT_TIMER_SCOPE(thread, scanner_timer); | 
|   9510   const String& src = String::Handle(zone, Source()); |   9040   const String& src = String::Handle(zone, Source()); | 
|   9511   const TokenStream& ts = TokenStream::Handle( |   9041   const TokenStream& ts = TokenStream::Handle( | 
|   9512       zone, TokenStream::New(src, private_key, use_shared_tokens)); |   9042       zone, TokenStream::New(src, private_key, use_shared_tokens)); | 
|   9513   set_tokens(ts); |   9043   set_tokens(ts); | 
|   9514   INC_STAT(thread, src_length, src.Length()); |   9044   INC_STAT(thread, src_length, src.Length()); | 
|   9515 } |   9045 } | 
|   9516  |   9046  | 
|   9517  |  | 
|   9518 void Script::SetLocationOffset(intptr_t line_offset, |   9047 void Script::SetLocationOffset(intptr_t line_offset, | 
|   9519                                intptr_t col_offset) const { |   9048                                intptr_t col_offset) const { | 
|   9520   ASSERT(line_offset >= 0); |   9049   ASSERT(line_offset >= 0); | 
|   9521   ASSERT(col_offset >= 0); |   9050   ASSERT(col_offset >= 0); | 
|   9522   StoreNonPointer(&raw_ptr()->line_offset_, line_offset); |   9051   StoreNonPointer(&raw_ptr()->line_offset_, line_offset); | 
|   9523   StoreNonPointer(&raw_ptr()->col_offset_, col_offset); |   9052   StoreNonPointer(&raw_ptr()->col_offset_, col_offset); | 
|   9524 } |   9053 } | 
|   9525  |   9054  | 
|   9526  |  | 
|   9527 // Specialized for AOT compilation, which does this lookup for every token |   9055 // Specialized for AOT compilation, which does this lookup for every token | 
|   9528 // position that could be part of a stack trace. |   9056 // position that could be part of a stack trace. | 
|   9529 intptr_t Script::GetTokenLineUsingLineStarts( |   9057 intptr_t Script::GetTokenLineUsingLineStarts( | 
|   9530     TokenPosition target_token_pos) const { |   9058     TokenPosition target_token_pos) const { | 
|   9531   if (target_token_pos.IsNoSource()) { |   9059   if (target_token_pos.IsNoSource()) { | 
|   9532     return 0; |   9060     return 0; | 
|   9533   } |   9061   } | 
|   9534   Zone* zone = Thread::Current()->zone(); |   9062   Zone* zone = Thread::Current()->zone(); | 
|   9535   Array& line_starts_array = Array::Handle(zone, line_starts()); |   9063   Array& line_starts_array = Array::Handle(zone, line_starts()); | 
|   9536   Smi& token_pos = Smi::Handle(zone); |   9064   Smi& token_pos = Smi::Handle(zone); | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|   9567     token_pos ^= line_starts_array.At(midpoint); |   9095     token_pos ^= line_starts_array.At(midpoint); | 
|   9568     if (token_pos.Value() > offset) { |   9096     if (token_pos.Value() > offset) { | 
|   9569       max = midpoint - 1; |   9097       max = midpoint - 1; | 
|   9570     } else { |   9098     } else { | 
|   9571       min = midpoint; |   9099       min = midpoint; | 
|   9572     } |   9100     } | 
|   9573   } |   9101   } | 
|   9574   return min + 1;  // Line numbers start at 1. |   9102   return min + 1;  // Line numbers start at 1. | 
|   9575 } |   9103 } | 
|   9576  |   9104  | 
|   9577  |  | 
|   9578 void Script::GetTokenLocation(TokenPosition token_pos, |   9105 void Script::GetTokenLocation(TokenPosition token_pos, | 
|   9579                               intptr_t* line, |   9106                               intptr_t* line, | 
|   9580                               intptr_t* column, |   9107                               intptr_t* column, | 
|   9581                               intptr_t* token_len) const { |   9108                               intptr_t* token_len) const { | 
|   9582   ASSERT(line != NULL); |   9109   ASSERT(line != NULL); | 
|   9583   Zone* zone = Thread::Current()->zone(); |   9110   Zone* zone = Thread::Current()->zone(); | 
|   9584  |   9111  | 
|   9585   if (kind() == RawScript::kKernelTag) { |   9112   if (kind() == RawScript::kKernelTag) { | 
|   9586     const Array& line_starts_array = Array::Handle(zone, line_starts()); |   9113     const Array& line_starts_array = Array::Handle(zone, line_starts()); | 
|   9587     if (line_starts_array.IsNull()) { |   9114     if (line_starts_array.IsNull()) { | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9673         *token_len = 1; |   9200         *token_len = 1; | 
|   9674       } |   9201       } | 
|   9675     } |   9202     } | 
|   9676     // On the first line of the script we must add the column offset. |   9203     // On the first line of the script we must add the column offset. | 
|   9677     if (relative_line == 1) { |   9204     if (relative_line == 1) { | 
|   9678       *column += col_offset(); |   9205       *column += col_offset(); | 
|   9679     } |   9206     } | 
|   9680   } |   9207   } | 
|   9681 } |   9208 } | 
|   9682  |   9209  | 
|   9683  |  | 
|   9684 void Script::TokenRangeAtLine(intptr_t line_number, |   9210 void Script::TokenRangeAtLine(intptr_t line_number, | 
|   9685                               TokenPosition* first_token_index, |   9211                               TokenPosition* first_token_index, | 
|   9686                               TokenPosition* last_token_index) const { |   9212                               TokenPosition* last_token_index) const { | 
|   9687   ASSERT(first_token_index != NULL && last_token_index != NULL); |   9213   ASSERT(first_token_index != NULL && last_token_index != NULL); | 
|   9688   ASSERT(line_number > 0); |   9214   ASSERT(line_number > 0); | 
|   9689  |   9215  | 
|   9690   if (kind() == RawScript::kKernelTag) { |   9216   if (kind() == RawScript::kKernelTag) { | 
|   9691     const Array& line_starts_array = Array::Handle(line_starts()); |   9217     const Array& line_starts_array = Array::Handle(line_starts()); | 
|   9692     if (line_starts_array.IsNull()) { |   9218     if (line_starts_array.IsNull()) { | 
|   9693       // Scripts in the AOT snapshot do not have a line starts array. |   9219       // Scripts in the AOT snapshot do not have a line starts array. | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9746   // know whether the previous token is a simple one or not. |   9272   // know whether the previous token is a simple one or not. | 
|   9747   TokenPosition end_pos = *first_token_index; |   9273   TokenPosition end_pos = *first_token_index; | 
|   9748   while (tkit.CurrentTokenKind() != Token::kNEWLINE && |   9274   while (tkit.CurrentTokenKind() != Token::kNEWLINE && | 
|   9749          tkit.CurrentTokenKind() != Token::kEOS) { |   9275          tkit.CurrentTokenKind() != Token::kEOS) { | 
|   9750     end_pos = tkit.CurrentPosition(); |   9276     end_pos = tkit.CurrentPosition(); | 
|   9751     tkit.Advance(); |   9277     tkit.Advance(); | 
|   9752   } |   9278   } | 
|   9753   *last_token_index = end_pos; |   9279   *last_token_index = end_pos; | 
|   9754 } |   9280 } | 
|   9755  |   9281  | 
|   9756  |  | 
|   9757 int32_t Script::SourceFingerprint() const { |   9282 int32_t Script::SourceFingerprint() const { | 
|   9758   return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos), |   9283   return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos), | 
|   9759                            TokenPosition(TokenPosition::kMaxSourcePos)); |   9284                            TokenPosition(TokenPosition::kMaxSourcePos)); | 
|   9760 } |   9285 } | 
|   9761  |   9286  | 
|   9762  |  | 
|   9763 int32_t Script::SourceFingerprint(TokenPosition start, |   9287 int32_t Script::SourceFingerprint(TokenPosition start, | 
|   9764                                   TokenPosition end) const { |   9288                                   TokenPosition end) const { | 
|   9765   uint32_t result = 0; |   9289   uint32_t result = 0; | 
|   9766   Zone* zone = Thread::Current()->zone(); |   9290   Zone* zone = Thread::Current()->zone(); | 
|   9767   TokenStream::Iterator tokens_iterator( |   9291   TokenStream::Iterator tokens_iterator( | 
|   9768       zone, TokenStream::Handle(zone, tokens()), start); |   9292       zone, TokenStream::Handle(zone, tokens()), start); | 
|   9769   Object& obj = Object::Handle(zone); |   9293   Object& obj = Object::Handle(zone); | 
|   9770   String& literal = String::Handle(zone); |   9294   String& literal = String::Handle(zone); | 
|   9771   while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) && |   9295   while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) && | 
|   9772          (tokens_iterator.CurrentPosition() < end)) { |   9296          (tokens_iterator.CurrentPosition() < end)) { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   9783       val = literal.Hash(); |   9307       val = literal.Hash(); | 
|   9784     } |   9308     } | 
|   9785     result = 31 * result + val; |   9309     result = 31 * result + val; | 
|   9786     tokens_iterator.Advance(); |   9310     tokens_iterator.Advance(); | 
|   9787   } |   9311   } | 
|   9788   result = result & ((static_cast<uint32_t>(1) << 31) - 1); |   9312   result = result & ((static_cast<uint32_t>(1) << 31) - 1); | 
|   9789   ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); |   9313   ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); | 
|   9790   return result; |   9314   return result; | 
|   9791 } |   9315 } | 
|   9792  |   9316  | 
|   9793  |  | 
|   9794 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { |   9317 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { | 
|   9795   const String& src = String::Handle(Source()); |   9318   const String& src = String::Handle(Source()); | 
|   9796   if (src.IsNull()) { |   9319   if (src.IsNull()) { | 
|   9797     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |   9320     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|   9798     return Symbols::OptimizedOut().raw(); |   9321     return Symbols::OptimizedOut().raw(); | 
|   9799   } |   9322   } | 
|   9800   intptr_t relative_line_number = line_number - line_offset(); |   9323   intptr_t relative_line_number = line_number - line_offset(); | 
|   9801   intptr_t current_line = 1; |   9324   intptr_t current_line = 1; | 
|   9802   intptr_t line_start_idx = -1; |   9325   intptr_t line_start_idx = -1; | 
|   9803   intptr_t last_char_idx = -1; |   9326   intptr_t last_char_idx = -1; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   9819   // Guarantee that returned string is never NULL. |   9342   // Guarantee that returned string is never NULL. | 
|   9820  |   9343  | 
|   9821   if (line_start_idx >= 0) { |   9344   if (line_start_idx >= 0) { | 
|   9822     return String::SubString(src, line_start_idx, |   9345     return String::SubString(src, line_start_idx, | 
|   9823                              last_char_idx - line_start_idx + 1, space); |   9346                              last_char_idx - line_start_idx + 1, space); | 
|   9824   } else { |   9347   } else { | 
|   9825     return Symbols::Empty().raw(); |   9348     return Symbols::Empty().raw(); | 
|   9826   } |   9349   } | 
|   9827 } |   9350 } | 
|   9828  |   9351  | 
|   9829  |  | 
|   9830 RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const { |   9352 RawString* Script::GetSnippet(TokenPosition from, TokenPosition to) const { | 
|   9831   intptr_t from_line; |   9353   intptr_t from_line; | 
|   9832   intptr_t from_column; |   9354   intptr_t from_column; | 
|   9833   intptr_t to_line; |   9355   intptr_t to_line; | 
|   9834   intptr_t to_column; |   9356   intptr_t to_column; | 
|   9835   GetTokenLocation(from, &from_line, &from_column); |   9357   GetTokenLocation(from, &from_line, &from_column); | 
|   9836   GetTokenLocation(to, &to_line, &to_column); |   9358   GetTokenLocation(to, &to_line, &to_column); | 
|   9837   return GetSnippet(from_line, from_column, to_line, to_column); |   9359   return GetSnippet(from_line, from_column, to_line, to_column); | 
|   9838 } |   9360 } | 
|   9839  |   9361  | 
|   9840  |  | 
|   9841 RawString* Script::GetSnippet(intptr_t from_line, |   9362 RawString* Script::GetSnippet(intptr_t from_line, | 
|   9842                               intptr_t from_column, |   9363                               intptr_t from_column, | 
|   9843                               intptr_t to_line, |   9364                               intptr_t to_line, | 
|   9844                               intptr_t to_column) const { |   9365                               intptr_t to_column) const { | 
|   9845   const String& src = String::Handle(Source()); |   9366   const String& src = String::Handle(Source()); | 
|   9846   if (src.IsNull()) { |   9367   if (src.IsNull()) { | 
|   9847     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |   9368     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|   9848     return Symbols::OptimizedOut().raw(); |   9369     return Symbols::OptimizedOut().raw(); | 
|   9849   } |   9370   } | 
|   9850   intptr_t length = src.Length(); |   9371   intptr_t length = src.Length(); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9885     } |   9406     } | 
|   9886   } |   9407   } | 
|   9887   String& snippet = String::Handle(); |   9408   String& snippet = String::Handle(); | 
|   9888   if ((snippet_start != -1) && (snippet_end != -1)) { |   9409   if ((snippet_start != -1) && (snippet_end != -1)) { | 
|   9889     snippet = |   9410     snippet = | 
|   9890         String::SubString(src, snippet_start, snippet_end - snippet_start); |   9411         String::SubString(src, snippet_start, snippet_end - snippet_start); | 
|   9891   } |   9412   } | 
|   9892   return snippet.raw(); |   9413   return snippet.raw(); | 
|   9893 } |   9414 } | 
|   9894  |   9415  | 
|   9895  |  | 
|   9896 RawScript* Script::New() { |   9416 RawScript* Script::New() { | 
|   9897   ASSERT(Object::script_class() != Class::null()); |   9417   ASSERT(Object::script_class() != Class::null()); | 
|   9898   RawObject* raw = |   9418   RawObject* raw = | 
|   9899       Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld); |   9419       Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld); | 
|   9900   return reinterpret_cast<RawScript*>(raw); |   9420   return reinterpret_cast<RawScript*>(raw); | 
|   9901 } |   9421 } | 
|   9902  |   9422  | 
|   9903  |  | 
|   9904 RawScript* Script::New(const String& url, |   9423 RawScript* Script::New(const String& url, | 
|   9905                        const String& source, |   9424                        const String& source, | 
|   9906                        RawScript::Kind kind) { |   9425                        RawScript::Kind kind) { | 
|   9907   return Script::New(url, url, source, kind); |   9426   return Script::New(url, url, source, kind); | 
|   9908 } |   9427 } | 
|   9909  |   9428  | 
|   9910  |  | 
|   9911 RawScript* Script::New(const String& url, |   9429 RawScript* Script::New(const String& url, | 
|   9912                        const String& resolved_url, |   9430                        const String& resolved_url, | 
|   9913                        const String& source, |   9431                        const String& source, | 
|   9914                        RawScript::Kind kind) { |   9432                        RawScript::Kind kind) { | 
|   9915   Thread* thread = Thread::Current(); |   9433   Thread* thread = Thread::Current(); | 
|   9916   Zone* zone = thread->zone(); |   9434   Zone* zone = thread->zone(); | 
|   9917   const Script& result = Script::Handle(zone, Script::New()); |   9435   const Script& result = Script::Handle(zone, Script::New()); | 
|   9918   result.set_url(String::Handle(zone, Symbols::New(thread, url))); |   9436   result.set_url(String::Handle(zone, Symbols::New(thread, url))); | 
|   9919   result.set_resolved_url( |   9437   result.set_resolved_url( | 
|   9920       String::Handle(zone, Symbols::New(thread, resolved_url))); |   9438       String::Handle(zone, Symbols::New(thread, resolved_url))); | 
|   9921   result.set_source(source); |   9439   result.set_source(source); | 
|   9922   result.set_kind(kind); |   9440   result.set_kind(kind); | 
|   9923   result.set_load_timestamp( |   9441   result.set_load_timestamp( | 
|   9924       FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis()); |   9442       FLAG_remove_script_timestamps_for_test ? 0 : OS::GetCurrentTimeMillis()); | 
|   9925   result.SetLocationOffset(0, 0); |   9443   result.SetLocationOffset(0, 0); | 
|   9926   return result.raw(); |   9444   return result.raw(); | 
|   9927 } |   9445 } | 
|   9928  |   9446  | 
|   9929  |  | 
|   9930 const char* Script::ToCString() const { |   9447 const char* Script::ToCString() const { | 
|   9931   const String& name = String::Handle(url()); |   9448   const String& name = String::Handle(url()); | 
|   9932   return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString()); |   9449   return OS::SCreate(Thread::Current()->zone(), "Script(%s)", name.ToCString()); | 
|   9933 } |   9450 } | 
|   9934  |   9451  | 
|   9935  |  | 
|   9936 RawLibrary* Script::FindLibrary() const { |   9452 RawLibrary* Script::FindLibrary() const { | 
|   9937   Thread* thread = Thread::Current(); |   9453   Thread* thread = Thread::Current(); | 
|   9938   Zone* zone = thread->zone(); |   9454   Zone* zone = thread->zone(); | 
|   9939   Isolate* isolate = thread->isolate(); |   9455   Isolate* isolate = thread->isolate(); | 
|   9940   const GrowableObjectArray& libs = |   9456   const GrowableObjectArray& libs = | 
|   9941       GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |   9457       GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 
|   9942   Library& lib = Library::Handle(zone); |   9458   Library& lib = Library::Handle(zone); | 
|   9943   Array& scripts = Array::Handle(zone); |   9459   Array& scripts = Array::Handle(zone); | 
|   9944   for (intptr_t i = 0; i < libs.Length(); i++) { |   9460   for (intptr_t i = 0; i < libs.Length(); i++) { | 
|   9945     lib ^= libs.At(i); |   9461     lib ^= libs.At(i); | 
|   9946     scripts = lib.LoadedScripts(); |   9462     scripts = lib.LoadedScripts(); | 
|   9947     for (intptr_t j = 0; j < scripts.Length(); j++) { |   9463     for (intptr_t j = 0; j < scripts.Length(); j++) { | 
|   9948       if (scripts.At(j) == raw()) { |   9464       if (scripts.At(j) == raw()) { | 
|   9949         return lib.raw(); |   9465         return lib.raw(); | 
|   9950       } |   9466       } | 
|   9951     } |   9467     } | 
|   9952   } |   9468   } | 
|   9953   return Library::null(); |   9469   return Library::null(); | 
|   9954 } |   9470 } | 
|   9955  |   9471  | 
|   9956  |  | 
|   9957 DictionaryIterator::DictionaryIterator(const Library& library) |   9472 DictionaryIterator::DictionaryIterator(const Library& library) | 
|   9958     : array_(Array::Handle(library.dictionary())), |   9473     : array_(Array::Handle(library.dictionary())), | 
|   9959       // Last element in array is a Smi indicating the number of entries used. |   9474       // Last element in array is a Smi indicating the number of entries used. | 
|   9960       size_(Array::Handle(library.dictionary()).Length() - 1), |   9475       size_(Array::Handle(library.dictionary()).Length() - 1), | 
|   9961       next_ix_(0) { |   9476       next_ix_(0) { | 
|   9962   MoveToNextObject(); |   9477   MoveToNextObject(); | 
|   9963 } |   9478 } | 
|   9964  |   9479  | 
|   9965  |  | 
|   9966 RawObject* DictionaryIterator::GetNext() { |   9480 RawObject* DictionaryIterator::GetNext() { | 
|   9967   ASSERT(HasNext()); |   9481   ASSERT(HasNext()); | 
|   9968   int ix = next_ix_++; |   9482   int ix = next_ix_++; | 
|   9969   MoveToNextObject(); |   9483   MoveToNextObject(); | 
|   9970   ASSERT(array_.At(ix) != Object::null()); |   9484   ASSERT(array_.At(ix) != Object::null()); | 
|   9971   return array_.At(ix); |   9485   return array_.At(ix); | 
|   9972 } |   9486 } | 
|   9973  |   9487  | 
|   9974  |  | 
|   9975 void DictionaryIterator::MoveToNextObject() { |   9488 void DictionaryIterator::MoveToNextObject() { | 
|   9976   Object& obj = Object::Handle(array_.At(next_ix_)); |   9489   Object& obj = Object::Handle(array_.At(next_ix_)); | 
|   9977   while (obj.IsNull() && HasNext()) { |   9490   while (obj.IsNull() && HasNext()) { | 
|   9978     next_ix_++; |   9491     next_ix_++; | 
|   9979     obj = array_.At(next_ix_); |   9492     obj = array_.At(next_ix_); | 
|   9980   } |   9493   } | 
|   9981 } |   9494 } | 
|   9982  |   9495  | 
|   9983  |  | 
|   9984 ClassDictionaryIterator::ClassDictionaryIterator(const Library& library, |   9496 ClassDictionaryIterator::ClassDictionaryIterator(const Library& library, | 
|   9985                                                  IterationKind kind) |   9497                                                  IterationKind kind) | 
|   9986     : DictionaryIterator(library), |   9498     : DictionaryIterator(library), | 
|   9987       toplevel_class_(Class::Handle((kind == kIteratePrivate) |   9499       toplevel_class_(Class::Handle((kind == kIteratePrivate) | 
|   9988                                         ? library.toplevel_class() |   9500                                         ? library.toplevel_class() | 
|   9989                                         : Class::null())) { |   9501                                         : Class::null())) { | 
|   9990   MoveToNextClass(); |   9502   MoveToNextClass(); | 
|   9991 } |   9503 } | 
|   9992  |   9504  | 
|   9993  |  | 
|   9994 RawClass* ClassDictionaryIterator::GetNextClass() { |   9505 RawClass* ClassDictionaryIterator::GetNextClass() { | 
|   9995   ASSERT(HasNext()); |   9506   ASSERT(HasNext()); | 
|   9996   Class& cls = Class::Handle(); |   9507   Class& cls = Class::Handle(); | 
|   9997   if (next_ix_ < size_) { |   9508   if (next_ix_ < size_) { | 
|   9998     int ix = next_ix_++; |   9509     int ix = next_ix_++; | 
|   9999     cls ^= array_.At(ix); |   9510     cls ^= array_.At(ix); | 
|  10000     MoveToNextClass(); |   9511     MoveToNextClass(); | 
|  10001     return cls.raw(); |   9512     return cls.raw(); | 
|  10002   } |   9513   } | 
|  10003   ASSERT(!toplevel_class_.IsNull()); |   9514   ASSERT(!toplevel_class_.IsNull()); | 
|  10004   cls = toplevel_class_.raw(); |   9515   cls = toplevel_class_.raw(); | 
|  10005   toplevel_class_ = Class::null(); |   9516   toplevel_class_ = Class::null(); | 
|  10006   return cls.raw(); |   9517   return cls.raw(); | 
|  10007 } |   9518 } | 
|  10008  |   9519  | 
|  10009  |  | 
|  10010 void ClassDictionaryIterator::MoveToNextClass() { |   9520 void ClassDictionaryIterator::MoveToNextClass() { | 
|  10011   Object& obj = Object::Handle(); |   9521   Object& obj = Object::Handle(); | 
|  10012   while (next_ix_ < size_) { |   9522   while (next_ix_ < size_) { | 
|  10013     obj = array_.At(next_ix_); |   9523     obj = array_.At(next_ix_); | 
|  10014     if (obj.IsClass()) { |   9524     if (obj.IsClass()) { | 
|  10015       return; |   9525       return; | 
|  10016     } |   9526     } | 
|  10017     next_ix_++; |   9527     next_ix_++; | 
|  10018   } |   9528   } | 
|  10019 } |   9529 } | 
|  10020  |   9530  | 
|  10021  |  | 
|  10022 LibraryPrefixIterator::LibraryPrefixIterator(const Library& library) |   9531 LibraryPrefixIterator::LibraryPrefixIterator(const Library& library) | 
|  10023     : DictionaryIterator(library) { |   9532     : DictionaryIterator(library) { | 
|  10024   Advance(); |   9533   Advance(); | 
|  10025 } |   9534 } | 
|  10026  |   9535  | 
|  10027  |  | 
|  10028 RawLibraryPrefix* LibraryPrefixIterator::GetNext() { |   9536 RawLibraryPrefix* LibraryPrefixIterator::GetNext() { | 
|  10029   ASSERT(HasNext()); |   9537   ASSERT(HasNext()); | 
|  10030   int ix = next_ix_++; |   9538   int ix = next_ix_++; | 
|  10031   Object& obj = Object::Handle(array_.At(ix)); |   9539   Object& obj = Object::Handle(array_.At(ix)); | 
|  10032   Advance(); |   9540   Advance(); | 
|  10033   return LibraryPrefix::Cast(obj).raw(); |   9541   return LibraryPrefix::Cast(obj).raw(); | 
|  10034 } |   9542 } | 
|  10035  |   9543  | 
|  10036  |  | 
|  10037 void LibraryPrefixIterator::Advance() { |   9544 void LibraryPrefixIterator::Advance() { | 
|  10038   Object& obj = Object::Handle(array_.At(next_ix_)); |   9545   Object& obj = Object::Handle(array_.At(next_ix_)); | 
|  10039   while (!obj.IsLibraryPrefix() && HasNext()) { |   9546   while (!obj.IsLibraryPrefix() && HasNext()) { | 
|  10040     next_ix_++; |   9547     next_ix_++; | 
|  10041     obj = array_.At(next_ix_); |   9548     obj = array_.At(next_ix_); | 
|  10042   } |   9549   } | 
|  10043 } |   9550 } | 
|  10044  |   9551  | 
|  10045  |  | 
|  10046 static void ReportTooManyImports(const Library& lib) { |   9552 static void ReportTooManyImports(const Library& lib) { | 
|  10047   const String& url = String::Handle(lib.url()); |   9553   const String& url = String::Handle(lib.url()); | 
|  10048   Report::MessageF(Report::kError, Script::Handle(lib.LookupScript(url)), |   9554   Report::MessageF(Report::kError, Script::Handle(lib.LookupScript(url)), | 
|  10049                    TokenPosition::kNoSource, Report::AtLocation, |   9555                    TokenPosition::kNoSource, Report::AtLocation, | 
|  10050                    "too many imports in library '%s'", url.ToCString()); |   9556                    "too many imports in library '%s'", url.ToCString()); | 
|  10051   UNREACHABLE(); |   9557   UNREACHABLE(); | 
|  10052 } |   9558 } | 
|  10053  |   9559  | 
|  10054  |  | 
|  10055 void Library::set_num_imports(intptr_t value) const { |   9560 void Library::set_num_imports(intptr_t value) const { | 
|  10056   if (!Utils::IsUint(16, value)) { |   9561   if (!Utils::IsUint(16, value)) { | 
|  10057     ReportTooManyImports(*this); |   9562     ReportTooManyImports(*this); | 
|  10058   } |   9563   } | 
|  10059   StoreNonPointer(&raw_ptr()->num_imports_, value); |   9564   StoreNonPointer(&raw_ptr()->num_imports_, value); | 
|  10060 } |   9565 } | 
|  10061  |   9566  | 
|  10062  |  | 
|  10063 void Library::SetName(const String& name) const { |   9567 void Library::SetName(const String& name) const { | 
|  10064   // Only set name once. |   9568   // Only set name once. | 
|  10065   ASSERT(!Loaded()); |   9569   ASSERT(!Loaded()); | 
|  10066   ASSERT(name.IsSymbol()); |   9570   ASSERT(name.IsSymbol()); | 
|  10067   StorePointer(&raw_ptr()->name_, name.raw()); |   9571   StorePointer(&raw_ptr()->name_, name.raw()); | 
|  10068 } |   9572 } | 
|  10069  |   9573  | 
|  10070  |  | 
|  10071 void Library::SetLoadInProgress() const { |   9574 void Library::SetLoadInProgress() const { | 
|  10072   // Must not already be in the process of being loaded. |   9575   // Must not already be in the process of being loaded. | 
|  10073   ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested); |   9576   ASSERT(raw_ptr()->load_state_ <= RawLibrary::kLoadRequested); | 
|  10074   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress); |   9577   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadInProgress); | 
|  10075 } |   9578 } | 
|  10076  |   9579  | 
|  10077  |  | 
|  10078 void Library::SetLoadRequested() const { |   9580 void Library::SetLoadRequested() const { | 
|  10079   // Must not be already loaded. |   9581   // Must not be already loaded. | 
|  10080   ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated); |   9582   ASSERT(raw_ptr()->load_state_ == RawLibrary::kAllocated); | 
|  10081   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested); |   9583   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadRequested); | 
|  10082 } |   9584 } | 
|  10083  |   9585  | 
|  10084  |  | 
|  10085 void Library::SetLoaded() const { |   9586 void Library::SetLoaded() const { | 
|  10086   // Should not be already loaded or just allocated. |   9587   // Should not be already loaded or just allocated. | 
|  10087   ASSERT(LoadInProgress() || LoadRequested()); |   9588   ASSERT(LoadInProgress() || LoadRequested()); | 
|  10088   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded); |   9589   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoaded); | 
|  10089 } |   9590 } | 
|  10090  |   9591  | 
|  10091  |  | 
|  10092 void Library::SetLoadError(const Instance& error) const { |   9592 void Library::SetLoadError(const Instance& error) const { | 
|  10093   // Should not be already successfully loaded or just allocated. |   9593   // Should not be already successfully loaded or just allocated. | 
|  10094   ASSERT(LoadInProgress() || LoadRequested() || LoadFailed()); |   9594   ASSERT(LoadInProgress() || LoadRequested() || LoadFailed()); | 
|  10095   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadError); |   9595   StoreNonPointer(&raw_ptr()->load_state_, RawLibrary::kLoadError); | 
|  10096   StorePointer(&raw_ptr()->load_error_, error.raw()); |   9596   StorePointer(&raw_ptr()->load_error_, error.raw()); | 
|  10097 } |   9597 } | 
|  10098  |   9598  | 
|  10099  |  | 
|  10100 // Traits for looking up Libraries by url in a hash set. |   9599 // Traits for looking up Libraries by url in a hash set. | 
|  10101 class LibraryUrlTraits { |   9600 class LibraryUrlTraits { | 
|  10102  public: |   9601  public: | 
|  10103   static const char* Name() { return "LibraryUrlTraits"; } |   9602   static const char* Name() { return "LibraryUrlTraits"; } | 
|  10104   static bool ReportStats() { return false; } |   9603   static bool ReportStats() { return false; } | 
|  10105  |   9604  | 
|  10106   // Called when growing the table. |   9605   // Called when growing the table. | 
|  10107   static bool IsMatch(const Object& a, const Object& b) { |   9606   static bool IsMatch(const Object& a, const Object& b) { | 
|  10108     ASSERT(a.IsLibrary() && b.IsLibrary()); |   9607     ASSERT(a.IsLibrary() && b.IsLibrary()); | 
|  10109     // Library objects are always canonical. |   9608     // Library objects are always canonical. | 
|  10110     return a.raw() == b.raw(); |   9609     return a.raw() == b.raw(); | 
|  10111   } |   9610   } | 
|  10112   static uword Hash(const Object& key) { return Library::Cast(key).UrlHash(); } |   9611   static uword Hash(const Object& key) { return Library::Cast(key).UrlHash(); } | 
|  10113 }; |   9612 }; | 
|  10114 typedef UnorderedHashSet<LibraryUrlTraits> LibraryLoadErrorSet; |   9613 typedef UnorderedHashSet<LibraryUrlTraits> LibraryLoadErrorSet; | 
|  10115  |   9614  | 
|  10116  |  | 
|  10117 RawInstance* Library::TransitiveLoadError() const { |   9615 RawInstance* Library::TransitiveLoadError() const { | 
|  10118   if (LoadError() != Instance::null()) { |   9616   if (LoadError() != Instance::null()) { | 
|  10119     return LoadError(); |   9617     return LoadError(); | 
|  10120   } |   9618   } | 
|  10121   Thread* thread = Thread::Current(); |   9619   Thread* thread = Thread::Current(); | 
|  10122   Isolate* isolate = thread->isolate(); |   9620   Isolate* isolate = thread->isolate(); | 
|  10123   Zone* zone = thread->zone(); |   9621   Zone* zone = thread->zone(); | 
|  10124   ObjectStore* object_store = isolate->object_store(); |   9622   ObjectStore* object_store = isolate->object_store(); | 
|  10125   LibraryLoadErrorSet set(object_store->library_load_error_table()); |   9623   LibraryLoadErrorSet set(object_store->library_load_error_table()); | 
|  10126   bool present = false; |   9624   bool present = false; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  10138     HANDLESCOPE(thread); |   9636     HANDLESCOPE(thread); | 
|  10139     lib = ImportLibraryAt(i); |   9637     lib = ImportLibraryAt(i); | 
|  10140     error = lib.TransitiveLoadError(); |   9638     error = lib.TransitiveLoadError(); | 
|  10141     if (!error.IsNull()) { |   9639     if (!error.IsNull()) { | 
|  10142       break; |   9640       break; | 
|  10143     } |   9641     } | 
|  10144   } |   9642   } | 
|  10145   return error.raw(); |   9643   return error.raw(); | 
|  10146 } |   9644 } | 
|  10147  |   9645  | 
|  10148  |  | 
|  10149 void Library::AddPatchClass(const Class& cls) const { |   9646 void Library::AddPatchClass(const Class& cls) const { | 
|  10150   ASSERT(Thread::Current()->IsMutatorThread()); |   9647   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10151   ASSERT(cls.is_patch()); |   9648   ASSERT(cls.is_patch()); | 
|  10152   ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null()); |   9649   ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null()); | 
|  10153   const GrowableObjectArray& patch_classes = |   9650   const GrowableObjectArray& patch_classes = | 
|  10154       GrowableObjectArray::Handle(this->patch_classes()); |   9651       GrowableObjectArray::Handle(this->patch_classes()); | 
|  10155   patch_classes.Add(cls); |   9652   patch_classes.Add(cls); | 
|  10156 } |   9653 } | 
|  10157  |   9654  | 
|  10158  |  | 
|  10159 RawClass* Library::GetPatchClass(const String& name) const { |   9655 RawClass* Library::GetPatchClass(const String& name) const { | 
|  10160   ASSERT(Thread::Current()->IsMutatorThread()); |   9656   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10161   const GrowableObjectArray& patch_classes = |   9657   const GrowableObjectArray& patch_classes = | 
|  10162       GrowableObjectArray::Handle(this->patch_classes()); |   9658       GrowableObjectArray::Handle(this->patch_classes()); | 
|  10163   Object& obj = Object::Handle(); |   9659   Object& obj = Object::Handle(); | 
|  10164   for (intptr_t i = 0; i < patch_classes.Length(); i++) { |   9660   for (intptr_t i = 0; i < patch_classes.Length(); i++) { | 
|  10165     obj = patch_classes.At(i); |   9661     obj = patch_classes.At(i); | 
|  10166     if (obj.IsClass() && |   9662     if (obj.IsClass() && | 
|  10167         (Class::Cast(obj).Name() == name.raw())) {  // Names are canonicalized. |   9663         (Class::Cast(obj).Name() == name.raw())) {  // Names are canonicalized. | 
|  10168       return Class::RawCast(obj.raw()); |   9664       return Class::RawCast(obj.raw()); | 
|  10169     } |   9665     } | 
|  10170   } |   9666   } | 
|  10171   return Class::null(); |   9667   return Class::null(); | 
|  10172 } |   9668 } | 
|  10173  |   9669  | 
|  10174  |  | 
|  10175 void Library::RemovePatchClass(const Class& cls) const { |   9670 void Library::RemovePatchClass(const Class& cls) const { | 
|  10176   ASSERT(Thread::Current()->IsMutatorThread()); |   9671   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10177   ASSERT(cls.is_patch()); |   9672   ASSERT(cls.is_patch()); | 
|  10178   const GrowableObjectArray& patch_classes = |   9673   const GrowableObjectArray& patch_classes = | 
|  10179       GrowableObjectArray::Handle(this->patch_classes()); |   9674       GrowableObjectArray::Handle(this->patch_classes()); | 
|  10180   const intptr_t num_classes = patch_classes.Length(); |   9675   const intptr_t num_classes = patch_classes.Length(); | 
|  10181   intptr_t i = 0; |   9676   intptr_t i = 0; | 
|  10182   while (i < num_classes) { |   9677   while (i < num_classes) { | 
|  10183     if (cls.raw() == patch_classes.At(i)) break; |   9678     if (cls.raw() == patch_classes.At(i)) break; | 
|  10184     i++; |   9679     i++; | 
|  10185   } |   9680   } | 
|  10186   if (i == num_classes) return; |   9681   if (i == num_classes) return; | 
|  10187   // Replace the entry with the script. We keep the script so that |   9682   // Replace the entry with the script. We keep the script so that | 
|  10188   // Library::LoadedScripts() can find it without having to iterate |   9683   // Library::LoadedScripts() can find it without having to iterate | 
|  10189   // over the members of each class. |   9684   // over the members of each class. | 
|  10190   ASSERT(i < num_classes);  // We must have found a class. |   9685   ASSERT(i < num_classes);  // We must have found a class. | 
|  10191   const Script& patch_script = Script::Handle(cls.script()); |   9686   const Script& patch_script = Script::Handle(cls.script()); | 
|  10192   patch_classes.SetAt(i, patch_script); |   9687   patch_classes.SetAt(i, patch_script); | 
|  10193 } |   9688 } | 
|  10194  |   9689  | 
|  10195  |  | 
|  10196 static RawString* MakeClassMetaName(Thread* thread, |   9690 static RawString* MakeClassMetaName(Thread* thread, | 
|  10197                                     Zone* zone, |   9691                                     Zone* zone, | 
|  10198                                     const Class& cls) { |   9692                                     const Class& cls) { | 
|  10199   return Symbols::FromConcat(thread, Symbols::At(), |   9693   return Symbols::FromConcat(thread, Symbols::At(), | 
|  10200                              String::Handle(zone, cls.Name())); |   9694                              String::Handle(zone, cls.Name())); | 
|  10201 } |   9695 } | 
|  10202  |   9696  | 
|  10203  |  | 
|  10204 static RawString* MakeFieldMetaName(Thread* thread, |   9697 static RawString* MakeFieldMetaName(Thread* thread, | 
|  10205                                     Zone* zone, |   9698                                     Zone* zone, | 
|  10206                                     const Field& field) { |   9699                                     const Field& field) { | 
|  10207   const String& cname = String::Handle( |   9700   const String& cname = String::Handle( | 
|  10208       zone, |   9701       zone, | 
|  10209       MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin()))); |   9702       MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin()))); | 
|  10210   GrowableHandlePtrArray<const String> pieces(zone, 3); |   9703   GrowableHandlePtrArray<const String> pieces(zone, 3); | 
|  10211   pieces.Add(cname); |   9704   pieces.Add(cname); | 
|  10212   pieces.Add(Symbols::At()); |   9705   pieces.Add(Symbols::At()); | 
|  10213   pieces.Add(String::Handle(field.name())); |   9706   pieces.Add(String::Handle(field.name())); | 
|  10214   return Symbols::FromConcatAll(thread, pieces); |   9707   return Symbols::FromConcatAll(thread, pieces); | 
|  10215 } |   9708 } | 
|  10216  |   9709  | 
|  10217  |  | 
|  10218 static RawString* MakeFunctionMetaName(Thread* thread, |   9710 static RawString* MakeFunctionMetaName(Thread* thread, | 
|  10219                                        Zone* zone, |   9711                                        Zone* zone, | 
|  10220                                        const Function& func) { |   9712                                        const Function& func) { | 
|  10221   const String& cname = String::Handle( |   9713   const String& cname = String::Handle( | 
|  10222       zone, |   9714       zone, | 
|  10223       MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin()))); |   9715       MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin()))); | 
|  10224   GrowableHandlePtrArray<const String> pieces(zone, 3); |   9716   GrowableHandlePtrArray<const String> pieces(zone, 3); | 
|  10225   pieces.Add(cname); |   9717   pieces.Add(cname); | 
|  10226   pieces.Add(Symbols::At()); |   9718   pieces.Add(Symbols::At()); | 
|  10227   pieces.Add(String::Handle(func.QualifiedScrubbedName())); |   9719   pieces.Add(String::Handle(func.QualifiedScrubbedName())); | 
|  10228   return Symbols::FromConcatAll(thread, pieces); |   9720   return Symbols::FromConcatAll(thread, pieces); | 
|  10229 } |   9721 } | 
|  10230  |   9722  | 
|  10231  |  | 
|  10232 static RawString* MakeTypeParameterMetaName(Thread* thread, |   9723 static RawString* MakeTypeParameterMetaName(Thread* thread, | 
|  10233                                             Zone* zone, |   9724                                             Zone* zone, | 
|  10234                                             const TypeParameter& param) { |   9725                                             const TypeParameter& param) { | 
|  10235   const String& cname = String::Handle( |   9726   const String& cname = String::Handle( | 
|  10236       zone, |   9727       zone, | 
|  10237       MakeClassMetaName(thread, zone, |   9728       MakeClassMetaName(thread, zone, | 
|  10238                         Class::Handle(zone, param.parameterized_class()))); |   9729                         Class::Handle(zone, param.parameterized_class()))); | 
|  10239   GrowableHandlePtrArray<const String> pieces(zone, 3); |   9730   GrowableHandlePtrArray<const String> pieces(zone, 3); | 
|  10240   pieces.Add(cname); |   9731   pieces.Add(cname); | 
|  10241   pieces.Add(Symbols::At()); |   9732   pieces.Add(Symbols::At()); | 
|  10242   pieces.Add(String::Handle(param.name())); |   9733   pieces.Add(String::Handle(param.name())); | 
|  10243   return Symbols::FromConcatAll(thread, pieces); |   9734   return Symbols::FromConcatAll(thread, pieces); | 
|  10244 } |   9735 } | 
|  10245  |   9736  | 
|  10246  |  | 
|  10247 void Library::AddMetadata(const Object& owner, |   9737 void Library::AddMetadata(const Object& owner, | 
|  10248                           const String& name, |   9738                           const String& name, | 
|  10249                           TokenPosition token_pos, |   9739                           TokenPosition token_pos, | 
|  10250                           intptr_t kernel_offset) const { |   9740                           intptr_t kernel_offset) const { | 
|  10251   Thread* thread = Thread::Current(); |   9741   Thread* thread = Thread::Current(); | 
|  10252   ASSERT(thread->IsMutatorThread()); |   9742   ASSERT(thread->IsMutatorThread()); | 
|  10253   Zone* zone = thread->zone(); |   9743   Zone* zone = thread->zone(); | 
|  10254   const String& metaname = String::Handle(zone, Symbols::New(thread, name)); |   9744   const String& metaname = String::Handle(zone, Symbols::New(thread, name)); | 
|  10255   const Field& field = |   9745   const Field& field = | 
|  10256       Field::Handle(zone, Field::NewTopLevel(metaname, |   9746       Field::Handle(zone, Field::NewTopLevel(metaname, | 
|  10257                                              false,  // is_final |   9747                                              false,  // is_final | 
|  10258                                              false,  // is_const |   9748                                              false,  // is_const | 
|  10259                                              owner, token_pos)); |   9749                                              owner, token_pos)); | 
|  10260   field.SetFieldType(Object::dynamic_type()); |   9750   field.SetFieldType(Object::dynamic_type()); | 
|  10261   field.set_is_reflectable(false); |   9751   field.set_is_reflectable(false); | 
|  10262   field.SetStaticValue(Array::empty_array(), true); |   9752   field.SetStaticValue(Array::empty_array(), true); | 
|  10263   field.set_kernel_offset(kernel_offset); |   9753   field.set_kernel_offset(kernel_offset); | 
|  10264   GrowableObjectArray& metadata = |   9754   GrowableObjectArray& metadata = | 
|  10265       GrowableObjectArray::Handle(zone, this->metadata()); |   9755       GrowableObjectArray::Handle(zone, this->metadata()); | 
|  10266   metadata.Add(field, Heap::kOld); |   9756   metadata.Add(field, Heap::kOld); | 
|  10267 } |   9757 } | 
|  10268  |   9758  | 
|  10269  |  | 
|  10270 void Library::AddClassMetadata(const Class& cls, |   9759 void Library::AddClassMetadata(const Class& cls, | 
|  10271                                const Object& tl_owner, |   9760                                const Object& tl_owner, | 
|  10272                                TokenPosition token_pos, |   9761                                TokenPosition token_pos, | 
|  10273                                intptr_t kernel_offset) const { |   9762                                intptr_t kernel_offset) const { | 
|  10274   Thread* thread = Thread::Current(); |   9763   Thread* thread = Thread::Current(); | 
|  10275   Zone* zone = thread->zone(); |   9764   Zone* zone = thread->zone(); | 
|  10276   // We use the toplevel class as the owner of a class's metadata field because |   9765   // We use the toplevel class as the owner of a class's metadata field because | 
|  10277   // a class's metadata is in scope of the library, not the class. |   9766   // a class's metadata is in scope of the library, not the class. | 
|  10278   AddMetadata(tl_owner, |   9767   AddMetadata(tl_owner, | 
|  10279               String::Handle(zone, MakeClassMetaName(thread, zone, cls)), |   9768               String::Handle(zone, MakeClassMetaName(thread, zone, cls)), | 
|  10280               token_pos, kernel_offset); |   9769               token_pos, kernel_offset); | 
|  10281 } |   9770 } | 
|  10282  |   9771  | 
|  10283  |  | 
|  10284 void Library::AddFieldMetadata(const Field& field, |   9772 void Library::AddFieldMetadata(const Field& field, | 
|  10285                                TokenPosition token_pos, |   9773                                TokenPosition token_pos, | 
|  10286                                intptr_t kernel_offset) const { |   9774                                intptr_t kernel_offset) const { | 
|  10287   Thread* thread = Thread::Current(); |   9775   Thread* thread = Thread::Current(); | 
|  10288   Zone* zone = thread->zone(); |   9776   Zone* zone = thread->zone(); | 
|  10289   AddMetadata(Object::Handle(zone, field.RawOwner()), |   9777   AddMetadata(Object::Handle(zone, field.RawOwner()), | 
|  10290               String::Handle(zone, MakeFieldMetaName(thread, zone, field)), |   9778               String::Handle(zone, MakeFieldMetaName(thread, zone, field)), | 
|  10291               token_pos, kernel_offset); |   9779               token_pos, kernel_offset); | 
|  10292 } |   9780 } | 
|  10293  |   9781  | 
|  10294  |  | 
|  10295 void Library::AddFunctionMetadata(const Function& func, |   9782 void Library::AddFunctionMetadata(const Function& func, | 
|  10296                                   TokenPosition token_pos, |   9783                                   TokenPosition token_pos, | 
|  10297                                   intptr_t kernel_offset) const { |   9784                                   intptr_t kernel_offset) const { | 
|  10298   Thread* thread = Thread::Current(); |   9785   Thread* thread = Thread::Current(); | 
|  10299   Zone* zone = thread->zone(); |   9786   Zone* zone = thread->zone(); | 
|  10300   AddMetadata(Object::Handle(zone, func.RawOwner()), |   9787   AddMetadata(Object::Handle(zone, func.RawOwner()), | 
|  10301               String::Handle(zone, MakeFunctionMetaName(thread, zone, func)), |   9788               String::Handle(zone, MakeFunctionMetaName(thread, zone, func)), | 
|  10302               token_pos, kernel_offset); |   9789               token_pos, kernel_offset); | 
|  10303 } |   9790 } | 
|  10304  |   9791  | 
|  10305  |  | 
|  10306 void Library::AddTypeParameterMetadata(const TypeParameter& param, |   9792 void Library::AddTypeParameterMetadata(const TypeParameter& param, | 
|  10307                                        TokenPosition token_pos) const { |   9793                                        TokenPosition token_pos) const { | 
|  10308   Thread* thread = Thread::Current(); |   9794   Thread* thread = Thread::Current(); | 
|  10309   Zone* zone = thread->zone(); |   9795   Zone* zone = thread->zone(); | 
|  10310   AddMetadata( |   9796   AddMetadata( | 
|  10311       Class::Handle(zone, param.parameterized_class()), |   9797       Class::Handle(zone, param.parameterized_class()), | 
|  10312       String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)), |   9798       String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)), | 
|  10313       token_pos); |   9799       token_pos); | 
|  10314 } |   9800 } | 
|  10315  |   9801  | 
|  10316  |  | 
|  10317 void Library::AddLibraryMetadata(const Object& tl_owner, |   9802 void Library::AddLibraryMetadata(const Object& tl_owner, | 
|  10318                                  TokenPosition token_pos) const { |   9803                                  TokenPosition token_pos) const { | 
|  10319   AddMetadata(tl_owner, Symbols::TopLevel(), token_pos); |   9804   AddMetadata(tl_owner, Symbols::TopLevel(), token_pos); | 
|  10320 } |   9805 } | 
|  10321  |   9806  | 
|  10322  |  | 
|  10323 RawString* Library::MakeMetadataName(const Object& obj) const { |   9807 RawString* Library::MakeMetadataName(const Object& obj) const { | 
|  10324   Thread* thread = Thread::Current(); |   9808   Thread* thread = Thread::Current(); | 
|  10325   Zone* zone = thread->zone(); |   9809   Zone* zone = thread->zone(); | 
|  10326   if (obj.IsClass()) { |   9810   if (obj.IsClass()) { | 
|  10327     return MakeClassMetaName(thread, zone, Class::Cast(obj)); |   9811     return MakeClassMetaName(thread, zone, Class::Cast(obj)); | 
|  10328   } else if (obj.IsField()) { |   9812   } else if (obj.IsField()) { | 
|  10329     return MakeFieldMetaName(thread, zone, Field::Cast(obj)); |   9813     return MakeFieldMetaName(thread, zone, Field::Cast(obj)); | 
|  10330   } else if (obj.IsFunction()) { |   9814   } else if (obj.IsFunction()) { | 
|  10331     return MakeFunctionMetaName(thread, zone, Function::Cast(obj)); |   9815     return MakeFunctionMetaName(thread, zone, Function::Cast(obj)); | 
|  10332   } else if (obj.IsLibrary()) { |   9816   } else if (obj.IsLibrary()) { | 
|  10333     return Symbols::TopLevel().raw(); |   9817     return Symbols::TopLevel().raw(); | 
|  10334   } else if (obj.IsTypeParameter()) { |   9818   } else if (obj.IsTypeParameter()) { | 
|  10335     return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj)); |   9819     return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj)); | 
|  10336   } |   9820   } | 
|  10337   UNIMPLEMENTED(); |   9821   UNIMPLEMENTED(); | 
|  10338   return String::null(); |   9822   return String::null(); | 
|  10339 } |   9823 } | 
|  10340  |   9824  | 
|  10341  |  | 
|  10342 RawField* Library::GetMetadataField(const String& metaname) const { |   9825 RawField* Library::GetMetadataField(const String& metaname) const { | 
|  10343   ASSERT(Thread::Current()->IsMutatorThread()); |   9826   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10344   const GrowableObjectArray& metadata = |   9827   const GrowableObjectArray& metadata = | 
|  10345       GrowableObjectArray::Handle(this->metadata()); |   9828       GrowableObjectArray::Handle(this->metadata()); | 
|  10346   Field& entry = Field::Handle(); |   9829   Field& entry = Field::Handle(); | 
|  10347   String& entryname = String::Handle(); |   9830   String& entryname = String::Handle(); | 
|  10348   intptr_t num_entries = metadata.Length(); |   9831   intptr_t num_entries = metadata.Length(); | 
|  10349   for (intptr_t i = 0; i < num_entries; i++) { |   9832   for (intptr_t i = 0; i < num_entries; i++) { | 
|  10350     entry ^= metadata.At(i); |   9833     entry ^= metadata.At(i); | 
|  10351     entryname = entry.name(); |   9834     entryname = entry.name(); | 
|  10352     if (entryname.Equals(metaname)) { |   9835     if (entryname.Equals(metaname)) { | 
|  10353       return entry.raw(); |   9836       return entry.raw(); | 
|  10354     } |   9837     } | 
|  10355   } |   9838   } | 
|  10356   return Field::null(); |   9839   return Field::null(); | 
|  10357 } |   9840 } | 
|  10358  |   9841  | 
|  10359  |  | 
|  10360 RawObject* Library::GetMetadata(const Object& obj) const { |   9842 RawObject* Library::GetMetadata(const Object& obj) const { | 
|  10361 #if defined(DART_PRECOMPILED_RUNTIME) |   9843 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  10362   COMPILE_ASSERT(!FLAG_enable_mirrors); |   9844   COMPILE_ASSERT(!FLAG_enable_mirrors); | 
|  10363   return Object::empty_array().raw(); |   9845   return Object::empty_array().raw(); | 
|  10364 #else |   9846 #else | 
|  10365   if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() && |   9847   if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() && | 
|  10366       !obj.IsLibrary() && !obj.IsTypeParameter()) { |   9848       !obj.IsLibrary() && !obj.IsTypeParameter()) { | 
|  10367     return Object::null(); |   9849     return Object::null(); | 
|  10368   } |   9850   } | 
|  10369   const String& metaname = String::Handle(MakeMetadataName(obj)); |   9851   const String& metaname = String::Handle(MakeMetadataName(obj)); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  10382     } |   9864     } | 
|  10383     if (metadata.IsArray()) { |   9865     if (metadata.IsArray()) { | 
|  10384       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); |   9866       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); | 
|  10385       field.SetStaticValue(Array::Cast(metadata), true); |   9867       field.SetStaticValue(Array::Cast(metadata), true); | 
|  10386     } |   9868     } | 
|  10387   } |   9869   } | 
|  10388   return metadata.raw(); |   9870   return metadata.raw(); | 
|  10389 #endif  // defined(DART_PRECOMPILED_RUNTIME) |   9871 #endif  // defined(DART_PRECOMPILED_RUNTIME) | 
|  10390 } |   9872 } | 
|  10391  |   9873  | 
|  10392  |  | 
|  10393 static bool ShouldBePrivate(const String& name) { |   9874 static bool ShouldBePrivate(const String& name) { | 
|  10394   return (name.Length() >= 1 && name.CharAt(0) == '_') || |   9875   return (name.Length() >= 1 && name.CharAt(0) == '_') || | 
|  10395          (name.Length() >= 5 && |   9876          (name.Length() >= 5 && | 
|  10396           (name.CharAt(4) == '_' && |   9877           (name.CharAt(4) == '_' && | 
|  10397            (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && |   9878            (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && | 
|  10398            name.CharAt(1) == 'e' && name.CharAt(2) == 't' && |   9879            name.CharAt(1) == 'e' && name.CharAt(2) == 't' && | 
|  10399            name.CharAt(3) == ':')); |   9880            name.CharAt(3) == ':')); | 
|  10400 } |   9881 } | 
|  10401  |   9882  | 
|  10402  |  | 
|  10403 RawObject* Library::ResolveName(const String& name) const { |   9883 RawObject* Library::ResolveName(const String& name) const { | 
|  10404   Object& obj = Object::Handle(); |   9884   Object& obj = Object::Handle(); | 
|  10405   if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) { |   9885   if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) { | 
|  10406     return obj.raw(); |   9886     return obj.raw(); | 
|  10407   } |   9887   } | 
|  10408   obj = LookupLocalObject(name); |   9888   obj = LookupLocalObject(name); | 
|  10409   if (!obj.IsNull()) { |   9889   if (!obj.IsNull()) { | 
|  10410     // Names that are in this library's dictionary and are unmangled |   9890     // Names that are in this library's dictionary and are unmangled | 
|  10411     // are not cached. This reduces the size of the cache. |   9891     // are not cached. This reduces the size of the cache. | 
|  10412     return obj.raw(); |   9892     return obj.raw(); | 
|  10413   } |   9893   } | 
|  10414   String& accessor_name = String::Handle(Field::LookupGetterSymbol(name)); |   9894   String& accessor_name = String::Handle(Field::LookupGetterSymbol(name)); | 
|  10415   if (!accessor_name.IsNull()) { |   9895   if (!accessor_name.IsNull()) { | 
|  10416     obj = LookupLocalObject(accessor_name); |   9896     obj = LookupLocalObject(accessor_name); | 
|  10417   } |   9897   } | 
|  10418   if (obj.IsNull()) { |   9898   if (obj.IsNull()) { | 
|  10419     accessor_name = Field::LookupSetterSymbol(name); |   9899     accessor_name = Field::LookupSetterSymbol(name); | 
|  10420     if (!accessor_name.IsNull()) { |   9900     if (!accessor_name.IsNull()) { | 
|  10421       obj = LookupLocalObject(accessor_name); |   9901       obj = LookupLocalObject(accessor_name); | 
|  10422     } |   9902     } | 
|  10423     if (obj.IsNull() && !ShouldBePrivate(name)) { |   9903     if (obj.IsNull() && !ShouldBePrivate(name)) { | 
|  10424       obj = LookupImportedObject(name); |   9904       obj = LookupImportedObject(name); | 
|  10425     } |   9905     } | 
|  10426   } |   9906   } | 
|  10427   AddToResolvedNamesCache(name, obj); |   9907   AddToResolvedNamesCache(name, obj); | 
|  10428   return obj.raw(); |   9908   return obj.raw(); | 
|  10429 } |   9909 } | 
|  10430  |   9910  | 
|  10431  |  | 
|  10432 class StringEqualsTraits { |   9911 class StringEqualsTraits { | 
|  10433  public: |   9912  public: | 
|  10434   static const char* Name() { return "StringEqualsTraits"; } |   9913   static const char* Name() { return "StringEqualsTraits"; } | 
|  10435   static bool ReportStats() { return false; } |   9914   static bool ReportStats() { return false; } | 
|  10436  |   9915  | 
|  10437   static bool IsMatch(const Object& a, const Object& b) { |   9916   static bool IsMatch(const Object& a, const Object& b) { | 
|  10438     return String::Cast(a).Equals(String::Cast(b)); |   9917     return String::Cast(a).Equals(String::Cast(b)); | 
|  10439   } |   9918   } | 
|  10440   static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } |   9919   static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } | 
|  10441 }; |   9920 }; | 
|  10442 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap; |   9921 typedef UnorderedHashMap<StringEqualsTraits> ResolvedNamesMap; | 
|  10443  |   9922  | 
|  10444  |  | 
|  10445 // Returns true if the name is found in the cache, false no cache hit. |   9923 // Returns true if the name is found in the cache, false no cache hit. | 
|  10446 // obj is set to the cached entry. It may be null, indicating that the |   9924 // obj is set to the cached entry. It may be null, indicating that the | 
|  10447 // name does not resolve to anything in this library. |   9925 // name does not resolve to anything in this library. | 
|  10448 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const { |   9926 bool Library::LookupResolvedNamesCache(const String& name, Object* obj) const { | 
|  10449   if (resolved_names() == Array::null()) { |   9927   if (resolved_names() == Array::null()) { | 
|  10450     return false; |   9928     return false; | 
|  10451   } |   9929   } | 
|  10452   ResolvedNamesMap cache(resolved_names()); |   9930   ResolvedNamesMap cache(resolved_names()); | 
|  10453   bool present = false; |   9931   bool present = false; | 
|  10454   *obj = cache.GetOrNull(name, &present); |   9932   *obj = cache.GetOrNull(name, &present); | 
|  10455 // Mutator compiler thread may add entries and therefore |   9933 // Mutator compiler thread may add entries and therefore | 
|  10456 // change 'resolved_names()' while running a background compilation; |   9934 // change 'resolved_names()' while running a background compilation; | 
|  10457 // ASSERT that 'resolved_names()' has not changed only in mutator. |   9935 // ASSERT that 'resolved_names()' has not changed only in mutator. | 
|  10458 #if defined(DEBUG) |   9936 #if defined(DEBUG) | 
|  10459   if (Thread::Current()->IsMutatorThread()) { |   9937   if (Thread::Current()->IsMutatorThread()) { | 
|  10460     ASSERT(cache.Release().raw() == resolved_names()); |   9938     ASSERT(cache.Release().raw() == resolved_names()); | 
|  10461   } else { |   9939   } else { | 
|  10462     // Release must be called in debug mode. |   9940     // Release must be called in debug mode. | 
|  10463     cache.Release(); |   9941     cache.Release(); | 
|  10464   } |   9942   } | 
|  10465 #endif |   9943 #endif | 
|  10466   return present; |   9944   return present; | 
|  10467 } |   9945 } | 
|  10468  |   9946  | 
|  10469  |  | 
|  10470 // Add a name to the resolved name cache. This name resolves to the |   9947 // Add a name to the resolved name cache. This name resolves to the | 
|  10471 // given object in this library scope. obj may be null, which means |   9948 // given object in this library scope. obj may be null, which means | 
|  10472 // the name does not resolve to anything in this library scope. |   9949 // the name does not resolve to anything in this library scope. | 
|  10473 void Library::AddToResolvedNamesCache(const String& name, |   9950 void Library::AddToResolvedNamesCache(const String& name, | 
|  10474                                       const Object& obj) const { |   9951                                       const Object& obj) const { | 
|  10475   if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { |   9952   if (!FLAG_use_lib_cache || Compiler::IsBackgroundCompilation()) { | 
|  10476     return; |   9953     return; | 
|  10477   } |   9954   } | 
|  10478   if (resolved_names() == Array::null()) { |   9955   if (resolved_names() == Array::null()) { | 
|  10479     InitResolvedNamesCache(); |   9956     InitResolvedNamesCache(); | 
|  10480   } |   9957   } | 
|  10481   ResolvedNamesMap cache(resolved_names()); |   9958   ResolvedNamesMap cache(resolved_names()); | 
|  10482   cache.UpdateOrInsert(name, obj); |   9959   cache.UpdateOrInsert(name, obj); | 
|  10483   StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); |   9960   StorePointer(&raw_ptr()->resolved_names_, cache.Release().raw()); | 
|  10484 } |   9961 } | 
|  10485  |   9962  | 
|  10486  |  | 
|  10487 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const { |   9963 bool Library::LookupExportedNamesCache(const String& name, Object* obj) const { | 
|  10488   ASSERT(FLAG_use_exp_cache); |   9964   ASSERT(FLAG_use_exp_cache); | 
|  10489   if (exported_names() == Array::null()) { |   9965   if (exported_names() == Array::null()) { | 
|  10490     return false; |   9966     return false; | 
|  10491   } |   9967   } | 
|  10492   ResolvedNamesMap cache(exported_names()); |   9968   ResolvedNamesMap cache(exported_names()); | 
|  10493   bool present = false; |   9969   bool present = false; | 
|  10494   *obj = cache.GetOrNull(name, &present); |   9970   *obj = cache.GetOrNull(name, &present); | 
|  10495 // Mutator compiler thread may add entries and therefore |   9971 // Mutator compiler thread may add entries and therefore | 
|  10496 // change 'exported_names()' while running a background compilation; |   9972 // change 'exported_names()' while running a background compilation; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  10512     return; |   9988     return; | 
|  10513   } |   9989   } | 
|  10514   if (exported_names() == Array::null()) { |   9990   if (exported_names() == Array::null()) { | 
|  10515     InitExportedNamesCache(); |   9991     InitExportedNamesCache(); | 
|  10516   } |   9992   } | 
|  10517   ResolvedNamesMap cache(exported_names()); |   9993   ResolvedNamesMap cache(exported_names()); | 
|  10518   cache.UpdateOrInsert(name, obj); |   9994   cache.UpdateOrInsert(name, obj); | 
|  10519   StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); |   9995   StorePointer(&raw_ptr()->exported_names_, cache.Release().raw()); | 
|  10520 } |   9996 } | 
|  10521  |   9997  | 
|  10522  |  | 
|  10523 void Library::InvalidateResolvedName(const String& name) const { |   9998 void Library::InvalidateResolvedName(const String& name) const { | 
|  10524   Thread* thread = Thread::Current(); |   9999   Thread* thread = Thread::Current(); | 
|  10525   Zone* zone = thread->zone(); |  10000   Zone* zone = thread->zone(); | 
|  10526   Object& entry = Object::Handle(zone); |  10001   Object& entry = Object::Handle(zone); | 
|  10527   if (LookupResolvedNamesCache(name, &entry)) { |  10002   if (LookupResolvedNamesCache(name, &entry)) { | 
|  10528     // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. |  10003     // TODO(koda): Support deleted sentinel in snapshots and remove only 'name'. | 
|  10529     ClearResolvedNamesCache(); |  10004     ClearResolvedNamesCache(); | 
|  10530   } |  10005   } | 
|  10531   // When a new name is added to a library, we need to invalidate all |  10006   // When a new name is added to a library, we need to invalidate all | 
|  10532   // caches that contain an entry for this name. If the name was previously |  10007   // caches that contain an entry for this name. If the name was previously | 
|  10533   // looked up but could not be resolved, the cache contains a null entry. |  10008   // looked up but could not be resolved, the cache contains a null entry. | 
|  10534   GrowableObjectArray& libs = GrowableObjectArray::Handle( |  10009   GrowableObjectArray& libs = GrowableObjectArray::Handle( | 
|  10535       zone, thread->isolate()->object_store()->libraries()); |  10010       zone, thread->isolate()->object_store()->libraries()); | 
|  10536   Library& lib = Library::Handle(zone); |  10011   Library& lib = Library::Handle(zone); | 
|  10537   intptr_t num_libs = libs.Length(); |  10012   intptr_t num_libs = libs.Length(); | 
|  10538   for (intptr_t i = 0; i < num_libs; i++) { |  10013   for (intptr_t i = 0; i < num_libs; i++) { | 
|  10539     lib ^= libs.At(i); |  10014     lib ^= libs.At(i); | 
|  10540     if (lib.LookupExportedNamesCache(name, &entry)) { |  10015     if (lib.LookupExportedNamesCache(name, &entry)) { | 
|  10541       lib.ClearExportedNamesCache(); |  10016       lib.ClearExportedNamesCache(); | 
|  10542     } |  10017     } | 
|  10543   } |  10018   } | 
|  10544 } |  10019 } | 
|  10545  |  10020  | 
|  10546  |  | 
|  10547 // Invalidate all exported names caches in the isolate. |  10021 // Invalidate all exported names caches in the isolate. | 
|  10548 void Library::InvalidateExportedNamesCaches() { |  10022 void Library::InvalidateExportedNamesCaches() { | 
|  10549   GrowableObjectArray& libs = GrowableObjectArray::Handle( |  10023   GrowableObjectArray& libs = GrowableObjectArray::Handle( | 
|  10550       Isolate::Current()->object_store()->libraries()); |  10024       Isolate::Current()->object_store()->libraries()); | 
|  10551   Library& lib = Library::Handle(); |  10025   Library& lib = Library::Handle(); | 
|  10552   intptr_t num_libs = libs.Length(); |  10026   intptr_t num_libs = libs.Length(); | 
|  10553   for (intptr_t i = 0; i < num_libs; i++) { |  10027   for (intptr_t i = 0; i < num_libs; i++) { | 
|  10554     lib ^= libs.At(i); |  10028     lib ^= libs.At(i); | 
|  10555     lib.ClearExportedNamesCache(); |  10029     lib.ClearExportedNamesCache(); | 
|  10556   } |  10030   } | 
|  10557 } |  10031 } | 
|  10558  |  10032  | 
|  10559  |  | 
|  10560 void Library::RehashDictionary(const Array& old_dict, |  10033 void Library::RehashDictionary(const Array& old_dict, | 
|  10561                                intptr_t new_dict_size) const { |  10034                                intptr_t new_dict_size) const { | 
|  10562   intptr_t old_dict_size = old_dict.Length() - 1; |  10035   intptr_t old_dict_size = old_dict.Length() - 1; | 
|  10563   const Array& new_dict = |  10036   const Array& new_dict = | 
|  10564       Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); |  10037       Array::Handle(Array::New(new_dict_size + 1, Heap::kOld)); | 
|  10565   // Rehash all elements from the original dictionary |  10038   // Rehash all elements from the original dictionary | 
|  10566   // to the newly allocated array. |  10039   // to the newly allocated array. | 
|  10567   Object& entry = Class::Handle(); |  10040   Object& entry = Class::Handle(); | 
|  10568   String& entry_name = String::Handle(); |  10041   String& entry_name = String::Handle(); | 
|  10569   Object& new_entry = Object::Handle(); |  10042   Object& new_entry = Object::Handle(); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  10585     } |  10058     } | 
|  10586   } |  10059   } | 
|  10587   // Set used count. |  10060   // Set used count. | 
|  10588   ASSERT(used < new_dict_size);  // Need at least one empty slot. |  10061   ASSERT(used < new_dict_size);  // Need at least one empty slot. | 
|  10589   new_entry = Smi::New(used); |  10062   new_entry = Smi::New(used); | 
|  10590   new_dict.SetAt(new_dict_size, new_entry); |  10063   new_dict.SetAt(new_dict_size, new_entry); | 
|  10591   // Remember the new dictionary now. |  10064   // Remember the new dictionary now. | 
|  10592   StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); |  10065   StorePointer(&raw_ptr()->dictionary_, new_dict.raw()); | 
|  10593 } |  10066 } | 
|  10594  |  10067  | 
|  10595  |  | 
|  10596 void Library::AddObject(const Object& obj, const String& name) const { |  10068 void Library::AddObject(const Object& obj, const String& name) const { | 
|  10597   ASSERT(Thread::Current()->IsMutatorThread()); |  10069   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10598   ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || |  10070   ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField() || | 
|  10599          obj.IsLibraryPrefix()); |  10071          obj.IsLibraryPrefix()); | 
|  10600   ASSERT(name.Equals(String::Handle(obj.DictionaryName()))); |  10072   ASSERT(name.Equals(String::Handle(obj.DictionaryName()))); | 
|  10601   ASSERT(LookupLocalObject(name) == Object::null()); |  10073   ASSERT(LookupLocalObject(name) == Object::null()); | 
|  10602   const Array& dict = Array::Handle(dictionary()); |  10074   const Array& dict = Array::Handle(dictionary()); | 
|  10603   intptr_t dict_size = dict.Length() - 1; |  10075   intptr_t dict_size = dict.Length() - 1; | 
|  10604   intptr_t index = name.Hash() % dict_size; |  10076   intptr_t index = name.Hash() % dict_size; | 
|  10605  |  10077  | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  10623     // TODO(iposva): Avoid exponential growth. |  10095     // TODO(iposva): Avoid exponential growth. | 
|  10624     RehashDictionary(dict, 2 * dict_size); |  10096     RehashDictionary(dict, 2 * dict_size); | 
|  10625   } |  10097   } | 
|  10626  |  10098  | 
|  10627   // Invalidate the cache of loaded scripts. |  10099   // Invalidate the cache of loaded scripts. | 
|  10628   if (loaded_scripts() != Array::null()) { |  10100   if (loaded_scripts() != Array::null()) { | 
|  10629     StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |  10101     StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 
|  10630   } |  10102   } | 
|  10631 } |  10103 } | 
|  10632  |  10104  | 
|  10633  |  | 
|  10634 // Lookup a name in the library's re-export namespace. |  10105 // Lookup a name in the library's re-export namespace. | 
|  10635 // This lookup can occur from two different threads: background compiler and |  10106 // This lookup can occur from two different threads: background compiler and | 
|  10636 // mutator thread. |  10107 // mutator thread. | 
|  10637 RawObject* Library::LookupReExport(const String& name, |  10108 RawObject* Library::LookupReExport(const String& name, | 
|  10638                                    ZoneGrowableArray<intptr_t>* trail) const { |  10109                                    ZoneGrowableArray<intptr_t>* trail) const { | 
|  10639   if (!HasExports()) { |  10110   if (!HasExports()) { | 
|  10640     return Object::null(); |  10111     return Object::null(); | 
|  10641   } |  10112   } | 
|  10642  |  10113  | 
|  10643   if (trail == NULL) { |  10114   if (trail == NULL) { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  10666       } |  10137       } | 
|  10667     } |  10138     } | 
|  10668   } |  10139   } | 
|  10669   bool in_cycle = (trail->RemoveLast() < 0); |  10140   bool in_cycle = (trail->RemoveLast() < 0); | 
|  10670   if (FLAG_use_exp_cache && !in_cycle && !Compiler::IsBackgroundCompilation()) { |  10141   if (FLAG_use_exp_cache && !in_cycle && !Compiler::IsBackgroundCompilation()) { | 
|  10671     AddToExportedNamesCache(name, obj); |  10142     AddToExportedNamesCache(name, obj); | 
|  10672   } |  10143   } | 
|  10673   return obj.raw(); |  10144   return obj.raw(); | 
|  10674 } |  10145 } | 
|  10675  |  10146  | 
|  10676  |  | 
|  10677 RawObject* Library::LookupEntry(const String& name, intptr_t* index) const { |  10147 RawObject* Library::LookupEntry(const String& name, intptr_t* index) const { | 
|  10678   Thread* thread = Thread::Current(); |  10148   Thread* thread = Thread::Current(); | 
|  10679   REUSABLE_ARRAY_HANDLESCOPE(thread); |  10149   REUSABLE_ARRAY_HANDLESCOPE(thread); | 
|  10680   REUSABLE_OBJECT_HANDLESCOPE(thread); |  10150   REUSABLE_OBJECT_HANDLESCOPE(thread); | 
|  10681   REUSABLE_STRING_HANDLESCOPE(thread); |  10151   REUSABLE_STRING_HANDLESCOPE(thread); | 
|  10682   Array& dict = thread->ArrayHandle(); |  10152   Array& dict = thread->ArrayHandle(); | 
|  10683   dict ^= dictionary(); |  10153   dict ^= dictionary(); | 
|  10684   intptr_t dict_size = dict.Length() - 1; |  10154   intptr_t dict_size = dict.Length() - 1; | 
|  10685   *index = name.Hash() % dict_size; |  10155   *index = name.Hash() % dict_size; | 
|  10686   Object& entry = thread->ObjectHandle(); |  10156   Object& entry = thread->ObjectHandle(); | 
|  10687   String& entry_name = thread->StringHandle(); |  10157   String& entry_name = thread->StringHandle(); | 
|  10688   entry = dict.At(*index); |  10158   entry = dict.At(*index); | 
|  10689   // Search the entry in the hash set. |  10159   // Search the entry in the hash set. | 
|  10690   while (!entry.IsNull()) { |  10160   while (!entry.IsNull()) { | 
|  10691     entry_name = entry.DictionaryName(); |  10161     entry_name = entry.DictionaryName(); | 
|  10692     ASSERT(!entry_name.IsNull()); |  10162     ASSERT(!entry_name.IsNull()); | 
|  10693     if (entry_name.Equals(name)) { |  10163     if (entry_name.Equals(name)) { | 
|  10694       return entry.raw(); |  10164       return entry.raw(); | 
|  10695     } |  10165     } | 
|  10696     *index = (*index + 1) % dict_size; |  10166     *index = (*index + 1) % dict_size; | 
|  10697     entry = dict.At(*index); |  10167     entry = dict.At(*index); | 
|  10698   } |  10168   } | 
|  10699   return Object::null(); |  10169   return Object::null(); | 
|  10700 } |  10170 } | 
|  10701  |  10171  | 
|  10702  |  | 
|  10703 void Library::ReplaceObject(const Object& obj, const String& name) const { |  10172 void Library::ReplaceObject(const Object& obj, const String& name) const { | 
|  10704   ASSERT(!Compiler::IsBackgroundCompilation()); |  10173   ASSERT(!Compiler::IsBackgroundCompilation()); | 
|  10705   ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField()); |  10174   ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField()); | 
|  10706   ASSERT(LookupLocalObject(name) != Object::null()); |  10175   ASSERT(LookupLocalObject(name) != Object::null()); | 
|  10707  |  10176  | 
|  10708   intptr_t index; |  10177   intptr_t index; | 
|  10709   LookupEntry(name, &index); |  10178   LookupEntry(name, &index); | 
|  10710   // The value is guaranteed to be found. |  10179   // The value is guaranteed to be found. | 
|  10711   const Array& dict = Array::Handle(dictionary()); |  10180   const Array& dict = Array::Handle(dictionary()); | 
|  10712   dict.SetAt(index, obj); |  10181   dict.SetAt(index, obj); | 
|  10713 } |  10182 } | 
|  10714  |  10183  | 
|  10715  |  | 
|  10716 void Library::AddClass(const Class& cls) const { |  10184 void Library::AddClass(const Class& cls) const { | 
|  10717   ASSERT(!Compiler::IsBackgroundCompilation()); |  10185   ASSERT(!Compiler::IsBackgroundCompilation()); | 
|  10718   const String& class_name = String::Handle(cls.Name()); |  10186   const String& class_name = String::Handle(cls.Name()); | 
|  10719   AddObject(cls, class_name); |  10187   AddObject(cls, class_name); | 
|  10720   // Link class to this library. |  10188   // Link class to this library. | 
|  10721   cls.set_library(*this); |  10189   cls.set_library(*this); | 
|  10722   InvalidateResolvedName(class_name); |  10190   InvalidateResolvedName(class_name); | 
|  10723 } |  10191 } | 
|  10724  |  10192  | 
|  10725  |  | 
|  10726 static void AddScriptIfUnique(const GrowableObjectArray& scripts, |  10193 static void AddScriptIfUnique(const GrowableObjectArray& scripts, | 
|  10727                               const Script& candidate) { |  10194                               const Script& candidate) { | 
|  10728   if (candidate.IsNull()) { |  10195   if (candidate.IsNull()) { | 
|  10729     return; |  10196     return; | 
|  10730   } |  10197   } | 
|  10731   Script& script_obj = Script::Handle(); |  10198   Script& script_obj = Script::Handle(); | 
|  10732  |  10199  | 
|  10733   for (int i = 0; i < scripts.Length(); i++) { |  10200   for (int i = 0; i < scripts.Length(); i++) { | 
|  10734     script_obj ^= scripts.At(i); |  10201     script_obj ^= scripts.At(i); | 
|  10735     if (script_obj.raw() == candidate.raw()) { |  10202     if (script_obj.raw() == candidate.raw()) { | 
|  10736       // We already have a reference to this script. |  10203       // We already have a reference to this script. | 
|  10737       return; |  10204       return; | 
|  10738     } |  10205     } | 
|  10739   } |  10206   } | 
|  10740   // Add script to the list of scripts. |  10207   // Add script to the list of scripts. | 
|  10741   scripts.Add(candidate); |  10208   scripts.Add(candidate); | 
|  10742 } |  10209 } | 
|  10743  |  10210  | 
|  10744  |  | 
|  10745 RawArray* Library::LoadedScripts() const { |  10211 RawArray* Library::LoadedScripts() const { | 
|  10746   ASSERT(Thread::Current()->IsMutatorThread()); |  10212   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  10747   // We compute the list of loaded scripts lazily. The result is |  10213   // We compute the list of loaded scripts lazily. The result is | 
|  10748   // cached in loaded_scripts_. |  10214   // cached in loaded_scripts_. | 
|  10749   if (loaded_scripts() == Array::null()) { |  10215   if (loaded_scripts() == Array::null()) { | 
|  10750     // Iterate over the library dictionary and collect all scripts. |  10216     // Iterate over the library dictionary and collect all scripts. | 
|  10751     const GrowableObjectArray& scripts = |  10217     const GrowableObjectArray& scripts = | 
|  10752         GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |  10218         GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 
|  10753     Object& entry = Object::Handle(); |  10219     Object& entry = Object::Handle(); | 
|  10754     Class& cls = Class::Handle(); |  10220     Class& cls = Class::Handle(); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  10799       } |  10265       } | 
|  10800     } |  10266     } | 
|  10801  |  10267  | 
|  10802     // Create the array of scripts and cache it in loaded_scripts_. |  10268     // Create the array of scripts and cache it in loaded_scripts_. | 
|  10803     const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts)); |  10269     const Array& scripts_array = Array::Handle(Array::MakeFixedLength(scripts)); | 
|  10804     StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw()); |  10270     StorePointer(&raw_ptr()->loaded_scripts_, scripts_array.raw()); | 
|  10805   } |  10271   } | 
|  10806   return loaded_scripts(); |  10272   return loaded_scripts(); | 
|  10807 } |  10273 } | 
|  10808  |  10274  | 
|  10809  |  | 
|  10810 // TODO(hausner): we might want to add a script dictionary to the |  10275 // TODO(hausner): we might want to add a script dictionary to the | 
|  10811 // library class to make this lookup faster. |  10276 // library class to make this lookup faster. | 
|  10812 RawScript* Library::LookupScript(const String& url) const { |  10277 RawScript* Library::LookupScript(const String& url) const { | 
|  10813   const intptr_t url_length = url.Length(); |  10278   const intptr_t url_length = url.Length(); | 
|  10814   if (url_length == 0) { |  10279   if (url_length == 0) { | 
|  10815     return Script::null(); |  10280     return Script::null(); | 
|  10816   } |  10281   } | 
|  10817   const Array& scripts = Array::Handle(LoadedScripts()); |  10282   const Array& scripts = Array::Handle(LoadedScripts()); | 
|  10818   Script& script = Script::Handle(); |  10283   Script& script = Script::Handle(); | 
|  10819   String& script_url = String::Handle(); |  10284   String& script_url = String::Handle(); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  10830       if (((url.CharAt(0) == '/') || |  10295       if (((url.CharAt(0) == '/') || | 
|  10831            (script_url.CharAt(start_idx - 1) == '/')) && |  10296            (script_url.CharAt(start_idx - 1) == '/')) && | 
|  10832           url.Equals(script_url, start_idx, url_length)) { |  10297           url.Equals(script_url, start_idx, url_length)) { | 
|  10833         return script.raw(); |  10298         return script.raw(); | 
|  10834       } |  10299       } | 
|  10835     } |  10300     } | 
|  10836   } |  10301   } | 
|  10837   return Script::null(); |  10302   return Script::null(); | 
|  10838 } |  10303 } | 
|  10839  |  10304  | 
|  10840  |  | 
|  10841 RawObject* Library::LookupLocalObject(const String& name) const { |  10305 RawObject* Library::LookupLocalObject(const String& name) const { | 
|  10842   intptr_t index; |  10306   intptr_t index; | 
|  10843   return LookupEntry(name, &index); |  10307   return LookupEntry(name, &index); | 
|  10844 } |  10308 } | 
|  10845  |  10309  | 
|  10846  |  | 
|  10847 RawField* Library::LookupFieldAllowPrivate(const String& name) const { |  10310 RawField* Library::LookupFieldAllowPrivate(const String& name) const { | 
|  10848   Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |  10311   Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); | 
|  10849   if (obj.IsField()) { |  10312   if (obj.IsField()) { | 
|  10850     return Field::Cast(obj).raw(); |  10313     return Field::Cast(obj).raw(); | 
|  10851   } |  10314   } | 
|  10852   return Field::null(); |  10315   return Field::null(); | 
|  10853 } |  10316 } | 
|  10854  |  10317  | 
|  10855  |  | 
|  10856 RawField* Library::LookupLocalField(const String& name) const { |  10318 RawField* Library::LookupLocalField(const String& name) const { | 
|  10857   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |  10319   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 
|  10858   if (obj.IsField()) { |  10320   if (obj.IsField()) { | 
|  10859     return Field::Cast(obj).raw(); |  10321     return Field::Cast(obj).raw(); | 
|  10860   } |  10322   } | 
|  10861   return Field::null(); |  10323   return Field::null(); | 
|  10862 } |  10324 } | 
|  10863  |  10325  | 
|  10864  |  | 
|  10865 RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const { |  10326 RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const { | 
|  10866   Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); |  10327   Object& obj = Object::Handle(LookupObjectAllowPrivate(name)); | 
|  10867   if (obj.IsFunction()) { |  10328   if (obj.IsFunction()) { | 
|  10868     return Function::Cast(obj).raw(); |  10329     return Function::Cast(obj).raw(); | 
|  10869   } |  10330   } | 
|  10870   return Function::null(); |  10331   return Function::null(); | 
|  10871 } |  10332 } | 
|  10872  |  10333  | 
|  10873  |  | 
|  10874 RawFunction* Library::LookupLocalFunction(const String& name) const { |  10334 RawFunction* Library::LookupLocalFunction(const String& name) const { | 
|  10875   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |  10335   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 
|  10876   if (obj.IsFunction()) { |  10336   if (obj.IsFunction()) { | 
|  10877     return Function::Cast(obj).raw(); |  10337     return Function::Cast(obj).raw(); | 
|  10878   } |  10338   } | 
|  10879   return Function::null(); |  10339   return Function::null(); | 
|  10880 } |  10340 } | 
|  10881  |  10341  | 
|  10882  |  | 
|  10883 RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const { |  10342 RawObject* Library::LookupLocalObjectAllowPrivate(const String& name) const { | 
|  10884   Thread* thread = Thread::Current(); |  10343   Thread* thread = Thread::Current(); | 
|  10885   Zone* zone = thread->zone(); |  10344   Zone* zone = thread->zone(); | 
|  10886   Object& obj = Object::Handle(zone, Object::null()); |  10345   Object& obj = Object::Handle(zone, Object::null()); | 
|  10887   obj = LookupLocalObject(name); |  10346   obj = LookupLocalObject(name); | 
|  10888   if (obj.IsNull() && ShouldBePrivate(name)) { |  10347   if (obj.IsNull() && ShouldBePrivate(name)) { | 
|  10889     String& private_name = String::Handle(zone, PrivateName(name)); |  10348     String& private_name = String::Handle(zone, PrivateName(name)); | 
|  10890     obj = LookupLocalObject(private_name); |  10349     obj = LookupLocalObject(private_name); | 
|  10891   } |  10350   } | 
|  10892   return obj.raw(); |  10351   return obj.raw(); | 
|  10893 } |  10352 } | 
|  10894  |  10353  | 
|  10895  |  | 
|  10896 RawObject* Library::LookupObjectAllowPrivate(const String& name) const { |  10354 RawObject* Library::LookupObjectAllowPrivate(const String& name) const { | 
|  10897   // First check if name is found in the local scope of the library. |  10355   // First check if name is found in the local scope of the library. | 
|  10898   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); |  10356   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name)); | 
|  10899   if (!obj.IsNull()) { |  10357   if (!obj.IsNull()) { | 
|  10900     return obj.raw(); |  10358     return obj.raw(); | 
|  10901   } |  10359   } | 
|  10902  |  10360  | 
|  10903   // Do not look up private names in imported libraries. |  10361   // Do not look up private names in imported libraries. | 
|  10904   if (ShouldBePrivate(name)) { |  10362   if (ShouldBePrivate(name)) { | 
|  10905     return Object::null(); |  10363     return Object::null(); | 
|  10906   } |  10364   } | 
|  10907  |  10365  | 
|  10908   // Now check if name is found in any imported libs. |  10366   // Now check if name is found in any imported libs. | 
|  10909   return LookupImportedObject(name); |  10367   return LookupImportedObject(name); | 
|  10910 } |  10368 } | 
|  10911  |  10369  | 
|  10912  |  | 
|  10913 RawObject* Library::LookupImportedObject(const String& name) const { |  10370 RawObject* Library::LookupImportedObject(const String& name) const { | 
|  10914   Object& obj = Object::Handle(); |  10371   Object& obj = Object::Handle(); | 
|  10915   Namespace& import = Namespace::Handle(); |  10372   Namespace& import = Namespace::Handle(); | 
|  10916   Library& import_lib = Library::Handle(); |  10373   Library& import_lib = Library::Handle(); | 
|  10917   String& import_lib_url = String::Handle(); |  10374   String& import_lib_url = String::Handle(); | 
|  10918   String& first_import_lib_url = String::Handle(); |  10375   String& first_import_lib_url = String::Handle(); | 
|  10919   Object& found_obj = Object::Handle(); |  10376   Object& found_obj = Object::Handle(); | 
|  10920   String& found_obj_name = String::Handle(); |  10377   String& found_obj_name = String::Handle(); | 
|  10921   ASSERT(!ShouldBePrivate(name)); |  10378   ASSERT(!ShouldBePrivate(name)); | 
|  10922   for (intptr_t i = 0; i < num_imports(); i++) { |  10379   for (intptr_t i = 0; i < num_imports(); i++) { | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  10964           if (found_obj_name.Equals(second_obj_name)) { |  10421           if (found_obj_name.Equals(second_obj_name)) { | 
|  10965             return Object::null(); |  10422             return Object::null(); | 
|  10966           } |  10423           } | 
|  10967         } |  10424         } | 
|  10968       } |  10425       } | 
|  10969     } |  10426     } | 
|  10970   } |  10427   } | 
|  10971   return found_obj.raw(); |  10428   return found_obj.raw(); | 
|  10972 } |  10429 } | 
|  10973  |  10430  | 
|  10974  |  | 
|  10975 RawClass* Library::LookupClass(const String& name) const { |  10431 RawClass* Library::LookupClass(const String& name) const { | 
|  10976   Object& obj = Object::Handle(ResolveName(name)); |  10432   Object& obj = Object::Handle(ResolveName(name)); | 
|  10977   if (obj.IsClass()) { |  10433   if (obj.IsClass()) { | 
|  10978     return Class::Cast(obj).raw(); |  10434     return Class::Cast(obj).raw(); | 
|  10979   } |  10435   } | 
|  10980   return Class::null(); |  10436   return Class::null(); | 
|  10981 } |  10437 } | 
|  10982  |  10438  | 
|  10983  |  | 
|  10984 RawClass* Library::LookupLocalClass(const String& name) const { |  10439 RawClass* Library::LookupLocalClass(const String& name) const { | 
|  10985   Object& obj = Object::Handle(LookupLocalObject(name)); |  10440   Object& obj = Object::Handle(LookupLocalObject(name)); | 
|  10986   if (obj.IsClass()) { |  10441   if (obj.IsClass()) { | 
|  10987     return Class::Cast(obj).raw(); |  10442     return Class::Cast(obj).raw(); | 
|  10988   } |  10443   } | 
|  10989   return Class::null(); |  10444   return Class::null(); | 
|  10990 } |  10445 } | 
|  10991  |  10446  | 
|  10992  |  | 
|  10993 RawClass* Library::LookupClassAllowPrivate(const String& name) const { |  10447 RawClass* Library::LookupClassAllowPrivate(const String& name) const { | 
|  10994   // See if the class is available in this library or in the top level |  10448   // See if the class is available in this library or in the top level | 
|  10995   // scope of any imported library. |  10449   // scope of any imported library. | 
|  10996   Zone* zone = Thread::Current()->zone(); |  10450   Zone* zone = Thread::Current()->zone(); | 
|  10997   const Class& cls = Class::Handle(zone, LookupClass(name)); |  10451   const Class& cls = Class::Handle(zone, LookupClass(name)); | 
|  10998   if (!cls.IsNull()) { |  10452   if (!cls.IsNull()) { | 
|  10999     return cls.raw(); |  10453     return cls.raw(); | 
|  11000   } |  10454   } | 
|  11001  |  10455  | 
|  11002   // Now try to lookup the class using its private name, but only in |  10456   // Now try to lookup the class using its private name, but only in | 
|  11003   // this library (not in imported libraries). |  10457   // this library (not in imported libraries). | 
|  11004   if (ShouldBePrivate(name)) { |  10458   if (ShouldBePrivate(name)) { | 
|  11005     String& private_name = String::Handle(zone, PrivateName(name)); |  10459     String& private_name = String::Handle(zone, PrivateName(name)); | 
|  11006     const Object& obj = Object::Handle(LookupLocalObject(private_name)); |  10460     const Object& obj = Object::Handle(LookupLocalObject(private_name)); | 
|  11007     if (obj.IsClass()) { |  10461     if (obj.IsClass()) { | 
|  11008       return Class::Cast(obj).raw(); |  10462       return Class::Cast(obj).raw(); | 
|  11009     } |  10463     } | 
|  11010   } |  10464   } | 
|  11011   return Class::null(); |  10465   return Class::null(); | 
|  11012 } |  10466 } | 
|  11013  |  10467  | 
|  11014  |  | 
|  11015 // Mixin applications can have multiple private keys from different libraries. |  10468 // Mixin applications can have multiple private keys from different libraries. | 
|  11016 RawClass* Library::SlowLookupClassAllowMultiPartPrivate( |  10469 RawClass* Library::SlowLookupClassAllowMultiPartPrivate( | 
|  11017     const String& name) const { |  10470     const String& name) const { | 
|  11018   Array& dict = Array::Handle(dictionary()); |  10471   Array& dict = Array::Handle(dictionary()); | 
|  11019   Object& entry = Object::Handle(); |  10472   Object& entry = Object::Handle(); | 
|  11020   String& cls_name = String::Handle(); |  10473   String& cls_name = String::Handle(); | 
|  11021   for (intptr_t i = 0; i < dict.Length(); i++) { |  10474   for (intptr_t i = 0; i < dict.Length(); i++) { | 
|  11022     entry = dict.At(i); |  10475     entry = dict.At(i); | 
|  11023     if (entry.IsClass()) { |  10476     if (entry.IsClass()) { | 
|  11024       cls_name = Class::Cast(entry).Name(); |  10477       cls_name = Class::Cast(entry).Name(); | 
|  11025       // Warning: comparison is not symmetric. |  10478       // Warning: comparison is not symmetric. | 
|  11026       if (String::EqualsIgnoringPrivateKey(cls_name, name)) { |  10479       if (String::EqualsIgnoringPrivateKey(cls_name, name)) { | 
|  11027         return Class::Cast(entry).raw(); |  10480         return Class::Cast(entry).raw(); | 
|  11028       } |  10481       } | 
|  11029     } |  10482     } | 
|  11030   } |  10483   } | 
|  11031   return Class::null(); |  10484   return Class::null(); | 
|  11032 } |  10485 } | 
|  11033  |  10486  | 
|  11034  |  | 
|  11035 RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const { |  10487 RawLibraryPrefix* Library::LookupLocalLibraryPrefix(const String& name) const { | 
|  11036   const Object& obj = Object::Handle(LookupLocalObject(name)); |  10488   const Object& obj = Object::Handle(LookupLocalObject(name)); | 
|  11037   if (obj.IsLibraryPrefix()) { |  10489   if (obj.IsLibraryPrefix()) { | 
|  11038     return LibraryPrefix::Cast(obj).raw(); |  10490     return LibraryPrefix::Cast(obj).raw(); | 
|  11039   } |  10491   } | 
|  11040   return LibraryPrefix::null(); |  10492   return LibraryPrefix::null(); | 
|  11041 } |  10493 } | 
|  11042  |  10494  | 
|  11043  |  | 
|  11044 void Library::set_toplevel_class(const Class& value) const { |  10495 void Library::set_toplevel_class(const Class& value) const { | 
|  11045   ASSERT(raw_ptr()->toplevel_class_ == Class::null()); |  10496   ASSERT(raw_ptr()->toplevel_class_ == Class::null()); | 
|  11046   StorePointer(&raw_ptr()->toplevel_class_, value.raw()); |  10497   StorePointer(&raw_ptr()->toplevel_class_, value.raw()); | 
|  11047 } |  10498 } | 
|  11048  |  10499  | 
|  11049  |  | 
|  11050 RawLibrary* Library::ImportLibraryAt(intptr_t index) const { |  10500 RawLibrary* Library::ImportLibraryAt(intptr_t index) const { | 
|  11051   Namespace& import = Namespace::Handle(ImportAt(index)); |  10501   Namespace& import = Namespace::Handle(ImportAt(index)); | 
|  11052   if (import.IsNull()) { |  10502   if (import.IsNull()) { | 
|  11053     return Library::null(); |  10503     return Library::null(); | 
|  11054   } |  10504   } | 
|  11055   return import.library(); |  10505   return import.library(); | 
|  11056 } |  10506 } | 
|  11057  |  10507  | 
|  11058  |  | 
|  11059 RawNamespace* Library::ImportAt(intptr_t index) const { |  10508 RawNamespace* Library::ImportAt(intptr_t index) const { | 
|  11060   if ((index < 0) || index >= num_imports()) { |  10509   if ((index < 0) || index >= num_imports()) { | 
|  11061     return Namespace::null(); |  10510     return Namespace::null(); | 
|  11062   } |  10511   } | 
|  11063   const Array& import_list = Array::Handle(imports()); |  10512   const Array& import_list = Array::Handle(imports()); | 
|  11064   return Namespace::RawCast(import_list.At(index)); |  10513   return Namespace::RawCast(import_list.At(index)); | 
|  11065 } |  10514 } | 
|  11066  |  10515  | 
|  11067  |  | 
|  11068 bool Library::ImportsCorelib() const { |  10516 bool Library::ImportsCorelib() const { | 
|  11069   Zone* zone = Thread::Current()->zone(); |  10517   Zone* zone = Thread::Current()->zone(); | 
|  11070   Library& imported = Library::Handle(zone); |  10518   Library& imported = Library::Handle(zone); | 
|  11071   intptr_t count = num_imports(); |  10519   intptr_t count = num_imports(); | 
|  11072   for (int i = 0; i < count; i++) { |  10520   for (int i = 0; i < count; i++) { | 
|  11073     imported = ImportLibraryAt(i); |  10521     imported = ImportLibraryAt(i); | 
|  11074     if (imported.IsCoreLibrary()) { |  10522     if (imported.IsCoreLibrary()) { | 
|  11075       return true; |  10523       return true; | 
|  11076     } |  10524     } | 
|  11077   } |  10525   } | 
|  11078   LibraryPrefix& prefix = LibraryPrefix::Handle(zone); |  10526   LibraryPrefix& prefix = LibraryPrefix::Handle(zone); | 
|  11079   LibraryPrefixIterator it(*this); |  10527   LibraryPrefixIterator it(*this); | 
|  11080   while (it.HasNext()) { |  10528   while (it.HasNext()) { | 
|  11081     prefix = it.GetNext(); |  10529     prefix = it.GetNext(); | 
|  11082     count = prefix.num_imports(); |  10530     count = prefix.num_imports(); | 
|  11083     for (int i = 0; i < count; i++) { |  10531     for (int i = 0; i < count; i++) { | 
|  11084       imported = prefix.GetLibrary(i); |  10532       imported = prefix.GetLibrary(i); | 
|  11085       if (imported.IsCoreLibrary()) { |  10533       if (imported.IsCoreLibrary()) { | 
|  11086         return true; |  10534         return true; | 
|  11087       } |  10535       } | 
|  11088     } |  10536     } | 
|  11089   } |  10537   } | 
|  11090   return false; |  10538   return false; | 
|  11091 } |  10539 } | 
|  11092  |  10540  | 
|  11093  |  | 
|  11094 void Library::DropDependenciesAndCaches() const { |  10541 void Library::DropDependenciesAndCaches() const { | 
|  11095   StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); |  10542   StorePointer(&raw_ptr()->imports_, Object::empty_array().raw()); | 
|  11096   StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); |  10543   StorePointer(&raw_ptr()->exports_, Object::empty_array().raw()); | 
|  11097   StoreNonPointer(&raw_ptr()->num_imports_, 0); |  10544   StoreNonPointer(&raw_ptr()->num_imports_, 0); | 
|  11098   StorePointer(&raw_ptr()->resolved_names_, Array::null()); |  10545   StorePointer(&raw_ptr()->resolved_names_, Array::null()); | 
|  11099   StorePointer(&raw_ptr()->exported_names_, Array::null()); |  10546   StorePointer(&raw_ptr()->exported_names_, Array::null()); | 
|  11100   StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); |  10547   StorePointer(&raw_ptr()->loaded_scripts_, Array::null()); | 
|  11101 } |  10548 } | 
|  11102  |  10549  | 
|  11103  |  | 
|  11104 void Library::AddImport(const Namespace& ns) const { |  10550 void Library::AddImport(const Namespace& ns) const { | 
|  11105   Array& imports = Array::Handle(this->imports()); |  10551   Array& imports = Array::Handle(this->imports()); | 
|  11106   intptr_t capacity = imports.Length(); |  10552   intptr_t capacity = imports.Length(); | 
|  11107   if (num_imports() == capacity) { |  10553   if (num_imports() == capacity) { | 
|  11108     capacity = capacity + kImportsCapacityIncrement + (capacity >> 2); |  10554     capacity = capacity + kImportsCapacityIncrement + (capacity >> 2); | 
|  11109     imports = Array::Grow(imports, capacity); |  10555     imports = Array::Grow(imports, capacity); | 
|  11110     StorePointer(&raw_ptr()->imports_, imports.raw()); |  10556     StorePointer(&raw_ptr()->imports_, imports.raw()); | 
|  11111   } |  10557   } | 
|  11112   intptr_t index = num_imports(); |  10558   intptr_t index = num_imports(); | 
|  11113   imports.SetAt(index, ns); |  10559   imports.SetAt(index, ns); | 
|  11114   set_num_imports(index + 1); |  10560   set_num_imports(index + 1); | 
|  11115 } |  10561 } | 
|  11116  |  10562  | 
|  11117  |  | 
|  11118 // Convenience function to determine whether the export list is |  10563 // Convenience function to determine whether the export list is | 
|  11119 // non-empty. |  10564 // non-empty. | 
|  11120 bool Library::HasExports() const { |  10565 bool Library::HasExports() const { | 
|  11121   return exports() != Object::empty_array().raw(); |  10566   return exports() != Object::empty_array().raw(); | 
|  11122 } |  10567 } | 
|  11123  |  10568  | 
|  11124  |  | 
|  11125 // We add one namespace at a time to the exports array and don't |  10569 // We add one namespace at a time to the exports array and don't | 
|  11126 // pre-allocate any unused capacity. The assumption is that |  10570 // pre-allocate any unused capacity. The assumption is that | 
|  11127 // re-exports are quite rare. |  10571 // re-exports are quite rare. | 
|  11128 void Library::AddExport(const Namespace& ns) const { |  10572 void Library::AddExport(const Namespace& ns) const { | 
|  11129   Array& exports = Array::Handle(this->exports()); |  10573   Array& exports = Array::Handle(this->exports()); | 
|  11130   intptr_t num_exports = exports.Length(); |  10574   intptr_t num_exports = exports.Length(); | 
|  11131   exports = Array::Grow(exports, num_exports + 1); |  10575   exports = Array::Grow(exports, num_exports + 1); | 
|  11132   StorePointer(&raw_ptr()->exports_, exports.raw()); |  10576   StorePointer(&raw_ptr()->exports_, exports.raw()); | 
|  11133   exports.SetAt(num_exports, ns); |  10577   exports.SetAt(num_exports, ns); | 
|  11134 } |  10578 } | 
|  11135  |  10579  | 
|  11136  |  | 
|  11137 static RawArray* NewDictionary(intptr_t initial_size) { |  10580 static RawArray* NewDictionary(intptr_t initial_size) { | 
|  11138   const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); |  10581   const Array& dict = Array::Handle(Array::New(initial_size + 1, Heap::kOld)); | 
|  11139   // The last element of the dictionary specifies the number of in use slots. |  10582   // The last element of the dictionary specifies the number of in use slots. | 
|  11140   dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); |  10583   dict.SetAt(initial_size, Smi::Handle(Smi::New(0))); | 
|  11141   return dict.raw(); |  10584   return dict.raw(); | 
|  11142 } |  10585 } | 
|  11143  |  10586  | 
|  11144  |  | 
|  11145 void Library::InitResolvedNamesCache() const { |  10587 void Library::InitResolvedNamesCache() const { | 
|  11146   ASSERT(Thread::Current()->IsMutatorThread()); |  10588   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  11147   StorePointer(&raw_ptr()->resolved_names_, |  10589   StorePointer(&raw_ptr()->resolved_names_, | 
|  11148                HashTables::New<ResolvedNamesMap>(64)); |  10590                HashTables::New<ResolvedNamesMap>(64)); | 
|  11149 } |  10591 } | 
|  11150  |  10592  | 
|  11151  |  | 
|  11152 void Library::ClearResolvedNamesCache() const { |  10593 void Library::ClearResolvedNamesCache() const { | 
|  11153   ASSERT(Thread::Current()->IsMutatorThread()); |  10594   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  11154   StorePointer(&raw_ptr()->resolved_names_, Array::null()); |  10595   StorePointer(&raw_ptr()->resolved_names_, Array::null()); | 
|  11155 } |  10596 } | 
|  11156  |  10597  | 
|  11157  |  | 
|  11158 void Library::InitExportedNamesCache() const { |  10598 void Library::InitExportedNamesCache() const { | 
|  11159   StorePointer(&raw_ptr()->exported_names_, |  10599   StorePointer(&raw_ptr()->exported_names_, | 
|  11160                HashTables::New<ResolvedNamesMap>(16)); |  10600                HashTables::New<ResolvedNamesMap>(16)); | 
|  11161 } |  10601 } | 
|  11162  |  10602  | 
|  11163  |  | 
|  11164 void Library::ClearExportedNamesCache() const { |  10603 void Library::ClearExportedNamesCache() const { | 
|  11165   StorePointer(&raw_ptr()->exported_names_, Array::null()); |  10604   StorePointer(&raw_ptr()->exported_names_, Array::null()); | 
|  11166 } |  10605 } | 
|  11167  |  10606  | 
|  11168  |  | 
|  11169 void Library::InitClassDictionary() const { |  10607 void Library::InitClassDictionary() const { | 
|  11170   // TODO(iposva): Find reasonable initial size. |  10608   // TODO(iposva): Find reasonable initial size. | 
|  11171   const int kInitialElementCount = 16; |  10609   const int kInitialElementCount = 16; | 
|  11172   StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); |  10610   StorePointer(&raw_ptr()->dictionary_, NewDictionary(kInitialElementCount)); | 
|  11173 } |  10611 } | 
|  11174  |  10612  | 
|  11175  |  | 
|  11176 void Library::InitImportList() const { |  10613 void Library::InitImportList() const { | 
|  11177   const Array& imports = |  10614   const Array& imports = | 
|  11178       Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); |  10615       Array::Handle(Array::New(kInitialImportsCapacity, Heap::kOld)); | 
|  11179   StorePointer(&raw_ptr()->imports_, imports.raw()); |  10616   StorePointer(&raw_ptr()->imports_, imports.raw()); | 
|  11180   StoreNonPointer(&raw_ptr()->num_imports_, 0); |  10617   StoreNonPointer(&raw_ptr()->num_imports_, 0); | 
|  11181 } |  10618 } | 
|  11182  |  10619  | 
|  11183  |  | 
|  11184 RawLibrary* Library::New() { |  10620 RawLibrary* Library::New() { | 
|  11185   ASSERT(Object::library_class() != Class::null()); |  10621   ASSERT(Object::library_class() != Class::null()); | 
|  11186   RawObject* raw = |  10622   RawObject* raw = | 
|  11187       Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld); |  10623       Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld); | 
|  11188   return reinterpret_cast<RawLibrary*>(raw); |  10624   return reinterpret_cast<RawLibrary*>(raw); | 
|  11189 } |  10625 } | 
|  11190  |  10626  | 
|  11191  |  | 
|  11192 RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) { |  10627 RawLibrary* Library::NewLibraryHelper(const String& url, bool import_core_lib) { | 
|  11193   Thread* thread = Thread::Current(); |  10628   Thread* thread = Thread::Current(); | 
|  11194   Zone* zone = thread->zone(); |  10629   Zone* zone = thread->zone(); | 
|  11195   ASSERT(thread->IsMutatorThread()); |  10630   ASSERT(thread->IsMutatorThread()); | 
|  11196   // Force the url to have a hash code. |  10631   // Force the url to have a hash code. | 
|  11197   url.Hash(); |  10632   url.Hash(); | 
|  11198   const bool dart_scheme = url.StartsWith(Symbols::DartScheme()); |  10633   const bool dart_scheme = url.StartsWith(Symbols::DartScheme()); | 
|  11199   const bool dart_private_scheme = |  10634   const bool dart_private_scheme = | 
|  11200       dart_scheme && url.StartsWith(Symbols::DartSchemePrivate()); |  10635       dart_scheme && url.StartsWith(Symbols::DartSchemePrivate()); | 
|  11201   const Library& result = Library::Handle(zone, Library::New()); |  10636   const Library& result = Library::Handle(zone, Library::New()); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  11241     const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); |  10676     const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); | 
|  11242     ASSERT(!core_lib.IsNull()); |  10677     ASSERT(!core_lib.IsNull()); | 
|  11243     const Namespace& ns = Namespace::Handle( |  10678     const Namespace& ns = Namespace::Handle( | 
|  11244         zone, |  10679         zone, | 
|  11245         Namespace::New(core_lib, Object::null_array(), Object::null_array())); |  10680         Namespace::New(core_lib, Object::null_array(), Object::null_array())); | 
|  11246     result.AddImport(ns); |  10681     result.AddImport(ns); | 
|  11247   } |  10682   } | 
|  11248   return result.raw(); |  10683   return result.raw(); | 
|  11249 } |  10684 } | 
|  11250  |  10685  | 
|  11251  |  | 
|  11252 RawLibrary* Library::New(const String& url) { |  10686 RawLibrary* Library::New(const String& url) { | 
|  11253   return NewLibraryHelper(url, false); |  10687   return NewLibraryHelper(url, false); | 
|  11254 } |  10688 } | 
|  11255  |  10689  | 
|  11256  |  | 
|  11257 void Library::InitCoreLibrary(Isolate* isolate) { |  10690 void Library::InitCoreLibrary(Isolate* isolate) { | 
|  11258   Thread* thread = Thread::Current(); |  10691   Thread* thread = Thread::Current(); | 
|  11259   Zone* zone = thread->zone(); |  10692   Zone* zone = thread->zone(); | 
|  11260   const String& core_lib_url = Symbols::DartCore(); |  10693   const String& core_lib_url = Symbols::DartCore(); | 
|  11261   const Library& core_lib = |  10694   const Library& core_lib = | 
|  11262       Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false)); |  10695       Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false)); | 
|  11263   core_lib.SetLoadRequested(); |  10696   core_lib.SetLoadRequested(); | 
|  11264   core_lib.Register(thread); |  10697   core_lib.Register(thread); | 
|  11265   isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib); |  10698   isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib); | 
|  11266   isolate->object_store()->set_root_library(Library::Handle()); |  10699   isolate->object_store()->set_root_library(Library::Handle()); | 
|  11267  |  10700  | 
|  11268   // Hook up predefined classes without setting their library pointers. These |  10701   // Hook up predefined classes without setting their library pointers. These | 
|  11269   // classes are coming from the VM isolate, and are shared between multiple |  10702   // classes are coming from the VM isolate, and are shared between multiple | 
|  11270   // isolates so setting their library pointers would be wrong. |  10703   // isolates so setting their library pointers would be wrong. | 
|  11271   const Class& cls = Class::Handle(zone, Object::dynamic_class()); |  10704   const Class& cls = Class::Handle(zone, Object::dynamic_class()); | 
|  11272   core_lib.AddObject(cls, String::Handle(zone, cls.Name())); |  10705   core_lib.AddObject(cls, String::Handle(zone, cls.Name())); | 
|  11273 } |  10706 } | 
|  11274  |  10707  | 
|  11275  |  | 
|  11276 RawObject* Library::Evaluate(const String& expr, |  10708 RawObject* Library::Evaluate(const String& expr, | 
|  11277                              const Array& param_names, |  10709                              const Array& param_names, | 
|  11278                              const Array& param_values) const { |  10710                              const Array& param_values) const { | 
|  11279   // Evaluate the expression as a static function of the toplevel class. |  10711   // Evaluate the expression as a static function of the toplevel class. | 
|  11280   Class& top_level_class = Class::Handle(toplevel_class()); |  10712   Class& top_level_class = Class::Handle(toplevel_class()); | 
|  11281   ASSERT(top_level_class.is_finalized()); |  10713   ASSERT(top_level_class.is_finalized()); | 
|  11282   return top_level_class.Evaluate(expr, param_names, param_values); |  10714   return top_level_class.Evaluate(expr, param_names, param_values); | 
|  11283 } |  10715 } | 
|  11284  |  10716  | 
|  11285  |  | 
|  11286 void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) { |  10717 void Library::InitNativeWrappersLibrary(Isolate* isolate, bool is_kernel) { | 
|  11287   static const int kNumNativeWrappersClasses = 4; |  10718   static const int kNumNativeWrappersClasses = 4; | 
|  11288   COMPILE_ASSERT((kNumNativeWrappersClasses > 0) && |  10719   COMPILE_ASSERT((kNumNativeWrappersClasses > 0) && | 
|  11289                  (kNumNativeWrappersClasses < 10)); |  10720                  (kNumNativeWrappersClasses < 10)); | 
|  11290   Thread* thread = Thread::Current(); |  10721   Thread* thread = Thread::Current(); | 
|  11291   Zone* zone = thread->zone(); |  10722   Zone* zone = thread->zone(); | 
|  11292   const String& native_flds_lib_url = Symbols::DartNativeWrappers(); |  10723   const String& native_flds_lib_url = Symbols::DartNativeWrappers(); | 
|  11293   const Library& native_flds_lib = Library::Handle( |  10724   const Library& native_flds_lib = Library::Handle( | 
|  11294       zone, Library::NewLibraryHelper(native_flds_lib_url, false)); |  10725       zone, Library::NewLibraryHelper(native_flds_lib_url, false)); | 
|  11295   const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); |  10726   const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName(); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  11310     Class::NewNativeWrapper(native_flds_lib, cls_name, fld_cnt); |  10741     Class::NewNativeWrapper(native_flds_lib, cls_name, fld_cnt); | 
|  11311   } |  10742   } | 
|  11312   // NOTE: If we bootstrap from a Kernel IR file we want to generate the |  10743   // NOTE: If we bootstrap from a Kernel IR file we want to generate the | 
|  11313   // synthetic constructors for the native wrapper classes.  We leave this up to |  10744   // synthetic constructors for the native wrapper classes.  We leave this up to | 
|  11314   // the [KernelReader] who will take care of it later. |  10745   // the [KernelReader] who will take care of it later. | 
|  11315   if (!is_kernel) { |  10746   if (!is_kernel) { | 
|  11316     native_flds_lib.SetLoaded(); |  10747     native_flds_lib.SetLoaded(); | 
|  11317   } |  10748   } | 
|  11318 } |  10749 } | 
|  11319  |  10750  | 
|  11320  |  | 
|  11321 // LibraryLookupSet maps URIs to libraries. |  10751 // LibraryLookupSet maps URIs to libraries. | 
|  11322 class LibraryLookupTraits { |  10752 class LibraryLookupTraits { | 
|  11323  public: |  10753  public: | 
|  11324   static const char* Name() { return "LibraryLookupTraits"; } |  10754   static const char* Name() { return "LibraryLookupTraits"; } | 
|  11325   static bool ReportStats() { return false; } |  10755   static bool ReportStats() { return false; } | 
|  11326  |  10756  | 
|  11327   static bool IsMatch(const Object& a, const Object& b) { |  10757   static bool IsMatch(const Object& a, const Object& b) { | 
|  11328     const String& a_str = String::Cast(a); |  10758     const String& a_str = String::Cast(a); | 
|  11329     const String& b_str = String::Cast(b); |  10759     const String& b_str = String::Cast(b); | 
|  11330  |  10760  | 
|  11331     ASSERT(a_str.HasHash() && b_str.HasHash()); |  10761     ASSERT(a_str.HasHash() && b_str.HasHash()); | 
|  11332     return a_str.Equals(b_str); |  10762     return a_str.Equals(b_str); | 
|  11333   } |  10763   } | 
|  11334  |  10764  | 
|  11335   static uword Hash(const Object& key) { return String::Cast(key).Hash(); } |  10765   static uword Hash(const Object& key) { return String::Cast(key).Hash(); } | 
|  11336  |  10766  | 
|  11337   static RawObject* NewKey(const String& str) { return str.raw(); } |  10767   static RawObject* NewKey(const String& str) { return str.raw(); } | 
|  11338 }; |  10768 }; | 
|  11339 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap; |  10769 typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap; | 
|  11340  |  10770  | 
|  11341  |  | 
|  11342 // Returns library with given url in current isolate, or NULL. |  10771 // Returns library with given url in current isolate, or NULL. | 
|  11343 RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) { |  10772 RawLibrary* Library::LookupLibrary(Thread* thread, const String& url) { | 
|  11344   Zone* zone = thread->zone(); |  10773   Zone* zone = thread->zone(); | 
|  11345   Isolate* isolate = thread->isolate(); |  10774   Isolate* isolate = thread->isolate(); | 
|  11346   ObjectStore* object_store = isolate->object_store(); |  10775   ObjectStore* object_store = isolate->object_store(); | 
|  11347  |  10776  | 
|  11348   // Make sure the URL string has an associated hash code |  10777   // Make sure the URL string has an associated hash code | 
|  11349   // to speed up the repeated equality checks. |  10778   // to speed up the repeated equality checks. | 
|  11350   url.Hash(); |  10779   url.Hash(); | 
|  11351  |  10780  | 
|  11352   // Use the libraries map to lookup the library by URL. |  10781   // Use the libraries map to lookup the library by URL. | 
|  11353   Library& lib = Library::Handle(zone); |  10782   Library& lib = Library::Handle(zone); | 
|  11354   if (object_store->libraries_map() == Array::null()) { |  10783   if (object_store->libraries_map() == Array::null()) { | 
|  11355     return Library::null(); |  10784     return Library::null(); | 
|  11356   } else { |  10785   } else { | 
|  11357     LibraryLookupMap map(object_store->libraries_map()); |  10786     LibraryLookupMap map(object_store->libraries_map()); | 
|  11358     lib ^= map.GetOrNull(url); |  10787     lib ^= map.GetOrNull(url); | 
|  11359     ASSERT(map.Release().raw() == object_store->libraries_map()); |  10788     ASSERT(map.Release().raw() == object_store->libraries_map()); | 
|  11360   } |  10789   } | 
|  11361   return lib.raw(); |  10790   return lib.raw(); | 
|  11362 } |  10791 } | 
|  11363  |  10792  | 
|  11364  |  | 
|  11365 RawError* Library::Patch(const Script& script) const { |  10793 RawError* Library::Patch(const Script& script) const { | 
|  11366   ASSERT(script.kind() == RawScript::kPatchTag); |  10794   ASSERT(script.kind() == RawScript::kPatchTag); | 
|  11367   return Compiler::Compile(*this, script); |  10795   return Compiler::Compile(*this, script); | 
|  11368 } |  10796 } | 
|  11369  |  10797  | 
|  11370  |  | 
|  11371 bool Library::IsPrivate(const String& name) { |  10798 bool Library::IsPrivate(const String& name) { | 
|  11372   if (ShouldBePrivate(name)) return true; |  10799   if (ShouldBePrivate(name)) return true; | 
|  11373   // Factory names: List._fromLiteral. |  10800   // Factory names: List._fromLiteral. | 
|  11374   for (intptr_t i = 1; i < name.Length() - 1; i++) { |  10801   for (intptr_t i = 1; i < name.Length() - 1; i++) { | 
|  11375     if (name.CharAt(i) == '.') { |  10802     if (name.CharAt(i) == '.') { | 
|  11376       if (name.CharAt(i + 1) == '_') { |  10803       if (name.CharAt(i + 1) == '_') { | 
|  11377         return true; |  10804         return true; | 
|  11378       } |  10805       } | 
|  11379     } |  10806     } | 
|  11380   } |  10807   } | 
|  11381   return false; |  10808   return false; | 
|  11382 } |  10809 } | 
|  11383  |  10810  | 
|  11384  |  | 
|  11385 // Create a private key for this library. It is based on the hash of the |  10811 // Create a private key for this library. It is based on the hash of the | 
|  11386 // library URI and the sequence number of the library to guarantee unique |  10812 // library URI and the sequence number of the library to guarantee unique | 
|  11387 // private keys without having to verify. |  10813 // private keys without having to verify. | 
|  11388 void Library::AllocatePrivateKey() const { |  10814 void Library::AllocatePrivateKey() const { | 
|  11389   Thread* thread = Thread::Current(); |  10815   Thread* thread = Thread::Current(); | 
|  11390   Zone* zone = thread->zone(); |  10816   Zone* zone = thread->zone(); | 
|  11391   Isolate* isolate = thread->isolate(); |  10817   Isolate* isolate = thread->isolate(); | 
|  11392  |  10818  | 
|  11393   if (FLAG_support_reload && isolate->IsReloading()) { |  10819   if (FLAG_support_reload && isolate->IsReloading()) { | 
|  11394     // When reloading, we need to make sure we use the original private key |  10820     // When reloading, we need to make sure we use the original private key | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  11414  |  10840  | 
|  11415   char private_key[32]; |  10841   char private_key[32]; | 
|  11416   OS::SNPrint(private_key, sizeof(private_key), "%c%" Pd "%06" Pd "", |  10842   OS::SNPrint(private_key, sizeof(private_key), "%c%" Pd "%06" Pd "", | 
|  11417               kPrivateKeySeparator, sequence_value, hash_value); |  10843               kPrivateKeySeparator, sequence_value, hash_value); | 
|  11418   const String& key = |  10844   const String& key = | 
|  11419       String::Handle(zone, String::New(private_key, Heap::kOld)); |  10845       String::Handle(zone, String::New(private_key, Heap::kOld)); | 
|  11420   key.Hash();  // This string may end up in the VM isolate. |  10846   key.Hash();  // This string may end up in the VM isolate. | 
|  11421   StorePointer(&raw_ptr()->private_key_, key.raw()); |  10847   StorePointer(&raw_ptr()->private_key_, key.raw()); | 
|  11422 } |  10848 } | 
|  11423  |  10849  | 
|  11424  |  | 
|  11425 const String& Library::PrivateCoreLibName(const String& member) { |  10850 const String& Library::PrivateCoreLibName(const String& member) { | 
|  11426   const Library& core_lib = Library::Handle(Library::CoreLibrary()); |  10851   const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 
|  11427   const String& private_name = String::ZoneHandle(core_lib.PrivateName(member)); |  10852   const String& private_name = String::ZoneHandle(core_lib.PrivateName(member)); | 
|  11428   return private_name; |  10853   return private_name; | 
|  11429 } |  10854 } | 
|  11430  |  10855  | 
|  11431  |  | 
|  11432 RawClass* Library::LookupCoreClass(const String& class_name) { |  10856 RawClass* Library::LookupCoreClass(const String& class_name) { | 
|  11433   Thread* thread = Thread::Current(); |  10857   Thread* thread = Thread::Current(); | 
|  11434   Zone* zone = thread->zone(); |  10858   Zone* zone = thread->zone(); | 
|  11435   const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); |  10859   const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); | 
|  11436   String& name = String::Handle(zone, class_name.raw()); |  10860   String& name = String::Handle(zone, class_name.raw()); | 
|  11437   if (class_name.CharAt(0) == kPrivateIdentifierStart) { |  10861   if (class_name.CharAt(0) == kPrivateIdentifierStart) { | 
|  11438     // Private identifiers are mangled on a per library basis. |  10862     // Private identifiers are mangled on a per library basis. | 
|  11439     name = Symbols::FromConcat(thread, name, |  10863     name = Symbols::FromConcat(thread, name, | 
|  11440                                String::Handle(zone, core_lib.private_key())); |  10864                                String::Handle(zone, core_lib.private_key())); | 
|  11441   } |  10865   } | 
|  11442   return core_lib.LookupClass(name); |  10866   return core_lib.LookupClass(name); | 
|  11443 } |  10867 } | 
|  11444  |  10868  | 
|  11445  |  | 
|  11446 // Cannot handle qualified names properly as it only appends private key to |  10869 // Cannot handle qualified names properly as it only appends private key to | 
|  11447 // the end (e.g. _Alfa.foo -> _Alfa.foo@...). |  10870 // the end (e.g. _Alfa.foo -> _Alfa.foo@...). | 
|  11448 RawString* Library::PrivateName(const String& name) const { |  10871 RawString* Library::PrivateName(const String& name) const { | 
|  11449   Thread* thread = Thread::Current(); |  10872   Thread* thread = Thread::Current(); | 
|  11450   Zone* zone = thread->zone(); |  10873   Zone* zone = thread->zone(); | 
|  11451   ASSERT(IsPrivate(name)); |  10874   ASSERT(IsPrivate(name)); | 
|  11452   // ASSERT(strchr(name, '@') == NULL); |  10875   // ASSERT(strchr(name, '@') == NULL); | 
|  11453   String& str = String::Handle(zone); |  10876   String& str = String::Handle(zone); | 
|  11454   str = name.raw(); |  10877   str = name.raw(); | 
|  11455   str = Symbols::FromConcat(thread, str, |  10878   str = Symbols::FromConcat(thread, str, | 
|  11456                             String::Handle(zone, this->private_key())); |  10879                             String::Handle(zone, this->private_key())); | 
|  11457   return str.raw(); |  10880   return str.raw(); | 
|  11458 } |  10881 } | 
|  11459  |  10882  | 
|  11460  |  | 
|  11461 RawLibrary* Library::GetLibrary(intptr_t index) { |  10883 RawLibrary* Library::GetLibrary(intptr_t index) { | 
|  11462   Thread* thread = Thread::Current(); |  10884   Thread* thread = Thread::Current(); | 
|  11463   Zone* zone = thread->zone(); |  10885   Zone* zone = thread->zone(); | 
|  11464   Isolate* isolate = thread->isolate(); |  10886   Isolate* isolate = thread->isolate(); | 
|  11465   const GrowableObjectArray& libs = |  10887   const GrowableObjectArray& libs = | 
|  11466       GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); |  10888       GrowableObjectArray::Handle(zone, isolate->object_store()->libraries()); | 
|  11467   ASSERT(!libs.IsNull()); |  10889   ASSERT(!libs.IsNull()); | 
|  11468   if ((0 <= index) && (index < libs.Length())) { |  10890   if ((0 <= index) && (index < libs.Length())) { | 
|  11469     Library& lib = Library::Handle(zone); |  10891     Library& lib = Library::Handle(zone); | 
|  11470     lib ^= libs.At(index); |  10892     lib ^= libs.At(index); | 
|  11471     return lib.raw(); |  10893     return lib.raw(); | 
|  11472   } |  10894   } | 
|  11473   return Library::null(); |  10895   return Library::null(); | 
|  11474 } |  10896 } | 
|  11475  |  10897  | 
|  11476  |  | 
|  11477 void Library::Register(Thread* thread) const { |  10898 void Library::Register(Thread* thread) const { | 
|  11478   Zone* zone = thread->zone(); |  10899   Zone* zone = thread->zone(); | 
|  11479   Isolate* isolate = thread->isolate(); |  10900   Isolate* isolate = thread->isolate(); | 
|  11480   ObjectStore* object_store = isolate->object_store(); |  10901   ObjectStore* object_store = isolate->object_store(); | 
|  11481  |  10902  | 
|  11482   // A library is "registered" in two places: |  10903   // A library is "registered" in two places: | 
|  11483   // - A growable array mapping from index to library. |  10904   // - A growable array mapping from index to library. | 
|  11484   const String& lib_url = String::Handle(zone, url()); |  10905   const String& lib_url = String::Handle(zone, url()); | 
|  11485   ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null()); |  10906   ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null()); | 
|  11486   ASSERT(lib_url.HasHash()); |  10907   ASSERT(lib_url.HasHash()); | 
|  11487   GrowableObjectArray& libs = |  10908   GrowableObjectArray& libs = | 
|  11488       GrowableObjectArray::Handle(zone, object_store->libraries()); |  10909       GrowableObjectArray::Handle(zone, object_store->libraries()); | 
|  11489   ASSERT(!libs.IsNull()); |  10910   ASSERT(!libs.IsNull()); | 
|  11490   set_index(libs.Length()); |  10911   set_index(libs.Length()); | 
|  11491   libs.Add(*this); |  10912   libs.Add(*this); | 
|  11492  |  10913  | 
|  11493   // - A map from URL string to library. |  10914   // - A map from URL string to library. | 
|  11494   if (object_store->libraries_map() == Array::null()) { |  10915   if (object_store->libraries_map() == Array::null()) { | 
|  11495     LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); |  10916     LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); | 
|  11496     object_store->set_libraries_map(map.Release()); |  10917     object_store->set_libraries_map(map.Release()); | 
|  11497   } |  10918   } | 
|  11498  |  10919  | 
|  11499   LibraryLookupMap map(object_store->libraries_map()); |  10920   LibraryLookupMap map(object_store->libraries_map()); | 
|  11500   bool present = map.UpdateOrInsert(lib_url, *this); |  10921   bool present = map.UpdateOrInsert(lib_url, *this); | 
|  11501   ASSERT(!present); |  10922   ASSERT(!present); | 
|  11502   object_store->set_libraries_map(map.Release()); |  10923   object_store->set_libraries_map(map.Release()); | 
|  11503 } |  10924 } | 
|  11504  |  10925  | 
|  11505  |  | 
|  11506 void Library::RegisterLibraries(Thread* thread, |  10926 void Library::RegisterLibraries(Thread* thread, | 
|  11507                                 const GrowableObjectArray& libs) { |  10927                                 const GrowableObjectArray& libs) { | 
|  11508   Zone* zone = thread->zone(); |  10928   Zone* zone = thread->zone(); | 
|  11509   Isolate* isolate = thread->isolate(); |  10929   Isolate* isolate = thread->isolate(); | 
|  11510   Library& lib = Library::Handle(zone); |  10930   Library& lib = Library::Handle(zone); | 
|  11511   String& lib_url = String::Handle(zone); |  10931   String& lib_url = String::Handle(zone); | 
|  11512  |  10932  | 
|  11513   LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); |  10933   LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld)); | 
|  11514  |  10934  | 
|  11515   intptr_t len = libs.Length(); |  10935   intptr_t len = libs.Length(); | 
|  11516   for (intptr_t i = 0; i < len; i++) { |  10936   for (intptr_t i = 0; i < len; i++) { | 
|  11517     lib ^= libs.At(i); |  10937     lib ^= libs.At(i); | 
|  11518     lib_url = lib.url(); |  10938     lib_url = lib.url(); | 
|  11519     map.InsertNewOrGetValue(lib_url, lib); |  10939     map.InsertNewOrGetValue(lib_url, lib); | 
|  11520   } |  10940   } | 
|  11521   // Now rememeber these in the isolate's object store. |  10941   // Now rememeber these in the isolate's object store. | 
|  11522   isolate->object_store()->set_libraries(libs); |  10942   isolate->object_store()->set_libraries(libs); | 
|  11523   isolate->object_store()->set_libraries_map(map.Release()); |  10943   isolate->object_store()->set_libraries_map(map.Release()); | 
|  11524 } |  10944 } | 
|  11525  |  10945  | 
|  11526  |  | 
|  11527 RawLibrary* Library::AsyncLibrary() { |  10946 RawLibrary* Library::AsyncLibrary() { | 
|  11528   return Isolate::Current()->object_store()->async_library(); |  10947   return Isolate::Current()->object_store()->async_library(); | 
|  11529 } |  10948 } | 
|  11530  |  10949  | 
|  11531  |  | 
|  11532 RawLibrary* Library::ConvertLibrary() { |  10950 RawLibrary* Library::ConvertLibrary() { | 
|  11533   return Isolate::Current()->object_store()->convert_library(); |  10951   return Isolate::Current()->object_store()->convert_library(); | 
|  11534 } |  10952 } | 
|  11535  |  10953  | 
|  11536  |  | 
|  11537 RawLibrary* Library::CoreLibrary() { |  10954 RawLibrary* Library::CoreLibrary() { | 
|  11538   return Isolate::Current()->object_store()->core_library(); |  10955   return Isolate::Current()->object_store()->core_library(); | 
|  11539 } |  10956 } | 
|  11540  |  10957  | 
|  11541  |  | 
|  11542 RawLibrary* Library::CollectionLibrary() { |  10958 RawLibrary* Library::CollectionLibrary() { | 
|  11543   return Isolate::Current()->object_store()->collection_library(); |  10959   return Isolate::Current()->object_store()->collection_library(); | 
|  11544 } |  10960 } | 
|  11545  |  10961  | 
|  11546  |  | 
|  11547 RawLibrary* Library::DeveloperLibrary() { |  10962 RawLibrary* Library::DeveloperLibrary() { | 
|  11548   return Isolate::Current()->object_store()->developer_library(); |  10963   return Isolate::Current()->object_store()->developer_library(); | 
|  11549 } |  10964 } | 
|  11550  |  10965  | 
|  11551  |  | 
|  11552 RawLibrary* Library::InternalLibrary() { |  10966 RawLibrary* Library::InternalLibrary() { | 
|  11553   return Isolate::Current()->object_store()->_internal_library(); |  10967   return Isolate::Current()->object_store()->_internal_library(); | 
|  11554 } |  10968 } | 
|  11555  |  10969  | 
|  11556  |  | 
|  11557 RawLibrary* Library::IsolateLibrary() { |  10970 RawLibrary* Library::IsolateLibrary() { | 
|  11558   return Isolate::Current()->object_store()->isolate_library(); |  10971   return Isolate::Current()->object_store()->isolate_library(); | 
|  11559 } |  10972 } | 
|  11560  |  10973  | 
|  11561  |  | 
|  11562 RawLibrary* Library::MathLibrary() { |  10974 RawLibrary* Library::MathLibrary() { | 
|  11563   return Isolate::Current()->object_store()->math_library(); |  10975   return Isolate::Current()->object_store()->math_library(); | 
|  11564 } |  10976 } | 
|  11565  |  10977  | 
|  11566  |  | 
|  11567 #if !defined(PRODUCT) |  10978 #if !defined(PRODUCT) | 
|  11568 RawLibrary* Library::MirrorsLibrary() { |  10979 RawLibrary* Library::MirrorsLibrary() { | 
|  11569   return Isolate::Current()->object_store()->mirrors_library(); |  10980   return Isolate::Current()->object_store()->mirrors_library(); | 
|  11570 } |  10981 } | 
|  11571 #endif |  10982 #endif | 
|  11572  |  10983  | 
|  11573  |  | 
|  11574 RawLibrary* Library::NativeWrappersLibrary() { |  10984 RawLibrary* Library::NativeWrappersLibrary() { | 
|  11575   return Isolate::Current()->object_store()->native_wrappers_library(); |  10985   return Isolate::Current()->object_store()->native_wrappers_library(); | 
|  11576 } |  10986 } | 
|  11577  |  10987  | 
|  11578  |  | 
|  11579 RawLibrary* Library::ProfilerLibrary() { |  10988 RawLibrary* Library::ProfilerLibrary() { | 
|  11580   return Isolate::Current()->object_store()->profiler_library(); |  10989   return Isolate::Current()->object_store()->profiler_library(); | 
|  11581 } |  10990 } | 
|  11582  |  10991  | 
|  11583  |  | 
|  11584 RawLibrary* Library::TypedDataLibrary() { |  10992 RawLibrary* Library::TypedDataLibrary() { | 
|  11585   return Isolate::Current()->object_store()->typed_data_library(); |  10993   return Isolate::Current()->object_store()->typed_data_library(); | 
|  11586 } |  10994 } | 
|  11587  |  10995  | 
|  11588  |  | 
|  11589 RawLibrary* Library::VMServiceLibrary() { |  10996 RawLibrary* Library::VMServiceLibrary() { | 
|  11590   return Isolate::Current()->object_store()->_vmservice_library(); |  10997   return Isolate::Current()->object_store()->_vmservice_library(); | 
|  11591 } |  10998 } | 
|  11592  |  10999  | 
|  11593  |  | 
|  11594 const char* Library::ToCString() const { |  11000 const char* Library::ToCString() const { | 
|  11595   const String& name = String::Handle(url()); |  11001   const String& name = String::Handle(url()); | 
|  11596   return OS::SCreate(Thread::Current()->zone(), "Library:'%s'", |  11002   return OS::SCreate(Thread::Current()->zone(), "Library:'%s'", | 
|  11597                      name.ToCString()); |  11003                      name.ToCString()); | 
|  11598 } |  11004 } | 
|  11599  |  11005  | 
|  11600  |  | 
|  11601 RawLibrary* LibraryPrefix::GetLibrary(int index) const { |  11006 RawLibrary* LibraryPrefix::GetLibrary(int index) const { | 
|  11602   if ((index >= 0) || (index < num_imports())) { |  11007   if ((index >= 0) || (index < num_imports())) { | 
|  11603     const Array& imports = Array::Handle(this->imports()); |  11008     const Array& imports = Array::Handle(this->imports()); | 
|  11604     Namespace& import = Namespace::Handle(); |  11009     Namespace& import = Namespace::Handle(); | 
|  11605     import ^= imports.At(index); |  11010     import ^= imports.At(index); | 
|  11606     return import.library(); |  11011     return import.library(); | 
|  11607   } |  11012   } | 
|  11608   return Library::null(); |  11013   return Library::null(); | 
|  11609 } |  11014 } | 
|  11610  |  11015  | 
|  11611  |  | 
|  11612 RawInstance* LibraryPrefix::LoadError() const { |  11016 RawInstance* LibraryPrefix::LoadError() const { | 
|  11613   Thread* thread = Thread::Current(); |  11017   Thread* thread = Thread::Current(); | 
|  11614   Isolate* isolate = thread->isolate(); |  11018   Isolate* isolate = thread->isolate(); | 
|  11615   Zone* zone = thread->zone(); |  11019   Zone* zone = thread->zone(); | 
|  11616   ObjectStore* object_store = isolate->object_store(); |  11020   ObjectStore* object_store = isolate->object_store(); | 
|  11617   GrowableObjectArray& libs = |  11021   GrowableObjectArray& libs = | 
|  11618       GrowableObjectArray::Handle(zone, object_store->libraries()); |  11022       GrowableObjectArray::Handle(zone, object_store->libraries()); | 
|  11619   ASSERT(!libs.IsNull()); |  11023   ASSERT(!libs.IsNull()); | 
|  11620   LibraryLoadErrorSet set(HashTables::New<LibraryLoadErrorSet>(libs.Length())); |  11024   LibraryLoadErrorSet set(HashTables::New<LibraryLoadErrorSet>(libs.Length())); | 
|  11621   object_store->set_library_load_error_table(set.Release()); |  11025   object_store->set_library_load_error_table(set.Release()); | 
|  11622   Library& lib = Library::Handle(zone); |  11026   Library& lib = Library::Handle(zone); | 
|  11623   Instance& error = Instance::Handle(zone); |  11027   Instance& error = Instance::Handle(zone); | 
|  11624   for (int32_t i = 0; i < num_imports(); i++) { |  11028   for (int32_t i = 0; i < num_imports(); i++) { | 
|  11625     lib = GetLibrary(i); |  11029     lib = GetLibrary(i); | 
|  11626     ASSERT(!lib.IsNull()); |  11030     ASSERT(!lib.IsNull()); | 
|  11627     HANDLESCOPE(thread); |  11031     HANDLESCOPE(thread); | 
|  11628     error = lib.TransitiveLoadError(); |  11032     error = lib.TransitiveLoadError(); | 
|  11629     if (!error.IsNull()) { |  11033     if (!error.IsNull()) { | 
|  11630       break; |  11034       break; | 
|  11631     } |  11035     } | 
|  11632   } |  11036   } | 
|  11633   object_store->set_library_load_error_table(Object::empty_array()); |  11037   object_store->set_library_load_error_table(Object::empty_array()); | 
|  11634   return error.raw(); |  11038   return error.raw(); | 
|  11635 } |  11039 } | 
|  11636  |  11040  | 
|  11637  |  | 
|  11638 bool LibraryPrefix::ContainsLibrary(const Library& library) const { |  11041 bool LibraryPrefix::ContainsLibrary(const Library& library) const { | 
|  11639   int32_t num_current_imports = num_imports(); |  11042   int32_t num_current_imports = num_imports(); | 
|  11640   if (num_current_imports > 0) { |  11043   if (num_current_imports > 0) { | 
|  11641     Library& lib = Library::Handle(); |  11044     Library& lib = Library::Handle(); | 
|  11642     const String& url = String::Handle(library.url()); |  11045     const String& url = String::Handle(library.url()); | 
|  11643     String& lib_url = String::Handle(); |  11046     String& lib_url = String::Handle(); | 
|  11644     for (int32_t i = 0; i < num_current_imports; i++) { |  11047     for (int32_t i = 0; i < num_current_imports; i++) { | 
|  11645       lib = GetLibrary(i); |  11048       lib = GetLibrary(i); | 
|  11646       ASSERT(!lib.IsNull()); |  11049       ASSERT(!lib.IsNull()); | 
|  11647       lib_url = lib.url(); |  11050       lib_url = lib.url(); | 
|  11648       if (url.Equals(lib_url)) { |  11051       if (url.Equals(lib_url)) { | 
|  11649         return true; |  11052         return true; | 
|  11650       } |  11053       } | 
|  11651     } |  11054     } | 
|  11652   } |  11055   } | 
|  11653   return false; |  11056   return false; | 
|  11654 } |  11057 } | 
|  11655  |  11058  | 
|  11656  |  | 
|  11657 void LibraryPrefix::AddImport(const Namespace& import) const { |  11059 void LibraryPrefix::AddImport(const Namespace& import) const { | 
|  11658   intptr_t num_current_imports = num_imports(); |  11060   intptr_t num_current_imports = num_imports(); | 
|  11659  |  11061  | 
|  11660   // Prefixes with deferred libraries can only contain one library. |  11062   // Prefixes with deferred libraries can only contain one library. | 
|  11661   ASSERT((num_current_imports == 0) || !is_deferred_load()); |  11063   ASSERT((num_current_imports == 0) || !is_deferred_load()); | 
|  11662  |  11064  | 
|  11663   // The library needs to be added to the list. |  11065   // The library needs to be added to the list. | 
|  11664   Array& imports = Array::Handle(this->imports()); |  11066   Array& imports = Array::Handle(this->imports()); | 
|  11665   const intptr_t length = (imports.IsNull()) ? 0 : imports.Length(); |  11067   const intptr_t length = (imports.IsNull()) ? 0 : imports.Length(); | 
|  11666   // Grow the list if it is full. |  11068   // Grow the list if it is full. | 
|  11667   if (num_current_imports >= length) { |  11069   if (num_current_imports >= length) { | 
|  11668     const intptr_t new_length = length + kIncrementSize + (length >> 2); |  11070     const intptr_t new_length = length + kIncrementSize + (length >> 2); | 
|  11669     imports = Array::Grow(imports, new_length, Heap::kOld); |  11071     imports = Array::Grow(imports, new_length, Heap::kOld); | 
|  11670     set_imports(imports); |  11072     set_imports(imports); | 
|  11671   } |  11073   } | 
|  11672   imports.SetAt(num_current_imports, import); |  11074   imports.SetAt(num_current_imports, import); | 
|  11673   set_num_imports(num_current_imports + 1); |  11075   set_num_imports(num_current_imports + 1); | 
|  11674 } |  11076 } | 
|  11675  |  11077  | 
|  11676  |  | 
|  11677 RawObject* LibraryPrefix::LookupObject(const String& name) const { |  11078 RawObject* LibraryPrefix::LookupObject(const String& name) const { | 
|  11678   if (!is_loaded() && !FLAG_load_deferred_eagerly) { |  11079   if (!is_loaded() && !FLAG_load_deferred_eagerly) { | 
|  11679     return Object::null(); |  11080     return Object::null(); | 
|  11680   } |  11081   } | 
|  11681   Array& imports = Array::Handle(this->imports()); |  11082   Array& imports = Array::Handle(this->imports()); | 
|  11682   Object& obj = Object::Handle(); |  11083   Object& obj = Object::Handle(); | 
|  11683   Namespace& import = Namespace::Handle(); |  11084   Namespace& import = Namespace::Handle(); | 
|  11684   Library& import_lib = Library::Handle(); |  11085   Library& import_lib = Library::Handle(); | 
|  11685   String& import_lib_url = String::Handle(); |  11086   String& import_lib_url = String::Handle(); | 
|  11686   String& first_import_lib_url = String::Handle(); |  11087   String& first_import_lib_url = String::Handle(); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  11731           if (found_obj_name.Equals(second_obj_name)) { |  11132           if (found_obj_name.Equals(second_obj_name)) { | 
|  11732             return Object::null(); |  11133             return Object::null(); | 
|  11733           } |  11134           } | 
|  11734         } |  11135         } | 
|  11735       } |  11136       } | 
|  11736     } |  11137     } | 
|  11737   } |  11138   } | 
|  11738   return found_obj.raw(); |  11139   return found_obj.raw(); | 
|  11739 } |  11140 } | 
|  11740  |  11141  | 
|  11741  |  | 
|  11742 RawClass* LibraryPrefix::LookupClass(const String& class_name) const { |  11142 RawClass* LibraryPrefix::LookupClass(const String& class_name) const { | 
|  11743   const Object& obj = Object::Handle(LookupObject(class_name)); |  11143   const Object& obj = Object::Handle(LookupObject(class_name)); | 
|  11744   if (obj.IsClass()) { |  11144   if (obj.IsClass()) { | 
|  11745     return Class::Cast(obj).raw(); |  11145     return Class::Cast(obj).raw(); | 
|  11746   } |  11146   } | 
|  11747   return Class::null(); |  11147   return Class::null(); | 
|  11748 } |  11148 } | 
|  11749  |  11149  | 
|  11750  |  | 
|  11751 void LibraryPrefix::set_is_loaded() const { |  11150 void LibraryPrefix::set_is_loaded() const { | 
|  11752   StoreNonPointer(&raw_ptr()->is_loaded_, true); |  11151   StoreNonPointer(&raw_ptr()->is_loaded_, true); | 
|  11753 } |  11152 } | 
|  11754  |  11153  | 
|  11755  |  | 
|  11756 bool LibraryPrefix::LoadLibrary() const { |  11154 bool LibraryPrefix::LoadLibrary() const { | 
|  11757   // Non-deferred prefixes are loaded. |  11155   // Non-deferred prefixes are loaded. | 
|  11758   ASSERT(is_deferred_load() || is_loaded()); |  11156   ASSERT(is_deferred_load() || is_loaded()); | 
|  11759   if (is_loaded()) { |  11157   if (is_loaded()) { | 
|  11760     return true;  // Load request has already completed. |  11158     return true;  // Load request has already completed. | 
|  11761   } |  11159   } | 
|  11762   ASSERT(is_deferred_load()); |  11160   ASSERT(is_deferred_load()); | 
|  11763   ASSERT(num_imports() == 1); |  11161   ASSERT(num_imports() == 1); | 
|  11764   if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) { |  11162   if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) { | 
|  11765     // The library list was tree-shaken away. |  11163     // The library list was tree-shaken away. | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  11799     if (obj.IsError()) { |  11197     if (obj.IsError()) { | 
|  11800       Exceptions::PropagateError(Error::Cast(obj)); |  11198       Exceptions::PropagateError(Error::Cast(obj)); | 
|  11801     } |  11199     } | 
|  11802   } else { |  11200   } else { | 
|  11803     // Another load request is in flight or previously failed. |  11201     // Another load request is in flight or previously failed. | 
|  11804     ASSERT(deferred_lib.LoadRequested() || deferred_lib.LoadFailed()); |  11202     ASSERT(deferred_lib.LoadRequested() || deferred_lib.LoadFailed()); | 
|  11805   } |  11203   } | 
|  11806   return false;  // Load request not yet completed. |  11204   return false;  // Load request not yet completed. | 
|  11807 } |  11205 } | 
|  11808  |  11206  | 
|  11809  |  | 
|  11810 RawArray* LibraryPrefix::dependent_code() const { |  11207 RawArray* LibraryPrefix::dependent_code() const { | 
|  11811   return raw_ptr()->dependent_code_; |  11208   return raw_ptr()->dependent_code_; | 
|  11812 } |  11209 } | 
|  11813  |  11210  | 
|  11814  |  | 
|  11815 void LibraryPrefix::set_dependent_code(const Array& array) const { |  11211 void LibraryPrefix::set_dependent_code(const Array& array) const { | 
|  11816   StorePointer(&raw_ptr()->dependent_code_, array.raw()); |  11212   StorePointer(&raw_ptr()->dependent_code_, array.raw()); | 
|  11817 } |  11213 } | 
|  11818  |  11214  | 
|  11819  |  | 
|  11820 class PrefixDependentArray : public WeakCodeReferences { |  11215 class PrefixDependentArray : public WeakCodeReferences { | 
|  11821  public: |  11216  public: | 
|  11822   explicit PrefixDependentArray(const LibraryPrefix& prefix) |  11217   explicit PrefixDependentArray(const LibraryPrefix& prefix) | 
|  11823       : WeakCodeReferences(Array::Handle(prefix.dependent_code())), |  11218       : WeakCodeReferences(Array::Handle(prefix.dependent_code())), | 
|  11824         prefix_(prefix) {} |  11219         prefix_(prefix) {} | 
|  11825  |  11220  | 
|  11826   virtual void UpdateArrayTo(const Array& value) { |  11221   virtual void UpdateArrayTo(const Array& value) { | 
|  11827     prefix_.set_dependent_code(value); |  11222     prefix_.set_dependent_code(value); | 
|  11828   } |  11223   } | 
|  11829  |  11224  | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  11843                 code.IsDisabled() ? "'patched'" : "'unpatched'", |  11238                 code.IsDisabled() ? "'patched'" : "'unpatched'", | 
|  11844                 Function::Handle(code.function()).ToCString()); |  11239                 Function::Handle(code.function()).ToCString()); | 
|  11845     } |  11240     } | 
|  11846   } |  11241   } | 
|  11847  |  11242  | 
|  11848  private: |  11243  private: | 
|  11849   const LibraryPrefix& prefix_; |  11244   const LibraryPrefix& prefix_; | 
|  11850   DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray); |  11245   DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray); | 
|  11851 }; |  11246 }; | 
|  11852  |  11247  | 
|  11853  |  | 
|  11854 void LibraryPrefix::RegisterDependentCode(const Code& code) const { |  11248 void LibraryPrefix::RegisterDependentCode(const Code& code) const { | 
|  11855   ASSERT(is_deferred_load()); |  11249   ASSERT(is_deferred_load()); | 
|  11856   // In background compilation, a library can be loaded while we are compiling. |  11250   // In background compilation, a library can be loaded while we are compiling. | 
|  11857   // The generated code will be rejected in that case, |  11251   // The generated code will be rejected in that case, | 
|  11858   ASSERT(!is_loaded() || Compiler::IsBackgroundCompilation()); |  11252   ASSERT(!is_loaded() || Compiler::IsBackgroundCompilation()); | 
|  11859   PrefixDependentArray a(*this); |  11253   PrefixDependentArray a(*this); | 
|  11860   a.Register(code); |  11254   a.Register(code); | 
|  11861 } |  11255 } | 
|  11862  |  11256  | 
|  11863  |  | 
|  11864 void LibraryPrefix::InvalidateDependentCode() const { |  11257 void LibraryPrefix::InvalidateDependentCode() const { | 
|  11865   PrefixDependentArray a(*this); |  11258   PrefixDependentArray a(*this); | 
|  11866   a.DisableCode(); |  11259   a.DisableCode(); | 
|  11867   set_is_loaded(); |  11260   set_is_loaded(); | 
|  11868 } |  11261 } | 
|  11869  |  11262  | 
|  11870  |  | 
|  11871 RawLibraryPrefix* LibraryPrefix::New() { |  11263 RawLibraryPrefix* LibraryPrefix::New() { | 
|  11872   RawObject* raw = Object::Allocate(LibraryPrefix::kClassId, |  11264   RawObject* raw = Object::Allocate(LibraryPrefix::kClassId, | 
|  11873                                     LibraryPrefix::InstanceSize(), Heap::kOld); |  11265                                     LibraryPrefix::InstanceSize(), Heap::kOld); | 
|  11874   return reinterpret_cast<RawLibraryPrefix*>(raw); |  11266   return reinterpret_cast<RawLibraryPrefix*>(raw); | 
|  11875 } |  11267 } | 
|  11876  |  11268  | 
|  11877  |  | 
|  11878 RawLibraryPrefix* LibraryPrefix::New(const String& name, |  11269 RawLibraryPrefix* LibraryPrefix::New(const String& name, | 
|  11879                                      const Namespace& import, |  11270                                      const Namespace& import, | 
|  11880                                      bool deferred_load, |  11271                                      bool deferred_load, | 
|  11881                                      const Library& importer) { |  11272                                      const Library& importer) { | 
|  11882   const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); |  11273   const LibraryPrefix& result = LibraryPrefix::Handle(LibraryPrefix::New()); | 
|  11883   result.set_name(name); |  11274   result.set_name(name); | 
|  11884   result.set_num_imports(0); |  11275   result.set_num_imports(0); | 
|  11885   result.set_importer(importer); |  11276   result.set_importer(importer); | 
|  11886   result.StoreNonPointer(&result.raw_ptr()->is_deferred_load_, deferred_load); |  11277   result.StoreNonPointer(&result.raw_ptr()->is_deferred_load_, deferred_load); | 
|  11887   result.StoreNonPointer(&result.raw_ptr()->is_loaded_, !deferred_load); |  11278   result.StoreNonPointer(&result.raw_ptr()->is_loaded_, !deferred_load); | 
|  11888   result.set_imports(Array::Handle(Array::New(kInitialSize))); |  11279   result.set_imports(Array::Handle(Array::New(kInitialSize))); | 
|  11889   result.AddImport(import); |  11280   result.AddImport(import); | 
|  11890   return result.raw(); |  11281   return result.raw(); | 
|  11891 } |  11282 } | 
|  11892  |  11283  | 
|  11893  |  | 
|  11894 void LibraryPrefix::set_name(const String& value) const { |  11284 void LibraryPrefix::set_name(const String& value) const { | 
|  11895   ASSERT(value.IsSymbol()); |  11285   ASSERT(value.IsSymbol()); | 
|  11896   StorePointer(&raw_ptr()->name_, value.raw()); |  11286   StorePointer(&raw_ptr()->name_, value.raw()); | 
|  11897 } |  11287 } | 
|  11898  |  11288  | 
|  11899  |  | 
|  11900 void LibraryPrefix::set_imports(const Array& value) const { |  11289 void LibraryPrefix::set_imports(const Array& value) const { | 
|  11901   StorePointer(&raw_ptr()->imports_, value.raw()); |  11290   StorePointer(&raw_ptr()->imports_, value.raw()); | 
|  11902 } |  11291 } | 
|  11903  |  11292  | 
|  11904  |  | 
|  11905 void LibraryPrefix::set_num_imports(intptr_t value) const { |  11293 void LibraryPrefix::set_num_imports(intptr_t value) const { | 
|  11906   if (!Utils::IsUint(16, value)) { |  11294   if (!Utils::IsUint(16, value)) { | 
|  11907     ReportTooManyImports(Library::Handle(importer())); |  11295     ReportTooManyImports(Library::Handle(importer())); | 
|  11908   } |  11296   } | 
|  11909   StoreNonPointer(&raw_ptr()->num_imports_, value); |  11297   StoreNonPointer(&raw_ptr()->num_imports_, value); | 
|  11910 } |  11298 } | 
|  11911  |  11299  | 
|  11912  |  | 
|  11913 void LibraryPrefix::set_importer(const Library& value) const { |  11300 void LibraryPrefix::set_importer(const Library& value) const { | 
|  11914   StorePointer(&raw_ptr()->importer_, value.raw()); |  11301   StorePointer(&raw_ptr()->importer_, value.raw()); | 
|  11915 } |  11302 } | 
|  11916  |  11303  | 
|  11917  |  | 
|  11918 const char* LibraryPrefix::ToCString() const { |  11304 const char* LibraryPrefix::ToCString() const { | 
|  11919   const String& prefix = String::Handle(name()); |  11305   const String& prefix = String::Handle(name()); | 
|  11920   return OS::SCreate(Thread::Current()->zone(), "LibraryPrefix:'%s'", |  11306   return OS::SCreate(Thread::Current()->zone(), "LibraryPrefix:'%s'", | 
|  11921                      prefix.ToCString()); |  11307                      prefix.ToCString()); | 
|  11922 } |  11308 } | 
|  11923  |  11309  | 
|  11924  |  | 
|  11925 void Namespace::set_metadata_field(const Field& value) const { |  11310 void Namespace::set_metadata_field(const Field& value) const { | 
|  11926   StorePointer(&raw_ptr()->metadata_field_, value.raw()); |  11311   StorePointer(&raw_ptr()->metadata_field_, value.raw()); | 
|  11927 } |  11312 } | 
|  11928  |  11313  | 
|  11929  |  | 
|  11930 void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) { |  11314 void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) { | 
|  11931   ASSERT(Field::Handle(metadata_field()).IsNull()); |  11315   ASSERT(Field::Handle(metadata_field()).IsNull()); | 
|  11932   Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(), |  11316   Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(), | 
|  11933                                                   false,  // is_final |  11317                                                   false,  // is_final | 
|  11934                                                   false,  // is_const |  11318                                                   false,  // is_const | 
|  11935                                                   owner, token_pos)); |  11319                                                   owner, token_pos)); | 
|  11936   field.set_is_reflectable(false); |  11320   field.set_is_reflectable(false); | 
|  11937   field.SetFieldType(Object::dynamic_type()); |  11321   field.SetFieldType(Object::dynamic_type()); | 
|  11938   field.SetStaticValue(Array::empty_array(), true); |  11322   field.SetStaticValue(Array::empty_array(), true); | 
|  11939   set_metadata_field(field); |  11323   set_metadata_field(field); | 
|  11940 } |  11324 } | 
|  11941  |  11325  | 
|  11942  |  | 
|  11943 RawObject* Namespace::GetMetadata() const { |  11326 RawObject* Namespace::GetMetadata() const { | 
|  11944 #if defined(DART_PRECOMPILED_RUNTIME) |  11327 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  11945   COMPILE_ASSERT(!FLAG_enable_mirrors); |  11328   COMPILE_ASSERT(!FLAG_enable_mirrors); | 
|  11946   return Object::empty_array().raw(); |  11329   return Object::empty_array().raw(); | 
|  11947 #else |  11330 #else | 
|  11948   Field& field = Field::Handle(metadata_field()); |  11331   Field& field = Field::Handle(metadata_field()); | 
|  11949   if (field.IsNull()) { |  11332   if (field.IsNull()) { | 
|  11950     // There is no metadata for this object. |  11333     // There is no metadata for this object. | 
|  11951     return Object::empty_array().raw(); |  11334     return Object::empty_array().raw(); | 
|  11952   } |  11335   } | 
|  11953   Object& metadata = Object::Handle(); |  11336   Object& metadata = Object::Handle(); | 
|  11954   metadata = field.StaticValue(); |  11337   metadata = field.StaticValue(); | 
|  11955   if (field.StaticValue() == Object::empty_array().raw()) { |  11338   if (field.StaticValue() == Object::empty_array().raw()) { | 
|  11956     metadata = Parser::ParseMetadata(field); |  11339     metadata = Parser::ParseMetadata(field); | 
|  11957     if (metadata.IsArray()) { |  11340     if (metadata.IsArray()) { | 
|  11958       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); |  11341       ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); | 
|  11959       field.SetStaticValue(Array::Cast(metadata), true); |  11342       field.SetStaticValue(Array::Cast(metadata), true); | 
|  11960     } |  11343     } | 
|  11961   } |  11344   } | 
|  11962   return metadata.raw(); |  11345   return metadata.raw(); | 
|  11963 #endif  // defined(DART_PRECOMPILED_RUNTIME) |  11346 #endif  // defined(DART_PRECOMPILED_RUNTIME) | 
|  11964 } |  11347 } | 
|  11965  |  11348  | 
|  11966  |  | 
|  11967 const char* Namespace::ToCString() const { |  11349 const char* Namespace::ToCString() const { | 
|  11968   const Library& lib = Library::Handle(library()); |  11350   const Library& lib = Library::Handle(library()); | 
|  11969   return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'", |  11351   return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'", | 
|  11970                      lib.ToCString()); |  11352                      lib.ToCString()); | 
|  11971 } |  11353 } | 
|  11972  |  11354  | 
|  11973  |  | 
|  11974 bool Namespace::HidesName(const String& name) const { |  11355 bool Namespace::HidesName(const String& name) const { | 
|  11975   // Quick check for common case with no combinators. |  11356   // Quick check for common case with no combinators. | 
|  11976   if (hide_names() == show_names()) { |  11357   if (hide_names() == show_names()) { | 
|  11977     ASSERT(hide_names() == Array::null()); |  11358     ASSERT(hide_names() == Array::null()); | 
|  11978     return false; |  11359     return false; | 
|  11979   } |  11360   } | 
|  11980   const String* plain_name = &name; |  11361   const String* plain_name = &name; | 
|  11981   if (Field::IsGetterName(name)) { |  11362   if (Field::IsGetterName(name)) { | 
|  11982     plain_name = &String::Handle(Field::NameFromGetter(name)); |  11363     plain_name = &String::Handle(Field::NameFromGetter(name)); | 
|  11983   } else if (Field::IsSetterName(name)) { |  11364   } else if (Field::IsSetterName(name)) { | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  12008       } |  11389       } | 
|  12009     } |  11390     } | 
|  12010     // There is a list of visible names. The name we're looking for is not |  11391     // There is a list of visible names. The name we're looking for is not | 
|  12011     // contained in the list, so it is hidden. |  11392     // contained in the list, so it is hidden. | 
|  12012     return true; |  11393     return true; | 
|  12013   } |  11394   } | 
|  12014   // The name is not filtered out. |  11395   // The name is not filtered out. | 
|  12015   return false; |  11396   return false; | 
|  12016 } |  11397 } | 
|  12017  |  11398  | 
|  12018  |  | 
|  12019 // Look up object with given name in library and filter out hidden |  11399 // Look up object with given name in library and filter out hidden | 
|  12020 // names. Also look up getters and setters. |  11400 // names. Also look up getters and setters. | 
|  12021 RawObject* Namespace::Lookup(const String& name, |  11401 RawObject* Namespace::Lookup(const String& name, | 
|  12022                              ZoneGrowableArray<intptr_t>* trail) const { |  11402                              ZoneGrowableArray<intptr_t>* trail) const { | 
|  12023   Zone* zone = Thread::Current()->zone(); |  11403   Zone* zone = Thread::Current()->zone(); | 
|  12024   const Library& lib = Library::Handle(zone, library()); |  11404   const Library& lib = Library::Handle(zone, library()); | 
|  12025  |  11405  | 
|  12026   if (trail != NULL) { |  11406   if (trail != NULL) { | 
|  12027     // Look for cycle in reexport graph. |  11407     // Look for cycle in reexport graph. | 
|  12028     for (int i = 0; i < trail->length(); i++) { |  11408     for (int i = 0; i < trail->length(); i++) { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  12066         obj = lib.LookupReExport(setter_name, trail); |  11446         obj = lib.LookupReExport(setter_name, trail); | 
|  12067       } |  11447       } | 
|  12068     } |  11448     } | 
|  12069   } |  11449   } | 
|  12070   if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { |  11450   if (obj.IsNull() || HidesName(name) || obj.IsLibraryPrefix()) { | 
|  12071     return Object::null(); |  11451     return Object::null(); | 
|  12072   } |  11452   } | 
|  12073   return obj.raw(); |  11453   return obj.raw(); | 
|  12074 } |  11454 } | 
|  12075  |  11455  | 
|  12076  |  | 
|  12077 RawNamespace* Namespace::New() { |  11456 RawNamespace* Namespace::New() { | 
|  12078   ASSERT(Object::namespace_class() != Class::null()); |  11457   ASSERT(Object::namespace_class() != Class::null()); | 
|  12079   RawObject* raw = Object::Allocate(Namespace::kClassId, |  11458   RawObject* raw = Object::Allocate(Namespace::kClassId, | 
|  12080                                     Namespace::InstanceSize(), Heap::kOld); |  11459                                     Namespace::InstanceSize(), Heap::kOld); | 
|  12081   return reinterpret_cast<RawNamespace*>(raw); |  11460   return reinterpret_cast<RawNamespace*>(raw); | 
|  12082 } |  11461 } | 
|  12083  |  11462  | 
|  12084  |  | 
|  12085 RawNamespace* Namespace::New(const Library& library, |  11463 RawNamespace* Namespace::New(const Library& library, | 
|  12086                              const Array& show_names, |  11464                              const Array& show_names, | 
|  12087                              const Array& hide_names) { |  11465                              const Array& hide_names) { | 
|  12088   ASSERT(show_names.IsNull() || (show_names.Length() > 0)); |  11466   ASSERT(show_names.IsNull() || (show_names.Length() > 0)); | 
|  12089   ASSERT(hide_names.IsNull() || (hide_names.Length() > 0)); |  11467   ASSERT(hide_names.IsNull() || (hide_names.Length() > 0)); | 
|  12090   const Namespace& result = Namespace::Handle(Namespace::New()); |  11468   const Namespace& result = Namespace::Handle(Namespace::New()); | 
|  12091   result.StorePointer(&result.raw_ptr()->library_, library.raw()); |  11469   result.StorePointer(&result.raw_ptr()->library_, library.raw()); | 
|  12092   result.StorePointer(&result.raw_ptr()->show_names_, show_names.raw()); |  11470   result.StorePointer(&result.raw_ptr()->show_names_, show_names.raw()); | 
|  12093   result.StorePointer(&result.raw_ptr()->hide_names_, hide_names.raw()); |  11471   result.StorePointer(&result.raw_ptr()->hide_names_, hide_names.raw()); | 
|  12094   return result.raw(); |  11472   return result.raw(); | 
|  12095 } |  11473 } | 
|  12096  |  11474  | 
|  12097  |  | 
|  12098 RawError* Library::CompileAll() { |  11475 RawError* Library::CompileAll() { | 
|  12099   Thread* thread = Thread::Current(); |  11476   Thread* thread = Thread::Current(); | 
|  12100   Zone* zone = thread->zone(); |  11477   Zone* zone = thread->zone(); | 
|  12101   Error& error = Error::Handle(zone); |  11478   Error& error = Error::Handle(zone); | 
|  12102   const GrowableObjectArray& libs = GrowableObjectArray::Handle( |  11479   const GrowableObjectArray& libs = GrowableObjectArray::Handle( | 
|  12103       Isolate::Current()->object_store()->libraries()); |  11480       Isolate::Current()->object_store()->libraries()); | 
|  12104   Library& lib = Library::Handle(zone); |  11481   Library& lib = Library::Handle(zone); | 
|  12105   Class& cls = Class::Handle(zone); |  11482   Class& cls = Class::Handle(zone); | 
|  12106   for (int i = 0; i < libs.Length(); i++) { |  11483   for (int i = 0; i < libs.Length(); i++) { | 
|  12107     lib ^= libs.At(i); |  11484     lib ^= libs.At(i); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  12133       if (result.IsError()) { |  11510       if (result.IsError()) { | 
|  12134         return Error::Cast(result).raw(); |  11511         return Error::Cast(result).raw(); | 
|  12135       } |  11512       } | 
|  12136       func.ClearICDataArray(); |  11513       func.ClearICDataArray(); | 
|  12137       func.ClearCode(); |  11514       func.ClearCode(); | 
|  12138     } |  11515     } | 
|  12139   } |  11516   } | 
|  12140   return Error::null(); |  11517   return Error::null(); | 
|  12141 } |  11518 } | 
|  12142  |  11519  | 
|  12143  |  | 
|  12144 RawError* Library::ParseAll(Thread* thread) { |  11520 RawError* Library::ParseAll(Thread* thread) { | 
|  12145   Zone* zone = thread->zone(); |  11521   Zone* zone = thread->zone(); | 
|  12146   Error& error = Error::Handle(zone); |  11522   Error& error = Error::Handle(zone); | 
|  12147   Isolate* isolate = thread->isolate(); |  11523   Isolate* isolate = thread->isolate(); | 
|  12148   const GrowableObjectArray& libs = |  11524   const GrowableObjectArray& libs = | 
|  12149       GrowableObjectArray::Handle(isolate->object_store()->libraries()); |  11525       GrowableObjectArray::Handle(isolate->object_store()->libraries()); | 
|  12150   Library& lib = Library::Handle(zone); |  11526   Library& lib = Library::Handle(zone); | 
|  12151   Class& cls = Class::Handle(zone); |  11527   Class& cls = Class::Handle(zone); | 
|  12152   for (int i = 0; i < libs.Length(); i++) { |  11528   for (int i = 0; i < libs.Length(); i++) { | 
|  12153     lib ^= libs.At(i); |  11529     lib ^= libs.At(i); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  12178       if (!error.IsNull()) { |  11554       if (!error.IsNull()) { | 
|  12179         return error.raw(); |  11555         return error.raw(); | 
|  12180       } |  11556       } | 
|  12181       func.ClearICDataArray(); |  11557       func.ClearICDataArray(); | 
|  12182       func.ClearCode(); |  11558       func.ClearCode(); | 
|  12183     } |  11559     } | 
|  12184   } |  11560   } | 
|  12185   return error.raw(); |  11561   return error.raw(); | 
|  12186 } |  11562 } | 
|  12187  |  11563  | 
|  12188  |  | 
|  12189 // Return Function::null() if function does not exist in libs. |  11564 // Return Function::null() if function does not exist in libs. | 
|  12190 RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs, |  11565 RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs, | 
|  12191                                   const char* class_name, |  11566                                   const char* class_name, | 
|  12192                                   const char* function_name) { |  11567                                   const char* function_name) { | 
|  12193   Thread* thread = Thread::Current(); |  11568   Thread* thread = Thread::Current(); | 
|  12194   Zone* zone = thread->zone(); |  11569   Zone* zone = thread->zone(); | 
|  12195   Function& func = Function::Handle(zone); |  11570   Function& func = Function::Handle(zone); | 
|  12196   String& class_str = String::Handle(zone); |  11571   String& class_str = String::Handle(zone); | 
|  12197   String& func_str = String::Handle(zone); |  11572   String& func_str = String::Handle(zone); | 
|  12198   Class& cls = Class::Handle(zone); |  11573   Class& cls = Class::Handle(zone); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  12212         func = cls.LookupFunctionAllowPrivate(func_str); |  11587         func = cls.LookupFunctionAllowPrivate(func_str); | 
|  12213       } |  11588       } | 
|  12214     } |  11589     } | 
|  12215     if (!func.IsNull()) { |  11590     if (!func.IsNull()) { | 
|  12216       return func.raw(); |  11591       return func.raw(); | 
|  12217     } |  11592     } | 
|  12218   } |  11593   } | 
|  12219   return Function::null(); |  11594   return Function::null(); | 
|  12220 } |  11595 } | 
|  12221  |  11596  | 
|  12222  |  | 
|  12223 RawObject* Library::GetFunctionClosure(const String& name) const { |  11597 RawObject* Library::GetFunctionClosure(const String& name) const { | 
|  12224   Thread* thread = Thread::Current(); |  11598   Thread* thread = Thread::Current(); | 
|  12225   Zone* zone = thread->zone(); |  11599   Zone* zone = thread->zone(); | 
|  12226   Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name)); |  11600   Function& func = Function::Handle(zone, LookupFunctionAllowPrivate(name)); | 
|  12227   if (func.IsNull()) { |  11601   if (func.IsNull()) { | 
|  12228     // Check whether the function is reexported into the library. |  11602     // Check whether the function is reexported into the library. | 
|  12229     const Object& obj = Object::Handle(zone, LookupReExport(name)); |  11603     const Object& obj = Object::Handle(zone, LookupReExport(name)); | 
|  12230     if (obj.IsFunction()) { |  11604     if (obj.IsFunction()) { | 
|  12231       func ^= obj.raw(); |  11605       func ^= obj.raw(); | 
|  12232     } else { |  11606     } else { | 
|  12233       // Check if there is a getter of 'name', in which case invoke it |  11607       // Check if there is a getter of 'name', in which case invoke it | 
|  12234       // and return the result. |  11608       // and return the result. | 
|  12235       const String& getter_name = String::Handle(zone, Field::GetterName(name)); |  11609       const String& getter_name = String::Handle(zone, Field::GetterName(name)); | 
|  12236       func = LookupFunctionAllowPrivate(getter_name); |  11610       func = LookupFunctionAllowPrivate(getter_name); | 
|  12237       if (func.IsNull()) { |  11611       if (func.IsNull()) { | 
|  12238         return Closure::null(); |  11612         return Closure::null(); | 
|  12239       } |  11613       } | 
|  12240       // Invoke the getter and return the result. |  11614       // Invoke the getter and return the result. | 
|  12241       return DartEntry::InvokeFunction(func, Object::empty_array()); |  11615       return DartEntry::InvokeFunction(func, Object::empty_array()); | 
|  12242     } |  11616     } | 
|  12243   } |  11617   } | 
|  12244   func = func.ImplicitClosureFunction(); |  11618   func = func.ImplicitClosureFunction(); | 
|  12245   return func.ImplicitStaticClosure(); |  11619   return func.ImplicitStaticClosure(); | 
|  12246 } |  11620 } | 
|  12247  |  11621  | 
|  12248  |  | 
|  12249 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT) |  11622 #if defined(DART_NO_SNAPSHOT) && !defined(PRODUCT) | 
|  12250 void Library::CheckFunctionFingerprints() { |  11623 void Library::CheckFunctionFingerprints() { | 
|  12251   GrowableArray<Library*> all_libs; |  11624   GrowableArray<Library*> all_libs; | 
|  12252   Function& func = Function::Handle(); |  11625   Function& func = Function::Handle(); | 
|  12253   bool has_errors = false; |  11626   bool has_errors = false; | 
|  12254  |  11627  | 
|  12255 #define CHECK_FINGERPRINTS(class_name, function_name, dest, fp)                \ |  11628 #define CHECK_FINGERPRINTS(class_name, function_name, dest, fp)                \ | 
|  12256   func = GetFunction(all_libs, #class_name, #function_name);                   \ |  11629   func = GetFunction(all_libs, #class_name, #function_name);                   \ | 
|  12257   if (func.IsNull()) {                                                         \ |  11630   if (func.IsNull()) {                                                         \ | 
|  12258     has_errors = true;                                                         \ |  11631     has_errors = true;                                                         \ | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|  12285   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary())); |  11658   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary())); | 
|  12286   MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); |  11659   MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); | 
|  12287  |  11660  | 
|  12288   all_libs.Clear(); |  11661   all_libs.Clear(); | 
|  12289   all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary())); |  11662   all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary())); | 
|  12290   TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); |  11663   TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2); | 
|  12291  |  11664  | 
|  12292 #undef CHECK_FINGERPRINTS |  11665 #undef CHECK_FINGERPRINTS | 
|  12293 #undef CHECK_FINGERPRINTS2 |  11666 #undef CHECK_FINGERPRINTS2 | 
|  12294  |  11667  | 
|  12295  |  | 
|  12296 #define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp)  \ |  11668 #define CHECK_FACTORY_FINGERPRINTS(symbol, class_name, factory_name, cid, fp)  \ | 
|  12297   func = GetFunction(all_libs, #class_name, #factory_name);                    \ |  11669   func = GetFunction(all_libs, #class_name, #factory_name);                    \ | 
|  12298   if (func.IsNull()) {                                                         \ |  11670   if (func.IsNull()) {                                                         \ | 
|  12299     has_errors = true;                                                         \ |  11671     has_errors = true;                                                         \ | 
|  12300     OS::Print("Function not found %s.%s\n", #class_name, #factory_name);       \ |  11672     OS::Print("Function not found %s.%s\n", #class_name, #factory_name);       \ | 
|  12301   } else {                                                                     \ |  11673   } else {                                                                     \ | 
|  12302     CHECK_FINGERPRINT2(func, symbol, cid, fp);                                 \ |  11674     CHECK_FINGERPRINT2(func, symbol, cid, fp);                                 \ | 
|  12303   } |  11675   } | 
|  12304  |  11676  | 
|  12305   all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary())); |  11677   all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary())); | 
|  12306   RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS); |  11678   RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS); | 
|  12307  |  11679  | 
|  12308 #undef CHECK_FACTORY_FINGERPRINTS |  11680 #undef CHECK_FACTORY_FINGERPRINTS | 
|  12309  |  11681  | 
|  12310   if (has_errors) { |  11682   if (has_errors) { | 
|  12311     FATAL("Fingerprint mismatch."); |  11683     FATAL("Fingerprint mismatch."); | 
|  12312   } |  11684   } | 
|  12313 } |  11685 } | 
|  12314 #endif  // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT). |  11686 #endif  // defined(DART_NO_SNAPSHOT) && !defined(PRODUCT). | 
|  12315  |  11687  | 
|  12316  |  | 
|  12317 RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) { |  11688 RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) { | 
|  12318   ASSERT(size >= 0); |  11689   ASSERT(size >= 0); | 
|  12319   ASSERT(Object::instructions_class() != Class::null()); |  11690   ASSERT(Object::instructions_class() != Class::null()); | 
|  12320   if (size < 0 || size > kMaxElements) { |  11691   if (size < 0 || size > kMaxElements) { | 
|  12321     // This should be caught before we reach here. |  11692     // This should be caught before we reach here. | 
|  12322     FATAL1("Fatal error in Instructions::New: invalid size %" Pd "\n", size); |  11693     FATAL1("Fatal error in Instructions::New: invalid size %" Pd "\n", size); | 
|  12323   } |  11694   } | 
|  12324   Instructions& result = Instructions::Handle(); |  11695   Instructions& result = Instructions::Handle(); | 
|  12325   { |  11696   { | 
|  12326     uword aligned_size = Instructions::InstanceSize(size); |  11697     uword aligned_size = Instructions::InstanceSize(size); | 
|  12327     RawObject* raw = |  11698     RawObject* raw = | 
|  12328         Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode); |  11699         Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode); | 
|  12329     NoSafepointScope no_safepoint; |  11700     NoSafepointScope no_safepoint; | 
|  12330     result ^= raw; |  11701     result ^= raw; | 
|  12331     result.SetSize(size); |  11702     result.SetSize(size); | 
|  12332     result.SetHasSingleEntryPoint(has_single_entry_point); |  11703     result.SetHasSingleEntryPoint(has_single_entry_point); | 
|  12333   } |  11704   } | 
|  12334   return result.raw(); |  11705   return result.raw(); | 
|  12335 } |  11706 } | 
|  12336  |  11707  | 
|  12337  |  | 
|  12338 const char* Instructions::ToCString() const { |  11708 const char* Instructions::ToCString() const { | 
|  12339   return "Instructions"; |  11709   return "Instructions"; | 
|  12340 } |  11710 } | 
|  12341  |  11711  | 
|  12342  |  | 
|  12343 // Encode integer |value| in SLEB128 format and store into |data|. |  11712 // Encode integer |value| in SLEB128 format and store into |data|. | 
|  12344 static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) { |  11713 static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) { | 
|  12345   bool is_last_part = false; |  11714   bool is_last_part = false; | 
|  12346   while (!is_last_part) { |  11715   while (!is_last_part) { | 
|  12347     uint8_t part = value & 0x7f; |  11716     uint8_t part = value & 0x7f; | 
|  12348     value >>= 7; |  11717     value >>= 7; | 
|  12349     if ((value == 0 && (part & 0x40) == 0) || |  11718     if ((value == 0 && (part & 0x40) == 0) || | 
|  12350         (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) { |  11719         (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) { | 
|  12351       is_last_part = true; |  11720       is_last_part = true; | 
|  12352     } else { |  11721     } else { | 
|  12353       part |= 0x80; |  11722       part |= 0x80; | 
|  12354     } |  11723     } | 
|  12355     data->Add(part); |  11724     data->Add(part); | 
|  12356   } |  11725   } | 
|  12357 } |  11726 } | 
|  12358  |  11727  | 
|  12359  |  | 
|  12360 // Decode integer in SLEB128 format from |data| and update |byte_index|. |  11728 // Decode integer in SLEB128 format from |data| and update |byte_index|. | 
|  12361 static intptr_t DecodeSLEB128(const uint8_t* data, |  11729 static intptr_t DecodeSLEB128(const uint8_t* data, | 
|  12362                               const intptr_t data_length, |  11730                               const intptr_t data_length, | 
|  12363                               intptr_t* byte_index) { |  11731                               intptr_t* byte_index) { | 
|  12364   ASSERT(*byte_index < data_length); |  11732   ASSERT(*byte_index < data_length); | 
|  12365   uword shift = 0; |  11733   uword shift = 0; | 
|  12366   intptr_t value = 0; |  11734   intptr_t value = 0; | 
|  12367   uint8_t part = 0; |  11735   uint8_t part = 0; | 
|  12368   do { |  11736   do { | 
|  12369     part = data[(*byte_index)++]; |  11737     part = data[(*byte_index)++]; | 
|  12370     value |= static_cast<intptr_t>(part & 0x7f) << shift; |  11738     value |= static_cast<intptr_t>(part & 0x7f) << shift; | 
|  12371     shift += 7; |  11739     shift += 7; | 
|  12372   } while ((part & 0x80) != 0); |  11740   } while ((part & 0x80) != 0); | 
|  12373  |  11741  | 
|  12374   if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) { |  11742   if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) { | 
|  12375     value |= static_cast<intptr_t>(kUwordMax << shift); |  11743     value |= static_cast<intptr_t>(kUwordMax << shift); | 
|  12376   } |  11744   } | 
|  12377   return value; |  11745   return value; | 
|  12378 } |  11746 } | 
|  12379  |  11747  | 
|  12380  |  | 
|  12381 // Encode integer in SLEB128 format. |  11748 // Encode integer in SLEB128 format. | 
|  12382 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, |  11749 void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data, | 
|  12383                                   intptr_t value) { |  11750                                   intptr_t value) { | 
|  12384   return EncodeSLEB128(data, value); |  11751   return EncodeSLEB128(data, value); | 
|  12385 } |  11752 } | 
|  12386  |  11753  | 
|  12387  |  | 
|  12388 // Decode SLEB128 encoded integer. Update byte_index to the next integer. |  11754 // Decode SLEB128 encoded integer. Update byte_index to the next integer. | 
|  12389 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { |  11755 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const { | 
|  12390   NoSafepointScope no_safepoint; |  11756   NoSafepointScope no_safepoint; | 
|  12391   const uint8_t* data = raw_ptr()->data(); |  11757   const uint8_t* data = raw_ptr()->data(); | 
|  12392   return DecodeSLEB128(data, Length(), byte_index); |  11758   return DecodeSLEB128(data, Length(), byte_index); | 
|  12393 } |  11759 } | 
|  12394  |  11760  | 
|  12395  |  | 
|  12396 RawObjectPool* ObjectPool::New(intptr_t len) { |  11761 RawObjectPool* ObjectPool::New(intptr_t len) { | 
|  12397   ASSERT(Object::object_pool_class() != Class::null()); |  11762   ASSERT(Object::object_pool_class() != Class::null()); | 
|  12398   if (len < 0 || len > kMaxElements) { |  11763   if (len < 0 || len > kMaxElements) { | 
|  12399     // This should be caught before we reach here. |  11764     // This should be caught before we reach here. | 
|  12400     FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len); |  11765     FATAL1("Fatal error in ObjectPool::New: invalid length %" Pd "\n", len); | 
|  12401   } |  11766   } | 
|  12402   ObjectPool& result = ObjectPool::Handle(); |  11767   ObjectPool& result = ObjectPool::Handle(); | 
|  12403   { |  11768   { | 
|  12404     uword size = ObjectPool::InstanceSize(len); |  11769     uword size = ObjectPool::InstanceSize(len); | 
|  12405     RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld); |  11770     RawObject* raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld); | 
|  12406     NoSafepointScope no_safepoint; |  11771     NoSafepointScope no_safepoint; | 
|  12407     result ^= raw; |  11772     result ^= raw; | 
|  12408     result.SetLength(len); |  11773     result.SetLength(len); | 
|  12409   } |  11774   } | 
|  12410  |  11775  | 
|  12411   // TODO(fschneider): Compress info array to just use just enough bits for |  11776   // TODO(fschneider): Compress info array to just use just enough bits for | 
|  12412   // the entry type enum. |  11777   // the entry type enum. | 
|  12413   const TypedData& info_array = TypedData::Handle( |  11778   const TypedData& info_array = TypedData::Handle( | 
|  12414       TypedData::New(kTypedDataInt8ArrayCid, len, Heap::kOld)); |  11779       TypedData::New(kTypedDataInt8ArrayCid, len, Heap::kOld)); | 
|  12415   result.set_info_array(info_array); |  11780   result.set_info_array(info_array); | 
|  12416   return result.raw(); |  11781   return result.raw(); | 
|  12417 } |  11782 } | 
|  12418  |  11783  | 
|  12419  |  | 
|  12420 void ObjectPool::set_info_array(const TypedData& info_array) const { |  11784 void ObjectPool::set_info_array(const TypedData& info_array) const { | 
|  12421   StorePointer(&raw_ptr()->info_array_, info_array.raw()); |  11785   StorePointer(&raw_ptr()->info_array_, info_array.raw()); | 
|  12422 } |  11786 } | 
|  12423  |  11787  | 
|  12424  |  | 
|  12425 ObjectPool::EntryType ObjectPool::InfoAt(intptr_t index) const { |  11788 ObjectPool::EntryType ObjectPool::InfoAt(intptr_t index) const { | 
|  12426   ObjectPoolInfo pool_info(*this); |  11789   ObjectPoolInfo pool_info(*this); | 
|  12427   return pool_info.InfoAt(index); |  11790   return pool_info.InfoAt(index); | 
|  12428 } |  11791 } | 
|  12429  |  11792  | 
|  12430  |  | 
|  12431 const char* ObjectPool::ToCString() const { |  11793 const char* ObjectPool::ToCString() const { | 
|  12432   Zone* zone = Thread::Current()->zone(); |  11794   Zone* zone = Thread::Current()->zone(); | 
|  12433   return zone->PrintToString("ObjectPool len:%" Pd, Length()); |  11795   return zone->PrintToString("ObjectPool len:%" Pd, Length()); | 
|  12434 } |  11796 } | 
|  12435  |  11797  | 
|  12436  |  | 
|  12437 void ObjectPool::DebugPrint() const { |  11798 void ObjectPool::DebugPrint() const { | 
|  12438   THR_Print("Object Pool: 0x%" Px "{\n", reinterpret_cast<uword>(raw())); |  11799   THR_Print("Object Pool: 0x%" Px "{\n", reinterpret_cast<uword>(raw())); | 
|  12439   for (intptr_t i = 0; i < Length(); i++) { |  11800   for (intptr_t i = 0; i < Length(); i++) { | 
|  12440     intptr_t offset = OffsetFromIndex(i); |  11801     intptr_t offset = OffsetFromIndex(i); | 
|  12441     THR_Print("  %" Pd " PP+0x%" Px ": ", i, offset); |  11802     THR_Print("  %" Pd " PP+0x%" Px ": ", i, offset); | 
|  12442     if (InfoAt(i) == kTaggedObject) { |  11803     if (InfoAt(i) == kTaggedObject) { | 
|  12443       RawObject* obj = ObjectAt(i); |  11804       RawObject* obj = ObjectAt(i); | 
|  12444       THR_Print("0x%" Px " %s (obj)\n", reinterpret_cast<uword>(obj), |  11805       THR_Print("0x%" Px " %s (obj)\n", reinterpret_cast<uword>(obj), | 
|  12445                 Object::Handle(obj).ToCString()); |  11806                 Object::Handle(obj).ToCString()); | 
|  12446     } else if (InfoAt(i) == kNativeEntry) { |  11807     } else if (InfoAt(i) == kNativeEntry) { | 
|  12447       THR_Print("0x%" Px " (native entry)\n", RawValueAt(i)); |  11808       THR_Print("0x%" Px " (native entry)\n", RawValueAt(i)); | 
|  12448     } else { |  11809     } else { | 
|  12449       THR_Print("0x%" Px " (raw)\n", RawValueAt(i)); |  11810       THR_Print("0x%" Px " (raw)\n", RawValueAt(i)); | 
|  12450     } |  11811     } | 
|  12451   } |  11812   } | 
|  12452   THR_Print("}\n"); |  11813   THR_Print("}\n"); | 
|  12453 } |  11814 } | 
|  12454  |  11815  | 
|  12455  |  | 
|  12456 intptr_t PcDescriptors::Length() const { |  11816 intptr_t PcDescriptors::Length() const { | 
|  12457   return raw_ptr()->length_; |  11817   return raw_ptr()->length_; | 
|  12458 } |  11818 } | 
|  12459  |  11819  | 
|  12460  |  | 
|  12461 void PcDescriptors::SetLength(intptr_t value) const { |  11820 void PcDescriptors::SetLength(intptr_t value) const { | 
|  12462   StoreNonPointer(&raw_ptr()->length_, value); |  11821   StoreNonPointer(&raw_ptr()->length_, value); | 
|  12463 } |  11822 } | 
|  12464  |  11823  | 
|  12465  |  | 
|  12466 void PcDescriptors::CopyData(GrowableArray<uint8_t>* delta_encoded_data) { |  11824 void PcDescriptors::CopyData(GrowableArray<uint8_t>* delta_encoded_data) { | 
|  12467   NoSafepointScope no_safepoint; |  11825   NoSafepointScope no_safepoint; | 
|  12468   uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]); |  11826   uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]); | 
|  12469   for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) { |  11827   for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) { | 
|  12470     data[i] = (*delta_encoded_data)[i]; |  11828     data[i] = (*delta_encoded_data)[i]; | 
|  12471   } |  11829   } | 
|  12472 } |  11830 } | 
|  12473  |  11831  | 
|  12474  |  | 
|  12475 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { |  11832 RawPcDescriptors* PcDescriptors::New(GrowableArray<uint8_t>* data) { | 
|  12476   ASSERT(Object::pc_descriptors_class() != Class::null()); |  11833   ASSERT(Object::pc_descriptors_class() != Class::null()); | 
|  12477   Thread* thread = Thread::Current(); |  11834   Thread* thread = Thread::Current(); | 
|  12478   PcDescriptors& result = PcDescriptors::Handle(thread->zone()); |  11835   PcDescriptors& result = PcDescriptors::Handle(thread->zone()); | 
|  12479   { |  11836   { | 
|  12480     uword size = PcDescriptors::InstanceSize(data->length()); |  11837     uword size = PcDescriptors::InstanceSize(data->length()); | 
|  12481     RawObject* raw = |  11838     RawObject* raw = | 
|  12482         Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); |  11839         Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); | 
|  12483     INC_STAT(thread, total_code_size, size); |  11840     INC_STAT(thread, total_code_size, size); | 
|  12484     INC_STAT(thread, pc_desc_size, size); |  11841     INC_STAT(thread, pc_desc_size, size); | 
|  12485     NoSafepointScope no_safepoint; |  11842     NoSafepointScope no_safepoint; | 
|  12486     result ^= raw; |  11843     result ^= raw; | 
|  12487     result.SetLength(data->length()); |  11844     result.SetLength(data->length()); | 
|  12488     result.CopyData(data); |  11845     result.CopyData(data); | 
|  12489   } |  11846   } | 
|  12490   return result.raw(); |  11847   return result.raw(); | 
|  12491 } |  11848 } | 
|  12492  |  11849  | 
|  12493  |  | 
|  12494 RawPcDescriptors* PcDescriptors::New(intptr_t length) { |  11850 RawPcDescriptors* PcDescriptors::New(intptr_t length) { | 
|  12495   ASSERT(Object::pc_descriptors_class() != Class::null()); |  11851   ASSERT(Object::pc_descriptors_class() != Class::null()); | 
|  12496   Thread* thread = Thread::Current(); |  11852   Thread* thread = Thread::Current(); | 
|  12497   PcDescriptors& result = PcDescriptors::Handle(thread->zone()); |  11853   PcDescriptors& result = PcDescriptors::Handle(thread->zone()); | 
|  12498   { |  11854   { | 
|  12499     uword size = PcDescriptors::InstanceSize(length); |  11855     uword size = PcDescriptors::InstanceSize(length); | 
|  12500     RawObject* raw = |  11856     RawObject* raw = | 
|  12501         Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); |  11857         Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld); | 
|  12502     INC_STAT(thread, total_code_size, size); |  11858     INC_STAT(thread, total_code_size, size); | 
|  12503     INC_STAT(thread, pc_desc_size, size); |  11859     INC_STAT(thread, pc_desc_size, size); | 
|  12504     NoSafepointScope no_safepoint; |  11860     NoSafepointScope no_safepoint; | 
|  12505     result ^= raw; |  11861     result ^= raw; | 
|  12506     result.SetLength(length); |  11862     result.SetLength(length); | 
|  12507   } |  11863   } | 
|  12508   return result.raw(); |  11864   return result.raw(); | 
|  12509 } |  11865 } | 
|  12510  |  11866  | 
|  12511  |  | 
|  12512 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { |  11867 const char* PcDescriptors::KindAsStr(RawPcDescriptors::Kind kind) { | 
|  12513   switch (kind) { |  11868   switch (kind) { | 
|  12514     case RawPcDescriptors::kDeopt: |  11869     case RawPcDescriptors::kDeopt: | 
|  12515       return "deopt        "; |  11870       return "deopt        "; | 
|  12516     case RawPcDescriptors::kIcCall: |  11871     case RawPcDescriptors::kIcCall: | 
|  12517       return "ic-call      "; |  11872       return "ic-call      "; | 
|  12518     case RawPcDescriptors::kUnoptStaticCall: |  11873     case RawPcDescriptors::kUnoptStaticCall: | 
|  12519       return "unopt-call   "; |  11874       return "unopt-call   "; | 
|  12520     case RawPcDescriptors::kRuntimeCall: |  11875     case RawPcDescriptors::kRuntimeCall: | 
|  12521       return "runtime-call "; |  11876       return "runtime-call "; | 
|  12522     case RawPcDescriptors::kOsrEntry: |  11877     case RawPcDescriptors::kOsrEntry: | 
|  12523       return "osr-entry    "; |  11878       return "osr-entry    "; | 
|  12524     case RawPcDescriptors::kRewind: |  11879     case RawPcDescriptors::kRewind: | 
|  12525       return "rewind       "; |  11880       return "rewind       "; | 
|  12526     case RawPcDescriptors::kOther: |  11881     case RawPcDescriptors::kOther: | 
|  12527       return "other        "; |  11882       return "other        "; | 
|  12528     case RawPcDescriptors::kAnyKind: |  11883     case RawPcDescriptors::kAnyKind: | 
|  12529       UNREACHABLE(); |  11884       UNREACHABLE(); | 
|  12530       break; |  11885       break; | 
|  12531   } |  11886   } | 
|  12532   UNREACHABLE(); |  11887   UNREACHABLE(); | 
|  12533   return ""; |  11888   return ""; | 
|  12534 } |  11889 } | 
|  12535  |  11890  | 
|  12536  |  | 
|  12537 void PcDescriptors::PrintHeaderString() { |  11891 void PcDescriptors::PrintHeaderString() { | 
|  12538   // 4 bits per hex digit + 2 for "0x". |  11892   // 4 bits per hex digit + 2 for "0x". | 
|  12539   const int addr_width = (kBitsPerWord / 4) + 2; |  11893   const int addr_width = (kBitsPerWord / 4) + 2; | 
|  12540   // "*" in a printf format specifier tells it to read the field width from |  11894   // "*" in a printf format specifier tells it to read the field width from | 
|  12541   // the printf argument list. |  11895   // the printf argument list. | 
|  12542   THR_Print("%-*s\tkind    \tdeopt-id\ttok-ix\ttry-ix\n", addr_width, "pc"); |  11896   THR_Print("%-*s\tkind    \tdeopt-id\ttok-ix\ttry-ix\n", addr_width, "pc"); | 
|  12543 } |  11897 } | 
|  12544  |  11898  | 
|  12545  |  | 
|  12546 const char* PcDescriptors::ToCString() const { |  11899 const char* PcDescriptors::ToCString() const { | 
|  12547 // "*" in a printf format specifier tells it to read the field width from |  11900 // "*" in a printf format specifier tells it to read the field width from | 
|  12548 // the printf argument list. |  11901 // the printf argument list. | 
|  12549 #define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%s\t%" Pd "\n" |  11902 #define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%s\t%" Pd "\n" | 
|  12550   if (Length() == 0) { |  11903   if (Length() == 0) { | 
|  12551     return "empty PcDescriptors\n"; |  11904     return "empty PcDescriptors\n"; | 
|  12552   } |  11905   } | 
|  12553   // 4 bits per hex digit. |  11906   // 4 bits per hex digit. | 
|  12554   const int addr_width = kBitsPerWord / 4; |  11907   const int addr_width = kBitsPerWord / 4; | 
|  12555   // First compute the buffer size required. |  11908   // First compute the buffer size required. | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  12570   while (iter.MoveNext()) { |  11923   while (iter.MoveNext()) { | 
|  12571     index += |  11924     index += | 
|  12572         OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width, |  11925         OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width, | 
|  12573                     iter.PcOffset(), KindAsStr(iter.Kind()), iter.DeoptId(), |  11926                     iter.PcOffset(), KindAsStr(iter.Kind()), iter.DeoptId(), | 
|  12574                     iter.TokenPos().ToCString(), iter.TryIndex()); |  11927                     iter.TokenPos().ToCString(), iter.TryIndex()); | 
|  12575   } |  11928   } | 
|  12576   return buffer; |  11929   return buffer; | 
|  12577 #undef FORMAT |  11930 #undef FORMAT | 
|  12578 } |  11931 } | 
|  12579  |  11932  | 
|  12580  |  | 
|  12581 // Verify assumptions (in debug mode only). |  11933 // Verify assumptions (in debug mode only). | 
|  12582 // - No two deopt descriptors have the same deoptimization id. |  11934 // - No two deopt descriptors have the same deoptimization id. | 
|  12583 // - No two ic-call descriptors have the same deoptimization id (type feedback). |  11935 // - No two ic-call descriptors have the same deoptimization id (type feedback). | 
|  12584 // A function without unique ids is marked as non-optimizable (e.g., because of |  11936 // A function without unique ids is marked as non-optimizable (e.g., because of | 
|  12585 // finally blocks). |  11937 // finally blocks). | 
|  12586 void PcDescriptors::Verify(const Function& function) const { |  11938 void PcDescriptors::Verify(const Function& function) const { | 
|  12587 #if defined(DEBUG) |  11939 #if defined(DEBUG) | 
|  12588   // Only check ids for unoptimized code that is optimizable. |  11940   // Only check ids for unoptimized code that is optimizable. | 
|  12589   if (!function.IsOptimizable()) { |  11941   if (!function.IsOptimizable()) { | 
|  12590     return; |  11942     return; | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  12614       ASSERT(!deopt_ids->Contains(iter.DeoptId())); |  11966       ASSERT(!deopt_ids->Contains(iter.DeoptId())); | 
|  12615       deopt_ids->Add(iter.DeoptId()); |  11967       deopt_ids->Add(iter.DeoptId()); | 
|  12616     } else { |  11968     } else { | 
|  12617       ASSERT(!iccall_ids->Contains(iter.DeoptId())); |  11969       ASSERT(!iccall_ids->Contains(iter.DeoptId())); | 
|  12618       iccall_ids->Add(iter.DeoptId()); |  11970       iccall_ids->Add(iter.DeoptId()); | 
|  12619     } |  11971     } | 
|  12620   } |  11972   } | 
|  12621 #endif  // DEBUG |  11973 #endif  // DEBUG | 
|  12622 } |  11974 } | 
|  12623  |  11975  | 
|  12624  |  | 
|  12625 void CodeSourceMap::SetLength(intptr_t value) const { |  11976 void CodeSourceMap::SetLength(intptr_t value) const { | 
|  12626   StoreNonPointer(&raw_ptr()->length_, value); |  11977   StoreNonPointer(&raw_ptr()->length_, value); | 
|  12627 } |  11978 } | 
|  12628  |  11979  | 
|  12629  |  | 
|  12630 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { |  11980 RawCodeSourceMap* CodeSourceMap::New(intptr_t length) { | 
|  12631   ASSERT(Object::code_source_map_class() != Class::null()); |  11981   ASSERT(Object::code_source_map_class() != Class::null()); | 
|  12632   Thread* thread = Thread::Current(); |  11982   Thread* thread = Thread::Current(); | 
|  12633   CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); |  11983   CodeSourceMap& result = CodeSourceMap::Handle(thread->zone()); | 
|  12634   { |  11984   { | 
|  12635     uword size = CodeSourceMap::InstanceSize(length); |  11985     uword size = CodeSourceMap::InstanceSize(length); | 
|  12636     RawObject* raw = |  11986     RawObject* raw = | 
|  12637         Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld); |  11987         Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld); | 
|  12638     NoSafepointScope no_safepoint; |  11988     NoSafepointScope no_safepoint; | 
|  12639     result ^= raw; |  11989     result ^= raw; | 
|  12640     result.SetLength(length); |  11990     result.SetLength(length); | 
|  12641   } |  11991   } | 
|  12642   return result.raw(); |  11992   return result.raw(); | 
|  12643 } |  11993 } | 
|  12644  |  11994  | 
|  12645  |  | 
|  12646 const char* CodeSourceMap::ToCString() const { |  11995 const char* CodeSourceMap::ToCString() const { | 
|  12647   return "CodeSourceMap"; |  11996   return "CodeSourceMap"; | 
|  12648 } |  11997 } | 
|  12649  |  11998  | 
|  12650  |  | 
|  12651 bool StackMap::GetBit(intptr_t bit_index) const { |  11999 bool StackMap::GetBit(intptr_t bit_index) const { | 
|  12652   ASSERT(InRange(bit_index)); |  12000   ASSERT(InRange(bit_index)); | 
|  12653   int byte_index = bit_index >> kBitsPerByteLog2; |  12001   int byte_index = bit_index >> kBitsPerByteLog2; | 
|  12654   int bit_remainder = bit_index & (kBitsPerByte - 1); |  12002   int bit_remainder = bit_index & (kBitsPerByte - 1); | 
|  12655   uint8_t byte_mask = 1U << bit_remainder; |  12003   uint8_t byte_mask = 1U << bit_remainder; | 
|  12656   uint8_t byte = raw_ptr()->data()[byte_index]; |  12004   uint8_t byte = raw_ptr()->data()[byte_index]; | 
|  12657   return (byte & byte_mask); |  12005   return (byte & byte_mask); | 
|  12658 } |  12006 } | 
|  12659  |  12007  | 
|  12660  |  | 
|  12661 void StackMap::SetBit(intptr_t bit_index, bool value) const { |  12008 void StackMap::SetBit(intptr_t bit_index, bool value) const { | 
|  12662   ASSERT(InRange(bit_index)); |  12009   ASSERT(InRange(bit_index)); | 
|  12663   int byte_index = bit_index >> kBitsPerByteLog2; |  12010   int byte_index = bit_index >> kBitsPerByteLog2; | 
|  12664   int bit_remainder = bit_index & (kBitsPerByte - 1); |  12011   int bit_remainder = bit_index & (kBitsPerByte - 1); | 
|  12665   uint8_t byte_mask = 1U << bit_remainder; |  12012   uint8_t byte_mask = 1U << bit_remainder; | 
|  12666   NoSafepointScope no_safepoint; |  12013   NoSafepointScope no_safepoint; | 
|  12667   uint8_t* byte_addr = UnsafeMutableNonPointer(&raw_ptr()->data()[byte_index]); |  12014   uint8_t* byte_addr = UnsafeMutableNonPointer(&raw_ptr()->data()[byte_index]); | 
|  12668   if (value) { |  12015   if (value) { | 
|  12669     *byte_addr |= byte_mask; |  12016     *byte_addr |= byte_mask; | 
|  12670   } else { |  12017   } else { | 
|  12671     *byte_addr &= ~byte_mask; |  12018     *byte_addr &= ~byte_mask; | 
|  12672   } |  12019   } | 
|  12673 } |  12020 } | 
|  12674  |  12021  | 
|  12675  |  | 
|  12676 RawStackMap* StackMap::New(intptr_t pc_offset, |  12022 RawStackMap* StackMap::New(intptr_t pc_offset, | 
|  12677                            BitmapBuilder* bmap, |  12023                            BitmapBuilder* bmap, | 
|  12678                            intptr_t slow_path_bit_count) { |  12024                            intptr_t slow_path_bit_count) { | 
|  12679   ASSERT(Object::stackmap_class() != Class::null()); |  12025   ASSERT(Object::stackmap_class() != Class::null()); | 
|  12680   ASSERT(bmap != NULL); |  12026   ASSERT(bmap != NULL); | 
|  12681   StackMap& result = StackMap::Handle(); |  12027   StackMap& result = StackMap::Handle(); | 
|  12682   // Guard against integer overflow of the instance size computation. |  12028   // Guard against integer overflow of the instance size computation. | 
|  12683   intptr_t length = bmap->Length(); |  12029   intptr_t length = bmap->Length(); | 
|  12684   intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; |  12030   intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; | 
|  12685   if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { |  12031   if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  12700   // address. |  12046   // address. | 
|  12701   ASSERT(pc_offset >= 0); |  12047   ASSERT(pc_offset >= 0); | 
|  12702   result.SetPcOffset(pc_offset); |  12048   result.SetPcOffset(pc_offset); | 
|  12703   for (intptr_t i = 0; i < length; ++i) { |  12049   for (intptr_t i = 0; i < length; ++i) { | 
|  12704     result.SetBit(i, bmap->Get(i)); |  12050     result.SetBit(i, bmap->Get(i)); | 
|  12705   } |  12051   } | 
|  12706   result.SetSlowPathBitCount(slow_path_bit_count); |  12052   result.SetSlowPathBitCount(slow_path_bit_count); | 
|  12707   return result.raw(); |  12053   return result.raw(); | 
|  12708 } |  12054 } | 
|  12709  |  12055  | 
|  12710  |  | 
|  12711 RawStackMap* StackMap::New(intptr_t length, |  12056 RawStackMap* StackMap::New(intptr_t length, | 
|  12712                            intptr_t slow_path_bit_count, |  12057                            intptr_t slow_path_bit_count, | 
|  12713                            intptr_t pc_offset) { |  12058                            intptr_t pc_offset) { | 
|  12714   ASSERT(Object::stackmap_class() != Class::null()); |  12059   ASSERT(Object::stackmap_class() != Class::null()); | 
|  12715   StackMap& result = StackMap::Handle(); |  12060   StackMap& result = StackMap::Handle(); | 
|  12716   // Guard against integer overflow of the instance size computation. |  12061   // Guard against integer overflow of the instance size computation. | 
|  12717   intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; |  12062   intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte; | 
|  12718   if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { |  12063   if ((payload_size < 0) || (payload_size > kMaxLengthInBytes)) { | 
|  12719     // This should be caught before we reach here. |  12064     // This should be caught before we reach here. | 
|  12720     FATAL1("Fatal error in StackMap::New: invalid length %" Pd "\n", length); |  12065     FATAL1("Fatal error in StackMap::New: invalid length %" Pd "\n", length); | 
|  12721   } |  12066   } | 
|  12722   { |  12067   { | 
|  12723     // StackMap data objects are associated with a code object, allocate them |  12068     // StackMap data objects are associated with a code object, allocate them | 
|  12724     // in old generation. |  12069     // in old generation. | 
|  12725     RawObject* raw = Object::Allocate( |  12070     RawObject* raw = Object::Allocate( | 
|  12726         StackMap::kClassId, StackMap::InstanceSize(length), Heap::kOld); |  12071         StackMap::kClassId, StackMap::InstanceSize(length), Heap::kOld); | 
|  12727     NoSafepointScope no_safepoint; |  12072     NoSafepointScope no_safepoint; | 
|  12728     result ^= raw; |  12073     result ^= raw; | 
|  12729     result.SetLength(length); |  12074     result.SetLength(length); | 
|  12730   } |  12075   } | 
|  12731   // When constructing a stackmap we store the pc offset in the stackmap's |  12076   // When constructing a stackmap we store the pc offset in the stackmap's | 
|  12732   // PC. StackMapTableBuilder::FinalizeStackMaps will replace it with the pc |  12077   // PC. StackMapTableBuilder::FinalizeStackMaps will replace it with the pc | 
|  12733   // address. |  12078   // address. | 
|  12734   ASSERT(pc_offset >= 0); |  12079   ASSERT(pc_offset >= 0); | 
|  12735   result.SetPcOffset(pc_offset); |  12080   result.SetPcOffset(pc_offset); | 
|  12736   result.SetSlowPathBitCount(slow_path_bit_count); |  12081   result.SetSlowPathBitCount(slow_path_bit_count); | 
|  12737   return result.raw(); |  12082   return result.raw(); | 
|  12738 } |  12083 } | 
|  12739  |  12084  | 
|  12740  |  | 
|  12741 const char* StackMap::ToCString() const { |  12085 const char* StackMap::ToCString() const { | 
|  12742 #define FORMAT "%#05x: " |  12086 #define FORMAT "%#05x: " | 
|  12743   if (IsNull()) { |  12087   if (IsNull()) { | 
|  12744     return "{null}"; |  12088     return "{null}"; | 
|  12745   } else { |  12089   } else { | 
|  12746     intptr_t fixed_length = OS::SNPrint(NULL, 0, FORMAT, PcOffset()) + 1; |  12090     intptr_t fixed_length = OS::SNPrint(NULL, 0, FORMAT, PcOffset()) + 1; | 
|  12747     Thread* thread = Thread::Current(); |  12091     Thread* thread = Thread::Current(); | 
|  12748     // Guard against integer overflow in the computation of alloc_size. |  12092     // Guard against integer overflow in the computation of alloc_size. | 
|  12749     // |  12093     // | 
|  12750     // TODO(kmillikin): We could just truncate the string if someone |  12094     // TODO(kmillikin): We could just truncate the string if someone | 
|  12751     // tries to print a 2 billion plus entry stackmap. |  12095     // tries to print a 2 billion plus entry stackmap. | 
|  12752     if (Length() > (kIntptrMax - fixed_length)) { |  12096     if (Length() > (kIntptrMax - fixed_length)) { | 
|  12753       FATAL1("Length() is unexpectedly large (%" Pd ")", Length()); |  12097       FATAL1("Length() is unexpectedly large (%" Pd ")", Length()); | 
|  12754     } |  12098     } | 
|  12755     intptr_t alloc_size = fixed_length + Length(); |  12099     intptr_t alloc_size = fixed_length + Length(); | 
|  12756     char* chars = thread->zone()->Alloc<char>(alloc_size); |  12100     char* chars = thread->zone()->Alloc<char>(alloc_size); | 
|  12757     intptr_t index = OS::SNPrint(chars, alloc_size, FORMAT, PcOffset()); |  12101     intptr_t index = OS::SNPrint(chars, alloc_size, FORMAT, PcOffset()); | 
|  12758     for (intptr_t i = 0; i < Length(); i++) { |  12102     for (intptr_t i = 0; i < Length(); i++) { | 
|  12759       chars[index++] = IsObject(i) ? '1' : '0'; |  12103       chars[index++] = IsObject(i) ? '1' : '0'; | 
|  12760     } |  12104     } | 
|  12761     chars[index] = '\0'; |  12105     chars[index] = '\0'; | 
|  12762     return chars; |  12106     return chars; | 
|  12763   } |  12107   } | 
|  12764 #undef FORMAT |  12108 #undef FORMAT | 
|  12765 } |  12109 } | 
|  12766  |  12110  | 
|  12767  |  | 
|  12768 RawString* LocalVarDescriptors::GetName(intptr_t var_index) const { |  12111 RawString* LocalVarDescriptors::GetName(intptr_t var_index) const { | 
|  12769   ASSERT(var_index < Length()); |  12112   ASSERT(var_index < Length()); | 
|  12770   ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString()); |  12113   ASSERT(Object::Handle(*raw()->nameAddrAt(var_index)).IsString()); | 
|  12771   return *raw()->nameAddrAt(var_index); |  12114   return *raw()->nameAddrAt(var_index); | 
|  12772 } |  12115 } | 
|  12773  |  12116  | 
|  12774  |  | 
|  12775 void LocalVarDescriptors::SetVar(intptr_t var_index, |  12117 void LocalVarDescriptors::SetVar(intptr_t var_index, | 
|  12776                                  const String& name, |  12118                                  const String& name, | 
|  12777                                  RawLocalVarDescriptors::VarInfo* info) const { |  12119                                  RawLocalVarDescriptors::VarInfo* info) const { | 
|  12778   ASSERT(var_index < Length()); |  12120   ASSERT(var_index < Length()); | 
|  12779   ASSERT(!name.IsNull()); |  12121   ASSERT(!name.IsNull()); | 
|  12780   StorePointer(raw()->nameAddrAt(var_index), name.raw()); |  12122   StorePointer(raw()->nameAddrAt(var_index), name.raw()); | 
|  12781   raw()->data()[var_index] = *info; |  12123   raw()->data()[var_index] = *info; | 
|  12782 } |  12124 } | 
|  12783  |  12125  | 
|  12784  |  | 
|  12785 void LocalVarDescriptors::GetInfo(intptr_t var_index, |  12126 void LocalVarDescriptors::GetInfo(intptr_t var_index, | 
|  12786                                   RawLocalVarDescriptors::VarInfo* info) const { |  12127                                   RawLocalVarDescriptors::VarInfo* info) const { | 
|  12787   ASSERT(var_index < Length()); |  12128   ASSERT(var_index < Length()); | 
|  12788   *info = raw()->data()[var_index]; |  12129   *info = raw()->data()[var_index]; | 
|  12789 } |  12130 } | 
|  12790  |  12131  | 
|  12791  |  | 
|  12792 static int PrintVarInfo(char* buffer, |  12132 static int PrintVarInfo(char* buffer, | 
|  12793                         int len, |  12133                         int len, | 
|  12794                         intptr_t i, |  12134                         intptr_t i, | 
|  12795                         const String& var_name, |  12135                         const String& var_name, | 
|  12796                         const RawLocalVarDescriptors::VarInfo& info) { |  12136                         const RawLocalVarDescriptors::VarInfo& info) { | 
|  12797   const RawLocalVarDescriptors::VarInfoKind kind = info.kind(); |  12137   const RawLocalVarDescriptors::VarInfoKind kind = info.kind(); | 
|  12798   const int32_t index = info.index(); |  12138   const int32_t index = info.index(); | 
|  12799   if (kind == RawLocalVarDescriptors::kContextLevel) { |  12139   if (kind == RawLocalVarDescriptors::kContextLevel) { | 
|  12800     return OS::SNPrint(buffer, len, |  12140     return OS::SNPrint(buffer, len, | 
|  12801                        "%2" Pd |  12141                        "%2" Pd | 
|  12802                        " %-13s level=%-3d" |  12142                        " %-13s level=%-3d" | 
|  12803                        " begin=%-3d end=%d\n", |  12143                        " begin=%-3d end=%d\n", | 
|  12804                        i, LocalVarDescriptors::KindToCString(kind), index, |  12144                        i, LocalVarDescriptors::KindToCString(kind), index, | 
|  12805                        static_cast<int>(info.begin_pos.value()), |  12145                        static_cast<int>(info.begin_pos.value()), | 
|  12806                        static_cast<int>(info.end_pos.value())); |  12146                        static_cast<int>(info.end_pos.value())); | 
|  12807   } else if (kind == RawLocalVarDescriptors::kContextVar) { |  12147   } else if (kind == RawLocalVarDescriptors::kContextVar) { | 
|  12808     return OS::SNPrint( |  12148     return OS::SNPrint( | 
|  12809         buffer, len, "%2" Pd |  12149         buffer, len, | 
|  12810                      " %-13s level=%-3d index=%-3d" |  12150         "%2" Pd | 
|  12811                      " begin=%-3d end=%-3d name=%s\n", |  12151         " %-13s level=%-3d index=%-3d" | 
 |  12152         " begin=%-3d end=%-3d name=%s\n", | 
|  12812         i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, |  12153         i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, | 
|  12813         static_cast<int>(info.begin_pos.Pos()), |  12154         static_cast<int>(info.begin_pos.Pos()), | 
|  12814         static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); |  12155         static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); | 
|  12815   } else { |  12156   } else { | 
|  12816     return OS::SNPrint( |  12157     return OS::SNPrint( | 
|  12817         buffer, len, "%2" Pd |  12158         buffer, len, | 
|  12818                      " %-13s scope=%-3d index=%-3d" |  12159         "%2" Pd | 
|  12819                      " begin=%-3d end=%-3d name=%s\n", |  12160         " %-13s scope=%-3d index=%-3d" | 
 |  12161         " begin=%-3d end=%-3d name=%s\n", | 
|  12820         i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, |  12162         i, LocalVarDescriptors::KindToCString(kind), info.scope_id, index, | 
|  12821         static_cast<int>(info.begin_pos.Pos()), |  12163         static_cast<int>(info.begin_pos.Pos()), | 
|  12822         static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); |  12164         static_cast<int>(info.end_pos.Pos()), var_name.ToCString()); | 
|  12823   } |  12165   } | 
|  12824 } |  12166 } | 
|  12825  |  12167  | 
|  12826  |  | 
|  12827 const char* LocalVarDescriptors::ToCString() const { |  12168 const char* LocalVarDescriptors::ToCString() const { | 
|  12828   if (IsNull()) { |  12169   if (IsNull()) { | 
|  12829     return "LocalVarDescriptors: null"; |  12170     return "LocalVarDescriptors: null"; | 
|  12830   } |  12171   } | 
|  12831   if (Length() == 0) { |  12172   if (Length() == 0) { | 
|  12832     return "empty LocalVarDescriptors"; |  12173     return "empty LocalVarDescriptors"; | 
|  12833   } |  12174   } | 
|  12834   intptr_t len = 1;  // Trailing '\0'. |  12175   intptr_t len = 1;  // Trailing '\0'. | 
|  12835   String& var_name = String::Handle(); |  12176   String& var_name = String::Handle(); | 
|  12836   for (intptr_t i = 0; i < Length(); i++) { |  12177   for (intptr_t i = 0; i < Length(); i++) { | 
|  12837     RawLocalVarDescriptors::VarInfo info; |  12178     RawLocalVarDescriptors::VarInfo info; | 
|  12838     var_name = GetName(i); |  12179     var_name = GetName(i); | 
|  12839     GetInfo(i, &info); |  12180     GetInfo(i, &info); | 
|  12840     len += PrintVarInfo(NULL, 0, i, var_name, info); |  12181     len += PrintVarInfo(NULL, 0, i, var_name, info); | 
|  12841   } |  12182   } | 
|  12842   char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); |  12183   char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1); | 
|  12843   buffer[0] = '\0'; |  12184   buffer[0] = '\0'; | 
|  12844   intptr_t num_chars = 0; |  12185   intptr_t num_chars = 0; | 
|  12845   for (intptr_t i = 0; i < Length(); i++) { |  12186   for (intptr_t i = 0; i < Length(); i++) { | 
|  12846     RawLocalVarDescriptors::VarInfo info; |  12187     RawLocalVarDescriptors::VarInfo info; | 
|  12847     var_name = GetName(i); |  12188     var_name = GetName(i); | 
|  12848     GetInfo(i, &info); |  12189     GetInfo(i, &info); | 
|  12849     num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i, |  12190     num_chars += PrintVarInfo((buffer + num_chars), (len - num_chars), i, | 
|  12850                               var_name, info); |  12191                               var_name, info); | 
|  12851   } |  12192   } | 
|  12852   return buffer; |  12193   return buffer; | 
|  12853 } |  12194 } | 
|  12854  |  12195  | 
|  12855  |  | 
|  12856 const char* LocalVarDescriptors::KindToCString( |  12196 const char* LocalVarDescriptors::KindToCString( | 
|  12857     RawLocalVarDescriptors::VarInfoKind kind) { |  12197     RawLocalVarDescriptors::VarInfoKind kind) { | 
|  12858   switch (kind) { |  12198   switch (kind) { | 
|  12859     case RawLocalVarDescriptors::kStackVar: |  12199     case RawLocalVarDescriptors::kStackVar: | 
|  12860       return "StackVar"; |  12200       return "StackVar"; | 
|  12861     case RawLocalVarDescriptors::kContextVar: |  12201     case RawLocalVarDescriptors::kContextVar: | 
|  12862       return "ContextVar"; |  12202       return "ContextVar"; | 
|  12863     case RawLocalVarDescriptors::kContextLevel: |  12203     case RawLocalVarDescriptors::kContextLevel: | 
|  12864       return "ContextLevel"; |  12204       return "ContextLevel"; | 
|  12865     case RawLocalVarDescriptors::kSavedCurrentContext: |  12205     case RawLocalVarDescriptors::kSavedCurrentContext: | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  12886         Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld); |  12226         Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld); | 
|  12887     INC_STAT(Thread::Current(), total_code_size, size); |  12227     INC_STAT(Thread::Current(), total_code_size, size); | 
|  12888     INC_STAT(Thread::Current(), vardesc_size, size); |  12228     INC_STAT(Thread::Current(), vardesc_size, size); | 
|  12889     NoSafepointScope no_safepoint; |  12229     NoSafepointScope no_safepoint; | 
|  12890     result ^= raw; |  12230     result ^= raw; | 
|  12891     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); |  12231     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables); | 
|  12892   } |  12232   } | 
|  12893   return result.raw(); |  12233   return result.raw(); | 
|  12894 } |  12234 } | 
|  12895  |  12235  | 
|  12896  |  | 
|  12897 intptr_t LocalVarDescriptors::Length() const { |  12236 intptr_t LocalVarDescriptors::Length() const { | 
|  12898   return raw_ptr()->num_entries_; |  12237   return raw_ptr()->num_entries_; | 
|  12899 } |  12238 } | 
|  12900  |  12239  | 
|  12901  |  | 
|  12902 intptr_t ExceptionHandlers::num_entries() const { |  12240 intptr_t ExceptionHandlers::num_entries() const { | 
|  12903   return raw_ptr()->num_entries_; |  12241   return raw_ptr()->num_entries_; | 
|  12904 } |  12242 } | 
|  12905  |  12243  | 
|  12906  |  | 
|  12907 void ExceptionHandlers::SetHandlerInfo(intptr_t try_index, |  12244 void ExceptionHandlers::SetHandlerInfo(intptr_t try_index, | 
|  12908                                        intptr_t outer_try_index, |  12245                                        intptr_t outer_try_index, | 
|  12909                                        uword handler_pc_offset, |  12246                                        uword handler_pc_offset, | 
|  12910                                        bool needs_stacktrace, |  12247                                        bool needs_stacktrace, | 
|  12911                                        bool has_catch_all, |  12248                                        bool has_catch_all, | 
|  12912                                        TokenPosition token_pos, |  12249                                        TokenPosition token_pos, | 
|  12913                                        bool is_generated) const { |  12250                                        bool is_generated) const { | 
|  12914   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12251   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12915   NoSafepointScope no_safepoint; |  12252   NoSafepointScope no_safepoint; | 
|  12916   ExceptionHandlerInfo* info = |  12253   ExceptionHandlerInfo* info = | 
|  12917       UnsafeMutableNonPointer(&raw_ptr()->data()[try_index]); |  12254       UnsafeMutableNonPointer(&raw_ptr()->data()[try_index]); | 
|  12918   info->outer_try_index = outer_try_index; |  12255   info->outer_try_index = outer_try_index; | 
|  12919   // Some C compilers warn about the comparison always being true when using <= |  12256   // Some C compilers warn about the comparison always being true when using <= | 
|  12920   // due to limited range of data type. |  12257   // due to limited range of data type. | 
|  12921   ASSERT((handler_pc_offset == static_cast<uword>(kMaxUint32)) || |  12258   ASSERT((handler_pc_offset == static_cast<uword>(kMaxUint32)) || | 
|  12922          (handler_pc_offset < static_cast<uword>(kMaxUint32))); |  12259          (handler_pc_offset < static_cast<uword>(kMaxUint32))); | 
|  12923   info->handler_pc_offset = handler_pc_offset; |  12260   info->handler_pc_offset = handler_pc_offset; | 
|  12924   info->needs_stacktrace = needs_stacktrace; |  12261   info->needs_stacktrace = needs_stacktrace; | 
|  12925   info->has_catch_all = has_catch_all; |  12262   info->has_catch_all = has_catch_all; | 
|  12926   info->is_generated = is_generated; |  12263   info->is_generated = is_generated; | 
|  12927 } |  12264 } | 
|  12928  |  12265  | 
|  12929 void ExceptionHandlers::GetHandlerInfo(intptr_t try_index, |  12266 void ExceptionHandlers::GetHandlerInfo(intptr_t try_index, | 
|  12930                                        ExceptionHandlerInfo* info) const { |  12267                                        ExceptionHandlerInfo* info) const { | 
|  12931   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12268   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12932   ASSERT(info != NULL); |  12269   ASSERT(info != NULL); | 
|  12933   *info = raw_ptr()->data()[try_index]; |  12270   *info = raw_ptr()->data()[try_index]; | 
|  12934 } |  12271 } | 
|  12935  |  12272  | 
|  12936  |  | 
|  12937 uword ExceptionHandlers::HandlerPCOffset(intptr_t try_index) const { |  12273 uword ExceptionHandlers::HandlerPCOffset(intptr_t try_index) const { | 
|  12938   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12274   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12939   return raw_ptr()->data()[try_index].handler_pc_offset; |  12275   return raw_ptr()->data()[try_index].handler_pc_offset; | 
|  12940 } |  12276 } | 
|  12941  |  12277  | 
|  12942  |  | 
|  12943 intptr_t ExceptionHandlers::OuterTryIndex(intptr_t try_index) const { |  12278 intptr_t ExceptionHandlers::OuterTryIndex(intptr_t try_index) const { | 
|  12944   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12279   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12945   return raw_ptr()->data()[try_index].outer_try_index; |  12280   return raw_ptr()->data()[try_index].outer_try_index; | 
|  12946 } |  12281 } | 
|  12947  |  12282  | 
|  12948  |  | 
|  12949 bool ExceptionHandlers::NeedsStackTrace(intptr_t try_index) const { |  12283 bool ExceptionHandlers::NeedsStackTrace(intptr_t try_index) const { | 
|  12950   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12284   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12951   return raw_ptr()->data()[try_index].needs_stacktrace; |  12285   return raw_ptr()->data()[try_index].needs_stacktrace; | 
|  12952 } |  12286 } | 
|  12953  |  12287  | 
|  12954  |  | 
|  12955 bool ExceptionHandlers::IsGenerated(intptr_t try_index) const { |  12288 bool ExceptionHandlers::IsGenerated(intptr_t try_index) const { | 
|  12956   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12289   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12957   return raw_ptr()->data()[try_index].is_generated; |  12290   return raw_ptr()->data()[try_index].is_generated; | 
|  12958 } |  12291 } | 
|  12959  |  12292  | 
|  12960  |  | 
|  12961 bool ExceptionHandlers::HasCatchAll(intptr_t try_index) const { |  12293 bool ExceptionHandlers::HasCatchAll(intptr_t try_index) const { | 
|  12962   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12294   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12963   return raw_ptr()->data()[try_index].has_catch_all; |  12295   return raw_ptr()->data()[try_index].has_catch_all; | 
|  12964 } |  12296 } | 
|  12965  |  12297  | 
|  12966  |  | 
|  12967 void ExceptionHandlers::SetHandledTypes(intptr_t try_index, |  12298 void ExceptionHandlers::SetHandledTypes(intptr_t try_index, | 
|  12968                                         const Array& handled_types) const { |  12299                                         const Array& handled_types) const { | 
|  12969   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12300   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12970   ASSERT(!handled_types.IsNull()); |  12301   ASSERT(!handled_types.IsNull()); | 
|  12971   const Array& handled_types_data = |  12302   const Array& handled_types_data = | 
|  12972       Array::Handle(raw_ptr()->handled_types_data_); |  12303       Array::Handle(raw_ptr()->handled_types_data_); | 
|  12973   handled_types_data.SetAt(try_index, handled_types); |  12304   handled_types_data.SetAt(try_index, handled_types); | 
|  12974 } |  12305 } | 
|  12975  |  12306  | 
|  12976  |  | 
|  12977 RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const { |  12307 RawArray* ExceptionHandlers::GetHandledTypes(intptr_t try_index) const { | 
|  12978   ASSERT((try_index >= 0) && (try_index < num_entries())); |  12308   ASSERT((try_index >= 0) && (try_index < num_entries())); | 
|  12979   Array& array = Array::Handle(raw_ptr()->handled_types_data_); |  12309   Array& array = Array::Handle(raw_ptr()->handled_types_data_); | 
|  12980   array ^= array.At(try_index); |  12310   array ^= array.At(try_index); | 
|  12981   return array.raw(); |  12311   return array.raw(); | 
|  12982 } |  12312 } | 
|  12983  |  12313  | 
|  12984  |  | 
|  12985 void ExceptionHandlers::set_handled_types_data(const Array& value) const { |  12314 void ExceptionHandlers::set_handled_types_data(const Array& value) const { | 
|  12986   StorePointer(&raw_ptr()->handled_types_data_, value.raw()); |  12315   StorePointer(&raw_ptr()->handled_types_data_, value.raw()); | 
|  12987 } |  12316 } | 
|  12988  |  12317  | 
|  12989  |  | 
|  12990 RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) { |  12318 RawExceptionHandlers* ExceptionHandlers::New(intptr_t num_handlers) { | 
|  12991   ASSERT(Object::exception_handlers_class() != Class::null()); |  12319   ASSERT(Object::exception_handlers_class() != Class::null()); | 
|  12992   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { |  12320   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { | 
|  12993     FATAL1( |  12321     FATAL1( | 
|  12994         "Fatal error in ExceptionHandlers::New(): " |  12322         "Fatal error in ExceptionHandlers::New(): " | 
|  12995         "invalid num_handlers %" Pd "\n", |  12323         "invalid num_handlers %" Pd "\n", | 
|  12996         num_handlers); |  12324         num_handlers); | 
|  12997   } |  12325   } | 
|  12998   ExceptionHandlers& result = ExceptionHandlers::Handle(); |  12326   ExceptionHandlers& result = ExceptionHandlers::Handle(); | 
|  12999   { |  12327   { | 
|  13000     uword size = ExceptionHandlers::InstanceSize(num_handlers); |  12328     uword size = ExceptionHandlers::InstanceSize(num_handlers); | 
|  13001     RawObject* raw = |  12329     RawObject* raw = | 
|  13002         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); |  12330         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); | 
|  13003     NoSafepointScope no_safepoint; |  12331     NoSafepointScope no_safepoint; | 
|  13004     result ^= raw; |  12332     result ^= raw; | 
|  13005     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); |  12333     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); | 
|  13006   } |  12334   } | 
|  13007   const Array& handled_types_data = |  12335   const Array& handled_types_data = | 
|  13008       (num_handlers == 0) ? Object::empty_array() |  12336       (num_handlers == 0) ? Object::empty_array() | 
|  13009                           : Array::Handle(Array::New(num_handlers, Heap::kOld)); |  12337                           : Array::Handle(Array::New(num_handlers, Heap::kOld)); | 
|  13010   result.set_handled_types_data(handled_types_data); |  12338   result.set_handled_types_data(handled_types_data); | 
|  13011   return result.raw(); |  12339   return result.raw(); | 
|  13012 } |  12340 } | 
|  13013  |  12341  | 
|  13014  |  | 
|  13015 RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) { |  12342 RawExceptionHandlers* ExceptionHandlers::New(const Array& handled_types_data) { | 
|  13016   ASSERT(Object::exception_handlers_class() != Class::null()); |  12343   ASSERT(Object::exception_handlers_class() != Class::null()); | 
|  13017   const intptr_t num_handlers = handled_types_data.Length(); |  12344   const intptr_t num_handlers = handled_types_data.Length(); | 
|  13018   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { |  12345   if ((num_handlers < 0) || (num_handlers >= kMaxHandlers)) { | 
|  13019     FATAL1( |  12346     FATAL1( | 
|  13020         "Fatal error in ExceptionHandlers::New(): " |  12347         "Fatal error in ExceptionHandlers::New(): " | 
|  13021         "invalid num_handlers %" Pd "\n", |  12348         "invalid num_handlers %" Pd "\n", | 
|  13022         num_handlers); |  12349         num_handlers); | 
|  13023   } |  12350   } | 
|  13024   ExceptionHandlers& result = ExceptionHandlers::Handle(); |  12351   ExceptionHandlers& result = ExceptionHandlers::Handle(); | 
|  13025   { |  12352   { | 
|  13026     uword size = ExceptionHandlers::InstanceSize(num_handlers); |  12353     uword size = ExceptionHandlers::InstanceSize(num_handlers); | 
|  13027     RawObject* raw = |  12354     RawObject* raw = | 
|  13028         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); |  12355         Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld); | 
|  13029     NoSafepointScope no_safepoint; |  12356     NoSafepointScope no_safepoint; | 
|  13030     result ^= raw; |  12357     result ^= raw; | 
|  13031     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); |  12358     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers); | 
|  13032   } |  12359   } | 
|  13033   result.set_handled_types_data(handled_types_data); |  12360   result.set_handled_types_data(handled_types_data); | 
|  13034   return result.raw(); |  12361   return result.raw(); | 
|  13035 } |  12362 } | 
|  13036  |  12363  | 
|  13037  |  | 
|  13038 const char* ExceptionHandlers::ToCString() const { |  12364 const char* ExceptionHandlers::ToCString() const { | 
|  13039 #define FORMAT1 "%" Pd " => %#x  (%" Pd " types) (outer %d) %s\n" |  12365 #define FORMAT1 "%" Pd " => %#x  (%" Pd " types) (outer %d) %s\n" | 
|  13040 #define FORMAT2 "  %d. %s\n" |  12366 #define FORMAT2 "  %d. %s\n" | 
|  13041   if (num_entries() == 0) { |  12367   if (num_entries() == 0) { | 
|  13042     return "empty ExceptionHandlers\n"; |  12368     return "empty ExceptionHandlers\n"; | 
|  13043   } |  12369   } | 
|  13044   Array& handled_types = Array::Handle(); |  12370   Array& handled_types = Array::Handle(); | 
|  13045   Type& type = Type::Handle(); |  12371   Type& type = Type::Handle(); | 
|  13046   ExceptionHandlerInfo info; |  12372   ExceptionHandlerInfo info; | 
|  13047   // First compute the buffer size required. |  12373   // First compute the buffer size required. | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|  13077       type ^= handled_types.At(k); |  12403       type ^= handled_types.At(k); | 
|  13078       num_chars += OS::SNPrint((buffer + num_chars), (len - num_chars), FORMAT2, |  12404       num_chars += OS::SNPrint((buffer + num_chars), (len - num_chars), FORMAT2, | 
|  13079                                k, type.ToCString()); |  12405                                k, type.ToCString()); | 
|  13080     } |  12406     } | 
|  13081   } |  12407   } | 
|  13082   return buffer; |  12408   return buffer; | 
|  13083 #undef FORMAT1 |  12409 #undef FORMAT1 | 
|  13084 #undef FORMAT2 |  12410 #undef FORMAT2 | 
|  13085 } |  12411 } | 
|  13086  |  12412  | 
|  13087  |  | 
|  13088 void SingleTargetCache::set_target(const Code& value) const { |  12413 void SingleTargetCache::set_target(const Code& value) const { | 
|  13089   StorePointer(&raw_ptr()->target_, value.raw()); |  12414   StorePointer(&raw_ptr()->target_, value.raw()); | 
|  13090 } |  12415 } | 
|  13091  |  12416  | 
|  13092  |  | 
|  13093 const char* SingleTargetCache::ToCString() const { |  12417 const char* SingleTargetCache::ToCString() const { | 
|  13094   return "SingleTargetCache"; |  12418   return "SingleTargetCache"; | 
|  13095 } |  12419 } | 
|  13096  |  12420  | 
|  13097  |  | 
|  13098 RawSingleTargetCache* SingleTargetCache::New() { |  12421 RawSingleTargetCache* SingleTargetCache::New() { | 
|  13099   SingleTargetCache& result = SingleTargetCache::Handle(); |  12422   SingleTargetCache& result = SingleTargetCache::Handle(); | 
|  13100   { |  12423   { | 
|  13101     // IC data objects are long living objects, allocate them in old generation. |  12424     // IC data objects are long living objects, allocate them in old generation. | 
|  13102     RawObject* raw = |  12425     RawObject* raw = | 
|  13103         Object::Allocate(SingleTargetCache::kClassId, |  12426         Object::Allocate(SingleTargetCache::kClassId, | 
|  13104                          SingleTargetCache::InstanceSize(), Heap::kOld); |  12427                          SingleTargetCache::InstanceSize(), Heap::kOld); | 
|  13105     NoSafepointScope no_safepoint; |  12428     NoSafepointScope no_safepoint; | 
|  13106     result ^= raw; |  12429     result ^= raw; | 
|  13107   } |  12430   } | 
|  13108   result.set_target(Code::Handle()); |  12431   result.set_target(Code::Handle()); | 
|  13109   result.set_entry_point(0); |  12432   result.set_entry_point(0); | 
|  13110   result.set_lower_limit(kIllegalCid); |  12433   result.set_lower_limit(kIllegalCid); | 
|  13111   result.set_upper_limit(kIllegalCid); |  12434   result.set_upper_limit(kIllegalCid); | 
|  13112   return result.raw(); |  12435   return result.raw(); | 
|  13113 } |  12436 } | 
|  13114  |  12437  | 
|  13115  |  | 
|  13116 void UnlinkedCall::set_target_name(const String& value) const { |  12438 void UnlinkedCall::set_target_name(const String& value) const { | 
|  13117   StorePointer(&raw_ptr()->target_name_, value.raw()); |  12439   StorePointer(&raw_ptr()->target_name_, value.raw()); | 
|  13118 } |  12440 } | 
|  13119  |  12441  | 
|  13120  |  | 
|  13121 void UnlinkedCall::set_args_descriptor(const Array& value) const { |  12442 void UnlinkedCall::set_args_descriptor(const Array& value) const { | 
|  13122   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |  12443   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 
|  13123 } |  12444 } | 
|  13124  |  12445  | 
|  13125  |  | 
|  13126 const char* UnlinkedCall::ToCString() const { |  12446 const char* UnlinkedCall::ToCString() const { | 
|  13127   return "UnlinkedCall"; |  12447   return "UnlinkedCall"; | 
|  13128 } |  12448 } | 
|  13129  |  12449  | 
|  13130  |  | 
|  13131 RawUnlinkedCall* UnlinkedCall::New() { |  12450 RawUnlinkedCall* UnlinkedCall::New() { | 
|  13132   RawObject* raw = Object::Allocate(UnlinkedCall::kClassId, |  12451   RawObject* raw = Object::Allocate(UnlinkedCall::kClassId, | 
|  13133                                     UnlinkedCall::InstanceSize(), Heap::kOld); |  12452                                     UnlinkedCall::InstanceSize(), Heap::kOld); | 
|  13134   return reinterpret_cast<RawUnlinkedCall*>(raw); |  12453   return reinterpret_cast<RawUnlinkedCall*>(raw); | 
|  13135 } |  12454 } | 
|  13136  |  12455  | 
|  13137  |  | 
|  13138 void ICData::ResetSwitchable(Zone* zone) const { |  12456 void ICData::ResetSwitchable(Zone* zone) const { | 
|  13139   ASSERT(NumArgsTested() == 1); |  12457   ASSERT(NumArgsTested() == 1); | 
|  13140   set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1))); |  12458   set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1))); | 
|  13141 } |  12459 } | 
|  13142  |  12460  | 
|  13143  |  | 
|  13144 const char* ICData::ToCString() const { |  12461 const char* ICData::ToCString() const { | 
|  13145   const String& name = String::Handle(target_name()); |  12462   const String& name = String::Handle(target_name()); | 
|  13146   const intptr_t num_args = NumArgsTested(); |  12463   const intptr_t num_args = NumArgsTested(); | 
|  13147   const intptr_t num_checks = NumberOfChecks(); |  12464   const intptr_t num_checks = NumberOfChecks(); | 
|  13148   const intptr_t type_args_len = TypeArgsLen(); |  12465   const intptr_t type_args_len = TypeArgsLen(); | 
|  13149   return OS::SCreate(Thread::Current()->zone(), |  12466   return OS::SCreate(Thread::Current()->zone(), | 
|  13150                      "ICData target:'%s' num-args: %" Pd " num-checks: %" Pd |  12467                      "ICData target:'%s' num-args: %" Pd " num-checks: %" Pd | 
|  13151                      " type-args-len: %" Pd "", |  12468                      " type-args-len: %" Pd "", | 
|  13152                      name.ToCString(), num_args, num_checks, type_args_len); |  12469                      name.ToCString(), num_args, num_checks, type_args_len); | 
|  13153 } |  12470 } | 
|  13154  |  12471  | 
|  13155  |  | 
|  13156 RawFunction* ICData::Owner() const { |  12472 RawFunction* ICData::Owner() const { | 
|  13157   Object& obj = Object::Handle(raw_ptr()->owner_); |  12473   Object& obj = Object::Handle(raw_ptr()->owner_); | 
|  13158   if (obj.IsNull()) { |  12474   if (obj.IsNull()) { | 
|  13159     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |  12475     ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|  13160     return Function::null(); |  12476     return Function::null(); | 
|  13161   } else if (obj.IsFunction()) { |  12477   } else if (obj.IsFunction()) { | 
|  13162     return Function::Cast(obj).raw(); |  12478     return Function::Cast(obj).raw(); | 
|  13163   } else { |  12479   } else { | 
|  13164     ICData& original = ICData::Handle(); |  12480     ICData& original = ICData::Handle(); | 
|  13165     original ^= obj.raw(); |  12481     original ^= obj.raw(); | 
|  13166     return original.Owner(); |  12482     return original.Owner(); | 
|  13167   } |  12483   } | 
|  13168 } |  12484 } | 
|  13169  |  12485  | 
|  13170  |  | 
|  13171 RawICData* ICData::Original() const { |  12486 RawICData* ICData::Original() const { | 
|  13172   if (IsNull()) { |  12487   if (IsNull()) { | 
|  13173     return ICData::null(); |  12488     return ICData::null(); | 
|  13174   } |  12489   } | 
|  13175   Object& obj = Object::Handle(raw_ptr()->owner_); |  12490   Object& obj = Object::Handle(raw_ptr()->owner_); | 
|  13176   if (obj.IsFunction()) { |  12491   if (obj.IsFunction()) { | 
|  13177     return this->raw(); |  12492     return this->raw(); | 
|  13178   } else { |  12493   } else { | 
|  13179     return ICData::RawCast(obj.raw()); |  12494     return ICData::RawCast(obj.raw()); | 
|  13180   } |  12495   } | 
|  13181 } |  12496 } | 
|  13182  |  12497  | 
|  13183  |  | 
|  13184 void ICData::SetOriginal(const ICData& value) const { |  12498 void ICData::SetOriginal(const ICData& value) const { | 
|  13185   ASSERT(value.IsOriginal()); |  12499   ASSERT(value.IsOriginal()); | 
|  13186   ASSERT(!value.IsNull()); |  12500   ASSERT(!value.IsNull()); | 
|  13187   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |  12501   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 
|  13188 } |  12502 } | 
|  13189  |  12503  | 
|  13190  |  | 
|  13191 void ICData::set_owner(const Function& value) const { |  12504 void ICData::set_owner(const Function& value) const { | 
|  13192   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); |  12505   StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(value.raw())); | 
|  13193 } |  12506 } | 
|  13194  |  12507  | 
|  13195  |  | 
|  13196 void ICData::set_target_name(const String& value) const { |  12508 void ICData::set_target_name(const String& value) const { | 
|  13197   ASSERT(!value.IsNull()); |  12509   ASSERT(!value.IsNull()); | 
|  13198   StorePointer(&raw_ptr()->target_name_, value.raw()); |  12510   StorePointer(&raw_ptr()->target_name_, value.raw()); | 
|  13199 } |  12511 } | 
|  13200  |  12512  | 
|  13201  |  | 
|  13202 void ICData::set_arguments_descriptor(const Array& value) const { |  12513 void ICData::set_arguments_descriptor(const Array& value) const { | 
|  13203   ASSERT(!value.IsNull()); |  12514   ASSERT(!value.IsNull()); | 
|  13204   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |  12515   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 
|  13205 } |  12516 } | 
|  13206  |  12517  | 
|  13207  |  | 
|  13208 void ICData::set_deopt_id(intptr_t value) const { |  12518 void ICData::set_deopt_id(intptr_t value) const { | 
|  13209 #if defined(DART_PRECOMPILED_RUNTIME) |  12519 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  13210   UNREACHABLE(); |  12520   UNREACHABLE(); | 
|  13211 #else |  12521 #else | 
|  13212   ASSERT(value <= kMaxInt32); |  12522   ASSERT(value <= kMaxInt32); | 
|  13213   StoreNonPointer(&raw_ptr()->deopt_id_, value); |  12523   StoreNonPointer(&raw_ptr()->deopt_id_, value); | 
|  13214 #endif |  12524 #endif | 
|  13215 } |  12525 } | 
|  13216  |  12526  | 
|  13217  |  | 
|  13218 void ICData::set_ic_data_array(const Array& value) const { |  12527 void ICData::set_ic_data_array(const Array& value) const { | 
|  13219   ASSERT(!value.IsNull()); |  12528   ASSERT(!value.IsNull()); | 
|  13220   StorePointer(&raw_ptr()->ic_data_, value.raw()); |  12529   StorePointer(&raw_ptr()->ic_data_, value.raw()); | 
|  13221 } |  12530 } | 
|  13222  |  12531  | 
|  13223  |  | 
|  13224 #if defined(TAG_IC_DATA) |  12532 #if defined(TAG_IC_DATA) | 
|  13225 void ICData::set_tag(intptr_t value) const { |  12533 void ICData::set_tag(intptr_t value) const { | 
|  13226   StoreNonPointer(&raw_ptr()->tag_, value); |  12534   StoreNonPointer(&raw_ptr()->tag_, value); | 
|  13227 } |  12535 } | 
|  13228 #endif |  12536 #endif | 
|  13229  |  12537  | 
|  13230 intptr_t ICData::NumArgsTested() const { |  12538 intptr_t ICData::NumArgsTested() const { | 
|  13231   return NumArgsTestedBits::decode(raw_ptr()->state_bits_); |  12539   return NumArgsTestedBits::decode(raw_ptr()->state_bits_); | 
|  13232 } |  12540 } | 
|  13233  |  12541  | 
|  13234  |  | 
|  13235 intptr_t ICData::TypeArgsLen() const { |  12542 intptr_t ICData::TypeArgsLen() const { | 
|  13236   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor())); |  12543   ArgumentsDescriptor args_desc(Array::Handle(arguments_descriptor())); | 
|  13237   return args_desc.TypeArgsLen(); |  12544   return args_desc.TypeArgsLen(); | 
|  13238 } |  12545 } | 
|  13239  |  12546  | 
|  13240  |  | 
|  13241 void ICData::SetNumArgsTested(intptr_t value) const { |  12547 void ICData::SetNumArgsTested(intptr_t value) const { | 
|  13242   ASSERT(Utils::IsUint(2, value)); |  12548   ASSERT(Utils::IsUint(2, value)); | 
|  13243   StoreNonPointer(&raw_ptr()->state_bits_, |  12549   StoreNonPointer(&raw_ptr()->state_bits_, | 
|  13244                   NumArgsTestedBits::update(value, raw_ptr()->state_bits_)); |  12550                   NumArgsTestedBits::update(value, raw_ptr()->state_bits_)); | 
|  13245 } |  12551 } | 
|  13246  |  12552  | 
|  13247  |  | 
|  13248 uint32_t ICData::DeoptReasons() const { |  12553 uint32_t ICData::DeoptReasons() const { | 
|  13249   return DeoptReasonBits::decode(raw_ptr()->state_bits_); |  12554   return DeoptReasonBits::decode(raw_ptr()->state_bits_); | 
|  13250 } |  12555 } | 
|  13251  |  12556  | 
|  13252  |  | 
|  13253 void ICData::SetDeoptReasons(uint32_t reasons) const { |  12557 void ICData::SetDeoptReasons(uint32_t reasons) const { | 
|  13254   StoreNonPointer(&raw_ptr()->state_bits_, |  12558   StoreNonPointer(&raw_ptr()->state_bits_, | 
|  13255                   DeoptReasonBits::update(reasons, raw_ptr()->state_bits_)); |  12559                   DeoptReasonBits::update(reasons, raw_ptr()->state_bits_)); | 
|  13256 } |  12560 } | 
|  13257  |  12561  | 
|  13258  |  | 
|  13259 bool ICData::HasDeoptReason(DeoptReasonId reason) const { |  12562 bool ICData::HasDeoptReason(DeoptReasonId reason) const { | 
|  13260   ASSERT(reason <= kLastRecordedDeoptReason); |  12563   ASSERT(reason <= kLastRecordedDeoptReason); | 
|  13261   return (DeoptReasons() & (1 << reason)) != 0; |  12564   return (DeoptReasons() & (1 << reason)) != 0; | 
|  13262 } |  12565 } | 
|  13263  |  12566  | 
|  13264  |  | 
|  13265 void ICData::AddDeoptReason(DeoptReasonId reason) const { |  12567 void ICData::AddDeoptReason(DeoptReasonId reason) const { | 
|  13266   if (reason <= kLastRecordedDeoptReason) { |  12568   if (reason <= kLastRecordedDeoptReason) { | 
|  13267     SetDeoptReasons(DeoptReasons() | (1 << reason)); |  12569     SetDeoptReasons(DeoptReasons() | (1 << reason)); | 
|  13268   } |  12570   } | 
|  13269 } |  12571 } | 
|  13270  |  12572  | 
|  13271  |  | 
|  13272 void ICData::SetIsStaticCall(bool static_call) const { |  12573 void ICData::SetIsStaticCall(bool static_call) const { | 
|  13273   StoreNonPointer(&raw_ptr()->state_bits_, |  12574   StoreNonPointer(&raw_ptr()->state_bits_, | 
|  13274                   StaticCallBit::update(static_call, raw_ptr()->state_bits_)); |  12575                   StaticCallBit::update(static_call, raw_ptr()->state_bits_)); | 
|  13275 } |  12576 } | 
|  13276  |  12577  | 
|  13277  |  | 
|  13278 bool ICData::is_static_call() const { |  12578 bool ICData::is_static_call() const { | 
|  13279   return StaticCallBit::decode(raw_ptr()->state_bits_); |  12579   return StaticCallBit::decode(raw_ptr()->state_bits_); | 
|  13280 } |  12580 } | 
|  13281  |  12581  | 
|  13282  |  | 
|  13283 void ICData::set_state_bits(uint32_t bits) const { |  12582 void ICData::set_state_bits(uint32_t bits) const { | 
|  13284   StoreNonPointer(&raw_ptr()->state_bits_, bits); |  12583   StoreNonPointer(&raw_ptr()->state_bits_, bits); | 
|  13285 } |  12584 } | 
|  13286  |  12585  | 
|  13287  |  | 
|  13288 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { |  12586 intptr_t ICData::TestEntryLengthFor(intptr_t num_args) { | 
|  13289   return num_args + 1 /* target function*/ + 1 /* frequency */; |  12587   return num_args + 1 /* target function*/ + 1 /* frequency */; | 
|  13290 } |  12588 } | 
|  13291  |  12589  | 
|  13292  |  | 
|  13293 intptr_t ICData::TestEntryLength() const { |  12590 intptr_t ICData::TestEntryLength() const { | 
|  13294   return TestEntryLengthFor(NumArgsTested()); |  12591   return TestEntryLengthFor(NumArgsTested()); | 
|  13295 } |  12592 } | 
|  13296  |  12593  | 
|  13297  |  | 
|  13298 intptr_t ICData::Length() const { |  12594 intptr_t ICData::Length() const { | 
|  13299   return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()); |  12595   return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength()); | 
|  13300 } |  12596 } | 
|  13301  |  12597  | 
|  13302  |  | 
|  13303 intptr_t ICData::NumberOfChecks() const { |  12598 intptr_t ICData::NumberOfChecks() const { | 
|  13304   const intptr_t length = Length(); |  12599   const intptr_t length = Length(); | 
|  13305   for (intptr_t i = 0; i < length; i++) { |  12600   for (intptr_t i = 0; i < length; i++) { | 
|  13306     if (IsSentinelAt(i)) { |  12601     if (IsSentinelAt(i)) { | 
|  13307       return i; |  12602       return i; | 
|  13308     } |  12603     } | 
|  13309   } |  12604   } | 
|  13310   UNREACHABLE(); |  12605   UNREACHABLE(); | 
|  13311   return -1; |  12606   return -1; | 
|  13312 } |  12607 } | 
|  13313  |  12608  | 
|  13314  |  | 
|  13315 bool ICData::NumberOfChecksIs(intptr_t n) const { |  12609 bool ICData::NumberOfChecksIs(intptr_t n) const { | 
|  13316   const intptr_t length = Length(); |  12610   const intptr_t length = Length(); | 
|  13317   for (intptr_t i = 0; i < length; i++) { |  12611   for (intptr_t i = 0; i < length; i++) { | 
|  13318     if (i == n) { |  12612     if (i == n) { | 
|  13319       return IsSentinelAt(i); |  12613       return IsSentinelAt(i); | 
|  13320     } else { |  12614     } else { | 
|  13321       if (IsSentinelAt(i)) return false; |  12615       if (IsSentinelAt(i)) return false; | 
|  13322     } |  12616     } | 
|  13323   } |  12617   } | 
|  13324   return n == length; |  12618   return n == length; | 
|  13325 } |  12619 } | 
|  13326  |  12620  | 
|  13327  |  | 
|  13328 // Discounts any checks with usage of zero. |  12621 // Discounts any checks with usage of zero. | 
|  13329 intptr_t ICData::NumberOfUsedChecks() const { |  12622 intptr_t ICData::NumberOfUsedChecks() const { | 
|  13330   intptr_t n = NumberOfChecks(); |  12623   intptr_t n = NumberOfChecks(); | 
|  13331   if (n == 0) { |  12624   if (n == 0) { | 
|  13332     return 0; |  12625     return 0; | 
|  13333   } |  12626   } | 
|  13334   intptr_t count = 0; |  12627   intptr_t count = 0; | 
|  13335   for (intptr_t i = 0; i < n; i++) { |  12628   for (intptr_t i = 0; i < n; i++) { | 
|  13336     if (GetCountAt(i) > 0) { |  12629     if (GetCountAt(i) > 0) { | 
|  13337       count++; |  12630       count++; | 
|  13338     } |  12631     } | 
|  13339   } |  12632   } | 
|  13340   return count; |  12633   return count; | 
|  13341 } |  12634 } | 
|  13342  |  12635  | 
|  13343  |  | 
|  13344 void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) { |  12636 void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) { | 
|  13345   ASSERT(!data.IsNull()); |  12637   ASSERT(!data.IsNull()); | 
|  13346   for (intptr_t i = 1; i <= test_entry_length; i++) { |  12638   for (intptr_t i = 1; i <= test_entry_length; i++) { | 
|  13347     data.SetAt(data.Length() - i, smi_illegal_cid()); |  12639     data.SetAt(data.Length() - i, smi_illegal_cid()); | 
|  13348   } |  12640   } | 
|  13349 } |  12641 } | 
|  13350  |  12642  | 
|  13351  |  | 
|  13352 #if defined(DEBUG) |  12643 #if defined(DEBUG) | 
|  13353 // Used in asserts to verify that a check is not added twice. |  12644 // Used in asserts to verify that a check is not added twice. | 
|  13354 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { |  12645 bool ICData::HasCheck(const GrowableArray<intptr_t>& cids) const { | 
|  13355   const intptr_t len = NumberOfChecks(); |  12646   const intptr_t len = NumberOfChecks(); | 
|  13356   for (intptr_t i = 0; i < len; i++) { |  12647   for (intptr_t i = 0; i < len; i++) { | 
|  13357     GrowableArray<intptr_t> class_ids; |  12648     GrowableArray<intptr_t> class_ids; | 
|  13358     GetClassIdsAt(i, &class_ids); |  12649     GetClassIdsAt(i, &class_ids); | 
|  13359     bool matches = true; |  12650     bool matches = true; | 
|  13360     for (intptr_t k = 0; k < class_ids.length(); k++) { |  12651     for (intptr_t k = 0; k < class_ids.length(); k++) { | 
|  13361       ASSERT(class_ids[k] != kIllegalCid); |  12652       ASSERT(class_ids[k] != kIllegalCid); | 
|  13362       if (class_ids[k] != cids[k]) { |  12653       if (class_ids[k] != cids[k]) { | 
|  13363         matches = false; |  12654         matches = false; | 
|  13364         break; |  12655         break; | 
|  13365       } |  12656       } | 
|  13366     } |  12657     } | 
|  13367     if (matches) { |  12658     if (matches) { | 
|  13368       return true; |  12659       return true; | 
|  13369     } |  12660     } | 
|  13370   } |  12661   } | 
|  13371   return false; |  12662   return false; | 
|  13372 } |  12663 } | 
|  13373 #endif  // DEBUG |  12664 #endif  // DEBUG | 
|  13374  |  12665  | 
|  13375  |  | 
|  13376 void ICData::WriteSentinelAt(intptr_t index) const { |  12666 void ICData::WriteSentinelAt(intptr_t index) const { | 
|  13377   const intptr_t len = Length(); |  12667   const intptr_t len = Length(); | 
|  13378   ASSERT(index >= 0); |  12668   ASSERT(index >= 0); | 
|  13379   ASSERT(index < len); |  12669   ASSERT(index < len); | 
|  13380   Array& data = Array::Handle(ic_data()); |  12670   Array& data = Array::Handle(ic_data()); | 
|  13381   const intptr_t start = index * TestEntryLength(); |  12671   const intptr_t start = index * TestEntryLength(); | 
|  13382   const intptr_t end = start + TestEntryLength(); |  12672   const intptr_t end = start + TestEntryLength(); | 
|  13383   for (intptr_t i = start; i < end; i++) { |  12673   for (intptr_t i = start; i < end; i++) { | 
|  13384     data.SetAt(i, smi_illegal_cid()); |  12674     data.SetAt(i, smi_illegal_cid()); | 
|  13385   } |  12675   } | 
|  13386 } |  12676 } | 
|  13387  |  12677  | 
|  13388  |  | 
|  13389 void ICData::ClearCountAt(intptr_t index) const { |  12678 void ICData::ClearCountAt(intptr_t index) const { | 
|  13390   ASSERT(index >= 0); |  12679   ASSERT(index >= 0); | 
|  13391   ASSERT(index < NumberOfChecks()); |  12680   ASSERT(index < NumberOfChecks()); | 
|  13392   SetCountAt(index, 0); |  12681   SetCountAt(index, 0); | 
|  13393 } |  12682 } | 
|  13394  |  12683  | 
|  13395  |  | 
|  13396 void ICData::ClearWithSentinel() const { |  12684 void ICData::ClearWithSentinel() const { | 
|  13397   if (IsImmutable()) { |  12685   if (IsImmutable()) { | 
|  13398     return; |  12686     return; | 
|  13399   } |  12687   } | 
|  13400   // Write the sentinel value into all entries except the first one. |  12688   // Write the sentinel value into all entries except the first one. | 
|  13401   const intptr_t len = Length(); |  12689   const intptr_t len = Length(); | 
|  13402   if (len == 0) { |  12690   if (len == 0) { | 
|  13403     return; |  12691     return; | 
|  13404   } |  12692   } | 
|  13405   // The final entry is always the sentinel. |  12693   // The final entry is always the sentinel. | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  13425   GetCheckAt(0, &class_ids, &target); |  12713   GetCheckAt(0, &class_ids, &target); | 
|  13426   if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && |  12714   if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && | 
|  13427       (class_ids[1] == kSmiCid)) { |  12715       (class_ids[1] == kSmiCid)) { | 
|  13428     // The smi fast path case, preserve the initial entry but reset the count. |  12716     // The smi fast path case, preserve the initial entry but reset the count. | 
|  13429     ClearCountAt(0); |  12717     ClearCountAt(0); | 
|  13430     return; |  12718     return; | 
|  13431   } |  12719   } | 
|  13432   WriteSentinelAt(0); |  12720   WriteSentinelAt(0); | 
|  13433 } |  12721 } | 
|  13434  |  12722  | 
|  13435  |  | 
|  13436 void ICData::ClearAndSetStaticTarget(const Function& func) const { |  12723 void ICData::ClearAndSetStaticTarget(const Function& func) const { | 
|  13437   if (IsImmutable()) { |  12724   if (IsImmutable()) { | 
|  13438     return; |  12725     return; | 
|  13439   } |  12726   } | 
|  13440   const intptr_t len = Length(); |  12727   const intptr_t len = Length(); | 
|  13441   if (len == 0) { |  12728   if (len == 0) { | 
|  13442     return; |  12729     return; | 
|  13443   } |  12730   } | 
|  13444   // The final entry is always the sentinel. |  12731   // The final entry is always the sentinel. | 
|  13445   ASSERT(IsSentinelAt(len - 1)); |  12732   ASSERT(IsSentinelAt(len - 1)); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  13469     const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid)); |  12756     const Smi& object_cid = Smi::Handle(Smi::New(kObjectCid)); | 
|  13470     for (intptr_t i = 0; i < NumArgsTested(); i++) { |  12757     for (intptr_t i = 0; i < NumArgsTested(); i++) { | 
|  13471       data.SetAt(i, object_cid); |  12758       data.SetAt(i, object_cid); | 
|  13472     } |  12759     } | 
|  13473     data.SetAt(NumArgsTested(), func); |  12760     data.SetAt(NumArgsTested(), func); | 
|  13474     const Smi& value = Smi::Handle(Smi::New(0)); |  12761     const Smi& value = Smi::Handle(Smi::New(0)); | 
|  13475     data.SetAt(NumArgsTested() + 1, value); |  12762     data.SetAt(NumArgsTested() + 1, value); | 
|  13476   } |  12763   } | 
|  13477 } |  12764 } | 
|  13478  |  12765  | 
|  13479  |  | 
|  13480 // Add an initial Smi/Smi check with count 0. |  12766 // Add an initial Smi/Smi check with count 0. | 
|  13481 bool ICData::AddSmiSmiCheckForFastSmiStubs() const { |  12767 bool ICData::AddSmiSmiCheckForFastSmiStubs() const { | 
|  13482   bool is_smi_two_args_op = false; |  12768   bool is_smi_two_args_op = false; | 
|  13483  |  12769  | 
|  13484   ASSERT(NumArgsTested() == 2); |  12770   ASSERT(NumArgsTested() == 2); | 
|  13485   const String& name = String::Handle(target_name()); |  12771   const String& name = String::Handle(target_name()); | 
|  13486   const Class& smi_class = Class::Handle(Smi::Class()); |  12772   const Class& smi_class = Class::Handle(Smi::Class()); | 
|  13487   Zone* zone = Thread::Current()->zone(); |  12773   Zone* zone = Thread::Current()->zone(); | 
|  13488   const Function& smi_op_target = |  12774   const Function& smi_op_target = | 
|  13489       Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name)); |  12775       Function::Handle(Resolver::ResolveDynamicAnyArgs(zone, smi_class, name)); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  13500     Function& target = Function::Handle(); |  12786     Function& target = Function::Handle(); | 
|  13501     GetCheckAt(0, &class_ids, &target); |  12787     GetCheckAt(0, &class_ids, &target); | 
|  13502     if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && |  12788     if ((target.raw() == smi_op_target.raw()) && (class_ids[0] == kSmiCid) && | 
|  13503         (class_ids[1] == kSmiCid)) { |  12789         (class_ids[1] == kSmiCid)) { | 
|  13504       is_smi_two_args_op = true; |  12790       is_smi_two_args_op = true; | 
|  13505     } |  12791     } | 
|  13506   } |  12792   } | 
|  13507   return is_smi_two_args_op; |  12793   return is_smi_two_args_op; | 
|  13508 } |  12794 } | 
|  13509  |  12795  | 
|  13510  |  | 
|  13511 // Used for unoptimized static calls when no class-ids are checked. |  12796 // Used for unoptimized static calls when no class-ids are checked. | 
|  13512 void ICData::AddTarget(const Function& target) const { |  12797 void ICData::AddTarget(const Function& target) const { | 
|  13513   ASSERT(!target.IsNull()); |  12798   ASSERT(!target.IsNull()); | 
|  13514   if (NumArgsTested() > 0) { |  12799   if (NumArgsTested() > 0) { | 
|  13515     // Create a fake cid entry, so that we can store the target. |  12800     // Create a fake cid entry, so that we can store the target. | 
|  13516     if (NumArgsTested() == 1) { |  12801     if (NumArgsTested() == 1) { | 
|  13517       AddReceiverCheck(kObjectCid, target, 1); |  12802       AddReceiverCheck(kObjectCid, target, 1); | 
|  13518     } else { |  12803     } else { | 
|  13519       GrowableArray<intptr_t> class_ids(NumArgsTested()); |  12804       GrowableArray<intptr_t> class_ids(NumArgsTested()); | 
|  13520       for (intptr_t i = 0; i < NumArgsTested(); i++) { |  12805       for (intptr_t i = 0; i < NumArgsTested(); i++) { | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  13537   data.SetAt(data_pos++, target); |  12822   data.SetAt(data_pos++, target); | 
|  13538   // Set count to 0 as this is called during compilation, before the |  12823   // Set count to 0 as this is called during compilation, before the | 
|  13539   // call has been executed. |  12824   // call has been executed. | 
|  13540   const Smi& value = Smi::Handle(Smi::New(0)); |  12825   const Smi& value = Smi::Handle(Smi::New(0)); | 
|  13541   data.SetAt(data_pos, value); |  12826   data.SetAt(data_pos, value); | 
|  13542   // Multithreaded access to ICData requires setting of array to be the last |  12827   // Multithreaded access to ICData requires setting of array to be the last | 
|  13543   // operation. |  12828   // operation. | 
|  13544   set_ic_data_array(data); |  12829   set_ic_data_array(data); | 
|  13545 } |  12830 } | 
|  13546  |  12831  | 
|  13547  |  | 
|  13548 bool ICData::ValidateInterceptor(const Function& target) const { |  12832 bool ICData::ValidateInterceptor(const Function& target) const { | 
|  13549   ObjectStore* store = Isolate::Current()->object_store(); |  12833   ObjectStore* store = Isolate::Current()->object_store(); | 
|  13550   ASSERT((target.raw() == store->simple_instance_of_true_function()) || |  12834   ASSERT((target.raw() == store->simple_instance_of_true_function()) || | 
|  13551          (target.raw() == store->simple_instance_of_false_function())); |  12835          (target.raw() == store->simple_instance_of_false_function())); | 
|  13552   const String& instance_of_name = String::Handle( |  12836   const String& instance_of_name = String::Handle( | 
|  13553       Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()); |  12837       Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()); | 
|  13554   ASSERT(target_name() == instance_of_name.raw()); |  12838   ASSERT(target_name() == instance_of_name.raw()); | 
|  13555   return true; |  12839   return true; | 
|  13556 } |  12840 } | 
|  13557  |  12841  | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  13601   } |  12885   } | 
|  13602   ASSERT(!target.IsNull()); |  12886   ASSERT(!target.IsNull()); | 
|  13603   data.SetAt(data_pos++, target); |  12887   data.SetAt(data_pos++, target); | 
|  13604   value = Smi::New(count); |  12888   value = Smi::New(count); | 
|  13605   data.SetAt(data_pos, value); |  12889   data.SetAt(data_pos, value); | 
|  13606   // Multithreaded access to ICData requires setting of array to be the last |  12890   // Multithreaded access to ICData requires setting of array to be the last | 
|  13607   // operation. |  12891   // operation. | 
|  13608   set_ic_data_array(data); |  12892   set_ic_data_array(data); | 
|  13609 } |  12893 } | 
|  13610  |  12894  | 
|  13611  |  | 
|  13612 RawArray* ICData::FindFreeIndex(intptr_t* index) const { |  12895 RawArray* ICData::FindFreeIndex(intptr_t* index) const { | 
|  13613   // The final entry is always the sentinel value, don't consider it |  12896   // The final entry is always the sentinel value, don't consider it | 
|  13614   // when searching. |  12897   // when searching. | 
|  13615   const intptr_t len = Length() - 1; |  12898   const intptr_t len = Length() - 1; | 
|  13616   Array& data = Array::Handle(ic_data()); |  12899   Array& data = Array::Handle(ic_data()); | 
|  13617   *index = len; |  12900   *index = len; | 
|  13618   for (intptr_t i = 0; i < len; i++) { |  12901   for (intptr_t i = 0; i < len; i++) { | 
|  13619     if (IsSentinelAt(i)) { |  12902     if (IsSentinelAt(i)) { | 
|  13620       *index = i; |  12903       *index = i; | 
|  13621       break; |  12904       break; | 
|  13622     } |  12905     } | 
|  13623   } |  12906   } | 
|  13624   if (*index < len) { |  12907   if (*index < len) { | 
|  13625     // We've found a free slot. |  12908     // We've found a free slot. | 
|  13626     return data.raw(); |  12909     return data.raw(); | 
|  13627   } |  12910   } | 
|  13628   // Append case. |  12911   // Append case. | 
|  13629   ASSERT(*index == len); |  12912   ASSERT(*index == len); | 
|  13630   ASSERT(*index >= 0); |  12913   ASSERT(*index >= 0); | 
|  13631   // Grow array. |  12914   // Grow array. | 
|  13632   const intptr_t new_len = data.Length() + TestEntryLength(); |  12915   const intptr_t new_len = data.Length() + TestEntryLength(); | 
|  13633   data = Array::Grow(data, new_len, Heap::kOld); |  12916   data = Array::Grow(data, new_len, Heap::kOld); | 
|  13634   WriteSentinel(data, TestEntryLength()); |  12917   WriteSentinel(data, TestEntryLength()); | 
|  13635   return data.raw(); |  12918   return data.raw(); | 
|  13636 } |  12919 } | 
|  13637  |  12920  | 
|  13638  |  | 
|  13639 void ICData::DebugDump() const { |  12921 void ICData::DebugDump() const { | 
|  13640   const Function& owner = Function::Handle(Owner()); |  12922   const Function& owner = Function::Handle(Owner()); | 
|  13641   THR_Print("ICData::DebugDump\n"); |  12923   THR_Print("ICData::DebugDump\n"); | 
|  13642   THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id()); |  12924   THR_Print("Owner = %s [deopt=%" Pd "]\n", owner.ToCString(), deopt_id()); | 
|  13643   THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested()); |  12925   THR_Print("NumArgsTested = %" Pd "\n", NumArgsTested()); | 
|  13644   THR_Print("Length = %" Pd "\n", Length()); |  12926   THR_Print("Length = %" Pd "\n", Length()); | 
|  13645   THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks()); |  12927   THR_Print("NumberOfChecks = %" Pd "\n", NumberOfChecks()); | 
|  13646  |  12928  | 
|  13647   GrowableArray<intptr_t> class_ids; |  12929   GrowableArray<intptr_t> class_ids; | 
|  13648   for (intptr_t i = 0; i < NumberOfChecks(); i++) { |  12930   for (intptr_t i = 0; i < NumberOfChecks(); i++) { | 
|  13649     THR_Print("Check[%" Pd "]:", i); |  12931     THR_Print("Check[%" Pd "]:", i); | 
|  13650     GetClassIdsAt(i, &class_ids); |  12932     GetClassIdsAt(i, &class_ids); | 
|  13651     for (intptr_t c = 0; c < class_ids.length(); c++) { |  12933     for (intptr_t c = 0; c < class_ids.length(); c++) { | 
|  13652       THR_Print(" %" Pd "", class_ids[c]); |  12934       THR_Print(" %" Pd "", class_ids[c]); | 
|  13653     } |  12935     } | 
|  13654     THR_Print("--- %" Pd " hits\n", GetCountAt(i)); |  12936     THR_Print("--- %" Pd " hits\n", GetCountAt(i)); | 
|  13655   } |  12937   } | 
|  13656 } |  12938 } | 
|  13657  |  12939  | 
|  13658  |  | 
|  13659 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |  12940 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 
|  13660                               const Function& target, |  12941                               const Function& target, | 
|  13661                               intptr_t count) const { |  12942                               intptr_t count) const { | 
|  13662 #if defined(DEBUG) |  12943 #if defined(DEBUG) | 
|  13663   GrowableArray<intptr_t> class_ids(1); |  12944   GrowableArray<intptr_t> class_ids(1); | 
|  13664   class_ids.Add(receiver_class_id); |  12945   class_ids.Add(receiver_class_id); | 
|  13665   ASSERT(!HasCheck(class_ids)); |  12946   ASSERT(!HasCheck(class_ids)); | 
|  13666 #endif  // DEBUG |  12947 #endif  // DEBUG | 
|  13667   ASSERT(!target.IsNull()); |  12948   ASSERT(!target.IsNull()); | 
|  13668   ASSERT(NumArgsTested() == 1);  // Otherwise use 'AddCheck'. |  12949   ASSERT(NumArgsTested() == 1);  // Otherwise use 'AddCheck'. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  13691     const Smi& entry_point = |  12972     const Smi& entry_point = | 
|  13692         Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint())); |  12973         Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint())); | 
|  13693     data.SetAt(data_pos + 1, code); |  12974     data.SetAt(data_pos + 1, code); | 
|  13694     data.SetAt(data_pos + 2, entry_point); |  12975     data.SetAt(data_pos + 2, entry_point); | 
|  13695   } |  12976   } | 
|  13696   // Multithreaded access to ICData requires setting of array to be the last |  12977   // Multithreaded access to ICData requires setting of array to be the last | 
|  13697   // operation. |  12978   // operation. | 
|  13698   set_ic_data_array(data); |  12979   set_ic_data_array(data); | 
|  13699 } |  12980 } | 
|  13700  |  12981  | 
|  13701  |  | 
|  13702 void ICData::GetCheckAt(intptr_t index, |  12982 void ICData::GetCheckAt(intptr_t index, | 
|  13703                         GrowableArray<intptr_t>* class_ids, |  12983                         GrowableArray<intptr_t>* class_ids, | 
|  13704                         Function* target) const { |  12984                         Function* target) const { | 
|  13705   ASSERT(index < NumberOfChecks()); |  12985   ASSERT(index < NumberOfChecks()); | 
|  13706   ASSERT(class_ids != NULL); |  12986   ASSERT(class_ids != NULL); | 
|  13707   ASSERT(target != NULL); |  12987   ASSERT(target != NULL); | 
|  13708   class_ids->Clear(); |  12988   class_ids->Clear(); | 
|  13709   const Array& data = Array::Handle(ic_data()); |  12989   const Array& data = Array::Handle(ic_data()); | 
|  13710   intptr_t data_pos = index * TestEntryLength(); |  12990   intptr_t data_pos = index * TestEntryLength(); | 
|  13711   for (intptr_t i = 0; i < NumArgsTested(); i++) { |  12991   for (intptr_t i = 0; i < NumArgsTested(); i++) { | 
|  13712     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |  12992     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); | 
|  13713   } |  12993   } | 
|  13714   (*target) ^= data.At(data_pos++); |  12994   (*target) ^= data.At(data_pos++); | 
|  13715 } |  12995 } | 
|  13716  |  12996  | 
|  13717  |  | 
|  13718 bool ICData::IsSentinelAt(intptr_t index) const { |  12997 bool ICData::IsSentinelAt(intptr_t index) const { | 
|  13719   ASSERT(index < Length()); |  12998   ASSERT(index < Length()); | 
|  13720   const Array& data = Array::Handle(ic_data()); |  12999   const Array& data = Array::Handle(ic_data()); | 
|  13721   const intptr_t entry_length = TestEntryLength(); |  13000   const intptr_t entry_length = TestEntryLength(); | 
|  13722   intptr_t data_pos = index * TestEntryLength(); |  13001   intptr_t data_pos = index * TestEntryLength(); | 
|  13723   for (intptr_t i = 0; i < entry_length; i++) { |  13002   for (intptr_t i = 0; i < entry_length; i++) { | 
|  13724     if (data.At(data_pos++) != smi_illegal_cid().raw()) { |  13003     if (data.At(data_pos++) != smi_illegal_cid().raw()) { | 
|  13725       return false; |  13004       return false; | 
|  13726     } |  13005     } | 
|  13727   } |  13006   } | 
|  13728   // The entry at |index| was filled with the value kIllegalCid. |  13007   // The entry at |index| was filled with the value kIllegalCid. | 
|  13729   return true; |  13008   return true; | 
|  13730 } |  13009 } | 
|  13731  |  13010  | 
|  13732  |  | 
|  13733 void ICData::GetClassIdsAt(intptr_t index, |  13011 void ICData::GetClassIdsAt(intptr_t index, | 
|  13734                            GrowableArray<intptr_t>* class_ids) const { |  13012                            GrowableArray<intptr_t>* class_ids) const { | 
|  13735   ASSERT(index < Length()); |  13013   ASSERT(index < Length()); | 
|  13736   ASSERT(class_ids != NULL); |  13014   ASSERT(class_ids != NULL); | 
|  13737   ASSERT(!IsSentinelAt(index)); |  13015   ASSERT(!IsSentinelAt(index)); | 
|  13738   class_ids->Clear(); |  13016   class_ids->Clear(); | 
|  13739   const Array& data = Array::Handle(ic_data()); |  13017   const Array& data = Array::Handle(ic_data()); | 
|  13740   intptr_t data_pos = index * TestEntryLength(); |  13018   intptr_t data_pos = index * TestEntryLength(); | 
|  13741   for (intptr_t i = 0; i < NumArgsTested(); i++) { |  13019   for (intptr_t i = 0; i < NumArgsTested(); i++) { | 
|  13742     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); |  13020     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++)))); | 
|  13743   } |  13021   } | 
|  13744 } |  13022 } | 
|  13745  |  13023  | 
|  13746  |  | 
|  13747 void ICData::GetOneClassCheckAt(intptr_t index, |  13024 void ICData::GetOneClassCheckAt(intptr_t index, | 
|  13748                                 intptr_t* class_id, |  13025                                 intptr_t* class_id, | 
|  13749                                 Function* target) const { |  13026                                 Function* target) const { | 
|  13750   ASSERT(class_id != NULL); |  13027   ASSERT(class_id != NULL); | 
|  13751   ASSERT(target != NULL); |  13028   ASSERT(target != NULL); | 
|  13752   ASSERT(NumArgsTested() == 1); |  13029   ASSERT(NumArgsTested() == 1); | 
|  13753   const Array& data = Array::Handle(ic_data()); |  13030   const Array& data = Array::Handle(ic_data()); | 
|  13754   const intptr_t data_pos = index * TestEntryLength(); |  13031   const intptr_t data_pos = index * TestEntryLength(); | 
|  13755   *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); |  13032   *class_id = Smi::Value(Smi::RawCast(data.At(data_pos))); | 
|  13756   *target ^= data.At(data_pos + 1); |  13033   *target ^= data.At(data_pos + 1); | 
|  13757 } |  13034 } | 
|  13758  |  13035  | 
|  13759  |  | 
|  13760 intptr_t ICData::GetCidAt(intptr_t index) const { |  13036 intptr_t ICData::GetCidAt(intptr_t index) const { | 
|  13761   ASSERT(NumArgsTested() == 1); |  13037   ASSERT(NumArgsTested() == 1); | 
|  13762   const Array& data = Array::Handle(ic_data()); |  13038   const Array& data = Array::Handle(ic_data()); | 
|  13763   const intptr_t data_pos = index * TestEntryLength(); |  13039   const intptr_t data_pos = index * TestEntryLength(); | 
|  13764   return Smi::Value(Smi::RawCast(data.At(data_pos))); |  13040   return Smi::Value(Smi::RawCast(data.At(data_pos))); | 
|  13765 } |  13041 } | 
|  13766  |  13042  | 
|  13767  |  | 
|  13768 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { |  13043 intptr_t ICData::GetClassIdAt(intptr_t index, intptr_t arg_nr) const { | 
|  13769   GrowableArray<intptr_t> class_ids; |  13044   GrowableArray<intptr_t> class_ids; | 
|  13770   GetClassIdsAt(index, &class_ids); |  13045   GetClassIdsAt(index, &class_ids); | 
|  13771   return class_ids[arg_nr]; |  13046   return class_ids[arg_nr]; | 
|  13772 } |  13047 } | 
|  13773  |  13048  | 
|  13774  |  | 
|  13775 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { |  13049 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const { | 
|  13776   ASSERT(index < Length()); |  13050   ASSERT(index < Length()); | 
|  13777   ASSERT(!IsSentinelAt(index)); |  13051   ASSERT(!IsSentinelAt(index)); | 
|  13778   const intptr_t data_pos = index * TestEntryLength(); |  13052   const intptr_t data_pos = index * TestEntryLength(); | 
|  13779   NoSafepointScope no_safepoint; |  13053   NoSafepointScope no_safepoint; | 
|  13780   RawArray* raw_data = ic_data(); |  13054   RawArray* raw_data = ic_data(); | 
|  13781   return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); |  13055   return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos])); | 
|  13782 } |  13056 } | 
|  13783  |  13057  | 
|  13784  |  | 
|  13785 RawFunction* ICData::GetTargetAt(intptr_t index) const { |  13058 RawFunction* ICData::GetTargetAt(intptr_t index) const { | 
|  13786   ASSERT(Isolate::Current()->compilation_allowed()); |  13059   ASSERT(Isolate::Current()->compilation_allowed()); | 
|  13787   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); |  13060   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); | 
|  13788   ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction()); |  13061   ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction()); | 
|  13789  |  13062  | 
|  13790   NoSafepointScope no_safepoint; |  13063   NoSafepointScope no_safepoint; | 
|  13791   RawArray* raw_data = ic_data(); |  13064   RawArray* raw_data = ic_data(); | 
|  13792   return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]); |  13065   return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]); | 
|  13793 } |  13066 } | 
|  13794  |  13067  | 
|  13795  |  | 
|  13796 RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const { |  13068 RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const { | 
|  13797   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); |  13069   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested(); | 
|  13798  |  13070  | 
|  13799   NoSafepointScope no_safepoint; |  13071   NoSafepointScope no_safepoint; | 
|  13800   RawArray* raw_data = ic_data(); |  13072   RawArray* raw_data = ic_data(); | 
|  13801   return raw_data->ptr()->data()[data_pos]; |  13073   return raw_data->ptr()->data()[data_pos]; | 
|  13802 } |  13074 } | 
|  13803  |  13075  | 
|  13804  |  | 
|  13805 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const { |  13076 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const { | 
|  13806   ASSERT(0 <= value); |  13077   ASSERT(0 <= value); | 
|  13807   ASSERT(value <= Smi::kMaxValue); |  13078   ASSERT(value <= Smi::kMaxValue); | 
|  13808   SetCountAt(index, Utils::Minimum(GetCountAt(index) + value, Smi::kMaxValue)); |  13079   SetCountAt(index, Utils::Minimum(GetCountAt(index) + value, Smi::kMaxValue)); | 
|  13809 } |  13080 } | 
|  13810  |  13081  | 
|  13811  |  | 
|  13812 void ICData::SetCountAt(intptr_t index, intptr_t value) const { |  13082 void ICData::SetCountAt(intptr_t index, intptr_t value) const { | 
|  13813   ASSERT(0 <= value); |  13083   ASSERT(0 <= value); | 
|  13814   ASSERT(value <= Smi::kMaxValue); |  13084   ASSERT(value <= Smi::kMaxValue); | 
|  13815  |  13085  | 
|  13816   const Array& data = Array::Handle(ic_data()); |  13086   const Array& data = Array::Handle(ic_data()); | 
|  13817   const intptr_t data_pos = |  13087   const intptr_t data_pos = | 
|  13818       index * TestEntryLength() + CountIndexFor(NumArgsTested()); |  13088       index * TestEntryLength() + CountIndexFor(NumArgsTested()); | 
|  13819   data.SetAt(data_pos, Smi::Handle(Smi::New(value))); |  13089   data.SetAt(data_pos, Smi::Handle(Smi::New(value))); | 
|  13820 } |  13090 } | 
|  13821  |  13091  | 
|  13822  |  | 
|  13823 intptr_t ICData::GetCountAt(intptr_t index) const { |  13092 intptr_t ICData::GetCountAt(intptr_t index) const { | 
|  13824   ASSERT(Isolate::Current()->compilation_allowed()); |  13093   ASSERT(Isolate::Current()->compilation_allowed()); | 
|  13825   const Array& data = Array::Handle(ic_data()); |  13094   const Array& data = Array::Handle(ic_data()); | 
|  13826   const intptr_t data_pos = |  13095   const intptr_t data_pos = | 
|  13827       index * TestEntryLength() + CountIndexFor(NumArgsTested()); |  13096       index * TestEntryLength() + CountIndexFor(NumArgsTested()); | 
|  13828   intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos))); |  13097   intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos))); | 
|  13829   if (value >= 0) return value; |  13098   if (value >= 0) return value; | 
|  13830  |  13099  | 
|  13831   // The counter very rarely overflows to a negative value, but if it does, we |  13100   // The counter very rarely overflows to a negative value, but if it does, we | 
|  13832   // would rather just reset it to zero. |  13101   // would rather just reset it to zero. | 
|  13833   SetCountAt(index, 0); |  13102   SetCountAt(index, 0); | 
|  13834   return 0; |  13103   return 0; | 
|  13835 } |  13104 } | 
|  13836  |  13105  | 
|  13837  |  | 
|  13838 intptr_t ICData::AggregateCount() const { |  13106 intptr_t ICData::AggregateCount() const { | 
|  13839   if (IsNull()) return 0; |  13107   if (IsNull()) return 0; | 
|  13840   const intptr_t len = NumberOfChecks(); |  13108   const intptr_t len = NumberOfChecks(); | 
|  13841   intptr_t count = 0; |  13109   intptr_t count = 0; | 
|  13842   for (intptr_t i = 0; i < len; i++) { |  13110   for (intptr_t i = 0; i < len; i++) { | 
|  13843     count += GetCountAt(i); |  13111     count += GetCountAt(i); | 
|  13844   } |  13112   } | 
|  13845   return count; |  13113   return count; | 
|  13846 } |  13114 } | 
|  13847  |  13115  | 
|  13848  |  | 
|  13849 void ICData::SetCodeAt(intptr_t index, const Code& value) const { |  13116 void ICData::SetCodeAt(intptr_t index, const Code& value) const { | 
|  13850   ASSERT(!Isolate::Current()->compilation_allowed()); |  13117   ASSERT(!Isolate::Current()->compilation_allowed()); | 
|  13851   const Array& data = Array::Handle(ic_data()); |  13118   const Array& data = Array::Handle(ic_data()); | 
|  13852   const intptr_t data_pos = |  13119   const intptr_t data_pos = | 
|  13853       index * TestEntryLength() + CodeIndexFor(NumArgsTested()); |  13120       index * TestEntryLength() + CodeIndexFor(NumArgsTested()); | 
|  13854   data.SetAt(data_pos, value); |  13121   data.SetAt(data_pos, value); | 
|  13855 } |  13122 } | 
|  13856  |  13123  | 
|  13857  |  | 
|  13858 void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const { |  13124 void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const { | 
|  13859   ASSERT(!Isolate::Current()->compilation_allowed()); |  13125   ASSERT(!Isolate::Current()->compilation_allowed()); | 
|  13860   const Array& data = Array::Handle(ic_data()); |  13126   const Array& data = Array::Handle(ic_data()); | 
|  13861   const intptr_t data_pos = |  13127   const intptr_t data_pos = | 
|  13862       index * TestEntryLength() + EntryPointIndexFor(NumArgsTested()); |  13128       index * TestEntryLength() + EntryPointIndexFor(NumArgsTested()); | 
|  13863   data.SetAt(data_pos, value); |  13129   data.SetAt(data_pos, value); | 
|  13864 } |  13130 } | 
|  13865  |  13131  | 
|  13866  |  | 
|  13867 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id, |  13132 RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id, | 
|  13868                                                  intptr_t* count_return) const { |  13133                                                  intptr_t* count_return) const { | 
|  13869   const intptr_t len = NumberOfChecks(); |  13134   const intptr_t len = NumberOfChecks(); | 
|  13870   for (intptr_t i = 0; i < len; i++) { |  13135   for (intptr_t i = 0; i < len; i++) { | 
|  13871     if (GetReceiverClassIdAt(i) == class_id) { |  13136     if (GetReceiverClassIdAt(i) == class_id) { | 
|  13872       *count_return = GetCountAt(i); |  13137       *count_return = GetCountAt(i); | 
|  13873       return GetTargetAt(i); |  13138       return GetTargetAt(i); | 
|  13874     } |  13139     } | 
|  13875   } |  13140   } | 
|  13876   return Function::null(); |  13141   return Function::null(); | 
|  13877 } |  13142 } | 
|  13878  |  13143  | 
|  13879  |  | 
|  13880 RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid, |  13144 RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid, | 
|  13881                                             const Function& target) const { |  13145                                             const Function& target) const { | 
|  13882   ASSERT(!IsNull()); |  13146   ASSERT(!IsNull()); | 
|  13883   const intptr_t kNumArgsTested = 1; |  13147   const intptr_t kNumArgsTested = 1; | 
|  13884   ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); |  13148   ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); | 
|  13885  |  13149  | 
|  13886   // Copy count so that we copy the state "count == 0" vs "count > 0". |  13150   // Copy count so that we copy the state "count == 0" vs "count > 0". | 
|  13887   result.AddReceiverCheck(cid, target, GetCountAt(0)); |  13151   result.AddReceiverCheck(cid, target, GetCountAt(0)); | 
|  13888   return result.raw(); |  13152   return result.raw(); | 
|  13889 } |  13153 } | 
|  13890  |  13154  | 
|  13891  |  | 
|  13892 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { |  13155 RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const { | 
|  13893   ASSERT(!IsNull()); |  13156   ASSERT(!IsNull()); | 
|  13894   ASSERT(NumArgsTested() > arg_nr); |  13157   ASSERT(NumArgsTested() > arg_nr); | 
|  13895   if ((arg_nr == 0) && (NumArgsTested() == 1)) { |  13158   if ((arg_nr == 0) && (NumArgsTested() == 1)) { | 
|  13896     // Frequent case. |  13159     // Frequent case. | 
|  13897     return raw(); |  13160     return raw(); | 
|  13898   } |  13161   } | 
|  13899   const intptr_t kNumArgsTested = 1; |  13162   const intptr_t kNumArgsTested = 1; | 
|  13900   ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); |  13163   ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested)); | 
|  13901   const intptr_t len = NumberOfChecks(); |  13164   const intptr_t len = NumberOfChecks(); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  13921     } else { |  13184     } else { | 
|  13922       // This will make sure that Smi is first if it exists. |  13185       // This will make sure that Smi is first if it exists. | 
|  13923       result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)), |  13186       result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)), | 
|  13924                               count); |  13187                               count); | 
|  13925     } |  13188     } | 
|  13926   } |  13189   } | 
|  13927  |  13190  | 
|  13928   return result.raw(); |  13191   return result.raw(); | 
|  13929 } |  13192 } | 
|  13930  |  13193  | 
|  13931  |  | 
|  13932 // (cid, count) tuple used to sort ICData by count. |  13194 // (cid, count) tuple used to sort ICData by count. | 
|  13933 struct CidCount { |  13195 struct CidCount { | 
|  13934   CidCount(intptr_t cid_, intptr_t count_, Function* f_) |  13196   CidCount(intptr_t cid_, intptr_t count_, Function* f_) | 
|  13935       : cid(cid_), count(count_), function(f_) {} |  13197       : cid(cid_), count(count_), function(f_) {} | 
|  13936  |  13198  | 
|  13937   static int HighestCountFirst(const CidCount* a, const CidCount* b); |  13199   static int HighestCountFirst(const CidCount* a, const CidCount* b); | 
|  13938  |  13200  | 
|  13939   intptr_t cid; |  13201   intptr_t cid; | 
|  13940   intptr_t count; |  13202   intptr_t count; | 
|  13941   Function* function; |  13203   Function* function; | 
|  13942 }; |  13204 }; | 
|  13943  |  13205  | 
|  13944  |  | 
|  13945 int CidCount::HighestCountFirst(const CidCount* a, const CidCount* b) { |  13206 int CidCount::HighestCountFirst(const CidCount* a, const CidCount* b) { | 
|  13946   if (a->count > b->count) { |  13207   if (a->count > b->count) { | 
|  13947     return -1; |  13208     return -1; | 
|  13948   } |  13209   } | 
|  13949   return (a->count < b->count) ? 1 : 0; |  13210   return (a->count < b->count) ? 1 : 0; | 
|  13950 } |  13211 } | 
|  13951  |  13212  | 
|  13952  |  | 
|  13953 RawICData* ICData::AsUnaryClassChecksSortedByCount() const { |  13213 RawICData* ICData::AsUnaryClassChecksSortedByCount() const { | 
|  13954   ASSERT(!IsNull()); |  13214   ASSERT(!IsNull()); | 
|  13955   const intptr_t kNumArgsTested = 1; |  13215   const intptr_t kNumArgsTested = 1; | 
|  13956   const intptr_t len = NumberOfChecks(); |  13216   const intptr_t len = NumberOfChecks(); | 
|  13957   if (len <= 1) { |  13217   if (len <= 1) { | 
|  13958     // No sorting needed. |  13218     // No sorting needed. | 
|  13959     return AsUnaryClassChecks(); |  13219     return AsUnaryClassChecks(); | 
|  13960   } |  13220   } | 
|  13961   GrowableArray<CidCount> aggregate; |  13221   GrowableArray<CidCount> aggregate; | 
|  13962   for (intptr_t i = 0; i < len; i++) { |  13222   for (intptr_t i = 0; i < len; i++) { | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  13995                Smi::Handle(Smi::New(aggregate[i].count))); |  13255                Smi::Handle(Smi::New(aggregate[i].count))); | 
|  13996  |  13256  | 
|  13997     pos += result.TestEntryLength(); |  13257     pos += result.TestEntryLength(); | 
|  13998   } |  13258   } | 
|  13999   WriteSentinel(data, result.TestEntryLength()); |  13259   WriteSentinel(data, result.TestEntryLength()); | 
|  14000   result.set_ic_data_array(data); |  13260   result.set_ic_data_array(data); | 
|  14001   ASSERT(result.NumberOfChecksIs(aggregate.length())); |  13261   ASSERT(result.NumberOfChecksIs(aggregate.length())); | 
|  14002   return result.raw(); |  13262   return result.raw(); | 
|  14003 } |  13263 } | 
|  14004  |  13264  | 
|  14005  |  | 
|  14006 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { |  13265 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { | 
|  14007   if (NumberOfChecksIs(0)) return false; |  13266   if (NumberOfChecksIs(0)) return false; | 
|  14008   Class& cls = Class::Handle(); |  13267   Class& cls = Class::Handle(); | 
|  14009   const intptr_t len = NumberOfChecks(); |  13268   const intptr_t len = NumberOfChecks(); | 
|  14010   for (intptr_t i = 0; i < len; i++) { |  13269   for (intptr_t i = 0; i < len; i++) { | 
|  14011     if (IsUsedAt(i)) { |  13270     if (IsUsedAt(i)) { | 
|  14012       cls = Function::Handle(GetTargetAt(i)).Owner(); |  13271       cls = Function::Handle(GetTargetAt(i)).Owner(); | 
|  14013       if (cls.id() != owner_cid) { |  13272       if (cls.id() != owner_cid) { | 
|  14014         return false; |  13273         return false; | 
|  14015       } |  13274       } | 
|  14016     } |  13275     } | 
|  14017   } |  13276   } | 
|  14018   return true; |  13277   return true; | 
|  14019 } |  13278 } | 
|  14020  |  13279  | 
|  14021  |  | 
|  14022 bool ICData::HasReceiverClassId(intptr_t class_id) const { |  13280 bool ICData::HasReceiverClassId(intptr_t class_id) const { | 
|  14023   ASSERT(NumArgsTested() > 0); |  13281   ASSERT(NumArgsTested() > 0); | 
|  14024   const intptr_t len = NumberOfChecks(); |  13282   const intptr_t len = NumberOfChecks(); | 
|  14025   for (intptr_t i = 0; i < len; i++) { |  13283   for (intptr_t i = 0; i < len; i++) { | 
|  14026     if (IsUsedAt(i)) { |  13284     if (IsUsedAt(i)) { | 
|  14027       const intptr_t test_class_id = GetReceiverClassIdAt(i); |  13285       const intptr_t test_class_id = GetReceiverClassIdAt(i); | 
|  14028       if (test_class_id == class_id) { |  13286       if (test_class_id == class_id) { | 
|  14029         return true; |  13287         return true; | 
|  14030       } |  13288       } | 
|  14031     } |  13289     } | 
|  14032   } |  13290   } | 
|  14033   return false; |  13291   return false; | 
|  14034 } |  13292 } | 
|  14035  |  13293  | 
|  14036  |  | 
|  14037 // Returns true if all targets are the same. |  13294 // Returns true if all targets are the same. | 
|  14038 // TODO(srdjan): if targets are native use their C_function to compare. |  13295 // TODO(srdjan): if targets are native use their C_function to compare. | 
|  14039 bool ICData::HasOneTarget() const { |  13296 bool ICData::HasOneTarget() const { | 
|  14040   ASSERT(!NumberOfChecksIs(0)); |  13297   ASSERT(!NumberOfChecksIs(0)); | 
|  14041   const Function& first_target = Function::Handle(GetTargetAt(0)); |  13298   const Function& first_target = Function::Handle(GetTargetAt(0)); | 
|  14042   const intptr_t len = NumberOfChecks(); |  13299   const intptr_t len = NumberOfChecks(); | 
|  14043   for (intptr_t i = 1; i < len; i++) { |  13300   for (intptr_t i = 1; i < len; i++) { | 
|  14044     if (IsUsedAt(i) && (GetTargetAt(i) != first_target.raw())) { |  13301     if (IsUsedAt(i) && (GetTargetAt(i) != first_target.raw())) { | 
|  14045       return false; |  13302       return false; | 
|  14046     } |  13303     } | 
|  14047   } |  13304   } | 
|  14048   return true; |  13305   return true; | 
|  14049 } |  13306 } | 
|  14050  |  13307  | 
|  14051  |  | 
|  14052 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, |  13308 void ICData::GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first, | 
|  14053                                    GrowableArray<intptr_t>* second) const { |  13309                                    GrowableArray<intptr_t>* second) const { | 
|  14054   ASSERT(NumArgsTested() == 2); |  13310   ASSERT(NumArgsTested() == 2); | 
|  14055   first->Clear(); |  13311   first->Clear(); | 
|  14056   second->Clear(); |  13312   second->Clear(); | 
|  14057   GrowableArray<intptr_t> class_ids; |  13313   GrowableArray<intptr_t> class_ids; | 
|  14058   const intptr_t len = NumberOfChecks(); |  13314   const intptr_t len = NumberOfChecks(); | 
|  14059   for (intptr_t i = 0; i < len; i++) { |  13315   for (intptr_t i = 0; i < len; i++) { | 
|  14060     if (GetCountAt(i) > 0) { |  13316     if (GetCountAt(i) > 0) { | 
|  14061       GetClassIdsAt(i, &class_ids); |  13317       GetClassIdsAt(i, &class_ids); | 
|  14062       ASSERT(class_ids.length() == 2); |  13318       ASSERT(class_ids.length() == 2); | 
|  14063       first->Add(class_ids[0]); |  13319       first->Add(class_ids[0]); | 
|  14064       second->Add(class_ids[1]); |  13320       second->Add(class_ids[1]); | 
|  14065     } |  13321     } | 
|  14066   } |  13322   } | 
|  14067 } |  13323 } | 
|  14068  |  13324  | 
|  14069  |  | 
|  14070 bool ICData::IsUsedAt(intptr_t i) const { |  13325 bool ICData::IsUsedAt(intptr_t i) const { | 
|  14071   if (GetCountAt(i) <= 0) { |  13326   if (GetCountAt(i) <= 0) { | 
|  14072     // Do not mistake unoptimized static call ICData for unused. |  13327     // Do not mistake unoptimized static call ICData for unused. | 
|  14073     // See ICData::AddTarget. |  13328     // See ICData::AddTarget. | 
|  14074     // TODO(srdjan): Make this test more robust. |  13329     // TODO(srdjan): Make this test more robust. | 
|  14075     if (NumArgsTested() > 0) { |  13330     if (NumArgsTested() > 0) { | 
|  14076       const intptr_t cid = GetReceiverClassIdAt(i); |  13331       const intptr_t cid = GetReceiverClassIdAt(i); | 
|  14077       if (cid == kObjectCid) { |  13332       if (cid == kObjectCid) { | 
|  14078         return true; |  13333         return true; | 
|  14079       } |  13334       } | 
|  14080     } |  13335     } | 
|  14081     return false; |  13336     return false; | 
|  14082   } |  13337   } | 
|  14083   return true; |  13338   return true; | 
|  14084 } |  13339 } | 
|  14085  |  13340  | 
|  14086  |  | 
|  14087 void ICData::InitOnce() { |  13341 void ICData::InitOnce() { | 
|  14088   for (int i = 0; i < kCachedICDataArrayCount; i++) { |  13342   for (int i = 0; i < kCachedICDataArrayCount; i++) { | 
|  14089     cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); |  13343     cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); | 
|  14090   } |  13344   } | 
|  14091 } |  13345 } | 
|  14092  |  13346  | 
|  14093  |  | 
|  14094 RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { |  13347 RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { | 
|  14095   // IC data array must be null terminated (sentinel entry). |  13348   // IC data array must be null terminated (sentinel entry). | 
|  14096   const intptr_t len = TestEntryLengthFor(num_args_tested); |  13349   const intptr_t len = TestEntryLengthFor(num_args_tested); | 
|  14097   const Array& array = Array::Handle(Array::New(len, Heap::kOld)); |  13350   const Array& array = Array::Handle(Array::New(len, Heap::kOld)); | 
|  14098   WriteSentinel(array, len); |  13351   WriteSentinel(array, len); | 
|  14099   array.MakeImmutable(); |  13352   array.MakeImmutable(); | 
|  14100   return array.raw(); |  13353   return array.raw(); | 
|  14101 } |  13354 } | 
|  14102  |  13355  | 
|  14103  |  | 
|  14104 RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested) { |  13356 RawArray* ICData::CachedEmptyICDataArray(intptr_t num_args_tested) { | 
|  14105   ASSERT(num_args_tested >= 0); |  13357   ASSERT(num_args_tested >= 0); | 
|  14106   ASSERT(num_args_tested < kCachedICDataArrayCount); |  13358   ASSERT(num_args_tested < kCachedICDataArrayCount); | 
|  14107   return cached_icdata_arrays_[num_args_tested]; |  13359   return cached_icdata_arrays_[num_args_tested]; | 
|  14108 } |  13360 } | 
|  14109  |  13361  | 
|  14110  |  | 
|  14111 // Does not initialize ICData array. |  13362 // Does not initialize ICData array. | 
|  14112 RawICData* ICData::NewDescriptor(Zone* zone, |  13363 RawICData* ICData::NewDescriptor(Zone* zone, | 
|  14113                                  const Function& owner, |  13364                                  const Function& owner, | 
|  14114                                  const String& target_name, |  13365                                  const String& target_name, | 
|  14115                                  const Array& arguments_descriptor, |  13366                                  const Array& arguments_descriptor, | 
|  14116                                  intptr_t deopt_id, |  13367                                  intptr_t deopt_id, | 
|  14117                                  intptr_t num_args_tested, |  13368                                  intptr_t num_args_tested, | 
|  14118                                  bool is_static_call) { |  13369                                  bool is_static_call) { | 
|  14119   ASSERT(!owner.IsNull()); |  13370   ASSERT(!owner.IsNull()); | 
|  14120   ASSERT(!target_name.IsNull()); |  13371   ASSERT(!target_name.IsNull()); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  14135   NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id)); |  13386   NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id)); | 
|  14136   result.set_state_bits(0); |  13387   result.set_state_bits(0); | 
|  14137 #if defined(TAG_IC_DATA) |  13388 #if defined(TAG_IC_DATA) | 
|  14138   result.set_tag(-1); |  13389   result.set_tag(-1); | 
|  14139 #endif |  13390 #endif | 
|  14140   result.SetIsStaticCall(is_static_call); |  13391   result.SetIsStaticCall(is_static_call); | 
|  14141   result.SetNumArgsTested(num_args_tested); |  13392   result.SetNumArgsTested(num_args_tested); | 
|  14142   return result.raw(); |  13393   return result.raw(); | 
|  14143 } |  13394 } | 
|  14144  |  13395  | 
|  14145  |  | 
|  14146 bool ICData::IsImmutable() const { |  13396 bool ICData::IsImmutable() const { | 
|  14147   const Array& data = Array::Handle(ic_data()); |  13397   const Array& data = Array::Handle(ic_data()); | 
|  14148   return data.IsImmutable(); |  13398   return data.IsImmutable(); | 
|  14149 } |  13399 } | 
|  14150  |  13400  | 
|  14151  |  | 
|  14152 RawICData* ICData::New() { |  13401 RawICData* ICData::New() { | 
|  14153   ICData& result = ICData::Handle(); |  13402   ICData& result = ICData::Handle(); | 
|  14154   { |  13403   { | 
|  14155     // IC data objects are long living objects, allocate them in old generation. |  13404     // IC data objects are long living objects, allocate them in old generation. | 
|  14156     RawObject* raw = |  13405     RawObject* raw = | 
|  14157         Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld); |  13406         Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld); | 
|  14158     NoSafepointScope no_safepoint; |  13407     NoSafepointScope no_safepoint; | 
|  14159     result ^= raw; |  13408     result ^= raw; | 
|  14160   } |  13409   } | 
|  14161   result.set_deopt_id(Thread::kNoDeoptId); |  13410   result.set_deopt_id(Thread::kNoDeoptId); | 
|  14162   result.set_state_bits(0); |  13411   result.set_state_bits(0); | 
|  14163 #if defined(TAG_IC_DATA) |  13412 #if defined(TAG_IC_DATA) | 
|  14164   result.set_tag(-1); |  13413   result.set_tag(-1); | 
|  14165 #endif |  13414 #endif | 
|  14166   return result.raw(); |  13415   return result.raw(); | 
|  14167 } |  13416 } | 
|  14168  |  13417  | 
|  14169  |  | 
|  14170 RawICData* ICData::New(const Function& owner, |  13418 RawICData* ICData::New(const Function& owner, | 
|  14171                        const String& target_name, |  13419                        const String& target_name, | 
|  14172                        const Array& arguments_descriptor, |  13420                        const Array& arguments_descriptor, | 
|  14173                        intptr_t deopt_id, |  13421                        intptr_t deopt_id, | 
|  14174                        intptr_t num_args_tested, |  13422                        intptr_t num_args_tested, | 
|  14175                        bool is_static_call) { |  13423                        bool is_static_call) { | 
|  14176   Zone* zone = Thread::Current()->zone(); |  13424   Zone* zone = Thread::Current()->zone(); | 
|  14177   const ICData& result = ICData::Handle( |  13425   const ICData& result = ICData::Handle( | 
|  14178       zone, NewDescriptor(zone, owner, target_name, arguments_descriptor, |  13426       zone, NewDescriptor(zone, owner, target_name, arguments_descriptor, | 
|  14179                           deopt_id, num_args_tested, is_static_call)); |  13427                           deopt_id, num_args_tested, is_static_call)); | 
|  14180   result.set_ic_data_array( |  13428   result.set_ic_data_array( | 
|  14181       Array::Handle(zone, CachedEmptyICDataArray(num_args_tested))); |  13429       Array::Handle(zone, CachedEmptyICDataArray(num_args_tested))); | 
|  14182   return result.raw(); |  13430   return result.raw(); | 
|  14183 } |  13431 } | 
|  14184  |  13432  | 
|  14185  |  | 
|  14186 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { |  13433 RawICData* ICData::NewFrom(const ICData& from, intptr_t num_args_tested) { | 
|  14187   const ICData& result = ICData::Handle(ICData::New( |  13434   const ICData& result = ICData::Handle(ICData::New( | 
|  14188       Function::Handle(from.Owner()), String::Handle(from.target_name()), |  13435       Function::Handle(from.Owner()), String::Handle(from.target_name()), | 
|  14189       Array::Handle(from.arguments_descriptor()), from.deopt_id(), |  13436       Array::Handle(from.arguments_descriptor()), from.deopt_id(), | 
|  14190       num_args_tested, from.is_static_call())); |  13437       num_args_tested, from.is_static_call())); | 
|  14191   // Copy deoptimization reasons. |  13438   // Copy deoptimization reasons. | 
|  14192   result.SetDeoptReasons(from.DeoptReasons()); |  13439   result.SetDeoptReasons(from.DeoptReasons()); | 
|  14193   return result.raw(); |  13440   return result.raw(); | 
|  14194 } |  13441 } | 
|  14195  |  13442  | 
|  14196  |  | 
|  14197 RawICData* ICData::Clone(const ICData& from) { |  13443 RawICData* ICData::Clone(const ICData& from) { | 
|  14198   Zone* zone = Thread::Current()->zone(); |  13444   Zone* zone = Thread::Current()->zone(); | 
|  14199   const ICData& result = ICData::Handle(ICData::NewDescriptor( |  13445   const ICData& result = ICData::Handle(ICData::NewDescriptor( | 
|  14200       zone, Function::Handle(zone, from.Owner()), |  13446       zone, Function::Handle(zone, from.Owner()), | 
|  14201       String::Handle(zone, from.target_name()), |  13447       String::Handle(zone, from.target_name()), | 
|  14202       Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(), |  13448       Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(), | 
|  14203       from.NumArgsTested(), from.is_static_call())); |  13449       from.NumArgsTested(), from.is_static_call())); | 
|  14204   // Clone entry array. |  13450   // Clone entry array. | 
|  14205   const Array& from_array = Array::Handle(zone, from.ic_data()); |  13451   const Array& from_array = Array::Handle(zone, from.ic_data()); | 
|  14206   const intptr_t len = from_array.Length(); |  13452   const intptr_t len = from_array.Length(); | 
|  14207   const Array& cloned_array = Array::Handle(zone, Array::New(len, Heap::kOld)); |  13453   const Array& cloned_array = Array::Handle(zone, Array::New(len, Heap::kOld)); | 
|  14208   Object& obj = Object::Handle(zone); |  13454   Object& obj = Object::Handle(zone); | 
|  14209   for (intptr_t i = 0; i < len; i++) { |  13455   for (intptr_t i = 0; i < len; i++) { | 
|  14210     obj = from_array.At(i); |  13456     obj = from_array.At(i); | 
|  14211     cloned_array.SetAt(i, obj); |  13457     cloned_array.SetAt(i, obj); | 
|  14212   } |  13458   } | 
|  14213   result.set_ic_data_array(cloned_array); |  13459   result.set_ic_data_array(cloned_array); | 
|  14214   // Copy deoptimization reasons. |  13460   // Copy deoptimization reasons. | 
|  14215   result.SetDeoptReasons(from.DeoptReasons()); |  13461   result.SetDeoptReasons(from.DeoptReasons()); | 
|  14216   return result.raw(); |  13462   return result.raw(); | 
|  14217 } |  13463 } | 
|  14218  |  13464  | 
|  14219  |  | 
|  14220 Code::Comments& Code::Comments::New(intptr_t count) { |  13465 Code::Comments& Code::Comments::New(intptr_t count) { | 
|  14221   Comments* comments; |  13466   Comments* comments; | 
|  14222   if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { |  13467   if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) { | 
|  14223     // This should be caught before we reach here. |  13468     // This should be caught before we reach here. | 
|  14224     FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", |  13469     FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n", | 
|  14225            count); |  13470            count); | 
|  14226   } |  13471   } | 
|  14227   if (count == 0) { |  13472   if (count == 0) { | 
|  14228     comments = new Comments(Object::empty_array()); |  13473     comments = new Comments(Object::empty_array()); | 
|  14229   } else { |  13474   } else { | 
|  14230     const Array& data = |  13475     const Array& data = | 
|  14231         Array::Handle(Array::New(count * kNumberOfEntries, Heap::kOld)); |  13476         Array::Handle(Array::New(count * kNumberOfEntries, Heap::kOld)); | 
|  14232     comments = new Comments(data); |  13477     comments = new Comments(data); | 
|  14233   } |  13478   } | 
|  14234   return *comments; |  13479   return *comments; | 
|  14235 } |  13480 } | 
|  14236  |  13481  | 
|  14237  |  | 
|  14238 intptr_t Code::Comments::Length() const { |  13482 intptr_t Code::Comments::Length() const { | 
|  14239   if (comments_.IsNull()) { |  13483   if (comments_.IsNull()) { | 
|  14240     return 0; |  13484     return 0; | 
|  14241   } |  13485   } | 
|  14242   return comments_.Length() / kNumberOfEntries; |  13486   return comments_.Length() / kNumberOfEntries; | 
|  14243 } |  13487 } | 
|  14244  |  13488  | 
|  14245  |  | 
|  14246 intptr_t Code::Comments::PCOffsetAt(intptr_t idx) const { |  13489 intptr_t Code::Comments::PCOffsetAt(intptr_t idx) const { | 
|  14247   return Smi::Value( |  13490   return Smi::Value( | 
|  14248       Smi::RawCast(comments_.At(idx * kNumberOfEntries + kPCOffsetEntry))); |  13491       Smi::RawCast(comments_.At(idx * kNumberOfEntries + kPCOffsetEntry))); | 
|  14249 } |  13492 } | 
|  14250  |  13493  | 
|  14251  |  | 
|  14252 void Code::Comments::SetPCOffsetAt(intptr_t idx, intptr_t pc) { |  13494 void Code::Comments::SetPCOffsetAt(intptr_t idx, intptr_t pc) { | 
|  14253   comments_.SetAt(idx * kNumberOfEntries + kPCOffsetEntry, |  13495   comments_.SetAt(idx * kNumberOfEntries + kPCOffsetEntry, | 
|  14254                   Smi::Handle(Smi::New(pc))); |  13496                   Smi::Handle(Smi::New(pc))); | 
|  14255 } |  13497 } | 
|  14256  |  13498  | 
|  14257  |  | 
|  14258 RawString* Code::Comments::CommentAt(intptr_t idx) const { |  13499 RawString* Code::Comments::CommentAt(intptr_t idx) const { | 
|  14259   return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry)); |  13500   return String::RawCast(comments_.At(idx * kNumberOfEntries + kCommentEntry)); | 
|  14260 } |  13501 } | 
|  14261  |  13502  | 
|  14262  |  | 
|  14263 void Code::Comments::SetCommentAt(intptr_t idx, const String& comment) { |  13503 void Code::Comments::SetCommentAt(intptr_t idx, const String& comment) { | 
|  14264   comments_.SetAt(idx * kNumberOfEntries + kCommentEntry, comment); |  13504   comments_.SetAt(idx * kNumberOfEntries + kCommentEntry, comment); | 
|  14265 } |  13505 } | 
|  14266  |  13506  | 
|  14267  |  | 
|  14268 Code::Comments::Comments(const Array& comments) : comments_(comments) {} |  13507 Code::Comments::Comments(const Array& comments) : comments_(comments) {} | 
|  14269  |  13508  | 
|  14270  |  | 
|  14271 RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const { |  13509 RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const { | 
|  14272   const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors()); |  13510   const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors()); | 
|  14273   if (v.IsNull()) { |  13511   if (v.IsNull()) { | 
|  14274     ASSERT(!is_optimized()); |  13512     ASSERT(!is_optimized()); | 
|  14275     const Function& f = Function::Handle(function()); |  13513     const Function& f = Function::Handle(function()); | 
|  14276     ASSERT(!f.IsIrregexpFunction());  // Not yet implemented. |  13514     ASSERT(!f.IsIrregexpFunction());  // Not yet implemented. | 
|  14277     Compiler::ComputeLocalVarDescriptors(*this); |  13515     Compiler::ComputeLocalVarDescriptors(*this); | 
|  14278   } |  13516   } | 
|  14279   return var_descriptors(); |  13517   return var_descriptors(); | 
|  14280 } |  13518 } | 
|  14281  |  13519  | 
|  14282  |  | 
|  14283 void Code::set_state_bits(intptr_t bits) const { |  13520 void Code::set_state_bits(intptr_t bits) const { | 
|  14284   StoreNonPointer(&raw_ptr()->state_bits_, bits); |  13521   StoreNonPointer(&raw_ptr()->state_bits_, bits); | 
|  14285 } |  13522 } | 
|  14286  |  13523  | 
|  14287  |  | 
|  14288 void Code::set_is_optimized(bool value) const { |  13524 void Code::set_is_optimized(bool value) const { | 
|  14289   set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_)); |  13525   set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_)); | 
|  14290 } |  13526 } | 
|  14291  |  13527  | 
|  14292  |  | 
|  14293 void Code::set_is_alive(bool value) const { |  13528 void Code::set_is_alive(bool value) const { | 
|  14294   set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); |  13529   set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_)); | 
|  14295 } |  13530 } | 
|  14296  |  13531  | 
|  14297  |  | 
|  14298 void Code::set_stackmaps(const Array& maps) const { |  13532 void Code::set_stackmaps(const Array& maps) const { | 
|  14299   ASSERT(maps.IsOld()); |  13533   ASSERT(maps.IsOld()); | 
|  14300   StorePointer(&raw_ptr()->stackmaps_, maps.raw()); |  13534   StorePointer(&raw_ptr()->stackmaps_, maps.raw()); | 
|  14301   INC_STAT(Thread::Current(), total_code_size, |  13535   INC_STAT(Thread::Current(), total_code_size, | 
|  14302            maps.IsNull() ? 0 : maps.Length() * sizeof(uword)); |  13536            maps.IsNull() ? 0 : maps.Length() * sizeof(uword)); | 
|  14303 } |  13537 } | 
|  14304  |  13538  | 
|  14305  |  | 
|  14306 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) |  13539 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) | 
|  14307 void Code::set_variables(const Smi& smi) const { |  13540 void Code::set_variables(const Smi& smi) const { | 
|  14308   StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw()); |  13541   StorePointer(&raw_ptr()->catch_entry_.variables_, smi.raw()); | 
|  14309 } |  13542 } | 
|  14310 #else |  13543 #else | 
|  14311 void Code::set_catch_entry_state_maps(const TypedData& maps) const { |  13544 void Code::set_catch_entry_state_maps(const TypedData& maps) const { | 
|  14312   StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw()); |  13545   StorePointer(&raw_ptr()->catch_entry_.catch_entry_state_maps_, maps.raw()); | 
|  14313 } |  13546 } | 
|  14314 #endif |  13547 #endif | 
|  14315  |  13548  | 
|  14316  |  | 
|  14317 void Code::set_deopt_info_array(const Array& array) const { |  13549 void Code::set_deopt_info_array(const Array& array) const { | 
|  14318 #if defined(DART_PRECOMPILED_RUNTIME) |  13550 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14319   UNREACHABLE(); |  13551   UNREACHABLE(); | 
|  14320 #else |  13552 #else | 
|  14321   ASSERT(array.IsOld()); |  13553   ASSERT(array.IsOld()); | 
|  14322   StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); |  13554   StorePointer(&raw_ptr()->deopt_info_array_, array.raw()); | 
|  14323 #endif |  13555 #endif | 
|  14324 } |  13556 } | 
|  14325  |  13557  | 
|  14326  |  | 
|  14327 void Code::set_static_calls_target_table(const Array& value) const { |  13558 void Code::set_static_calls_target_table(const Array& value) const { | 
|  14328 #if defined(DART_PRECOMPILED_RUNTIME) |  13559 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14329   UNREACHABLE(); |  13560   UNREACHABLE(); | 
|  14330 #else |  13561 #else | 
|  14331   StorePointer(&raw_ptr()->static_calls_target_table_, value.raw()); |  13562   StorePointer(&raw_ptr()->static_calls_target_table_, value.raw()); | 
|  14332 #endif |  13563 #endif | 
|  14333 #if defined(DEBUG) |  13564 #if defined(DEBUG) | 
|  14334   // Check that the table is sorted by pc offsets. |  13565   // Check that the table is sorted by pc offsets. | 
|  14335   // FlowGraphCompiler::AddStaticCallTarget adds pc-offsets to the table while |  13566   // FlowGraphCompiler::AddStaticCallTarget adds pc-offsets to the table while | 
|  14336   // emitting assembly. This guarantees that every succeeding pc-offset is |  13567   // emitting assembly. This guarantees that every succeeding pc-offset is | 
|  14337   // larger than the previously added one. |  13568   // larger than the previously added one. | 
|  14338   for (intptr_t i = kSCallTableEntryLength; i < value.Length(); |  13569   for (intptr_t i = kSCallTableEntryLength; i < value.Length(); | 
|  14339        i += kSCallTableEntryLength) { |  13570        i += kSCallTableEntryLength) { | 
|  14340     ASSERT(value.At(i - kSCallTableEntryLength) < value.At(i)); |  13571     ASSERT(value.At(i - kSCallTableEntryLength) < value.At(i)); | 
|  14341   } |  13572   } | 
|  14342 #endif  // DEBUG |  13573 #endif  // DEBUG | 
|  14343 } |  13574 } | 
|  14344  |  13575  | 
|  14345  |  | 
|  14346 bool Code::HasBreakpoint() const { |  13576 bool Code::HasBreakpoint() const { | 
|  14347   if (!FLAG_support_debugger) { |  13577   if (!FLAG_support_debugger) { | 
|  14348     return false; |  13578     return false; | 
|  14349   } |  13579   } | 
|  14350   return Isolate::Current()->debugger()->HasBreakpoint(*this); |  13580   return Isolate::Current()->debugger()->HasBreakpoint(*this); | 
|  14351 } |  13581 } | 
|  14352  |  13582  | 
|  14353  |  | 
|  14354 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, |  13583 RawTypedData* Code::GetDeoptInfoAtPc(uword pc, | 
|  14355                                      ICData::DeoptReasonId* deopt_reason, |  13584                                      ICData::DeoptReasonId* deopt_reason, | 
|  14356                                      uint32_t* deopt_flags) const { |  13585                                      uint32_t* deopt_flags) const { | 
|  14357 #if defined(DART_PRECOMPILED_RUNTIME) |  13586 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14358   ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); |  13587   ASSERT(Dart::vm_snapshot_kind() == Snapshot::kFullAOT); | 
|  14359   return TypedData::null(); |  13588   return TypedData::null(); | 
|  14360 #else |  13589 #else | 
|  14361   ASSERT(is_optimized()); |  13590   ASSERT(is_optimized()); | 
|  14362   const Instructions& instrs = Instructions::Handle(instructions()); |  13591   const Instructions& instrs = Instructions::Handle(instructions()); | 
|  14363   uword code_entry = instrs.PayloadStart(); |  13592   uword code_entry = instrs.PayloadStart(); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  14378       *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); |  13607       *deopt_reason = DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 
|  14379       *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); |  13608       *deopt_flags = DeoptTable::FlagsField::decode(reason_and_flags.Value()); | 
|  14380       return info.raw(); |  13609       return info.raw(); | 
|  14381     } |  13610     } | 
|  14382   } |  13611   } | 
|  14383   *deopt_reason = ICData::kDeoptUnknown; |  13612   *deopt_reason = ICData::kDeoptUnknown; | 
|  14384   return TypedData::null(); |  13613   return TypedData::null(); | 
|  14385 #endif  // defined(DART_PRECOMPILED_RUNTIME) |  13614 #endif  // defined(DART_PRECOMPILED_RUNTIME) | 
|  14386 } |  13615 } | 
|  14387  |  13616  | 
|  14388  |  | 
|  14389 intptr_t Code::BinarySearchInSCallTable(uword pc) const { |  13617 intptr_t Code::BinarySearchInSCallTable(uword pc) const { | 
|  14390 #if defined(DART_PRECOMPILED_RUNTIME) |  13618 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14391   UNREACHABLE(); |  13619   UNREACHABLE(); | 
|  14392 #else |  13620 #else | 
|  14393   NoSafepointScope no_safepoint; |  13621   NoSafepointScope no_safepoint; | 
|  14394   const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); |  13622   const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_); | 
|  14395   RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart())); |  13623   RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart())); | 
|  14396   intptr_t imin = 0; |  13624   intptr_t imin = 0; | 
|  14397   intptr_t imax = table.Length() / kSCallTableEntryLength; |  13625   intptr_t imax = table.Length() / kSCallTableEntryLength; | 
|  14398   while (imax >= imin) { |  13626   while (imax >= imin) { | 
|  14399     const intptr_t imid = ((imax - imin) / 2) + imin; |  13627     const intptr_t imid = ((imax - imin) / 2) + imin; | 
|  14400     const intptr_t real_index = imid * kSCallTableEntryLength; |  13628     const intptr_t real_index = imid * kSCallTableEntryLength; | 
|  14401     RawObject* key_in_table = table.At(real_index); |  13629     RawObject* key_in_table = table.At(real_index); | 
|  14402     if (key_in_table < key) { |  13630     if (key_in_table < key) { | 
|  14403       imin = imid + 1; |  13631       imin = imid + 1; | 
|  14404     } else if (key_in_table > key) { |  13632     } else if (key_in_table > key) { | 
|  14405       imax = imid - 1; |  13633       imax = imid - 1; | 
|  14406     } else { |  13634     } else { | 
|  14407       return real_index; |  13635       return real_index; | 
|  14408     } |  13636     } | 
|  14409   } |  13637   } | 
|  14410 #endif |  13638 #endif | 
|  14411   return -1; |  13639   return -1; | 
|  14412 } |  13640 } | 
|  14413  |  13641  | 
|  14414  |  | 
|  14415 RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const { |  13642 RawFunction* Code::GetStaticCallTargetFunctionAt(uword pc) const { | 
|  14416 #if defined(DART_PRECOMPILED_RUNTIME) |  13643 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14417   UNREACHABLE(); |  13644   UNREACHABLE(); | 
|  14418   return Function::null(); |  13645   return Function::null(); | 
|  14419 #else |  13646 #else | 
|  14420   const intptr_t i = BinarySearchInSCallTable(pc); |  13647   const intptr_t i = BinarySearchInSCallTable(pc); | 
|  14421   if (i < 0) { |  13648   if (i < 0) { | 
|  14422     return Function::null(); |  13649     return Function::null(); | 
|  14423   } |  13650   } | 
|  14424   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |  13651   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 
|  14425   Function& function = Function::Handle(); |  13652   Function& function = Function::Handle(); | 
|  14426   function ^= array.At(i + kSCallTableFunctionEntry); |  13653   function ^= array.At(i + kSCallTableFunctionEntry); | 
|  14427   return function.raw(); |  13654   return function.raw(); | 
|  14428 #endif |  13655 #endif | 
|  14429 } |  13656 } | 
|  14430  |  13657  | 
|  14431  |  | 
|  14432 RawCode* Code::GetStaticCallTargetCodeAt(uword pc) const { |  13658 RawCode* Code::GetStaticCallTargetCodeAt(uword pc) const { | 
|  14433 #if defined(DART_PRECOMPILED_RUNTIME) |  13659 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14434   UNREACHABLE(); |  13660   UNREACHABLE(); | 
|  14435   return Code::null(); |  13661   return Code::null(); | 
|  14436 #else |  13662 #else | 
|  14437   const intptr_t i = BinarySearchInSCallTable(pc); |  13663   const intptr_t i = BinarySearchInSCallTable(pc); | 
|  14438   if (i < 0) { |  13664   if (i < 0) { | 
|  14439     return Code::null(); |  13665     return Code::null(); | 
|  14440   } |  13666   } | 
|  14441   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |  13667   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 
|  14442   Code& code = Code::Handle(); |  13668   Code& code = Code::Handle(); | 
|  14443   code ^= array.At(i + kSCallTableCodeEntry); |  13669   code ^= array.At(i + kSCallTableCodeEntry); | 
|  14444   return code.raw(); |  13670   return code.raw(); | 
|  14445 #endif |  13671 #endif | 
|  14446 } |  13672 } | 
|  14447  |  13673  | 
|  14448  |  | 
|  14449 void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const { |  13674 void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const { | 
|  14450 #if defined(DART_PRECOMPILED_RUNTIME) |  13675 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14451   UNREACHABLE(); |  13676   UNREACHABLE(); | 
|  14452 #else |  13677 #else | 
|  14453   const intptr_t i = BinarySearchInSCallTable(pc); |  13678   const intptr_t i = BinarySearchInSCallTable(pc); | 
|  14454   ASSERT(i >= 0); |  13679   ASSERT(i >= 0); | 
|  14455   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |  13680   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 
|  14456   ASSERT(code.IsNull() || |  13681   ASSERT(code.IsNull() || | 
|  14457          (code.function() == array.At(i + kSCallTableFunctionEntry))); |  13682          (code.function() == array.At(i + kSCallTableFunctionEntry))); | 
|  14458   array.SetAt(i + kSCallTableCodeEntry, code); |  13683   array.SetAt(i + kSCallTableCodeEntry, code); | 
|  14459 #endif |  13684 #endif | 
|  14460 } |  13685 } | 
|  14461  |  13686  | 
|  14462  |  | 
|  14463 void Code::SetStubCallTargetCodeAt(uword pc, const Code& code) const { |  13687 void Code::SetStubCallTargetCodeAt(uword pc, const Code& code) const { | 
|  14464 #if defined(DART_PRECOMPILED_RUNTIME) |  13688 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14465   UNREACHABLE(); |  13689   UNREACHABLE(); | 
|  14466 #else |  13690 #else | 
|  14467   const intptr_t i = BinarySearchInSCallTable(pc); |  13691   const intptr_t i = BinarySearchInSCallTable(pc); | 
|  14468   ASSERT(i >= 0); |  13692   ASSERT(i >= 0); | 
|  14469   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); |  13693   const Array& array = Array::Handle(raw_ptr()->static_calls_target_table_); | 
|  14470 #if defined(DEBUG) |  13694 #if defined(DEBUG) | 
|  14471   if (array.At(i + kSCallTableFunctionEntry) == Function::null()) { |  13695   if (array.At(i + kSCallTableFunctionEntry) == Function::null()) { | 
|  14472     ASSERT(!code.IsNull() && Object::Handle(code.owner()).IsClass()); |  13696     ASSERT(!code.IsNull() && Object::Handle(code.owner()).IsClass()); | 
|  14473   } else { |  13697   } else { | 
|  14474     ASSERT(code.IsNull() || |  13698     ASSERT(code.IsNull() || | 
|  14475            (code.function() == array.At(i + kSCallTableFunctionEntry))); |  13699            (code.function() == array.At(i + kSCallTableFunctionEntry))); | 
|  14476   } |  13700   } | 
|  14477 #endif |  13701 #endif | 
|  14478   array.SetAt(i + kSCallTableCodeEntry, code); |  13702   array.SetAt(i + kSCallTableCodeEntry, code); | 
|  14479 #endif |  13703 #endif | 
|  14480 } |  13704 } | 
|  14481  |  13705  | 
|  14482  |  | 
|  14483 void Code::Disassemble(DisassemblyFormatter* formatter) const { |  13706 void Code::Disassemble(DisassemblyFormatter* formatter) const { | 
|  14484 #ifndef PRODUCT |  13707 #ifndef PRODUCT | 
|  14485   if (!FLAG_support_disassembler) { |  13708   if (!FLAG_support_disassembler) { | 
|  14486     return; |  13709     return; | 
|  14487   } |  13710   } | 
|  14488   const Instructions& instr = Instructions::Handle(instructions()); |  13711   const Instructions& instr = Instructions::Handle(instructions()); | 
|  14489   uword start = instr.PayloadStart(); |  13712   uword start = instr.PayloadStart(); | 
|  14490   if (formatter == NULL) { |  13713   if (formatter == NULL) { | 
|  14491     Disassembler::Disassemble(start, start + instr.Size(), *this); |  13714     Disassembler::Disassemble(start, start + instr.Size(), *this); | 
|  14492   } else { |  13715   } else { | 
|  14493     Disassembler::Disassemble(start, start + instr.Size(), formatter, *this); |  13716     Disassembler::Disassemble(start, start + instr.Size(), formatter, *this); | 
|  14494   } |  13717   } | 
|  14495 #endif |  13718 #endif | 
|  14496 } |  13719 } | 
|  14497  |  13720  | 
|  14498  |  | 
|  14499 const Code::Comments& Code::comments() const { |  13721 const Code::Comments& Code::comments() const { | 
|  14500 #if defined(DART_PRECOMPILED_RUNTIME) |  13722 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14501   Comments* comments = new Code::Comments(Array::Handle()); |  13723   Comments* comments = new Code::Comments(Array::Handle()); | 
|  14502 #else |  13724 #else | 
|  14503   Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); |  13725   Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); | 
|  14504 #endif |  13726 #endif | 
|  14505   return *comments; |  13727   return *comments; | 
|  14506 } |  13728 } | 
|  14507  |  13729  | 
|  14508  |  | 
|  14509 void Code::set_comments(const Code::Comments& comments) const { |  13730 void Code::set_comments(const Code::Comments& comments) const { | 
|  14510 #if defined(DART_PRECOMPILED_RUNTIME) |  13731 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14511   UNREACHABLE(); |  13732   UNREACHABLE(); | 
|  14512 #else |  13733 #else | 
|  14513   ASSERT(comments.comments_.IsOld()); |  13734   ASSERT(comments.comments_.IsOld()); | 
|  14514   StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); |  13735   StorePointer(&raw_ptr()->comments_, comments.comments_.raw()); | 
|  14515 #endif |  13736 #endif | 
|  14516 } |  13737 } | 
|  14517  |  13738  | 
|  14518  |  | 
|  14519 void Code::SetPrologueOffset(intptr_t offset) const { |  13739 void Code::SetPrologueOffset(intptr_t offset) const { | 
|  14520 #if defined(DART_PRECOMPILED_RUNTIME) |  13740 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14521   UNREACHABLE(); |  13741   UNREACHABLE(); | 
|  14522 #else |  13742 #else | 
|  14523   ASSERT(offset >= 0); |  13743   ASSERT(offset >= 0); | 
|  14524   StoreSmi( |  13744   StoreSmi( | 
|  14525       reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_), |  13745       reinterpret_cast<RawSmi* const*>(&raw_ptr()->return_address_metadata_), | 
|  14526       Smi::New(offset)); |  13746       Smi::New(offset)); | 
|  14527 #endif |  13747 #endif | 
|  14528 } |  13748 } | 
|  14529  |  13749  | 
|  14530  |  | 
|  14531 intptr_t Code::GetPrologueOffset() const { |  13750 intptr_t Code::GetPrologueOffset() const { | 
|  14532 #if defined(DART_PRECOMPILED_RUNTIME) |  13751 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14533   return -1; |  13752   return -1; | 
|  14534 #else |  13753 #else | 
|  14535   const Object& object = Object::Handle(raw_ptr()->return_address_metadata_); |  13754   const Object& object = Object::Handle(raw_ptr()->return_address_metadata_); | 
|  14536   // In the future we may put something other than a smi in |  13755   // In the future we may put something other than a smi in | 
|  14537   // |return_address_metadata_|. |  13756   // |return_address_metadata_|. | 
|  14538   if (object.IsNull() || !object.IsSmi()) { |  13757   if (object.IsNull() || !object.IsSmi()) { | 
|  14539     return -1; |  13758     return -1; | 
|  14540   } |  13759   } | 
|  14541   return Smi::Cast(object).Value(); |  13760   return Smi::Cast(object).Value(); | 
|  14542 #endif |  13761 #endif | 
|  14543 } |  13762 } | 
|  14544  |  13763  | 
|  14545  |  | 
|  14546 RawArray* Code::inlined_id_to_function() const { |  13764 RawArray* Code::inlined_id_to_function() const { | 
|  14547   return raw_ptr()->inlined_id_to_function_; |  13765   return raw_ptr()->inlined_id_to_function_; | 
|  14548 } |  13766 } | 
|  14549  |  13767  | 
|  14550  |  | 
|  14551 void Code::set_inlined_id_to_function(const Array& value) const { |  13768 void Code::set_inlined_id_to_function(const Array& value) const { | 
|  14552   ASSERT(value.IsOld()); |  13769   ASSERT(value.IsOld()); | 
|  14553   StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); |  13770   StorePointer(&raw_ptr()->inlined_id_to_function_, value.raw()); | 
|  14554 } |  13771 } | 
|  14555  |  13772  | 
|  14556  |  | 
|  14557 RawCode* Code::New(intptr_t pointer_offsets_length) { |  13773 RawCode* Code::New(intptr_t pointer_offsets_length) { | 
|  14558   if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { |  13774   if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) { | 
|  14559     // This should be caught before we reach here. |  13775     // This should be caught before we reach here. | 
|  14560     FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", |  13776     FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n", | 
|  14561            pointer_offsets_length); |  13777            pointer_offsets_length); | 
|  14562   } |  13778   } | 
|  14563   ASSERT(Object::code_class() != Class::null()); |  13779   ASSERT(Object::code_class() != Class::null()); | 
|  14564   Code& result = Code::Handle(); |  13780   Code& result = Code::Handle(); | 
|  14565   { |  13781   { | 
|  14566     uword size = Code::InstanceSize(pointer_offsets_length); |  13782     uword size = Code::InstanceSize(pointer_offsets_length); | 
|  14567     RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); |  13783     RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld); | 
|  14568     NoSafepointScope no_safepoint; |  13784     NoSafepointScope no_safepoint; | 
|  14569     result ^= raw; |  13785     result ^= raw; | 
|  14570     result.set_pointer_offsets_length(pointer_offsets_length); |  13786     result.set_pointer_offsets_length(pointer_offsets_length); | 
|  14571     result.set_is_optimized(false); |  13787     result.set_is_optimized(false); | 
|  14572     result.set_is_alive(false); |  13788     result.set_is_alive(false); | 
|  14573     result.set_comments(Comments::New(0)); |  13789     result.set_comments(Comments::New(0)); | 
|  14574     result.set_compile_timestamp(0); |  13790     result.set_compile_timestamp(0); | 
|  14575     result.set_pc_descriptors(Object::empty_descriptors()); |  13791     result.set_pc_descriptors(Object::empty_descriptors()); | 
|  14576   } |  13792   } | 
|  14577   return result.raw(); |  13793   return result.raw(); | 
|  14578 } |  13794 } | 
|  14579  |  13795  | 
|  14580  |  | 
|  14581 RawCode* Code::FinalizeCode(const char* name, |  13796 RawCode* Code::FinalizeCode(const char* name, | 
|  14582                             Assembler* assembler, |  13797                             Assembler* assembler, | 
|  14583                             bool optimized) { |  13798                             bool optimized) { | 
|  14584   Isolate* isolate = Isolate::Current(); |  13799   Isolate* isolate = Isolate::Current(); | 
|  14585   if (!isolate->compilation_allowed()) { |  13800   if (!isolate->compilation_allowed()) { | 
|  14586     FATAL1("Precompilation missed code %s\n", name); |  13801     FATAL1("Precompilation missed code %s\n", name); | 
|  14587   } |  13802   } | 
|  14588  |  13803  | 
|  14589   ASSERT(assembler != NULL); |  13804   ASSERT(assembler != NULL); | 
|  14590   const ObjectPool& object_pool = |  13805   const ObjectPool& object_pool = | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  14658   } else { |  13873   } else { | 
|  14659     // No prologue was ever entered, optimistically assume nothing was ever |  13874     // No prologue was ever entered, optimistically assume nothing was ever | 
|  14660     // pushed onto the stack. |  13875     // pushed onto the stack. | 
|  14661     code.SetPrologueOffset(assembler->CodeSize()); |  13876     code.SetPrologueOffset(assembler->CodeSize()); | 
|  14662   } |  13877   } | 
|  14663   INC_STAT(Thread::Current(), total_code_size, |  13878   INC_STAT(Thread::Current(), total_code_size, | 
|  14664            code.comments().comments_.Length()); |  13879            code.comments().comments_.Length()); | 
|  14665   return code.raw(); |  13880   return code.raw(); | 
|  14666 } |  13881 } | 
|  14667  |  13882  | 
|  14668  |  | 
|  14669 RawCode* Code::FinalizeCode(const Function& function, |  13883 RawCode* Code::FinalizeCode(const Function& function, | 
|  14670                             Assembler* assembler, |  13884                             Assembler* assembler, | 
|  14671                             bool optimized) { |  13885                             bool optimized) { | 
|  14672 // Calling ToLibNamePrefixedQualifiedCString is very expensive, |  13886 // Calling ToLibNamePrefixedQualifiedCString is very expensive, | 
|  14673 // try to avoid it. |  13887 // try to avoid it. | 
|  14674 #ifndef PRODUCT |  13888 #ifndef PRODUCT | 
|  14675   if (CodeObservers::AreActive()) { |  13889   if (CodeObservers::AreActive()) { | 
|  14676     return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), assembler, |  13890     return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(), assembler, | 
|  14677                         optimized); |  13891                         optimized); | 
|  14678   } |  13892   } | 
|  14679 #endif  // !PRODUCT |  13893 #endif  // !PRODUCT | 
|  14680   return FinalizeCode("", assembler, optimized); |  13894   return FinalizeCode("", assembler, optimized); | 
|  14681 } |  13895 } | 
|  14682  |  13896  | 
|  14683  |  | 
|  14684 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { |  13897 bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { | 
|  14685   return RawCode::ContainsPC(raw_obj, pc_); |  13898   return RawCode::ContainsPC(raw_obj, pc_); | 
|  14686 } |  13899 } | 
|  14687  |  13900  | 
|  14688  |  | 
|  14689 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { |  13901 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) { | 
|  14690   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate())); |  13902   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate())); | 
|  14691   if (isolate->heap() == NULL) { |  13903   if (isolate->heap() == NULL) { | 
|  14692     return Code::null(); |  13904     return Code::null(); | 
|  14693   } |  13905   } | 
|  14694   NoSafepointScope no_safepoint; |  13906   NoSafepointScope no_safepoint; | 
|  14695   SlowFindRawCodeVisitor visitor(pc); |  13907   SlowFindRawCodeVisitor visitor(pc); | 
|  14696   RawObject* needle = isolate->heap()->FindOldObject(&visitor); |  13908   RawObject* needle = isolate->heap()->FindOldObject(&visitor); | 
|  14697   if (needle != Code::null()) { |  13909   if (needle != Code::null()) { | 
|  14698     return static_cast<RawCode*>(needle); |  13910     return static_cast<RawCode*>(needle); | 
|  14699   } |  13911   } | 
|  14700   return Code::null(); |  13912   return Code::null(); | 
|  14701 } |  13913 } | 
|  14702  |  13914  | 
|  14703  |  | 
|  14704 RawCode* Code::LookupCode(uword pc) { |  13915 RawCode* Code::LookupCode(uword pc) { | 
|  14705   return LookupCodeInIsolate(Isolate::Current(), pc); |  13916   return LookupCodeInIsolate(Isolate::Current(), pc); | 
|  14706 } |  13917 } | 
|  14707  |  13918  | 
|  14708  |  | 
|  14709 RawCode* Code::LookupCodeInVmIsolate(uword pc) { |  13919 RawCode* Code::LookupCodeInVmIsolate(uword pc) { | 
|  14710   return LookupCodeInIsolate(Dart::vm_isolate(), pc); |  13920   return LookupCodeInIsolate(Dart::vm_isolate(), pc); | 
|  14711 } |  13921 } | 
|  14712  |  13922  | 
|  14713  |  | 
|  14714 // Given a pc and a timestamp, lookup the code. |  13923 // Given a pc and a timestamp, lookup the code. | 
|  14715 RawCode* Code::FindCode(uword pc, int64_t timestamp) { |  13924 RawCode* Code::FindCode(uword pc, int64_t timestamp) { | 
|  14716   Code& code = Code::Handle(Code::LookupCode(pc)); |  13925   Code& code = Code::Handle(Code::LookupCode(pc)); | 
|  14717   if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |  13926   if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 
|  14718       (code.PayloadStart() == pc)) { |  13927       (code.PayloadStart() == pc)) { | 
|  14719     // Found code in isolate. |  13928     // Found code in isolate. | 
|  14720     return code.raw(); |  13929     return code.raw(); | 
|  14721   } |  13930   } | 
|  14722   code ^= Code::LookupCodeInVmIsolate(pc); |  13931   code ^= Code::LookupCodeInVmIsolate(pc); | 
|  14723   if (!code.IsNull() && (code.compile_timestamp() == timestamp) && |  13932   if (!code.IsNull() && (code.compile_timestamp() == timestamp) && | 
|  14724       (code.PayloadStart() == pc)) { |  13933       (code.PayloadStart() == pc)) { | 
|  14725     // Found code in VM isolate. |  13934     // Found code in VM isolate. | 
|  14726     return code.raw(); |  13935     return code.raw(); | 
|  14727   } |  13936   } | 
|  14728   return Code::null(); |  13937   return Code::null(); | 
|  14729 } |  13938 } | 
|  14730  |  13939  | 
|  14731  |  | 
|  14732 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { |  13940 TokenPosition Code::GetTokenIndexOfPC(uword pc) const { | 
|  14733   uword pc_offset = pc - PayloadStart(); |  13941   uword pc_offset = pc - PayloadStart(); | 
|  14734   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |  13942   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 
|  14735   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); |  13943   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind); | 
|  14736   while (iter.MoveNext()) { |  13944   while (iter.MoveNext()) { | 
|  14737     if (iter.PcOffset() == pc_offset) { |  13945     if (iter.PcOffset() == pc_offset) { | 
|  14738       return iter.TokenPos(); |  13946       return iter.TokenPos(); | 
|  14739     } |  13947     } | 
|  14740   } |  13948   } | 
|  14741   return TokenPosition::kNoSource; |  13949   return TokenPosition::kNoSource; | 
|  14742 } |  13950 } | 
|  14743  |  13951  | 
|  14744  |  | 
|  14745 uword Code::GetPcForDeoptId(intptr_t deopt_id, |  13952 uword Code::GetPcForDeoptId(intptr_t deopt_id, | 
|  14746                             RawPcDescriptors::Kind kind) const { |  13953                             RawPcDescriptors::Kind kind) const { | 
|  14747   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |  13954   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 
|  14748   PcDescriptors::Iterator iter(descriptors, kind); |  13955   PcDescriptors::Iterator iter(descriptors, kind); | 
|  14749   while (iter.MoveNext()) { |  13956   while (iter.MoveNext()) { | 
|  14750     if (iter.DeoptId() == deopt_id) { |  13957     if (iter.DeoptId() == deopt_id) { | 
|  14751       uword pc_offset = iter.PcOffset(); |  13958       uword pc_offset = iter.PcOffset(); | 
|  14752       uword pc = PayloadStart() + pc_offset; |  13959       uword pc = PayloadStart() + pc_offset; | 
|  14753       ASSERT(ContainsInstructionAt(pc)); |  13960       ASSERT(ContainsInstructionAt(pc)); | 
|  14754       return pc; |  13961       return pc; | 
|  14755     } |  13962     } | 
|  14756   } |  13963   } | 
|  14757   return 0; |  13964   return 0; | 
|  14758 } |  13965 } | 
|  14759  |  13966  | 
|  14760  |  | 
|  14761 intptr_t Code::GetDeoptIdForOsr(uword pc) const { |  13967 intptr_t Code::GetDeoptIdForOsr(uword pc) const { | 
|  14762   uword pc_offset = pc - PayloadStart(); |  13968   uword pc_offset = pc - PayloadStart(); | 
|  14763   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |  13969   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 
|  14764   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); |  13970   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry); | 
|  14765   while (iter.MoveNext()) { |  13971   while (iter.MoveNext()) { | 
|  14766     if (iter.PcOffset() == pc_offset) { |  13972     if (iter.PcOffset() == pc_offset) { | 
|  14767       return iter.DeoptId(); |  13973       return iter.DeoptId(); | 
|  14768     } |  13974     } | 
|  14769   } |  13975   } | 
|  14770   return Thread::kNoDeoptId; |  13976   return Thread::kNoDeoptId; | 
|  14771 } |  13977 } | 
|  14772  |  13978  | 
|  14773  |  | 
|  14774 const char* Code::ToCString() const { |  13979 const char* Code::ToCString() const { | 
|  14775   return Thread::Current()->zone()->PrintToString("Code(%s)", QualifiedName()); |  13980   return Thread::Current()->zone()->PrintToString("Code(%s)", QualifiedName()); | 
|  14776 } |  13981 } | 
|  14777  |  13982  | 
|  14778  |  | 
|  14779 const char* Code::Name() const { |  13983 const char* Code::Name() const { | 
|  14780   Zone* zone = Thread::Current()->zone(); |  13984   Zone* zone = Thread::Current()->zone(); | 
|  14781   const Object& obj = Object::Handle(zone, owner()); |  13985   const Object& obj = Object::Handle(zone, owner()); | 
|  14782   if (obj.IsNull()) { |  13986   if (obj.IsNull()) { | 
|  14783     // Regular stub. |  13987     // Regular stub. | 
|  14784     const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); |  13988     const char* name = StubCode::NameOfStub(UncheckedEntryPoint()); | 
|  14785     if (name == NULL) { |  13989     if (name == NULL) { | 
|  14786       ASSERT(!StubCode::HasBeenInitialized()); |  13990       ASSERT(!StubCode::HasBeenInitialized()); | 
|  14787       return zone->PrintToString("[this stub]");  // Not yet recorded. |  13991       return zone->PrintToString("[this stub]");  // Not yet recorded. | 
|  14788     } |  13992     } | 
|  14789     return zone->PrintToString("[Stub] %s", name); |  13993     return zone->PrintToString("[Stub] %s", name); | 
|  14790   } else if (obj.IsClass()) { |  13994   } else if (obj.IsClass()) { | 
|  14791     // Allocation stub. |  13995     // Allocation stub. | 
|  14792     String& cls_name = String::Handle(zone, Class::Cast(obj).ScrubbedName()); |  13996     String& cls_name = String::Handle(zone, Class::Cast(obj).ScrubbedName()); | 
|  14793     ASSERT(!cls_name.IsNull()); |  13997     ASSERT(!cls_name.IsNull()); | 
|  14794     return zone->PrintToString("[Stub] Allocate %s", cls_name.ToCString()); |  13998     return zone->PrintToString("[Stub] Allocate %s", cls_name.ToCString()); | 
|  14795   } else { |  13999   } else { | 
|  14796     ASSERT(obj.IsFunction()); |  14000     ASSERT(obj.IsFunction()); | 
|  14797     // Dart function. |  14001     // Dart function. | 
|  14798     const char* opt = is_optimized() ? "*" : ""; |  14002     const char* opt = is_optimized() ? "*" : ""; | 
|  14799     const char* function_name = |  14003     const char* function_name = | 
|  14800         String::Handle(zone, Function::Cast(obj).UserVisibleName()).ToCString(); |  14004         String::Handle(zone, Function::Cast(obj).UserVisibleName()).ToCString(); | 
|  14801     return zone->PrintToString("%s%s", opt, function_name); |  14005     return zone->PrintToString("%s%s", opt, function_name); | 
|  14802   } |  14006   } | 
|  14803 } |  14007 } | 
|  14804  |  14008  | 
|  14805  |  | 
|  14806 const char* Code::QualifiedName() const { |  14009 const char* Code::QualifiedName() const { | 
|  14807   Zone* zone = Thread::Current()->zone(); |  14010   Zone* zone = Thread::Current()->zone(); | 
|  14808   const Object& obj = Object::Handle(zone, owner()); |  14011   const Object& obj = Object::Handle(zone, owner()); | 
|  14809   if (obj.IsFunction()) { |  14012   if (obj.IsFunction()) { | 
|  14810     const char* opt = is_optimized() ? "*" : ""; |  14013     const char* opt = is_optimized() ? "*" : ""; | 
|  14811     const char* function_name = |  14014     const char* function_name = | 
|  14812         String::Handle(zone, Function::Cast(obj).QualifiedScrubbedName()) |  14015         String::Handle(zone, Function::Cast(obj).QualifiedScrubbedName()) | 
|  14813             .ToCString(); |  14016             .ToCString(); | 
|  14814     return zone->PrintToString("%s%s", opt, function_name); |  14017     return zone->PrintToString("%s%s", opt, function_name); | 
|  14815   } |  14018   } | 
|  14816   return Name(); |  14019   return Name(); | 
|  14817 } |  14020 } | 
|  14818  |  14021  | 
|  14819  |  | 
|  14820 bool Code::IsAllocationStubCode() const { |  14022 bool Code::IsAllocationStubCode() const { | 
|  14821   const Object& obj = Object::Handle(owner()); |  14023   const Object& obj = Object::Handle(owner()); | 
|  14822   return obj.IsClass(); |  14024   return obj.IsClass(); | 
|  14823 } |  14025 } | 
|  14824  |  14026  | 
|  14825  |  | 
|  14826 bool Code::IsStubCode() const { |  14027 bool Code::IsStubCode() const { | 
|  14827   const Object& obj = Object::Handle(owner()); |  14028   const Object& obj = Object::Handle(owner()); | 
|  14828   return obj.IsNull(); |  14029   return obj.IsNull(); | 
|  14829 } |  14030 } | 
|  14830  |  14031  | 
|  14831  |  | 
|  14832 bool Code::IsFunctionCode() const { |  14032 bool Code::IsFunctionCode() const { | 
|  14833   const Object& obj = Object::Handle(owner()); |  14033   const Object& obj = Object::Handle(owner()); | 
|  14834   return obj.IsFunction(); |  14034   return obj.IsFunction(); | 
|  14835 } |  14035 } | 
|  14836  |  14036  | 
|  14837  |  | 
|  14838 void Code::DisableDartCode() const { |  14037 void Code::DisableDartCode() const { | 
|  14839   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); |  14038   DEBUG_ASSERT(IsMutatorOrAtSafepoint()); | 
|  14840   ASSERT(IsFunctionCode()); |  14039   ASSERT(IsFunctionCode()); | 
|  14841   ASSERT(instructions() == active_instructions()); |  14040   ASSERT(instructions() == active_instructions()); | 
|  14842   const Code& new_code = |  14041   const Code& new_code = | 
|  14843       Code::Handle(StubCode::FixCallersTarget_entry()->code()); |  14042       Code::Handle(StubCode::FixCallersTarget_entry()->code()); | 
|  14844   SetActiveInstructions(Instructions::Handle(new_code.instructions())); |  14043   SetActiveInstructions(Instructions::Handle(new_code.instructions())); | 
|  14845 } |  14044 } | 
|  14846  |  14045  | 
|  14847  |  | 
|  14848 void Code::DisableStubCode() const { |  14046 void Code::DisableStubCode() const { | 
|  14849 #if !defined(TARGET_ARCH_DBC) |  14047 #if !defined(TARGET_ARCH_DBC) | 
|  14850   ASSERT(Thread::Current()->IsMutatorThread()); |  14048   ASSERT(Thread::Current()->IsMutatorThread()); | 
|  14851   ASSERT(IsAllocationStubCode()); |  14049   ASSERT(IsAllocationStubCode()); | 
|  14852   ASSERT(instructions() == active_instructions()); |  14050   ASSERT(instructions() == active_instructions()); | 
|  14853   const Code& new_code = |  14051   const Code& new_code = | 
|  14854       Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); |  14052       Code::Handle(StubCode::FixAllocationStubTarget_entry()->code()); | 
|  14855   SetActiveInstructions(Instructions::Handle(new_code.instructions())); |  14053   SetActiveInstructions(Instructions::Handle(new_code.instructions())); | 
|  14856 #else |  14054 #else | 
|  14857   // DBC does not use allocation stubs. |  14055   // DBC does not use allocation stubs. | 
|  14858   UNIMPLEMENTED(); |  14056   UNIMPLEMENTED(); | 
|  14859 #endif  // !defined(TARGET_ARCH_DBC) |  14057 #endif  // !defined(TARGET_ARCH_DBC) | 
|  14860 } |  14058 } | 
|  14861  |  14059  | 
|  14862  |  | 
|  14863 void Code::SetActiveInstructions(const Instructions& instructions) const { |  14060 void Code::SetActiveInstructions(const Instructions& instructions) const { | 
|  14864 #if defined(DART_PRECOMPILED_RUNTIME) |  14061 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14865   UNREACHABLE(); |  14062   UNREACHABLE(); | 
|  14866 #else |  14063 #else | 
|  14867   DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); |  14064   DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive()); | 
|  14868   // RawInstructions are never allocated in New space and hence a |  14065   // RawInstructions are never allocated in New space and hence a | 
|  14869   // store buffer update is not needed here. |  14066   // store buffer update is not needed here. | 
|  14870   StorePointer(&raw_ptr()->active_instructions_, instructions.raw()); |  14067   StorePointer(&raw_ptr()->active_instructions_, instructions.raw()); | 
|  14871   StoreNonPointer(&raw_ptr()->entry_point_, |  14068   StoreNonPointer(&raw_ptr()->entry_point_, | 
|  14872                   Instructions::UncheckedEntryPoint(instructions.raw())); |  14069                   Instructions::UncheckedEntryPoint(instructions.raw())); | 
|  14873   StoreNonPointer(&raw_ptr()->checked_entry_point_, |  14070   StoreNonPointer(&raw_ptr()->checked_entry_point_, | 
|  14874                   Instructions::CheckedEntryPoint(instructions.raw())); |  14071                   Instructions::CheckedEntryPoint(instructions.raw())); | 
|  14875 #endif |  14072 #endif | 
|  14876 } |  14073 } | 
|  14877  |  14074  | 
|  14878  |  | 
|  14879 RawStackMap* Code::GetStackMap(uint32_t pc_offset, |  14075 RawStackMap* Code::GetStackMap(uint32_t pc_offset, | 
|  14880                                Array* maps, |  14076                                Array* maps, | 
|  14881                                StackMap* map) const { |  14077                                StackMap* map) const { | 
|  14882   // This code is used during iterating frames during a GC and hence it |  14078   // This code is used during iterating frames during a GC and hence it | 
|  14883   // should not in turn start a GC. |  14079   // should not in turn start a GC. | 
|  14884   NoSafepointScope no_safepoint; |  14080   NoSafepointScope no_safepoint; | 
|  14885   if (stackmaps() == Array::null()) { |  14081   if (stackmaps() == Array::null()) { | 
|  14886     // No stack maps are present in the code object which means this |  14082     // No stack maps are present in the code object which means this | 
|  14887     // frame relies on tagged pointers. |  14083     // frame relies on tagged pointers. | 
|  14888     return StackMap::null(); |  14084     return StackMap::null(); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  14900   } |  14096   } | 
|  14901   // If we are missing a stack map, this must either be unoptimized code, or |  14097   // If we are missing a stack map, this must either be unoptimized code, or | 
|  14902   // the entry to an osr function. (In which case all stack slots are |  14098   // the entry to an osr function. (In which case all stack slots are | 
|  14903   // considered to have tagged pointers.) |  14099   // considered to have tagged pointers.) | 
|  14904   // Running with --verify-on-transition should hit this. |  14100   // Running with --verify-on-transition should hit this. | 
|  14905   ASSERT(!is_optimized() || |  14101   ASSERT(!is_optimized() || | 
|  14906          (pc_offset == UncheckedEntryPoint() - PayloadStart())); |  14102          (pc_offset == UncheckedEntryPoint() - PayloadStart())); | 
|  14907   return StackMap::null(); |  14103   return StackMap::null(); | 
|  14908 } |  14104 } | 
|  14909  |  14105  | 
|  14910  |  | 
|  14911 void Code::GetInlinedFunctionsAtInstruction( |  14106 void Code::GetInlinedFunctionsAtInstruction( | 
|  14912     intptr_t pc_offset, |  14107     intptr_t pc_offset, | 
|  14913     GrowableArray<const Function*>* functions, |  14108     GrowableArray<const Function*>* functions, | 
|  14914     GrowableArray<TokenPosition>* token_positions) const { |  14109     GrowableArray<TokenPosition>* token_positions) const { | 
|  14915   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |  14110   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 
|  14916   if (map.IsNull()) { |  14111   if (map.IsNull()) { | 
|  14917     ASSERT(!IsFunctionCode()); |  14112     ASSERT(!IsFunctionCode()); | 
|  14918     return;  // VM stub or allocation stub. |  14113     return;  // VM stub or allocation stub. | 
|  14919   } |  14114   } | 
|  14920   const Array& id_map = Array::Handle(inlined_id_to_function()); |  14115   const Array& id_map = Array::Handle(inlined_id_to_function()); | 
|  14921   const Function& root = Function::Handle(function()); |  14116   const Function& root = Function::Handle(function()); | 
|  14922   CodeSourceMapReader reader(map, id_map, root); |  14117   CodeSourceMapReader reader(map, id_map, root); | 
|  14923   reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); |  14118   reader.GetInlinedFunctionsAt(pc_offset, functions, token_positions); | 
|  14924 } |  14119 } | 
|  14925  |  14120  | 
|  14926  |  | 
|  14927 #ifndef PRODUCT |  14121 #ifndef PRODUCT | 
|  14928 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { |  14122 void Code::PrintJSONInlineIntervals(JSONObject* jsobj) const { | 
|  14929   if (!is_optimized()) { |  14123   if (!is_optimized()) { | 
|  14930     return;  // No inlining. |  14124     return;  // No inlining. | 
|  14931   } |  14125   } | 
|  14932   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |  14126   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 
|  14933   const Array& id_map = Array::Handle(inlined_id_to_function()); |  14127   const Array& id_map = Array::Handle(inlined_id_to_function()); | 
|  14934   const Function& root = Function::Handle(function()); |  14128   const Function& root = Function::Handle(function()); | 
|  14935   CodeSourceMapReader reader(map, id_map, root); |  14129   CodeSourceMapReader reader(map, id_map, root); | 
|  14936   reader.PrintJSONInlineIntervals(jsobj); |  14130   reader.PrintJSONInlineIntervals(jsobj); | 
|  14937 } |  14131 } | 
|  14938 #endif |  14132 #endif | 
|  14939  |  14133  | 
|  14940  |  | 
|  14941 void Code::DumpInlineIntervals() const { |  14134 void Code::DumpInlineIntervals() const { | 
|  14942   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |  14135   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 
|  14943   if (map.IsNull()) { |  14136   if (map.IsNull()) { | 
|  14944     // Stub code. |  14137     // Stub code. | 
|  14945     return; |  14138     return; | 
|  14946   } |  14139   } | 
|  14947   const Array& id_map = Array::Handle(inlined_id_to_function()); |  14140   const Array& id_map = Array::Handle(inlined_id_to_function()); | 
|  14948   const Function& root = Function::Handle(function()); |  14141   const Function& root = Function::Handle(function()); | 
|  14949   CodeSourceMapReader reader(map, id_map, root); |  14142   CodeSourceMapReader reader(map, id_map, root); | 
|  14950   reader.DumpInlineIntervals(PayloadStart()); |  14143   reader.DumpInlineIntervals(PayloadStart()); | 
|  14951 } |  14144 } | 
|  14952  |  14145  | 
|  14953  |  | 
|  14954 void Code::DumpSourcePositions() const { |  14146 void Code::DumpSourcePositions() const { | 
|  14955   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); |  14147   const CodeSourceMap& map = CodeSourceMap::Handle(code_source_map()); | 
|  14956   if (map.IsNull()) { |  14148   if (map.IsNull()) { | 
|  14957     // Stub code. |  14149     // Stub code. | 
|  14958     return; |  14150     return; | 
|  14959   } |  14151   } | 
|  14960   const Array& id_map = Array::Handle(inlined_id_to_function()); |  14152   const Array& id_map = Array::Handle(inlined_id_to_function()); | 
|  14961   const Function& root = Function::Handle(function()); |  14153   const Function& root = Function::Handle(function()); | 
|  14962   CodeSourceMapReader reader(map, id_map, root); |  14154   CodeSourceMapReader reader(map, id_map, root); | 
|  14963   reader.DumpSourcePositions(PayloadStart()); |  14155   reader.DumpSourcePositions(PayloadStart()); | 
|  14964 } |  14156 } | 
|  14965  |  14157  | 
|  14966  |  | 
|  14967 RawArray* Code::await_token_positions() const { |  14158 RawArray* Code::await_token_positions() const { | 
|  14968 #if defined(DART_PRECOMPILED_RUNTIME) |  14159 #if defined(DART_PRECOMPILED_RUNTIME) | 
|  14969   return Array::null(); |  14160   return Array::null(); | 
|  14970 #else |  14161 #else | 
|  14971   return raw_ptr()->await_token_positions_; |  14162   return raw_ptr()->await_token_positions_; | 
|  14972 #endif |  14163 #endif | 
|  14973 } |  14164 } | 
|  14974  |  14165  | 
|  14975 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { |  14166 RawContext* Context::New(intptr_t num_variables, Heap::Space space) { | 
|  14976   ASSERT(num_variables >= 0); |  14167   ASSERT(num_variables >= 0); | 
|  14977   ASSERT(Object::context_class() != Class::null()); |  14168   ASSERT(Object::context_class() != Class::null()); | 
|  14978  |  14169  | 
|  14979   if (num_variables < 0 || num_variables > kMaxElements) { |  14170   if (num_variables < 0 || num_variables > kMaxElements) { | 
|  14980     // This should be caught before we reach here. |  14171     // This should be caught before we reach here. | 
|  14981     FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n", |  14172     FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n", | 
|  14982            num_variables); |  14173            num_variables); | 
|  14983   } |  14174   } | 
|  14984   Context& result = Context::Handle(); |  14175   Context& result = Context::Handle(); | 
|  14985   { |  14176   { | 
|  14986     RawObject* raw = Object::Allocate( |  14177     RawObject* raw = Object::Allocate( | 
|  14987         Context::kClassId, Context::InstanceSize(num_variables), space); |  14178         Context::kClassId, Context::InstanceSize(num_variables), space); | 
|  14988     NoSafepointScope no_safepoint; |  14179     NoSafepointScope no_safepoint; | 
|  14989     result ^= raw; |  14180     result ^= raw; | 
|  14990     result.set_num_variables(num_variables); |  14181     result.set_num_variables(num_variables); | 
|  14991   } |  14182   } | 
|  14992   return result.raw(); |  14183   return result.raw(); | 
|  14993 } |  14184 } | 
|  14994  |  14185  | 
|  14995  |  | 
|  14996 const char* Context::ToCString() const { |  14186 const char* Context::ToCString() const { | 
|  14997   if (IsNull()) { |  14187   if (IsNull()) { | 
|  14998     return "Context: null"; |  14188     return "Context: null"; | 
|  14999   } |  14189   } | 
|  15000   Zone* zone = Thread::Current()->zone(); |  14190   Zone* zone = Thread::Current()->zone(); | 
|  15001   const Context& parent_ctx = Context::Handle(parent()); |  14191   const Context& parent_ctx = Context::Handle(parent()); | 
|  15002   if (parent_ctx.IsNull()) { |  14192   if (parent_ctx.IsNull()) { | 
|  15003     return zone->PrintToString("Context num_variables: %" Pd "", |  14193     return zone->PrintToString("Context num_variables: %" Pd "", | 
|  15004                                num_variables()); |  14194                                num_variables()); | 
|  15005   } else { |  14195   } else { | 
|  15006     const char* parent_str = parent_ctx.ToCString(); |  14196     const char* parent_str = parent_ctx.ToCString(); | 
|  15007     return zone->PrintToString("Context num_variables: %" Pd " parent:{ %s }", |  14197     return zone->PrintToString("Context num_variables: %" Pd " parent:{ %s }", | 
|  15008                                num_variables(), parent_str); |  14198                                num_variables(), parent_str); | 
|  15009   } |  14199   } | 
|  15010 } |  14200 } | 
|  15011  |  14201  | 
|  15012  |  | 
|  15013 static void IndentN(int count) { |  14202 static void IndentN(int count) { | 
|  15014   for (int i = 0; i < count; i++) { |  14203   for (int i = 0; i < count; i++) { | 
|  15015     THR_Print(" "); |  14204     THR_Print(" "); | 
|  15016   } |  14205   } | 
|  15017 } |  14206 } | 
|  15018  |  14207  | 
|  15019  |  | 
|  15020 void Context::Dump(int indent) const { |  14208 void Context::Dump(int indent) const { | 
|  15021   if (IsNull()) { |  14209   if (IsNull()) { | 
|  15022     IndentN(indent); |  14210     IndentN(indent); | 
|  15023     THR_Print("Context@null\n"); |  14211     THR_Print("Context@null\n"); | 
|  15024     return; |  14212     return; | 
|  15025   } |  14213   } | 
|  15026  |  14214  | 
|  15027   IndentN(indent); |  14215   IndentN(indent); | 
|  15028   THR_Print("Context@%p vars(%" Pd ") {\n", this->raw(), num_variables()); |  14216   THR_Print("Context@%p vars(%" Pd ") {\n", this->raw(), num_variables()); | 
|  15029   Object& obj = Object::Handle(); |  14217   Object& obj = Object::Handle(); | 
|  15030   for (intptr_t i = 0; i < num_variables(); i++) { |  14218   for (intptr_t i = 0; i < num_variables(); i++) { | 
|  15031     IndentN(indent + 2); |  14219     IndentN(indent + 2); | 
|  15032     obj = At(i); |  14220     obj = At(i); | 
|  15033     const char* s = obj.ToCString(); |  14221     const char* s = obj.ToCString(); | 
|  15034     if (strlen(s) > 50) { |  14222     if (strlen(s) > 50) { | 
|  15035       THR_Print("[%" Pd "] = [first 50 chars:] %.50s...\n", i, s); |  14223       THR_Print("[%" Pd "] = [first 50 chars:] %.50s...\n", i, s); | 
|  15036     } else { |  14224     } else { | 
|  15037       THR_Print("[%" Pd "] = %s\n", i, s); |  14225       THR_Print("[%" Pd "] = %s\n", i, s); | 
|  15038     } |  14226     } | 
|  15039   } |  14227   } | 
|  15040  |  14228  | 
|  15041   const Context& parent_ctx = Context::Handle(parent()); |  14229   const Context& parent_ctx = Context::Handle(parent()); | 
|  15042   if (!parent_ctx.IsNull()) { |  14230   if (!parent_ctx.IsNull()) { | 
|  15043     parent_ctx.Dump(indent + 2); |  14231     parent_ctx.Dump(indent + 2); | 
|  15044   } |  14232   } | 
|  15045   IndentN(indent); |  14233   IndentN(indent); | 
|  15046   THR_Print("}\n"); |  14234   THR_Print("}\n"); | 
|  15047 } |  14235 } | 
|  15048  |  14236  | 
|  15049  |  | 
|  15050 RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) { |  14237 RawContextScope* ContextScope::New(intptr_t num_variables, bool is_implicit) { | 
|  15051   ASSERT(Object::context_scope_class() != Class::null()); |  14238   ASSERT(Object::context_scope_class() != Class::null()); | 
|  15052   if (num_variables < 0 || num_variables > kMaxElements) { |  14239   if (num_variables < 0 || num_variables > kMaxElements) { | 
|  15053     // This should be caught before we reach here. |  14240     // This should be caught before we reach here. | 
|  15054     FATAL1("Fatal error in ContextScope::New: invalid num_variables %" Pd "\n", |  14241     FATAL1("Fatal error in ContextScope::New: invalid num_variables %" Pd "\n", | 
|  15055            num_variables); |  14242            num_variables); | 
|  15056   } |  14243   } | 
|  15057   intptr_t size = ContextScope::InstanceSize(num_variables); |  14244   intptr_t size = ContextScope::InstanceSize(num_variables); | 
|  15058   ContextScope& result = ContextScope::Handle(); |  14245   ContextScope& result = ContextScope::Handle(); | 
|  15059   { |  14246   { | 
|  15060     RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld); |  14247     RawObject* raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld); | 
|  15061     NoSafepointScope no_safepoint; |  14248     NoSafepointScope no_safepoint; | 
|  15062     result ^= raw; |  14249     result ^= raw; | 
|  15063     result.set_num_variables(num_variables); |  14250     result.set_num_variables(num_variables); | 
|  15064     result.set_is_implicit(is_implicit); |  14251     result.set_is_implicit(is_implicit); | 
|  15065   } |  14252   } | 
|  15066   return result.raw(); |  14253   return result.raw(); | 
|  15067 } |  14254 } | 
|  15068  |  14255  | 
|  15069  |  | 
|  15070 TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const { |  14256 TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const { | 
|  15071   return TokenPosition(Smi::Value(VariableDescAddr(scope_index)->token_pos)); |  14257   return TokenPosition(Smi::Value(VariableDescAddr(scope_index)->token_pos)); | 
|  15072 } |  14258 } | 
|  15073  |  14259  | 
|  15074  |  | 
|  15075 void ContextScope::SetTokenIndexAt(intptr_t scope_index, |  14260 void ContextScope::SetTokenIndexAt(intptr_t scope_index, | 
|  15076                                    TokenPosition token_pos) const { |  14261                                    TokenPosition token_pos) const { | 
|  15077   StoreSmi(&VariableDescAddr(scope_index)->token_pos, |  14262   StoreSmi(&VariableDescAddr(scope_index)->token_pos, | 
|  15078            Smi::New(token_pos.value())); |  14263            Smi::New(token_pos.value())); | 
|  15079 } |  14264 } | 
|  15080  |  14265  | 
|  15081  |  | 
|  15082 TokenPosition ContextScope::DeclarationTokenIndexAt( |  14266 TokenPosition ContextScope::DeclarationTokenIndexAt( | 
|  15083     intptr_t scope_index) const { |  14267     intptr_t scope_index) const { | 
|  15084   return TokenPosition( |  14268   return TokenPosition( | 
|  15085       Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos)); |  14269       Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos)); | 
|  15086 } |  14270 } | 
|  15087  |  14271  | 
|  15088  |  | 
|  15089 void ContextScope::SetDeclarationTokenIndexAt( |  14272 void ContextScope::SetDeclarationTokenIndexAt( | 
|  15090     intptr_t scope_index, |  14273     intptr_t scope_index, | 
|  15091     TokenPosition declaration_token_pos) const { |  14274     TokenPosition declaration_token_pos) const { | 
|  15092   StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos, |  14275   StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos, | 
|  15093            Smi::New(declaration_token_pos.value())); |  14276            Smi::New(declaration_token_pos.value())); | 
|  15094 } |  14277 } | 
|  15095  |  14278  | 
|  15096  |  | 
|  15097 RawString* ContextScope::NameAt(intptr_t scope_index) const { |  14279 RawString* ContextScope::NameAt(intptr_t scope_index) const { | 
|  15098   return VariableDescAddr(scope_index)->name; |  14280   return VariableDescAddr(scope_index)->name; | 
|  15099 } |  14281 } | 
|  15100  |  14282  | 
|  15101  |  | 
|  15102 void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const { |  14283 void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const { | 
|  15103   StorePointer(&(VariableDescAddr(scope_index)->name), name.raw()); |  14284   StorePointer(&(VariableDescAddr(scope_index)->name), name.raw()); | 
|  15104 } |  14285 } | 
|  15105  |  14286  | 
|  15106  |  | 
|  15107 bool ContextScope::IsFinalAt(intptr_t scope_index) const { |  14287 bool ContextScope::IsFinalAt(intptr_t scope_index) const { | 
|  15108   return Bool::Handle(VariableDescAddr(scope_index)->is_final).value(); |  14288   return Bool::Handle(VariableDescAddr(scope_index)->is_final).value(); | 
|  15109 } |  14289 } | 
|  15110  |  14290  | 
|  15111  |  | 
|  15112 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const { |  14291 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const { | 
|  15113   StorePointer(&(VariableDescAddr(scope_index)->is_final), |  14292   StorePointer(&(VariableDescAddr(scope_index)->is_final), | 
|  15114                Bool::Get(is_final).raw()); |  14293                Bool::Get(is_final).raw()); | 
|  15115 } |  14294 } | 
|  15116  |  14295  | 
|  15117  |  | 
|  15118 bool ContextScope::IsConstAt(intptr_t scope_index) const { |  14296 bool ContextScope::IsConstAt(intptr_t scope_index) const { | 
|  15119   return Bool::Handle(VariableDescAddr(scope_index)->is_const).value(); |  14297   return Bool::Handle(VariableDescAddr(scope_index)->is_const).value(); | 
|  15120 } |  14298 } | 
|  15121  |  14299  | 
|  15122  |  | 
|  15123 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const { |  14300 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const { | 
|  15124   StorePointer(&(VariableDescAddr(scope_index)->is_const), |  14301   StorePointer(&(VariableDescAddr(scope_index)->is_const), | 
|  15125                Bool::Get(is_const).raw()); |  14302                Bool::Get(is_const).raw()); | 
|  15126 } |  14303 } | 
|  15127  |  14304  | 
|  15128  |  | 
|  15129 RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const { |  14305 RawAbstractType* ContextScope::TypeAt(intptr_t scope_index) const { | 
|  15130   ASSERT(!IsConstAt(scope_index)); |  14306   ASSERT(!IsConstAt(scope_index)); | 
|  15131   return VariableDescAddr(scope_index)->type; |  14307   return VariableDescAddr(scope_index)->type; | 
|  15132 } |  14308 } | 
|  15133  |  14309  | 
|  15134  |  | 
|  15135 void ContextScope::SetTypeAt(intptr_t scope_index, |  14310 void ContextScope::SetTypeAt(intptr_t scope_index, | 
|  15136                              const AbstractType& type) const { |  14311                              const AbstractType& type) const { | 
|  15137   StorePointer(&(VariableDescAddr(scope_index)->type), type.raw()); |  14312   StorePointer(&(VariableDescAddr(scope_index)->type), type.raw()); | 
|  15138 } |  14313 } | 
|  15139  |  14314  | 
|  15140  |  | 
|  15141 RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const { |  14315 RawInstance* ContextScope::ConstValueAt(intptr_t scope_index) const { | 
|  15142   ASSERT(IsConstAt(scope_index)); |  14316   ASSERT(IsConstAt(scope_index)); | 
|  15143   return VariableDescAddr(scope_index)->value; |  14317   return VariableDescAddr(scope_index)->value; | 
|  15144 } |  14318 } | 
|  15145  |  14319  | 
|  15146  |  | 
|  15147 void ContextScope::SetConstValueAt(intptr_t scope_index, |  14320 void ContextScope::SetConstValueAt(intptr_t scope_index, | 
|  15148                                    const Instance& value) const { |  14321                                    const Instance& value) const { | 
|  15149   ASSERT(IsConstAt(scope_index)); |  14322   ASSERT(IsConstAt(scope_index)); | 
|  15150   StorePointer(&(VariableDescAddr(scope_index)->value), value.raw()); |  14323   StorePointer(&(VariableDescAddr(scope_index)->value), value.raw()); | 
|  15151 } |  14324 } | 
|  15152  |  14325  | 
|  15153  |  | 
|  15154 intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const { |  14326 intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const { | 
|  15155   return Smi::Value(VariableDescAddr(scope_index)->context_index); |  14327   return Smi::Value(VariableDescAddr(scope_index)->context_index); | 
|  15156 } |  14328 } | 
|  15157  |  14329  | 
|  15158  |  | 
|  15159 void ContextScope::SetContextIndexAt(intptr_t scope_index, |  14330 void ContextScope::SetContextIndexAt(intptr_t scope_index, | 
|  15160                                      intptr_t context_index) const { |  14331                                      intptr_t context_index) const { | 
|  15161   StoreSmi(&(VariableDescAddr(scope_index)->context_index), |  14332   StoreSmi(&(VariableDescAddr(scope_index)->context_index), | 
|  15162            Smi::New(context_index)); |  14333            Smi::New(context_index)); | 
|  15163 } |  14334 } | 
|  15164  |  14335  | 
|  15165  |  | 
|  15166 intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const { |  14336 intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const { | 
|  15167   return Smi::Value(VariableDescAddr(scope_index)->context_level); |  14337   return Smi::Value(VariableDescAddr(scope_index)->context_level); | 
|  15168 } |  14338 } | 
|  15169  |  14339  | 
|  15170  |  | 
|  15171 void ContextScope::SetContextLevelAt(intptr_t scope_index, |  14340 void ContextScope::SetContextLevelAt(intptr_t scope_index, | 
|  15172                                      intptr_t context_level) const { |  14341                                      intptr_t context_level) const { | 
|  15173   StoreSmi(&(VariableDescAddr(scope_index)->context_level), |  14342   StoreSmi(&(VariableDescAddr(scope_index)->context_level), | 
|  15174            Smi::New(context_level)); |  14343            Smi::New(context_level)); | 
|  15175 } |  14344 } | 
|  15176  |  14345  | 
|  15177  |  | 
|  15178 const char* ContextScope::ToCString() const { |  14346 const char* ContextScope::ToCString() const { | 
|  15179   const char* prev_cstr = "ContextScope:"; |  14347   const char* prev_cstr = "ContextScope:"; | 
|  15180   String& name = String::Handle(); |  14348   String& name = String::Handle(); | 
|  15181   for (int i = 0; i < num_variables(); i++) { |  14349   for (int i = 0; i < num_variables(); i++) { | 
|  15182     name = NameAt(i); |  14350     name = NameAt(i); | 
|  15183     const char* cname = name.ToCString(); |  14351     const char* cname = name.ToCString(); | 
|  15184     TokenPosition pos = TokenIndexAt(i); |  14352     TokenPosition pos = TokenIndexAt(i); | 
|  15185     intptr_t idx = ContextIndexAt(i); |  14353     intptr_t idx = ContextIndexAt(i); | 
|  15186     intptr_t lvl = ContextLevelAt(i); |  14354     intptr_t lvl = ContextLevelAt(i); | 
|  15187     char* chars = |  14355     char* chars = | 
|  15188         OS::SCreate(Thread::Current()->zone(), |  14356         OS::SCreate(Thread::Current()->zone(), | 
|  15189                     "%s\nvar %s  token-pos %s  ctx lvl %" Pd "  index %" Pd "", |  14357                     "%s\nvar %s  token-pos %s  ctx lvl %" Pd "  index %" Pd "", | 
|  15190                     prev_cstr, cname, pos.ToCString(), lvl, idx); |  14358                     prev_cstr, cname, pos.ToCString(), lvl, idx); | 
|  15191     prev_cstr = chars; |  14359     prev_cstr = chars; | 
|  15192   } |  14360   } | 
|  15193   return prev_cstr; |  14361   return prev_cstr; | 
|  15194 } |  14362 } | 
|  15195  |  14363  | 
|  15196  |  | 
|  15197 RawArray* MegamorphicCache::buckets() const { |  14364 RawArray* MegamorphicCache::buckets() const { | 
|  15198   return raw_ptr()->buckets_; |  14365   return raw_ptr()->buckets_; | 
|  15199 } |  14366 } | 
|  15200  |  14367  | 
|  15201  |  | 
|  15202 void MegamorphicCache::set_buckets(const Array& buckets) const { |  14368 void MegamorphicCache::set_buckets(const Array& buckets) const { | 
|  15203   StorePointer(&raw_ptr()->buckets_, buckets.raw()); |  14369   StorePointer(&raw_ptr()->buckets_, buckets.raw()); | 
|  15204 } |  14370 } | 
|  15205  |  14371  | 
|  15206  |  | 
|  15207 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask |  14372 // Class IDs in the table are smi-tagged, so we use a smi-tagged mask | 
|  15208 // and target class ID to avoid untagging (on each iteration of the |  14373 // and target class ID to avoid untagging (on each iteration of the | 
|  15209 // test loop) in generated code. |  14374 // test loop) in generated code. | 
|  15210 intptr_t MegamorphicCache::mask() const { |  14375 intptr_t MegamorphicCache::mask() const { | 
|  15211   return Smi::Value(raw_ptr()->mask_); |  14376   return Smi::Value(raw_ptr()->mask_); | 
|  15212 } |  14377 } | 
|  15213  |  14378  | 
|  15214  |  | 
|  15215 void MegamorphicCache::set_mask(intptr_t mask) const { |  14379 void MegamorphicCache::set_mask(intptr_t mask) const { | 
|  15216   StoreSmi(&raw_ptr()->mask_, Smi::New(mask)); |  14380   StoreSmi(&raw_ptr()->mask_, Smi::New(mask)); | 
|  15217 } |  14381 } | 
|  15218  |  14382  | 
|  15219  |  | 
|  15220 intptr_t MegamorphicCache::filled_entry_count() const { |  14383 intptr_t MegamorphicCache::filled_entry_count() const { | 
|  15221   return raw_ptr()->filled_entry_count_; |  14384   return raw_ptr()->filled_entry_count_; | 
|  15222 } |  14385 } | 
|  15223  |  14386  | 
|  15224  |  | 
|  15225 void MegamorphicCache::set_filled_entry_count(intptr_t count) const { |  14387 void MegamorphicCache::set_filled_entry_count(intptr_t count) const { | 
|  15226   StoreNonPointer(&raw_ptr()->filled_entry_count_, count); |  14388   StoreNonPointer(&raw_ptr()->filled_entry_count_, count); | 
|  15227 } |  14389 } | 
|  15228  |  14390  | 
|  15229  |  | 
|  15230 void MegamorphicCache::set_target_name(const String& value) const { |  14391 void MegamorphicCache::set_target_name(const String& value) const { | 
|  15231   StorePointer(&raw_ptr()->target_name_, value.raw()); |  14392   StorePointer(&raw_ptr()->target_name_, value.raw()); | 
|  15232 } |  14393 } | 
|  15233  |  14394  | 
|  15234  |  | 
|  15235 void MegamorphicCache::set_arguments_descriptor(const Array& value) const { |  14395 void MegamorphicCache::set_arguments_descriptor(const Array& value) const { | 
|  15236   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); |  14396   StorePointer(&raw_ptr()->args_descriptor_, value.raw()); | 
|  15237 } |  14397 } | 
|  15238  |  14398  | 
|  15239  |  | 
|  15240 RawMegamorphicCache* MegamorphicCache::New() { |  14399 RawMegamorphicCache* MegamorphicCache::New() { | 
|  15241   MegamorphicCache& result = MegamorphicCache::Handle(); |  14400   MegamorphicCache& result = MegamorphicCache::Handle(); | 
|  15242   { |  14401   { | 
|  15243     RawObject* raw = |  14402     RawObject* raw = | 
|  15244         Object::Allocate(MegamorphicCache::kClassId, |  14403         Object::Allocate(MegamorphicCache::kClassId, | 
|  15245                          MegamorphicCache::InstanceSize(), Heap::kOld); |  14404                          MegamorphicCache::InstanceSize(), Heap::kOld); | 
|  15246     NoSafepointScope no_safepoint; |  14405     NoSafepointScope no_safepoint; | 
|  15247     result ^= raw; |  14406     result ^= raw; | 
|  15248   } |  14407   } | 
|  15249   result.set_filled_entry_count(0); |  14408   result.set_filled_entry_count(0); | 
|  15250   return result.raw(); |  14409   return result.raw(); | 
|  15251 } |  14410 } | 
|  15252  |  14411  | 
|  15253  |  | 
|  15254 RawMegamorphicCache* MegamorphicCache::New(const String& target_name, |  14412 RawMegamorphicCache* MegamorphicCache::New(const String& target_name, | 
|  15255                                            const Array& arguments_descriptor) { |  14413                                            const Array& arguments_descriptor) { | 
|  15256   MegamorphicCache& result = MegamorphicCache::Handle(); |  14414   MegamorphicCache& result = MegamorphicCache::Handle(); | 
|  15257   { |  14415   { | 
|  15258     RawObject* raw = |  14416     RawObject* raw = | 
|  15259         Object::Allocate(MegamorphicCache::kClassId, |  14417         Object::Allocate(MegamorphicCache::kClassId, | 
|  15260                          MegamorphicCache::InstanceSize(), Heap::kOld); |  14418                          MegamorphicCache::InstanceSize(), Heap::kOld); | 
|  15261     NoSafepointScope no_safepoint; |  14419     NoSafepointScope no_safepoint; | 
|  15262     result ^= raw; |  14420     result ^= raw; | 
|  15263   } |  14421   } | 
|  15264   const intptr_t capacity = kInitialCapacity; |  14422   const intptr_t capacity = kInitialCapacity; | 
|  15265   const Array& buckets = |  14423   const Array& buckets = | 
|  15266       Array::Handle(Array::New(kEntryLength * capacity, Heap::kOld)); |  14424       Array::Handle(Array::New(kEntryLength * capacity, Heap::kOld)); | 
|  15267   const Function& handler = |  14425   const Function& handler = | 
|  15268       Function::Handle(MegamorphicCacheTable::miss_handler(Isolate::Current())); |  14426       Function::Handle(MegamorphicCacheTable::miss_handler(Isolate::Current())); | 
|  15269   for (intptr_t i = 0; i < capacity; ++i) { |  14427   for (intptr_t i = 0; i < capacity; ++i) { | 
|  15270     SetEntry(buckets, i, smi_illegal_cid(), handler); |  14428     SetEntry(buckets, i, smi_illegal_cid(), handler); | 
|  15271   } |  14429   } | 
|  15272   result.set_buckets(buckets); |  14430   result.set_buckets(buckets); | 
|  15273   result.set_mask(capacity - 1); |  14431   result.set_mask(capacity - 1); | 
|  15274   result.set_target_name(target_name); |  14432   result.set_target_name(target_name); | 
|  15275   result.set_arguments_descriptor(arguments_descriptor); |  14433   result.set_arguments_descriptor(arguments_descriptor); | 
|  15276   result.set_filled_entry_count(0); |  14434   result.set_filled_entry_count(0); | 
|  15277   return result.raw(); |  14435   return result.raw(); | 
|  15278 } |  14436 } | 
|  15279  |  14437  | 
|  15280  |  | 
|  15281 void MegamorphicCache::EnsureCapacity() const { |  14438 void MegamorphicCache::EnsureCapacity() const { | 
|  15282   intptr_t old_capacity = mask() + 1; |  14439   intptr_t old_capacity = mask() + 1; | 
|  15283   double load_limit = kLoadFactor * static_cast<double>(old_capacity); |  14440   double load_limit = kLoadFactor * static_cast<double>(old_capacity); | 
|  15284   if (static_cast<double>(filled_entry_count() + 1) > load_limit) { |  14441   if (static_cast<double>(filled_entry_count() + 1) > load_limit) { | 
|  15285     const Array& old_buckets = Array::Handle(buckets()); |  14442     const Array& old_buckets = Array::Handle(buckets()); | 
|  15286     intptr_t new_capacity = old_capacity * 2; |  14443     intptr_t new_capacity = old_capacity * 2; | 
|  15287     const Array& new_buckets = |  14444     const Array& new_buckets = | 
|  15288         Array::Handle(Array::New(kEntryLength * new_capacity)); |  14445         Array::Handle(Array::New(kEntryLength * new_capacity)); | 
|  15289  |  14446  | 
|  15290     Function& target = Function::Handle( |  14447     Function& target = Function::Handle( | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  15301     for (intptr_t i = 0; i < old_capacity; ++i) { |  14458     for (intptr_t i = 0; i < old_capacity; ++i) { | 
|  15302       class_id ^= GetClassId(old_buckets, i); |  14459       class_id ^= GetClassId(old_buckets, i); | 
|  15303       if (class_id.Value() != kIllegalCid) { |  14460       if (class_id.Value() != kIllegalCid) { | 
|  15304         target ^= GetTargetFunction(old_buckets, i); |  14461         target ^= GetTargetFunction(old_buckets, i); | 
|  15305         Insert(class_id, target); |  14462         Insert(class_id, target); | 
|  15306       } |  14463       } | 
|  15307     } |  14464     } | 
|  15308   } |  14465   } | 
|  15309 } |  14466 } | 
|  15310  |  14467  | 
|  15311  |  | 
|  15312 void MegamorphicCache::Insert(const Smi& class_id, |  14468 void MegamorphicCache::Insert(const Smi& class_id, | 
|  15313                               const Function& target) const { |  14469                               const Function& target) const { | 
|  15314   ASSERT(static_cast<double>(filled_entry_count() + 1) <= |  14470   ASSERT(static_cast<double>(filled_entry_count() + 1) <= | 
|  15315          (kLoadFactor * static_cast<double>(mask() + 1))); |  14471          (kLoadFactor * static_cast<double>(mask() + 1))); | 
|  15316   const Array& backing_array = Array::Handle(buckets()); |  14472   const Array& backing_array = Array::Handle(buckets()); | 
|  15317   intptr_t id_mask = mask(); |  14473   intptr_t id_mask = mask(); | 
|  15318   intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask; |  14474   intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask; | 
|  15319   intptr_t i = index; |  14475   intptr_t i = index; | 
|  15320   do { |  14476   do { | 
|  15321     if (Smi::Value(Smi::RawCast(GetClassId(backing_array, i))) == kIllegalCid) { |  14477     if (Smi::Value(Smi::RawCast(GetClassId(backing_array, i))) == kIllegalCid) { | 
|  15322       SetEntry(backing_array, i, class_id, target); |  14478       SetEntry(backing_array, i, class_id, target); | 
|  15323       set_filled_entry_count(filled_entry_count() + 1); |  14479       set_filled_entry_count(filled_entry_count() + 1); | 
|  15324       return; |  14480       return; | 
|  15325     } |  14481     } | 
|  15326     i = (i + 1) & id_mask; |  14482     i = (i + 1) & id_mask; | 
|  15327   } while (i != index); |  14483   } while (i != index); | 
|  15328   UNREACHABLE(); |  14484   UNREACHABLE(); | 
|  15329 } |  14485 } | 
|  15330  |  14486  | 
|  15331  |  | 
|  15332 const char* MegamorphicCache::ToCString() const { |  14487 const char* MegamorphicCache::ToCString() const { | 
|  15333   const String& name = String::Handle(target_name()); |  14488   const String& name = String::Handle(target_name()); | 
|  15334   return OS::SCreate(Thread::Current()->zone(), "MegamorphicCache(%s)", |  14489   return OS::SCreate(Thread::Current()->zone(), "MegamorphicCache(%s)", | 
|  15335                      name.ToCString()); |  14490                      name.ToCString()); | 
|  15336 } |  14491 } | 
|  15337  |  14492  | 
|  15338  |  | 
|  15339 RawSubtypeTestCache* SubtypeTestCache::New() { |  14493 RawSubtypeTestCache* SubtypeTestCache::New() { | 
|  15340   ASSERT(Object::subtypetestcache_class() != Class::null()); |  14494   ASSERT(Object::subtypetestcache_class() != Class::null()); | 
|  15341   SubtypeTestCache& result = SubtypeTestCache::Handle(); |  14495   SubtypeTestCache& result = SubtypeTestCache::Handle(); | 
|  15342   { |  14496   { | 
|  15343     // SubtypeTestCache objects are long living objects, allocate them in the |  14497     // SubtypeTestCache objects are long living objects, allocate them in the | 
|  15344     // old generation. |  14498     // old generation. | 
|  15345     RawObject* raw = |  14499     RawObject* raw = | 
|  15346         Object::Allocate(SubtypeTestCache::kClassId, |  14500         Object::Allocate(SubtypeTestCache::kClassId, | 
|  15347                          SubtypeTestCache::InstanceSize(), Heap::kOld); |  14501                          SubtypeTestCache::InstanceSize(), Heap::kOld); | 
|  15348     NoSafepointScope no_safepoint; |  14502     NoSafepointScope no_safepoint; | 
|  15349     result ^= raw; |  14503     result ^= raw; | 
|  15350   } |  14504   } | 
|  15351   const Array& cache = Array::Handle(Array::New(kTestEntryLength, Heap::kOld)); |  14505   const Array& cache = Array::Handle(Array::New(kTestEntryLength, Heap::kOld)); | 
|  15352   result.set_cache(cache); |  14506   result.set_cache(cache); | 
|  15353   return result.raw(); |  14507   return result.raw(); | 
|  15354 } |  14508 } | 
|  15355  |  14509  | 
|  15356  |  | 
|  15357 void SubtypeTestCache::set_cache(const Array& value) const { |  14510 void SubtypeTestCache::set_cache(const Array& value) const { | 
|  15358   StorePointer(&raw_ptr()->cache_, value.raw()); |  14511   StorePointer(&raw_ptr()->cache_, value.raw()); | 
|  15359 } |  14512 } | 
|  15360  |  14513  | 
|  15361  |  | 
|  15362 intptr_t SubtypeTestCache::NumberOfChecks() const { |  14514 intptr_t SubtypeTestCache::NumberOfChecks() const { | 
|  15363   NoSafepointScope no_safepoint; |  14515   NoSafepointScope no_safepoint; | 
|  15364   // Do not count the sentinel; |  14516   // Do not count the sentinel; | 
|  15365   return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1; |  14517   return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1; | 
|  15366 } |  14518 } | 
|  15367  |  14519  | 
|  15368  |  | 
|  15369 void SubtypeTestCache::AddCheck( |  14520 void SubtypeTestCache::AddCheck( | 
|  15370     const Object& instance_class_id_or_function, |  14521     const Object& instance_class_id_or_function, | 
|  15371     const TypeArguments& instance_type_arguments, |  14522     const TypeArguments& instance_type_arguments, | 
|  15372     const TypeArguments& instantiator_type_arguments, |  14523     const TypeArguments& instantiator_type_arguments, | 
|  15373     const TypeArguments& function_type_arguments, |  14524     const TypeArguments& function_type_arguments, | 
|  15374     const Bool& test_result) const { |  14525     const Bool& test_result) const { | 
|  15375   intptr_t old_num = NumberOfChecks(); |  14526   intptr_t old_num = NumberOfChecks(); | 
|  15376   Array& data = Array::Handle(cache()); |  14527   Array& data = Array::Handle(cache()); | 
|  15377   intptr_t new_len = data.Length() + kTestEntryLength; |  14528   intptr_t new_len = data.Length() + kTestEntryLength; | 
|  15378   data = Array::Grow(data, new_len); |  14529   data = Array::Grow(data, new_len); | 
|  15379   set_cache(data); |  14530   set_cache(data); | 
|  15380   intptr_t data_pos = old_num * kTestEntryLength; |  14531   intptr_t data_pos = old_num * kTestEntryLength; | 
|  15381   data.SetAt(data_pos + kInstanceClassIdOrFunction, |  14532   data.SetAt(data_pos + kInstanceClassIdOrFunction, | 
|  15382              instance_class_id_or_function); |  14533              instance_class_id_or_function); | 
|  15383   data.SetAt(data_pos + kInstanceTypeArguments, instance_type_arguments); |  14534   data.SetAt(data_pos + kInstanceTypeArguments, instance_type_arguments); | 
|  15384   data.SetAt(data_pos + kInstantiatorTypeArguments, |  14535   data.SetAt(data_pos + kInstantiatorTypeArguments, | 
|  15385              instantiator_type_arguments); |  14536              instantiator_type_arguments); | 
|  15386   data.SetAt(data_pos + kFunctionTypeArguments, function_type_arguments); |  14537   data.SetAt(data_pos + kFunctionTypeArguments, function_type_arguments); | 
|  15387   data.SetAt(data_pos + kTestResult, test_result); |  14538   data.SetAt(data_pos + kTestResult, test_result); | 
|  15388 } |  14539 } | 
|  15389  |  14540  | 
|  15390  |  | 
|  15391 void SubtypeTestCache::GetCheck(intptr_t ix, |  14541 void SubtypeTestCache::GetCheck(intptr_t ix, | 
|  15392                                 Object* instance_class_id_or_function, |  14542                                 Object* instance_class_id_or_function, | 
|  15393                                 TypeArguments* instance_type_arguments, |  14543                                 TypeArguments* instance_type_arguments, | 
|  15394                                 TypeArguments* instantiator_type_arguments, |  14544                                 TypeArguments* instantiator_type_arguments, | 
|  15395                                 TypeArguments* function_type_arguments, |  14545                                 TypeArguments* function_type_arguments, | 
|  15396                                 Bool* test_result) const { |  14546                                 Bool* test_result) const { | 
|  15397   Array& data = Array::Handle(cache()); |  14547   Array& data = Array::Handle(cache()); | 
|  15398   intptr_t data_pos = ix * kTestEntryLength; |  14548   intptr_t data_pos = ix * kTestEntryLength; | 
|  15399   *instance_class_id_or_function = |  14549   *instance_class_id_or_function = | 
|  15400       data.At(data_pos + kInstanceClassIdOrFunction); |  14550       data.At(data_pos + kInstanceClassIdOrFunction); | 
|  15401   *instance_type_arguments ^= data.At(data_pos + kInstanceTypeArguments); |  14551   *instance_type_arguments ^= data.At(data_pos + kInstanceTypeArguments); | 
|  15402   *instantiator_type_arguments ^= |  14552   *instantiator_type_arguments ^= | 
|  15403       data.At(data_pos + kInstantiatorTypeArguments); |  14553       data.At(data_pos + kInstantiatorTypeArguments); | 
|  15404   *function_type_arguments ^= data.At(data_pos + kFunctionTypeArguments); |  14554   *function_type_arguments ^= data.At(data_pos + kFunctionTypeArguments); | 
|  15405   *test_result ^= data.At(data_pos + kTestResult); |  14555   *test_result ^= data.At(data_pos + kTestResult); | 
|  15406 } |  14556 } | 
|  15407  |  14557  | 
|  15408  |  | 
|  15409 const char* SubtypeTestCache::ToCString() const { |  14558 const char* SubtypeTestCache::ToCString() const { | 
|  15410   return "SubtypeTestCache"; |  14559   return "SubtypeTestCache"; | 
|  15411 } |  14560 } | 
|  15412  |  14561  | 
|  15413  |  | 
|  15414 const char* Error::ToErrorCString() const { |  14562 const char* Error::ToErrorCString() const { | 
|  15415   if (IsNull()) { |  14563   if (IsNull()) { | 
|  15416     return "Error: null"; |  14564     return "Error: null"; | 
|  15417   } |  14565   } | 
|  15418   UNREACHABLE(); |  14566   UNREACHABLE(); | 
|  15419   return "Error"; |  14567   return "Error"; | 
|  15420 } |  14568 } | 
|  15421  |  14569  | 
|  15422  |  | 
|  15423 const char* Error::ToCString() const { |  14570 const char* Error::ToCString() const { | 
|  15424   if (IsNull()) { |  14571   if (IsNull()) { | 
|  15425     return "Error: null"; |  14572     return "Error: null"; | 
|  15426   } |  14573   } | 
|  15427   // Error is an abstract class.  We should never reach here. |  14574   // Error is an abstract class.  We should never reach here. | 
|  15428   UNREACHABLE(); |  14575   UNREACHABLE(); | 
|  15429   return "Error"; |  14576   return "Error"; | 
|  15430 } |  14577 } | 
|  15431  |  14578  | 
|  15432  |  | 
|  15433 RawApiError* ApiError::New() { |  14579 RawApiError* ApiError::New() { | 
|  15434   ASSERT(Object::api_error_class() != Class::null()); |  14580   ASSERT(Object::api_error_class() != Class::null()); | 
|  15435   RawObject* raw = Object::Allocate(ApiError::kClassId, |  14581   RawObject* raw = Object::Allocate(ApiError::kClassId, | 
|  15436                                     ApiError::InstanceSize(), Heap::kOld); |  14582                                     ApiError::InstanceSize(), Heap::kOld); | 
|  15437   return reinterpret_cast<RawApiError*>(raw); |  14583   return reinterpret_cast<RawApiError*>(raw); | 
|  15438 } |  14584 } | 
|  15439  |  14585  | 
|  15440  |  | 
|  15441 RawApiError* ApiError::New(const String& message, Heap::Space space) { |  14586 RawApiError* ApiError::New(const String& message, Heap::Space space) { | 
|  15442 #ifndef PRODUCT |  14587 #ifndef PRODUCT | 
|  15443   if (FLAG_print_stacktrace_at_api_error) { |  14588   if (FLAG_print_stacktrace_at_api_error) { | 
|  15444     OS::PrintErr("ApiError: %s\n", message.ToCString()); |  14589     OS::PrintErr("ApiError: %s\n", message.ToCString()); | 
|  15445     Profiler::DumpStackTrace(false /* for_crash */); |  14590     Profiler::DumpStackTrace(false /* for_crash */); | 
|  15446   } |  14591   } | 
|  15447 #endif  // !PRODUCT |  14592 #endif  // !PRODUCT | 
|  15448  |  14593  | 
|  15449   ASSERT(Object::api_error_class() != Class::null()); |  14594   ASSERT(Object::api_error_class() != Class::null()); | 
|  15450   ApiError& result = ApiError::Handle(); |  14595   ApiError& result = ApiError::Handle(); | 
|  15451   { |  14596   { | 
|  15452     RawObject* raw = |  14597     RawObject* raw = | 
|  15453         Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space); |  14598         Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space); | 
|  15454     NoSafepointScope no_safepoint; |  14599     NoSafepointScope no_safepoint; | 
|  15455     result ^= raw; |  14600     result ^= raw; | 
|  15456   } |  14601   } | 
|  15457   result.set_message(message); |  14602   result.set_message(message); | 
|  15458   return result.raw(); |  14603   return result.raw(); | 
|  15459 } |  14604 } | 
|  15460  |  14605  | 
|  15461  |  | 
|  15462 void ApiError::set_message(const String& message) const { |  14606 void ApiError::set_message(const String& message) const { | 
|  15463   StorePointer(&raw_ptr()->message_, message.raw()); |  14607   StorePointer(&raw_ptr()->message_, message.raw()); | 
|  15464 } |  14608 } | 
|  15465  |  14609  | 
|  15466  |  | 
|  15467 const char* ApiError::ToErrorCString() const { |  14610 const char* ApiError::ToErrorCString() const { | 
|  15468   const String& msg_str = String::Handle(message()); |  14611   const String& msg_str = String::Handle(message()); | 
|  15469   return msg_str.ToCString(); |  14612   return msg_str.ToCString(); | 
|  15470 } |  14613 } | 
|  15471  |  14614  | 
|  15472  |  | 
|  15473 const char* ApiError::ToCString() const { |  14615 const char* ApiError::ToCString() const { | 
|  15474   return "ApiError"; |  14616   return "ApiError"; | 
|  15475 } |  14617 } | 
|  15476  |  14618  | 
|  15477  |  | 
|  15478 RawLanguageError* LanguageError::New() { |  14619 RawLanguageError* LanguageError::New() { | 
|  15479   ASSERT(Object::language_error_class() != Class::null()); |  14620   ASSERT(Object::language_error_class() != Class::null()); | 
|  15480   RawObject* raw = Object::Allocate(LanguageError::kClassId, |  14621   RawObject* raw = Object::Allocate(LanguageError::kClassId, | 
|  15481                                     LanguageError::InstanceSize(), Heap::kOld); |  14622                                     LanguageError::InstanceSize(), Heap::kOld); | 
|  15482   return reinterpret_cast<RawLanguageError*>(raw); |  14623   return reinterpret_cast<RawLanguageError*>(raw); | 
|  15483 } |  14624 } | 
|  15484  |  14625  | 
|  15485  |  | 
|  15486 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error, |  14626 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error, | 
|  15487                                                const Script& script, |  14627                                                const Script& script, | 
|  15488                                                TokenPosition token_pos, |  14628                                                TokenPosition token_pos, | 
|  15489                                                bool report_after_token, |  14629                                                bool report_after_token, | 
|  15490                                                Report::Kind kind, |  14630                                                Report::Kind kind, | 
|  15491                                                Heap::Space space, |  14631                                                Heap::Space space, | 
|  15492                                                const char* format, |  14632                                                const char* format, | 
|  15493                                                va_list args) { |  14633                                                va_list args) { | 
|  15494   ASSERT(Object::language_error_class() != Class::null()); |  14634   ASSERT(Object::language_error_class() != Class::null()); | 
|  15495   LanguageError& result = LanguageError::Handle(); |  14635   LanguageError& result = LanguageError::Handle(); | 
|  15496   { |  14636   { | 
|  15497     RawObject* raw = Object::Allocate(LanguageError::kClassId, |  14637     RawObject* raw = Object::Allocate(LanguageError::kClassId, | 
|  15498                                       LanguageError::InstanceSize(), space); |  14638                                       LanguageError::InstanceSize(), space); | 
|  15499     NoSafepointScope no_safepoint; |  14639     NoSafepointScope no_safepoint; | 
|  15500     result ^= raw; |  14640     result ^= raw; | 
|  15501   } |  14641   } | 
|  15502   result.set_previous_error(prev_error); |  14642   result.set_previous_error(prev_error); | 
|  15503   result.set_script(script); |  14643   result.set_script(script); | 
|  15504   result.set_token_pos(token_pos); |  14644   result.set_token_pos(token_pos); | 
|  15505   result.set_report_after_token(report_after_token); |  14645   result.set_report_after_token(report_after_token); | 
|  15506   result.set_kind(kind); |  14646   result.set_kind(kind); | 
|  15507   result.set_message( |  14647   result.set_message( | 
|  15508       String::Handle(String::NewFormattedV(format, args, space))); |  14648       String::Handle(String::NewFormattedV(format, args, space))); | 
|  15509   return result.raw(); |  14649   return result.raw(); | 
|  15510 } |  14650 } | 
|  15511  |  14651  | 
|  15512  |  | 
|  15513 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error, |  14652 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error, | 
|  15514                                               const Script& script, |  14653                                               const Script& script, | 
|  15515                                               TokenPosition token_pos, |  14654                                               TokenPosition token_pos, | 
|  15516                                               bool report_after_token, |  14655                                               bool report_after_token, | 
|  15517                                               Report::Kind kind, |  14656                                               Report::Kind kind, | 
|  15518                                               Heap::Space space, |  14657                                               Heap::Space space, | 
|  15519                                               const char* format, |  14658                                               const char* format, | 
|  15520                                               ...) { |  14659                                               ...) { | 
|  15521   va_list args; |  14660   va_list args; | 
|  15522   va_start(args, format); |  14661   va_start(args, format); | 
|  15523   RawLanguageError* result = LanguageError::NewFormattedV( |  14662   RawLanguageError* result = LanguageError::NewFormattedV( | 
|  15524       prev_error, script, token_pos, report_after_token, kind, space, format, |  14663       prev_error, script, token_pos, report_after_token, kind, space, format, | 
|  15525       args); |  14664       args); | 
|  15526   NoSafepointScope no_safepoint; |  14665   NoSafepointScope no_safepoint; | 
|  15527   va_end(args); |  14666   va_end(args); | 
|  15528   return result; |  14667   return result; | 
|  15529 } |  14668 } | 
|  15530  |  14669  | 
|  15531  |  | 
|  15532 RawLanguageError* LanguageError::New(const String& formatted_message, |  14670 RawLanguageError* LanguageError::New(const String& formatted_message, | 
|  15533                                      Report::Kind kind, |  14671                                      Report::Kind kind, | 
|  15534                                      Heap::Space space) { |  14672                                      Heap::Space space) { | 
|  15535   ASSERT(Object::language_error_class() != Class::null()); |  14673   ASSERT(Object::language_error_class() != Class::null()); | 
|  15536   LanguageError& result = LanguageError::Handle(); |  14674   LanguageError& result = LanguageError::Handle(); | 
|  15537   { |  14675   { | 
|  15538     RawObject* raw = Object::Allocate(LanguageError::kClassId, |  14676     RawObject* raw = Object::Allocate(LanguageError::kClassId, | 
|  15539                                       LanguageError::InstanceSize(), space); |  14677                                       LanguageError::InstanceSize(), space); | 
|  15540     NoSafepointScope no_safepoint; |  14678     NoSafepointScope no_safepoint; | 
|  15541     result ^= raw; |  14679     result ^= raw; | 
|  15542   } |  14680   } | 
|  15543   result.set_formatted_message(formatted_message); |  14681   result.set_formatted_message(formatted_message); | 
|  15544   result.set_kind(kind); |  14682   result.set_kind(kind); | 
|  15545   return result.raw(); |  14683   return result.raw(); | 
|  15546 } |  14684 } | 
|  15547  |  14685  | 
|  15548  |  | 
|  15549 void LanguageError::set_previous_error(const Error& value) const { |  14686 void LanguageError::set_previous_error(const Error& value) const { | 
|  15550   StorePointer(&raw_ptr()->previous_error_, value.raw()); |  14687   StorePointer(&raw_ptr()->previous_error_, value.raw()); | 
|  15551 } |  14688 } | 
|  15552  |  14689  | 
|  15553  |  | 
|  15554 void LanguageError::set_script(const Script& value) const { |  14690 void LanguageError::set_script(const Script& value) const { | 
|  15555   StorePointer(&raw_ptr()->script_, value.raw()); |  14691   StorePointer(&raw_ptr()->script_, value.raw()); | 
|  15556 } |  14692 } | 
|  15557  |  14693  | 
|  15558  |  | 
|  15559 void LanguageError::set_token_pos(TokenPosition token_pos) const { |  14694 void LanguageError::set_token_pos(TokenPosition token_pos) const { | 
|  15560   ASSERT(!token_pos.IsClassifying()); |  14695   ASSERT(!token_pos.IsClassifying()); | 
|  15561   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |  14696   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|  15562 } |  14697 } | 
|  15563  |  14698  | 
|  15564  |  | 
|  15565 void LanguageError::set_report_after_token(bool value) { |  14699 void LanguageError::set_report_after_token(bool value) { | 
|  15566   StoreNonPointer(&raw_ptr()->report_after_token_, value); |  14700   StoreNonPointer(&raw_ptr()->report_after_token_, value); | 
|  15567 } |  14701 } | 
|  15568  |  14702  | 
|  15569  |  | 
|  15570 void LanguageError::set_kind(uint8_t value) const { |  14703 void LanguageError::set_kind(uint8_t value) const { | 
|  15571   StoreNonPointer(&raw_ptr()->kind_, value); |  14704   StoreNonPointer(&raw_ptr()->kind_, value); | 
|  15572 } |  14705 } | 
|  15573  |  14706  | 
|  15574  |  | 
|  15575 void LanguageError::set_message(const String& value) const { |  14707 void LanguageError::set_message(const String& value) const { | 
|  15576   StorePointer(&raw_ptr()->message_, value.raw()); |  14708   StorePointer(&raw_ptr()->message_, value.raw()); | 
|  15577 } |  14709 } | 
|  15578  |  14710  | 
|  15579  |  | 
|  15580 void LanguageError::set_formatted_message(const String& value) const { |  14711 void LanguageError::set_formatted_message(const String& value) const { | 
|  15581   StorePointer(&raw_ptr()->formatted_message_, value.raw()); |  14712   StorePointer(&raw_ptr()->formatted_message_, value.raw()); | 
|  15582 } |  14713 } | 
|  15583  |  14714  | 
|  15584  |  | 
|  15585 RawString* LanguageError::FormatMessage() const { |  14715 RawString* LanguageError::FormatMessage() const { | 
|  15586   if (formatted_message() != String::null()) { |  14716   if (formatted_message() != String::null()) { | 
|  15587     return formatted_message(); |  14717     return formatted_message(); | 
|  15588   } |  14718   } | 
|  15589   String& result = String::Handle( |  14719   String& result = String::Handle( | 
|  15590       Report::PrependSnippet(kind(), Script::Handle(script()), token_pos(), |  14720       Report::PrependSnippet(kind(), Script::Handle(script()), token_pos(), | 
|  15591                              report_after_token(), String::Handle(message()))); |  14721                              report_after_token(), String::Handle(message()))); | 
|  15592   // Prepend previous error message. |  14722   // Prepend previous error message. | 
|  15593   const Error& prev_error = Error::Handle(previous_error()); |  14723   const Error& prev_error = Error::Handle(previous_error()); | 
|  15594   if (!prev_error.IsNull()) { |  14724   if (!prev_error.IsNull()) { | 
|  15595     result = String::Concat( |  14725     result = String::Concat( | 
|  15596         String::Handle(String::New(prev_error.ToErrorCString())), result); |  14726         String::Handle(String::New(prev_error.ToErrorCString())), result); | 
|  15597   } |  14727   } | 
|  15598   set_formatted_message(result); |  14728   set_formatted_message(result); | 
|  15599   return result.raw(); |  14729   return result.raw(); | 
|  15600 } |  14730 } | 
|  15601  |  14731  | 
|  15602  |  | 
|  15603 const char* LanguageError::ToErrorCString() const { |  14732 const char* LanguageError::ToErrorCString() const { | 
|  15604   Thread* thread = Thread::Current(); |  14733   Thread* thread = Thread::Current(); | 
|  15605   NoReloadScope no_reload_scope(thread->isolate(), thread); |  14734   NoReloadScope no_reload_scope(thread->isolate(), thread); | 
|  15606   const String& msg_str = String::Handle(FormatMessage()); |  14735   const String& msg_str = String::Handle(FormatMessage()); | 
|  15607   return msg_str.ToCString(); |  14736   return msg_str.ToCString(); | 
|  15608 } |  14737 } | 
|  15609  |  14738  | 
|  15610  |  | 
|  15611 const char* LanguageError::ToCString() const { |  14739 const char* LanguageError::ToCString() const { | 
|  15612   return "LanguageError"; |  14740   return "LanguageError"; | 
|  15613 } |  14741 } | 
|  15614  |  14742  | 
|  15615  |  | 
|  15616 RawUnhandledException* UnhandledException::New(const Instance& exception, |  14743 RawUnhandledException* UnhandledException::New(const Instance& exception, | 
|  15617                                                const Instance& stacktrace, |  14744                                                const Instance& stacktrace, | 
|  15618                                                Heap::Space space) { |  14745                                                Heap::Space space) { | 
|  15619   ASSERT(Object::unhandled_exception_class() != Class::null()); |  14746   ASSERT(Object::unhandled_exception_class() != Class::null()); | 
|  15620   UnhandledException& result = UnhandledException::Handle(); |  14747   UnhandledException& result = UnhandledException::Handle(); | 
|  15621   { |  14748   { | 
|  15622     RawObject* raw = |  14749     RawObject* raw = | 
|  15623         Object::Allocate(UnhandledException::kClassId, |  14750         Object::Allocate(UnhandledException::kClassId, | 
|  15624                          UnhandledException::InstanceSize(), space); |  14751                          UnhandledException::InstanceSize(), space); | 
|  15625     NoSafepointScope no_safepoint; |  14752     NoSafepointScope no_safepoint; | 
|  15626     result ^= raw; |  14753     result ^= raw; | 
|  15627   } |  14754   } | 
|  15628   result.set_exception(exception); |  14755   result.set_exception(exception); | 
|  15629   result.set_stacktrace(stacktrace); |  14756   result.set_stacktrace(stacktrace); | 
|  15630   return result.raw(); |  14757   return result.raw(); | 
|  15631 } |  14758 } | 
|  15632  |  14759  | 
|  15633  |  | 
|  15634 RawUnhandledException* UnhandledException::New(Heap::Space space) { |  14760 RawUnhandledException* UnhandledException::New(Heap::Space space) { | 
|  15635   ASSERT(Object::unhandled_exception_class() != Class::null()); |  14761   ASSERT(Object::unhandled_exception_class() != Class::null()); | 
|  15636   UnhandledException& result = UnhandledException::Handle(); |  14762   UnhandledException& result = UnhandledException::Handle(); | 
|  15637   { |  14763   { | 
|  15638     RawObject* raw = |  14764     RawObject* raw = | 
|  15639         Object::Allocate(UnhandledException::kClassId, |  14765         Object::Allocate(UnhandledException::kClassId, | 
|  15640                          UnhandledException::InstanceSize(), space); |  14766                          UnhandledException::InstanceSize(), space); | 
|  15641     NoSafepointScope no_safepoint; |  14767     NoSafepointScope no_safepoint; | 
|  15642     result ^= raw; |  14768     result ^= raw; | 
|  15643   } |  14769   } | 
|  15644   result.set_exception(Object::null_instance()); |  14770   result.set_exception(Object::null_instance()); | 
|  15645   result.set_stacktrace(StackTrace::Handle()); |  14771   result.set_stacktrace(StackTrace::Handle()); | 
|  15646   return result.raw(); |  14772   return result.raw(); | 
|  15647 } |  14773 } | 
|  15648  |  14774  | 
|  15649  |  | 
|  15650 void UnhandledException::set_exception(const Instance& exception) const { |  14775 void UnhandledException::set_exception(const Instance& exception) const { | 
|  15651   StorePointer(&raw_ptr()->exception_, exception.raw()); |  14776   StorePointer(&raw_ptr()->exception_, exception.raw()); | 
|  15652 } |  14777 } | 
|  15653  |  14778  | 
|  15654  |  | 
|  15655 void UnhandledException::set_stacktrace(const Instance& stacktrace) const { |  14779 void UnhandledException::set_stacktrace(const Instance& stacktrace) const { | 
|  15656   StorePointer(&raw_ptr()->stacktrace_, stacktrace.raw()); |  14780   StorePointer(&raw_ptr()->stacktrace_, stacktrace.raw()); | 
|  15657 } |  14781 } | 
|  15658  |  14782  | 
|  15659  |  | 
|  15660 const char* UnhandledException::ToErrorCString() const { |  14783 const char* UnhandledException::ToErrorCString() const { | 
|  15661   Thread* thread = Thread::Current(); |  14784   Thread* thread = Thread::Current(); | 
|  15662   Isolate* isolate = thread->isolate(); |  14785   Isolate* isolate = thread->isolate(); | 
|  15663   NoReloadScope no_reload_scope(isolate, thread); |  14786   NoReloadScope no_reload_scope(isolate, thread); | 
|  15664   HANDLESCOPE(thread); |  14787   HANDLESCOPE(thread); | 
|  15665   Object& strtmp = Object::Handle(); |  14788   Object& strtmp = Object::Handle(); | 
|  15666   const char* exc_str; |  14789   const char* exc_str; | 
|  15667   if (exception() == isolate->object_store()->out_of_memory()) { |  14790   if (exception() == isolate->object_store()->out_of_memory()) { | 
|  15668     exc_str = "Out of Memory"; |  14791     exc_str = "Out of Memory"; | 
|  15669   } else if (exception() == isolate->object_store()->stack_overflow()) { |  14792   } else if (exception() == isolate->object_store()->stack_overflow()) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  15681   strtmp = DartLibraryCalls::ToString(stack); |  14804   strtmp = DartLibraryCalls::ToString(stack); | 
|  15682   const char* stack_str = |  14805   const char* stack_str = | 
|  15683       "<Received error while converting stack trace to string>"; |  14806       "<Received error while converting stack trace to string>"; | 
|  15684   if (!strtmp.IsError()) { |  14807   if (!strtmp.IsError()) { | 
|  15685     stack_str = strtmp.ToCString(); |  14808     stack_str = strtmp.ToCString(); | 
|  15686   } |  14809   } | 
|  15687   return OS::SCreate(thread->zone(), "Unhandled exception:\n%s\n%s", exc_str, |  14810   return OS::SCreate(thread->zone(), "Unhandled exception:\n%s\n%s", exc_str, | 
|  15688                      stack_str); |  14811                      stack_str); | 
|  15689 } |  14812 } | 
|  15690  |  14813  | 
|  15691  |  | 
|  15692 const char* UnhandledException::ToCString() const { |  14814 const char* UnhandledException::ToCString() const { | 
|  15693   return "UnhandledException"; |  14815   return "UnhandledException"; | 
|  15694 } |  14816 } | 
|  15695  |  14817  | 
|  15696  |  | 
|  15697 RawUnwindError* UnwindError::New(const String& message, Heap::Space space) { |  14818 RawUnwindError* UnwindError::New(const String& message, Heap::Space space) { | 
|  15698   ASSERT(Object::unwind_error_class() != Class::null()); |  14819   ASSERT(Object::unwind_error_class() != Class::null()); | 
|  15699   UnwindError& result = UnwindError::Handle(); |  14820   UnwindError& result = UnwindError::Handle(); | 
|  15700   { |  14821   { | 
|  15701     RawObject* raw = Object::Allocate(UnwindError::kClassId, |  14822     RawObject* raw = Object::Allocate(UnwindError::kClassId, | 
|  15702                                       UnwindError::InstanceSize(), space); |  14823                                       UnwindError::InstanceSize(), space); | 
|  15703     NoSafepointScope no_safepoint; |  14824     NoSafepointScope no_safepoint; | 
|  15704     result ^= raw; |  14825     result ^= raw; | 
|  15705   } |  14826   } | 
|  15706   result.set_message(message); |  14827   result.set_message(message); | 
|  15707   result.set_is_user_initiated(false); |  14828   result.set_is_user_initiated(false); | 
|  15708   return result.raw(); |  14829   return result.raw(); | 
|  15709 } |  14830 } | 
|  15710  |  14831  | 
|  15711  |  | 
|  15712 void UnwindError::set_message(const String& message) const { |  14832 void UnwindError::set_message(const String& message) const { | 
|  15713   StorePointer(&raw_ptr()->message_, message.raw()); |  14833   StorePointer(&raw_ptr()->message_, message.raw()); | 
|  15714 } |  14834 } | 
|  15715  |  14835  | 
|  15716  |  | 
|  15717 void UnwindError::set_is_user_initiated(bool value) const { |  14836 void UnwindError::set_is_user_initiated(bool value) const { | 
|  15718   StoreNonPointer(&raw_ptr()->is_user_initiated_, value); |  14837   StoreNonPointer(&raw_ptr()->is_user_initiated_, value); | 
|  15719 } |  14838 } | 
|  15720  |  14839  | 
|  15721  |  | 
|  15722 const char* UnwindError::ToErrorCString() const { |  14840 const char* UnwindError::ToErrorCString() const { | 
|  15723   const String& msg_str = String::Handle(message()); |  14841   const String& msg_str = String::Handle(message()); | 
|  15724   return msg_str.ToCString(); |  14842   return msg_str.ToCString(); | 
|  15725 } |  14843 } | 
|  15726  |  14844  | 
|  15727  |  | 
|  15728 const char* UnwindError::ToCString() const { |  14845 const char* UnwindError::ToCString() const { | 
|  15729   return "UnwindError"; |  14846   return "UnwindError"; | 
|  15730 } |  14847 } | 
|  15731  |  14848  | 
|  15732  |  | 
|  15733 RawObject* Instance::Evaluate(const Class& method_cls, |  14849 RawObject* Instance::Evaluate(const Class& method_cls, | 
|  15734                               const String& expr, |  14850                               const String& expr, | 
|  15735                               const Array& param_names, |  14851                               const Array& param_names, | 
|  15736                               const Array& param_values) const { |  14852                               const Array& param_values) const { | 
|  15737   const Function& eval_func = Function::Handle( |  14853   const Function& eval_func = Function::Handle( | 
|  15738       Function::EvaluateHelper(method_cls, expr, param_names, false)); |  14854       Function::EvaluateHelper(method_cls, expr, param_names, false)); | 
|  15739   const Array& args = Array::Handle(Array::New(1 + param_values.Length())); |  14855   const Array& args = Array::Handle(Array::New(1 + param_values.Length())); | 
|  15740   PassiveObject& param = PassiveObject::Handle(); |  14856   PassiveObject& param = PassiveObject::Handle(); | 
|  15741   args.SetAt(0, *this); |  14857   args.SetAt(0, *this); | 
|  15742   for (intptr_t i = 0; i < param_values.Length(); i++) { |  14858   for (intptr_t i = 0; i < param_values.Length(); i++) { | 
|  15743     param = param_values.At(i); |  14859     param = param_values.At(i); | 
|  15744     args.SetAt(i + 1, param); |  14860     args.SetAt(i + 1, param); | 
|  15745   } |  14861   } | 
|  15746   return DartEntry::InvokeFunction(eval_func, args); |  14862   return DartEntry::InvokeFunction(eval_func, args); | 
|  15747 } |  14863 } | 
|  15748  |  14864  | 
|  15749  |  | 
|  15750 RawObject* Instance::HashCode() const { |  14865 RawObject* Instance::HashCode() const { | 
|  15751   // TODO(koda): Optimize for all builtin classes and all classes |  14866   // TODO(koda): Optimize for all builtin classes and all classes | 
|  15752   // that do not override hashCode. |  14867   // that do not override hashCode. | 
|  15753   return DartLibraryCalls::HashCode(*this); |  14868   return DartLibraryCalls::HashCode(*this); | 
|  15754 } |  14869 } | 
|  15755  |  14870  | 
|  15756  |  | 
|  15757 bool Instance::CanonicalizeEquals(const Instance& other) const { |  14871 bool Instance::CanonicalizeEquals(const Instance& other) const { | 
|  15758   if (this->raw() == other.raw()) { |  14872   if (this->raw() == other.raw()) { | 
|  15759     return true;  // "===". |  14873     return true;  // "===". | 
|  15760   } |  14874   } | 
|  15761  |  14875  | 
|  15762   if (other.IsNull() || (this->clazz() != other.clazz())) { |  14876   if (other.IsNull() || (this->clazz() != other.clazz())) { | 
|  15763     return false; |  14877     return false; | 
|  15764   } |  14878   } | 
|  15765  |  14879  | 
|  15766   { |  14880   { | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  15779          offset += kWordSize) { |  14893          offset += kWordSize) { | 
|  15780       if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != |  14894       if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != | 
|  15781           (*reinterpret_cast<RawObject**>(other_addr + offset))) { |  14895           (*reinterpret_cast<RawObject**>(other_addr + offset))) { | 
|  15782         return false; |  14896         return false; | 
|  15783       } |  14897       } | 
|  15784     } |  14898     } | 
|  15785   } |  14899   } | 
|  15786   return true; |  14900   return true; | 
|  15787 } |  14901 } | 
|  15788  |  14902  | 
|  15789  |  | 
|  15790 uword Instance::ComputeCanonicalTableHash() const { |  14903 uword Instance::ComputeCanonicalTableHash() const { | 
|  15791   ASSERT(!IsNull()); |  14904   ASSERT(!IsNull()); | 
|  15792   NoSafepointScope no_safepoint; |  14905   NoSafepointScope no_safepoint; | 
|  15793   const intptr_t instance_size = SizeFromClass(); |  14906   const intptr_t instance_size = SizeFromClass(); | 
|  15794   ASSERT(instance_size != 0); |  14907   ASSERT(instance_size != 0); | 
|  15795   uword hash = instance_size; |  14908   uword hash = instance_size; | 
|  15796   uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); |  14909   uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); | 
|  15797   for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; |  14910   for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; | 
|  15798        offset += kWordSize) { |  14911        offset += kWordSize) { | 
|  15799     uword value = reinterpret_cast<uword>( |  14912     uword value = reinterpret_cast<uword>( | 
|  15800         *reinterpret_cast<RawObject**>(this_addr + offset)); |  14913         *reinterpret_cast<RawObject**>(this_addr + offset)); | 
|  15801     hash = CombineHashes(hash, value); |  14914     hash = CombineHashes(hash, value); | 
|  15802   } |  14915   } | 
|  15803   return FinalizeHash(hash, (kBitsPerWord - 1)); |  14916   return FinalizeHash(hash, (kBitsPerWord - 1)); | 
|  15804 } |  14917 } | 
|  15805  |  14918  | 
|  15806  |  | 
|  15807 #if defined(DEBUG) |  14919 #if defined(DEBUG) | 
|  15808 class CheckForPointers : public ObjectPointerVisitor { |  14920 class CheckForPointers : public ObjectPointerVisitor { | 
|  15809  public: |  14921  public: | 
|  15810   explicit CheckForPointers(Isolate* isolate) |  14922   explicit CheckForPointers(Isolate* isolate) | 
|  15811       : ObjectPointerVisitor(isolate), has_pointers_(false) {} |  14923       : ObjectPointerVisitor(isolate), has_pointers_(false) {} | 
|  15812  |  14924  | 
|  15813   bool has_pointers() const { return has_pointers_; } |  14925   bool has_pointers() const { return has_pointers_; } | 
|  15814  |  14926  | 
|  15815   void VisitPointers(RawObject** first, RawObject** last) { |  14927   void VisitPointers(RawObject** first, RawObject** last) { | 
|  15816     if (first != last) { |  14928     if (first != last) { | 
|  15817       has_pointers_ = true; |  14929       has_pointers_ = true; | 
|  15818     } |  14930     } | 
|  15819   } |  14931   } | 
|  15820  |  14932  | 
|  15821  private: |  14933  private: | 
|  15822   bool has_pointers_; |  14934   bool has_pointers_; | 
|  15823  |  14935  | 
|  15824   DISALLOW_COPY_AND_ASSIGN(CheckForPointers); |  14936   DISALLOW_COPY_AND_ASSIGN(CheckForPointers); | 
|  15825 }; |  14937 }; | 
|  15826 #endif  // DEBUG |  14938 #endif  // DEBUG | 
|  15827  |  14939  | 
|  15828  |  | 
|  15829 bool Instance::CheckAndCanonicalizeFields(Thread* thread, |  14940 bool Instance::CheckAndCanonicalizeFields(Thread* thread, | 
|  15830                                           const char** error_str) const { |  14941                                           const char** error_str) const { | 
|  15831   if (GetClassId() >= kNumPredefinedCids) { |  14942   if (GetClassId() >= kNumPredefinedCids) { | 
|  15832     // Iterate over all fields, canonicalize numbers and strings, expect all |  14943     // Iterate over all fields, canonicalize numbers and strings, expect all | 
|  15833     // other instances to be canonical otherwise report error (return false). |  14944     // other instances to be canonical otherwise report error (return false). | 
|  15834     Zone* zone = thread->zone(); |  14945     Zone* zone = thread->zone(); | 
|  15835     Object& obj = Object::Handle(zone); |  14946     Object& obj = Object::Handle(zone); | 
|  15836     const intptr_t instance_size = SizeFromClass(); |  14947     const intptr_t instance_size = SizeFromClass(); | 
|  15837     ASSERT(instance_size != 0); |  14948     ASSERT(instance_size != 0); | 
|  15838     for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; |  14949     for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  15855 #if defined(DEBUG) |  14966 #if defined(DEBUG) | 
|  15856     // Make sure that we are not missing any fields. |  14967     // Make sure that we are not missing any fields. | 
|  15857     CheckForPointers has_pointers(Isolate::Current()); |  14968     CheckForPointers has_pointers(Isolate::Current()); | 
|  15858     this->raw()->VisitPointers(&has_pointers); |  14969     this->raw()->VisitPointers(&has_pointers); | 
|  15859     ASSERT(!has_pointers.has_pointers()); |  14970     ASSERT(!has_pointers.has_pointers()); | 
|  15860 #endif  // DEBUG |  14971 #endif  // DEBUG | 
|  15861   } |  14972   } | 
|  15862   return true; |  14973   return true; | 
|  15863 } |  14974 } | 
|  15864  |  14975  | 
|  15865  |  | 
|  15866 RawInstance* Instance::CheckAndCanonicalize(Thread* thread, |  14976 RawInstance* Instance::CheckAndCanonicalize(Thread* thread, | 
|  15867                                             const char** error_str) const { |  14977                                             const char** error_str) const { | 
|  15868   ASSERT(!IsNull()); |  14978   ASSERT(!IsNull()); | 
|  15869   if (this->IsCanonical()) { |  14979   if (this->IsCanonical()) { | 
|  15870     return this->raw(); |  14980     return this->raw(); | 
|  15871   } |  14981   } | 
|  15872   if (!CheckAndCanonicalizeFields(thread, error_str)) { |  14982   if (!CheckAndCanonicalizeFields(thread, error_str)) { | 
|  15873     return Instance::null(); |  14983     return Instance::null(); | 
|  15874   } |  14984   } | 
|  15875   Zone* zone = thread->zone(); |  14985   Zone* zone = thread->zone(); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  15888       result ^= Object::Clone(*this, Heap::kOld); |  14998       result ^= Object::Clone(*this, Heap::kOld); | 
|  15889     } else { |  14999     } else { | 
|  15890       result ^= this->raw(); |  15000       result ^= this->raw(); | 
|  15891     } |  15001     } | 
|  15892     ASSERT(result.IsOld()); |  15002     ASSERT(result.IsOld()); | 
|  15893     result.SetCanonical(); |  15003     result.SetCanonical(); | 
|  15894     return cls.InsertCanonicalConstant(zone, result); |  15004     return cls.InsertCanonicalConstant(zone, result); | 
|  15895   } |  15005   } | 
|  15896 } |  15006 } | 
|  15897  |  15007  | 
|  15898  |  | 
|  15899 #if defined(DEBUG) |  15008 #if defined(DEBUG) | 
|  15900 bool Instance::CheckIsCanonical(Thread* thread) const { |  15009 bool Instance::CheckIsCanonical(Thread* thread) const { | 
|  15901   Zone* zone = thread->zone(); |  15010   Zone* zone = thread->zone(); | 
|  15902   Isolate* isolate = thread->isolate(); |  15011   Isolate* isolate = thread->isolate(); | 
|  15903   Instance& result = Instance::Handle(zone); |  15012   Instance& result = Instance::Handle(zone); | 
|  15904   const Class& cls = Class::Handle(zone, this->clazz()); |  15013   const Class& cls = Class::Handle(zone, this->clazz()); | 
|  15905   SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |  15014   SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 
|  15906   result ^= cls.LookupCanonicalInstance(zone, *this); |  15015   result ^= cls.LookupCanonicalInstance(zone, *this); | 
|  15907   return (result.raw() == this->raw()); |  15016   return (result.raw() == this->raw()); | 
|  15908 } |  15017 } | 
|  15909 #endif  // DEBUG |  15018 #endif  // DEBUG | 
|  15910  |  15019  | 
|  15911  |  | 
|  15912 RawAbstractType* Instance::GetType(Heap::Space space) const { |  15020 RawAbstractType* Instance::GetType(Heap::Space space) const { | 
|  15913   if (IsNull()) { |  15021   if (IsNull()) { | 
|  15914     return Type::NullType(); |  15022     return Type::NullType(); | 
|  15915   } |  15023   } | 
|  15916   const Class& cls = Class::Handle(clazz()); |  15024   const Class& cls = Class::Handle(clazz()); | 
|  15917   if (cls.IsClosureClass()) { |  15025   if (cls.IsClosureClass()) { | 
|  15918     const Function& signature = |  15026     const Function& signature = | 
|  15919         Function::Handle(Closure::Cast(*this).function()); |  15027         Function::Handle(Closure::Cast(*this).function()); | 
|  15920     Type& type = Type::Handle(signature.SignatureType()); |  15028     Type& type = Type::Handle(signature.SignatureType()); | 
|  15921     if (!type.IsInstantiated()) { |  15029     if (!type.IsInstantiated()) { | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  15940     if (cls.NumTypeArguments() > 0) { |  15048     if (cls.NumTypeArguments() > 0) { | 
|  15941       type_arguments = GetTypeArguments(); |  15049       type_arguments = GetTypeArguments(); | 
|  15942     } |  15050     } | 
|  15943     type = Type::New(cls, type_arguments, TokenPosition::kNoSource, space); |  15051     type = Type::New(cls, type_arguments, TokenPosition::kNoSource, space); | 
|  15944     type.SetIsFinalized(); |  15052     type.SetIsFinalized(); | 
|  15945     type ^= type.Canonicalize(); |  15053     type ^= type.Canonicalize(); | 
|  15946   } |  15054   } | 
|  15947   return type.raw(); |  15055   return type.raw(); | 
|  15948 } |  15056 } | 
|  15949  |  15057  | 
|  15950  |  | 
|  15951 RawTypeArguments* Instance::GetTypeArguments() const { |  15058 RawTypeArguments* Instance::GetTypeArguments() const { | 
|  15952   const Class& cls = Class::Handle(clazz()); |  15059   const Class& cls = Class::Handle(clazz()); | 
|  15953   intptr_t field_offset = cls.type_arguments_field_offset(); |  15060   intptr_t field_offset = cls.type_arguments_field_offset(); | 
|  15954   ASSERT(field_offset != Class::kNoTypeArguments); |  15061   ASSERT(field_offset != Class::kNoTypeArguments); | 
|  15955   TypeArguments& type_arguments = TypeArguments::Handle(); |  15062   TypeArguments& type_arguments = TypeArguments::Handle(); | 
|  15956   type_arguments ^= *FieldAddrAtOffset(field_offset); |  15063   type_arguments ^= *FieldAddrAtOffset(field_offset); | 
|  15957   return type_arguments.raw(); |  15064   return type_arguments.raw(); | 
|  15958 } |  15065 } | 
|  15959  |  15066  | 
|  15960  |  | 
|  15961 void Instance::SetTypeArguments(const TypeArguments& value) const { |  15067 void Instance::SetTypeArguments(const TypeArguments& value) const { | 
|  15962   ASSERT(value.IsNull() || value.IsCanonical()); |  15068   ASSERT(value.IsNull() || value.IsCanonical()); | 
|  15963   const Class& cls = Class::Handle(clazz()); |  15069   const Class& cls = Class::Handle(clazz()); | 
|  15964   intptr_t field_offset = cls.type_arguments_field_offset(); |  15070   intptr_t field_offset = cls.type_arguments_field_offset(); | 
|  15965   ASSERT(field_offset != Class::kNoTypeArguments); |  15071   ASSERT(field_offset != Class::kNoTypeArguments); | 
|  15966   SetFieldAtOffset(field_offset, value); |  15072   SetFieldAtOffset(field_offset, value); | 
|  15967 } |  15073 } | 
|  15968  |  15074  | 
|  15969  |  | 
|  15970 bool Instance::IsInstanceOf( |  15075 bool Instance::IsInstanceOf( | 
|  15971     const AbstractType& other, |  15076     const AbstractType& other, | 
|  15972     const TypeArguments& other_instantiator_type_arguments, |  15077     const TypeArguments& other_instantiator_type_arguments, | 
|  15973     const TypeArguments& other_function_type_arguments, |  15078     const TypeArguments& other_function_type_arguments, | 
|  15974     Error* bound_error) const { |  15079     Error* bound_error) const { | 
|  15975   ASSERT(other.IsFinalized()); |  15080   ASSERT(other.IsFinalized()); | 
|  15976   ASSERT(!other.IsDynamicType()); |  15081   ASSERT(!other.IsDynamicType()); | 
|  15977   ASSERT(!other.IsTypeRef());  // Must be dereferenced at compile time. |  15082   ASSERT(!other.IsTypeRef());  // Must be dereferenced at compile time. | 
|  15978   ASSERT(!other.IsMalformed()); |  15083   ASSERT(!other.IsMalformed()); | 
|  15979   ASSERT(!other.IsMalbounded()); |  15084   ASSERT(!other.IsMalbounded()); | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  16094   if (IsNull()) { |  15199   if (IsNull()) { | 
|  16095     ASSERT(cls.IsNullClass()); |  15200     ASSERT(cls.IsNullClass()); | 
|  16096     // As of Dart 1.5, the null instance and Null type are handled differently. |  15201     // As of Dart 1.5, the null instance and Null type are handled differently. | 
|  16097     // We already checked other for dynamic and void. |  15202     // We already checked other for dynamic and void. | 
|  16098     return other_class.IsNullClass() || other_class.IsObjectClass(); |  15203     return other_class.IsNullClass() || other_class.IsObjectClass(); | 
|  16099   } |  15204   } | 
|  16100   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |  15205   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 
|  16101                          bound_error, NULL, Heap::kOld); |  15206                          bound_error, NULL, Heap::kOld); | 
|  16102 } |  15207 } | 
|  16103  |  15208  | 
|  16104  |  | 
|  16105 bool Instance::OperatorEquals(const Instance& other) const { |  15209 bool Instance::OperatorEquals(const Instance& other) const { | 
|  16106   // TODO(koda): Optimize for all builtin classes and all classes |  15210   // TODO(koda): Optimize for all builtin classes and all classes | 
|  16107   // that do not override operator==. |  15211   // that do not override operator==. | 
|  16108   return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |  15212   return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 
|  16109 } |  15213 } | 
|  16110  |  15214  | 
|  16111  |  | 
|  16112 bool Instance::IsIdenticalTo(const Instance& other) const { |  15215 bool Instance::IsIdenticalTo(const Instance& other) const { | 
|  16113   if (raw() == other.raw()) return true; |  15216   if (raw() == other.raw()) return true; | 
|  16114   if (IsInteger() && other.IsInteger()) { |  15217   if (IsInteger() && other.IsInteger()) { | 
|  16115     return Integer::Cast(*this).Equals(other); |  15218     return Integer::Cast(*this).Equals(other); | 
|  16116   } |  15219   } | 
|  16117   if (IsDouble() && other.IsDouble()) { |  15220   if (IsDouble() && other.IsDouble()) { | 
|  16118     double other_value = Double::Cast(other).value(); |  15221     double other_value = Double::Cast(other).value(); | 
|  16119     return Double::Cast(*this).BitwiseEqualsToDouble(other_value); |  15222     return Double::Cast(*this).BitwiseEqualsToDouble(other_value); | 
|  16120   } |  15223   } | 
|  16121   return false; |  15224   return false; | 
|  16122 } |  15225 } | 
|  16123  |  15226  | 
|  16124  |  | 
|  16125 intptr_t* Instance::NativeFieldsDataAddr() const { |  15227 intptr_t* Instance::NativeFieldsDataAddr() const { | 
|  16126   ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |  15228   ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); | 
|  16127   RawTypedData* native_fields = |  15229   RawTypedData* native_fields = | 
|  16128       reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); |  15230       reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); | 
|  16129   if (native_fields == TypedData::null()) { |  15231   if (native_fields == TypedData::null()) { | 
|  16130     return NULL; |  15232     return NULL; | 
|  16131   } |  15233   } | 
|  16132   return reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); |  15234   return reinterpret_cast<intptr_t*>(native_fields->ptr()->data()); | 
|  16133 } |  15235 } | 
|  16134  |  15236  | 
|  16135  |  | 
|  16136 void Instance::SetNativeField(int index, intptr_t value) const { |  15237 void Instance::SetNativeField(int index, intptr_t value) const { | 
|  16137   ASSERT(IsValidNativeIndex(index)); |  15238   ASSERT(IsValidNativeIndex(index)); | 
|  16138   Object& native_fields = Object::Handle(*NativeFieldsAddr()); |  15239   Object& native_fields = Object::Handle(*NativeFieldsAddr()); | 
|  16139   if (native_fields.IsNull()) { |  15240   if (native_fields.IsNull()) { | 
|  16140     // Allocate backing storage for the native fields. |  15241     // Allocate backing storage for the native fields. | 
|  16141     native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); |  15242     native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); | 
|  16142     StorePointer(NativeFieldsAddr(), native_fields.raw()); |  15243     StorePointer(NativeFieldsAddr(), native_fields.raw()); | 
|  16143   } |  15244   } | 
|  16144   intptr_t byte_offset = index * sizeof(intptr_t); |  15245   intptr_t byte_offset = index * sizeof(intptr_t); | 
|  16145   TypedData::Cast(native_fields).SetIntPtr(byte_offset, value); |  15246   TypedData::Cast(native_fields).SetIntPtr(byte_offset, value); | 
|  16146 } |  15247 } | 
|  16147  |  15248  | 
|  16148  |  | 
|  16149 void Instance::SetNativeFields(uint16_t num_native_fields, |  15249 void Instance::SetNativeFields(uint16_t num_native_fields, | 
|  16150                                const intptr_t* field_values) const { |  15250                                const intptr_t* field_values) const { | 
|  16151   ASSERT(num_native_fields == NumNativeFields()); |  15251   ASSERT(num_native_fields == NumNativeFields()); | 
|  16152   ASSERT(field_values != NULL); |  15252   ASSERT(field_values != NULL); | 
|  16153   Object& native_fields = Object::Handle(*NativeFieldsAddr()); |  15253   Object& native_fields = Object::Handle(*NativeFieldsAddr()); | 
|  16154   if (native_fields.IsNull()) { |  15254   if (native_fields.IsNull()) { | 
|  16155     // Allocate backing storage for the native fields. |  15255     // Allocate backing storage for the native fields. | 
|  16156     native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); |  15256     native_fields = TypedData::New(kIntPtrCid, NumNativeFields()); | 
|  16157     StorePointer(NativeFieldsAddr(), native_fields.raw()); |  15257     StorePointer(NativeFieldsAddr(), native_fields.raw()); | 
|  16158   } |  15258   } | 
|  16159   for (uint16_t i = 0; i < num_native_fields; i++) { |  15259   for (uint16_t i = 0; i < num_native_fields; i++) { | 
|  16160     intptr_t byte_offset = i * sizeof(intptr_t); |  15260     intptr_t byte_offset = i * sizeof(intptr_t); | 
|  16161     TypedData::Cast(native_fields).SetIntPtr(byte_offset, field_values[i]); |  15261     TypedData::Cast(native_fields).SetIntPtr(byte_offset, field_values[i]); | 
|  16162   } |  15262   } | 
|  16163 } |  15263 } | 
|  16164  |  15264  | 
|  16165  |  | 
|  16166 bool Instance::IsCallable(Function* function) const { |  15265 bool Instance::IsCallable(Function* function) const { | 
|  16167   Class& cls = Class::Handle(clazz()); |  15266   Class& cls = Class::Handle(clazz()); | 
|  16168   if (cls.IsClosureClass()) { |  15267   if (cls.IsClosureClass()) { | 
|  16169     if (function != NULL) { |  15268     if (function != NULL) { | 
|  16170       *function = Closure::Cast(*this).function(); |  15269       *function = Closure::Cast(*this).function(); | 
|  16171     } |  15270     } | 
|  16172     return true; |  15271     return true; | 
|  16173   } |  15272   } | 
|  16174   // Try to resolve a "call" method. |  15273   // Try to resolve a "call" method. | 
|  16175   Function& call_function = Function::Handle(); |  15274   Function& call_function = Function::Handle(); | 
|  16176   do { |  15275   do { | 
|  16177     call_function = cls.LookupDynamicFunction(Symbols::Call()); |  15276     call_function = cls.LookupDynamicFunction(Symbols::Call()); | 
|  16178     if (!call_function.IsNull()) { |  15277     if (!call_function.IsNull()) { | 
|  16179       if (function != NULL) { |  15278       if (function != NULL) { | 
|  16180         *function = call_function.raw(); |  15279         *function = call_function.raw(); | 
|  16181       } |  15280       } | 
|  16182       return true; |  15281       return true; | 
|  16183     } |  15282     } | 
|  16184     cls = cls.SuperClass(); |  15283     cls = cls.SuperClass(); | 
|  16185   } while (!cls.IsNull()); |  15284   } while (!cls.IsNull()); | 
|  16186   return false; |  15285   return false; | 
|  16187 } |  15286 } | 
|  16188  |  15287  | 
|  16189  |  | 
|  16190 RawInstance* Instance::New(const Class& cls, Heap::Space space) { |  15288 RawInstance* Instance::New(const Class& cls, Heap::Space space) { | 
|  16191   Thread* thread = Thread::Current(); |  15289   Thread* thread = Thread::Current(); | 
|  16192   if (cls.EnsureIsFinalized(thread) != Error::null()) { |  15290   if (cls.EnsureIsFinalized(thread) != Error::null()) { | 
|  16193     return Instance::null(); |  15291     return Instance::null(); | 
|  16194   } |  15292   } | 
|  16195   intptr_t instance_size = cls.instance_size(); |  15293   intptr_t instance_size = cls.instance_size(); | 
|  16196   ASSERT(instance_size > 0); |  15294   ASSERT(instance_size > 0); | 
|  16197   RawObject* raw = Object::Allocate(cls.id(), instance_size, space); |  15295   RawObject* raw = Object::Allocate(cls.id(), instance_size, space); | 
|  16198   return reinterpret_cast<RawInstance*>(raw); |  15296   return reinterpret_cast<RawInstance*>(raw); | 
|  16199 } |  15297 } | 
|  16200  |  15298  | 
|  16201  |  | 
|  16202 bool Instance::IsValidFieldOffset(intptr_t offset) const { |  15299 bool Instance::IsValidFieldOffset(intptr_t offset) const { | 
|  16203   Thread* thread = Thread::Current(); |  15300   Thread* thread = Thread::Current(); | 
|  16204   REUSABLE_CLASS_HANDLESCOPE(thread); |  15301   REUSABLE_CLASS_HANDLESCOPE(thread); | 
|  16205   Class& cls = thread->ClassHandle(); |  15302   Class& cls = thread->ClassHandle(); | 
|  16206   cls = clazz(); |  15303   cls = clazz(); | 
|  16207   return (offset >= 0 && offset <= (cls.instance_size() - kWordSize)); |  15304   return (offset >= 0 && offset <= (cls.instance_size() - kWordSize)); | 
|  16208 } |  15305 } | 
|  16209  |  15306  | 
|  16210  |  | 
|  16211 intptr_t Instance::ElementSizeFor(intptr_t cid) { |  15307 intptr_t Instance::ElementSizeFor(intptr_t cid) { | 
|  16212   if (RawObject::IsExternalTypedDataClassId(cid)) { |  15308   if (RawObject::IsExternalTypedDataClassId(cid)) { | 
|  16213     return ExternalTypedData::ElementSizeInBytes(cid); |  15309     return ExternalTypedData::ElementSizeInBytes(cid); | 
|  16214   } else if (RawObject::IsTypedDataClassId(cid)) { |  15310   } else if (RawObject::IsTypedDataClassId(cid)) { | 
|  16215     return TypedData::ElementSizeInBytes(cid); |  15311     return TypedData::ElementSizeInBytes(cid); | 
|  16216   } |  15312   } | 
|  16217   switch (cid) { |  15313   switch (cid) { | 
|  16218     case kArrayCid: |  15314     case kArrayCid: | 
|  16219     case kImmutableArrayCid: |  15315     case kImmutableArrayCid: | 
|  16220       return Array::kBytesPerElement; |  15316       return Array::kBytesPerElement; | 
|  16221     case kOneByteStringCid: |  15317     case kOneByteStringCid: | 
|  16222       return OneByteString::kBytesPerElement; |  15318       return OneByteString::kBytesPerElement; | 
|  16223     case kTwoByteStringCid: |  15319     case kTwoByteStringCid: | 
|  16224       return TwoByteString::kBytesPerElement; |  15320       return TwoByteString::kBytesPerElement; | 
|  16225     case kExternalOneByteStringCid: |  15321     case kExternalOneByteStringCid: | 
|  16226       return ExternalOneByteString::kBytesPerElement; |  15322       return ExternalOneByteString::kBytesPerElement; | 
|  16227     case kExternalTwoByteStringCid: |  15323     case kExternalTwoByteStringCid: | 
|  16228       return ExternalTwoByteString::kBytesPerElement; |  15324       return ExternalTwoByteString::kBytesPerElement; | 
|  16229     default: |  15325     default: | 
|  16230       UNIMPLEMENTED(); |  15326       UNIMPLEMENTED(); | 
|  16231       return 0; |  15327       return 0; | 
|  16232   } |  15328   } | 
|  16233 } |  15329 } | 
|  16234  |  15330  | 
|  16235  |  | 
|  16236 intptr_t Instance::DataOffsetFor(intptr_t cid) { |  15331 intptr_t Instance::DataOffsetFor(intptr_t cid) { | 
|  16237   if (RawObject::IsExternalTypedDataClassId(cid) || |  15332   if (RawObject::IsExternalTypedDataClassId(cid) || | 
|  16238       RawObject::IsExternalStringClassId(cid)) { |  15333       RawObject::IsExternalStringClassId(cid)) { | 
|  16239     // Elements start at offset 0 of the external data. |  15334     // Elements start at offset 0 of the external data. | 
|  16240     return 0; |  15335     return 0; | 
|  16241   } |  15336   } | 
|  16242   if (RawObject::IsTypedDataClassId(cid)) { |  15337   if (RawObject::IsTypedDataClassId(cid)) { | 
|  16243     return TypedData::data_offset(); |  15338     return TypedData::data_offset(); | 
|  16244   } |  15339   } | 
|  16245   switch (cid) { |  15340   switch (cid) { | 
|  16246     case kArrayCid: |  15341     case kArrayCid: | 
|  16247     case kImmutableArrayCid: |  15342     case kImmutableArrayCid: | 
|  16248       return Array::data_offset(); |  15343       return Array::data_offset(); | 
|  16249     case kOneByteStringCid: |  15344     case kOneByteStringCid: | 
|  16250       return OneByteString::data_offset(); |  15345       return OneByteString::data_offset(); | 
|  16251     case kTwoByteStringCid: |  15346     case kTwoByteStringCid: | 
|  16252       return TwoByteString::data_offset(); |  15347       return TwoByteString::data_offset(); | 
|  16253     default: |  15348     default: | 
|  16254       UNIMPLEMENTED(); |  15349       UNIMPLEMENTED(); | 
|  16255       return Array::data_offset(); |  15350       return Array::data_offset(); | 
|  16256   } |  15351   } | 
|  16257 } |  15352 } | 
|  16258  |  15353  | 
|  16259  |  | 
|  16260 const char* Instance::ToCString() const { |  15354 const char* Instance::ToCString() const { | 
|  16261   if (IsNull()) { |  15355   if (IsNull()) { | 
|  16262     return "null"; |  15356     return "null"; | 
|  16263   } else if (raw() == Object::sentinel().raw()) { |  15357   } else if (raw() == Object::sentinel().raw()) { | 
|  16264     return "sentinel"; |  15358     return "sentinel"; | 
|  16265   } else if (raw() == Object::transition_sentinel().raw()) { |  15359   } else if (raw() == Object::transition_sentinel().raw()) { | 
|  16266     return "transition_sentinel"; |  15360     return "transition_sentinel"; | 
|  16267   } else if (raw() == Object::unknown_constant().raw()) { |  15361   } else if (raw() == Object::unknown_constant().raw()) { | 
|  16268     return "unknown_constant"; |  15362     return "unknown_constant"; | 
|  16269   } else if (raw() == Object::non_constant().raw()) { |  15363   } else if (raw() == Object::non_constant().raw()) { | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  16282       type_arguments = GetTypeArguments(); |  15376       type_arguments = GetTypeArguments(); | 
|  16283     } |  15377     } | 
|  16284     const Type& type = |  15378     const Type& type = | 
|  16285         Type::Handle(Type::New(cls, type_arguments, TokenPosition::kNoSource)); |  15379         Type::Handle(Type::New(cls, type_arguments, TokenPosition::kNoSource)); | 
|  16286     const String& type_name = String::Handle(type.UserVisibleName()); |  15380     const String& type_name = String::Handle(type.UserVisibleName()); | 
|  16287     return OS::SCreate(Thread::Current()->zone(), "Instance of '%s'", |  15381     return OS::SCreate(Thread::Current()->zone(), "Instance of '%s'", | 
|  16288                        type_name.ToCString()); |  15382                        type_name.ToCString()); | 
|  16289   } |  15383   } | 
|  16290 } |  15384 } | 
|  16291  |  15385  | 
|  16292  |  | 
|  16293 bool AbstractType::IsResolved() const { |  15386 bool AbstractType::IsResolved() const { | 
|  16294   // AbstractType is an abstract class. |  15387   // AbstractType is an abstract class. | 
|  16295   UNREACHABLE(); |  15388   UNREACHABLE(); | 
|  16296   return false; |  15389   return false; | 
|  16297 } |  15390 } | 
|  16298  |  15391  | 
|  16299  |  | 
|  16300 void AbstractType::SetIsResolved() const { |  15392 void AbstractType::SetIsResolved() const { | 
|  16301   // AbstractType is an abstract class. |  15393   // AbstractType is an abstract class. | 
|  16302   UNREACHABLE(); |  15394   UNREACHABLE(); | 
|  16303 } |  15395 } | 
|  16304  |  15396  | 
|  16305  |  | 
|  16306 bool AbstractType::HasResolvedTypeClass() const { |  15397 bool AbstractType::HasResolvedTypeClass() const { | 
|  16307   // AbstractType is an abstract class. |  15398   // AbstractType is an abstract class. | 
|  16308   UNREACHABLE(); |  15399   UNREACHABLE(); | 
|  16309   return false; |  15400   return false; | 
|  16310 } |  15401 } | 
|  16311  |  15402  | 
|  16312  |  | 
|  16313 classid_t AbstractType::type_class_id() const { |  15403 classid_t AbstractType::type_class_id() const { | 
|  16314   // AbstractType is an abstract class. |  15404   // AbstractType is an abstract class. | 
|  16315   UNREACHABLE(); |  15405   UNREACHABLE(); | 
|  16316   return kIllegalCid; |  15406   return kIllegalCid; | 
|  16317 } |  15407 } | 
|  16318  |  15408  | 
|  16319  |  | 
|  16320 RawClass* AbstractType::type_class() const { |  15409 RawClass* AbstractType::type_class() const { | 
|  16321   // AbstractType is an abstract class. |  15410   // AbstractType is an abstract class. | 
|  16322   UNREACHABLE(); |  15411   UNREACHABLE(); | 
|  16323   return Class::null(); |  15412   return Class::null(); | 
|  16324 } |  15413 } | 
|  16325  |  15414  | 
|  16326  |  | 
|  16327 RawUnresolvedClass* AbstractType::unresolved_class() const { |  15415 RawUnresolvedClass* AbstractType::unresolved_class() const { | 
|  16328   // AbstractType is an abstract class. |  15416   // AbstractType is an abstract class. | 
|  16329   UNREACHABLE(); |  15417   UNREACHABLE(); | 
|  16330   return UnresolvedClass::null(); |  15418   return UnresolvedClass::null(); | 
|  16331 } |  15419 } | 
|  16332  |  15420  | 
|  16333  |  | 
|  16334 RawTypeArguments* AbstractType::arguments() const { |  15421 RawTypeArguments* AbstractType::arguments() const { | 
|  16335   // AbstractType is an abstract class. |  15422   // AbstractType is an abstract class. | 
|  16336   UNREACHABLE(); |  15423   UNREACHABLE(); | 
|  16337   return NULL; |  15424   return NULL; | 
|  16338 } |  15425 } | 
|  16339  |  15426  | 
|  16340  |  | 
|  16341 void AbstractType::set_arguments(const TypeArguments& value) const { |  15427 void AbstractType::set_arguments(const TypeArguments& value) const { | 
|  16342   // AbstractType is an abstract class. |  15428   // AbstractType is an abstract class. | 
|  16343   UNREACHABLE(); |  15429   UNREACHABLE(); | 
|  16344 } |  15430 } | 
|  16345  |  15431  | 
|  16346 TokenPosition AbstractType::token_pos() const { |  15432 TokenPosition AbstractType::token_pos() const { | 
|  16347   // AbstractType is an abstract class. |  15433   // AbstractType is an abstract class. | 
|  16348   UNREACHABLE(); |  15434   UNREACHABLE(); | 
|  16349   return TokenPosition::kNoSource; |  15435   return TokenPosition::kNoSource; | 
|  16350 } |  15436 } | 
|  16351  |  15437  | 
|  16352  |  | 
|  16353 bool AbstractType::IsInstantiated(Genericity genericity, |  15438 bool AbstractType::IsInstantiated(Genericity genericity, | 
|  16354                                   intptr_t num_free_fun_type_params, |  15439                                   intptr_t num_free_fun_type_params, | 
|  16355                                   TrailPtr trail) const { |  15440                                   TrailPtr trail) const { | 
|  16356   // AbstractType is an abstract class. |  15441   // AbstractType is an abstract class. | 
|  16357   UNREACHABLE(); |  15442   UNREACHABLE(); | 
|  16358   return false; |  15443   return false; | 
|  16359 } |  15444 } | 
|  16360  |  15445  | 
|  16361  |  | 
|  16362 bool AbstractType::IsFinalized() const { |  15446 bool AbstractType::IsFinalized() const { | 
|  16363   // AbstractType is an abstract class. |  15447   // AbstractType is an abstract class. | 
|  16364   UNREACHABLE(); |  15448   UNREACHABLE(); | 
|  16365   return false; |  15449   return false; | 
|  16366 } |  15450 } | 
|  16367  |  15451  | 
|  16368  |  | 
|  16369 void AbstractType::SetIsFinalized() const { |  15452 void AbstractType::SetIsFinalized() const { | 
|  16370   // AbstractType is an abstract class. |  15453   // AbstractType is an abstract class. | 
|  16371   UNREACHABLE(); |  15454   UNREACHABLE(); | 
|  16372 } |  15455 } | 
|  16373  |  15456  | 
|  16374  |  | 
|  16375 bool AbstractType::IsBeingFinalized() const { |  15457 bool AbstractType::IsBeingFinalized() const { | 
|  16376   // AbstractType is an abstract class. |  15458   // AbstractType is an abstract class. | 
|  16377   UNREACHABLE(); |  15459   UNREACHABLE(); | 
|  16378   return false; |  15460   return false; | 
|  16379 } |  15461 } | 
|  16380  |  15462  | 
|  16381  |  | 
|  16382 void AbstractType::SetIsBeingFinalized() const { |  15463 void AbstractType::SetIsBeingFinalized() const { | 
|  16383   // AbstractType is an abstract class. |  15464   // AbstractType is an abstract class. | 
|  16384   UNREACHABLE(); |  15465   UNREACHABLE(); | 
|  16385 } |  15466 } | 
|  16386  |  15467  | 
|  16387  |  | 
|  16388 bool AbstractType::IsMalformed() const { |  15468 bool AbstractType::IsMalformed() const { | 
|  16389   // AbstractType is an abstract class. |  15469   // AbstractType is an abstract class. | 
|  16390   UNREACHABLE(); |  15470   UNREACHABLE(); | 
|  16391   return false; |  15471   return false; | 
|  16392 } |  15472 } | 
|  16393  |  15473  | 
|  16394  |  | 
|  16395 bool AbstractType::IsMalbounded() const { |  15474 bool AbstractType::IsMalbounded() const { | 
|  16396   // AbstractType is an abstract class. |  15475   // AbstractType is an abstract class. | 
|  16397   UNREACHABLE(); |  15476   UNREACHABLE(); | 
|  16398   return false; |  15477   return false; | 
|  16399 } |  15478 } | 
|  16400  |  15479  | 
|  16401  |  | 
|  16402 bool AbstractType::IsMalformedOrMalbounded() const { |  15480 bool AbstractType::IsMalformedOrMalbounded() const { | 
|  16403   // AbstractType is an abstract class. |  15481   // AbstractType is an abstract class. | 
|  16404   UNREACHABLE(); |  15482   UNREACHABLE(); | 
|  16405   return false; |  15483   return false; | 
|  16406 } |  15484 } | 
|  16407  |  15485  | 
|  16408  |  | 
|  16409 RawLanguageError* AbstractType::error() const { |  15486 RawLanguageError* AbstractType::error() const { | 
|  16410   // AbstractType is an abstract class. |  15487   // AbstractType is an abstract class. | 
|  16411   UNREACHABLE(); |  15488   UNREACHABLE(); | 
|  16412   return LanguageError::null(); |  15489   return LanguageError::null(); | 
|  16413 } |  15490 } | 
|  16414  |  15491  | 
|  16415  |  | 
|  16416 void AbstractType::set_error(const LanguageError& value) const { |  15492 void AbstractType::set_error(const LanguageError& value) const { | 
|  16417   // AbstractType is an abstract class. |  15493   // AbstractType is an abstract class. | 
|  16418   UNREACHABLE(); |  15494   UNREACHABLE(); | 
|  16419 } |  15495 } | 
|  16420  |  15496  | 
|  16421  |  | 
|  16422 bool AbstractType::IsEquivalent(const Instance& other, TrailPtr trail) const { |  15497 bool AbstractType::IsEquivalent(const Instance& other, TrailPtr trail) const { | 
|  16423   // AbstractType is an abstract class. |  15498   // AbstractType is an abstract class. | 
|  16424   UNREACHABLE(); |  15499   UNREACHABLE(); | 
|  16425   return false; |  15500   return false; | 
|  16426 } |  15501 } | 
|  16427  |  15502  | 
|  16428  |  | 
|  16429 bool AbstractType::IsRecursive() const { |  15503 bool AbstractType::IsRecursive() const { | 
|  16430   // AbstractType is an abstract class. |  15504   // AbstractType is an abstract class. | 
|  16431   UNREACHABLE(); |  15505   UNREACHABLE(); | 
|  16432   return false; |  15506   return false; | 
|  16433 } |  15507 } | 
|  16434  |  15508  | 
|  16435  |  | 
|  16436 RawAbstractType* AbstractType::InstantiateFrom( |  15509 RawAbstractType* AbstractType::InstantiateFrom( | 
|  16437     const TypeArguments& instantiator_type_arguments, |  15510     const TypeArguments& instantiator_type_arguments, | 
|  16438     const TypeArguments& function_type_arguments, |  15511     const TypeArguments& function_type_arguments, | 
|  16439     Error* bound_error, |  15512     Error* bound_error, | 
|  16440     TrailPtr instantiation_trail, |  15513     TrailPtr instantiation_trail, | 
|  16441     TrailPtr bound_trail, |  15514     TrailPtr bound_trail, | 
|  16442     Heap::Space space) const { |  15515     Heap::Space space) const { | 
|  16443   // AbstractType is an abstract class. |  15516   // AbstractType is an abstract class. | 
|  16444   UNREACHABLE(); |  15517   UNREACHABLE(); | 
|  16445   return NULL; |  15518   return NULL; | 
|  16446 } |  15519 } | 
|  16447  |  15520  | 
|  16448  |  | 
|  16449 RawAbstractType* AbstractType::CloneUnfinalized() const { |  15521 RawAbstractType* AbstractType::CloneUnfinalized() const { | 
|  16450   // AbstractType is an abstract class. |  15522   // AbstractType is an abstract class. | 
|  16451   UNREACHABLE(); |  15523   UNREACHABLE(); | 
|  16452   return NULL; |  15524   return NULL; | 
|  16453 } |  15525 } | 
|  16454  |  15526  | 
|  16455  |  | 
|  16456 RawAbstractType* AbstractType::CloneUninstantiated(const Class& new_owner, |  15527 RawAbstractType* AbstractType::CloneUninstantiated(const Class& new_owner, | 
|  16457                                                    TrailPtr trail) const { |  15528                                                    TrailPtr trail) const { | 
|  16458   // AbstractType is an abstract class. |  15529   // AbstractType is an abstract class. | 
|  16459   UNREACHABLE(); |  15530   UNREACHABLE(); | 
|  16460   return NULL; |  15531   return NULL; | 
|  16461 } |  15532 } | 
|  16462  |  15533  | 
|  16463  |  | 
|  16464 RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const { |  15534 RawAbstractType* AbstractType::Canonicalize(TrailPtr trail) const { | 
|  16465   // AbstractType is an abstract class. |  15535   // AbstractType is an abstract class. | 
|  16466   UNREACHABLE(); |  15536   UNREACHABLE(); | 
|  16467   return NULL; |  15537   return NULL; | 
|  16468 } |  15538 } | 
|  16469  |  15539  | 
|  16470  |  | 
|  16471 RawString* AbstractType::EnumerateURIs() const { |  15540 RawString* AbstractType::EnumerateURIs() const { | 
|  16472   // AbstractType is an abstract class. |  15541   // AbstractType is an abstract class. | 
|  16473   UNREACHABLE(); |  15542   UNREACHABLE(); | 
|  16474   return NULL; |  15543   return NULL; | 
|  16475 } |  15544 } | 
|  16476  |  15545  | 
|  16477  |  | 
|  16478 RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const { |  15546 RawAbstractType* AbstractType::OnlyBuddyInTrail(TrailPtr trail) const { | 
|  16479   if (trail == NULL) { |  15547   if (trail == NULL) { | 
|  16480     return AbstractType::null(); |  15548     return AbstractType::null(); | 
|  16481   } |  15549   } | 
|  16482   const intptr_t len = trail->length(); |  15550   const intptr_t len = trail->length(); | 
|  16483   ASSERT((len % 2) == 0); |  15551   ASSERT((len % 2) == 0); | 
|  16484   for (intptr_t i = 0; i < len; i += 2) { |  15552   for (intptr_t i = 0; i < len; i += 2) { | 
|  16485     ASSERT(trail->At(i).IsZoneHandle()); |  15553     ASSERT(trail->At(i).IsZoneHandle()); | 
|  16486     ASSERT(trail->At(i + 1).IsZoneHandle()); |  15554     ASSERT(trail->At(i + 1).IsZoneHandle()); | 
|  16487     if (trail->At(i).raw() == this->raw()) { |  15555     if (trail->At(i).raw() == this->raw()) { | 
|  16488       ASSERT(!trail->At(i + 1).IsNull()); |  15556       ASSERT(!trail->At(i + 1).IsNull()); | 
|  16489       return trail->At(i + 1).raw(); |  15557       return trail->At(i + 1).raw(); | 
|  16490     } |  15558     } | 
|  16491   } |  15559   } | 
|  16492   return AbstractType::null(); |  15560   return AbstractType::null(); | 
|  16493 } |  15561 } | 
|  16494  |  15562  | 
|  16495  |  | 
|  16496 void AbstractType::AddOnlyBuddyToTrail(TrailPtr* trail, |  15563 void AbstractType::AddOnlyBuddyToTrail(TrailPtr* trail, | 
|  16497                                        const AbstractType& buddy) const { |  15564                                        const AbstractType& buddy) const { | 
|  16498   if (*trail == NULL) { |  15565   if (*trail == NULL) { | 
|  16499     *trail = new Trail(Thread::Current()->zone(), 4); |  15566     *trail = new Trail(Thread::Current()->zone(), 4); | 
|  16500   } else { |  15567   } else { | 
|  16501     ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); |  15568     ASSERT(OnlyBuddyInTrail(*trail) == AbstractType::null()); | 
|  16502   } |  15569   } | 
|  16503   (*trail)->Add(*this); |  15570   (*trail)->Add(*this); | 
|  16504   (*trail)->Add(buddy); |  15571   (*trail)->Add(buddy); | 
|  16505 } |  15572 } | 
|  16506  |  15573  | 
|  16507  |  | 
|  16508 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { |  15574 bool AbstractType::TestAndAddToTrail(TrailPtr* trail) const { | 
|  16509   if (*trail == NULL) { |  15575   if (*trail == NULL) { | 
|  16510     *trail = new Trail(Thread::Current()->zone(), 4); |  15576     *trail = new Trail(Thread::Current()->zone(), 4); | 
|  16511   } else { |  15577   } else { | 
|  16512     const intptr_t len = (*trail)->length(); |  15578     const intptr_t len = (*trail)->length(); | 
|  16513     for (intptr_t i = 0; i < len; i++) { |  15579     for (intptr_t i = 0; i < len; i++) { | 
|  16514       if ((*trail)->At(i).raw() == this->raw()) { |  15580       if ((*trail)->At(i).raw() == this->raw()) { | 
|  16515         return true; |  15581         return true; | 
|  16516       } |  15582       } | 
|  16517     } |  15583     } | 
|  16518   } |  15584   } | 
|  16519   (*trail)->Add(*this); |  15585   (*trail)->Add(*this); | 
|  16520   return false; |  15586   return false; | 
|  16521 } |  15587 } | 
|  16522  |  15588  | 
|  16523  |  | 
|  16524 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, |  15589 bool AbstractType::TestAndAddBuddyToTrail(TrailPtr* trail, | 
|  16525                                           const AbstractType& buddy) const { |  15590                                           const AbstractType& buddy) const { | 
|  16526   if (*trail == NULL) { |  15591   if (*trail == NULL) { | 
|  16527     *trail = new Trail(Thread::Current()->zone(), 4); |  15592     *trail = new Trail(Thread::Current()->zone(), 4); | 
|  16528   } else { |  15593   } else { | 
|  16529     const intptr_t len = (*trail)->length(); |  15594     const intptr_t len = (*trail)->length(); | 
|  16530     ASSERT((len % 2) == 0); |  15595     ASSERT((len % 2) == 0); | 
|  16531     const bool this_is_typeref = IsTypeRef(); |  15596     const bool this_is_typeref = IsTypeRef(); | 
|  16532     const bool buddy_is_typeref = buddy.IsTypeRef(); |  15597     const bool buddy_is_typeref = buddy.IsTypeRef(); | 
|  16533     // Note that at least one of 'this' and 'buddy' should be a typeref, with |  15598     // Note that at least one of 'this' and 'buddy' should be a typeref, with | 
|  16534     // one exception, when the class of the 'this' type implements the 'call' |  15599     // one exception, when the class of the 'this' type implements the 'call' | 
|  16535     // method, thereby possibly creating a recursive type (see regress_29405). |  15600     // method, thereby possibly creating a recursive type (see regress_29405). | 
|  16536     for (intptr_t i = 0; i < len; i += 2) { |  15601     for (intptr_t i = 0; i < len; i += 2) { | 
|  16537       if ((((*trail)->At(i).raw() == this->raw()) || |  15602       if ((((*trail)->At(i).raw() == this->raw()) || | 
|  16538            (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && |  15603            (buddy_is_typeref && (*trail)->At(i).Equals(*this))) && | 
|  16539           (((*trail)->At(i + 1).raw() == buddy.raw()) || |  15604           (((*trail)->At(i + 1).raw() == buddy.raw()) || | 
|  16540            (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { |  15605            (this_is_typeref && (*trail)->At(i + 1).Equals(buddy)))) { | 
|  16541         return true; |  15606         return true; | 
|  16542       } |  15607       } | 
|  16543     } |  15608     } | 
|  16544   } |  15609   } | 
|  16545   (*trail)->Add(*this); |  15610   (*trail)->Add(*this); | 
|  16546   (*trail)->Add(buddy); |  15611   (*trail)->Add(buddy); | 
|  16547   return false; |  15612   return false; | 
|  16548 } |  15613 } | 
|  16549  |  15614  | 
|  16550  |  | 
|  16551 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |  15615 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 
|  16552   ASSERT(name_visibility != kScrubbedName); |  15616   ASSERT(name_visibility != kScrubbedName); | 
|  16553   Thread* thread = Thread::Current(); |  15617   Thread* thread = Thread::Current(); | 
|  16554   Zone* zone = thread->zone(); |  15618   Zone* zone = thread->zone(); | 
|  16555   if (IsBoundedType()) { |  15619   if (IsBoundedType()) { | 
|  16556     const AbstractType& type = |  15620     const AbstractType& type = | 
|  16557         AbstractType::Handle(zone, BoundedType::Cast(*this).type()); |  15621         AbstractType::Handle(zone, BoundedType::Cast(*this).type()); | 
|  16558     if (name_visibility == kUserVisibleName) { |  15622     if (name_visibility == kUserVisibleName) { | 
|  16559       return type.BuildName(kUserVisibleName); |  15623       return type.BuildName(kUserVisibleName); | 
|  16560     } |  15624     } | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  16662         zone, args.SubvectorName(first_type_param_index, num_type_params, |  15726         zone, args.SubvectorName(first_type_param_index, num_type_params, | 
|  16663                                  name_visibility)); |  15727                                  name_visibility)); | 
|  16664     pieces.Add(args_name); |  15728     pieces.Add(args_name); | 
|  16665   } |  15729   } | 
|  16666   // The name is only used for type checking and debugging purposes. |  15730   // The name is only used for type checking and debugging purposes. | 
|  16667   // Unless profiling data shows otherwise, it is not worth caching the name in |  15731   // Unless profiling data shows otherwise, it is not worth caching the name in | 
|  16668   // the type. |  15732   // the type. | 
|  16669   return Symbols::FromConcatAll(thread, pieces); |  15733   return Symbols::FromConcatAll(thread, pieces); | 
|  16670 } |  15734 } | 
|  16671  |  15735  | 
|  16672  |  | 
|  16673 RawString* AbstractType::ClassName() const { |  15736 RawString* AbstractType::ClassName() const { | 
|  16674   ASSERT(!IsFunctionType()); |  15737   ASSERT(!IsFunctionType()); | 
|  16675   if (HasResolvedTypeClass()) { |  15738   if (HasResolvedTypeClass()) { | 
|  16676     return Class::Handle(type_class()).Name(); |  15739     return Class::Handle(type_class()).Name(); | 
|  16677   } else { |  15740   } else { | 
|  16678     return UnresolvedClass::Handle(unresolved_class()).Name(); |  15741     return UnresolvedClass::Handle(unresolved_class()).Name(); | 
|  16679   } |  15742   } | 
|  16680 } |  15743 } | 
|  16681  |  15744  | 
|  16682  |  | 
|  16683 bool AbstractType::IsDynamicType() const { |  15745 bool AbstractType::IsDynamicType() const { | 
|  16684   if (IsCanonical()) { |  15746   if (IsCanonical()) { | 
|  16685     return raw() == Object::dynamic_type().raw(); |  15747     return raw() == Object::dynamic_type().raw(); | 
|  16686   } |  15748   } | 
|  16687   return HasResolvedTypeClass() && (type_class() == Object::dynamic_class()); |  15749   return HasResolvedTypeClass() && (type_class() == Object::dynamic_class()); | 
|  16688 } |  15750 } | 
|  16689  |  15751  | 
|  16690  |  | 
|  16691 bool AbstractType::IsVoidType() const { |  15752 bool AbstractType::IsVoidType() const { | 
|  16692   return raw() == Object::void_type().raw(); |  15753   return raw() == Object::void_type().raw(); | 
|  16693 } |  15754 } | 
|  16694  |  15755  | 
|  16695  |  | 
|  16696 bool AbstractType::IsNullType() const { |  15756 bool AbstractType::IsNullType() const { | 
|  16697   return !IsFunctionType() && HasResolvedTypeClass() && |  15757   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16698          (type_class() == Isolate::Current()->object_store()->null_class()); |  15758          (type_class() == Isolate::Current()->object_store()->null_class()); | 
|  16699 } |  15759 } | 
|  16700  |  15760  | 
|  16701  |  | 
|  16702 bool AbstractType::IsBoolType() const { |  15761 bool AbstractType::IsBoolType() const { | 
|  16703   return !IsFunctionType() && HasResolvedTypeClass() && |  15762   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16704          (type_class() == Isolate::Current()->object_store()->bool_class()); |  15763          (type_class() == Isolate::Current()->object_store()->bool_class()); | 
|  16705 } |  15764 } | 
|  16706  |  15765  | 
|  16707  |  | 
|  16708 bool AbstractType::IsIntType() const { |  15766 bool AbstractType::IsIntType() const { | 
|  16709   return !IsFunctionType() && HasResolvedTypeClass() && |  15767   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16710          (type_class() == Type::Handle(Type::IntType()).type_class()); |  15768          (type_class() == Type::Handle(Type::IntType()).type_class()); | 
|  16711 } |  15769 } | 
|  16712  |  15770  | 
|  16713  |  | 
|  16714 bool AbstractType::IsInt64Type() const { |  15771 bool AbstractType::IsInt64Type() const { | 
|  16715   return !IsFunctionType() && HasResolvedTypeClass() && |  15772   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16716          (type_class() == Type::Handle(Type::Int64Type()).type_class()); |  15773          (type_class() == Type::Handle(Type::Int64Type()).type_class()); | 
|  16717 } |  15774 } | 
|  16718  |  15775  | 
|  16719  |  | 
|  16720 bool AbstractType::IsDoubleType() const { |  15776 bool AbstractType::IsDoubleType() const { | 
|  16721   return !IsFunctionType() && HasResolvedTypeClass() && |  15777   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16722          (type_class() == Type::Handle(Type::Double()).type_class()); |  15778          (type_class() == Type::Handle(Type::Double()).type_class()); | 
|  16723 } |  15779 } | 
|  16724  |  15780  | 
|  16725  |  | 
|  16726 bool AbstractType::IsFloat32x4Type() const { |  15781 bool AbstractType::IsFloat32x4Type() const { | 
|  16727   return !IsFunctionType() && HasResolvedTypeClass() && |  15782   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16728          (type_class() == Type::Handle(Type::Float32x4()).type_class()); |  15783          (type_class() == Type::Handle(Type::Float32x4()).type_class()); | 
|  16729 } |  15784 } | 
|  16730  |  15785  | 
|  16731  |  | 
|  16732 bool AbstractType::IsFloat64x2Type() const { |  15786 bool AbstractType::IsFloat64x2Type() const { | 
|  16733   return !IsFunctionType() && HasResolvedTypeClass() && |  15787   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16734          (type_class() == Type::Handle(Type::Float64x2()).type_class()); |  15788          (type_class() == Type::Handle(Type::Float64x2()).type_class()); | 
|  16735 } |  15789 } | 
|  16736  |  15790  | 
|  16737  |  | 
|  16738 bool AbstractType::IsInt32x4Type() const { |  15791 bool AbstractType::IsInt32x4Type() const { | 
|  16739   return !IsFunctionType() && HasResolvedTypeClass() && |  15792   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16740          (type_class() == Type::Handle(Type::Int32x4()).type_class()); |  15793          (type_class() == Type::Handle(Type::Int32x4()).type_class()); | 
|  16741 } |  15794 } | 
|  16742  |  15795  | 
|  16743  |  | 
|  16744 bool AbstractType::IsNumberType() const { |  15796 bool AbstractType::IsNumberType() const { | 
|  16745   return !IsFunctionType() && HasResolvedTypeClass() && |  15797   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16746          (type_class() == Type::Handle(Type::Number()).type_class()); |  15798          (type_class() == Type::Handle(Type::Number()).type_class()); | 
|  16747 } |  15799 } | 
|  16748  |  15800  | 
|  16749  |  | 
|  16750 bool AbstractType::IsSmiType() const { |  15801 bool AbstractType::IsSmiType() const { | 
|  16751   return !IsFunctionType() && HasResolvedTypeClass() && |  15802   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16752          (type_class() == Type::Handle(Type::SmiType()).type_class()); |  15803          (type_class() == Type::Handle(Type::SmiType()).type_class()); | 
|  16753 } |  15804 } | 
|  16754  |  15805  | 
|  16755  |  | 
|  16756 bool AbstractType::IsStringType() const { |  15806 bool AbstractType::IsStringType() const { | 
|  16757   return !IsFunctionType() && HasResolvedTypeClass() && |  15807   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16758          (type_class() == Type::Handle(Type::StringType()).type_class()); |  15808          (type_class() == Type::Handle(Type::StringType()).type_class()); | 
|  16759 } |  15809 } | 
|  16760  |  15810  | 
|  16761  |  | 
|  16762 bool AbstractType::IsDartFunctionType() const { |  15811 bool AbstractType::IsDartFunctionType() const { | 
|  16763   return !IsFunctionType() && HasResolvedTypeClass() && |  15812   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16764          (type_class() == Type::Handle(Type::DartFunctionType()).type_class()); |  15813          (type_class() == Type::Handle(Type::DartFunctionType()).type_class()); | 
|  16765 } |  15814 } | 
|  16766  |  15815  | 
|  16767  |  | 
|  16768 bool AbstractType::IsDartClosureType() const { |  15816 bool AbstractType::IsDartClosureType() const { | 
|  16769   return !IsFunctionType() && HasResolvedTypeClass() && |  15817   return !IsFunctionType() && HasResolvedTypeClass() && | 
|  16770          (type_class() == Isolate::Current()->object_store()->closure_class()); |  15818          (type_class() == Isolate::Current()->object_store()->closure_class()); | 
|  16771 } |  15819 } | 
|  16772  |  15820  | 
|  16773  |  | 
|  16774 bool AbstractType::TypeTest(TypeTestKind test_kind, |  15821 bool AbstractType::TypeTest(TypeTestKind test_kind, | 
|  16775                             const AbstractType& other, |  15822                             const AbstractType& other, | 
|  16776                             Error* bound_error, |  15823                             Error* bound_error, | 
|  16777                             TrailPtr bound_trail, |  15824                             TrailPtr bound_trail, | 
|  16778                             Heap::Space space) const { |  15825                             Heap::Space space) const { | 
|  16779   ASSERT(IsFinalized()); |  15826   ASSERT(IsFinalized()); | 
|  16780   ASSERT(other.IsFinalized()); |  15827   ASSERT(other.IsFinalized()); | 
|  16781   if (IsMalformed() || other.IsMalformed()) { |  15828   if (IsMalformed() || other.IsMalformed()) { | 
|  16782     // Malformed types involved in subtype tests should be handled specially |  15829     // Malformed types involved in subtype tests should be handled specially | 
|  16783     // by the caller. Malformed types should only be encountered here in a |  15830     // by the caller. Malformed types should only be encountered here in a | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  16934   } |  15981   } | 
|  16935   if (IsFunctionType()) { |  15982   if (IsFunctionType()) { | 
|  16936     return false; |  15983     return false; | 
|  16937   } |  15984   } | 
|  16938   return type_cls.TypeTest(test_kind, TypeArguments::Handle(zone, arguments()), |  15985   return type_cls.TypeTest(test_kind, TypeArguments::Handle(zone, arguments()), | 
|  16939                            Class::Handle(zone, other.type_class()), |  15986                            Class::Handle(zone, other.type_class()), | 
|  16940                            TypeArguments::Handle(zone, other.arguments()), |  15987                            TypeArguments::Handle(zone, other.arguments()), | 
|  16941                            bound_error, bound_trail, space); |  15988                            bound_error, bound_trail, space); | 
|  16942 } |  15989 } | 
|  16943  |  15990  | 
|  16944  |  | 
|  16945 intptr_t AbstractType::Hash() const { |  15991 intptr_t AbstractType::Hash() const { | 
|  16946   // AbstractType is an abstract class. |  15992   // AbstractType is an abstract class. | 
|  16947   UNREACHABLE(); |  15993   UNREACHABLE(); | 
|  16948   return 0; |  15994   return 0; | 
|  16949 } |  15995 } | 
|  16950  |  15996  | 
|  16951  |  | 
|  16952 const char* AbstractType::ToCString() const { |  15997 const char* AbstractType::ToCString() const { | 
|  16953   if (IsNull()) { |  15998   if (IsNull()) { | 
|  16954     return "AbstractType: null"; |  15999     return "AbstractType: null"; | 
|  16955   } |  16000   } | 
|  16956   // AbstractType is an abstract class. |  16001   // AbstractType is an abstract class. | 
|  16957   UNREACHABLE(); |  16002   UNREACHABLE(); | 
|  16958   return "AbstractType"; |  16003   return "AbstractType"; | 
|  16959 } |  16004 } | 
|  16960  |  16005  | 
|  16961  |  | 
|  16962 RawType* Type::NullType() { |  16006 RawType* Type::NullType() { | 
|  16963   return Isolate::Current()->object_store()->null_type(); |  16007   return Isolate::Current()->object_store()->null_type(); | 
|  16964 } |  16008 } | 
|  16965  |  16009  | 
|  16966  |  | 
|  16967 RawType* Type::DynamicType() { |  16010 RawType* Type::DynamicType() { | 
|  16968   return Object::dynamic_type().raw(); |  16011   return Object::dynamic_type().raw(); | 
|  16969 } |  16012 } | 
|  16970  |  16013  | 
|  16971  |  | 
|  16972 RawType* Type::VoidType() { |  16014 RawType* Type::VoidType() { | 
|  16973   return Object::void_type().raw(); |  16015   return Object::void_type().raw(); | 
|  16974 } |  16016 } | 
|  16975  |  16017  | 
|  16976  |  | 
|  16977 RawType* Type::ObjectType() { |  16018 RawType* Type::ObjectType() { | 
|  16978   return Isolate::Current()->object_store()->object_type(); |  16019   return Isolate::Current()->object_store()->object_type(); | 
|  16979 } |  16020 } | 
|  16980  |  16021  | 
|  16981  |  | 
|  16982 RawType* Type::BoolType() { |  16022 RawType* Type::BoolType() { | 
|  16983   return Isolate::Current()->object_store()->bool_type(); |  16023   return Isolate::Current()->object_store()->bool_type(); | 
|  16984 } |  16024 } | 
|  16985  |  16025  | 
|  16986  |  | 
|  16987 RawType* Type::IntType() { |  16026 RawType* Type::IntType() { | 
|  16988   return Isolate::Current()->object_store()->int_type(); |  16027   return Isolate::Current()->object_store()->int_type(); | 
|  16989 } |  16028 } | 
|  16990  |  16029  | 
|  16991  |  | 
|  16992 RawType* Type::Int64Type() { |  16030 RawType* Type::Int64Type() { | 
|  16993   return Isolate::Current()->object_store()->int64_type(); |  16031   return Isolate::Current()->object_store()->int64_type(); | 
|  16994 } |  16032 } | 
|  16995  |  16033  | 
|  16996  |  | 
|  16997 RawType* Type::SmiType() { |  16034 RawType* Type::SmiType() { | 
|  16998   return Isolate::Current()->object_store()->smi_type(); |  16035   return Isolate::Current()->object_store()->smi_type(); | 
|  16999 } |  16036 } | 
|  17000  |  16037  | 
|  17001  |  | 
|  17002 RawType* Type::MintType() { |  16038 RawType* Type::MintType() { | 
|  17003   return Isolate::Current()->object_store()->mint_type(); |  16039   return Isolate::Current()->object_store()->mint_type(); | 
|  17004 } |  16040 } | 
|  17005  |  16041  | 
|  17006  |  | 
|  17007 RawType* Type::Double() { |  16042 RawType* Type::Double() { | 
|  17008   return Isolate::Current()->object_store()->double_type(); |  16043   return Isolate::Current()->object_store()->double_type(); | 
|  17009 } |  16044 } | 
|  17010  |  16045  | 
|  17011  |  | 
|  17012 RawType* Type::Float32x4() { |  16046 RawType* Type::Float32x4() { | 
|  17013   return Isolate::Current()->object_store()->float32x4_type(); |  16047   return Isolate::Current()->object_store()->float32x4_type(); | 
|  17014 } |  16048 } | 
|  17015  |  16049  | 
|  17016  |  | 
|  17017 RawType* Type::Float64x2() { |  16050 RawType* Type::Float64x2() { | 
|  17018   return Isolate::Current()->object_store()->float64x2_type(); |  16051   return Isolate::Current()->object_store()->float64x2_type(); | 
|  17019 } |  16052 } | 
|  17020  |  16053  | 
|  17021  |  | 
|  17022 RawType* Type::Int32x4() { |  16054 RawType* Type::Int32x4() { | 
|  17023   return Isolate::Current()->object_store()->int32x4_type(); |  16055   return Isolate::Current()->object_store()->int32x4_type(); | 
|  17024 } |  16056 } | 
|  17025  |  16057  | 
|  17026  |  | 
|  17027 RawType* Type::Number() { |  16058 RawType* Type::Number() { | 
|  17028   return Isolate::Current()->object_store()->number_type(); |  16059   return Isolate::Current()->object_store()->number_type(); | 
|  17029 } |  16060 } | 
|  17030  |  16061  | 
|  17031  |  | 
|  17032 RawType* Type::StringType() { |  16062 RawType* Type::StringType() { | 
|  17033   return Isolate::Current()->object_store()->string_type(); |  16063   return Isolate::Current()->object_store()->string_type(); | 
|  17034 } |  16064 } | 
|  17035  |  16065  | 
|  17036  |  | 
|  17037 RawType* Type::ArrayType() { |  16066 RawType* Type::ArrayType() { | 
|  17038   return Isolate::Current()->object_store()->array_type(); |  16067   return Isolate::Current()->object_store()->array_type(); | 
|  17039 } |  16068 } | 
|  17040  |  16069  | 
|  17041  |  | 
|  17042 RawType* Type::DartFunctionType() { |  16070 RawType* Type::DartFunctionType() { | 
|  17043   return Isolate::Current()->object_store()->function_type(); |  16071   return Isolate::Current()->object_store()->function_type(); | 
|  17044 } |  16072 } | 
|  17045  |  16073  | 
|  17046  |  | 
|  17047 RawType* Type::NewNonParameterizedType(const Class& type_class) { |  16074 RawType* Type::NewNonParameterizedType(const Class& type_class) { | 
|  17048   ASSERT(type_class.NumTypeArguments() == 0); |  16075   ASSERT(type_class.NumTypeArguments() == 0); | 
|  17049   Type& type = Type::Handle(type_class.CanonicalType()); |  16076   Type& type = Type::Handle(type_class.CanonicalType()); | 
|  17050   if (type.IsNull()) { |  16077   if (type.IsNull()) { | 
|  17051     type ^= Type::New(Object::Handle(type_class.raw()), |  16078     type ^= Type::New(Object::Handle(type_class.raw()), | 
|  17052                       Object::null_type_arguments(), TokenPosition::kNoSource); |  16079                       Object::null_type_arguments(), TokenPosition::kNoSource); | 
|  17053     type.SetIsFinalized(); |  16080     type.SetIsFinalized(); | 
|  17054     type ^= type.Canonicalize(); |  16081     type ^= type.Canonicalize(); | 
|  17055   } |  16082   } | 
|  17056   ASSERT(type.IsFinalized()); |  16083   ASSERT(type.IsFinalized()); | 
|  17057   return type.raw(); |  16084   return type.raw(); | 
|  17058 } |  16085 } | 
|  17059  |  16086  | 
|  17060  |  | 
|  17061 void Type::SetIsFinalized() const { |  16087 void Type::SetIsFinalized() const { | 
|  17062   ASSERT(!IsFinalized()); |  16088   ASSERT(!IsFinalized()); | 
|  17063   if (IsInstantiated()) { |  16089   if (IsInstantiated()) { | 
|  17064     ASSERT(HasResolvedTypeClass()); |  16090     ASSERT(HasResolvedTypeClass()); | 
|  17065     set_type_state(RawType::kFinalizedInstantiated); |  16091     set_type_state(RawType::kFinalizedInstantiated); | 
|  17066   } else { |  16092   } else { | 
|  17067     set_type_state(RawType::kFinalizedUninstantiated); |  16093     set_type_state(RawType::kFinalizedUninstantiated); | 
|  17068   } |  16094   } | 
|  17069 } |  16095 } | 
|  17070  |  16096  | 
|  17071  |  | 
|  17072 void Type::ResetIsFinalized() const { |  16097 void Type::ResetIsFinalized() const { | 
|  17073   ASSERT(IsFinalized()); |  16098   ASSERT(IsFinalized()); | 
|  17074   set_type_state(RawType::kBeingFinalized); |  16099   set_type_state(RawType::kBeingFinalized); | 
|  17075   SetIsFinalized(); |  16100   SetIsFinalized(); | 
|  17076 } |  16101 } | 
|  17077  |  16102  | 
|  17078  |  | 
|  17079 void Type::SetIsBeingFinalized() const { |  16103 void Type::SetIsBeingFinalized() const { | 
|  17080   ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized()); |  16104   ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized()); | 
|  17081   set_type_state(RawType::kBeingFinalized); |  16105   set_type_state(RawType::kBeingFinalized); | 
|  17082 } |  16106 } | 
|  17083  |  16107  | 
|  17084  |  | 
|  17085 bool Type::IsMalformed() const { |  16108 bool Type::IsMalformed() const { | 
|  17086   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |  16109   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 
|  17087     return false;  // Valid type, but not a function type. |  16110     return false;  // Valid type, but not a function type. | 
|  17088   } |  16111   } | 
|  17089   if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |  16112   if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 
|  17090     return false;  // Valid function type. |  16113     return false;  // Valid function type. | 
|  17091   } |  16114   } | 
|  17092   const LanguageError& type_error = LanguageError::Handle(error()); |  16115   const LanguageError& type_error = LanguageError::Handle(error()); | 
|  17093   ASSERT(!type_error.IsNull()); |  16116   ASSERT(!type_error.IsNull()); | 
|  17094   return type_error.kind() == Report::kMalformedType; |  16117   return type_error.kind() == Report::kMalformedType; | 
|  17095 } |  16118 } | 
|  17096  |  16119  | 
|  17097  |  | 
|  17098 bool Type::IsMalbounded() const { |  16120 bool Type::IsMalbounded() const { | 
|  17099   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |  16121   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 
|  17100     return false;  // Valid type, but not a function type. |  16122     return false;  // Valid type, but not a function type. | 
|  17101   } |  16123   } | 
|  17102   if (!Isolate::Current()->type_checks()) { |  16124   if (!Isolate::Current()->type_checks()) { | 
|  17103     return false; |  16125     return false; | 
|  17104   } |  16126   } | 
|  17105   if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |  16127   if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 
|  17106     return false;  // Valid function type. |  16128     return false;  // Valid function type. | 
|  17107   } |  16129   } | 
|  17108   const LanguageError& type_error = LanguageError::Handle(error()); |  16130   const LanguageError& type_error = LanguageError::Handle(error()); | 
|  17109   ASSERT(!type_error.IsNull()); |  16131   ASSERT(!type_error.IsNull()); | 
|  17110   return type_error.kind() == Report::kMalboundedType; |  16132   return type_error.kind() == Report::kMalboundedType; | 
|  17111 } |  16133 } | 
|  17112  |  16134  | 
|  17113  |  | 
|  17114 bool Type::IsMalformedOrMalbounded() const { |  16135 bool Type::IsMalformedOrMalbounded() const { | 
|  17115   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { |  16136   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) { | 
|  17116     return false;  // Valid type, but not a function type. |  16137     return false;  // Valid type, but not a function type. | 
|  17117   } |  16138   } | 
|  17118   const LanguageError& type_error = LanguageError::Handle(error()); |  16139   const LanguageError& type_error = LanguageError::Handle(error()); | 
|  17119   if (type_error.IsNull()) { |  16140   if (type_error.IsNull()) { | 
|  17120     return false;  // Valid function type. |  16141     return false;  // Valid function type. | 
|  17121   } |  16142   } | 
|  17122   if (type_error.kind() == Report::kMalformedType) { |  16143   if (type_error.kind() == Report::kMalformedType) { | 
|  17123     return true; |  16144     return true; | 
|  17124   } |  16145   } | 
|  17125   ASSERT(type_error.kind() == Report::kMalboundedType); |  16146   ASSERT(type_error.kind() == Report::kMalboundedType); | 
|  17126   return Isolate::Current()->type_checks(); |  16147   return Isolate::Current()->type_checks(); | 
|  17127 } |  16148 } | 
|  17128  |  16149  | 
|  17129  |  | 
|  17130 RawLanguageError* Type::error() const { |  16150 RawLanguageError* Type::error() const { | 
|  17131   if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) { |  16151   if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) { | 
|  17132     return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_); |  16152     return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_); | 
|  17133   } |  16153   } | 
|  17134   return LanguageError::null(); |  16154   return LanguageError::null(); | 
|  17135 } |  16155 } | 
|  17136  |  16156  | 
|  17137  |  | 
|  17138 void Type::set_error(const LanguageError& value) const { |  16157 void Type::set_error(const LanguageError& value) const { | 
|  17139   StorePointer(&raw_ptr()->sig_or_err_.error_, value.raw()); |  16158   StorePointer(&raw_ptr()->sig_or_err_.error_, value.raw()); | 
|  17140 } |  16159 } | 
|  17141  |  16160  | 
|  17142  |  | 
|  17143 RawFunction* Type::signature() const { |  16161 RawFunction* Type::signature() const { | 
|  17144   intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId(); |  16162   intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId(); | 
|  17145   if (cid == kNullCid) { |  16163   if (cid == kNullCid) { | 
|  17146     return Function::null(); |  16164     return Function::null(); | 
|  17147   } |  16165   } | 
|  17148   if (cid == kFunctionCid) { |  16166   if (cid == kFunctionCid) { | 
|  17149     return Function::RawCast(raw_ptr()->sig_or_err_.signature_); |  16167     return Function::RawCast(raw_ptr()->sig_or_err_.signature_); | 
|  17150   } |  16168   } | 
|  17151   ASSERT(cid == kLanguageErrorCid);  // Type is malformed or malbounded. |  16169   ASSERT(cid == kLanguageErrorCid);  // Type is malformed or malbounded. | 
|  17152   return Function::null(); |  16170   return Function::null(); | 
|  17153 } |  16171 } | 
|  17154  |  16172  | 
|  17155  |  | 
|  17156 void Type::set_signature(const Function& value) const { |  16173 void Type::set_signature(const Function& value) const { | 
|  17157   StorePointer(&raw_ptr()->sig_or_err_.signature_, value.raw()); |  16174   StorePointer(&raw_ptr()->sig_or_err_.signature_, value.raw()); | 
|  17158 } |  16175 } | 
|  17159  |  16176  | 
|  17160  |  | 
|  17161 void Type::SetIsResolved() const { |  16177 void Type::SetIsResolved() const { | 
|  17162   ASSERT(!IsResolved()); |  16178   ASSERT(!IsResolved()); | 
|  17163   set_type_state(RawType::kResolved); |  16179   set_type_state(RawType::kResolved); | 
|  17164 } |  16180 } | 
|  17165  |  16181  | 
|  17166  |  | 
|  17167 bool Type::HasResolvedTypeClass() const { |  16182 bool Type::HasResolvedTypeClass() const { | 
|  17168   return !raw_ptr()->type_class_id_->IsHeapObject(); |  16183   return !raw_ptr()->type_class_id_->IsHeapObject(); | 
|  17169 } |  16184 } | 
|  17170  |  16185  | 
|  17171  |  | 
|  17172 classid_t Type::type_class_id() const { |  16186 classid_t Type::type_class_id() const { | 
|  17173   ASSERT(HasResolvedTypeClass()); |  16187   ASSERT(HasResolvedTypeClass()); | 
|  17174   return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_)); |  16188   return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->type_class_id_)); | 
|  17175 } |  16189 } | 
|  17176  |  16190  | 
|  17177  |  | 
|  17178 RawClass* Type::type_class() const { |  16191 RawClass* Type::type_class() const { | 
|  17179   return Isolate::Current()->class_table()->At(type_class_id()); |  16192   return Isolate::Current()->class_table()->At(type_class_id()); | 
|  17180 } |  16193 } | 
|  17181  |  16194  | 
|  17182  |  | 
|  17183 RawUnresolvedClass* Type::unresolved_class() const { |  16195 RawUnresolvedClass* Type::unresolved_class() const { | 
|  17184 #ifdef DEBUG |  16196 #ifdef DEBUG | 
|  17185   ASSERT(!HasResolvedTypeClass()); |  16197   ASSERT(!HasResolvedTypeClass()); | 
|  17186   UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); |  16198   UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); | 
|  17187   unresolved_class ^= raw_ptr()->type_class_id_; |  16199   unresolved_class ^= raw_ptr()->type_class_id_; | 
|  17188   ASSERT(!unresolved_class.IsNull()); |  16200   ASSERT(!unresolved_class.IsNull()); | 
|  17189   return unresolved_class.raw(); |  16201   return unresolved_class.raw(); | 
|  17190 #else |  16202 #else | 
|  17191   ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull()); |  16203   ASSERT(!Object::Handle(raw_ptr()->type_class_id_).IsNull()); | 
|  17192   ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass()); |  16204   ASSERT(Object::Handle(raw_ptr()->type_class_id_).IsUnresolvedClass()); | 
|  17193   return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_); |  16205   return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_id_); | 
|  17194 #endif |  16206 #endif | 
|  17195 } |  16207 } | 
|  17196  |  16208  | 
|  17197  |  | 
|  17198 bool Type::IsInstantiated(Genericity genericity, |  16209 bool Type::IsInstantiated(Genericity genericity, | 
|  17199                           intptr_t num_free_fun_type_params, |  16210                           intptr_t num_free_fun_type_params, | 
|  17200                           TrailPtr trail) const { |  16211                           TrailPtr trail) const { | 
|  17201   if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |  16212   if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | 
|  17202     return true; |  16213     return true; | 
|  17203   } |  16214   } | 
|  17204   if ((genericity == kAny) && (num_free_fun_type_params == kMaxInt32) && |  16215   if ((genericity == kAny) && (num_free_fun_type_params == kMaxInt32) && | 
|  17205       (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) { |  16216       (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated)) { | 
|  17206     return false; |  16217     return false; | 
|  17207   } |  16218   } | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  17235       // Type arguments are reset to null when finalizing such a type. |  16246       // Type arguments are reset to null when finalizing such a type. | 
|  17236       ASSERT(!IsFinalized()); |  16247       ASSERT(!IsFinalized()); | 
|  17237       len = num_type_args; |  16248       len = num_type_args; | 
|  17238     } |  16249     } | 
|  17239   } |  16250   } | 
|  17240   return (len == 0) || |  16251   return (len == 0) || | 
|  17241          args.IsSubvectorInstantiated(num_type_args - len, len, genericity, |  16252          args.IsSubvectorInstantiated(num_type_args - len, len, genericity, | 
|  17242                                       num_free_fun_type_params, trail); |  16253                                       num_free_fun_type_params, trail); | 
|  17243 } |  16254 } | 
|  17244  |  16255  | 
|  17245  |  | 
|  17246 RawAbstractType* Type::InstantiateFrom( |  16256 RawAbstractType* Type::InstantiateFrom( | 
|  17247     const TypeArguments& instantiator_type_arguments, |  16257     const TypeArguments& instantiator_type_arguments, | 
|  17248     const TypeArguments& function_type_arguments, |  16258     const TypeArguments& function_type_arguments, | 
|  17249     Error* bound_error, |  16259     Error* bound_error, | 
|  17250     TrailPtr instantiation_trail, |  16260     TrailPtr instantiation_trail, | 
|  17251     TrailPtr bound_trail, |  16261     TrailPtr bound_trail, | 
|  17252     Heap::Space space) const { |  16262     Heap::Space space) const { | 
|  17253   Zone* zone = Thread::Current()->zone(); |  16263   Zone* zone = Thread::Current()->zone(); | 
|  17254   ASSERT(IsFinalized() || IsBeingFinalized()); |  16264   ASSERT(IsFinalized() || IsBeingFinalized()); | 
|  17255   ASSERT(!IsInstantiated()); |  16265   ASSERT(!IsInstantiated()); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  17306   } else { |  16316   } else { | 
|  17307     instantiated_type.SetIsResolved(); |  16317     instantiated_type.SetIsResolved(); | 
|  17308     if (IsBeingFinalized()) { |  16318     if (IsBeingFinalized()) { | 
|  17309       instantiated_type.SetIsBeingFinalized(); |  16319       instantiated_type.SetIsBeingFinalized(); | 
|  17310     } |  16320     } | 
|  17311   } |  16321   } | 
|  17312   // Canonicalization is not part of instantiation. |  16322   // Canonicalization is not part of instantiation. | 
|  17313   return instantiated_type.raw(); |  16323   return instantiated_type.raw(); | 
|  17314 } |  16324 } | 
|  17315  |  16325  | 
|  17316  |  | 
|  17317 bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const { |  16326 bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const { | 
|  17318   ASSERT(!IsNull()); |  16327   ASSERT(!IsNull()); | 
|  17319   if (raw() == other.raw()) { |  16328   if (raw() == other.raw()) { | 
|  17320     return true; |  16329     return true; | 
|  17321   } |  16330   } | 
|  17322   if (other.IsTypeRef()) { |  16331   if (other.IsTypeRef()) { | 
|  17323     // Unfold right hand type. Divergence is controlled by left hand type. |  16332     // Unfold right hand type. Divergence is controlled by left hand type. | 
|  17324     const AbstractType& other_ref_type = |  16333     const AbstractType& other_ref_type = | 
|  17325         AbstractType::Handle(TypeRef::Cast(other).type()); |  16334         AbstractType::Handle(TypeRef::Cast(other).type()); | 
|  17326     ASSERT(!other_ref_type.IsTypeRef()); |  16335     ASSERT(!other_ref_type.IsTypeRef()); | 
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  17470     return true; |  16479     return true; | 
|  17471   } |  16480   } | 
|  17472   for (intptr_t i = num_fixed_params; i < num_params; i++) { |  16481   for (intptr_t i = num_fixed_params; i < num_params; i++) { | 
|  17473     if (sig_fun.ParameterNameAt(i) != other_sig_fun.ParameterNameAt(i)) { |  16482     if (sig_fun.ParameterNameAt(i) != other_sig_fun.ParameterNameAt(i)) { | 
|  17474       return false; |  16483       return false; | 
|  17475     } |  16484     } | 
|  17476   } |  16485   } | 
|  17477   return true; |  16486   return true; | 
|  17478 } |  16487 } | 
|  17479  |  16488  | 
|  17480  |  | 
|  17481 bool Type::IsRecursive() const { |  16489 bool Type::IsRecursive() const { | 
|  17482   return TypeArguments::Handle(arguments()).IsRecursive(); |  16490   return TypeArguments::Handle(arguments()).IsRecursive(); | 
|  17483 } |  16491 } | 
|  17484  |  16492  | 
|  17485  |  | 
|  17486 RawAbstractType* Type::CloneUnfinalized() const { |  16493 RawAbstractType* Type::CloneUnfinalized() const { | 
|  17487   ASSERT(IsResolved()); |  16494   ASSERT(IsResolved()); | 
|  17488   if (IsFinalized()) { |  16495   if (IsFinalized()) { | 
|  17489     return raw(); |  16496     return raw(); | 
|  17490   } |  16497   } | 
|  17491   ASSERT(!IsMalformed());       // Malformed types are finalized. |  16498   ASSERT(!IsMalformed());       // Malformed types are finalized. | 
|  17492   ASSERT(!IsBeingFinalized());  // Cloning must occur prior to finalization. |  16499   ASSERT(!IsBeingFinalized());  // Cloning must occur prior to finalization. | 
|  17493   Zone* zone = Thread::Current()->zone(); |  16500   Zone* zone = Thread::Current()->zone(); | 
|  17494   const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |  16501   const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 
|  17495   const TypeArguments& type_args_clone = |  16502   const TypeArguments& type_args_clone = | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  17542       fun_clone.SetParameterTypeAt(i, type); |  16549       fun_clone.SetParameterTypeAt(i, type); | 
|  17543     } |  16550     } | 
|  17544     fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); |  16551     fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); | 
|  17545     clone.set_signature(fun_clone); |  16552     clone.set_signature(fun_clone); | 
|  17546     fun_clone.SetSignatureType(clone); |  16553     fun_clone.SetSignatureType(clone); | 
|  17547   } |  16554   } | 
|  17548   clone.SetIsResolved(); |  16555   clone.SetIsResolved(); | 
|  17549   return clone.raw(); |  16556   return clone.raw(); | 
|  17550 } |  16557 } | 
|  17551  |  16558  | 
|  17552  |  | 
|  17553 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, |  16559 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, | 
|  17554                                            TrailPtr trail) const { |  16560                                            TrailPtr trail) const { | 
|  17555   ASSERT(IsFinalized()); |  16561   ASSERT(IsFinalized()); | 
|  17556   ASSERT(IsCanonical()); |  16562   ASSERT(IsCanonical()); | 
|  17557   ASSERT(!IsMalformed()); |  16563   ASSERT(!IsMalformed()); | 
|  17558   if (IsInstantiated()) { |  16564   if (IsInstantiated()) { | 
|  17559     return raw(); |  16565     return raw(); | 
|  17560   } |  16566   } | 
|  17561   // We may recursively encounter a type already being cloned, because we clone |  16567   // We may recursively encounter a type already being cloned, because we clone | 
|  17562   // the upper bounds of its uninstantiated type arguments in the same pass. |  16568   // the upper bounds of its uninstantiated type arguments in the same pass. | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  17622       AddOnlyBuddyToTrail(&trail, clone); |  16628       AddOnlyBuddyToTrail(&trail, clone); | 
|  17623     } |  16629     } | 
|  17624     type_args = type_args.CloneUninstantiated(new_owner, trail); |  16630     type_args = type_args.CloneUninstantiated(new_owner, trail); | 
|  17625     clone.set_arguments(type_args); |  16631     clone.set_arguments(type_args); | 
|  17626   } |  16632   } | 
|  17627   clone.SetIsFinalized(); |  16633   clone.SetIsFinalized(); | 
|  17628   clone ^= clone.Canonicalize(); |  16634   clone ^= clone.Canonicalize(); | 
|  17629   return clone.raw(); |  16635   return clone.raw(); | 
|  17630 } |  16636 } | 
|  17631  |  16637  | 
|  17632  |  | 
|  17633 RawAbstractType* Type::Canonicalize(TrailPtr trail) const { |  16638 RawAbstractType* Type::Canonicalize(TrailPtr trail) const { | 
|  17634   ASSERT(IsFinalized()); |  16639   ASSERT(IsFinalized()); | 
|  17635   if (IsCanonical() || IsMalformed()) { |  16640   if (IsCanonical() || IsMalformed()) { | 
|  17636     ASSERT(IsMalformed() || TypeArguments::Handle(arguments()).IsOld()); |  16641     ASSERT(IsMalformed() || TypeArguments::Handle(arguments()).IsOld()); | 
|  17637     return this->raw(); |  16642     return this->raw(); | 
|  17638   } |  16643   } | 
|  17639   Thread* thread = Thread::Current(); |  16644   Thread* thread = Thread::Current(); | 
|  17640   Zone* zone = thread->zone(); |  16645   Zone* zone = thread->zone(); | 
|  17641   Isolate* isolate = thread->isolate(); |  16646   Isolate* isolate = thread->isolate(); | 
|  17642  |  16647  | 
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  17752       ASSERT(type.IsOld()); |  16757       ASSERT(type.IsOld()); | 
|  17753       type.SetCanonical();  // Mark object as being canonical. |  16758       type.SetCanonical();  // Mark object as being canonical. | 
|  17754       bool present = table.Insert(type); |  16759       bool present = table.Insert(type); | 
|  17755       ASSERT(!present); |  16760       ASSERT(!present); | 
|  17756     } |  16761     } | 
|  17757     object_store->set_canonical_types(table.Release()); |  16762     object_store->set_canonical_types(table.Release()); | 
|  17758   } |  16763   } | 
|  17759   return type.raw(); |  16764   return type.raw(); | 
|  17760 } |  16765 } | 
|  17761  |  16766  | 
|  17762  |  | 
|  17763 #if defined(DEBUG) |  16767 #if defined(DEBUG) | 
|  17764 bool Type::CheckIsCanonical(Thread* thread) const { |  16768 bool Type::CheckIsCanonical(Thread* thread) const { | 
|  17765   if (IsMalformed()) { |  16769   if (IsMalformed()) { | 
|  17766     return true; |  16770     return true; | 
|  17767   } |  16771   } | 
|  17768   if (type_class() == Object::dynamic_class()) { |  16772   if (type_class() == Object::dynamic_class()) { | 
|  17769     return (raw() == Object::dynamic_type().raw()); |  16773     return (raw() == Object::dynamic_type().raw()); | 
|  17770   } |  16774   } | 
|  17771   Zone* zone = thread->zone(); |  16775   Zone* zone = thread->zone(); | 
|  17772   Isolate* isolate = thread->isolate(); |  16776   Isolate* isolate = thread->isolate(); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  17784   { |  16788   { | 
|  17785     SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); |  16789     SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); | 
|  17786     CanonicalTypeSet table(zone, object_store->canonical_types()); |  16790     CanonicalTypeSet table(zone, object_store->canonical_types()); | 
|  17787     type ^= table.GetOrNull(CanonicalTypeKey(*this)); |  16791     type ^= table.GetOrNull(CanonicalTypeKey(*this)); | 
|  17788     object_store->set_canonical_types(table.Release()); |  16792     object_store->set_canonical_types(table.Release()); | 
|  17789   } |  16793   } | 
|  17790   return (raw() == type.raw()); |  16794   return (raw() == type.raw()); | 
|  17791 } |  16795 } | 
|  17792 #endif  // DEBUG |  16796 #endif  // DEBUG | 
|  17793  |  16797  | 
|  17794  |  | 
|  17795 RawString* Type::EnumerateURIs() const { |  16798 RawString* Type::EnumerateURIs() const { | 
|  17796   if (IsDynamicType() || IsVoidType()) { |  16799   if (IsDynamicType() || IsVoidType()) { | 
|  17797     return Symbols::Empty().raw(); |  16800     return Symbols::Empty().raw(); | 
|  17798   } |  16801   } | 
|  17799   Thread* thread = Thread::Current(); |  16802   Thread* thread = Thread::Current(); | 
|  17800   Zone* zone = thread->zone(); |  16803   Zone* zone = thread->zone(); | 
|  17801   GrowableHandlePtrArray<const String> pieces(zone, 6); |  16804   GrowableHandlePtrArray<const String> pieces(zone, 6); | 
|  17802   if (IsFunctionType()) { |  16805   if (IsFunctionType()) { | 
|  17803     // The scope class and type arguments do not appear explicitly in the user |  16806     // The scope class and type arguments do not appear explicitly in the user | 
|  17804     // visible name. The type arguments were used to instantiate the function |  16807     // visible name. The type arguments were used to instantiate the function | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  17821     pieces.Add(Symbols::SpaceIsFromSpace()); |  16824     pieces.Add(Symbols::SpaceIsFromSpace()); | 
|  17822     const Library& library = Library::Handle(zone, cls.library()); |  16825     const Library& library = Library::Handle(zone, cls.library()); | 
|  17823     pieces.Add(String::Handle(zone, library.url())); |  16826     pieces.Add(String::Handle(zone, library.url())); | 
|  17824     pieces.Add(Symbols::NewLine()); |  16827     pieces.Add(Symbols::NewLine()); | 
|  17825     const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |  16828     const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 
|  17826     pieces.Add(String::Handle(zone, type_args.EnumerateURIs())); |  16829     pieces.Add(String::Handle(zone, type_args.EnumerateURIs())); | 
|  17827   } |  16830   } | 
|  17828   return Symbols::FromConcatAll(thread, pieces); |  16831   return Symbols::FromConcatAll(thread, pieces); | 
|  17829 } |  16832 } | 
|  17830  |  16833  | 
|  17831  |  | 
|  17832 intptr_t Type::ComputeHash() const { |  16834 intptr_t Type::ComputeHash() const { | 
|  17833   ASSERT(IsFinalized()); |  16835   ASSERT(IsFinalized()); | 
|  17834   uint32_t result = 1; |  16836   uint32_t result = 1; | 
|  17835   if (IsMalformed()) return result; |  16837   if (IsMalformed()) return result; | 
|  17836   result = CombineHashes(result, Class::Handle(type_class()).id()); |  16838   result = CombineHashes(result, Class::Handle(type_class()).id()); | 
|  17837   result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); |  16839   result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); | 
|  17838   if (IsFunctionType()) { |  16840   if (IsFunctionType()) { | 
|  17839     const Function& sig_fun = Function::Handle(signature()); |  16841     const Function& sig_fun = Function::Handle(signature()); | 
|  17840     AbstractType& type = AbstractType::Handle(sig_fun.result_type()); |  16842     AbstractType& type = AbstractType::Handle(sig_fun.result_type()); | 
|  17841     result = CombineHashes(result, type.Hash()); |  16843     result = CombineHashes(result, type.Hash()); | 
|  17842     result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters()); |  16844     result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters()); | 
|  17843     const intptr_t num_params = sig_fun.NumParameters(); |  16845     const intptr_t num_params = sig_fun.NumParameters(); | 
|  17844     for (intptr_t i = 0; i < num_params; i++) { |  16846     for (intptr_t i = 0; i < num_params; i++) { | 
|  17845       type = sig_fun.ParameterTypeAt(i); |  16847       type = sig_fun.ParameterTypeAt(i); | 
|  17846       result = CombineHashes(result, type.Hash()); |  16848       result = CombineHashes(result, type.Hash()); | 
|  17847     } |  16849     } | 
|  17848     if (sig_fun.NumOptionalNamedParameters() > 0) { |  16850     if (sig_fun.NumOptionalNamedParameters() > 0) { | 
|  17849       String& param_name = String::Handle(); |  16851       String& param_name = String::Handle(); | 
|  17850       for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { |  16852       for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) { | 
|  17851         param_name = sig_fun.ParameterNameAt(i); |  16853         param_name = sig_fun.ParameterNameAt(i); | 
|  17852         result = CombineHashes(result, param_name.Hash()); |  16854         result = CombineHashes(result, param_name.Hash()); | 
|  17853       } |  16855       } | 
|  17854     } |  16856     } | 
|  17855   } |  16857   } | 
|  17856   result = FinalizeHash(result, kHashBits); |  16858   result = FinalizeHash(result, kHashBits); | 
|  17857   SetHash(result); |  16859   SetHash(result); | 
|  17858   return result; |  16860   return result; | 
|  17859 } |  16861 } | 
|  17860  |  16862  | 
|  17861  |  | 
|  17862 void Type::set_type_class(const Class& value) const { |  16863 void Type::set_type_class(const Class& value) const { | 
|  17863   ASSERT(!value.IsNull()); |  16864   ASSERT(!value.IsNull()); | 
|  17864   StorePointer(&raw_ptr()->type_class_id_, |  16865   StorePointer(&raw_ptr()->type_class_id_, | 
|  17865                reinterpret_cast<RawObject*>(Smi::New(value.id()))); |  16866                reinterpret_cast<RawObject*>(Smi::New(value.id()))); | 
|  17866 } |  16867 } | 
|  17867  |  16868  | 
|  17868  |  | 
|  17869 void Type::set_unresolved_class(const Object& value) const { |  16869 void Type::set_unresolved_class(const Object& value) const { | 
|  17870   ASSERT(!value.IsNull() && value.IsUnresolvedClass()); |  16870   ASSERT(!value.IsNull() && value.IsUnresolvedClass()); | 
|  17871   StorePointer(&raw_ptr()->type_class_id_, value.raw()); |  16871   StorePointer(&raw_ptr()->type_class_id_, value.raw()); | 
|  17872 } |  16872 } | 
|  17873  |  16873  | 
|  17874  |  | 
|  17875 void Type::set_arguments(const TypeArguments& value) const { |  16874 void Type::set_arguments(const TypeArguments& value) const { | 
|  17876   ASSERT(!IsCanonical()); |  16875   ASSERT(!IsCanonical()); | 
|  17877   StorePointer(&raw_ptr()->arguments_, value.raw()); |  16876   StorePointer(&raw_ptr()->arguments_, value.raw()); | 
|  17878 } |  16877 } | 
|  17879  |  16878  | 
|  17880  |  | 
|  17881 RawType* Type::New(Heap::Space space) { |  16879 RawType* Type::New(Heap::Space space) { | 
|  17882   RawObject* raw = |  16880   RawObject* raw = | 
|  17883       Object::Allocate(Type::kClassId, Type::InstanceSize(), space); |  16881       Object::Allocate(Type::kClassId, Type::InstanceSize(), space); | 
|  17884   return reinterpret_cast<RawType*>(raw); |  16882   return reinterpret_cast<RawType*>(raw); | 
|  17885 } |  16883 } | 
|  17886  |  16884  | 
|  17887  |  | 
|  17888 RawType* Type::New(const Object& clazz, |  16885 RawType* Type::New(const Object& clazz, | 
|  17889                    const TypeArguments& arguments, |  16886                    const TypeArguments& arguments, | 
|  17890                    TokenPosition token_pos, |  16887                    TokenPosition token_pos, | 
|  17891                    Heap::Space space) { |  16888                    Heap::Space space) { | 
|  17892   const Type& result = Type::Handle(Type::New(space)); |  16889   const Type& result = Type::Handle(Type::New(space)); | 
|  17893   if (clazz.IsClass()) { |  16890   if (clazz.IsClass()) { | 
|  17894     result.set_type_class(Class::Cast(clazz)); |  16891     result.set_type_class(Class::Cast(clazz)); | 
|  17895   } else { |  16892   } else { | 
|  17896     result.set_unresolved_class(clazz); |  16893     result.set_unresolved_class(clazz); | 
|  17897   } |  16894   } | 
|  17898   result.set_arguments(arguments); |  16895   result.set_arguments(arguments); | 
|  17899   result.SetHash(0); |  16896   result.SetHash(0); | 
|  17900   result.set_token_pos(token_pos); |  16897   result.set_token_pos(token_pos); | 
|  17901   result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); |  16898   result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated); | 
|  17902   return result.raw(); |  16899   return result.raw(); | 
|  17903 } |  16900 } | 
|  17904  |  16901  | 
|  17905  |  | 
|  17906 void Type::set_token_pos(TokenPosition token_pos) const { |  16902 void Type::set_token_pos(TokenPosition token_pos) const { | 
|  17907   ASSERT(!token_pos.IsClassifying()); |  16903   ASSERT(!token_pos.IsClassifying()); | 
|  17908   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |  16904   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|  17909 } |  16905 } | 
|  17910  |  16906  | 
|  17911  |  | 
|  17912 void Type::set_type_state(int8_t state) const { |  16907 void Type::set_type_state(int8_t state) const { | 
|  17913   ASSERT((state >= RawType::kAllocated) && |  16908   ASSERT((state >= RawType::kAllocated) && | 
|  17914          (state <= RawType::kFinalizedUninstantiated)); |  16909          (state <= RawType::kFinalizedUninstantiated)); | 
|  17915   StoreNonPointer(&raw_ptr()->type_state_, state); |  16910   StoreNonPointer(&raw_ptr()->type_state_, state); | 
|  17916 } |  16911 } | 
|  17917  |  16912  | 
|  17918  |  | 
|  17919 const char* Type::ToCString() const { |  16913 const char* Type::ToCString() const { | 
|  17920   if (IsNull()) { |  16914   if (IsNull()) { | 
|  17921     return "Type: null"; |  16915     return "Type: null"; | 
|  17922   } |  16916   } | 
|  17923   Zone* zone = Thread::Current()->zone(); |  16917   Zone* zone = Thread::Current()->zone(); | 
|  17924   const char* unresolved = IsResolved() ? "" : "Unresolved "; |  16918   const char* unresolved = IsResolved() ? "" : "Unresolved "; | 
|  17925   const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); |  16919   const TypeArguments& type_args = TypeArguments::Handle(zone, arguments()); | 
|  17926   const char* args_cstr = type_args.IsNull() ? "null" : type_args.ToCString(); |  16920   const char* args_cstr = type_args.IsNull() ? "null" : type_args.ToCString(); | 
|  17927   Class& cls = Class::Handle(zone); |  16921   Class& cls = Class::Handle(zone); | 
|  17928   const char* class_name; |  16922   const char* class_name; | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  17948   } else if (IsResolved() && IsFinalized() && IsRecursive()) { |  16942   } else if (IsResolved() && IsFinalized() && IsRecursive()) { | 
|  17949     const intptr_t hash = Hash(); |  16943     const intptr_t hash = Hash(); | 
|  17950     return OS::SCreate(zone, "Type: (@%p H%" Px ") class '%s', args:[%s]", |  16944     return OS::SCreate(zone, "Type: (@%p H%" Px ") class '%s', args:[%s]", | 
|  17951                        raw(), hash, class_name, args_cstr); |  16945                        raw(), hash, class_name, args_cstr); | 
|  17952   } else { |  16946   } else { | 
|  17953     return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved, |  16947     return OS::SCreate(zone, "%sType: class '%s', args:[%s]", unresolved, | 
|  17954                        class_name, args_cstr); |  16948                        class_name, args_cstr); | 
|  17955   } |  16949   } | 
|  17956 } |  16950 } | 
|  17957  |  16951  | 
|  17958  |  | 
|  17959 bool TypeRef::IsInstantiated(Genericity genericity, |  16952 bool TypeRef::IsInstantiated(Genericity genericity, | 
|  17960                              intptr_t num_free_fun_type_params, |  16953                              intptr_t num_free_fun_type_params, | 
|  17961                              TrailPtr trail) const { |  16954                              TrailPtr trail) const { | 
|  17962   if (TestAndAddToTrail(&trail)) { |  16955   if (TestAndAddToTrail(&trail)) { | 
|  17963     return true; |  16956     return true; | 
|  17964   } |  16957   } | 
|  17965   const AbstractType& ref_type = AbstractType::Handle(type()); |  16958   const AbstractType& ref_type = AbstractType::Handle(type()); | 
|  17966   return !ref_type.IsNull() && |  16959   return !ref_type.IsNull() && | 
|  17967          ref_type.IsInstantiated(genericity, num_free_fun_type_params, trail); |  16960          ref_type.IsInstantiated(genericity, num_free_fun_type_params, trail); | 
|  17968 } |  16961 } | 
|  17969  |  16962  | 
|  17970  |  | 
|  17971 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const { |  16963 bool TypeRef::IsEquivalent(const Instance& other, TrailPtr trail) const { | 
|  17972   if (raw() == other.raw()) { |  16964   if (raw() == other.raw()) { | 
|  17973     return true; |  16965     return true; | 
|  17974   } |  16966   } | 
|  17975   if (!other.IsAbstractType()) { |  16967   if (!other.IsAbstractType()) { | 
|  17976     return false; |  16968     return false; | 
|  17977   } |  16969   } | 
|  17978   if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { |  16970   if (TestAndAddBuddyToTrail(&trail, AbstractType::Cast(other))) { | 
|  17979     return true; |  16971     return true; | 
|  17980   } |  16972   } | 
|  17981   const AbstractType& ref_type = AbstractType::Handle(type()); |  16973   const AbstractType& ref_type = AbstractType::Handle(type()); | 
|  17982   return !ref_type.IsNull() && ref_type.IsEquivalent(other, trail); |  16974   return !ref_type.IsNull() && ref_type.IsEquivalent(other, trail); | 
|  17983 } |  16975 } | 
|  17984  |  16976  | 
|  17985  |  | 
|  17986 RawTypeRef* TypeRef::InstantiateFrom( |  16977 RawTypeRef* TypeRef::InstantiateFrom( | 
|  17987     const TypeArguments& instantiator_type_arguments, |  16978     const TypeArguments& instantiator_type_arguments, | 
|  17988     const TypeArguments& function_type_arguments, |  16979     const TypeArguments& function_type_arguments, | 
|  17989     Error* bound_error, |  16980     Error* bound_error, | 
|  17990     TrailPtr instantiation_trail, |  16981     TrailPtr instantiation_trail, | 
|  17991     TrailPtr bound_trail, |  16982     TrailPtr bound_trail, | 
|  17992     Heap::Space space) const { |  16983     Heap::Space space) const { | 
|  17993   TypeRef& instantiated_type_ref = TypeRef::Handle(); |  16984   TypeRef& instantiated_type_ref = TypeRef::Handle(); | 
|  17994   instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); |  16985   instantiated_type_ref ^= OnlyBuddyInTrail(instantiation_trail); | 
|  17995   if (!instantiated_type_ref.IsNull()) { |  16986   if (!instantiated_type_ref.IsNull()) { | 
|  17996     return instantiated_type_ref.raw(); |  16987     return instantiated_type_ref.raw(); | 
|  17997   } |  16988   } | 
|  17998   instantiated_type_ref = TypeRef::New(); |  16989   instantiated_type_ref = TypeRef::New(); | 
|  17999   AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); |  16990   AddOnlyBuddyToTrail(&instantiation_trail, instantiated_type_ref); | 
|  18000  |  16991  | 
|  18001   AbstractType& ref_type = AbstractType::Handle(type()); |  16992   AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18002   ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); |  16993   ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); | 
|  18003   AbstractType& instantiated_ref_type = AbstractType::Handle(); |  16994   AbstractType& instantiated_ref_type = AbstractType::Handle(); | 
|  18004   instantiated_ref_type = ref_type.InstantiateFrom( |  16995   instantiated_ref_type = ref_type.InstantiateFrom( | 
|  18005       instantiator_type_arguments, function_type_arguments, bound_error, |  16996       instantiator_type_arguments, function_type_arguments, bound_error, | 
|  18006       instantiation_trail, bound_trail, space); |  16997       instantiation_trail, bound_trail, space); | 
|  18007   ASSERT(!instantiated_ref_type.IsTypeRef()); |  16998   ASSERT(!instantiated_ref_type.IsTypeRef()); | 
|  18008   instantiated_type_ref.set_type(instantiated_ref_type); |  16999   instantiated_type_ref.set_type(instantiated_ref_type); | 
|  18009   return instantiated_type_ref.raw(); |  17000   return instantiated_type_ref.raw(); | 
|  18010 } |  17001 } | 
|  18011  |  17002  | 
|  18012  |  | 
|  18013 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, |  17003 RawTypeRef* TypeRef::CloneUninstantiated(const Class& new_owner, | 
|  18014                                          TrailPtr trail) const { |  17004                                          TrailPtr trail) const { | 
|  18015   TypeRef& cloned_type_ref = TypeRef::Handle(); |  17005   TypeRef& cloned_type_ref = TypeRef::Handle(); | 
|  18016   cloned_type_ref ^= OnlyBuddyInTrail(trail); |  17006   cloned_type_ref ^= OnlyBuddyInTrail(trail); | 
|  18017   if (!cloned_type_ref.IsNull()) { |  17007   if (!cloned_type_ref.IsNull()) { | 
|  18018     return cloned_type_ref.raw(); |  17008     return cloned_type_ref.raw(); | 
|  18019   } |  17009   } | 
|  18020   cloned_type_ref = TypeRef::New(); |  17010   cloned_type_ref = TypeRef::New(); | 
|  18021   AddOnlyBuddyToTrail(&trail, cloned_type_ref); |  17011   AddOnlyBuddyToTrail(&trail, cloned_type_ref); | 
|  18022   AbstractType& ref_type = AbstractType::Handle(type()); |  17012   AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18023   ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); |  17013   ASSERT(!ref_type.IsNull() && !ref_type.IsTypeRef()); | 
|  18024   AbstractType& cloned_ref_type = AbstractType::Handle(); |  17014   AbstractType& cloned_ref_type = AbstractType::Handle(); | 
|  18025   cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); |  17015   cloned_ref_type = ref_type.CloneUninstantiated(new_owner, trail); | 
|  18026   ASSERT(!cloned_ref_type.IsTypeRef()); |  17016   ASSERT(!cloned_ref_type.IsTypeRef()); | 
|  18027   cloned_type_ref.set_type(cloned_ref_type); |  17017   cloned_type_ref.set_type(cloned_ref_type); | 
|  18028   return cloned_type_ref.raw(); |  17018   return cloned_type_ref.raw(); | 
|  18029 } |  17019 } | 
|  18030  |  17020  | 
|  18031  |  | 
|  18032 void TypeRef::set_type(const AbstractType& value) const { |  17021 void TypeRef::set_type(const AbstractType& value) const { | 
|  18033   ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); |  17022   ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass()); | 
|  18034   ASSERT(!value.IsTypeRef()); |  17023   ASSERT(!value.IsTypeRef()); | 
|  18035   StorePointer(&raw_ptr()->type_, value.raw()); |  17024   StorePointer(&raw_ptr()->type_, value.raw()); | 
|  18036 } |  17025 } | 
|  18037  |  17026  | 
|  18038  |  | 
|  18039 // A TypeRef cannot be canonical by definition. Only its referenced type can be. |  17027 // A TypeRef cannot be canonical by definition. Only its referenced type can be. | 
|  18040 // Consider the type Derived, where class Derived extends Base<Derived>. |  17028 // Consider the type Derived, where class Derived extends Base<Derived>. | 
|  18041 // The first type argument of its flattened type argument vector is Derived, |  17029 // The first type argument of its flattened type argument vector is Derived, | 
|  18042 // represented by a TypeRef pointing to itself. |  17030 // represented by a TypeRef pointing to itself. | 
|  18043 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const { |  17031 RawAbstractType* TypeRef::Canonicalize(TrailPtr trail) const { | 
|  18044   if (TestAndAddToTrail(&trail)) { |  17032   if (TestAndAddToTrail(&trail)) { | 
|  18045     return raw(); |  17033     return raw(); | 
|  18046   } |  17034   } | 
|  18047   // TODO(regis): Try to reduce the number of nodes required to represent the |  17035   // TODO(regis): Try to reduce the number of nodes required to represent the | 
|  18048   // referenced recursive type. |  17036   // referenced recursive type. | 
|  18049   AbstractType& ref_type = AbstractType::Handle(type()); |  17037   AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18050   ASSERT(!ref_type.IsNull()); |  17038   ASSERT(!ref_type.IsNull()); | 
|  18051   ref_type = ref_type.Canonicalize(trail); |  17039   ref_type = ref_type.Canonicalize(trail); | 
|  18052   set_type(ref_type); |  17040   set_type(ref_type); | 
|  18053   return raw(); |  17041   return raw(); | 
|  18054 } |  17042 } | 
|  18055  |  17043  | 
|  18056  |  | 
|  18057 #if defined(DEBUG) |  17044 #if defined(DEBUG) | 
|  18058 bool TypeRef::CheckIsCanonical(Thread* thread) const { |  17045 bool TypeRef::CheckIsCanonical(Thread* thread) const { | 
|  18059   AbstractType& ref_type = AbstractType::Handle(type()); |  17046   AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18060   ASSERT(!ref_type.IsNull()); |  17047   ASSERT(!ref_type.IsNull()); | 
|  18061   return ref_type.CheckIsCanonical(thread); |  17048   return ref_type.CheckIsCanonical(thread); | 
|  18062 } |  17049 } | 
|  18063 #endif  // DEBUG |  17050 #endif  // DEBUG | 
|  18064  |  17051  | 
|  18065  |  | 
|  18066 RawString* TypeRef::EnumerateURIs() const { |  17052 RawString* TypeRef::EnumerateURIs() const { | 
|  18067   Thread* thread = Thread::Current(); |  17053   Thread* thread = Thread::Current(); | 
|  18068   Zone* zone = thread->zone(); |  17054   Zone* zone = thread->zone(); | 
|  18069   const AbstractType& ref_type = AbstractType::Handle(zone, type()); |  17055   const AbstractType& ref_type = AbstractType::Handle(zone, type()); | 
|  18070   ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType()); |  17056   ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType()); | 
|  18071   GrowableHandlePtrArray<const String> pieces(zone, 6); |  17057   GrowableHandlePtrArray<const String> pieces(zone, 6); | 
|  18072   const Class& cls = Class::Handle(zone, ref_type.type_class()); |  17058   const Class& cls = Class::Handle(zone, ref_type.type_class()); | 
|  18073   pieces.Add(Symbols::TwoSpaces()); |  17059   pieces.Add(Symbols::TwoSpaces()); | 
|  18074   pieces.Add(String::Handle(zone, cls.UserVisibleName())); |  17060   pieces.Add(String::Handle(zone, cls.UserVisibleName())); | 
|  18075   // Break cycle by not printing type arguments, but '<optimized out>' instead. |  17061   // Break cycle by not printing type arguments, but '<optimized out>' instead. | 
|  18076   pieces.Add(Symbols::OptimizedOut()); |  17062   pieces.Add(Symbols::OptimizedOut()); | 
|  18077   pieces.Add(Symbols::SpaceIsFromSpace()); |  17063   pieces.Add(Symbols::SpaceIsFromSpace()); | 
|  18078   const Library& library = Library::Handle(zone, cls.library()); |  17064   const Library& library = Library::Handle(zone, cls.library()); | 
|  18079   pieces.Add(String::Handle(zone, library.url())); |  17065   pieces.Add(String::Handle(zone, library.url())); | 
|  18080   pieces.Add(Symbols::NewLine()); |  17066   pieces.Add(Symbols::NewLine()); | 
|  18081   return Symbols::FromConcatAll(thread, pieces); |  17067   return Symbols::FromConcatAll(thread, pieces); | 
|  18082 } |  17068 } | 
|  18083  |  17069  | 
|  18084  |  | 
|  18085 intptr_t TypeRef::Hash() const { |  17070 intptr_t TypeRef::Hash() const { | 
|  18086   // Do not calculate the hash of the referenced type to avoid divergence. |  17071   // Do not calculate the hash of the referenced type to avoid divergence. | 
|  18087   const AbstractType& ref_type = AbstractType::Handle(type()); |  17072   const AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18088   ASSERT(!ref_type.IsNull()); |  17073   ASSERT(!ref_type.IsNull()); | 
|  18089   const uint32_t result = Class::Handle(ref_type.type_class()).id(); |  17074   const uint32_t result = Class::Handle(ref_type.type_class()).id(); | 
|  18090   return FinalizeHash(result, kHashBits); |  17075   return FinalizeHash(result, kHashBits); | 
|  18091 } |  17076 } | 
|  18092  |  17077  | 
|  18093  |  | 
|  18094 RawTypeRef* TypeRef::New() { |  17078 RawTypeRef* TypeRef::New() { | 
|  18095   RawObject* raw = |  17079   RawObject* raw = | 
|  18096       Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld); |  17080       Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld); | 
|  18097   return reinterpret_cast<RawTypeRef*>(raw); |  17081   return reinterpret_cast<RawTypeRef*>(raw); | 
|  18098 } |  17082 } | 
|  18099  |  17083  | 
|  18100  |  | 
|  18101 RawTypeRef* TypeRef::New(const AbstractType& type) { |  17084 RawTypeRef* TypeRef::New(const AbstractType& type) { | 
|  18102   const TypeRef& result = TypeRef::Handle(TypeRef::New()); |  17085   const TypeRef& result = TypeRef::Handle(TypeRef::New()); | 
|  18103   result.set_type(type); |  17086   result.set_type(type); | 
|  18104   return result.raw(); |  17087   return result.raw(); | 
|  18105 } |  17088 } | 
|  18106  |  17089  | 
|  18107  |  | 
|  18108 const char* TypeRef::ToCString() const { |  17090 const char* TypeRef::ToCString() const { | 
|  18109   AbstractType& ref_type = AbstractType::Handle(type()); |  17091   AbstractType& ref_type = AbstractType::Handle(type()); | 
|  18110   if (ref_type.IsNull()) { |  17092   if (ref_type.IsNull()) { | 
|  18111     return "TypeRef: null"; |  17093     return "TypeRef: null"; | 
|  18112   } |  17094   } | 
|  18113   const char* type_cstr = |  17095   const char* type_cstr = | 
|  18114       String::Handle(Class::Handle(type_class()).Name()).ToCString(); |  17096       String::Handle(Class::Handle(type_class()).Name()).ToCString(); | 
|  18115   if (ref_type.IsFinalized()) { |  17097   if (ref_type.IsFinalized()) { | 
|  18116     const intptr_t hash = ref_type.Hash(); |  17098     const intptr_t hash = ref_type.Hash(); | 
|  18117     return OS::SCreate(Thread::Current()->zone(), |  17099     return OS::SCreate(Thread::Current()->zone(), | 
|  18118                        "TypeRef: %s<...> (@%p H%" Px ")", type_cstr, |  17100                        "TypeRef: %s<...> (@%p H%" Px ")", type_cstr, | 
|  18119                        ref_type.raw(), hash); |  17101                        ref_type.raw(), hash); | 
|  18120   } else { |  17102   } else { | 
|  18121     return OS::SCreate(Thread::Current()->zone(), "TypeRef: %s<...>", |  17103     return OS::SCreate(Thread::Current()->zone(), "TypeRef: %s<...>", | 
|  18122                        type_cstr); |  17104                        type_cstr); | 
|  18123   } |  17105   } | 
|  18124 } |  17106 } | 
|  18125  |  17107  | 
|  18126  |  | 
|  18127 void TypeParameter::SetIsFinalized() const { |  17108 void TypeParameter::SetIsFinalized() const { | 
|  18128   ASSERT(!IsFinalized()); |  17109   ASSERT(!IsFinalized()); | 
|  18129   set_type_state(RawTypeParameter::kFinalizedUninstantiated); |  17110   set_type_state(RawTypeParameter::kFinalizedUninstantiated); | 
|  18130 } |  17111 } | 
|  18131  |  17112  | 
|  18132  |  | 
|  18133 bool TypeParameter::IsInstantiated(Genericity genericity, |  17113 bool TypeParameter::IsInstantiated(Genericity genericity, | 
|  18134                                    intptr_t num_free_fun_type_params, |  17114                                    intptr_t num_free_fun_type_params, | 
|  18135                                    TrailPtr trail) const { |  17115                                    TrailPtr trail) const { | 
|  18136   if (IsClassTypeParameter()) { |  17116   if (IsClassTypeParameter()) { | 
|  18137     return genericity == kFunctions; |  17117     return genericity == kFunctions; | 
|  18138   } |  17118   } | 
|  18139   ASSERT(IsFunctionTypeParameter()); |  17119   ASSERT(IsFunctionTypeParameter()); | 
|  18140   ASSERT(IsFinalized()); |  17120   ASSERT(IsFinalized()); | 
|  18141   return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params); |  17121   return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params); | 
|  18142 } |  17122 } | 
|  18143  |  17123  | 
|  18144  |  | 
|  18145 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { |  17124 bool TypeParameter::IsEquivalent(const Instance& other, TrailPtr trail) const { | 
|  18146   if (raw() == other.raw()) { |  17125   if (raw() == other.raw()) { | 
|  18147     return true; |  17126     return true; | 
|  18148   } |  17127   } | 
|  18149   if (other.IsTypeRef()) { |  17128   if (other.IsTypeRef()) { | 
|  18150     // Unfold right hand type. Divergence is controlled by left hand type. |  17129     // Unfold right hand type. Divergence is controlled by left hand type. | 
|  18151     const AbstractType& other_ref_type = |  17130     const AbstractType& other_ref_type = | 
|  18152         AbstractType::Handle(TypeRef::Cast(other).type()); |  17131         AbstractType::Handle(TypeRef::Cast(other).type()); | 
|  18153     ASSERT(!other_ref_type.IsTypeRef()); |  17132     ASSERT(!other_ref_type.IsTypeRef()); | 
|  18154     return IsEquivalent(other_ref_type, trail); |  17133     return IsEquivalent(other_ref_type, trail); | 
|  18155   } |  17134   } | 
|  18156   if (!other.IsTypeParameter()) { |  17135   if (!other.IsTypeParameter()) { | 
|  18157     return false; |  17136     return false; | 
|  18158   } |  17137   } | 
|  18159   const TypeParameter& other_type_param = TypeParameter::Cast(other); |  17138   const TypeParameter& other_type_param = TypeParameter::Cast(other); | 
|  18160   if (parameterized_class_id() != other_type_param.parameterized_class_id()) { |  17139   if (parameterized_class_id() != other_type_param.parameterized_class_id()) { | 
|  18161     return false; |  17140     return false; | 
|  18162   } |  17141   } | 
|  18163   // The function doesn't matter in type tests, but it does in canonicalization. |  17142   // The function doesn't matter in type tests, but it does in canonicalization. | 
|  18164   if (parameterized_function() != other_type_param.parameterized_function()) { |  17143   if (parameterized_function() != other_type_param.parameterized_function()) { | 
|  18165     return false; |  17144     return false; | 
|  18166   } |  17145   } | 
|  18167   if (IsFinalized() == other_type_param.IsFinalized()) { |  17146   if (IsFinalized() == other_type_param.IsFinalized()) { | 
|  18168     return (index() == other_type_param.index()); |  17147     return (index() == other_type_param.index()); | 
|  18169   } |  17148   } | 
|  18170   return name() == other_type_param.name(); |  17149   return name() == other_type_param.name(); | 
|  18171 } |  17150 } | 
|  18172  |  17151  | 
|  18173  |  | 
|  18174 void TypeParameter::set_parameterized_class(const Class& value) const { |  17152 void TypeParameter::set_parameterized_class(const Class& value) const { | 
|  18175   // Set value may be null. |  17153   // Set value may be null. | 
|  18176   classid_t cid = kFunctionCid;  // Denotes a function type parameter. |  17154   classid_t cid = kFunctionCid;  // Denotes a function type parameter. | 
|  18177   if (!value.IsNull()) { |  17155   if (!value.IsNull()) { | 
|  18178     cid = value.id(); |  17156     cid = value.id(); | 
|  18179   } |  17157   } | 
|  18180   StoreNonPointer(&raw_ptr()->parameterized_class_id_, cid); |  17158   StoreNonPointer(&raw_ptr()->parameterized_class_id_, cid); | 
|  18181 } |  17159 } | 
|  18182  |  17160  | 
|  18183  |  | 
|  18184 classid_t TypeParameter::parameterized_class_id() const { |  17161 classid_t TypeParameter::parameterized_class_id() const { | 
|  18185   return raw_ptr()->parameterized_class_id_; |  17162   return raw_ptr()->parameterized_class_id_; | 
|  18186 } |  17163 } | 
|  18187  |  17164  | 
|  18188  |  | 
|  18189 RawClass* TypeParameter::parameterized_class() const { |  17165 RawClass* TypeParameter::parameterized_class() const { | 
|  18190   classid_t cid = parameterized_class_id(); |  17166   classid_t cid = parameterized_class_id(); | 
|  18191   if (cid == kFunctionCid) { |  17167   if (cid == kFunctionCid) { | 
|  18192     return Class::null(); |  17168     return Class::null(); | 
|  18193   } |  17169   } | 
|  18194   return Isolate::Current()->class_table()->At(cid); |  17170   return Isolate::Current()->class_table()->At(cid); | 
|  18195 } |  17171 } | 
|  18196  |  17172  | 
|  18197  |  | 
|  18198 void TypeParameter::set_parameterized_function(const Function& value) const { |  17173 void TypeParameter::set_parameterized_function(const Function& value) const { | 
|  18199   StorePointer(&raw_ptr()->parameterized_function_, value.raw()); |  17174   StorePointer(&raw_ptr()->parameterized_function_, value.raw()); | 
|  18200 } |  17175 } | 
|  18201  |  17176  | 
|  18202  |  | 
|  18203 void TypeParameter::set_index(intptr_t value) const { |  17177 void TypeParameter::set_index(intptr_t value) const { | 
|  18204   ASSERT(value >= 0); |  17178   ASSERT(value >= 0); | 
|  18205   ASSERT(Utils::IsInt(16, value)); |  17179   ASSERT(Utils::IsInt(16, value)); | 
|  18206   StoreNonPointer(&raw_ptr()->index_, value); |  17180   StoreNonPointer(&raw_ptr()->index_, value); | 
|  18207 } |  17181 } | 
|  18208  |  17182  | 
|  18209  |  | 
|  18210 void TypeParameter::set_name(const String& value) const { |  17183 void TypeParameter::set_name(const String& value) const { | 
|  18211   ASSERT(value.IsSymbol()); |  17184   ASSERT(value.IsSymbol()); | 
|  18212   StorePointer(&raw_ptr()->name_, value.raw()); |  17185   StorePointer(&raw_ptr()->name_, value.raw()); | 
|  18213 } |  17186 } | 
|  18214  |  17187  | 
|  18215  |  | 
|  18216 void TypeParameter::set_bound(const AbstractType& value) const { |  17188 void TypeParameter::set_bound(const AbstractType& value) const { | 
|  18217   StorePointer(&raw_ptr()->bound_, value.raw()); |  17189   StorePointer(&raw_ptr()->bound_, value.raw()); | 
|  18218 } |  17190 } | 
|  18219  |  17191  | 
|  18220  |  | 
|  18221 RawAbstractType* TypeParameter::InstantiateFrom( |  17192 RawAbstractType* TypeParameter::InstantiateFrom( | 
|  18222     const TypeArguments& instantiator_type_arguments, |  17193     const TypeArguments& instantiator_type_arguments, | 
|  18223     const TypeArguments& function_type_arguments, |  17194     const TypeArguments& function_type_arguments, | 
|  18224     Error* bound_error, |  17195     Error* bound_error, | 
|  18225     TrailPtr instantiation_trail, |  17196     TrailPtr instantiation_trail, | 
|  18226     TrailPtr bound_trail, |  17197     TrailPtr bound_trail, | 
|  18227     Heap::Space space) const { |  17198     Heap::Space space) const { | 
|  18228   ASSERT(IsFinalized()); |  17199   ASSERT(IsFinalized()); | 
|  18229   if (IsFunctionTypeParameter()) { |  17200   if (IsFunctionTypeParameter()) { | 
|  18230     // We make the distinction between a null function_type_arguments vector, |  17201     // We make the distinction between a null function_type_arguments vector, | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  18254   // it is still uninstantiated and that we are instantiating at finalization |  17225   // it is still uninstantiated and that we are instantiating at finalization | 
|  18255   // time (i.e. compile time). |  17226   // time (i.e. compile time). | 
|  18256   // Indeed, the instantiator (type arguments of an instance) is always |  17227   // Indeed, the instantiator (type arguments of an instance) is always | 
|  18257   // instantiated at run time and any bounds were checked during allocation. |  17228   // instantiated at run time and any bounds were checked during allocation. | 
|  18258   // Similarly, function type arguments are always instantiated before being |  17229   // Similarly, function type arguments are always instantiated before being | 
|  18259   // passed to a function at run time and bounds are checked as part of the |  17230   // passed to a function at run time and bounds are checked as part of the | 
|  18260   // signature compatibility check (during call resolution or in the function |  17231   // signature compatibility check (during call resolution or in the function | 
|  18261   // prolog). |  17232   // prolog). | 
|  18262 } |  17233 } | 
|  18263  |  17234  | 
|  18264  |  | 
|  18265 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |  17235 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 
|  18266                                const AbstractType& upper_bound, |  17236                                const AbstractType& upper_bound, | 
|  18267                                Error* bound_error, |  17237                                Error* bound_error, | 
|  18268                                TrailPtr bound_trail, |  17238                                TrailPtr bound_trail, | 
|  18269                                Heap::Space space) const { |  17239                                Heap::Space space) const { | 
|  18270   ASSERT((bound_error != NULL) && bound_error->IsNull()); |  17240   ASSERT((bound_error != NULL) && bound_error->IsNull()); | 
|  18271   ASSERT(bounded_type.IsFinalized()); |  17241   ASSERT(bounded_type.IsFinalized()); | 
|  18272   ASSERT(upper_bound.IsFinalized()); |  17242   ASSERT(upper_bound.IsFinalized()); | 
|  18273   ASSERT(!bounded_type.IsMalformed()); |  17243   ASSERT(!bounded_type.IsMalformed()); | 
|  18274   if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { |  17244   if (bounded_type.IsTypeRef() || upper_bound.IsTypeRef()) { | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  18317           type_param_name.ToCString(), class_name.ToCString(), |  17287           type_param_name.ToCString(), class_name.ToCString(), | 
|  18318           declared_bound_name.ToCString(), bounded_type_name.ToCString(), |  17288           declared_bound_name.ToCString(), bounded_type_name.ToCString(), | 
|  18319           upper_bound_name.ToCString(), |  17289           upper_bound_name.ToCString(), | 
|  18320           String::Handle(bounded_type.EnumerateURIs()).ToCString(), |  17290           String::Handle(bounded_type.EnumerateURIs()).ToCString(), | 
|  18321           String::Handle(upper_bound.EnumerateURIs()).ToCString()); |  17291           String::Handle(upper_bound.EnumerateURIs()).ToCString()); | 
|  18322     } |  17292     } | 
|  18323   } |  17293   } | 
|  18324   return false; |  17294   return false; | 
|  18325 } |  17295 } | 
|  18326  |  17296  | 
|  18327  |  | 
|  18328 RawAbstractType* TypeParameter::CloneUnfinalized() const { |  17297 RawAbstractType* TypeParameter::CloneUnfinalized() const { | 
|  18329   if (IsFinalized()) { |  17298   if (IsFinalized()) { | 
|  18330     return raw(); |  17299     return raw(); | 
|  18331   } |  17300   } | 
|  18332   // No need to clone bound, as it is not part of the finalization state. |  17301   // No need to clone bound, as it is not part of the finalization state. | 
|  18333   return TypeParameter::New(Class::Handle(parameterized_class()), |  17302   return TypeParameter::New(Class::Handle(parameterized_class()), | 
|  18334                             Function::Handle(parameterized_function()), index(), |  17303                             Function::Handle(parameterized_function()), index(), | 
|  18335                             String::Handle(name()), |  17304                             String::Handle(name()), | 
|  18336                             AbstractType::Handle(bound()), token_pos()); |  17305                             AbstractType::Handle(bound()), token_pos()); | 
|  18337 } |  17306 } | 
|  18338  |  17307  | 
|  18339  |  | 
|  18340 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, |  17308 RawAbstractType* TypeParameter::CloneUninstantiated(const Class& new_owner, | 
|  18341                                                     TrailPtr trail) const { |  17309                                                     TrailPtr trail) const { | 
|  18342   ASSERT(IsFinalized()); |  17310   ASSERT(IsFinalized()); | 
|  18343   Thread* thread = Thread::Current(); |  17311   Thread* thread = Thread::Current(); | 
|  18344   Zone* zone = thread->zone(); |  17312   Zone* zone = thread->zone(); | 
|  18345   TypeParameter& clone = TypeParameter::Handle(zone); |  17313   TypeParameter& clone = TypeParameter::Handle(zone); | 
|  18346   clone ^= OnlyBuddyInTrail(trail); |  17314   clone ^= OnlyBuddyInTrail(trail); | 
|  18347   if (!clone.IsNull()) { |  17315   if (!clone.IsNull()) { | 
|  18348     return clone.raw(); |  17316     return clone.raw(); | 
|  18349   } |  17317   } | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  18362   clone = TypeParameter::New(cls, fun, new_index, String::Handle(zone, name()), |  17330   clone = TypeParameter::New(cls, fun, new_index, String::Handle(zone, name()), | 
|  18363                              upper_bound,  // Not cloned yet. |  17331                              upper_bound,  // Not cloned yet. | 
|  18364                              token_pos()); |  17332                              token_pos()); | 
|  18365   clone.SetIsFinalized(); |  17333   clone.SetIsFinalized(); | 
|  18366   AddOnlyBuddyToTrail(&trail, clone); |  17334   AddOnlyBuddyToTrail(&trail, clone); | 
|  18367   upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |  17335   upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 
|  18368   clone.set_bound(upper_bound); |  17336   clone.set_bound(upper_bound); | 
|  18369   return clone.raw(); |  17337   return clone.raw(); | 
|  18370 } |  17338 } | 
|  18371  |  17339  | 
|  18372  |  | 
|  18373 RawString* TypeParameter::EnumerateURIs() const { |  17340 RawString* TypeParameter::EnumerateURIs() const { | 
|  18374   Thread* thread = Thread::Current(); |  17341   Thread* thread = Thread::Current(); | 
|  18375   Zone* zone = thread->zone(); |  17342   Zone* zone = thread->zone(); | 
|  18376   GrowableHandlePtrArray<const String> pieces(zone, 4); |  17343   GrowableHandlePtrArray<const String> pieces(zone, 4); | 
|  18377   pieces.Add(Symbols::TwoSpaces()); |  17344   pieces.Add(Symbols::TwoSpaces()); | 
|  18378   pieces.Add(String::Handle(zone, name())); |  17345   pieces.Add(String::Handle(zone, name())); | 
|  18379   Class& cls = Class::Handle(zone, parameterized_class()); |  17346   Class& cls = Class::Handle(zone, parameterized_class()); | 
|  18380   if (cls.IsNull()) { |  17347   if (cls.IsNull()) { | 
|  18381     const Function& fun = Function::Handle(zone, parameterized_function()); |  17348     const Function& fun = Function::Handle(zone, parameterized_function()); | 
|  18382     pieces.Add(Symbols::SpaceOfSpace()); |  17349     pieces.Add(Symbols::SpaceOfSpace()); | 
|  18383     pieces.Add(String::Handle(zone, fun.UserVisibleName())); |  17350     pieces.Add(String::Handle(zone, fun.UserVisibleName())); | 
|  18384     cls = fun.Owner();  // May be null. |  17351     cls = fun.Owner();  // May be null. | 
|  18385     // TODO(regis): Should we keep the function owner for better error messages? |  17352     // TODO(regis): Should we keep the function owner for better error messages? | 
|  18386   } |  17353   } | 
|  18387   if (!cls.IsNull()) { |  17354   if (!cls.IsNull()) { | 
|  18388     pieces.Add(Symbols::SpaceOfSpace()); |  17355     pieces.Add(Symbols::SpaceOfSpace()); | 
|  18389     pieces.Add(String::Handle(zone, cls.UserVisibleName())); |  17356     pieces.Add(String::Handle(zone, cls.UserVisibleName())); | 
|  18390     pieces.Add(Symbols::SpaceIsFromSpace()); |  17357     pieces.Add(Symbols::SpaceIsFromSpace()); | 
|  18391     const Library& library = Library::Handle(zone, cls.library()); |  17358     const Library& library = Library::Handle(zone, cls.library()); | 
|  18392     pieces.Add(String::Handle(zone, library.url())); |  17359     pieces.Add(String::Handle(zone, library.url())); | 
|  18393   } |  17360   } | 
|  18394   pieces.Add(Symbols::NewLine()); |  17361   pieces.Add(Symbols::NewLine()); | 
|  18395   return Symbols::FromConcatAll(thread, pieces); |  17362   return Symbols::FromConcatAll(thread, pieces); | 
|  18396 } |  17363 } | 
|  18397  |  17364  | 
|  18398  |  | 
|  18399 intptr_t TypeParameter::ComputeHash() const { |  17365 intptr_t TypeParameter::ComputeHash() const { | 
|  18400   ASSERT(IsFinalized()); |  17366   ASSERT(IsFinalized()); | 
|  18401   uint32_t result; |  17367   uint32_t result; | 
|  18402   if (IsClassTypeParameter()) { |  17368   if (IsClassTypeParameter()) { | 
|  18403     result = parameterized_class_id(); |  17369     result = parameterized_class_id(); | 
|  18404   } else { |  17370   } else { | 
|  18405     result = Function::Handle(parameterized_function()).Hash(); |  17371     result = Function::Handle(parameterized_function()).Hash(); | 
|  18406   } |  17372   } | 
|  18407   // No need to include the hash of the bound, since the type parameter is fully |  17373   // No need to include the hash of the bound, since the type parameter is fully | 
|  18408   // identified by its class and index. |  17374   // identified by its class and index. | 
|  18409   result = CombineHashes(result, index()); |  17375   result = CombineHashes(result, index()); | 
|  18410   result = FinalizeHash(result, kHashBits); |  17376   result = FinalizeHash(result, kHashBits); | 
|  18411   SetHash(result); |  17377   SetHash(result); | 
|  18412   return result; |  17378   return result; | 
|  18413 } |  17379 } | 
|  18414  |  17380  | 
|  18415  |  | 
|  18416 RawTypeParameter* TypeParameter::New() { |  17381 RawTypeParameter* TypeParameter::New() { | 
|  18417   RawObject* raw = Object::Allocate(TypeParameter::kClassId, |  17382   RawObject* raw = Object::Allocate(TypeParameter::kClassId, | 
|  18418                                     TypeParameter::InstanceSize(), Heap::kOld); |  17383                                     TypeParameter::InstanceSize(), Heap::kOld); | 
|  18419   return reinterpret_cast<RawTypeParameter*>(raw); |  17384   return reinterpret_cast<RawTypeParameter*>(raw); | 
|  18420 } |  17385 } | 
|  18421  |  17386  | 
|  18422  |  | 
|  18423 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, |  17387 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, | 
|  18424                                      const Function& parameterized_function, |  17388                                      const Function& parameterized_function, | 
|  18425                                      intptr_t index, |  17389                                      intptr_t index, | 
|  18426                                      const String& name, |  17390                                      const String& name, | 
|  18427                                      const AbstractType& bound, |  17391                                      const AbstractType& bound, | 
|  18428                                      TokenPosition token_pos) { |  17392                                      TokenPosition token_pos) { | 
|  18429   ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); |  17393   ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); | 
|  18430   const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |  17394   const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); | 
|  18431   result.set_parameterized_class(parameterized_class); |  17395   result.set_parameterized_class(parameterized_class); | 
|  18432   result.set_parameterized_function(parameterized_function); |  17396   result.set_parameterized_function(parameterized_function); | 
|  18433   result.set_index(index); |  17397   result.set_index(index); | 
|  18434   result.set_name(name); |  17398   result.set_name(name); | 
|  18435   result.set_bound(bound); |  17399   result.set_bound(bound); | 
|  18436   result.SetHash(0); |  17400   result.SetHash(0); | 
|  18437   result.set_token_pos(token_pos); |  17401   result.set_token_pos(token_pos); | 
|  18438   result.StoreNonPointer(&result.raw_ptr()->type_state_, |  17402   result.StoreNonPointer(&result.raw_ptr()->type_state_, | 
|  18439                          RawTypeParameter::kAllocated); |  17403                          RawTypeParameter::kAllocated); | 
|  18440   return result.raw(); |  17404   return result.raw(); | 
|  18441 } |  17405 } | 
|  18442  |  17406  | 
|  18443  |  | 
|  18444 void TypeParameter::set_token_pos(TokenPosition token_pos) const { |  17407 void TypeParameter::set_token_pos(TokenPosition token_pos) const { | 
|  18445   ASSERT(!token_pos.IsClassifying()); |  17408   ASSERT(!token_pos.IsClassifying()); | 
|  18446   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); |  17409   StoreNonPointer(&raw_ptr()->token_pos_, token_pos); | 
|  18447 } |  17410 } | 
|  18448  |  17411  | 
|  18449  |  | 
|  18450 void TypeParameter::set_type_state(int8_t state) const { |  17412 void TypeParameter::set_type_state(int8_t state) const { | 
|  18451   ASSERT((state == RawTypeParameter::kAllocated) || |  17413   ASSERT((state == RawTypeParameter::kAllocated) || | 
|  18452          (state == RawTypeParameter::kBeingFinalized) || |  17414          (state == RawTypeParameter::kBeingFinalized) || | 
|  18453          (state == RawTypeParameter::kFinalizedUninstantiated)); |  17415          (state == RawTypeParameter::kFinalizedUninstantiated)); | 
|  18454   StoreNonPointer(&raw_ptr()->type_state_, state); |  17416   StoreNonPointer(&raw_ptr()->type_state_, state); | 
|  18455 } |  17417 } | 
|  18456  |  17418  | 
|  18457  |  | 
|  18458 const char* TypeParameter::ToCString() const { |  17419 const char* TypeParameter::ToCString() const { | 
|  18459   const char* name_cstr = String::Handle(Name()).ToCString(); |  17420   const char* name_cstr = String::Handle(Name()).ToCString(); | 
|  18460   const AbstractType& upper_bound = AbstractType::Handle(bound()); |  17421   const AbstractType& upper_bound = AbstractType::Handle(bound()); | 
|  18461   const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); |  17422   const char* bound_cstr = String::Handle(upper_bound.Name()).ToCString(); | 
|  18462   if (IsFunctionTypeParameter()) { |  17423   if (IsFunctionTypeParameter()) { | 
|  18463     const char* format = |  17424     const char* format = | 
|  18464         "TypeParameter: name %s; index: %d; function: %s; bound: %s"; |  17425         "TypeParameter: name %s; index: %d; function: %s; bound: %s"; | 
|  18465     const Function& function = Function::Handle(parameterized_function()); |  17426     const Function& function = Function::Handle(parameterized_function()); | 
|  18466     const char* fun_cstr = String::Handle(function.name()).ToCString(); |  17427     const char* fun_cstr = String::Handle(function.name()).ToCString(); | 
|  18467     intptr_t len = |  17428     intptr_t len = | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  18478         cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |  17439         cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); | 
|  18479     intptr_t len = |  17440     intptr_t len = | 
|  18480         OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + |  17441         OS::SNPrint(NULL, 0, format, name_cstr, index(), cls_cstr, bound_cstr) + | 
|  18481         1; |  17442         1; | 
|  18482     char* chars = Thread::Current()->zone()->Alloc<char>(len); |  17443     char* chars = Thread::Current()->zone()->Alloc<char>(len); | 
|  18483     OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr, bound_cstr); |  17444     OS::SNPrint(chars, len, format, name_cstr, index(), cls_cstr, bound_cstr); | 
|  18484     return chars; |  17445     return chars; | 
|  18485   } |  17446   } | 
|  18486 } |  17447 } | 
|  18487  |  17448  | 
|  18488  |  | 
|  18489 bool BoundedType::IsMalformed() const { |  17449 bool BoundedType::IsMalformed() const { | 
|  18490   return AbstractType::Handle(type()).IsMalformed(); |  17450   return AbstractType::Handle(type()).IsMalformed(); | 
|  18491 } |  17451 } | 
|  18492  |  17452  | 
|  18493  |  | 
|  18494 bool BoundedType::IsMalbounded() const { |  17453 bool BoundedType::IsMalbounded() const { | 
|  18495   return AbstractType::Handle(type()).IsMalbounded(); |  17454   return AbstractType::Handle(type()).IsMalbounded(); | 
|  18496 } |  17455 } | 
|  18497  |  17456  | 
|  18498  |  | 
|  18499 bool BoundedType::IsMalformedOrMalbounded() const { |  17457 bool BoundedType::IsMalformedOrMalbounded() const { | 
|  18500   return AbstractType::Handle(type()).IsMalformedOrMalbounded(); |  17458   return AbstractType::Handle(type()).IsMalformedOrMalbounded(); | 
|  18501 } |  17459 } | 
|  18502  |  17460  | 
|  18503  |  | 
|  18504 RawLanguageError* BoundedType::error() const { |  17461 RawLanguageError* BoundedType::error() const { | 
|  18505   return AbstractType::Handle(type()).error(); |  17462   return AbstractType::Handle(type()).error(); | 
|  18506 } |  17463 } | 
|  18507  |  17464  | 
|  18508  |  | 
|  18509 bool BoundedType::IsEquivalent(const Instance& other, TrailPtr trail) const { |  17465 bool BoundedType::IsEquivalent(const Instance& other, TrailPtr trail) const { | 
|  18510   // BoundedType are not canonicalized, because their bound may get finalized |  17466   // BoundedType are not canonicalized, because their bound may get finalized | 
|  18511   // after the BoundedType is created and initialized. |  17467   // after the BoundedType is created and initialized. | 
|  18512   if (raw() == other.raw()) { |  17468   if (raw() == other.raw()) { | 
|  18513     return true; |  17469     return true; | 
|  18514   } |  17470   } | 
|  18515   if (other.IsTypeRef()) { |  17471   if (other.IsTypeRef()) { | 
|  18516     // Unfold right hand type. Divergence is controlled by left hand type. |  17472     // Unfold right hand type. Divergence is controlled by left hand type. | 
|  18517     const AbstractType& other_ref_type = |  17473     const AbstractType& other_ref_type = | 
|  18518         AbstractType::Handle(TypeRef::Cast(other).type()); |  17474         AbstractType::Handle(TypeRef::Cast(other).type()); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  18530   const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); |  17486   const AbstractType& other_type = AbstractType::Handle(other_bounded.type()); | 
|  18531   if (!this_type.IsEquivalent(other_type, trail)) { |  17487   if (!this_type.IsEquivalent(other_type, trail)) { | 
|  18532     return false; |  17488     return false; | 
|  18533   } |  17489   } | 
|  18534   const AbstractType& this_bound = AbstractType::Handle(bound()); |  17490   const AbstractType& this_bound = AbstractType::Handle(bound()); | 
|  18535   const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); |  17491   const AbstractType& other_bound = AbstractType::Handle(other_bounded.bound()); | 
|  18536   return this_bound.IsFinalized() && other_bound.IsFinalized() && |  17492   return this_bound.IsFinalized() && other_bound.IsFinalized() && | 
|  18537          this_bound.Equals(other_bound);  // Different graph, do not pass trail. |  17493          this_bound.Equals(other_bound);  // Different graph, do not pass trail. | 
|  18538 } |  17494 } | 
|  18539  |  17495  | 
|  18540  |  | 
|  18541 bool BoundedType::IsRecursive() const { |  17496 bool BoundedType::IsRecursive() const { | 
|  18542   return AbstractType::Handle(type()).IsRecursive(); |  17497   return AbstractType::Handle(type()).IsRecursive(); | 
|  18543 } |  17498 } | 
|  18544  |  17499  | 
|  18545  |  | 
|  18546 void BoundedType::set_type(const AbstractType& value) const { |  17500 void BoundedType::set_type(const AbstractType& value) const { | 
|  18547   ASSERT(value.IsFinalized() || value.IsBeingFinalized() || |  17501   ASSERT(value.IsFinalized() || value.IsBeingFinalized() || | 
|  18548          value.IsTypeParameter()); |  17502          value.IsTypeParameter()); | 
|  18549   ASSERT(!value.IsMalformed()); |  17503   ASSERT(!value.IsMalformed()); | 
|  18550   StorePointer(&raw_ptr()->type_, value.raw()); |  17504   StorePointer(&raw_ptr()->type_, value.raw()); | 
|  18551 } |  17505 } | 
|  18552  |  17506  | 
|  18553  |  | 
|  18554 void BoundedType::set_bound(const AbstractType& value) const { |  17507 void BoundedType::set_bound(const AbstractType& value) const { | 
|  18555   // The bound may still be unfinalized because of legal cycles. |  17508   // The bound may still be unfinalized because of legal cycles. | 
|  18556   // It must be finalized before it is checked at run time, though. |  17509   // It must be finalized before it is checked at run time, though. | 
|  18557   ASSERT(value.IsFinalized() || value.IsBeingFinalized()); |  17510   ASSERT(value.IsFinalized() || value.IsBeingFinalized()); | 
|  18558   StorePointer(&raw_ptr()->bound_, value.raw()); |  17511   StorePointer(&raw_ptr()->bound_, value.raw()); | 
|  18559 } |  17512 } | 
|  18560  |  17513  | 
|  18561  |  | 
|  18562 void BoundedType::set_type_parameter(const TypeParameter& value) const { |  17514 void BoundedType::set_type_parameter(const TypeParameter& value) const { | 
|  18563   // A null type parameter is set when marking a type malformed because of a |  17515   // A null type parameter is set when marking a type malformed because of a | 
|  18564   // bound error at compile time. |  17516   // bound error at compile time. | 
|  18565   ASSERT(value.IsNull() || value.IsFinalized()); |  17517   ASSERT(value.IsNull() || value.IsFinalized()); | 
|  18566   StorePointer(&raw_ptr()->type_parameter_, value.raw()); |  17518   StorePointer(&raw_ptr()->type_parameter_, value.raw()); | 
|  18567 } |  17519 } | 
|  18568  |  17520  | 
|  18569  |  | 
|  18570 RawAbstractType* BoundedType::InstantiateFrom( |  17521 RawAbstractType* BoundedType::InstantiateFrom( | 
|  18571     const TypeArguments& instantiator_type_arguments, |  17522     const TypeArguments& instantiator_type_arguments, | 
|  18572     const TypeArguments& function_type_arguments, |  17523     const TypeArguments& function_type_arguments, | 
|  18573     Error* bound_error, |  17524     Error* bound_error, | 
|  18574     TrailPtr instantiation_trail, |  17525     TrailPtr instantiation_trail, | 
|  18575     TrailPtr bound_trail, |  17526     TrailPtr bound_trail, | 
|  18576     Heap::Space space) const { |  17527     Heap::Space space) const { | 
|  18577   ASSERT(IsFinalized()); |  17528   ASSERT(IsFinalized()); | 
|  18578   AbstractType& bounded_type = AbstractType::Handle(type()); |  17529   AbstractType& bounded_type = AbstractType::Handle(type()); | 
|  18579   ASSERT(bounded_type.IsFinalized()); |  17530   ASSERT(bounded_type.IsFinalized()); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  18634         // or partially instantiated bounded_type and upper_bound, but keeping |  17585         // or partially instantiated bounded_type and upper_bound, but keeping | 
|  18635         // type_param. |  17586         // type_param. | 
|  18636         instantiated_bounded_type = BoundedType::New( |  17587         instantiated_bounded_type = BoundedType::New( | 
|  18637             instantiated_bounded_type, instantiated_upper_bound, type_param); |  17588             instantiated_bounded_type, instantiated_upper_bound, type_param); | 
|  18638       } |  17589       } | 
|  18639     } |  17590     } | 
|  18640   } |  17591   } | 
|  18641   return instantiated_bounded_type.raw(); |  17592   return instantiated_bounded_type.raw(); | 
|  18642 } |  17593 } | 
|  18643  |  17594  | 
|  18644  |  | 
|  18645 RawAbstractType* BoundedType::CloneUnfinalized() const { |  17595 RawAbstractType* BoundedType::CloneUnfinalized() const { | 
|  18646   if (IsFinalized()) { |  17596   if (IsFinalized()) { | 
|  18647     return raw(); |  17597     return raw(); | 
|  18648   } |  17598   } | 
|  18649   const AbstractType& bounded_type = AbstractType::Handle(type()); |  17599   const AbstractType& bounded_type = AbstractType::Handle(type()); | 
|  18650   const AbstractType& bounded_type_clone = |  17600   const AbstractType& bounded_type_clone = | 
|  18651       AbstractType::Handle(bounded_type.CloneUnfinalized()); |  17601       AbstractType::Handle(bounded_type.CloneUnfinalized()); | 
|  18652   if (bounded_type_clone.raw() == bounded_type.raw()) { |  17602   if (bounded_type_clone.raw() == bounded_type.raw()) { | 
|  18653     return raw(); |  17603     return raw(); | 
|  18654   } |  17604   } | 
|  18655   // No need to clone bound or type parameter, as they are not part of the |  17605   // No need to clone bound or type parameter, as they are not part of the | 
|  18656   // finalization state of this bounded type. |  17606   // finalization state of this bounded type. | 
|  18657   return BoundedType::New(bounded_type, AbstractType::Handle(bound()), |  17607   return BoundedType::New(bounded_type, AbstractType::Handle(bound()), | 
|  18658                           TypeParameter::Handle(type_parameter())); |  17608                           TypeParameter::Handle(type_parameter())); | 
|  18659 } |  17609 } | 
|  18660  |  17610  | 
|  18661  |  | 
|  18662 RawAbstractType* BoundedType::CloneUninstantiated(const Class& new_owner, |  17611 RawAbstractType* BoundedType::CloneUninstantiated(const Class& new_owner, | 
|  18663                                                   TrailPtr trail) const { |  17612                                                   TrailPtr trail) const { | 
|  18664   if (IsInstantiated()) { |  17613   if (IsInstantiated()) { | 
|  18665     return raw(); |  17614     return raw(); | 
|  18666   } |  17615   } | 
|  18667   AbstractType& bounded_type = AbstractType::Handle(type()); |  17616   AbstractType& bounded_type = AbstractType::Handle(type()); | 
|  18668   bounded_type = bounded_type.CloneUninstantiated(new_owner, trail); |  17617   bounded_type = bounded_type.CloneUninstantiated(new_owner, trail); | 
|  18669   AbstractType& upper_bound = AbstractType::Handle(bound()); |  17618   AbstractType& upper_bound = AbstractType::Handle(bound()); | 
|  18670   upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); |  17619   upper_bound = upper_bound.CloneUninstantiated(new_owner, trail); | 
|  18671   TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |  17620   TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 
|  18672   type_param ^= type_param.CloneUninstantiated(new_owner, trail); |  17621   type_param ^= type_param.CloneUninstantiated(new_owner, trail); | 
|  18673   return BoundedType::New(bounded_type, upper_bound, type_param); |  17622   return BoundedType::New(bounded_type, upper_bound, type_param); | 
|  18674 } |  17623 } | 
|  18675  |  17624  | 
|  18676  |  | 
|  18677 RawString* BoundedType::EnumerateURIs() const { |  17625 RawString* BoundedType::EnumerateURIs() const { | 
|  18678   // The bound does not appear in the user visible name. |  17626   // The bound does not appear in the user visible name. | 
|  18679   return AbstractType::Handle(type()).EnumerateURIs(); |  17627   return AbstractType::Handle(type()).EnumerateURIs(); | 
|  18680 } |  17628 } | 
|  18681  |  17629  | 
|  18682  |  | 
|  18683 intptr_t BoundedType::ComputeHash() const { |  17630 intptr_t BoundedType::ComputeHash() const { | 
|  18684   uint32_t result = AbstractType::Handle(type()).Hash(); |  17631   uint32_t result = AbstractType::Handle(type()).Hash(); | 
|  18685   // No need to include the hash of the bound, since the bound is defined by the |  17632   // No need to include the hash of the bound, since the bound is defined by the | 
|  18686   // type parameter (modulo instantiation state). |  17633   // type parameter (modulo instantiation state). | 
|  18687   result = |  17634   result = | 
|  18688       CombineHashes(result, TypeParameter::Handle(type_parameter()).Hash()); |  17635       CombineHashes(result, TypeParameter::Handle(type_parameter()).Hash()); | 
|  18689   result = FinalizeHash(result, kHashBits); |  17636   result = FinalizeHash(result, kHashBits); | 
|  18690   SetHash(result); |  17637   SetHash(result); | 
|  18691   return result; |  17638   return result; | 
|  18692 } |  17639 } | 
|  18693  |  17640  | 
|  18694  |  | 
|  18695 RawBoundedType* BoundedType::New() { |  17641 RawBoundedType* BoundedType::New() { | 
|  18696   RawObject* raw = Object::Allocate(BoundedType::kClassId, |  17642   RawObject* raw = Object::Allocate(BoundedType::kClassId, | 
|  18697                                     BoundedType::InstanceSize(), Heap::kOld); |  17643                                     BoundedType::InstanceSize(), Heap::kOld); | 
|  18698   return reinterpret_cast<RawBoundedType*>(raw); |  17644   return reinterpret_cast<RawBoundedType*>(raw); | 
|  18699 } |  17645 } | 
|  18700  |  17646  | 
|  18701  |  | 
|  18702 RawBoundedType* BoundedType::New(const AbstractType& type, |  17647 RawBoundedType* BoundedType::New(const AbstractType& type, | 
|  18703                                  const AbstractType& bound, |  17648                                  const AbstractType& bound, | 
|  18704                                  const TypeParameter& type_parameter) { |  17649                                  const TypeParameter& type_parameter) { | 
|  18705   const BoundedType& result = BoundedType::Handle(BoundedType::New()); |  17650   const BoundedType& result = BoundedType::Handle(BoundedType::New()); | 
|  18706   result.set_type(type); |  17651   result.set_type(type); | 
|  18707   result.set_bound(bound); |  17652   result.set_bound(bound); | 
|  18708   result.SetHash(0); |  17653   result.SetHash(0); | 
|  18709   result.set_type_parameter(type_parameter); |  17654   result.set_type_parameter(type_parameter); | 
|  18710   return result.raw(); |  17655   return result.raw(); | 
|  18711 } |  17656 } | 
|  18712  |  17657  | 
|  18713  |  | 
|  18714 const char* BoundedType::ToCString() const { |  17658 const char* BoundedType::ToCString() const { | 
|  18715   const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; |  17659   const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; | 
|  18716   const char* type_cstr = |  17660   const char* type_cstr = | 
|  18717       String::Handle(AbstractType::Handle(type()).Name()).ToCString(); |  17661       String::Handle(AbstractType::Handle(type()).Name()).ToCString(); | 
|  18718   const char* bound_cstr = |  17662   const char* bound_cstr = | 
|  18719       String::Handle(AbstractType::Handle(bound()).Name()).ToCString(); |  17663       String::Handle(AbstractType::Handle(bound()).Name()).ToCString(); | 
|  18720   const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |  17664   const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 
|  18721   const char* type_param_cstr = String::Handle(type_param.name()).ToCString(); |  17665   const char* type_param_cstr = String::Handle(type_param.name()).ToCString(); | 
|  18722   const Class& cls = Class::Handle(type_param.parameterized_class()); |  17666   const Class& cls = Class::Handle(type_param.parameterized_class()); | 
|  18723   const char* cls_cstr = String::Handle(cls.Name()).ToCString(); |  17667   const char* cls_cstr = String::Handle(cls.Name()).ToCString(); | 
|  18724   intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, bound_cstr, |  17668   intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, bound_cstr, | 
|  18725                              type_param_cstr, cls_cstr) + |  17669                              type_param_cstr, cls_cstr) + | 
|  18726                  1; |  17670                  1; | 
|  18727   char* chars = Thread::Current()->zone()->Alloc<char>(len); |  17671   char* chars = Thread::Current()->zone()->Alloc<char>(len); | 
|  18728   OS::SNPrint(chars, len, format, type_cstr, bound_cstr, type_param_cstr, |  17672   OS::SNPrint(chars, len, format, type_cstr, bound_cstr, type_param_cstr, | 
|  18729               cls_cstr); |  17673               cls_cstr); | 
|  18730   return chars; |  17674   return chars; | 
|  18731 } |  17675 } | 
|  18732  |  17676  | 
|  18733  |  | 
|  18734 TokenPosition MixinAppType::token_pos() const { |  17677 TokenPosition MixinAppType::token_pos() const { | 
|  18735   return AbstractType::Handle(MixinTypeAt(0)).token_pos(); |  17678   return AbstractType::Handle(MixinTypeAt(0)).token_pos(); | 
|  18736 } |  17679 } | 
|  18737  |  17680  | 
|  18738  |  | 
|  18739 intptr_t MixinAppType::Depth() const { |  17681 intptr_t MixinAppType::Depth() const { | 
|  18740   return Array::Handle(mixin_types()).Length(); |  17682   return Array::Handle(mixin_types()).Length(); | 
|  18741 } |  17683 } | 
|  18742  |  17684  | 
|  18743  |  | 
|  18744 RawString* MixinAppType::Name() const { |  17685 RawString* MixinAppType::Name() const { | 
|  18745   return String::New("MixinAppType"); |  17686   return String::New("MixinAppType"); | 
|  18746 } |  17687 } | 
|  18747  |  17688  | 
|  18748  |  | 
|  18749 const char* MixinAppType::ToCString() const { |  17689 const char* MixinAppType::ToCString() const { | 
|  18750   const char* format = "MixinAppType: super type: %s; first mixin type: %s"; |  17690   const char* format = "MixinAppType: super type: %s; first mixin type: %s"; | 
|  18751   const char* super_type_cstr = |  17691   const char* super_type_cstr = | 
|  18752       String::Handle(AbstractType::Handle(super_type()).Name()).ToCString(); |  17692       String::Handle(AbstractType::Handle(super_type()).Name()).ToCString(); | 
|  18753   const char* first_mixin_type_cstr = |  17693   const char* first_mixin_type_cstr = | 
|  18754       String::Handle(AbstractType::Handle(MixinTypeAt(0)).Name()).ToCString(); |  17694       String::Handle(AbstractType::Handle(MixinTypeAt(0)).Name()).ToCString(); | 
|  18755   intptr_t len = |  17695   intptr_t len = | 
|  18756       OS::SNPrint(NULL, 0, format, super_type_cstr, first_mixin_type_cstr) + 1; |  17696       OS::SNPrint(NULL, 0, format, super_type_cstr, first_mixin_type_cstr) + 1; | 
|  18757   char* chars = Thread::Current()->zone()->Alloc<char>(len); |  17697   char* chars = Thread::Current()->zone()->Alloc<char>(len); | 
|  18758   OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_type_cstr); |  17698   OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_type_cstr); | 
|  18759   return chars; |  17699   return chars; | 
|  18760 } |  17700 } | 
|  18761  |  17701  | 
|  18762  |  | 
|  18763 RawAbstractType* MixinAppType::MixinTypeAt(intptr_t depth) const { |  17702 RawAbstractType* MixinAppType::MixinTypeAt(intptr_t depth) const { | 
|  18764   return AbstractType::RawCast(Array::Handle(mixin_types()).At(depth)); |  17703   return AbstractType::RawCast(Array::Handle(mixin_types()).At(depth)); | 
|  18765 } |  17704 } | 
|  18766  |  17705  | 
|  18767  |  | 
|  18768 void MixinAppType::set_super_type(const AbstractType& value) const { |  17706 void MixinAppType::set_super_type(const AbstractType& value) const { | 
|  18769   StorePointer(&raw_ptr()->super_type_, value.raw()); |  17707   StorePointer(&raw_ptr()->super_type_, value.raw()); | 
|  18770 } |  17708 } | 
|  18771  |  17709  | 
|  18772  |  | 
|  18773 void MixinAppType::set_mixin_types(const Array& value) const { |  17710 void MixinAppType::set_mixin_types(const Array& value) const { | 
|  18774   StorePointer(&raw_ptr()->mixin_types_, value.raw()); |  17711   StorePointer(&raw_ptr()->mixin_types_, value.raw()); | 
|  18775 } |  17712 } | 
|  18776  |  17713  | 
|  18777  |  | 
|  18778 RawMixinAppType* MixinAppType::New() { |  17714 RawMixinAppType* MixinAppType::New() { | 
|  18779   // MixinAppType objects do not survive finalization, so allocate |  17715   // MixinAppType objects do not survive finalization, so allocate | 
|  18780   // on new heap. |  17716   // on new heap. | 
|  18781   RawObject* raw = Object::Allocate(MixinAppType::kClassId, |  17717   RawObject* raw = Object::Allocate(MixinAppType::kClassId, | 
|  18782                                     MixinAppType::InstanceSize(), Heap::kOld); |  17718                                     MixinAppType::InstanceSize(), Heap::kOld); | 
|  18783   return reinterpret_cast<RawMixinAppType*>(raw); |  17719   return reinterpret_cast<RawMixinAppType*>(raw); | 
|  18784 } |  17720 } | 
|  18785  |  17721  | 
|  18786  |  | 
|  18787 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, |  17722 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, | 
|  18788                                    const Array& mixin_types) { |  17723                                    const Array& mixin_types) { | 
|  18789   const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); |  17724   const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); | 
|  18790   result.set_super_type(super_type); |  17725   result.set_super_type(super_type); | 
|  18791   result.set_mixin_types(mixin_types); |  17726   result.set_mixin_types(mixin_types); | 
|  18792   return result.raw(); |  17727   return result.raw(); | 
|  18793 } |  17728 } | 
|  18794  |  17729  | 
|  18795  |  | 
|  18796 RawInstance* Number::CheckAndCanonicalize(Thread* thread, |  17730 RawInstance* Number::CheckAndCanonicalize(Thread* thread, | 
|  18797                                           const char** error_str) const { |  17731                                           const char** error_str) const { | 
|  18798   intptr_t cid = GetClassId(); |  17732   intptr_t cid = GetClassId(); | 
|  18799   switch (cid) { |  17733   switch (cid) { | 
|  18800     case kSmiCid: |  17734     case kSmiCid: | 
|  18801       return reinterpret_cast<RawSmi*>(raw_value()); |  17735       return reinterpret_cast<RawSmi*>(raw_value()); | 
|  18802     case kMintCid: |  17736     case kMintCid: | 
|  18803       return Mint::NewCanonical(Mint::Cast(*this).value()); |  17737       return Mint::NewCanonical(Mint::Cast(*this).value()); | 
|  18804     case kDoubleCid: |  17738     case kDoubleCid: | 
|  18805       return Double::NewCanonical(Double::Cast(*this).value()); |  17739       return Double::NewCanonical(Double::Cast(*this).value()); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  18840         cls.InsertCanonicalNumber(zone, index, result); |  17774         cls.InsertCanonicalNumber(zone, index, result); | 
|  18841         return result.raw(); |  17775         return result.raw(); | 
|  18842       } |  17776       } | 
|  18843     } |  17777     } | 
|  18844     default: |  17778     default: | 
|  18845       UNREACHABLE(); |  17779       UNREACHABLE(); | 
|  18846   } |  17780   } | 
|  18847   return Instance::null(); |  17781   return Instance::null(); | 
|  18848 } |  17782 } | 
|  18849  |  17783  | 
|  18850  |  | 
|  18851 #if defined(DEBUG) |  17784 #if defined(DEBUG) | 
|  18852 bool Number::CheckIsCanonical(Thread* thread) const { |  17785 bool Number::CheckIsCanonical(Thread* thread) const { | 
|  18853   intptr_t cid = GetClassId(); |  17786   intptr_t cid = GetClassId(); | 
|  18854   intptr_t idx = 0; |  17787   intptr_t idx = 0; | 
|  18855   Zone* zone = thread->zone(); |  17788   Zone* zone = thread->zone(); | 
|  18856   const Class& cls = Class::Handle(zone, this->clazz()); |  17789   const Class& cls = Class::Handle(zone, this->clazz()); | 
|  18857   switch (cid) { |  17790   switch (cid) { | 
|  18858     case kSmiCid: |  17791     case kSmiCid: | 
|  18859       return true; |  17792       return true; | 
|  18860     case kMintCid: { |  17793     case kMintCid: { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  18872       result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx); |  17805       result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx); | 
|  18873       return (result.raw() == this->raw()); |  17806       return (result.raw() == this->raw()); | 
|  18874     } |  17807     } | 
|  18875     default: |  17808     default: | 
|  18876       UNREACHABLE(); |  17809       UNREACHABLE(); | 
|  18877   } |  17810   } | 
|  18878   return false; |  17811   return false; | 
|  18879 } |  17812 } | 
|  18880 #endif  // DEBUG |  17813 #endif  // DEBUG | 
|  18881  |  17814  | 
|  18882  |  | 
|  18883 const char* Number::ToCString() const { |  17815 const char* Number::ToCString() const { | 
|  18884   // Number is an interface. No instances of Number should exist. |  17816   // Number is an interface. No instances of Number should exist. | 
|  18885   UNREACHABLE(); |  17817   UNREACHABLE(); | 
|  18886   return "Number"; |  17818   return "Number"; | 
|  18887 } |  17819 } | 
|  18888  |  17820  | 
|  18889  |  | 
|  18890 const char* Integer::ToCString() const { |  17821 const char* Integer::ToCString() const { | 
|  18891   // Integer is an interface. No instances of Integer should exist except null. |  17822   // Integer is an interface. No instances of Integer should exist except null. | 
|  18892   ASSERT(IsNull()); |  17823   ASSERT(IsNull()); | 
|  18893   return "NULL Integer"; |  17824   return "NULL Integer"; | 
|  18894 } |  17825 } | 
|  18895  |  17826  | 
|  18896  |  | 
|  18897 RawInteger* Integer::New(const String& str, Heap::Space space) { |  17827 RawInteger* Integer::New(const String& str, Heap::Space space) { | 
|  18898   // We are not supposed to have integers represented as two byte strings. |  17828   // We are not supposed to have integers represented as two byte strings. | 
|  18899   ASSERT(str.IsOneByteString()); |  17829   ASSERT(str.IsOneByteString()); | 
|  18900   int64_t value; |  17830   int64_t value; | 
|  18901   if (!OS::StringToInt64(str.ToCString(), &value)) { |  17831   if (!OS::StringToInt64(str.ToCString(), &value)) { | 
|  18902     const Bigint& big = |  17832     const Bigint& big = | 
|  18903         Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); |  17833         Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); | 
|  18904     ASSERT(!big.FitsIntoSmi()); |  17834     ASSERT(!big.FitsIntoSmi()); | 
|  18905     ASSERT(!big.FitsIntoInt64()); |  17835     ASSERT(!big.FitsIntoInt64()); | 
|  18906     if (!FLAG_limit_ints_to_64_bits) { |  17836     if (!FLAG_limit_ints_to_64_bits) { | 
|  18907       return big.raw(); |  17837       return big.raw(); | 
|  18908     } |  17838     } | 
|  18909     // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |  17839     // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 
|  18910     value = big.AsTruncatedInt64Value(); |  17840     value = big.AsTruncatedInt64Value(); | 
|  18911   } |  17841   } | 
|  18912   return Integer::New(value, space); |  17842   return Integer::New(value, space); | 
|  18913 } |  17843 } | 
|  18914  |  17844  | 
|  18915  |  | 
|  18916 RawInteger* Integer::NewCanonical(const String& str) { |  17845 RawInteger* Integer::NewCanonical(const String& str) { | 
|  18917   // We are not supposed to have integers represented as two byte strings. |  17846   // We are not supposed to have integers represented as two byte strings. | 
|  18918   ASSERT(str.IsOneByteString()); |  17847   ASSERT(str.IsOneByteString()); | 
|  18919   int64_t value; |  17848   int64_t value; | 
|  18920   if (!OS::StringToInt64(str.ToCString(), &value)) { |  17849   if (!OS::StringToInt64(str.ToCString(), &value)) { | 
|  18921     const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); |  17850     const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); | 
|  18922     ASSERT(!big.FitsIntoSmi()); |  17851     ASSERT(!big.FitsIntoSmi()); | 
|  18923     ASSERT(!big.FitsIntoInt64()); |  17852     ASSERT(!big.FitsIntoInt64()); | 
|  18924     if (!FLAG_limit_ints_to_64_bits) { |  17853     if (!FLAG_limit_ints_to_64_bits) { | 
|  18925       return big.raw(); |  17854       return big.raw(); | 
|  18926     } |  17855     } | 
|  18927     // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |  17856     // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 
|  18928     value = big.AsTruncatedInt64Value(); |  17857     value = big.AsTruncatedInt64Value(); | 
|  18929   } |  17858   } | 
|  18930   if (Smi::IsValid(value)) { |  17859   if (Smi::IsValid(value)) { | 
|  18931     return Smi::New(static_cast<intptr_t>(value)); |  17860     return Smi::New(static_cast<intptr_t>(value)); | 
|  18932   } |  17861   } | 
|  18933   return Mint::NewCanonical(value); |  17862   return Mint::NewCanonical(value); | 
|  18934 } |  17863 } | 
|  18935  |  17864  | 
|  18936  |  | 
|  18937 RawInteger* Integer::New(int64_t value, Heap::Space space) { |  17865 RawInteger* Integer::New(int64_t value, Heap::Space space) { | 
|  18938   const bool is_smi = Smi::IsValid(value); |  17866   const bool is_smi = Smi::IsValid(value); | 
|  18939   if (is_smi) { |  17867   if (is_smi) { | 
|  18940     return Smi::New(static_cast<intptr_t>(value)); |  17868     return Smi::New(static_cast<intptr_t>(value)); | 
|  18941   } |  17869   } | 
|  18942   return Mint::New(value, space); |  17870   return Mint::New(value, space); | 
|  18943 } |  17871 } | 
|  18944  |  17872  | 
|  18945  |  | 
|  18946 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |  17873 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { | 
|  18947   if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |  17874   if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 
|  18948     if (FLAG_limit_ints_to_64_bits) { |  17875     if (FLAG_limit_ints_to_64_bits) { | 
|  18949       // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. |  17876       // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 
|  18950       return Integer::New(static_cast<int64_t>(value), space); |  17877       return Integer::New(static_cast<int64_t>(value), space); | 
|  18951     } else { |  17878     } else { | 
|  18952       return Bigint::NewFromUint64(value, space); |  17879       return Bigint::NewFromUint64(value, space); | 
|  18953     } |  17880     } | 
|  18954   } else { |  17881   } else { | 
|  18955     return Integer::New(value, space); |  17882     return Integer::New(value, space); | 
|  18956   } |  17883   } | 
|  18957 } |  17884 } | 
|  18958  |  17885  | 
|  18959  |  | 
|  18960 bool Integer::Equals(const Instance& other) const { |  17886 bool Integer::Equals(const Instance& other) const { | 
|  18961   // Integer is an abstract class. |  17887   // Integer is an abstract class. | 
|  18962   UNREACHABLE(); |  17888   UNREACHABLE(); | 
|  18963   return false; |  17889   return false; | 
|  18964 } |  17890 } | 
|  18965  |  17891  | 
|  18966  |  | 
|  18967 bool Integer::IsZero() const { |  17892 bool Integer::IsZero() const { | 
|  18968   // Integer is an abstract class. |  17893   // Integer is an abstract class. | 
|  18969   UNREACHABLE(); |  17894   UNREACHABLE(); | 
|  18970   return false; |  17895   return false; | 
|  18971 } |  17896 } | 
|  18972  |  17897  | 
|  18973  |  | 
|  18974 bool Integer::IsNegative() const { |  17898 bool Integer::IsNegative() const { | 
|  18975   // Integer is an abstract class. |  17899   // Integer is an abstract class. | 
|  18976   UNREACHABLE(); |  17900   UNREACHABLE(); | 
|  18977   return false; |  17901   return false; | 
|  18978 } |  17902 } | 
|  18979  |  17903  | 
|  18980  |  | 
|  18981 double Integer::AsDoubleValue() const { |  17904 double Integer::AsDoubleValue() const { | 
|  18982   // Integer is an abstract class. |  17905   // Integer is an abstract class. | 
|  18983   UNREACHABLE(); |  17906   UNREACHABLE(); | 
|  18984   return 0.0; |  17907   return 0.0; | 
|  18985 } |  17908 } | 
|  18986  |  17909  | 
|  18987  |  | 
|  18988 int64_t Integer::AsInt64Value() const { |  17910 int64_t Integer::AsInt64Value() const { | 
|  18989   // Integer is an abstract class. |  17911   // Integer is an abstract class. | 
|  18990   UNREACHABLE(); |  17912   UNREACHABLE(); | 
|  18991   return 0; |  17913   return 0; | 
|  18992 } |  17914 } | 
|  18993  |  17915  | 
|  18994  |  | 
|  18995 uint32_t Integer::AsTruncatedUint32Value() const { |  17916 uint32_t Integer::AsTruncatedUint32Value() const { | 
|  18996   // Integer is an abstract class. |  17917   // Integer is an abstract class. | 
|  18997   UNREACHABLE(); |  17918   UNREACHABLE(); | 
|  18998   return 0; |  17919   return 0; | 
|  18999 } |  17920 } | 
|  19000  |  17921  | 
|  19001  |  | 
|  19002 bool Integer::FitsIntoSmi() const { |  17922 bool Integer::FitsIntoSmi() const { | 
|  19003   // Integer is an abstract class. |  17923   // Integer is an abstract class. | 
|  19004   UNREACHABLE(); |  17924   UNREACHABLE(); | 
|  19005   return false; |  17925   return false; | 
|  19006 } |  17926 } | 
|  19007  |  17927  | 
|  19008  |  | 
|  19009 int Integer::CompareWith(const Integer& other) const { |  17928 int Integer::CompareWith(const Integer& other) const { | 
|  19010   // Integer is an abstract class. |  17929   // Integer is an abstract class. | 
|  19011   UNREACHABLE(); |  17930   UNREACHABLE(); | 
|  19012   return 0; |  17931   return 0; | 
|  19013 } |  17932 } | 
|  19014  |  17933  | 
|  19015  |  | 
|  19016 RawInteger* Integer::AsValidInteger() const { |  17934 RawInteger* Integer::AsValidInteger() const { | 
|  19017   if (IsSmi()) return raw(); |  17935   if (IsSmi()) return raw(); | 
|  19018   if (IsMint()) { |  17936   if (IsMint()) { | 
|  19019     Mint& mint = Mint::Handle(); |  17937     Mint& mint = Mint::Handle(); | 
|  19020     mint ^= raw(); |  17938     mint ^= raw(); | 
|  19021     if (Smi::IsValid(mint.value())) { |  17939     if (Smi::IsValid(mint.value())) { | 
|  19022       return Smi::New(static_cast<intptr_t>(mint.value())); |  17940       return Smi::New(static_cast<intptr_t>(mint.value())); | 
|  19023     } else { |  17941     } else { | 
|  19024       return raw(); |  17942       return raw(); | 
|  19025     } |  17943     } | 
|  19026   } |  17944   } | 
|  19027   if (Bigint::Cast(*this).FitsIntoInt64()) { |  17945   if (Bigint::Cast(*this).FitsIntoInt64()) { | 
|  19028     const int64_t value = AsInt64Value(); |  17946     const int64_t value = AsInt64Value(); | 
|  19029     if (Smi::IsValid(value)) { |  17947     if (Smi::IsValid(value)) { | 
|  19030       // This cast is safe because Smi::IsValid verifies that value will fit. |  17948       // This cast is safe because Smi::IsValid verifies that value will fit. | 
|  19031       intptr_t val = static_cast<intptr_t>(value); |  17949       intptr_t val = static_cast<intptr_t>(value); | 
|  19032       return Smi::New(val); |  17950       return Smi::New(val); | 
|  19033     } |  17951     } | 
|  19034     return Mint::New(value); |  17952     return Mint::New(value); | 
|  19035   } |  17953   } | 
|  19036   return raw(); |  17954   return raw(); | 
|  19037 } |  17955 } | 
|  19038  |  17956  | 
|  19039  |  | 
|  19040 RawInteger* Integer::ArithmeticOp(Token::Kind operation, |  17957 RawInteger* Integer::ArithmeticOp(Token::Kind operation, | 
|  19041                                   const Integer& other, |  17958                                   const Integer& other, | 
|  19042                                   Heap::Space space) const { |  17959                                   Heap::Space space) const { | 
|  19043   // In 32-bit mode, the result of any operation between two Smis will fit in a |  17960   // In 32-bit mode, the result of any operation between two Smis will fit in a | 
|  19044   // 32-bit signed result, except the product of two Smis, which will be 64-bit. |  17961   // 32-bit signed result, except the product of two Smis, which will be 64-bit. | 
|  19045   // In 64-bit mode, the result of any operation between two Smis will fit in a |  17962   // In 64-bit mode, the result of any operation between two Smis will fit in a | 
|  19046   // 64-bit signed result, except the product of two Smis (see below). |  17963   // 64-bit signed result, except the product of two Smis (see below). | 
|  19047   if (IsSmi() && other.IsSmi()) { |  17964   if (IsSmi() && other.IsSmi()) { | 
|  19048     const intptr_t left_value = Smi::Value(Smi::RawCast(raw())); |  17965     const intptr_t left_value = Smi::Value(Smi::RawCast(raw())); | 
|  19049     const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw())); |  17966     const intptr_t right_value = Smi::Value(Smi::RawCast(other.raw())); | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  19155         return Integer::New(remainder, space); |  18072         return Integer::New(remainder, space); | 
|  19156       } |  18073       } | 
|  19157       default: |  18074       default: | 
|  19158         UNIMPLEMENTED(); |  18075         UNIMPLEMENTED(); | 
|  19159     } |  18076     } | 
|  19160   } |  18077   } | 
|  19161   ASSERT(!FLAG_limit_ints_to_64_bits); |  18078   ASSERT(!FLAG_limit_ints_to_64_bits); | 
|  19162   return Integer::null();  // Notify caller that a bigint operation is required. |  18079   return Integer::null();  // Notify caller that a bigint operation is required. | 
|  19163 } |  18080 } | 
|  19164  |  18081  | 
|  19165  |  | 
|  19166 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { |  18082 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { | 
|  19167   return !op1.IsBigint() && !op2.IsBigint(); |  18083   return !op1.IsBigint() && !op2.IsBigint(); | 
|  19168 } |  18084 } | 
|  19169  |  18085  | 
|  19170  |  | 
|  19171 RawInteger* Integer::BitOp(Token::Kind kind, |  18086 RawInteger* Integer::BitOp(Token::Kind kind, | 
|  19172                            const Integer& other, |  18087                            const Integer& other, | 
|  19173                            Heap::Space space) const { |  18088                            Heap::Space space) const { | 
|  19174   if (IsSmi() && other.IsSmi()) { |  18089   if (IsSmi() && other.IsSmi()) { | 
|  19175     intptr_t op1_value = Smi::Value(Smi::RawCast(raw())); |  18090     intptr_t op1_value = Smi::Value(Smi::RawCast(raw())); | 
|  19176     intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw())); |  18091     intptr_t op2_value = Smi::Value(Smi::RawCast(other.raw())); | 
|  19177     intptr_t result = 0; |  18092     intptr_t result = 0; | 
|  19178     switch (kind) { |  18093     switch (kind) { | 
|  19179       case Token::kBIT_AND: |  18094       case Token::kBIT_AND: | 
|  19180         result = op1_value & op2_value; |  18095         result = op1_value & op2_value; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  19201       case Token::kBIT_XOR: |  18116       case Token::kBIT_XOR: | 
|  19202         return Integer::New(a ^ b, space); |  18117         return Integer::New(a ^ b, space); | 
|  19203       default: |  18118       default: | 
|  19204         UNIMPLEMENTED(); |  18119         UNIMPLEMENTED(); | 
|  19205     } |  18120     } | 
|  19206   } |  18121   } | 
|  19207   ASSERT(!FLAG_limit_ints_to_64_bits); |  18122   ASSERT(!FLAG_limit_ints_to_64_bits); | 
|  19208   return Integer::null();  // Notify caller that a bigint operation is required. |  18123   return Integer::null();  // Notify caller that a bigint operation is required. | 
|  19209 } |  18124 } | 
|  19210  |  18125  | 
|  19211  |  | 
|  19212 // TODO(srdjan): Clarify handling of negative right operand in a shift op. |  18126 // TODO(srdjan): Clarify handling of negative right operand in a shift op. | 
|  19213 RawInteger* Smi::ShiftOp(Token::Kind kind, |  18127 RawInteger* Smi::ShiftOp(Token::Kind kind, | 
|  19214                          const Smi& other, |  18128                          const Smi& other, | 
|  19215                          Heap::Space space) const { |  18129                          Heap::Space space) const { | 
|  19216   intptr_t result = 0; |  18130   intptr_t result = 0; | 
|  19217   const intptr_t left_value = Value(); |  18131   const intptr_t left_value = Value(); | 
|  19218   const intptr_t right_value = other.Value(); |  18132   const intptr_t right_value = other.Value(); | 
|  19219   ASSERT(right_value >= 0); |  18133   ASSERT(right_value >= 0); | 
|  19220   switch (kind) { |  18134   switch (kind) { | 
|  19221     case Token::kSHL: { |  18135     case Token::kSHL: { | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|  19248       result = left_value >> shift_amount; |  18162       result = left_value >> shift_amount; | 
|  19249       break; |  18163       break; | 
|  19250     } |  18164     } | 
|  19251     default: |  18165     default: | 
|  19252       UNIMPLEMENTED(); |  18166       UNIMPLEMENTED(); | 
|  19253   } |  18167   } | 
|  19254   ASSERT(Smi::IsValid(result)); |  18168   ASSERT(Smi::IsValid(result)); | 
|  19255   return Smi::New(result); |  18169   return Smi::New(result); | 
|  19256 } |  18170 } | 
|  19257  |  18171  | 
|  19258  |  | 
|  19259 bool Smi::Equals(const Instance& other) const { |  18172 bool Smi::Equals(const Instance& other) const { | 
|  19260   if (other.IsNull() || !other.IsSmi()) { |  18173   if (other.IsNull() || !other.IsSmi()) { | 
|  19261     return false; |  18174     return false; | 
|  19262   } |  18175   } | 
|  19263   return (this->Value() == Smi::Cast(other).Value()); |  18176   return (this->Value() == Smi::Cast(other).Value()); | 
|  19264 } |  18177 } | 
|  19265  |  18178  | 
|  19266  |  | 
|  19267 double Smi::AsDoubleValue() const { |  18179 double Smi::AsDoubleValue() const { | 
|  19268   return static_cast<double>(this->Value()); |  18180   return static_cast<double>(this->Value()); | 
|  19269 } |  18181 } | 
|  19270  |  18182  | 
|  19271  |  | 
|  19272 int64_t Smi::AsInt64Value() const { |  18183 int64_t Smi::AsInt64Value() const { | 
|  19273   return this->Value(); |  18184   return this->Value(); | 
|  19274 } |  18185 } | 
|  19275  |  18186  | 
|  19276  |  | 
|  19277 uint32_t Smi::AsTruncatedUint32Value() const { |  18187 uint32_t Smi::AsTruncatedUint32Value() const { | 
|  19278   return this->Value() & 0xFFFFFFFF; |  18188   return this->Value() & 0xFFFFFFFF; | 
|  19279 } |  18189 } | 
|  19280  |  18190  | 
|  19281  |  | 
|  19282 int Smi::CompareWith(const Integer& other) const { |  18191 int Smi::CompareWith(const Integer& other) const { | 
|  19283   if (other.IsSmi()) { |  18192   if (other.IsSmi()) { | 
|  19284     const Smi& other_smi = Smi::Cast(other); |  18193     const Smi& other_smi = Smi::Cast(other); | 
|  19285     if (this->Value() < other_smi.Value()) { |  18194     if (this->Value() < other_smi.Value()) { | 
|  19286       return -1; |  18195       return -1; | 
|  19287     } else if (this->Value() > other_smi.Value()) { |  18196     } else if (this->Value() > other_smi.Value()) { | 
|  19288       return 1; |  18197       return 1; | 
|  19289     } else { |  18198     } else { | 
|  19290       return 0; |  18199       return 0; | 
|  19291     } |  18200     } | 
|  19292   } |  18201   } | 
|  19293   ASSERT(!other.FitsIntoSmi()); |  18202   ASSERT(!other.FitsIntoSmi()); | 
|  19294   if (other.IsMint() || other.IsBigint()) { |  18203   if (other.IsMint() || other.IsBigint()) { | 
|  19295     if (this->IsNegative() == other.IsNegative()) { |  18204     if (this->IsNegative() == other.IsNegative()) { | 
|  19296       return this->IsNegative() ? 1 : -1; |  18205       return this->IsNegative() ? 1 : -1; | 
|  19297     } |  18206     } | 
|  19298     return this->IsNegative() ? -1 : 1; |  18207     return this->IsNegative() ? -1 : 1; | 
|  19299   } |  18208   } | 
|  19300   UNREACHABLE(); |  18209   UNREACHABLE(); | 
|  19301   return 0; |  18210   return 0; | 
|  19302 } |  18211 } | 
|  19303  |  18212  | 
|  19304  |  | 
|  19305 const char* Smi::ToCString() const { |  18213 const char* Smi::ToCString() const { | 
|  19306   return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value()); |  18214   return OS::SCreate(Thread::Current()->zone(), "%" Pd "", Value()); | 
|  19307 } |  18215 } | 
|  19308  |  18216  | 
|  19309  |  | 
|  19310 RawClass* Smi::Class() { |  18217 RawClass* Smi::Class() { | 
|  19311   return Isolate::Current()->object_store()->smi_class(); |  18218   return Isolate::Current()->object_store()->smi_class(); | 
|  19312 } |  18219 } | 
|  19313  |  18220  | 
|  19314  |  | 
|  19315 void Mint::set_value(int64_t value) const { |  18221 void Mint::set_value(int64_t value) const { | 
|  19316   StoreNonPointer(&raw_ptr()->value_, value); |  18222   StoreNonPointer(&raw_ptr()->value_, value); | 
|  19317 } |  18223 } | 
|  19318  |  18224  | 
|  19319  |  | 
|  19320 RawMint* Mint::New(int64_t val, Heap::Space space) { |  18225 RawMint* Mint::New(int64_t val, Heap::Space space) { | 
|  19321   // Do not allocate a Mint if Smi would do. |  18226   // Do not allocate a Mint if Smi would do. | 
|  19322   ASSERT(!Smi::IsValid(val)); |  18227   ASSERT(!Smi::IsValid(val)); | 
|  19323   ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null()); |  18228   ASSERT(Isolate::Current()->object_store()->mint_class() != Class::null()); | 
|  19324   Mint& result = Mint::Handle(); |  18229   Mint& result = Mint::Handle(); | 
|  19325   { |  18230   { | 
|  19326     RawObject* raw = |  18231     RawObject* raw = | 
|  19327         Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space); |  18232         Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space); | 
|  19328     NoSafepointScope no_safepoint; |  18233     NoSafepointScope no_safepoint; | 
|  19329     result ^= raw; |  18234     result ^= raw; | 
|  19330   } |  18235   } | 
|  19331   result.set_value(val); |  18236   result.set_value(val); | 
|  19332   return result.raw(); |  18237   return result.raw(); | 
|  19333 } |  18238 } | 
|  19334  |  18239  | 
|  19335  |  | 
|  19336 RawMint* Mint::NewCanonical(int64_t value) { |  18240 RawMint* Mint::NewCanonical(int64_t value) { | 
|  19337   // Do not allocate a Mint if Smi would do. |  18241   // Do not allocate a Mint if Smi would do. | 
|  19338   ASSERT(!Smi::IsValid(value)); |  18242   ASSERT(!Smi::IsValid(value)); | 
|  19339   Thread* thread = Thread::Current(); |  18243   Thread* thread = Thread::Current(); | 
|  19340   Zone* zone = thread->zone(); |  18244   Zone* zone = thread->zone(); | 
|  19341   Isolate* isolate = thread->isolate(); |  18245   Isolate* isolate = thread->isolate(); | 
|  19342   const Class& cls = Class::Handle(zone, isolate->object_store()->mint_class()); |  18246   const Class& cls = Class::Handle(zone, isolate->object_store()->mint_class()); | 
|  19343   Mint& canonical_value = Mint::Handle(zone); |  18247   Mint& canonical_value = Mint::Handle(zone); | 
|  19344   intptr_t index = 0; |  18248   intptr_t index = 0; | 
|  19345   canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); |  18249   canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  19357     } |  18261     } | 
|  19358     canonical_value = Mint::New(value, Heap::kOld); |  18262     canonical_value = Mint::New(value, Heap::kOld); | 
|  19359     canonical_value.SetCanonical(); |  18263     canonical_value.SetCanonical(); | 
|  19360     // The value needs to be added to the constants list. Grow the list if |  18264     // The value needs to be added to the constants list. Grow the list if | 
|  19361     // it is full. |  18265     // it is full. | 
|  19362     cls.InsertCanonicalNumber(zone, index, canonical_value); |  18266     cls.InsertCanonicalNumber(zone, index, canonical_value); | 
|  19363     return canonical_value.raw(); |  18267     return canonical_value.raw(); | 
|  19364   } |  18268   } | 
|  19365 } |  18269 } | 
|  19366  |  18270  | 
|  19367  |  | 
|  19368 bool Mint::Equals(const Instance& other) const { |  18271 bool Mint::Equals(const Instance& other) const { | 
|  19369   if (this->raw() == other.raw()) { |  18272   if (this->raw() == other.raw()) { | 
|  19370     // Both handles point to the same raw instance. |  18273     // Both handles point to the same raw instance. | 
|  19371     return true; |  18274     return true; | 
|  19372   } |  18275   } | 
|  19373   if (!other.IsMint() || other.IsNull()) { |  18276   if (!other.IsMint() || other.IsNull()) { | 
|  19374     return false; |  18277     return false; | 
|  19375   } |  18278   } | 
|  19376   return value() == Mint::Cast(other).value(); |  18279   return value() == Mint::Cast(other).value(); | 
|  19377 } |  18280 } | 
|  19378  |  18281  | 
|  19379  |  | 
|  19380 double Mint::AsDoubleValue() const { |  18282 double Mint::AsDoubleValue() const { | 
|  19381   return static_cast<double>(this->value()); |  18283   return static_cast<double>(this->value()); | 
|  19382 } |  18284 } | 
|  19383  |  18285  | 
|  19384  |  | 
|  19385 int64_t Mint::AsInt64Value() const { |  18286 int64_t Mint::AsInt64Value() const { | 
|  19386   return this->value(); |  18287   return this->value(); | 
|  19387 } |  18288 } | 
|  19388  |  18289  | 
|  19389  |  | 
|  19390 uint32_t Mint::AsTruncatedUint32Value() const { |  18290 uint32_t Mint::AsTruncatedUint32Value() const { | 
|  19391   return this->value() & 0xFFFFFFFF; |  18291   return this->value() & 0xFFFFFFFF; | 
|  19392 } |  18292 } | 
|  19393  |  18293  | 
|  19394  |  | 
|  19395 bool Mint::FitsIntoSmi() const { |  18294 bool Mint::FitsIntoSmi() const { | 
|  19396   return Smi::IsValid(AsInt64Value()); |  18295   return Smi::IsValid(AsInt64Value()); | 
|  19397 } |  18296 } | 
|  19398  |  18297  | 
|  19399  |  | 
|  19400 int Mint::CompareWith(const Integer& other) const { |  18298 int Mint::CompareWith(const Integer& other) const { | 
|  19401   ASSERT(!FitsIntoSmi()); |  18299   ASSERT(!FitsIntoSmi()); | 
|  19402   if (other.IsMint() || other.IsSmi()) { |  18300   if (other.IsMint() || other.IsSmi()) { | 
|  19403     int64_t a = AsInt64Value(); |  18301     int64_t a = AsInt64Value(); | 
|  19404     int64_t b = other.AsInt64Value(); |  18302     int64_t b = other.AsInt64Value(); | 
|  19405     if (a < b) { |  18303     if (a < b) { | 
|  19406       return -1; |  18304       return -1; | 
|  19407     } else if (a > b) { |  18305     } else if (a > b) { | 
|  19408       return 1; |  18306       return 1; | 
|  19409     } else { |  18307     } else { | 
|  19410       return 0; |  18308       return 0; | 
|  19411     } |  18309     } | 
|  19412   } |  18310   } | 
|  19413   ASSERT(other.IsBigint()); |  18311   ASSERT(other.IsBigint()); | 
|  19414   ASSERT(!Bigint::Cast(other).FitsIntoInt64()); |  18312   ASSERT(!Bigint::Cast(other).FitsIntoInt64()); | 
|  19415   if (this->IsNegative() == other.IsNegative()) { |  18313   if (this->IsNegative() == other.IsNegative()) { | 
|  19416     return this->IsNegative() ? 1 : -1; |  18314     return this->IsNegative() ? 1 : -1; | 
|  19417   } |  18315   } | 
|  19418   return this->IsNegative() ? -1 : 1; |  18316   return this->IsNegative() ? -1 : 1; | 
|  19419 } |  18317 } | 
|  19420  |  18318  | 
|  19421  |  | 
|  19422 const char* Mint::ToCString() const { |  18319 const char* Mint::ToCString() const { | 
|  19423   return OS::SCreate(Thread::Current()->zone(), "%" Pd64 "", value()); |  18320   return OS::SCreate(Thread::Current()->zone(), "%" Pd64 "", value()); | 
|  19424 } |  18321 } | 
|  19425  |  18322  | 
|  19426  |  | 
|  19427 void Double::set_value(double value) const { |  18323 void Double::set_value(double value) const { | 
|  19428   StoreNonPointer(&raw_ptr()->value_, value); |  18324   StoreNonPointer(&raw_ptr()->value_, value); | 
|  19429 } |  18325 } | 
|  19430  |  18326  | 
|  19431  |  | 
|  19432 bool Double::BitwiseEqualsToDouble(double value) const { |  18327 bool Double::BitwiseEqualsToDouble(double value) const { | 
|  19433   intptr_t value_offset = Double::value_offset(); |  18328   intptr_t value_offset = Double::value_offset(); | 
|  19434   void* this_addr = reinterpret_cast<void*>( |  18329   void* this_addr = reinterpret_cast<void*>( | 
|  19435       reinterpret_cast<uword>(this->raw_ptr()) + value_offset); |  18330       reinterpret_cast<uword>(this->raw_ptr()) + value_offset); | 
|  19436   void* other_addr = reinterpret_cast<void*>(&value); |  18331   void* other_addr = reinterpret_cast<void*>(&value); | 
|  19437   return (memcmp(this_addr, other_addr, sizeof(value)) == 0); |  18332   return (memcmp(this_addr, other_addr, sizeof(value)) == 0); | 
|  19438 } |  18333 } | 
|  19439  |  18334  | 
|  19440  |  | 
|  19441 bool Double::OperatorEquals(const Instance& other) const { |  18335 bool Double::OperatorEquals(const Instance& other) const { | 
|  19442   if (this->IsNull() || other.IsNull()) { |  18336   if (this->IsNull() || other.IsNull()) { | 
|  19443     return (this->IsNull() && other.IsNull()); |  18337     return (this->IsNull() && other.IsNull()); | 
|  19444   } |  18338   } | 
|  19445   if (!other.IsDouble()) { |  18339   if (!other.IsDouble()) { | 
|  19446     return false; |  18340     return false; | 
|  19447   } |  18341   } | 
|  19448   return this->value() == Double::Cast(other).value(); |  18342   return this->value() == Double::Cast(other).value(); | 
|  19449 } |  18343 } | 
|  19450  |  18344  | 
|  19451  |  | 
|  19452 bool Double::CanonicalizeEquals(const Instance& other) const { |  18345 bool Double::CanonicalizeEquals(const Instance& other) const { | 
|  19453   if (this->raw() == other.raw()) { |  18346   if (this->raw() == other.raw()) { | 
|  19454     return true;  // "===". |  18347     return true;  // "===". | 
|  19455   } |  18348   } | 
|  19456   if (other.IsNull() || !other.IsDouble()) { |  18349   if (other.IsNull() || !other.IsDouble()) { | 
|  19457     return false; |  18350     return false; | 
|  19458   } |  18351   } | 
|  19459   return BitwiseEqualsToDouble(Double::Cast(other).value()); |  18352   return BitwiseEqualsToDouble(Double::Cast(other).value()); | 
|  19460 } |  18353 } | 
|  19461  |  18354  | 
|  19462  |  | 
|  19463 RawDouble* Double::New(double d, Heap::Space space) { |  18355 RawDouble* Double::New(double d, Heap::Space space) { | 
|  19464   ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); |  18356   ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); | 
|  19465   Double& result = Double::Handle(); |  18357   Double& result = Double::Handle(); | 
|  19466   { |  18358   { | 
|  19467     RawObject* raw = |  18359     RawObject* raw = | 
|  19468         Object::Allocate(Double::kClassId, Double::InstanceSize(), space); |  18360         Object::Allocate(Double::kClassId, Double::InstanceSize(), space); | 
|  19469     NoSafepointScope no_safepoint; |  18361     NoSafepointScope no_safepoint; | 
|  19470     result ^= raw; |  18362     result ^= raw; | 
|  19471   } |  18363   } | 
|  19472   result.set_value(d); |  18364   result.set_value(d); | 
|  19473   return result.raw(); |  18365   return result.raw(); | 
|  19474 } |  18366 } | 
|  19475  |  18367  | 
|  19476  |  | 
|  19477 RawDouble* Double::New(const String& str, Heap::Space space) { |  18368 RawDouble* Double::New(const String& str, Heap::Space space) { | 
|  19478   double double_value; |  18369   double double_value; | 
|  19479   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |  18370   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 
|  19480     return Double::Handle().raw(); |  18371     return Double::Handle().raw(); | 
|  19481   } |  18372   } | 
|  19482   return New(double_value, space); |  18373   return New(double_value, space); | 
|  19483 } |  18374 } | 
|  19484  |  18375  | 
|  19485  |  | 
|  19486 RawDouble* Double::NewCanonical(double value) { |  18376 RawDouble* Double::NewCanonical(double value) { | 
|  19487   Thread* thread = Thread::Current(); |  18377   Thread* thread = Thread::Current(); | 
|  19488   Zone* zone = thread->zone(); |  18378   Zone* zone = thread->zone(); | 
|  19489   Isolate* isolate = thread->isolate(); |  18379   Isolate* isolate = thread->isolate(); | 
|  19490   const Class& cls = Class::Handle(isolate->object_store()->double_class()); |  18380   const Class& cls = Class::Handle(isolate->object_store()->double_class()); | 
|  19491   // Linear search to see whether this value is already present in the |  18381   // Linear search to see whether this value is already present in the | 
|  19492   // list of canonicalized constants. |  18382   // list of canonicalized constants. | 
|  19493   Double& canonical_value = Double::Handle(zone); |  18383   Double& canonical_value = Double::Handle(zone); | 
|  19494   intptr_t index = 0; |  18384   intptr_t index = 0; | 
|  19495  |  18385  | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  19508     } |  18398     } | 
|  19509     canonical_value = Double::New(value, Heap::kOld); |  18399     canonical_value = Double::New(value, Heap::kOld); | 
|  19510     canonical_value.SetCanonical(); |  18400     canonical_value.SetCanonical(); | 
|  19511     // The value needs to be added to the constants list. Grow the list if |  18401     // The value needs to be added to the constants list. Grow the list if | 
|  19512     // it is full. |  18402     // it is full. | 
|  19513     cls.InsertCanonicalNumber(zone, index, canonical_value); |  18403     cls.InsertCanonicalNumber(zone, index, canonical_value); | 
|  19514     return canonical_value.raw(); |  18404     return canonical_value.raw(); | 
|  19515   } |  18405   } | 
|  19516 } |  18406 } | 
|  19517  |  18407  | 
|  19518  |  | 
|  19519 RawDouble* Double::NewCanonical(const String& str) { |  18408 RawDouble* Double::NewCanonical(const String& str) { | 
|  19520   double double_value; |  18409   double double_value; | 
|  19521   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |  18410   if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 
|  19522     return Double::Handle().raw(); |  18411     return Double::Handle().raw(); | 
|  19523   } |  18412   } | 
|  19524   return NewCanonical(double_value); |  18413   return NewCanonical(double_value); | 
|  19525 } |  18414 } | 
|  19526  |  18415  | 
|  19527  |  | 
|  19528 RawString* Number::ToString(Heap::Space space) const { |  18416 RawString* Number::ToString(Heap::Space space) const { | 
|  19529   // Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant. |  18417   // Refactoring can avoid Zone::Alloc and strlen, but gains are insignificant. | 
|  19530   const char* cstr = ToCString(); |  18418   const char* cstr = ToCString(); | 
|  19531   intptr_t len = strlen(cstr); |  18419   intptr_t len = strlen(cstr); | 
|  19532 // Resulting string is ASCII ... |  18420 // Resulting string is ASCII ... | 
|  19533 #ifdef DEBUG |  18421 #ifdef DEBUG | 
|  19534   for (intptr_t i = 0; i < len; ++i) { |  18422   for (intptr_t i = 0; i < len; ++i) { | 
|  19535     ASSERT(static_cast<uint8_t>(cstr[i]) < 128); |  18423     ASSERT(static_cast<uint8_t>(cstr[i]) < 128); | 
|  19536   } |  18424   } | 
|  19537 #endif  // DEBUG |  18425 #endif  // DEBUG | 
|  19538   // ... which is a subset of Latin-1. |  18426   // ... which is a subset of Latin-1. | 
|  19539   return String::FromLatin1(reinterpret_cast<const uint8_t*>(cstr), len, space); |  18427   return String::FromLatin1(reinterpret_cast<const uint8_t*>(cstr), len, space); | 
|  19540 } |  18428 } | 
|  19541  |  18429  | 
|  19542  |  | 
|  19543 const char* Double::ToCString() const { |  18430 const char* Double::ToCString() const { | 
|  19544   if (isnan(value())) { |  18431   if (isnan(value())) { | 
|  19545     return "NaN"; |  18432     return "NaN"; | 
|  19546   } |  18433   } | 
|  19547   if (isinf(value())) { |  18434   if (isinf(value())) { | 
|  19548     return value() < 0 ? "-Infinity" : "Infinity"; |  18435     return value() < 0 ? "-Infinity" : "Infinity"; | 
|  19549   } |  18436   } | 
|  19550   const int kBufferSize = 128; |  18437   const int kBufferSize = 128; | 
|  19551   char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); |  18438   char* buffer = Thread::Current()->zone()->Alloc<char>(kBufferSize); | 
|  19552   buffer[kBufferSize - 1] = '\0'; |  18439   buffer[kBufferSize - 1] = '\0'; | 
|  19553   DoubleToCString(value(), buffer, kBufferSize); |  18440   DoubleToCString(value(), buffer, kBufferSize); | 
|  19554   return buffer; |  18441   return buffer; | 
|  19555 } |  18442 } | 
|  19556  |  18443  | 
|  19557  |  | 
|  19558 bool Bigint::Neg() const { |  18444 bool Bigint::Neg() const { | 
|  19559   return Bool::Handle(neg()).value(); |  18445   return Bool::Handle(neg()).value(); | 
|  19560 } |  18446 } | 
|  19561  |  18447  | 
|  19562  |  | 
|  19563 void Bigint::SetNeg(bool value) const { |  18448 void Bigint::SetNeg(bool value) const { | 
|  19564   StorePointer(&raw_ptr()->neg_, Bool::Get(value).raw()); |  18449   StorePointer(&raw_ptr()->neg_, Bool::Get(value).raw()); | 
|  19565 } |  18450 } | 
|  19566  |  18451  | 
|  19567  |  | 
|  19568 intptr_t Bigint::Used() const { |  18452 intptr_t Bigint::Used() const { | 
|  19569   return Smi::Value(used()); |  18453   return Smi::Value(used()); | 
|  19570 } |  18454 } | 
|  19571  |  18455  | 
|  19572  |  | 
|  19573 void Bigint::SetUsed(intptr_t value) const { |  18456 void Bigint::SetUsed(intptr_t value) const { | 
|  19574   StoreSmi(&raw_ptr()->used_, Smi::New(value)); |  18457   StoreSmi(&raw_ptr()->used_, Smi::New(value)); | 
|  19575 } |  18458 } | 
|  19576  |  18459  | 
|  19577  |  | 
|  19578 uint32_t Bigint::DigitAt(intptr_t index) const { |  18460 uint32_t Bigint::DigitAt(intptr_t index) const { | 
|  19579   const TypedData& typed_data = TypedData::Handle(digits()); |  18461   const TypedData& typed_data = TypedData::Handle(digits()); | 
|  19580   return typed_data.GetUint32(index << 2); |  18462   return typed_data.GetUint32(index << 2); | 
|  19581 } |  18463 } | 
|  19582  |  18464  | 
|  19583  |  | 
|  19584 void Bigint::set_digits(const TypedData& value) const { |  18465 void Bigint::set_digits(const TypedData& value) const { | 
|  19585   // The VM expects digits_ to be a Uint32List (not null). |  18466   // The VM expects digits_ to be a Uint32List (not null). | 
|  19586   ASSERT(!value.IsNull() && (value.GetClassId() == kTypedDataUint32ArrayCid)); |  18467   ASSERT(!value.IsNull() && (value.GetClassId() == kTypedDataUint32ArrayCid)); | 
|  19587   StorePointer(&raw_ptr()->digits_, value.raw()); |  18468   StorePointer(&raw_ptr()->digits_, value.raw()); | 
|  19588 } |  18469 } | 
|  19589  |  18470  | 
|  19590  |  | 
|  19591 RawTypedData* Bigint::NewDigits(intptr_t length, Heap::Space space) { |  18471 RawTypedData* Bigint::NewDigits(intptr_t length, Heap::Space space) { | 
|  19592   ASSERT(length > 0); |  18472   ASSERT(length > 0); | 
|  19593   // Account for leading zero for 64-bit processing. |  18473   // Account for leading zero for 64-bit processing. | 
|  19594   return TypedData::New(kTypedDataUint32ArrayCid, length + 1, space); |  18474   return TypedData::New(kTypedDataUint32ArrayCid, length + 1, space); | 
|  19595 } |  18475 } | 
|  19596  |  18476  | 
|  19597  |  | 
|  19598 uint32_t Bigint::DigitAt(const TypedData& digits, intptr_t index) { |  18477 uint32_t Bigint::DigitAt(const TypedData& digits, intptr_t index) { | 
|  19599   return digits.GetUint32(index << 2); |  18478   return digits.GetUint32(index << 2); | 
|  19600 } |  18479 } | 
|  19601  |  18480  | 
|  19602  |  | 
|  19603 void Bigint::SetDigitAt(const TypedData& digits, |  18481 void Bigint::SetDigitAt(const TypedData& digits, | 
|  19604                         intptr_t index, |  18482                         intptr_t index, | 
|  19605                         uint32_t value) { |  18483                         uint32_t value) { | 
|  19606   digits.SetUint32(index << 2, value); |  18484   digits.SetUint32(index << 2, value); | 
|  19607 } |  18485 } | 
|  19608  |  18486  | 
|  19609  |  | 
|  19610 bool Bigint::Equals(const Instance& other) const { |  18487 bool Bigint::Equals(const Instance& other) const { | 
|  19611   if (this->raw() == other.raw()) { |  18488   if (this->raw() == other.raw()) { | 
|  19612     // Both handles point to the same raw instance. |  18489     // Both handles point to the same raw instance. | 
|  19613     return true; |  18490     return true; | 
|  19614   } |  18491   } | 
|  19615  |  18492  | 
|  19616   if (!other.IsBigint() || other.IsNull()) { |  18493   if (!other.IsBigint() || other.IsNull()) { | 
|  19617     return false; |  18494     return false; | 
|  19618   } |  18495   } | 
|  19619  |  18496  | 
|  19620   const Bigint& other_bgi = Bigint::Cast(other); |  18497   const Bigint& other_bgi = Bigint::Cast(other); | 
|  19621  |  18498  | 
|  19622   if (this->Neg() != other_bgi.Neg()) { |  18499   if (this->Neg() != other_bgi.Neg()) { | 
|  19623     return false; |  18500     return false; | 
|  19624   } |  18501   } | 
|  19625  |  18502  | 
|  19626   const intptr_t used = this->Used(); |  18503   const intptr_t used = this->Used(); | 
|  19627   if (used != other_bgi.Used()) { |  18504   if (used != other_bgi.Used()) { | 
|  19628     return false; |  18505     return false; | 
|  19629   } |  18506   } | 
|  19630  |  18507  | 
|  19631   for (intptr_t i = 0; i < used; i++) { |  18508   for (intptr_t i = 0; i < used; i++) { | 
|  19632     if (this->DigitAt(i) != other_bgi.DigitAt(i)) { |  18509     if (this->DigitAt(i) != other_bgi.DigitAt(i)) { | 
|  19633       return false; |  18510       return false; | 
|  19634     } |  18511     } | 
|  19635   } |  18512   } | 
|  19636   return true; |  18513   return true; | 
|  19637 } |  18514 } | 
|  19638  |  18515  | 
|  19639  |  | 
|  19640 bool Bigint::CheckAndCanonicalizeFields(Thread* thread, |  18516 bool Bigint::CheckAndCanonicalizeFields(Thread* thread, | 
|  19641                                         const char** error_str) const { |  18517                                         const char** error_str) const { | 
|  19642   Zone* zone = thread->zone(); |  18518   Zone* zone = thread->zone(); | 
|  19643   // Bool field neg should always be canonical. |  18519   // Bool field neg should always be canonical. | 
|  19644   ASSERT(Bool::Handle(zone, neg()).IsCanonical()); |  18520   ASSERT(Bool::Handle(zone, neg()).IsCanonical()); | 
|  19645   // Smi field used is canonical by definition. |  18521   // Smi field used is canonical by definition. | 
|  19646   if (Used() > 0) { |  18522   if (Used() > 0) { | 
|  19647     // Canonicalize TypedData field digits. |  18523     // Canonicalize TypedData field digits. | 
|  19648     TypedData& digits_ = TypedData::Handle(zone, digits()); |  18524     TypedData& digits_ = TypedData::Handle(zone, digits()); | 
|  19649     digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); |  18525     digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); | 
|  19650     ASSERT(!digits_.IsNull()); |  18526     ASSERT(!digits_.IsNull()); | 
|  19651     set_digits(digits_); |  18527     set_digits(digits_); | 
|  19652   } else { |  18528   } else { | 
|  19653     ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); |  18529     ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); | 
|  19654   } |  18530   } | 
|  19655   return true; |  18531   return true; | 
|  19656 } |  18532 } | 
|  19657  |  18533  | 
|  19658  |  | 
|  19659 RawBigint* Bigint::New(Heap::Space space) { |  18534 RawBigint* Bigint::New(Heap::Space space) { | 
|  19660   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |  18535   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 
|  19661   Thread* thread = Thread::Current(); |  18536   Thread* thread = Thread::Current(); | 
|  19662   Zone* zone = thread->zone(); |  18537   Zone* zone = thread->zone(); | 
|  19663   Isolate* isolate = thread->isolate(); |  18538   Isolate* isolate = thread->isolate(); | 
|  19664   ASSERT(isolate->object_store()->bigint_class() != Class::null()); |  18539   ASSERT(isolate->object_store()->bigint_class() != Class::null()); | 
|  19665   Bigint& result = Bigint::Handle(zone); |  18540   Bigint& result = Bigint::Handle(zone); | 
|  19666   { |  18541   { | 
|  19667     RawObject* raw = |  18542     RawObject* raw = | 
|  19668         Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); |  18543         Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); | 
|  19669     NoSafepointScope no_safepoint; |  18544     NoSafepointScope no_safepoint; | 
|  19670     result ^= raw; |  18545     result ^= raw; | 
|  19671   } |  18546   } | 
|  19672   result.SetNeg(false); |  18547   result.SetNeg(false); | 
|  19673   result.SetUsed(0); |  18548   result.SetUsed(0); | 
|  19674   result.set_digits( |  18549   result.set_digits( | 
|  19675       TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |  18550       TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 
|  19676   return result.raw(); |  18551   return result.raw(); | 
|  19677 } |  18552 } | 
|  19678  |  18553  | 
|  19679  |  | 
|  19680 RawBigint* Bigint::New(bool neg, |  18554 RawBigint* Bigint::New(bool neg, | 
|  19681                        intptr_t used, |  18555                        intptr_t used, | 
|  19682                        const TypedData& digits, |  18556                        const TypedData& digits, | 
|  19683                        Heap::Space space) { |  18557                        Heap::Space space) { | 
|  19684   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |  18558   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 
|  19685   ASSERT((used == 0) || |  18559   ASSERT((used == 0) || | 
|  19686          (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); |  18560          (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); | 
|  19687   Thread* thread = Thread::Current(); |  18561   Thread* thread = Thread::Current(); | 
|  19688   Zone* zone = thread->zone(); |  18562   Zone* zone = thread->zone(); | 
|  19689   Isolate* isolate = thread->isolate(); |  18563   Isolate* isolate = thread->isolate(); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  19710   } else { |  18584   } else { | 
|  19711     neg = false; |  18585     neg = false; | 
|  19712     result.set_digits( |  18586     result.set_digits( | 
|  19713         TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |  18587         TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 
|  19714   } |  18588   } | 
|  19715   result.SetNeg(neg); |  18589   result.SetNeg(neg); | 
|  19716   result.SetUsed(used); |  18590   result.SetUsed(used); | 
|  19717   return result.raw(); |  18591   return result.raw(); | 
|  19718 } |  18592 } | 
|  19719  |  18593  | 
|  19720  |  | 
|  19721 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { |  18594 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { | 
|  19722   // Currently only used to convert Smi or Mint to hex String, therefore do |  18595   // Currently only used to convert Smi or Mint to hex String, therefore do | 
|  19723   // not throw RangeError if --limit-ints-to-64-bits. |  18596   // not throw RangeError if --limit-ints-to-64-bits. | 
|  19724   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |  18597   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 
|  19725   const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |  18598   const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 
|  19726   bool neg; |  18599   bool neg; | 
|  19727   uint64_t abs_value; |  18600   uint64_t abs_value; | 
|  19728   if (value < 0) { |  18601   if (value < 0) { | 
|  19729     neg = true; |  18602     neg = true; | 
|  19730     abs_value = -value; |  18603     abs_value = -value; | 
|  19731   } else { |  18604   } else { | 
|  19732     neg = false; |  18605     neg = false; | 
|  19733     abs_value = value; |  18606     abs_value = value; | 
|  19734   } |  18607   } | 
|  19735   SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); |  18608   SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); | 
|  19736   SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); |  18609   SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); | 
|  19737   return New(neg, 2, digits, space); |  18610   return New(neg, 2, digits, space); | 
|  19738 } |  18611 } | 
|  19739  |  18612  | 
|  19740  |  | 
|  19741 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { |  18613 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { | 
|  19742   // TODO(alexmarkov): Revise this assertion if this factory method is used |  18614   // TODO(alexmarkov): Revise this assertion if this factory method is used | 
|  19743   // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. |  18615   // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | 
|  19744   ASSERT(!FLAG_limit_ints_to_64_bits); |  18616   ASSERT(!FLAG_limit_ints_to_64_bits); | 
|  19745   const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |  18617   const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 
|  19746   SetDigitAt(digits, 0, static_cast<uint32_t>(value)); |  18618   SetDigitAt(digits, 0, static_cast<uint32_t>(value)); | 
|  19747   SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); |  18619   SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); | 
|  19748   return New(false, 2, digits, space); |  18620   return New(false, 2, digits, space); | 
|  19749 } |  18621 } | 
|  19750  |  18622  | 
|  19751  |  | 
|  19752 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, |  18623 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, | 
|  19753                                        intptr_t shift, |  18624                                        intptr_t shift, | 
|  19754                                        Heap::Space space) { |  18625                                        Heap::Space space) { | 
|  19755   // TODO(alexmarkov): Revise this assertion if this factory method is used |  18626   // TODO(alexmarkov): Revise this assertion if this factory method is used | 
|  19756   // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. |  18627   // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | 
|  19757   ASSERT(!FLAG_limit_ints_to_64_bits); |  18628   ASSERT(!FLAG_limit_ints_to_64_bits); | 
|  19758   ASSERT(kBitsPerDigit == 32); |  18629   ASSERT(kBitsPerDigit == 32); | 
|  19759   ASSERT(shift >= 0); |  18630   ASSERT(shift >= 0); | 
|  19760   const intptr_t digit_shift = shift / kBitsPerDigit; |  18631   const intptr_t digit_shift = shift / kBitsPerDigit; | 
|  19761   const intptr_t bit_shift = shift % kBitsPerDigit; |  18632   const intptr_t bit_shift = shift % kBitsPerDigit; | 
|  19762   const intptr_t used = 3 + digit_shift; |  18633   const intptr_t used = 3 + digit_shift; | 
|  19763   const TypedData& digits = TypedData::Handle(NewDigits(used, space)); |  18634   const TypedData& digits = TypedData::Handle(NewDigits(used, space)); | 
|  19764   bool neg; |  18635   bool neg; | 
|  19765   uint64_t abs_value; |  18636   uint64_t abs_value; | 
|  19766   if (value < 0) { |  18637   if (value < 0) { | 
|  19767     neg = true; |  18638     neg = true; | 
|  19768     abs_value = -value; |  18639     abs_value = -value; | 
|  19769   } else { |  18640   } else { | 
|  19770     neg = false; |  18641     neg = false; | 
|  19771     abs_value = value; |  18642     abs_value = value; | 
|  19772   } |  18643   } | 
|  19773   for (intptr_t i = 0; i < digit_shift; i++) { |  18644   for (intptr_t i = 0; i < digit_shift; i++) { | 
|  19774     SetDigitAt(digits, i, 0); |  18645     SetDigitAt(digits, i, 0); | 
|  19775   } |  18646   } | 
|  19776   SetDigitAt(digits, 0 + digit_shift, |  18647   SetDigitAt(digits, 0 + digit_shift, | 
|  19777              static_cast<uint32_t>(abs_value << bit_shift)); |  18648              static_cast<uint32_t>(abs_value << bit_shift)); | 
|  19778   SetDigitAt(digits, 1 + digit_shift, |  18649   SetDigitAt(digits, 1 + digit_shift, | 
|  19779              static_cast<uint32_t>(abs_value >> (32 - bit_shift))); |  18650              static_cast<uint32_t>(abs_value >> (32 - bit_shift))); | 
|  19780   SetDigitAt(digits, 2 + digit_shift, |  18651   SetDigitAt(digits, 2 + digit_shift, | 
|  19781              (bit_shift == 0) ? 0 : static_cast<uint32_t>(abs_value >> |  18652              (bit_shift == 0) | 
|  19782                                                           (64 - bit_shift))); |  18653                  ? 0 | 
 |  18654                  : static_cast<uint32_t>(abs_value >> (64 - bit_shift))); | 
|  19783   return New(neg, used, digits, space); |  18655   return New(neg, used, digits, space); | 
|  19784 } |  18656 } | 
|  19785  |  18657  | 
|  19786  |  | 
|  19787 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { |  18658 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { | 
|  19788   // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. |  18659   // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 
|  19789   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |  18660   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 
|  19790   ASSERT(str != NULL); |  18661   ASSERT(str != NULL); | 
|  19791   bool neg = false; |  18662   bool neg = false; | 
|  19792   TypedData& digits = TypedData::Handle(); |  18663   TypedData& digits = TypedData::Handle(); | 
|  19793   if (str[0] == '-') { |  18664   if (str[0] == '-') { | 
|  19794     ASSERT(str[1] != '-'); |  18665     ASSERT(str[1] != '-'); | 
|  19795     neg = true; |  18666     neg = true; | 
|  19796     str++; |  18667     str++; | 
|  19797   } |  18668   } | 
|  19798   intptr_t used; |  18669   intptr_t used; | 
|  19799   const intptr_t str_length = strlen(str); |  18670   const intptr_t str_length = strlen(str); | 
|  19800   if ((str_length >= 2) && (str[0] == '0') && |  18671   if ((str_length >= 2) && (str[0] == '0') && | 
|  19801       ((str[1] == 'x') || (str[1] == 'X'))) { |  18672       ((str[1] == 'x') || (str[1] == 'X'))) { | 
|  19802     digits = NewDigitsFromHexCString(&str[2], &used, space); |  18673     digits = NewDigitsFromHexCString(&str[2], &used, space); | 
|  19803   } else { |  18674   } else { | 
|  19804     digits = NewDigitsFromDecCString(str, &used, space); |  18675     digits = NewDigitsFromDecCString(str, &used, space); | 
|  19805   } |  18676   } | 
|  19806   return New(neg, used, digits, space); |  18677   return New(neg, used, digits, space); | 
|  19807 } |  18678 } | 
|  19808  |  18679  | 
|  19809  |  | 
|  19810 RawBigint* Bigint::NewCanonical(const String& str) { |  18680 RawBigint* Bigint::NewCanonical(const String& str) { | 
|  19811   // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. |  18681   // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 
|  19812   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. |  18682   // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 
|  19813   Thread* thread = Thread::Current(); |  18683   Thread* thread = Thread::Current(); | 
|  19814   Zone* zone = thread->zone(); |  18684   Zone* zone = thread->zone(); | 
|  19815   Isolate* isolate = thread->isolate(); |  18685   Isolate* isolate = thread->isolate(); | 
|  19816   const Bigint& value = |  18686   const Bigint& value = | 
|  19817       Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); |  18687       Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); | 
|  19818   const Class& cls = |  18688   const Class& cls = | 
|  19819       Class::Handle(zone, isolate->object_store()->bigint_class()); |  18689       Class::Handle(zone, isolate->object_store()->bigint_class()); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  19833       } |  18703       } | 
|  19834     } |  18704     } | 
|  19835     value.SetCanonical(); |  18705     value.SetCanonical(); | 
|  19836     // The value needs to be added to the constants list. Grow the list if |  18706     // The value needs to be added to the constants list. Grow the list if | 
|  19837     // it is full. |  18707     // it is full. | 
|  19838     cls.InsertCanonicalNumber(zone, index, value); |  18708     cls.InsertCanonicalNumber(zone, index, value); | 
|  19839     return value.raw(); |  18709     return value.raw(); | 
|  19840   } |  18710   } | 
|  19841 } |  18711 } | 
|  19842  |  18712  | 
|  19843  |  | 
|  19844 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, |  18713 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, | 
|  19845                                               intptr_t* used, |  18714                                               intptr_t* used, | 
|  19846                                               Heap::Space space) { |  18715                                               Heap::Space space) { | 
|  19847   const int kBitsPerHexDigit = 4; |  18716   const int kBitsPerHexDigit = 4; | 
|  19848   const int kHexDigitsPerDigit = 8; |  18717   const int kHexDigitsPerDigit = 8; | 
|  19849   const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; |  18718   const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; | 
|  19850   intptr_t hex_i = strlen(str);  // Terminating byte excluded. |  18719   intptr_t hex_i = strlen(str);  // Terminating byte excluded. | 
|  19851   if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { |  18720   if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { | 
|  19852     FATAL("Fatal error parsing hex bigint: string too long or empty"); |  18721     FATAL("Fatal error parsing hex bigint: string too long or empty"); | 
|  19853   } |  18722   } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  19865       digit = 0; |  18734       digit = 0; | 
|  19866     } |  18735     } | 
|  19867   } |  18736   } | 
|  19868   if (bit_i != 0) { |  18737   if (bit_i != 0) { | 
|  19869     SetDigitAt(digits, used_++, digit); |  18738     SetDigitAt(digits, used_++, digit); | 
|  19870   } |  18739   } | 
|  19871   *used = used_; |  18740   *used = used_; | 
|  19872   return digits.raw(); |  18741   return digits.raw(); | 
|  19873 } |  18742 } | 
|  19874  |  18743  | 
|  19875  |  | 
|  19876 RawTypedData* Bigint::NewDigitsFromDecCString(const char* str, |  18744 RawTypedData* Bigint::NewDigitsFromDecCString(const char* str, | 
|  19877                                               intptr_t* used, |  18745                                               intptr_t* used, | 
|  19878                                               Heap::Space space) { |  18746                                               Heap::Space space) { | 
|  19879   // Read 9 digits a time. 10^9 < 2^32. |  18747   // Read 9 digits a time. 10^9 < 2^32. | 
|  19880   const int kDecDigitsPerIteration = 9; |  18748   const int kDecDigitsPerIteration = 9; | 
|  19881   const uint32_t kTenMultiplier = 1000000000; |  18749   const uint32_t kTenMultiplier = 1000000000; | 
|  19882   ASSERT(kBitsPerDigit == 32); |  18750   ASSERT(kBitsPerDigit == 32); | 
|  19883   const intptr_t str_length = strlen(str); |  18751   const intptr_t str_length = strlen(str); | 
|  19884   if ((str_length <= 0) || (str_length >= kMaxInt32)) { |  18752   if ((str_length <= 0) || (str_length >= kMaxInt32)) { | 
|  19885     FATAL("Fatal error parsing dec bigint: string too long or empty"); |  18753     FATAL("Fatal error parsing dec bigint: string too long or empty"); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  19920           (static_cast<uint64_t>(DigitAt(digits, i)) * kTenMultiplier) + digit; |  18788           (static_cast<uint64_t>(DigitAt(digits, i)) * kTenMultiplier) + digit; | 
|  19921       SetDigitAt(digits, i, static_cast<uint32_t>(product & kDigitMask)); |  18789       SetDigitAt(digits, i, static_cast<uint32_t>(product & kDigitMask)); | 
|  19922       digit = static_cast<uint32_t>(product >> kBitsPerDigit); |  18790       digit = static_cast<uint32_t>(product >> kBitsPerDigit); | 
|  19923     } |  18791     } | 
|  19924     SetDigitAt(digits, used_++, digit); |  18792     SetDigitAt(digits, used_++, digit); | 
|  19925   } |  18793   } | 
|  19926   *used = used_; |  18794   *used = used_; | 
|  19927   return digits.raw(); |  18795   return digits.raw(); | 
|  19928 } |  18796 } | 
|  19929  |  18797  | 
|  19930  |  | 
|  19931 static double Uint64ToDouble(uint64_t x) { |  18798 static double Uint64ToDouble(uint64_t x) { | 
|  19932 #if _WIN64 |  18799 #if _WIN64 | 
|  19933   // For static_cast<double>(x) MSVC x64 generates |  18800   // For static_cast<double>(x) MSVC x64 generates | 
|  19934   // |  18801   // | 
|  19935   //    cvtsi2sd xmm0, rax |  18802   //    cvtsi2sd xmm0, rax | 
|  19936   //    test  rax, rax |  18803   //    test  rax, rax | 
|  19937   //    jns done |  18804   //    jns done | 
|  19938   //    addsd xmm0, static_cast<double>(2^64) |  18805   //    addsd xmm0, static_cast<double>(2^64) | 
|  19939   //  done: |  18806   //  done: | 
|  19940   // |  18807   // | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  19964   } else { |  18831   } else { | 
|  19965     const double half = |  18832     const double half = | 
|  19966         static_cast<double>(static_cast<int64_t>(x >> 1) | (y & 1)); |  18833         static_cast<double>(static_cast<int64_t>(x >> 1) | (y & 1)); | 
|  19967     return half + half; |  18834     return half + half; | 
|  19968   } |  18835   } | 
|  19969 #else |  18836 #else | 
|  19970   return static_cast<double>(x); |  18837   return static_cast<double>(x); | 
|  19971 #endif |  18838 #endif | 
|  19972 } |  18839 } | 
|  19973  |  18840  | 
|  19974  |  | 
|  19975 double Bigint::AsDoubleValue() const { |  18841 double Bigint::AsDoubleValue() const { | 
|  19976   ASSERT(kBitsPerDigit == 32); |  18842   ASSERT(kBitsPerDigit == 32); | 
|  19977   const intptr_t used = Used(); |  18843   const intptr_t used = Used(); | 
|  19978   if (used == 0) { |  18844   if (used == 0) { | 
|  19979     return 0.0; |  18845     return 0.0; | 
|  19980   } |  18846   } | 
|  19981   if (used <= 2) { |  18847   if (used <= 2) { | 
|  19982     const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; |  18848     const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 
|  19983     const uint64_t abs_value = (digit1 << 32) + DigitAt(0); |  18849     const uint64_t abs_value = (digit1 << 32) + DigitAt(0); | 
|  19984     const double abs_double_value = Uint64ToDouble(abs_value); |  18850     const double abs_double_value = Uint64ToDouble(abs_value); | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  20099   // exponent by one instead of playing around with the significand. |  18965   // exponent by one instead of playing around with the significand. | 
|  20100   const uint64_t biased_exponent = exponent + kExponentBias - 1; |  18966   const uint64_t biased_exponent = exponent + kExponentBias - 1; | 
|  20101   // Note that we must use the plus operator instead of bit-or. |  18967   // Note that we must use the plus operator instead of bit-or. | 
|  20102   const uint64_t double_bits = |  18968   const uint64_t double_bits = | 
|  20103       (biased_exponent << kPhysicalSignificandSize) + significand; |  18969       (biased_exponent << kPhysicalSignificandSize) + significand; | 
|  20104  |  18970  | 
|  20105   const double value = bit_cast<double>(double_bits); |  18971   const double value = bit_cast<double>(double_bits); | 
|  20106   return Neg() ? -value : value; |  18972   return Neg() ? -value : value; | 
|  20107 } |  18973 } | 
|  20108  |  18974  | 
|  20109  |  | 
|  20110 bool Bigint::FitsIntoSmi() const { |  18975 bool Bigint::FitsIntoSmi() const { | 
|  20111   return FitsIntoInt64() && Smi::IsValid(AsInt64Value()); |  18976   return FitsIntoInt64() && Smi::IsValid(AsInt64Value()); | 
|  20112 } |  18977 } | 
|  20113  |  18978  | 
|  20114  |  | 
|  20115 bool Bigint::FitsIntoInt64() const { |  18979 bool Bigint::FitsIntoInt64() const { | 
|  20116   ASSERT(Bigint::kBitsPerDigit == 32); |  18980   ASSERT(Bigint::kBitsPerDigit == 32); | 
|  20117   const intptr_t used = Used(); |  18981   const intptr_t used = Used(); | 
|  20118   if (used < 2) return true; |  18982   if (used < 2) return true; | 
|  20119   if (used > 2) return false; |  18983   if (used > 2) return false; | 
|  20120   const uint64_t digit1 = DigitAt(1); |  18984   const uint64_t digit1 = DigitAt(1); | 
|  20121   const uint64_t value = (digit1 << 32) + DigitAt(0); |  18985   const uint64_t value = (digit1 << 32) + DigitAt(0); | 
|  20122   uint64_t limit = Mint::kMaxValue; |  18986   uint64_t limit = Mint::kMaxValue; | 
|  20123   if (Neg()) { |  18987   if (Neg()) { | 
|  20124     limit++; |  18988     limit++; | 
|  20125   } |  18989   } | 
|  20126   return value <= limit; |  18990   return value <= limit; | 
|  20127 } |  18991 } | 
|  20128  |  18992  | 
|  20129  |  | 
|  20130 int64_t Bigint::AsTruncatedInt64Value() const { |  18993 int64_t Bigint::AsTruncatedInt64Value() const { | 
|  20131   const intptr_t used = Used(); |  18994   const intptr_t used = Used(); | 
|  20132   if (used == 0) return 0; |  18995   if (used == 0) return 0; | 
|  20133   const int64_t digit1 = (used > 1) ? DigitAt(1) : 0; |  18996   const int64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 
|  20134   const int64_t value = (digit1 << 32) + DigitAt(0); |  18997   const int64_t value = (digit1 << 32) + DigitAt(0); | 
|  20135   return Neg() ? -value : value; |  18998   return Neg() ? -value : value; | 
|  20136 } |  18999 } | 
|  20137  |  19000  | 
|  20138  |  | 
|  20139 int64_t Bigint::AsInt64Value() const { |  19001 int64_t Bigint::AsInt64Value() const { | 
|  20140   ASSERT(FitsIntoInt64()); |  19002   ASSERT(FitsIntoInt64()); | 
|  20141   return AsTruncatedInt64Value(); |  19003   return AsTruncatedInt64Value(); | 
|  20142 } |  19004 } | 
|  20143  |  19005  | 
|  20144  |  | 
|  20145 bool Bigint::FitsIntoUint64() const { |  19006 bool Bigint::FitsIntoUint64() const { | 
|  20146   ASSERT(Bigint::kBitsPerDigit == 32); |  19007   ASSERT(Bigint::kBitsPerDigit == 32); | 
|  20147   return !Neg() && (Used() <= 2); |  19008   return !Neg() && (Used() <= 2); | 
|  20148 } |  19009 } | 
|  20149  |  19010  | 
|  20150  |  | 
|  20151 uint64_t Bigint::AsUint64Value() const { |  19011 uint64_t Bigint::AsUint64Value() const { | 
|  20152   ASSERT(FitsIntoUint64()); |  19012   ASSERT(FitsIntoUint64()); | 
|  20153   const intptr_t used = Used(); |  19013   const intptr_t used = Used(); | 
|  20154   if (used == 0) return 0; |  19014   if (used == 0) return 0; | 
|  20155   const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; |  19015   const uint64_t digit1 = (used > 1) ? DigitAt(1) : 0; | 
|  20156   return (digit1 << 32) + DigitAt(0); |  19016   return (digit1 << 32) + DigitAt(0); | 
|  20157 } |  19017 } | 
|  20158  |  19018  | 
|  20159  |  | 
|  20160 uint32_t Bigint::AsTruncatedUint32Value() const { |  19019 uint32_t Bigint::AsTruncatedUint32Value() const { | 
|  20161   // Note: the previous implementation of Bigint returned the absolute value |  19020   // Note: the previous implementation of Bigint returned the absolute value | 
|  20162   // truncated to 32 bits, which is not consistent with Smi and Mint behavior. |  19021   // truncated to 32 bits, which is not consistent with Smi and Mint behavior. | 
|  20163   ASSERT(Bigint::kBitsPerDigit == 32); |  19022   ASSERT(Bigint::kBitsPerDigit == 32); | 
|  20164   const intptr_t used = Used(); |  19023   const intptr_t used = Used(); | 
|  20165   if (used == 0) return 0; |  19024   if (used == 0) return 0; | 
|  20166   const uint32_t digit0 = DigitAt(0); |  19025   const uint32_t digit0 = DigitAt(0); | 
|  20167   return Neg() ? static_cast<uint32_t>(-static_cast<int32_t>(digit0)) : digit0; |  19026   return Neg() ? static_cast<uint32_t>(-static_cast<int32_t>(digit0)) : digit0; | 
|  20168 } |  19027 } | 
|  20169  |  19028  | 
|  20170  |  | 
|  20171 // For positive values: Smi < Mint < Bigint. |  19029 // For positive values: Smi < Mint < Bigint. | 
|  20172 int Bigint::CompareWith(const Integer& other) const { |  19030 int Bigint::CompareWith(const Integer& other) const { | 
|  20173   ASSERT(!FitsIntoSmi()); |  19031   ASSERT(!FitsIntoSmi()); | 
|  20174   ASSERT(!FitsIntoInt64()); |  19032   ASSERT(!FitsIntoInt64()); | 
|  20175   if (other.IsBigint() && (IsNegative() == other.IsNegative())) { |  19033   if (other.IsBigint() && (IsNegative() == other.IsNegative())) { | 
|  20176     const Bigint& other_bgi = Bigint::Cast(other); |  19034     const Bigint& other_bgi = Bigint::Cast(other); | 
|  20177     int64_t result = Used() - other_bgi.Used(); |  19035     int64_t result = Used() - other_bgi.Used(); | 
|  20178     if (result == 0) { |  19036     if (result == 0) { | 
|  20179       for (intptr_t i = Used(); --i >= 0;) { |  19037       for (intptr_t i = Used(); --i >= 0;) { | 
|  20180         result = DigitAt(i); |  19038         result = DigitAt(i); | 
|  20181         result -= other_bgi.DigitAt(i); |  19039         result -= other_bgi.DigitAt(i); | 
|  20182         if (result != 0) break; |  19040         if (result != 0) break; | 
|  20183       } |  19041       } | 
|  20184     } |  19042     } | 
|  20185     if (IsNegative()) { |  19043     if (IsNegative()) { | 
|  20186       result = -result; |  19044       result = -result; | 
|  20187     } |  19045     } | 
|  20188     return result > 0 ? 1 : result < 0 ? -1 : 0; |  19046     return result > 0 ? 1 : result < 0 ? -1 : 0; | 
|  20189   } |  19047   } | 
|  20190   return this->IsNegative() ? -1 : 1; |  19048   return this->IsNegative() ? -1 : 1; | 
|  20191 } |  19049 } | 
|  20192  |  19050  | 
|  20193  |  | 
|  20194 const char* Bigint::ToDecCString(Zone* zone) const { |  19051 const char* Bigint::ToDecCString(Zone* zone) const { | 
|  20195   // log10(2) ~= 0.30102999566398114. |  19052   // log10(2) ~= 0.30102999566398114. | 
|  20196   const intptr_t kLog2Dividend = 30103; |  19053   const intptr_t kLog2Dividend = 30103; | 
|  20197   const intptr_t kLog2Divisor = 100000; |  19054   const intptr_t kLog2Divisor = 100000; | 
|  20198   intptr_t used = Used(); |  19055   intptr_t used = Used(); | 
|  20199   const intptr_t kMaxUsed = |  19056   const intptr_t kMaxUsed = | 
|  20200       kIntptrMax / kBitsPerDigit / kLog2Dividend * kLog2Divisor; |  19057       kIntptrMax / kBitsPerDigit / kLog2Dividend * kLog2Divisor; | 
|  20201   if (used > kMaxUsed) { |  19058   if (used > kMaxUsed) { | 
|  20202     Exceptions::ThrowOOM(); |  19059     Exceptions::ThrowOOM(); | 
|  20203     UNREACHABLE(); |  19060     UNREACHABLE(); | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  20255     char tmp = chars[i]; |  19112     char tmp = chars[i]; | 
|  20256     chars[i] = chars[j]; |  19113     chars[i] = chars[j]; | 
|  20257     chars[j] = tmp; |  19114     chars[j] = tmp; | 
|  20258     i++; |  19115     i++; | 
|  20259     j--; |  19116     j--; | 
|  20260   } |  19117   } | 
|  20261   chars[pos] = '\0'; |  19118   chars[pos] = '\0'; | 
|  20262   return chars; |  19119   return chars; | 
|  20263 } |  19120 } | 
|  20264  |  19121  | 
|  20265  |  | 
|  20266 const char* Bigint::ToHexCString(Zone* zone) const { |  19122 const char* Bigint::ToHexCString(Zone* zone) const { | 
|  20267   const intptr_t used = Used(); |  19123   const intptr_t used = Used(); | 
|  20268   if (used == 0) { |  19124   if (used == 0) { | 
|  20269     const char* zero = "0x0"; |  19125     const char* zero = "0x0"; | 
|  20270     const size_t len = strlen(zero) + 1; |  19126     const size_t len = strlen(zero) + 1; | 
|  20271     char* chars = zone->Alloc<char>(len); |  19127     char* chars = zone->Alloc<char>(len); | 
|  20272     strncpy(chars, zero, len); |  19128     strncpy(chars, zero, len); | 
|  20273     return chars; |  19129     return chars; | 
|  20274   } |  19130   } | 
|  20275   const int kBitsPerHexDigit = 4; |  19131   const int kBitsPerHexDigit = 4; | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|  20306   } |  19162   } | 
|  20307   chars[--pos] = 'x'; |  19163   chars[--pos] = 'x'; | 
|  20308   chars[--pos] = '0'; |  19164   chars[--pos] = '0'; | 
|  20309   if (Neg()) { |  19165   if (Neg()) { | 
|  20310     chars[--pos] = '-'; |  19166     chars[--pos] = '-'; | 
|  20311   } |  19167   } | 
|  20312   ASSERT(pos == 0); |  19168   ASSERT(pos == 0); | 
|  20313   return chars; |  19169   return chars; | 
|  20314 } |  19170 } | 
|  20315  |  19171  | 
|  20316  |  | 
|  20317 const char* Bigint::ToCString() const { |  19172 const char* Bigint::ToCString() const { | 
|  20318   return ToDecCString(Thread::Current()->zone()); |  19173   return ToDecCString(Thread::Current()->zone()); | 
|  20319 } |  19174 } | 
|  20320  |  19175  | 
|  20321  |  | 
|  20322 // Synchronize with implementation in compiler (intrinsifier). |  19176 // Synchronize with implementation in compiler (intrinsifier). | 
|  20323 class StringHasher : ValueObject { |  19177 class StringHasher : ValueObject { | 
|  20324  public: |  19178  public: | 
|  20325   StringHasher() : hash_(0) {} |  19179   StringHasher() : hash_(0) {} | 
|  20326   void Add(int32_t ch) { hash_ = CombineHashes(hash_, ch); } |  19180   void Add(int32_t ch) { hash_ = CombineHashes(hash_, ch); } | 
|  20327   void Add(const String& str, intptr_t begin_index, intptr_t len); |  19181   void Add(const String& str, intptr_t begin_index, intptr_t len); | 
|  20328  |  19182  | 
|  20329   // Return a non-zero hash of at most 'bits' bits. |  19183   // Return a non-zero hash of at most 'bits' bits. | 
|  20330   intptr_t Finalize(int bits) { |  19184   intptr_t Finalize(int bits) { | 
|  20331     ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); |  19185     ASSERT(1 <= bits && bits <= (kBitsPerWord - 1)); | 
|  20332     hash_ = FinalizeHash(hash_, bits); |  19186     hash_ = FinalizeHash(hash_, bits); | 
|  20333     ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); |  19187     ASSERT(hash_ <= static_cast<uint32_t>(kMaxInt32)); | 
|  20334     return hash_; |  19188     return hash_; | 
|  20335   } |  19189   } | 
|  20336  |  19190  | 
|  20337  private: |  19191  private: | 
|  20338   uint32_t hash_; |  19192   uint32_t hash_; | 
|  20339 }; |  19193 }; | 
|  20340  |  19194  | 
|  20341  |  | 
|  20342 void StringHasher::Add(const String& str, intptr_t begin_index, intptr_t len) { |  19195 void StringHasher::Add(const String& str, intptr_t begin_index, intptr_t len) { | 
|  20343   ASSERT(begin_index >= 0); |  19196   ASSERT(begin_index >= 0); | 
|  20344   ASSERT(len >= 0); |  19197   ASSERT(len >= 0); | 
|  20345   ASSERT((begin_index + len) <= str.Length()); |  19198   ASSERT((begin_index + len) <= str.Length()); | 
|  20346   if (len == 0) { |  19199   if (len == 0) { | 
|  20347     return; |  19200     return; | 
|  20348   } |  19201   } | 
|  20349   if (str.IsOneByteString()) { |  19202   if (str.IsOneByteString()) { | 
|  20350     NoSafepointScope no_safepoint; |  19203     NoSafepointScope no_safepoint; | 
|  20351     uint8_t* str_addr = OneByteString::CharAddr(str, begin_index); |  19204     uint8_t* str_addr = OneByteString::CharAddr(str, begin_index); | 
|  20352     for (intptr_t i = 0; i < len; i++) { |  19205     for (intptr_t i = 0; i < len; i++) { | 
|  20353       Add(*str_addr); |  19206       Add(*str_addr); | 
|  20354       str_addr++; |  19207       str_addr++; | 
|  20355     } |  19208     } | 
|  20356   } else { |  19209   } else { | 
|  20357     String::CodePointIterator it(str, begin_index, len); |  19210     String::CodePointIterator it(str, begin_index, len); | 
|  20358     while (it.Next()) { |  19211     while (it.Next()) { | 
|  20359       Add(it.Current()); |  19212       Add(it.Current()); | 
|  20360     } |  19213     } | 
|  20361   } |  19214   } | 
|  20362 } |  19215 } | 
|  20363  |  19216  | 
|  20364  |  | 
|  20365 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { |  19217 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { | 
|  20366   StringHasher hasher; |  19218   StringHasher hasher; | 
|  20367   hasher.Add(str, begin_index, len); |  19219   hasher.Add(str, begin_index, len); | 
|  20368   return hasher.Finalize(kHashBits); |  19220   return hasher.Finalize(kHashBits); | 
|  20369 } |  19221 } | 
|  20370  |  19222  | 
|  20371  |  | 
|  20372 intptr_t String::HashConcat(const String& str1, const String& str2) { |  19223 intptr_t String::HashConcat(const String& str1, const String& str2) { | 
|  20373   intptr_t len1 = str1.Length(); |  19224   intptr_t len1 = str1.Length(); | 
|  20374   // Since String::Hash works at the code point (rune) level, a surrogate pair |  19225   // Since String::Hash works at the code point (rune) level, a surrogate pair | 
|  20375   // that crosses the boundary between str1 and str2 must be composed. |  19226   // that crosses the boundary between str1 and str2 must be composed. | 
|  20376   if (str1.IsTwoByteString() && Utf16::IsLeadSurrogate(str1.CharAt(len1 - 1))) { |  19227   if (str1.IsTwoByteString() && Utf16::IsLeadSurrogate(str1.CharAt(len1 - 1))) { | 
|  20377     const String& temp = String::Handle(String::Concat(str1, str2)); |  19228     const String& temp = String::Handle(String::Concat(str1, str2)); | 
|  20378     return temp.Hash(); |  19229     return temp.Hash(); | 
|  20379   } else { |  19230   } else { | 
|  20380     StringHasher hasher; |  19231     StringHasher hasher; | 
|  20381     hasher.Add(str1, 0, len1); |  19232     hasher.Add(str1, 0, len1); | 
|  20382     hasher.Add(str2, 0, str2.Length()); |  19233     hasher.Add(str2, 0, str2.Length()); | 
|  20383     return hasher.Finalize(kHashBits); |  19234     return hasher.Finalize(kHashBits); | 
|  20384   } |  19235   } | 
|  20385 } |  19236 } | 
|  20386  |  19237  | 
|  20387  |  | 
|  20388 template <typename T> |  19238 template <typename T> | 
|  20389 static intptr_t HashImpl(const T* characters, intptr_t len) { |  19239 static intptr_t HashImpl(const T* characters, intptr_t len) { | 
|  20390   ASSERT(len >= 0); |  19240   ASSERT(len >= 0); | 
|  20391   StringHasher hasher; |  19241   StringHasher hasher; | 
|  20392   for (intptr_t i = 0; i < len; i++) { |  19242   for (intptr_t i = 0; i < len; i++) { | 
|  20393     hasher.Add(characters[i]); |  19243     hasher.Add(characters[i]); | 
|  20394   } |  19244   } | 
|  20395   return hasher.Finalize(String::kHashBits); |  19245   return hasher.Finalize(String::kHashBits); | 
|  20396 } |  19246 } | 
|  20397  |  19247  | 
|  20398  |  | 
|  20399 intptr_t String::Hash(RawString* raw) { |  19248 intptr_t String::Hash(RawString* raw) { | 
|  20400   StringHasher hasher; |  19249   StringHasher hasher; | 
|  20401   uword length = Smi::Value(raw->ptr()->length_); |  19250   uword length = Smi::Value(raw->ptr()->length_); | 
|  20402   if (raw->IsOneByteString() || raw->IsExternalOneByteString()) { |  19251   if (raw->IsOneByteString() || raw->IsExternalOneByteString()) { | 
|  20403     const uint8_t* data; |  19252     const uint8_t* data; | 
|  20404     if (raw->IsOneByteString()) { |  19253     if (raw->IsOneByteString()) { | 
|  20405       data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data(); |  19254       data = reinterpret_cast<RawOneByteString*>(raw)->ptr()->data(); | 
|  20406     } else { |  19255     } else { | 
|  20407       ASSERT(raw->IsExternalOneByteString()); |  19256       ASSERT(raw->IsExternalOneByteString()); | 
|  20408       RawExternalOneByteString* str = |  19257       RawExternalOneByteString* str = | 
|  20409           reinterpret_cast<RawExternalOneByteString*>(raw); |  19258           reinterpret_cast<RawExternalOneByteString*>(raw); | 
|  20410       data = str->ptr()->external_data_->data(); |  19259       data = str->ptr()->external_data_->data(); | 
|  20411     } |  19260     } | 
|  20412     return String::Hash(data, length); |  19261     return String::Hash(data, length); | 
|  20413   } else { |  19262   } else { | 
|  20414     const uint16_t* data; |  19263     const uint16_t* data; | 
|  20415     if (raw->IsTwoByteString()) { |  19264     if (raw->IsTwoByteString()) { | 
|  20416       data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data(); |  19265       data = reinterpret_cast<RawTwoByteString*>(raw)->ptr()->data(); | 
|  20417     } else { |  19266     } else { | 
|  20418       ASSERT(raw->IsExternalTwoByteString()); |  19267       ASSERT(raw->IsExternalTwoByteString()); | 
|  20419       RawExternalTwoByteString* str = |  19268       RawExternalTwoByteString* str = | 
|  20420           reinterpret_cast<RawExternalTwoByteString*>(raw); |  19269           reinterpret_cast<RawExternalTwoByteString*>(raw); | 
|  20421       data = str->ptr()->external_data_->data(); |  19270       data = str->ptr()->external_data_->data(); | 
|  20422     } |  19271     } | 
|  20423     return String::Hash(data, length); |  19272     return String::Hash(data, length); | 
|  20424   } |  19273   } | 
|  20425 } |  19274 } | 
|  20426  |  19275  | 
|  20427  |  | 
|  20428 intptr_t String::Hash(const char* characters, intptr_t len) { |  19276 intptr_t String::Hash(const char* characters, intptr_t len) { | 
|  20429   return HashImpl(characters, len); |  19277   return HashImpl(characters, len); | 
|  20430 } |  19278 } | 
|  20431  |  19279  | 
|  20432  |  | 
|  20433 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { |  19280 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { | 
|  20434   return HashImpl(characters, len); |  19281   return HashImpl(characters, len); | 
|  20435 } |  19282 } | 
|  20436  |  19283  | 
|  20437  |  | 
|  20438 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { |  19284 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { | 
|  20439   StringHasher hasher; |  19285   StringHasher hasher; | 
|  20440   intptr_t i = 0; |  19286   intptr_t i = 0; | 
|  20441   while (i < len) { |  19287   while (i < len) { | 
|  20442     hasher.Add(Utf16::Next(characters, &i, len)); |  19288     hasher.Add(Utf16::Next(characters, &i, len)); | 
|  20443   } |  19289   } | 
|  20444   return hasher.Finalize(kHashBits); |  19290   return hasher.Finalize(kHashBits); | 
|  20445 } |  19291 } | 
|  20446  |  19292  | 
|  20447  |  | 
|  20448 intptr_t String::Hash(const int32_t* characters, intptr_t len) { |  19293 intptr_t String::Hash(const int32_t* characters, intptr_t len) { | 
|  20449   return HashImpl(characters, len); |  19294   return HashImpl(characters, len); | 
|  20450 } |  19295 } | 
|  20451  |  19296  | 
|  20452  |  | 
|  20453 uint16_t String::CharAt(intptr_t index) const { |  19297 uint16_t String::CharAt(intptr_t index) const { | 
|  20454   intptr_t class_id = raw()->GetClassId(); |  19298   intptr_t class_id = raw()->GetClassId(); | 
|  20455   ASSERT(RawObject::IsStringClassId(class_id)); |  19299   ASSERT(RawObject::IsStringClassId(class_id)); | 
|  20456   if (class_id == kOneByteStringCid) { |  19300   if (class_id == kOneByteStringCid) { | 
|  20457     return OneByteString::CharAt(*this, index); |  19301     return OneByteString::CharAt(*this, index); | 
|  20458   } |  19302   } | 
|  20459   if (class_id == kTwoByteStringCid) { |  19303   if (class_id == kTwoByteStringCid) { | 
|  20460     return TwoByteString::CharAt(*this, index); |  19304     return TwoByteString::CharAt(*this, index); | 
|  20461   } |  19305   } | 
|  20462   if (class_id == kExternalOneByteStringCid) { |  19306   if (class_id == kExternalOneByteStringCid) { | 
|  20463     return ExternalOneByteString::CharAt(*this, index); |  19307     return ExternalOneByteString::CharAt(*this, index); | 
|  20464   } |  19308   } | 
|  20465   ASSERT(class_id == kExternalTwoByteStringCid); |  19309   ASSERT(class_id == kExternalTwoByteStringCid); | 
|  20466   return ExternalTwoByteString::CharAt(*this, index); |  19310   return ExternalTwoByteString::CharAt(*this, index); | 
|  20467 } |  19311 } | 
|  20468  |  19312  | 
|  20469  |  | 
|  20470 Scanner::CharAtFunc String::CharAtFunc() const { |  19313 Scanner::CharAtFunc String::CharAtFunc() const { | 
|  20471   intptr_t class_id = raw()->GetClassId(); |  19314   intptr_t class_id = raw()->GetClassId(); | 
|  20472   ASSERT(RawObject::IsStringClassId(class_id)); |  19315   ASSERT(RawObject::IsStringClassId(class_id)); | 
|  20473   if (class_id == kOneByteStringCid) { |  19316   if (class_id == kOneByteStringCid) { | 
|  20474     return &OneByteString::CharAt; |  19317     return &OneByteString::CharAt; | 
|  20475   } |  19318   } | 
|  20476   if (class_id == kTwoByteStringCid) { |  19319   if (class_id == kTwoByteStringCid) { | 
|  20477     return &TwoByteString::CharAt; |  19320     return &TwoByteString::CharAt; | 
|  20478   } |  19321   } | 
|  20479   if (class_id == kExternalOneByteStringCid) { |  19322   if (class_id == kExternalOneByteStringCid) { | 
|  20480     return &ExternalOneByteString::CharAt; |  19323     return &ExternalOneByteString::CharAt; | 
|  20481   } |  19324   } | 
|  20482   ASSERT(class_id == kExternalTwoByteStringCid); |  19325   ASSERT(class_id == kExternalTwoByteStringCid); | 
|  20483   return &ExternalTwoByteString::CharAt; |  19326   return &ExternalTwoByteString::CharAt; | 
|  20484 } |  19327 } | 
|  20485  |  19328  | 
|  20486  |  | 
|  20487 intptr_t String::CharSize() const { |  19329 intptr_t String::CharSize() const { | 
|  20488   intptr_t class_id = raw()->GetClassId(); |  19330   intptr_t class_id = raw()->GetClassId(); | 
|  20489   if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { |  19331   if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { | 
|  20490     return kOneByteChar; |  19332     return kOneByteChar; | 
|  20491   } |  19333   } | 
|  20492   ASSERT(class_id == kTwoByteStringCid || |  19334   ASSERT(class_id == kTwoByteStringCid || | 
|  20493          class_id == kExternalTwoByteStringCid); |  19335          class_id == kExternalTwoByteStringCid); | 
|  20494   return kTwoByteChar; |  19336   return kTwoByteChar; | 
|  20495 } |  19337 } | 
|  20496  |  19338  | 
|  20497  |  | 
|  20498 void* String::GetPeer() const { |  19339 void* String::GetPeer() const { | 
|  20499   intptr_t class_id = raw()->GetClassId(); |  19340   intptr_t class_id = raw()->GetClassId(); | 
|  20500   if (class_id == kExternalOneByteStringCid) { |  19341   if (class_id == kExternalOneByteStringCid) { | 
|  20501     return ExternalOneByteString::GetPeer(*this); |  19342     return ExternalOneByteString::GetPeer(*this); | 
|  20502   } |  19343   } | 
|  20503   ASSERT(class_id == kExternalTwoByteStringCid); |  19344   ASSERT(class_id == kExternalTwoByteStringCid); | 
|  20504   return ExternalTwoByteString::GetPeer(*this); |  19345   return ExternalTwoByteString::GetPeer(*this); | 
|  20505 } |  19346 } | 
|  20506  |  19347  | 
|  20507  |  | 
|  20508 bool String::Equals(const Instance& other) const { |  19348 bool String::Equals(const Instance& other) const { | 
|  20509   if (this->raw() == other.raw()) { |  19349   if (this->raw() == other.raw()) { | 
|  20510     // Both handles point to the same raw instance. |  19350     // Both handles point to the same raw instance. | 
|  20511     return true; |  19351     return true; | 
|  20512   } |  19352   } | 
|  20513  |  19353  | 
|  20514   if (!other.IsString()) { |  19354   if (!other.IsString()) { | 
|  20515     return false; |  19355     return false; | 
|  20516   } |  19356   } | 
|  20517  |  19357  | 
|  20518   const String& other_string = String::Cast(other); |  19358   const String& other_string = String::Cast(other); | 
|  20519   return Equals(other_string); |  19359   return Equals(other_string); | 
|  20520 } |  19360 } | 
|  20521  |  19361  | 
|  20522  |  | 
|  20523 bool String::Equals(const String& str, |  19362 bool String::Equals(const String& str, | 
|  20524                     intptr_t begin_index, |  19363                     intptr_t begin_index, | 
|  20525                     intptr_t len) const { |  19364                     intptr_t len) const { | 
|  20526   ASSERT(begin_index >= 0); |  19365   ASSERT(begin_index >= 0); | 
|  20527   ASSERT((begin_index == 0) || (begin_index < str.Length())); |  19366   ASSERT((begin_index == 0) || (begin_index < str.Length())); | 
|  20528   ASSERT(len >= 0); |  19367   ASSERT(len >= 0); | 
|  20529   ASSERT(len <= str.Length()); |  19368   ASSERT(len <= str.Length()); | 
|  20530   if (len != this->Length()) { |  19369   if (len != this->Length()) { | 
|  20531     return false;  // Lengths don't match. |  19370     return false;  // Lengths don't match. | 
|  20532   } |  19371   } | 
|  20533  |  19372  | 
|  20534   Scanner::CharAtFunc this_char_at_func = this->CharAtFunc(); |  19373   Scanner::CharAtFunc this_char_at_func = this->CharAtFunc(); | 
|  20535   Scanner::CharAtFunc str_char_at_func = str.CharAtFunc(); |  19374   Scanner::CharAtFunc str_char_at_func = str.CharAtFunc(); | 
|  20536   for (intptr_t i = 0; i < len; i++) { |  19375   for (intptr_t i = 0; i < len; i++) { | 
|  20537     if (this_char_at_func(*this, i) != str_char_at_func(str, begin_index + i)) { |  19376     if (this_char_at_func(*this, i) != str_char_at_func(str, begin_index + i)) { | 
|  20538       return false; |  19377       return false; | 
|  20539     } |  19378     } | 
|  20540   } |  19379   } | 
|  20541  |  19380  | 
|  20542   return true; |  19381   return true; | 
|  20543 } |  19382 } | 
|  20544  |  19383  | 
|  20545  |  | 
|  20546 bool String::Equals(const char* cstr) const { |  19384 bool String::Equals(const char* cstr) const { | 
|  20547   ASSERT(cstr != NULL); |  19385   ASSERT(cstr != NULL); | 
|  20548   CodePointIterator it(*this); |  19386   CodePointIterator it(*this); | 
|  20549   intptr_t len = strlen(cstr); |  19387   intptr_t len = strlen(cstr); | 
|  20550   while (it.Next()) { |  19388   while (it.Next()) { | 
|  20551     if (*cstr == '\0') { |  19389     if (*cstr == '\0') { | 
|  20552       // Lengths don't match. |  19390       // Lengths don't match. | 
|  20553       return false; |  19391       return false; | 
|  20554     } |  19392     } | 
|  20555     int32_t ch; |  19393     int32_t ch; | 
|  20556     intptr_t consumed = |  19394     intptr_t consumed = | 
|  20557         Utf8::Decode(reinterpret_cast<const uint8_t*>(cstr), len, &ch); |  19395         Utf8::Decode(reinterpret_cast<const uint8_t*>(cstr), len, &ch); | 
|  20558     if (consumed == 0 || it.Current() != ch) { |  19396     if (consumed == 0 || it.Current() != ch) { | 
|  20559       return false; |  19397       return false; | 
|  20560     } |  19398     } | 
|  20561     cstr += consumed; |  19399     cstr += consumed; | 
|  20562     len -= consumed; |  19400     len -= consumed; | 
|  20563   } |  19401   } | 
|  20564   return *cstr == '\0'; |  19402   return *cstr == '\0'; | 
|  20565 } |  19403 } | 
|  20566  |  19404  | 
|  20567  |  | 
|  20568 bool String::Equals(const uint8_t* latin1_array, intptr_t len) const { |  19405 bool String::Equals(const uint8_t* latin1_array, intptr_t len) const { | 
|  20569   if (len != this->Length()) { |  19406   if (len != this->Length()) { | 
|  20570     // Lengths don't match. |  19407     // Lengths don't match. | 
|  20571     return false; |  19408     return false; | 
|  20572   } |  19409   } | 
|  20573  |  19410  | 
|  20574   for (intptr_t i = 0; i < len; i++) { |  19411   for (intptr_t i = 0; i < len; i++) { | 
|  20575     if (this->CharAt(i) != latin1_array[i]) { |  19412     if (this->CharAt(i) != latin1_array[i]) { | 
|  20576       return false; |  19413       return false; | 
|  20577     } |  19414     } | 
|  20578   } |  19415   } | 
|  20579   return true; |  19416   return true; | 
|  20580 } |  19417 } | 
|  20581  |  19418  | 
|  20582  |  | 
|  20583 bool String::Equals(const uint16_t* utf16_array, intptr_t len) const { |  19419 bool String::Equals(const uint16_t* utf16_array, intptr_t len) const { | 
|  20584   if (len != this->Length()) { |  19420   if (len != this->Length()) { | 
|  20585     // Lengths don't match. |  19421     // Lengths don't match. | 
|  20586     return false; |  19422     return false; | 
|  20587   } |  19423   } | 
|  20588  |  19424  | 
|  20589   for (intptr_t i = 0; i < len; i++) { |  19425   for (intptr_t i = 0; i < len; i++) { | 
|  20590     if (this->CharAt(i) != utf16_array[i]) { |  19426     if (this->CharAt(i) != utf16_array[i]) { | 
|  20591       return false; |  19427       return false; | 
|  20592     } |  19428     } | 
|  20593   } |  19429   } | 
|  20594   return true; |  19430   return true; | 
|  20595 } |  19431 } | 
|  20596  |  19432  | 
|  20597  |  | 
|  20598 bool String::Equals(const int32_t* utf32_array, intptr_t len) const { |  19433 bool String::Equals(const int32_t* utf32_array, intptr_t len) const { | 
|  20599   if (len < 0) return false; |  19434   if (len < 0) return false; | 
|  20600   intptr_t j = 0; |  19435   intptr_t j = 0; | 
|  20601   for (intptr_t i = 0; i < len; ++i) { |  19436   for (intptr_t i = 0; i < len; ++i) { | 
|  20602     if (Utf::IsSupplementary(utf32_array[i])) { |  19437     if (Utf::IsSupplementary(utf32_array[i])) { | 
|  20603       uint16_t encoded[2]; |  19438       uint16_t encoded[2]; | 
|  20604       Utf16::Encode(utf32_array[i], &encoded[0]); |  19439       Utf16::Encode(utf32_array[i], &encoded[0]); | 
|  20605       if (j + 1 >= Length()) return false; |  19440       if (j + 1 >= Length()) return false; | 
|  20606       if (CharAt(j++) != encoded[0]) return false; |  19441       if (CharAt(j++) != encoded[0]) return false; | 
|  20607       if (CharAt(j++) != encoded[1]) return false; |  19442       if (CharAt(j++) != encoded[1]) return false; | 
|  20608     } else { |  19443     } else { | 
|  20609       if (j >= Length()) return false; |  19444       if (j >= Length()) return false; | 
|  20610       if (CharAt(j++) != utf32_array[i]) return false; |  19445       if (CharAt(j++) != utf32_array[i]) return false; | 
|  20611     } |  19446     } | 
|  20612   } |  19447   } | 
|  20613   return j == Length(); |  19448   return j == Length(); | 
|  20614 } |  19449 } | 
|  20615  |  19450  | 
|  20616  |  | 
|  20617 bool String::EqualsConcat(const String& str1, const String& str2) const { |  19451 bool String::EqualsConcat(const String& str1, const String& str2) const { | 
|  20618   return (Length() == str1.Length() + str2.Length()) && |  19452   return (Length() == str1.Length() + str2.Length()) && | 
|  20619          str1.Equals(*this, 0, str1.Length()) && |  19453          str1.Equals(*this, 0, str1.Length()) && | 
|  20620          str2.Equals(*this, str1.Length(), str2.Length()); |  19454          str2.Equals(*this, str1.Length(), str2.Length()); | 
|  20621 } |  19455 } | 
|  20622  |  19456  | 
|  20623  |  | 
|  20624 intptr_t String::CompareTo(const String& other) const { |  19457 intptr_t String::CompareTo(const String& other) const { | 
|  20625   const intptr_t this_len = this->Length(); |  19458   const intptr_t this_len = this->Length(); | 
|  20626   const intptr_t other_len = other.IsNull() ? 0 : other.Length(); |  19459   const intptr_t other_len = other.IsNull() ? 0 : other.Length(); | 
|  20627   const intptr_t len = (this_len < other_len) ? this_len : other_len; |  19460   const intptr_t len = (this_len < other_len) ? this_len : other_len; | 
|  20628   for (intptr_t i = 0; i < len; i++) { |  19461   for (intptr_t i = 0; i < len; i++) { | 
|  20629     uint16_t this_code_unit = this->CharAt(i); |  19462     uint16_t this_code_unit = this->CharAt(i); | 
|  20630     uint16_t other_code_unit = other.CharAt(i); |  19463     uint16_t other_code_unit = other.CharAt(i); | 
|  20631     if (this_code_unit < other_code_unit) { |  19464     if (this_code_unit < other_code_unit) { | 
|  20632       return -1; |  19465       return -1; | 
|  20633     } |  19466     } | 
|  20634     if (this_code_unit > other_code_unit) { |  19467     if (this_code_unit > other_code_unit) { | 
|  20635       return 1; |  19468       return 1; | 
|  20636     } |  19469     } | 
|  20637   } |  19470   } | 
|  20638   if (this_len < other_len) return -1; |  19471   if (this_len < other_len) return -1; | 
|  20639   if (this_len > other_len) return 1; |  19472   if (this_len > other_len) return 1; | 
|  20640   return 0; |  19473   return 0; | 
|  20641 } |  19474 } | 
|  20642  |  19475  | 
|  20643  |  | 
|  20644 bool String::StartsWith(const String& other) const { |  19476 bool String::StartsWith(const String& other) const { | 
|  20645   if (other.IsNull() || (other.Length() > this->Length())) { |  19477   if (other.IsNull() || (other.Length() > this->Length())) { | 
|  20646     return false; |  19478     return false; | 
|  20647   } |  19479   } | 
|  20648   intptr_t slen = other.Length(); |  19480   intptr_t slen = other.Length(); | 
|  20649   for (int i = 0; i < slen; i++) { |  19481   for (int i = 0; i < slen; i++) { | 
|  20650     if (this->CharAt(i) != other.CharAt(i)) { |  19482     if (this->CharAt(i) != other.CharAt(i)) { | 
|  20651       return false; |  19483       return false; | 
|  20652     } |  19484     } | 
|  20653   } |  19485   } | 
|  20654   return true; |  19486   return true; | 
|  20655 } |  19487 } | 
|  20656  |  19488  | 
|  20657  |  | 
|  20658 RawInstance* String::CheckAndCanonicalize(Thread* thread, |  19489 RawInstance* String::CheckAndCanonicalize(Thread* thread, | 
|  20659                                           const char** error_str) const { |  19490                                           const char** error_str) const { | 
|  20660   if (IsCanonical()) { |  19491   if (IsCanonical()) { | 
|  20661     return this->raw(); |  19492     return this->raw(); | 
|  20662   } |  19493   } | 
|  20663   return Symbols::New(Thread::Current(), *this); |  19494   return Symbols::New(Thread::Current(), *this); | 
|  20664 } |  19495 } | 
|  20665  |  19496  | 
|  20666  |  | 
|  20667 #if defined(DEBUG) |  19497 #if defined(DEBUG) | 
|  20668 bool String::CheckIsCanonical(Thread* thread) const { |  19498 bool String::CheckIsCanonical(Thread* thread) const { | 
|  20669   Zone* zone = thread->zone(); |  19499   Zone* zone = thread->zone(); | 
|  20670   const String& str = String::Handle(zone, Symbols::Lookup(thread, *this)); |  19500   const String& str = String::Handle(zone, Symbols::Lookup(thread, *this)); | 
|  20671   return (str.raw() == this->raw()); |  19501   return (str.raw() == this->raw()); | 
|  20672 } |  19502 } | 
|  20673 #endif  // DEBUG |  19503 #endif  // DEBUG | 
|  20674  |  19504  | 
|  20675  |  | 
|  20676 RawString* String::New(const char* cstr, Heap::Space space) { |  19505 RawString* String::New(const char* cstr, Heap::Space space) { | 
|  20677   ASSERT(cstr != NULL); |  19506   ASSERT(cstr != NULL); | 
|  20678   intptr_t array_len = strlen(cstr); |  19507   intptr_t array_len = strlen(cstr); | 
|  20679   const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); |  19508   const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); | 
|  20680   return String::FromUTF8(utf8_array, array_len, space); |  19509   return String::FromUTF8(utf8_array, array_len, space); | 
|  20681 } |  19510 } | 
|  20682  |  19511  | 
|  20683  |  | 
|  20684 RawString* String::FromUTF8(const uint8_t* utf8_array, |  19512 RawString* String::FromUTF8(const uint8_t* utf8_array, | 
|  20685                             intptr_t array_len, |  19513                             intptr_t array_len, | 
|  20686                             Heap::Space space) { |  19514                             Heap::Space space) { | 
|  20687   Utf8::Type type; |  19515   Utf8::Type type; | 
|  20688   intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); |  19516   intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); | 
|  20689   if (type == Utf8::kLatin1) { |  19517   if (type == Utf8::kLatin1) { | 
|  20690     const String& strobj = String::Handle(OneByteString::New(len, space)); |  19518     const String& strobj = String::Handle(OneByteString::New(len, space)); | 
|  20691     if (len > 0) { |  19519     if (len > 0) { | 
|  20692       NoSafepointScope no_safepoint; |  19520       NoSafepointScope no_safepoint; | 
|  20693       Utf8::DecodeToLatin1(utf8_array, array_len, |  19521       Utf8::DecodeToLatin1(utf8_array, array_len, | 
|  20694                            OneByteString::CharAddr(strobj, 0), len); |  19522                            OneByteString::CharAddr(strobj, 0), len); | 
|  20695     } |  19523     } | 
|  20696     return strobj.raw(); |  19524     return strobj.raw(); | 
|  20697   } |  19525   } | 
|  20698   ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); |  19526   ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); | 
|  20699   const String& strobj = String::Handle(TwoByteString::New(len, space)); |  19527   const String& strobj = String::Handle(TwoByteString::New(len, space)); | 
|  20700   NoSafepointScope no_safepoint; |  19528   NoSafepointScope no_safepoint; | 
|  20701   Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::CharAddr(strobj, 0), |  19529   Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::CharAddr(strobj, 0), | 
|  20702                       len); |  19530                       len); | 
|  20703   return strobj.raw(); |  19531   return strobj.raw(); | 
|  20704 } |  19532 } | 
|  20705  |  19533  | 
|  20706  |  | 
|  20707 RawString* String::FromLatin1(const uint8_t* latin1_array, |  19534 RawString* String::FromLatin1(const uint8_t* latin1_array, | 
|  20708                               intptr_t array_len, |  19535                               intptr_t array_len, | 
|  20709                               Heap::Space space) { |  19536                               Heap::Space space) { | 
|  20710   return OneByteString::New(latin1_array, array_len, space); |  19537   return OneByteString::New(latin1_array, array_len, space); | 
|  20711 } |  19538 } | 
|  20712  |  19539  | 
|  20713  |  | 
|  20714 RawString* String::FromUTF16(const uint16_t* utf16_array, |  19540 RawString* String::FromUTF16(const uint16_t* utf16_array, | 
|  20715                              intptr_t array_len, |  19541                              intptr_t array_len, | 
|  20716                              Heap::Space space) { |  19542                              Heap::Space space) { | 
|  20717   bool is_one_byte_string = true; |  19543   bool is_one_byte_string = true; | 
|  20718   for (intptr_t i = 0; i < array_len; ++i) { |  19544   for (intptr_t i = 0; i < array_len; ++i) { | 
|  20719     if (!Utf::IsLatin1(utf16_array[i])) { |  19545     if (!Utf::IsLatin1(utf16_array[i])) { | 
|  20720       is_one_byte_string = false; |  19546       is_one_byte_string = false; | 
|  20721       break; |  19547       break; | 
|  20722     } |  19548     } | 
|  20723   } |  19549   } | 
|  20724   if (is_one_byte_string) { |  19550   if (is_one_byte_string) { | 
|  20725     return OneByteString::New(utf16_array, array_len, space); |  19551     return OneByteString::New(utf16_array, array_len, space); | 
|  20726   } |  19552   } | 
|  20727   return TwoByteString::New(utf16_array, array_len, space); |  19553   return TwoByteString::New(utf16_array, array_len, space); | 
|  20728 } |  19554 } | 
|  20729  |  19555  | 
|  20730  |  | 
|  20731 RawString* String::FromUTF32(const int32_t* utf32_array, |  19556 RawString* String::FromUTF32(const int32_t* utf32_array, | 
|  20732                              intptr_t array_len, |  19557                              intptr_t array_len, | 
|  20733                              Heap::Space space) { |  19558                              Heap::Space space) { | 
|  20734   bool is_one_byte_string = true; |  19559   bool is_one_byte_string = true; | 
|  20735   intptr_t utf16_len = array_len; |  19560   intptr_t utf16_len = array_len; | 
|  20736   for (intptr_t i = 0; i < array_len; ++i) { |  19561   for (intptr_t i = 0; i < array_len; ++i) { | 
|  20737     if (!Utf::IsLatin1(utf32_array[i])) { |  19562     if (!Utf::IsLatin1(utf32_array[i])) { | 
|  20738       is_one_byte_string = false; |  19563       is_one_byte_string = false; | 
|  20739       if (Utf::IsSupplementary(utf32_array[i])) { |  19564       if (Utf::IsSupplementary(utf32_array[i])) { | 
|  20740         utf16_len += 1; |  19565         utf16_len += 1; | 
|  20741       } |  19566       } | 
|  20742     } |  19567     } | 
|  20743   } |  19568   } | 
|  20744   if (is_one_byte_string) { |  19569   if (is_one_byte_string) { | 
|  20745     return OneByteString::New(utf32_array, array_len, space); |  19570     return OneByteString::New(utf32_array, array_len, space); | 
|  20746   } |  19571   } | 
|  20747   return TwoByteString::New(utf16_len, utf32_array, array_len, space); |  19572   return TwoByteString::New(utf16_len, utf32_array, array_len, space); | 
|  20748 } |  19573 } | 
|  20749  |  19574  | 
|  20750  |  | 
|  20751 RawString* String::New(const String& str, Heap::Space space) { |  19575 RawString* String::New(const String& str, Heap::Space space) { | 
|  20752   // Currently this just creates a copy of the string in the correct space. |  19576   // Currently this just creates a copy of the string in the correct space. | 
|  20753   // Once we have external string support, this will also create a heap copy of |  19577   // Once we have external string support, this will also create a heap copy of | 
|  20754   // the string if necessary. Some optimizations are possible, such as not |  19578   // the string if necessary. Some optimizations are possible, such as not | 
|  20755   // copying internal strings into the same space. |  19579   // copying internal strings into the same space. | 
|  20756   intptr_t len = str.Length(); |  19580   intptr_t len = str.Length(); | 
|  20757   String& result = String::Handle(); |  19581   String& result = String::Handle(); | 
|  20758   intptr_t char_size = str.CharSize(); |  19582   intptr_t char_size = str.CharSize(); | 
|  20759   if (char_size == kOneByteChar) { |  19583   if (char_size == kOneByteChar) { | 
|  20760     result = OneByteString::New(len, space); |  19584     result = OneByteString::New(len, space); | 
|  20761   } else { |  19585   } else { | 
|  20762     ASSERT(char_size == kTwoByteChar); |  19586     ASSERT(char_size == kTwoByteChar); | 
|  20763     result = TwoByteString::New(len, space); |  19587     result = TwoByteString::New(len, space); | 
|  20764   } |  19588   } | 
|  20765   String::Copy(result, 0, str, 0, len); |  19589   String::Copy(result, 0, str, 0, len); | 
|  20766   return result.raw(); |  19590   return result.raw(); | 
|  20767 } |  19591 } | 
|  20768  |  19592  | 
|  20769  |  | 
|  20770 RawString* String::NewExternal(const uint8_t* characters, |  19593 RawString* String::NewExternal(const uint8_t* characters, | 
|  20771                                intptr_t len, |  19594                                intptr_t len, | 
|  20772                                void* peer, |  19595                                void* peer, | 
|  20773                                Dart_PeerFinalizer callback, |  19596                                Dart_PeerFinalizer callback, | 
|  20774                                Heap::Space space) { |  19597                                Heap::Space space) { | 
|  20775   return ExternalOneByteString::New(characters, len, peer, callback, space); |  19598   return ExternalOneByteString::New(characters, len, peer, callback, space); | 
|  20776 } |  19599 } | 
|  20777  |  19600  | 
|  20778  |  | 
|  20779 RawString* String::NewExternal(const uint16_t* characters, |  19601 RawString* String::NewExternal(const uint16_t* characters, | 
|  20780                                intptr_t len, |  19602                                intptr_t len, | 
|  20781                                void* peer, |  19603                                void* peer, | 
|  20782                                Dart_PeerFinalizer callback, |  19604                                Dart_PeerFinalizer callback, | 
|  20783                                Heap::Space space) { |  19605                                Heap::Space space) { | 
|  20784   return ExternalTwoByteString::New(characters, len, peer, callback, space); |  19606   return ExternalTwoByteString::New(characters, len, peer, callback, space); | 
|  20785 } |  19607 } | 
|  20786  |  19608  | 
|  20787  |  | 
|  20788 void String::Copy(const String& dst, |  19609 void String::Copy(const String& dst, | 
|  20789                   intptr_t dst_offset, |  19610                   intptr_t dst_offset, | 
|  20790                   const uint8_t* characters, |  19611                   const uint8_t* characters, | 
|  20791                   intptr_t len) { |  19612                   intptr_t len) { | 
|  20792   ASSERT(dst_offset >= 0); |  19613   ASSERT(dst_offset >= 0); | 
|  20793   ASSERT(len >= 0); |  19614   ASSERT(len >= 0); | 
|  20794   ASSERT(len <= (dst.Length() - dst_offset)); |  19615   ASSERT(len <= (dst.Length() - dst_offset)); | 
|  20795   if (dst.IsOneByteString()) { |  19616   if (dst.IsOneByteString()) { | 
|  20796     NoSafepointScope no_safepoint; |  19617     NoSafepointScope no_safepoint; | 
|  20797     if (len > 0) { |  19618     if (len > 0) { | 
|  20798       memmove(OneByteString::CharAddr(dst, dst_offset), characters, len); |  19619       memmove(OneByteString::CharAddr(dst, dst_offset), characters, len); | 
|  20799     } |  19620     } | 
|  20800   } else if (dst.IsTwoByteString()) { |  19621   } else if (dst.IsTwoByteString()) { | 
|  20801     for (intptr_t i = 0; i < len; ++i) { |  19622     for (intptr_t i = 0; i < len; ++i) { | 
|  20802       *TwoByteString::CharAddr(dst, i + dst_offset) = characters[i]; |  19623       *TwoByteString::CharAddr(dst, i + dst_offset) = characters[i]; | 
|  20803     } |  19624     } | 
|  20804   } |  19625   } | 
|  20805 } |  19626 } | 
|  20806  |  19627  | 
|  20807  |  | 
|  20808 void String::Copy(const String& dst, |  19628 void String::Copy(const String& dst, | 
|  20809                   intptr_t dst_offset, |  19629                   intptr_t dst_offset, | 
|  20810                   const uint16_t* utf16_array, |  19630                   const uint16_t* utf16_array, | 
|  20811                   intptr_t array_len) { |  19631                   intptr_t array_len) { | 
|  20812   ASSERT(dst_offset >= 0); |  19632   ASSERT(dst_offset >= 0); | 
|  20813   ASSERT(array_len >= 0); |  19633   ASSERT(array_len >= 0); | 
|  20814   ASSERT(array_len <= (dst.Length() - dst_offset)); |  19634   ASSERT(array_len <= (dst.Length() - dst_offset)); | 
|  20815   if (dst.IsOneByteString()) { |  19635   if (dst.IsOneByteString()) { | 
|  20816     NoSafepointScope no_safepoint; |  19636     NoSafepointScope no_safepoint; | 
|  20817     for (intptr_t i = 0; i < array_len; ++i) { |  19637     for (intptr_t i = 0; i < array_len; ++i) { | 
|  20818       ASSERT(Utf::IsLatin1(utf16_array[i])); |  19638       ASSERT(Utf::IsLatin1(utf16_array[i])); | 
|  20819       *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; |  19639       *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i]; | 
|  20820     } |  19640     } | 
|  20821   } else { |  19641   } else { | 
|  20822     ASSERT(dst.IsTwoByteString()); |  19642     ASSERT(dst.IsTwoByteString()); | 
|  20823     NoSafepointScope no_safepoint; |  19643     NoSafepointScope no_safepoint; | 
|  20824     if (array_len > 0) { |  19644     if (array_len > 0) { | 
|  20825       memmove(TwoByteString::CharAddr(dst, dst_offset), utf16_array, |  19645       memmove(TwoByteString::CharAddr(dst, dst_offset), utf16_array, | 
|  20826               array_len * 2); |  19646               array_len * 2); | 
|  20827     } |  19647     } | 
|  20828   } |  19648   } | 
|  20829 } |  19649 } | 
|  20830  |  19650  | 
|  20831  |  | 
|  20832 void String::Copy(const String& dst, |  19651 void String::Copy(const String& dst, | 
|  20833                   intptr_t dst_offset, |  19652                   intptr_t dst_offset, | 
|  20834                   const String& src, |  19653                   const String& src, | 
|  20835                   intptr_t src_offset, |  19654                   intptr_t src_offset, | 
|  20836                   intptr_t len) { |  19655                   intptr_t len) { | 
|  20837   ASSERT(dst_offset >= 0); |  19656   ASSERT(dst_offset >= 0); | 
|  20838   ASSERT(src_offset >= 0); |  19657   ASSERT(src_offset >= 0); | 
|  20839   ASSERT(len >= 0); |  19658   ASSERT(len >= 0); | 
|  20840   ASSERT(len <= (dst.Length() - dst_offset)); |  19659   ASSERT(len <= (dst.Length() - dst_offset)); | 
|  20841   ASSERT(len <= (src.Length() - src_offset)); |  19660   ASSERT(len <= (src.Length() - src_offset)); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  20861       } else { |  19680       } else { | 
|  20862         ASSERT(src.IsExternalTwoByteString()); |  19681         ASSERT(src.IsExternalTwoByteString()); | 
|  20863         NoSafepointScope no_safepoint; |  19682         NoSafepointScope no_safepoint; | 
|  20864         String::Copy(dst, dst_offset, |  19683         String::Copy(dst, dst_offset, | 
|  20865                      ExternalTwoByteString::CharAddr(src, src_offset), len); |  19684                      ExternalTwoByteString::CharAddr(src, src_offset), len); | 
|  20866       } |  19685       } | 
|  20867     } |  19686     } | 
|  20868   } |  19687   } | 
|  20869 } |  19688 } | 
|  20870  |  19689  | 
|  20871  |  | 
|  20872 RawString* String::EscapeSpecialCharacters(const String& str) { |  19690 RawString* String::EscapeSpecialCharacters(const String& str) { | 
|  20873   if (str.IsOneByteString()) { |  19691   if (str.IsOneByteString()) { | 
|  20874     return OneByteString::EscapeSpecialCharacters(str); |  19692     return OneByteString::EscapeSpecialCharacters(str); | 
|  20875   } |  19693   } | 
|  20876   if (str.IsTwoByteString()) { |  19694   if (str.IsTwoByteString()) { | 
|  20877     return TwoByteString::EscapeSpecialCharacters(str); |  19695     return TwoByteString::EscapeSpecialCharacters(str); | 
|  20878   } |  19696   } | 
|  20879   if (str.IsExternalOneByteString()) { |  19697   if (str.IsExternalOneByteString()) { | 
|  20880     return ExternalOneByteString::EscapeSpecialCharacters(str); |  19698     return ExternalOneByteString::EscapeSpecialCharacters(str); | 
|  20881   } |  19699   } | 
|  20882   ASSERT(str.IsExternalTwoByteString()); |  19700   ASSERT(str.IsExternalTwoByteString()); | 
|  20883   // If EscapeSpecialCharacters is frequently called on external two byte |  19701   // If EscapeSpecialCharacters is frequently called on external two byte | 
|  20884   // strings, we should implement it directly on ExternalTwoByteString rather |  19702   // strings, we should implement it directly on ExternalTwoByteString rather | 
|  20885   // than first converting to a TwoByteString. |  19703   // than first converting to a TwoByteString. | 
|  20886   return TwoByteString::EscapeSpecialCharacters( |  19704   return TwoByteString::EscapeSpecialCharacters( | 
|  20887       String::Handle(TwoByteString::New(str, Heap::kNew))); |  19705       String::Handle(TwoByteString::New(str, Heap::kNew))); | 
|  20888 } |  19706 } | 
|  20889  |  19707  | 
|  20890  |  | 
|  20891 static bool IsPercent(int32_t c) { |  19708 static bool IsPercent(int32_t c) { | 
|  20892   return c == '%'; |  19709   return c == '%'; | 
|  20893 } |  19710 } | 
|  20894  |  19711  | 
|  20895  |  | 
|  20896 static bool IsHexCharacter(int32_t c) { |  19712 static bool IsHexCharacter(int32_t c) { | 
|  20897   if (c >= '0' && c <= '9') { |  19713   if (c >= '0' && c <= '9') { | 
|  20898     return true; |  19714     return true; | 
|  20899   } |  19715   } | 
|  20900   if (c >= 'A' && c <= 'F') { |  19716   if (c >= 'A' && c <= 'F') { | 
|  20901     return true; |  19717     return true; | 
|  20902   } |  19718   } | 
|  20903   return false; |  19719   return false; | 
|  20904 } |  19720 } | 
|  20905  |  19721  | 
|  20906  |  | 
|  20907 static bool IsURISafeCharacter(int32_t c) { |  19722 static bool IsURISafeCharacter(int32_t c) { | 
|  20908   if ((c >= '0') && (c <= '9')) { |  19723   if ((c >= '0') && (c <= '9')) { | 
|  20909     return true; |  19724     return true; | 
|  20910   } |  19725   } | 
|  20911   if ((c >= 'a') && (c <= 'z')) { |  19726   if ((c >= 'a') && (c <= 'z')) { | 
|  20912     return true; |  19727     return true; | 
|  20913   } |  19728   } | 
|  20914   if ((c >= 'A') && (c <= 'Z')) { |  19729   if ((c >= 'A') && (c <= 'Z')) { | 
|  20915     return true; |  19730     return true; | 
|  20916   } |  19731   } | 
|  20917   return (c == '-') || (c == '_') || (c == '.') || (c == '~'); |  19732   return (c == '-') || (c == '_') || (c == '.') || (c == '~'); | 
|  20918 } |  19733 } | 
|  20919  |  19734  | 
|  20920  |  | 
|  20921 static int32_t GetHexCharacter(int32_t c) { |  19735 static int32_t GetHexCharacter(int32_t c) { | 
|  20922   ASSERT(c >= 0); |  19736   ASSERT(c >= 0); | 
|  20923   ASSERT(c < 16); |  19737   ASSERT(c < 16); | 
|  20924   const char* hex = "0123456789ABCDEF"; |  19738   const char* hex = "0123456789ABCDEF"; | 
|  20925   return hex[c]; |  19739   return hex[c]; | 
|  20926 } |  19740 } | 
|  20927  |  19741  | 
|  20928  |  | 
|  20929 static int32_t GetHexValue(int32_t c) { |  19742 static int32_t GetHexValue(int32_t c) { | 
|  20930   if (c >= '0' && c <= '9') { |  19743   if (c >= '0' && c <= '9') { | 
|  20931     return c - '0'; |  19744     return c - '0'; | 
|  20932   } |  19745   } | 
|  20933   if (c >= 'A' && c <= 'F') { |  19746   if (c >= 'A' && c <= 'F') { | 
|  20934     return c - 'A' + 10; |  19747     return c - 'A' + 10; | 
|  20935   } |  19748   } | 
|  20936   UNREACHABLE(); |  19749   UNREACHABLE(); | 
|  20937   return 0; |  19750   return 0; | 
|  20938 } |  19751 } | 
|  20939  |  19752  | 
|  20940  |  | 
|  20941 static int32_t MergeHexCharacters(int32_t c1, int32_t c2) { |  19753 static int32_t MergeHexCharacters(int32_t c1, int32_t c2) { | 
|  20942   return GetHexValue(c1) << 4 | GetHexValue(c2); |  19754   return GetHexValue(c1) << 4 | GetHexValue(c2); | 
|  20943 } |  19755 } | 
|  20944  |  19756  | 
|  20945  |  | 
|  20946 const char* String::EncodeIRI(const String& str) { |  19757 const char* String::EncodeIRI(const String& str) { | 
|  20947   const intptr_t len = Utf8::Length(str); |  19758   const intptr_t len = Utf8::Length(str); | 
|  20948   Zone* zone = Thread::Current()->zone(); |  19759   Zone* zone = Thread::Current()->zone(); | 
|  20949   uint8_t* utf8 = zone->Alloc<uint8_t>(len); |  19760   uint8_t* utf8 = zone->Alloc<uint8_t>(len); | 
|  20950   str.ToUTF8(utf8, len); |  19761   str.ToUTF8(utf8, len); | 
|  20951   intptr_t num_escapes = 0; |  19762   intptr_t num_escapes = 0; | 
|  20952   for (int i = 0; i < len; ++i) { |  19763   for (int i = 0; i < len; ++i) { | 
|  20953     uint8_t byte = utf8[i]; |  19764     uint8_t byte = utf8[i]; | 
|  20954     if (!IsURISafeCharacter(byte)) { |  19765     if (!IsURISafeCharacter(byte)) { | 
|  20955       num_escapes += 2; |  19766       num_escapes += 2; | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  20966       cstr[index++] = GetHexCharacter(byte & 0xF); |  19777       cstr[index++] = GetHexCharacter(byte & 0xF); | 
|  20967     } else { |  19778     } else { | 
|  20968       ASSERT(byte <= 127); |  19779       ASSERT(byte <= 127); | 
|  20969       cstr[index++] = byte; |  19780       cstr[index++] = byte; | 
|  20970     } |  19781     } | 
|  20971   } |  19782   } | 
|  20972   cstr[index] = '\0'; |  19783   cstr[index] = '\0'; | 
|  20973   return cstr; |  19784   return cstr; | 
|  20974 } |  19785 } | 
|  20975  |  19786  | 
|  20976  |  | 
|  20977 RawString* String::DecodeIRI(const String& str) { |  19787 RawString* String::DecodeIRI(const String& str) { | 
|  20978   CodePointIterator cpi(str); |  19788   CodePointIterator cpi(str); | 
|  20979   intptr_t num_escapes = 0; |  19789   intptr_t num_escapes = 0; | 
|  20980   intptr_t len = str.Length(); |  19790   intptr_t len = str.Length(); | 
|  20981   { |  19791   { | 
|  20982     CodePointIterator cpi(str); |  19792     CodePointIterator cpi(str); | 
|  20983     while (cpi.Next()) { |  19793     while (cpi.Next()) { | 
|  20984       int32_t code_point = cpi.Current(); |  19794       int32_t code_point = cpi.Current(); | 
|  20985       if (IsPercent(code_point)) { |  19795       if (IsPercent(code_point)) { | 
|  20986         // Verify that the two characters following the % are hex digits. |  19796         // Verify that the two characters following the % are hex digits. | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  21023       } else { |  19833       } else { | 
|  21024         ASSERT(code_point >= 0 && code_point < 256); |  19834         ASSERT(code_point >= 0 && code_point < 256); | 
|  21025         utf8[index] = static_cast<uint8_t>(code_point); |  19835         utf8[index] = static_cast<uint8_t>(code_point); | 
|  21026       } |  19836       } | 
|  21027       index++; |  19837       index++; | 
|  21028     } |  19838     } | 
|  21029   } |  19839   } | 
|  21030   return FromUTF8(utf8, utf8_len); |  19840   return FromUTF8(utf8, utf8_len); | 
|  21031 } |  19841 } | 
|  21032  |  19842  | 
|  21033  |  | 
|  21034 RawString* String::NewFormatted(const char* format, ...) { |  19843 RawString* String::NewFormatted(const char* format, ...) { | 
|  21035   va_list args; |  19844   va_list args; | 
|  21036   va_start(args, format); |  19845   va_start(args, format); | 
|  21037   RawString* result = NewFormattedV(format, args); |  19846   RawString* result = NewFormattedV(format, args); | 
|  21038   NoSafepointScope no_safepoint; |  19847   NoSafepointScope no_safepoint; | 
|  21039   va_end(args); |  19848   va_end(args); | 
|  21040   return result; |  19849   return result; | 
|  21041 } |  19850 } | 
|  21042  |  19851  | 
|  21043  |  | 
|  21044 RawString* String::NewFormatted(Heap::Space space, const char* format, ...) { |  19852 RawString* String::NewFormatted(Heap::Space space, const char* format, ...) { | 
|  21045   va_list args; |  19853   va_list args; | 
|  21046   va_start(args, format); |  19854   va_start(args, format); | 
|  21047   RawString* result = NewFormattedV(format, args, space); |  19855   RawString* result = NewFormattedV(format, args, space); | 
|  21048   NoSafepointScope no_safepoint; |  19856   NoSafepointScope no_safepoint; | 
|  21049   va_end(args); |  19857   va_end(args); | 
|  21050   return result; |  19858   return result; | 
|  21051 } |  19859 } | 
|  21052  |  19860  | 
|  21053  |  | 
|  21054 RawString* String::NewFormattedV(const char* format, |  19861 RawString* String::NewFormattedV(const char* format, | 
|  21055                                  va_list args, |  19862                                  va_list args, | 
|  21056                                  Heap::Space space) { |  19863                                  Heap::Space space) { | 
|  21057   va_list args_copy; |  19864   va_list args_copy; | 
|  21058   va_copy(args_copy, args); |  19865   va_copy(args_copy, args); | 
|  21059   intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); |  19866   intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); | 
|  21060   va_end(args_copy); |  19867   va_end(args_copy); | 
|  21061  |  19868  | 
|  21062   Zone* zone = Thread::Current()->zone(); |  19869   Zone* zone = Thread::Current()->zone(); | 
|  21063   char* buffer = zone->Alloc<char>(len + 1); |  19870   char* buffer = zone->Alloc<char>(len + 1); | 
|  21064   OS::VSNPrint(buffer, (len + 1), format, args); |  19871   OS::VSNPrint(buffer, (len + 1), format, args); | 
|  21065  |  19872  | 
|  21066   return String::New(buffer, space); |  19873   return String::New(buffer, space); | 
|  21067 } |  19874 } | 
|  21068  |  19875  | 
|  21069  |  | 
|  21070 RawString* String::Concat(const String& str1, |  19876 RawString* String::Concat(const String& str1, | 
|  21071                           const String& str2, |  19877                           const String& str2, | 
|  21072                           Heap::Space space) { |  19878                           Heap::Space space) { | 
|  21073   ASSERT(!str1.IsNull() && !str2.IsNull()); |  19879   ASSERT(!str1.IsNull() && !str2.IsNull()); | 
|  21074   intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |  19880   intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); | 
|  21075   if (char_size == kTwoByteChar) { |  19881   if (char_size == kTwoByteChar) { | 
|  21076     return TwoByteString::Concat(str1, str2, space); |  19882     return TwoByteString::Concat(str1, str2, space); | 
|  21077   } |  19883   } | 
|  21078   return OneByteString::Concat(str1, str2, space); |  19884   return OneByteString::Concat(str1, str2, space); | 
|  21079 } |  19885 } | 
|  21080  |  19886  | 
|  21081  |  | 
|  21082 RawString* String::ConcatAll(const Array& strings, Heap::Space space) { |  19887 RawString* String::ConcatAll(const Array& strings, Heap::Space space) { | 
|  21083   return ConcatAllRange(strings, 0, strings.Length(), space); |  19888   return ConcatAllRange(strings, 0, strings.Length(), space); | 
|  21084 } |  19889 } | 
|  21085  |  19890  | 
|  21086  |  | 
|  21087 RawString* String::ConcatAllRange(const Array& strings, |  19891 RawString* String::ConcatAllRange(const Array& strings, | 
|  21088                                   intptr_t start, |  19892                                   intptr_t start, | 
|  21089                                   intptr_t end, |  19893                                   intptr_t end, | 
|  21090                                   Heap::Space space) { |  19894                                   Heap::Space space) { | 
|  21091   ASSERT(!strings.IsNull()); |  19895   ASSERT(!strings.IsNull()); | 
|  21092   ASSERT(start >= 0); |  19896   ASSERT(start >= 0); | 
|  21093   ASSERT(end <= strings.Length()); |  19897   ASSERT(end <= strings.Length()); | 
|  21094   intptr_t result_len = 0; |  19898   intptr_t result_len = 0; | 
|  21095   String& str = String::Handle(); |  19899   String& str = String::Handle(); | 
|  21096   intptr_t char_size = kOneByteChar; |  19900   intptr_t char_size = kOneByteChar; | 
|  21097   // Compute 'char_size' and 'result_len'. |  19901   // Compute 'char_size' and 'result_len'. | 
|  21098   for (intptr_t i = start; i < end; i++) { |  19902   for (intptr_t i = start; i < end; i++) { | 
|  21099     str ^= strings.At(i); |  19903     str ^= strings.At(i); | 
|  21100     const intptr_t str_len = str.Length(); |  19904     const intptr_t str_len = str.Length(); | 
|  21101     if ((kMaxElements - result_len) < str_len) { |  19905     if ((kMaxElements - result_len) < str_len) { | 
|  21102       Exceptions::ThrowOOM(); |  19906       Exceptions::ThrowOOM(); | 
|  21103       UNREACHABLE(); |  19907       UNREACHABLE(); | 
|  21104     } |  19908     } | 
|  21105     result_len += str_len; |  19909     result_len += str_len; | 
|  21106     char_size = Utils::Maximum(char_size, str.CharSize()); |  19910     char_size = Utils::Maximum(char_size, str.CharSize()); | 
|  21107   } |  19911   } | 
|  21108   if (char_size == kOneByteChar) { |  19912   if (char_size == kOneByteChar) { | 
|  21109     return OneByteString::ConcatAll(strings, start, end, result_len, space); |  19913     return OneByteString::ConcatAll(strings, start, end, result_len, space); | 
|  21110   } |  19914   } | 
|  21111   ASSERT(char_size == kTwoByteChar); |  19915   ASSERT(char_size == kTwoByteChar); | 
|  21112   return TwoByteString::ConcatAll(strings, start, end, result_len, space); |  19916   return TwoByteString::ConcatAll(strings, start, end, result_len, space); | 
|  21113 } |  19917 } | 
|  21114  |  19918  | 
|  21115  |  | 
|  21116 RawString* String::SubString(const String& str, |  19919 RawString* String::SubString(const String& str, | 
|  21117                              intptr_t begin_index, |  19920                              intptr_t begin_index, | 
|  21118                              Heap::Space space) { |  19921                              Heap::Space space) { | 
|  21119   ASSERT(!str.IsNull()); |  19922   ASSERT(!str.IsNull()); | 
|  21120   if (begin_index >= str.Length()) { |  19923   if (begin_index >= str.Length()) { | 
|  21121     return String::null(); |  19924     return String::null(); | 
|  21122   } |  19925   } | 
|  21123   return String::SubString(str, begin_index, (str.Length() - begin_index), |  19926   return String::SubString(str, begin_index, (str.Length() - begin_index), | 
|  21124                            space); |  19927                            space); | 
|  21125 } |  19928 } | 
|  21126  |  19929  | 
|  21127  |  | 
|  21128 RawString* String::SubString(Thread* thread, |  19930 RawString* String::SubString(Thread* thread, | 
|  21129                              const String& str, |  19931                              const String& str, | 
|  21130                              intptr_t begin_index, |  19932                              intptr_t begin_index, | 
|  21131                              intptr_t length, |  19933                              intptr_t length, | 
|  21132                              Heap::Space space) { |  19934                              Heap::Space space) { | 
|  21133   ASSERT(!str.IsNull()); |  19935   ASSERT(!str.IsNull()); | 
|  21134   ASSERT(begin_index >= 0); |  19936   ASSERT(begin_index >= 0); | 
|  21135   ASSERT(length >= 0); |  19937   ASSERT(length >= 0); | 
|  21136   if (begin_index <= str.Length() && length == 0) { |  19938   if (begin_index <= str.Length() && length == 0) { | 
|  21137     return Symbols::Empty().raw(); |  19939     return Symbols::Empty().raw(); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  21153   String& result = thread->StringHandle(); |  19955   String& result = thread->StringHandle(); | 
|  21154   if (is_one_byte_string) { |  19956   if (is_one_byte_string) { | 
|  21155     result = OneByteString::New(length, space); |  19957     result = OneByteString::New(length, space); | 
|  21156   } else { |  19958   } else { | 
|  21157     result = TwoByteString::New(length, space); |  19959     result = TwoByteString::New(length, space); | 
|  21158   } |  19960   } | 
|  21159   String::Copy(result, 0, str, begin_index, length); |  19961   String::Copy(result, 0, str, begin_index, length); | 
|  21160   return result.raw(); |  19962   return result.raw(); | 
|  21161 } |  19963 } | 
|  21162  |  19964  | 
|  21163  |  | 
|  21164 const char* String::ToCString() const { |  19965 const char* String::ToCString() const { | 
|  21165   if (IsOneByteString()) { |  19966   if (IsOneByteString()) { | 
|  21166     // Quick conversion if OneByteString contains only ASCII characters. |  19967     // Quick conversion if OneByteString contains only ASCII characters. | 
|  21167     intptr_t len = Length(); |  19968     intptr_t len = Length(); | 
|  21168     if (len == 0) { |  19969     if (len == 0) { | 
|  21169       return ""; |  19970       return ""; | 
|  21170     } |  19971     } | 
|  21171     Zone* zone = Thread::Current()->zone(); |  19972     Zone* zone = Thread::Current()->zone(); | 
|  21172     uint8_t* result = zone->Alloc<uint8_t>(len + 1); |  19973     uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 
|  21173     NoSafepointScope no_safepoint; |  19974     NoSafepointScope no_safepoint; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  21186     } |  19987     } | 
|  21187   } |  19988   } | 
|  21188   const intptr_t len = Utf8::Length(*this); |  19989   const intptr_t len = Utf8::Length(*this); | 
|  21189   Zone* zone = Thread::Current()->zone(); |  19990   Zone* zone = Thread::Current()->zone(); | 
|  21190   uint8_t* result = zone->Alloc<uint8_t>(len + 1); |  19991   uint8_t* result = zone->Alloc<uint8_t>(len + 1); | 
|  21191   ToUTF8(result, len); |  19992   ToUTF8(result, len); | 
|  21192   result[len] = 0; |  19993   result[len] = 0; | 
|  21193   return reinterpret_cast<const char*>(result); |  19994   return reinterpret_cast<const char*>(result); | 
|  21194 } |  19995 } | 
|  21195  |  19996  | 
|  21196  |  | 
|  21197 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |  19997 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { | 
|  21198   ASSERT(array_len >= Utf8::Length(*this)); |  19998   ASSERT(array_len >= Utf8::Length(*this)); | 
|  21199   Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |  19999   Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); | 
|  21200 } |  20000 } | 
|  21201  |  20001  | 
|  21202  |  | 
|  21203 static FinalizablePersistentHandle* AddFinalizer( |  20002 static FinalizablePersistentHandle* AddFinalizer( | 
|  21204     const Object& referent, |  20003     const Object& referent, | 
|  21205     void* peer, |  20004     void* peer, | 
|  21206     Dart_WeakPersistentHandleFinalizer callback, |  20005     Dart_WeakPersistentHandleFinalizer callback, | 
|  21207     intptr_t external_size) { |  20006     intptr_t external_size) { | 
|  21208   ASSERT((callback != NULL && peer != NULL) || |  20007   ASSERT((callback != NULL && peer != NULL) || | 
|  21209          (callback == NULL && peer == NULL)); |  20008          (callback == NULL && peer == NULL)); | 
|  21210   return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, |  20009   return FinalizablePersistentHandle::New(Isolate::Current(), referent, peer, | 
|  21211                                           callback, external_size); |  20010                                           callback, external_size); | 
|  21212 } |  20011 } | 
|  21213  |  20012  | 
|  21214  |  | 
|  21215 RawString* String::MakeExternal(void* array, |  20013 RawString* String::MakeExternal(void* array, | 
|  21216                                 intptr_t external_size, |  20014                                 intptr_t external_size, | 
|  21217                                 void* peer, |  20015                                 void* peer, | 
|  21218                                 Dart_PeerFinalizer cback) const { |  20016                                 Dart_PeerFinalizer cback) const { | 
|  21219   ASSERT(FLAG_support_externalizable_strings); |  20017   ASSERT(FLAG_support_externalizable_strings); | 
|  21220   String& result = String::Handle(); |  20018   String& result = String::Handle(); | 
|  21221   void* external_data; |  20019   void* external_data; | 
|  21222   Dart_WeakPersistentHandleFinalizer finalizer; |  20020   Dart_WeakPersistentHandleFinalizer finalizer; | 
|  21223   { |  20021   { | 
|  21224     NoSafepointScope no_safepoint; |  20022     NoSafepointScope no_safepoint; | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  21299              (result.Hash() == String::Hash(ext_array, str_length))); |  20097              (result.Hash() == String::Hash(ext_array, str_length))); | 
|  21300       ExternalTwoByteString::SetExternalData(result, ext_data); |  20098       ExternalTwoByteString::SetExternalData(result, ext_data); | 
|  21301       external_data = ext_data; |  20099       external_data = ext_data; | 
|  21302       finalizer = ExternalTwoByteString::Finalize; |  20100       finalizer = ExternalTwoByteString::Finalize; | 
|  21303     } |  20101     } | 
|  21304   }  // NoSafepointScope |  20102   }  // NoSafepointScope | 
|  21305   AddFinalizer(result, external_data, finalizer, external_size); |  20103   AddFinalizer(result, external_data, finalizer, external_size); | 
|  21306   return this->raw(); |  20104   return this->raw(); | 
|  21307 } |  20105 } | 
|  21308  |  20106  | 
|  21309  |  | 
|  21310 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |  20107 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 
|  21311                              const String& str, |  20108                              const String& str, | 
|  21312                              Heap::Space space) { |  20109                              Heap::Space space) { | 
|  21313   ASSERT(!str.IsNull()); |  20110   ASSERT(!str.IsNull()); | 
|  21314   bool has_mapping = false; |  20111   bool has_mapping = false; | 
|  21315   int32_t dst_max = 0; |  20112   int32_t dst_max = 0; | 
|  21316   CodePointIterator it(str); |  20113   CodePointIterator it(str); | 
|  21317   while (it.Next()) { |  20114   while (it.Next()) { | 
|  21318     int32_t src = it.Current(); |  20115     int32_t src = it.Current(); | 
|  21319     int32_t dst = mapping(src); |  20116     int32_t dst = mapping(src); | 
|  21320     if (src != dst) { |  20117     if (src != dst) { | 
|  21321       has_mapping = true; |  20118       has_mapping = true; | 
|  21322     } |  20119     } | 
|  21323     dst_max = Utils::Maximum(dst_max, dst); |  20120     dst_max = Utils::Maximum(dst_max, dst); | 
|  21324   } |  20121   } | 
|  21325   if (!has_mapping) { |  20122   if (!has_mapping) { | 
|  21326     return str.raw(); |  20123     return str.raw(); | 
|  21327   } |  20124   } | 
|  21328   if (Utf::IsLatin1(dst_max)) { |  20125   if (Utf::IsLatin1(dst_max)) { | 
|  21329     return OneByteString::Transform(mapping, str, space); |  20126     return OneByteString::Transform(mapping, str, space); | 
|  21330   } |  20127   } | 
|  21331   ASSERT(Utf::IsBmp(dst_max) || Utf::IsSupplementary(dst_max)); |  20128   ASSERT(Utf::IsBmp(dst_max) || Utf::IsSupplementary(dst_max)); | 
|  21332   return TwoByteString::Transform(mapping, str, space); |  20129   return TwoByteString::Transform(mapping, str, space); | 
|  21333 } |  20130 } | 
|  21334  |  20131  | 
|  21335  |  | 
|  21336 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |  20132 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 
|  21337   // TODO(cshapiro): create a fast-path for OneByteString instances. |  20133   // TODO(cshapiro): create a fast-path for OneByteString instances. | 
|  21338   return Transform(CaseMapping::ToUpper, str, space); |  20134   return Transform(CaseMapping::ToUpper, str, space); | 
|  21339 } |  20135 } | 
|  21340  |  20136  | 
|  21341  |  | 
|  21342 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |  20137 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 
|  21343   // TODO(cshapiro): create a fast-path for OneByteString instances. |  20138   // TODO(cshapiro): create a fast-path for OneByteString instances. | 
|  21344   return Transform(CaseMapping::ToLower, str, space); |  20139   return Transform(CaseMapping::ToLower, str, space); | 
|  21345 } |  20140 } | 
|  21346  |  20141  | 
|  21347 bool String::ParseDouble(const String& str, |  20142 bool String::ParseDouble(const String& str, | 
|  21348                          intptr_t start, |  20143                          intptr_t start, | 
|  21349                          intptr_t end, |  20144                          intptr_t end, | 
|  21350                          double* result) { |  20145                          double* result) { | 
|  21351   ASSERT(0 <= start); |  20146   ASSERT(0 <= start); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  21368       } else { |  20163       } else { | 
|  21369         return false;  // Not ASCII, so definitely not valid double numeral. |  20164         return false;  // Not ASCII, so definitely not valid double numeral. | 
|  21370       } |  20165       } | 
|  21371     } |  20166     } | 
|  21372     startChar = chars; |  20167     startChar = chars; | 
|  21373   } |  20168   } | 
|  21374   return CStringToDouble(reinterpret_cast<const char*>(startChar), length, |  20169   return CStringToDouble(reinterpret_cast<const char*>(startChar), length, | 
|  21375                          result); |  20170                          result); | 
|  21376 } |  20171 } | 
|  21377  |  20172  | 
|  21378  |  | 
|  21379 // Check to see if 'str1' matches 'str2' as is or |  20173 // Check to see if 'str1' matches 'str2' as is or | 
|  21380 // once the private key separator is stripped from str2. |  20174 // once the private key separator is stripped from str2. | 
|  21381 // |  20175 // | 
|  21382 // Things are made more complicated by the fact that constructors are |  20176 // Things are made more complicated by the fact that constructors are | 
|  21383 // added *after* the private suffix, so "foo@123.named" should match |  20177 // added *after* the private suffix, so "foo@123.named" should match | 
|  21384 // "foo.named". |  20178 // "foo.named". | 
|  21385 // |  20179 // | 
|  21386 // Also, the private suffix can occur more than once in the name, as in: |  20180 // Also, the private suffix can occur more than once in the name, as in: | 
|  21387 // |  20181 // | 
|  21388 //    _ReceivePortImpl@6be832b._internal@6be832b |  20182 //    _ReceivePortImpl@6be832b._internal@6be832b | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  21421       return false; |  20215       return false; | 
|  21422     } |  20216     } | 
|  21423     str2_pos++; |  20217     str2_pos++; | 
|  21424   } |  20218   } | 
|  21425  |  20219  | 
|  21426   // We have reached the end of mangled_name string. |  20220   // We have reached the end of mangled_name string. | 
|  21427   ASSERT(pos == len); |  20221   ASSERT(pos == len); | 
|  21428   return (str2_pos == str2_len); |  20222   return (str2_pos == str2_len); | 
|  21429 } |  20223 } | 
|  21430  |  20224  | 
|  21431  |  | 
|  21432 #define EQUALS_IGNORING_PRIVATE_KEY(class_id, type, str1, str2)                \ |  20225 #define EQUALS_IGNORING_PRIVATE_KEY(class_id, type, str1, str2)                \ | 
|  21433   switch (class_id) {                                                          \ |  20226   switch (class_id) {                                                          \ | 
|  21434     case kOneByteStringCid:                                                    \ |  20227     case kOneByteStringCid:                                                    \ | 
|  21435       return dart::EqualsIgnoringPrivateKey<type, OneByteString>(str1, str2);  \ |  20228       return dart::EqualsIgnoringPrivateKey<type, OneByteString>(str1, str2);  \ | 
|  21436     case kTwoByteStringCid:                                                    \ |  20229     case kTwoByteStringCid:                                                    \ | 
|  21437       return dart::EqualsIgnoringPrivateKey<type, TwoByteString>(str1, str2);  \ |  20230       return dart::EqualsIgnoringPrivateKey<type, TwoByteString>(str1, str2);  \ | 
|  21438     case kExternalOneByteStringCid:                                            \ |  20231     case kExternalOneByteStringCid:                                            \ | 
|  21439       return dart::EqualsIgnoringPrivateKey<type, ExternalOneByteString>(      \ |  20232       return dart::EqualsIgnoringPrivateKey<type, ExternalOneByteString>(      \ | 
|  21440           str1, str2);                                                         \ |  20233           str1, str2);                                                         \ | 
|  21441     case kExternalTwoByteStringCid:                                            \ |  20234     case kExternalTwoByteStringCid:                                            \ | 
|  21442       return dart::EqualsIgnoringPrivateKey<type, ExternalTwoByteString>(      \ |  20235       return dart::EqualsIgnoringPrivateKey<type, ExternalTwoByteString>(      \ | 
|  21443           str1, str2);                                                         \ |  20236           str1, str2);                                                         \ | 
|  21444   }                                                                            \ |  20237   }                                                                            \ | 
|  21445   UNREACHABLE(); |  20238   UNREACHABLE(); | 
|  21446  |  20239  | 
|  21447  |  | 
|  21448 bool String::EqualsIgnoringPrivateKey(const String& str1, const String& str2) { |  20240 bool String::EqualsIgnoringPrivateKey(const String& str1, const String& str2) { | 
|  21449   if (str1.raw() == str2.raw()) { |  20241   if (str1.raw() == str2.raw()) { | 
|  21450     return true;  // Both handles point to the same raw instance. |  20242     return true;  // Both handles point to the same raw instance. | 
|  21451   } |  20243   } | 
|  21452   NoSafepointScope no_safepoint; |  20244   NoSafepointScope no_safepoint; | 
|  21453   intptr_t str1_class_id = str1.raw()->GetClassId(); |  20245   intptr_t str1_class_id = str1.raw()->GetClassId(); | 
|  21454   intptr_t str2_class_id = str2.raw()->GetClassId(); |  20246   intptr_t str2_class_id = str2.raw()->GetClassId(); | 
|  21455   switch (str1_class_id) { |  20247   switch (str1_class_id) { | 
|  21456     case kOneByteStringCid: |  20248     case kOneByteStringCid: | 
|  21457       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2); |  20249       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, OneByteString, str1, str2); | 
|  21458       break; |  20250       break; | 
|  21459     case kTwoByteStringCid: |  20251     case kTwoByteStringCid: | 
|  21460       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, TwoByteString, str1, str2); |  20252       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, TwoByteString, str1, str2); | 
|  21461       break; |  20253       break; | 
|  21462     case kExternalOneByteStringCid: |  20254     case kExternalOneByteStringCid: | 
|  21463       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalOneByteString, str1, |  20255       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalOneByteString, str1, | 
|  21464                                   str2); |  20256                                   str2); | 
|  21465       break; |  20257       break; | 
|  21466     case kExternalTwoByteStringCid: |  20258     case kExternalTwoByteStringCid: | 
|  21467       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalTwoByteString, str1, |  20259       EQUALS_IGNORING_PRIVATE_KEY(str2_class_id, ExternalTwoByteString, str1, | 
|  21468                                   str2); |  20260                                   str2); | 
|  21469       break; |  20261       break; | 
|  21470   } |  20262   } | 
|  21471   UNREACHABLE(); |  20263   UNREACHABLE(); | 
|  21472   return false; |  20264   return false; | 
|  21473 } |  20265 } | 
|  21474  |  20266  | 
|  21475  |  | 
|  21476 bool String::CodePointIterator::Next() { |  20267 bool String::CodePointIterator::Next() { | 
|  21477   ASSERT(index_ >= -1); |  20268   ASSERT(index_ >= -1); | 
|  21478   intptr_t length = Utf16::Length(ch_); |  20269   intptr_t length = Utf16::Length(ch_); | 
|  21479   if (index_ < (end_ - length)) { |  20270   if (index_ < (end_ - length)) { | 
|  21480     index_ += length; |  20271     index_ += length; | 
|  21481     ch_ = str_.CharAt(index_); |  20272     ch_ = str_.CharAt(index_); | 
|  21482     if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) { |  20273     if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) { | 
|  21483       int32_t ch2 = str_.CharAt(index_ + 1); |  20274       int32_t ch2 = str_.CharAt(index_ + 1); | 
|  21484       if (Utf16::IsTrailSurrogate(ch2)) { |  20275       if (Utf16::IsTrailSurrogate(ch2)) { | 
|  21485         ch_ = Utf16::Decode(ch_, ch2); |  20276         ch_ = Utf16::Decode(ch_, ch2); | 
|  21486       } |  20277       } | 
|  21487     } |  20278     } | 
|  21488     return true; |  20279     return true; | 
|  21489   } |  20280   } | 
|  21490   index_ = end_; |  20281   index_ = end_; | 
|  21491   return false; |  20282   return false; | 
|  21492 } |  20283 } | 
|  21493  |  20284  | 
|  21494  |  | 
|  21495 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { |  20285 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { | 
|  21496   intptr_t len = str.Length(); |  20286   intptr_t len = str.Length(); | 
|  21497   if (len > 0) { |  20287   if (len > 0) { | 
|  21498     intptr_t num_escapes = 0; |  20288     intptr_t num_escapes = 0; | 
|  21499     for (intptr_t i = 0; i < len; i++) { |  20289     for (intptr_t i = 0; i < len; i++) { | 
|  21500       num_escapes += EscapeOverhead(CharAt(str, i)); |  20290       num_escapes += EscapeOverhead(CharAt(str, i)); | 
|  21501     } |  20291     } | 
|  21502     const String& dststr = |  20292     const String& dststr = | 
|  21503         String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); |  20293         String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); | 
|  21504     intptr_t index = 0; |  20294     intptr_t index = 0; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  21517       } else { |  20307       } else { | 
|  21518         SetCharAt(dststr, index, ch); |  20308         SetCharAt(dststr, index, ch); | 
|  21519         index += 1; |  20309         index += 1; | 
|  21520       } |  20310       } | 
|  21521     } |  20311     } | 
|  21522     return OneByteString::raw(dststr); |  20312     return OneByteString::raw(dststr); | 
|  21523   } |  20313   } | 
|  21524   return OneByteString::raw(Symbols::Empty()); |  20314   return OneByteString::raw(Symbols::Empty()); | 
|  21525 } |  20315 } | 
|  21526  |  20316  | 
|  21527  |  | 
|  21528 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( |  20317 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( | 
|  21529     const String& str) { |  20318     const String& str) { | 
|  21530   intptr_t len = str.Length(); |  20319   intptr_t len = str.Length(); | 
|  21531   if (len > 0) { |  20320   if (len > 0) { | 
|  21532     intptr_t num_escapes = 0; |  20321     intptr_t num_escapes = 0; | 
|  21533     for (intptr_t i = 0; i < len; i++) { |  20322     for (intptr_t i = 0; i < len; i++) { | 
|  21534       num_escapes += EscapeOverhead(CharAt(str, i)); |  20323       num_escapes += EscapeOverhead(CharAt(str, i)); | 
|  21535     } |  20324     } | 
|  21536     const String& dststr = |  20325     const String& dststr = | 
|  21537         String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); |  20326         String::Handle(OneByteString::New(len + num_escapes, Heap::kNew)); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  21551       } else { |  20340       } else { | 
|  21552         OneByteString::SetCharAt(dststr, index, ch); |  20341         OneByteString::SetCharAt(dststr, index, ch); | 
|  21553         index += 1; |  20342         index += 1; | 
|  21554       } |  20343       } | 
|  21555     } |  20344     } | 
|  21556     return OneByteString::raw(dststr); |  20345     return OneByteString::raw(dststr); | 
|  21557   } |  20346   } | 
|  21558   return OneByteString::raw(Symbols::Empty()); |  20347   return OneByteString::raw(Symbols::Empty()); | 
|  21559 } |  20348 } | 
|  21560  |  20349  | 
|  21561  |  | 
|  21562 RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) { |  20350 RawOneByteString* OneByteString::New(intptr_t len, Heap::Space space) { | 
|  21563   ASSERT((Isolate::Current() == Dart::vm_isolate()) || |  20351   ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 
|  21564          ((Isolate::Current()->object_store() != NULL) && |  20352          ((Isolate::Current()->object_store() != NULL) && | 
|  21565           (Isolate::Current()->object_store()->one_byte_string_class() != |  20353           (Isolate::Current()->object_store()->one_byte_string_class() != | 
|  21566            Class::null()))); |  20354            Class::null()))); | 
|  21567   if (len < 0 || len > kMaxElements) { |  20355   if (len < 0 || len > kMaxElements) { | 
|  21568     // This should be caught before we reach here. |  20356     // This should be caught before we reach here. | 
|  21569     FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len); |  20357     FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len); | 
|  21570   } |  20358   } | 
|  21571   { |  20359   { | 
|  21572     RawObject* raw = Object::Allocate(OneByteString::kClassId, |  20360     RawObject* raw = Object::Allocate(OneByteString::kClassId, | 
|  21573                                       OneByteString::InstanceSize(len), space); |  20361                                       OneByteString::InstanceSize(len), space); | 
|  21574     NoSafepointScope no_safepoint; |  20362     NoSafepointScope no_safepoint; | 
|  21575     RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw); |  20363     RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw); | 
|  21576     result->StoreSmi(&(result->ptr()->length_), Smi::New(len)); |  20364     result->StoreSmi(&(result->ptr()->length_), Smi::New(len)); | 
|  21577 #if !defined(HASH_IN_OBJECT_HEADER) |  20365 #if !defined(HASH_IN_OBJECT_HEADER) | 
|  21578     result->StoreSmi(&(result->ptr()->hash_), Smi::New(0)); |  20366     result->StoreSmi(&(result->ptr()->hash_), Smi::New(0)); | 
|  21579 #endif |  20367 #endif | 
|  21580     return result; |  20368     return result; | 
|  21581   } |  20369   } | 
|  21582 } |  20370 } | 
|  21583  |  20371  | 
|  21584  |  | 
|  21585 RawOneByteString* OneByteString::New(const uint8_t* characters, |  20372 RawOneByteString* OneByteString::New(const uint8_t* characters, | 
|  21586                                      intptr_t len, |  20373                                      intptr_t len, | 
|  21587                                      Heap::Space space) { |  20374                                      Heap::Space space) { | 
|  21588   const String& result = String::Handle(OneByteString::New(len, space)); |  20375   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21589   if (len > 0) { |  20376   if (len > 0) { | 
|  21590     NoSafepointScope no_safepoint; |  20377     NoSafepointScope no_safepoint; | 
|  21591     memmove(CharAddr(result, 0), characters, len); |  20378     memmove(CharAddr(result, 0), characters, len); | 
|  21592   } |  20379   } | 
|  21593   return OneByteString::raw(result); |  20380   return OneByteString::raw(result); | 
|  21594 } |  20381 } | 
|  21595  |  20382  | 
|  21596  |  | 
|  21597 RawOneByteString* OneByteString::New(const uint16_t* characters, |  20383 RawOneByteString* OneByteString::New(const uint16_t* characters, | 
|  21598                                      intptr_t len, |  20384                                      intptr_t len, | 
|  21599                                      Heap::Space space) { |  20385                                      Heap::Space space) { | 
|  21600   const String& result = String::Handle(OneByteString::New(len, space)); |  20386   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21601   NoSafepointScope no_safepoint; |  20387   NoSafepointScope no_safepoint; | 
|  21602   for (intptr_t i = 0; i < len; ++i) { |  20388   for (intptr_t i = 0; i < len; ++i) { | 
|  21603     ASSERT(Utf::IsLatin1(characters[i])); |  20389     ASSERT(Utf::IsLatin1(characters[i])); | 
|  21604     *CharAddr(result, i) = characters[i]; |  20390     *CharAddr(result, i) = characters[i]; | 
|  21605   } |  20391   } | 
|  21606   return OneByteString::raw(result); |  20392   return OneByteString::raw(result); | 
|  21607 } |  20393 } | 
|  21608  |  20394  | 
|  21609  |  | 
|  21610 RawOneByteString* OneByteString::New(const int32_t* characters, |  20395 RawOneByteString* OneByteString::New(const int32_t* characters, | 
|  21611                                      intptr_t len, |  20396                                      intptr_t len, | 
|  21612                                      Heap::Space space) { |  20397                                      Heap::Space space) { | 
|  21613   const String& result = String::Handle(OneByteString::New(len, space)); |  20398   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21614   NoSafepointScope no_safepoint; |  20399   NoSafepointScope no_safepoint; | 
|  21615   for (intptr_t i = 0; i < len; ++i) { |  20400   for (intptr_t i = 0; i < len; ++i) { | 
|  21616     ASSERT(Utf::IsLatin1(characters[i])); |  20401     ASSERT(Utf::IsLatin1(characters[i])); | 
|  21617     *CharAddr(result, i) = characters[i]; |  20402     *CharAddr(result, i) = characters[i]; | 
|  21618   } |  20403   } | 
|  21619   return OneByteString::raw(result); |  20404   return OneByteString::raw(result); | 
|  21620 } |  20405 } | 
|  21621  |  20406  | 
|  21622  |  | 
|  21623 RawOneByteString* OneByteString::New(const String& str, Heap::Space space) { |  20407 RawOneByteString* OneByteString::New(const String& str, Heap::Space space) { | 
|  21624   intptr_t len = str.Length(); |  20408   intptr_t len = str.Length(); | 
|  21625   const String& result = String::Handle(OneByteString::New(len, space)); |  20409   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21626   String::Copy(result, 0, str, 0, len); |  20410   String::Copy(result, 0, str, 0, len); | 
|  21627   return OneByteString::raw(result); |  20411   return OneByteString::raw(result); | 
|  21628 } |  20412 } | 
|  21629  |  20413  | 
|  21630  |  | 
|  21631 RawOneByteString* OneByteString::New(const String& other_one_byte_string, |  20414 RawOneByteString* OneByteString::New(const String& other_one_byte_string, | 
|  21632                                      intptr_t other_start_index, |  20415                                      intptr_t other_start_index, | 
|  21633                                      intptr_t other_len, |  20416                                      intptr_t other_len, | 
|  21634                                      Heap::Space space) { |  20417                                      Heap::Space space) { | 
|  21635   const String& result = String::Handle(OneByteString::New(other_len, space)); |  20418   const String& result = String::Handle(OneByteString::New(other_len, space)); | 
|  21636   ASSERT(other_one_byte_string.IsOneByteString()); |  20419   ASSERT(other_one_byte_string.IsOneByteString()); | 
|  21637   if (other_len > 0) { |  20420   if (other_len > 0) { | 
|  21638     NoSafepointScope no_safepoint; |  20421     NoSafepointScope no_safepoint; | 
|  21639     memmove(OneByteString::CharAddr(result, 0), |  20422     memmove(OneByteString::CharAddr(result, 0), | 
|  21640             OneByteString::CharAddr(other_one_byte_string, other_start_index), |  20423             OneByteString::CharAddr(other_one_byte_string, other_start_index), | 
|  21641             other_len); |  20424             other_len); | 
|  21642   } |  20425   } | 
|  21643   return OneByteString::raw(result); |  20426   return OneByteString::raw(result); | 
|  21644 } |  20427 } | 
|  21645  |  20428  | 
|  21646  |  | 
|  21647 RawOneByteString* OneByteString::New(const TypedData& other_typed_data, |  20429 RawOneByteString* OneByteString::New(const TypedData& other_typed_data, | 
|  21648                                      intptr_t other_start_index, |  20430                                      intptr_t other_start_index, | 
|  21649                                      intptr_t other_len, |  20431                                      intptr_t other_len, | 
|  21650                                      Heap::Space space) { |  20432                                      Heap::Space space) { | 
|  21651   const String& result = String::Handle(OneByteString::New(other_len, space)); |  20433   const String& result = String::Handle(OneByteString::New(other_len, space)); | 
|  21652   ASSERT(other_typed_data.ElementSizeInBytes() == 1); |  20434   ASSERT(other_typed_data.ElementSizeInBytes() == 1); | 
|  21653   if (other_len > 0) { |  20435   if (other_len > 0) { | 
|  21654     NoSafepointScope no_safepoint; |  20436     NoSafepointScope no_safepoint; | 
|  21655     memmove(OneByteString::CharAddr(result, 0), |  20437     memmove(OneByteString::CharAddr(result, 0), | 
|  21656             other_typed_data.DataAddr(other_start_index), other_len); |  20438             other_typed_data.DataAddr(other_start_index), other_len); | 
|  21657   } |  20439   } | 
|  21658   return OneByteString::raw(result); |  20440   return OneByteString::raw(result); | 
|  21659 } |  20441 } | 
|  21660  |  20442  | 
|  21661  |  | 
|  21662 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data, |  20443 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data, | 
|  21663                                      intptr_t other_start_index, |  20444                                      intptr_t other_start_index, | 
|  21664                                      intptr_t other_len, |  20445                                      intptr_t other_len, | 
|  21665                                      Heap::Space space) { |  20446                                      Heap::Space space) { | 
|  21666   const String& result = String::Handle(OneByteString::New(other_len, space)); |  20447   const String& result = String::Handle(OneByteString::New(other_len, space)); | 
|  21667   ASSERT(other_typed_data.ElementSizeInBytes() == 1); |  20448   ASSERT(other_typed_data.ElementSizeInBytes() == 1); | 
|  21668   if (other_len > 0) { |  20449   if (other_len > 0) { | 
|  21669     NoSafepointScope no_safepoint; |  20450     NoSafepointScope no_safepoint; | 
|  21670     memmove(OneByteString::CharAddr(result, 0), |  20451     memmove(OneByteString::CharAddr(result, 0), | 
|  21671             other_typed_data.DataAddr(other_start_index), other_len); |  20452             other_typed_data.DataAddr(other_start_index), other_len); | 
|  21672   } |  20453   } | 
|  21673   return OneByteString::raw(result); |  20454   return OneByteString::raw(result); | 
|  21674 } |  20455 } | 
|  21675  |  20456  | 
|  21676  |  | 
|  21677 RawOneByteString* OneByteString::Concat(const String& str1, |  20457 RawOneByteString* OneByteString::Concat(const String& str1, | 
|  21678                                         const String& str2, |  20458                                         const String& str2, | 
|  21679                                         Heap::Space space) { |  20459                                         Heap::Space space) { | 
|  21680   intptr_t len1 = str1.Length(); |  20460   intptr_t len1 = str1.Length(); | 
|  21681   intptr_t len2 = str2.Length(); |  20461   intptr_t len2 = str2.Length(); | 
|  21682   intptr_t len = len1 + len2; |  20462   intptr_t len = len1 + len2; | 
|  21683   const String& result = String::Handle(OneByteString::New(len, space)); |  20463   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21684   String::Copy(result, 0, str1, 0, len1); |  20464   String::Copy(result, 0, str1, 0, len1); | 
|  21685   String::Copy(result, len1, str2, 0, len2); |  20465   String::Copy(result, len1, str2, 0, len2); | 
|  21686   return OneByteString::raw(result); |  20466   return OneByteString::raw(result); | 
|  21687 } |  20467 } | 
|  21688  |  20468  | 
|  21689  |  | 
|  21690 RawOneByteString* OneByteString::ConcatAll(const Array& strings, |  20469 RawOneByteString* OneByteString::ConcatAll(const Array& strings, | 
|  21691                                            intptr_t start, |  20470                                            intptr_t start, | 
|  21692                                            intptr_t end, |  20471                                            intptr_t end, | 
|  21693                                            intptr_t len, |  20472                                            intptr_t len, | 
|  21694                                            Heap::Space space) { |  20473                                            Heap::Space space) { | 
|  21695   ASSERT(!strings.IsNull()); |  20474   ASSERT(!strings.IsNull()); | 
|  21696   ASSERT(start >= 0); |  20475   ASSERT(start >= 0); | 
|  21697   ASSERT(end <= strings.Length()); |  20476   ASSERT(end <= strings.Length()); | 
|  21698   const String& result = String::Handle(OneByteString::New(len, space)); |  20477   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21699   String& str = String::Handle(); |  20478   String& str = String::Handle(); | 
|  21700   intptr_t pos = 0; |  20479   intptr_t pos = 0; | 
|  21701   for (intptr_t i = start; i < end; i++) { |  20480   for (intptr_t i = start; i < end; i++) { | 
|  21702     str ^= strings.At(i); |  20481     str ^= strings.At(i); | 
|  21703     const intptr_t str_len = str.Length(); |  20482     const intptr_t str_len = str.Length(); | 
|  21704     String::Copy(result, pos, str, 0, str_len); |  20483     String::Copy(result, pos, str, 0, str_len); | 
|  21705     ASSERT((kMaxElements - pos) >= str_len); |  20484     ASSERT((kMaxElements - pos) >= str_len); | 
|  21706     pos += str_len; |  20485     pos += str_len; | 
|  21707   } |  20486   } | 
|  21708   return OneByteString::raw(result); |  20487   return OneByteString::raw(result); | 
|  21709 } |  20488 } | 
|  21710  |  20489  | 
|  21711  |  | 
|  21712 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |  20490 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 
|  21713                                            const String& str, |  20491                                            const String& str, | 
|  21714                                            Heap::Space space) { |  20492                                            Heap::Space space) { | 
|  21715   ASSERT(!str.IsNull()); |  20493   ASSERT(!str.IsNull()); | 
|  21716   intptr_t len = str.Length(); |  20494   intptr_t len = str.Length(); | 
|  21717   const String& result = String::Handle(OneByteString::New(len, space)); |  20495   const String& result = String::Handle(OneByteString::New(len, space)); | 
|  21718   NoSafepointScope no_safepoint; |  20496   NoSafepointScope no_safepoint; | 
|  21719   for (intptr_t i = 0; i < len; ++i) { |  20497   for (intptr_t i = 0; i < len; ++i) { | 
|  21720     int32_t ch = mapping(str.CharAt(i)); |  20498     int32_t ch = mapping(str.CharAt(i)); | 
|  21721     ASSERT(Utf::IsLatin1(ch)); |  20499     ASSERT(Utf::IsLatin1(ch)); | 
|  21722     *CharAddr(result, i) = ch; |  20500     *CharAddr(result, i) = ch; | 
|  21723   } |  20501   } | 
|  21724   return OneByteString::raw(result); |  20502   return OneByteString::raw(result); | 
|  21725 } |  20503 } | 
|  21726  |  20504  | 
|  21727  |  | 
|  21728 RawOneByteString* OneByteString::SubStringUnchecked(const String& str, |  20505 RawOneByteString* OneByteString::SubStringUnchecked(const String& str, | 
|  21729                                                     intptr_t begin_index, |  20506                                                     intptr_t begin_index, | 
|  21730                                                     intptr_t length, |  20507                                                     intptr_t length, | 
|  21731                                                     Heap::Space space) { |  20508                                                     Heap::Space space) { | 
|  21732   ASSERT(!str.IsNull() && str.IsOneByteString()); |  20509   ASSERT(!str.IsNull() && str.IsOneByteString()); | 
|  21733   ASSERT(begin_index >= 0); |  20510   ASSERT(begin_index >= 0); | 
|  21734   ASSERT(length >= 0); |  20511   ASSERT(length >= 0); | 
|  21735   if (begin_index <= str.Length() && length == 0) { |  20512   if (begin_index <= str.Length() && length == 0) { | 
|  21736     return OneByteString::raw(Symbols::Empty()); |  20513     return OneByteString::raw(Symbols::Empty()); | 
|  21737   } |  20514   } | 
|  21738   ASSERT(begin_index < str.Length()); |  20515   ASSERT(begin_index < str.Length()); | 
|  21739   RawOneByteString* result = OneByteString::New(length, space); |  20516   RawOneByteString* result = OneByteString::New(length, space); | 
|  21740   NoSafepointScope no_safepoint; |  20517   NoSafepointScope no_safepoint; | 
|  21741   if (length > 0) { |  20518   if (length > 0) { | 
|  21742     uint8_t* dest = &result->ptr()->data()[0]; |  20519     uint8_t* dest = &result->ptr()->data()[0]; | 
|  21743     const uint8_t* src = &raw_ptr(str)->data()[begin_index]; |  20520     const uint8_t* src = &raw_ptr(str)->data()[begin_index]; | 
|  21744     memmove(dest, src, length); |  20521     memmove(dest, src, length); | 
|  21745   } |  20522   } | 
|  21746   return result; |  20523   return result; | 
|  21747 } |  20524 } | 
|  21748  |  20525  | 
|  21749  |  | 
|  21750 void OneByteString::SetPeer(const String& str, |  20526 void OneByteString::SetPeer(const String& str, | 
|  21751                             intptr_t external_size, |  20527                             intptr_t external_size, | 
|  21752                             void* peer, |  20528                             void* peer, | 
|  21753                             Dart_PeerFinalizer cback) { |  20529                             Dart_PeerFinalizer cback) { | 
|  21754   ASSERT(!str.IsNull() && str.IsOneByteString()); |  20530   ASSERT(!str.IsNull() && str.IsOneByteString()); | 
|  21755   ASSERT(peer != NULL); |  20531   ASSERT(peer != NULL); | 
|  21756   ExternalStringData<uint8_t>* ext_data = |  20532   ExternalStringData<uint8_t>* ext_data = | 
|  21757       new ExternalStringData<uint8_t>(NULL, peer, cback); |  20533       new ExternalStringData<uint8_t>(NULL, peer, cback); | 
|  21758   AddFinalizer(str, ext_data, OneByteString::Finalize, external_size); |  20534   AddFinalizer(str, ext_data, OneByteString::Finalize, external_size); | 
|  21759   Isolate::Current()->heap()->SetPeer(str.raw(), peer); |  20535   Isolate::Current()->heap()->SetPeer(str.raw(), peer); | 
|  21760 } |  20536 } | 
|  21761  |  20537  | 
|  21762  |  | 
|  21763 void OneByteString::Finalize(void* isolate_callback_data, |  20538 void OneByteString::Finalize(void* isolate_callback_data, | 
|  21764                              Dart_WeakPersistentHandle handle, |  20539                              Dart_WeakPersistentHandle handle, | 
|  21765                              void* peer) { |  20540                              void* peer) { | 
|  21766   delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); |  20541   delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); | 
|  21767 } |  20542 } | 
|  21768  |  20543  | 
|  21769  |  | 
|  21770 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { |  20544 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { | 
|  21771   intptr_t len = str.Length(); |  20545   intptr_t len = str.Length(); | 
|  21772   if (len > 0) { |  20546   if (len > 0) { | 
|  21773     intptr_t num_escapes = 0; |  20547     intptr_t num_escapes = 0; | 
|  21774     for (intptr_t i = 0; i < len; i++) { |  20548     for (intptr_t i = 0; i < len; i++) { | 
|  21775       num_escapes += EscapeOverhead(CharAt(str, i)); |  20549       num_escapes += EscapeOverhead(CharAt(str, i)); | 
|  21776     } |  20550     } | 
|  21777     const String& dststr = |  20551     const String& dststr = | 
|  21778         String::Handle(TwoByteString::New(len + num_escapes, Heap::kNew)); |  20552         String::Handle(TwoByteString::New(len + num_escapes, Heap::kNew)); | 
|  21779     intptr_t index = 0; |  20553     intptr_t index = 0; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  21792       } else { |  20566       } else { | 
|  21793         SetCharAt(dststr, index, ch); |  20567         SetCharAt(dststr, index, ch); | 
|  21794         index += 1; |  20568         index += 1; | 
|  21795       } |  20569       } | 
|  21796     } |  20570     } | 
|  21797     return TwoByteString::raw(dststr); |  20571     return TwoByteString::raw(dststr); | 
|  21798   } |  20572   } | 
|  21799   return TwoByteString::New(0, Heap::kNew); |  20573   return TwoByteString::New(0, Heap::kNew); | 
|  21800 } |  20574 } | 
|  21801  |  20575  | 
|  21802  |  | 
|  21803 RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) { |  20576 RawTwoByteString* TwoByteString::New(intptr_t len, Heap::Space space) { | 
|  21804   ASSERT(Isolate::Current()->object_store()->two_byte_string_class()); |  20577   ASSERT(Isolate::Current()->object_store()->two_byte_string_class()); | 
|  21805   if (len < 0 || len > kMaxElements) { |  20578   if (len < 0 || len > kMaxElements) { | 
|  21806     // This should be caught before we reach here. |  20579     // This should be caught before we reach here. | 
|  21807     FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len); |  20580     FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len); | 
|  21808   } |  20581   } | 
|  21809   String& result = String::Handle(); |  20582   String& result = String::Handle(); | 
|  21810   { |  20583   { | 
|  21811     RawObject* raw = Object::Allocate(TwoByteString::kClassId, |  20584     RawObject* raw = Object::Allocate(TwoByteString::kClassId, | 
|  21812                                       TwoByteString::InstanceSize(len), space); |  20585                                       TwoByteString::InstanceSize(len), space); | 
|  21813     NoSafepointScope no_safepoint; |  20586     NoSafepointScope no_safepoint; | 
|  21814     result ^= raw; |  20587     result ^= raw; | 
|  21815     result.SetLength(len); |  20588     result.SetLength(len); | 
|  21816     result.SetHash(0); |  20589     result.SetHash(0); | 
|  21817   } |  20590   } | 
|  21818   return TwoByteString::raw(result); |  20591   return TwoByteString::raw(result); | 
|  21819 } |  20592 } | 
|  21820  |  20593  | 
|  21821  |  | 
|  21822 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, |  20594 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, | 
|  21823                                      intptr_t array_len, |  20595                                      intptr_t array_len, | 
|  21824                                      Heap::Space space) { |  20596                                      Heap::Space space) { | 
|  21825   ASSERT(array_len > 0); |  20597   ASSERT(array_len > 0); | 
|  21826   const String& result = String::Handle(TwoByteString::New(array_len, space)); |  20598   const String& result = String::Handle(TwoByteString::New(array_len, space)); | 
|  21827   { |  20599   { | 
|  21828     NoSafepointScope no_safepoint; |  20600     NoSafepointScope no_safepoint; | 
|  21829     memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); |  20601     memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); | 
|  21830   } |  20602   } | 
|  21831   return TwoByteString::raw(result); |  20603   return TwoByteString::raw(result); | 
|  21832 } |  20604 } | 
|  21833  |  20605  | 
|  21834  |  | 
|  21835 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |  20606 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, | 
|  21836                                      const int32_t* utf32_array, |  20607                                      const int32_t* utf32_array, | 
|  21837                                      intptr_t array_len, |  20608                                      intptr_t array_len, | 
|  21838                                      Heap::Space space) { |  20609                                      Heap::Space space) { | 
|  21839   ASSERT((array_len > 0) && (utf16_len >= array_len)); |  20610   ASSERT((array_len > 0) && (utf16_len >= array_len)); | 
|  21840   const String& result = String::Handle(TwoByteString::New(utf16_len, space)); |  20611   const String& result = String::Handle(TwoByteString::New(utf16_len, space)); | 
|  21841   { |  20612   { | 
|  21842     NoSafepointScope no_safepoint; |  20613     NoSafepointScope no_safepoint; | 
|  21843     intptr_t j = 0; |  20614     intptr_t j = 0; | 
|  21844     for (intptr_t i = 0; i < array_len; ++i) { |  20615     for (intptr_t i = 0; i < array_len; ++i) { | 
|  21845       if (Utf::IsSupplementary(utf32_array[i])) { |  20616       if (Utf::IsSupplementary(utf32_array[i])) { | 
|  21846         ASSERT(j < (utf16_len - 1)); |  20617         ASSERT(j < (utf16_len - 1)); | 
|  21847         Utf16::Encode(utf32_array[i], CharAddr(result, j)); |  20618         Utf16::Encode(utf32_array[i], CharAddr(result, j)); | 
|  21848         j += 2; |  20619         j += 2; | 
|  21849       } else { |  20620       } else { | 
|  21850         ASSERT(j < utf16_len); |  20621         ASSERT(j < utf16_len); | 
|  21851         *CharAddr(result, j) = utf32_array[i]; |  20622         *CharAddr(result, j) = utf32_array[i]; | 
|  21852         j += 1; |  20623         j += 1; | 
|  21853       } |  20624       } | 
|  21854     } |  20625     } | 
|  21855   } |  20626   } | 
|  21856   return TwoByteString::raw(result); |  20627   return TwoByteString::raw(result); | 
|  21857 } |  20628 } | 
|  21858  |  20629  | 
|  21859  |  | 
|  21860 RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) { |  20630 RawTwoByteString* TwoByteString::New(const String& str, Heap::Space space) { | 
|  21861   intptr_t len = str.Length(); |  20631   intptr_t len = str.Length(); | 
|  21862   const String& result = String::Handle(TwoByteString::New(len, space)); |  20632   const String& result = String::Handle(TwoByteString::New(len, space)); | 
|  21863   String::Copy(result, 0, str, 0, len); |  20633   String::Copy(result, 0, str, 0, len); | 
|  21864   return TwoByteString::raw(result); |  20634   return TwoByteString::raw(result); | 
|  21865 } |  20635 } | 
|  21866  |  20636  | 
|  21867  |  | 
|  21868 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data, |  20637 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data, | 
|  21869                                      intptr_t other_start_index, |  20638                                      intptr_t other_start_index, | 
|  21870                                      intptr_t other_len, |  20639                                      intptr_t other_len, | 
|  21871                                      Heap::Space space) { |  20640                                      Heap::Space space) { | 
|  21872   const String& result = String::Handle(TwoByteString::New(other_len, space)); |  20641   const String& result = String::Handle(TwoByteString::New(other_len, space)); | 
|  21873   if (other_len > 0) { |  20642   if (other_len > 0) { | 
|  21874     NoSafepointScope no_safepoint; |  20643     NoSafepointScope no_safepoint; | 
|  21875     memmove(TwoByteString::CharAddr(result, 0), |  20644     memmove(TwoByteString::CharAddr(result, 0), | 
|  21876             other_typed_data.DataAddr(other_start_index), |  20645             other_typed_data.DataAddr(other_start_index), | 
|  21877             other_len * sizeof(uint16_t)); |  20646             other_len * sizeof(uint16_t)); | 
|  21878   } |  20647   } | 
|  21879   return TwoByteString::raw(result); |  20648   return TwoByteString::raw(result); | 
|  21880 } |  20649 } | 
|  21881  |  20650  | 
|  21882  |  | 
|  21883 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data, |  20651 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data, | 
|  21884                                      intptr_t other_start_index, |  20652                                      intptr_t other_start_index, | 
|  21885                                      intptr_t other_len, |  20653                                      intptr_t other_len, | 
|  21886                                      Heap::Space space) { |  20654                                      Heap::Space space) { | 
|  21887   const String& result = String::Handle(TwoByteString::New(other_len, space)); |  20655   const String& result = String::Handle(TwoByteString::New(other_len, space)); | 
|  21888   if (other_len > 0) { |  20656   if (other_len > 0) { | 
|  21889     NoSafepointScope no_safepoint; |  20657     NoSafepointScope no_safepoint; | 
|  21890     memmove(TwoByteString::CharAddr(result, 0), |  20658     memmove(TwoByteString::CharAddr(result, 0), | 
|  21891             other_typed_data.DataAddr(other_start_index), |  20659             other_typed_data.DataAddr(other_start_index), | 
|  21892             other_len * sizeof(uint16_t)); |  20660             other_len * sizeof(uint16_t)); | 
|  21893   } |  20661   } | 
|  21894   return TwoByteString::raw(result); |  20662   return TwoByteString::raw(result); | 
|  21895 } |  20663 } | 
|  21896  |  20664  | 
|  21897  |  | 
|  21898 RawTwoByteString* TwoByteString::Concat(const String& str1, |  20665 RawTwoByteString* TwoByteString::Concat(const String& str1, | 
|  21899                                         const String& str2, |  20666                                         const String& str2, | 
|  21900                                         Heap::Space space) { |  20667                                         Heap::Space space) { | 
|  21901   intptr_t len1 = str1.Length(); |  20668   intptr_t len1 = str1.Length(); | 
|  21902   intptr_t len2 = str2.Length(); |  20669   intptr_t len2 = str2.Length(); | 
|  21903   intptr_t len = len1 + len2; |  20670   intptr_t len = len1 + len2; | 
|  21904   const String& result = String::Handle(TwoByteString::New(len, space)); |  20671   const String& result = String::Handle(TwoByteString::New(len, space)); | 
|  21905   String::Copy(result, 0, str1, 0, len1); |  20672   String::Copy(result, 0, str1, 0, len1); | 
|  21906   String::Copy(result, len1, str2, 0, len2); |  20673   String::Copy(result, len1, str2, 0, len2); | 
|  21907   return TwoByteString::raw(result); |  20674   return TwoByteString::raw(result); | 
|  21908 } |  20675 } | 
|  21909  |  20676  | 
|  21910  |  | 
|  21911 RawTwoByteString* TwoByteString::ConcatAll(const Array& strings, |  20677 RawTwoByteString* TwoByteString::ConcatAll(const Array& strings, | 
|  21912                                            intptr_t start, |  20678                                            intptr_t start, | 
|  21913                                            intptr_t end, |  20679                                            intptr_t end, | 
|  21914                                            intptr_t len, |  20680                                            intptr_t len, | 
|  21915                                            Heap::Space space) { |  20681                                            Heap::Space space) { | 
|  21916   ASSERT(!strings.IsNull()); |  20682   ASSERT(!strings.IsNull()); | 
|  21917   ASSERT(start >= 0); |  20683   ASSERT(start >= 0); | 
|  21918   ASSERT(end <= strings.Length()); |  20684   ASSERT(end <= strings.Length()); | 
|  21919   const String& result = String::Handle(TwoByteString::New(len, space)); |  20685   const String& result = String::Handle(TwoByteString::New(len, space)); | 
|  21920   String& str = String::Handle(); |  20686   String& str = String::Handle(); | 
|  21921   intptr_t pos = 0; |  20687   intptr_t pos = 0; | 
|  21922   for (intptr_t i = start; i < end; i++) { |  20688   for (intptr_t i = start; i < end; i++) { | 
|  21923     str ^= strings.At(i); |  20689     str ^= strings.At(i); | 
|  21924     const intptr_t str_len = str.Length(); |  20690     const intptr_t str_len = str.Length(); | 
|  21925     String::Copy(result, pos, str, 0, str_len); |  20691     String::Copy(result, pos, str, 0, str_len); | 
|  21926     ASSERT((kMaxElements - pos) >= str_len); |  20692     ASSERT((kMaxElements - pos) >= str_len); | 
|  21927     pos += str_len; |  20693     pos += str_len; | 
|  21928   } |  20694   } | 
|  21929   return TwoByteString::raw(result); |  20695   return TwoByteString::raw(result); | 
|  21930 } |  20696 } | 
|  21931  |  20697  | 
|  21932  |  | 
|  21933 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |  20698 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 
|  21934                                            const String& str, |  20699                                            const String& str, | 
|  21935                                            Heap::Space space) { |  20700                                            Heap::Space space) { | 
|  21936   ASSERT(!str.IsNull()); |  20701   ASSERT(!str.IsNull()); | 
|  21937   intptr_t len = str.Length(); |  20702   intptr_t len = str.Length(); | 
|  21938   const String& result = String::Handle(TwoByteString::New(len, space)); |  20703   const String& result = String::Handle(TwoByteString::New(len, space)); | 
|  21939   String::CodePointIterator it(str); |  20704   String::CodePointIterator it(str); | 
|  21940   intptr_t i = 0; |  20705   intptr_t i = 0; | 
|  21941   NoSafepointScope no_safepoint; |  20706   NoSafepointScope no_safepoint; | 
|  21942   while (it.Next()) { |  20707   while (it.Next()) { | 
|  21943     int32_t src = it.Current(); |  20708     int32_t src = it.Current(); | 
|  21944     int32_t dst = mapping(src); |  20709     int32_t dst = mapping(src); | 
|  21945     ASSERT(dst >= 0 && dst <= 0x10FFFF); |  20710     ASSERT(dst >= 0 && dst <= 0x10FFFF); | 
|  21946     intptr_t len = Utf16::Length(dst); |  20711     intptr_t len = Utf16::Length(dst); | 
|  21947     if (len == 1) { |  20712     if (len == 1) { | 
|  21948       *CharAddr(result, i) = dst; |  20713       *CharAddr(result, i) = dst; | 
|  21949     } else { |  20714     } else { | 
|  21950       ASSERT(len == 2); |  20715       ASSERT(len == 2); | 
|  21951       Utf16::Encode(dst, CharAddr(result, i)); |  20716       Utf16::Encode(dst, CharAddr(result, i)); | 
|  21952     } |  20717     } | 
|  21953     i += len; |  20718     i += len; | 
|  21954   } |  20719   } | 
|  21955   return TwoByteString::raw(result); |  20720   return TwoByteString::raw(result); | 
|  21956 } |  20721 } | 
|  21957  |  20722  | 
|  21958  |  | 
|  21959 void TwoByteString::SetPeer(const String& str, |  20723 void TwoByteString::SetPeer(const String& str, | 
|  21960                             intptr_t external_size, |  20724                             intptr_t external_size, | 
|  21961                             void* peer, |  20725                             void* peer, | 
|  21962                             Dart_PeerFinalizer cback) { |  20726                             Dart_PeerFinalizer cback) { | 
|  21963   ASSERT(!str.IsNull() && str.IsTwoByteString()); |  20727   ASSERT(!str.IsNull() && str.IsTwoByteString()); | 
|  21964   ASSERT(peer != NULL); |  20728   ASSERT(peer != NULL); | 
|  21965   ExternalStringData<uint16_t>* ext_data = |  20729   ExternalStringData<uint16_t>* ext_data = | 
|  21966       new ExternalStringData<uint16_t>(NULL, peer, cback); |  20730       new ExternalStringData<uint16_t>(NULL, peer, cback); | 
|  21967   AddFinalizer(str, ext_data, TwoByteString::Finalize, external_size); |  20731   AddFinalizer(str, ext_data, TwoByteString::Finalize, external_size); | 
|  21968   Isolate::Current()->heap()->SetPeer(str.raw(), peer); |  20732   Isolate::Current()->heap()->SetPeer(str.raw(), peer); | 
|  21969 } |  20733 } | 
|  21970  |  20734  | 
|  21971  |  | 
|  21972 void TwoByteString::Finalize(void* isolate_callback_data, |  20735 void TwoByteString::Finalize(void* isolate_callback_data, | 
|  21973                              Dart_WeakPersistentHandle handle, |  20736                              Dart_WeakPersistentHandle handle, | 
|  21974                              void* peer) { |  20737                              void* peer) { | 
|  21975   delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |  20738   delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 
|  21976 } |  20739 } | 
|  21977  |  20740  | 
|  21978  |  | 
|  21979 RawExternalOneByteString* ExternalOneByteString::New( |  20741 RawExternalOneByteString* ExternalOneByteString::New( | 
|  21980     const uint8_t* data, |  20742     const uint8_t* data, | 
|  21981     intptr_t len, |  20743     intptr_t len, | 
|  21982     void* peer, |  20744     void* peer, | 
|  21983     Dart_PeerFinalizer callback, |  20745     Dart_PeerFinalizer callback, | 
|  21984     Heap::Space space) { |  20746     Heap::Space space) { | 
|  21985   ASSERT(Isolate::Current()->object_store()->external_one_byte_string_class() != |  20747   ASSERT(Isolate::Current()->object_store()->external_one_byte_string_class() != | 
|  21986          Class::null()); |  20748          Class::null()); | 
|  21987   if (len < 0 || len > kMaxElements) { |  20749   if (len < 0 || len > kMaxElements) { | 
|  21988     // This should be caught before we reach here. |  20750     // This should be caught before we reach here. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  22001     result.SetLength(len); |  20763     result.SetLength(len); | 
|  22002     result.SetHash(0); |  20764     result.SetHash(0); | 
|  22003     SetExternalData(result, external_data); |  20765     SetExternalData(result, external_data); | 
|  22004   } |  20766   } | 
|  22005   intptr_t external_size = len; |  20767   intptr_t external_size = len; | 
|  22006   AddFinalizer(result, external_data, ExternalOneByteString::Finalize, |  20768   AddFinalizer(result, external_data, ExternalOneByteString::Finalize, | 
|  22007                external_size); |  20769                external_size); | 
|  22008   return ExternalOneByteString::raw(result); |  20770   return ExternalOneByteString::raw(result); | 
|  22009 } |  20771 } | 
|  22010  |  20772  | 
|  22011  |  | 
|  22012 void ExternalOneByteString::Finalize(void* isolate_callback_data, |  20773 void ExternalOneByteString::Finalize(void* isolate_callback_data, | 
|  22013                                      Dart_WeakPersistentHandle handle, |  20774                                      Dart_WeakPersistentHandle handle, | 
|  22014                                      void* peer) { |  20775                                      void* peer) { | 
|  22015   delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); |  20776   delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); | 
|  22016 } |  20777 } | 
|  22017  |  20778  | 
|  22018  |  | 
|  22019 RawExternalTwoByteString* ExternalTwoByteString::New( |  20779 RawExternalTwoByteString* ExternalTwoByteString::New( | 
|  22020     const uint16_t* data, |  20780     const uint16_t* data, | 
|  22021     intptr_t len, |  20781     intptr_t len, | 
|  22022     void* peer, |  20782     void* peer, | 
|  22023     Dart_PeerFinalizer callback, |  20783     Dart_PeerFinalizer callback, | 
|  22024     Heap::Space space) { |  20784     Heap::Space space) { | 
|  22025   ASSERT(Isolate::Current()->object_store()->external_two_byte_string_class() != |  20785   ASSERT(Isolate::Current()->object_store()->external_two_byte_string_class() != | 
|  22026          Class::null()); |  20786          Class::null()); | 
|  22027   if (len < 0 || len > kMaxElements) { |  20787   if (len < 0 || len > kMaxElements) { | 
|  22028     // This should be caught before we reach here. |  20788     // This should be caught before we reach here. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  22041     result.SetLength(len); |  20801     result.SetLength(len); | 
|  22042     result.SetHash(0); |  20802     result.SetHash(0); | 
|  22043     SetExternalData(result, external_data); |  20803     SetExternalData(result, external_data); | 
|  22044   } |  20804   } | 
|  22045   intptr_t external_size = len * 2; |  20805   intptr_t external_size = len * 2; | 
|  22046   AddFinalizer(result, external_data, ExternalTwoByteString::Finalize, |  20806   AddFinalizer(result, external_data, ExternalTwoByteString::Finalize, | 
|  22047                external_size); |  20807                external_size); | 
|  22048   return ExternalTwoByteString::raw(result); |  20808   return ExternalTwoByteString::raw(result); | 
|  22049 } |  20809 } | 
|  22050  |  20810  | 
|  22051  |  | 
|  22052 void ExternalTwoByteString::Finalize(void* isolate_callback_data, |  20811 void ExternalTwoByteString::Finalize(void* isolate_callback_data, | 
|  22053                                      Dart_WeakPersistentHandle handle, |  20812                                      Dart_WeakPersistentHandle handle, | 
|  22054                                      void* peer) { |  20813                                      void* peer) { | 
|  22055   delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |  20814   delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 
|  22056 } |  20815 } | 
|  22057  |  20816  | 
|  22058  |  | 
|  22059 RawBool* Bool::New(bool value) { |  20817 RawBool* Bool::New(bool value) { | 
|  22060   ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null()); |  20818   ASSERT(Isolate::Current()->object_store()->bool_class() != Class::null()); | 
|  22061   Bool& result = Bool::Handle(); |  20819   Bool& result = Bool::Handle(); | 
|  22062   { |  20820   { | 
|  22063     // Since the two boolean instances are singletons we allocate them straight |  20821     // Since the two boolean instances are singletons we allocate them straight | 
|  22064     // in the old generation. |  20822     // in the old generation. | 
|  22065     RawObject* raw = |  20823     RawObject* raw = | 
|  22066         Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld); |  20824         Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld); | 
|  22067     NoSafepointScope no_safepoint; |  20825     NoSafepointScope no_safepoint; | 
|  22068     result ^= raw; |  20826     result ^= raw; | 
|  22069   } |  20827   } | 
|  22070   result.set_value(value); |  20828   result.set_value(value); | 
|  22071   result.SetCanonical(); |  20829   result.SetCanonical(); | 
|  22072   return result.raw(); |  20830   return result.raw(); | 
|  22073 } |  20831 } | 
|  22074  |  20832  | 
|  22075  |  | 
|  22076 const char* Bool::ToCString() const { |  20833 const char* Bool::ToCString() const { | 
|  22077   return value() ? "true" : "false"; |  20834   return value() ? "true" : "false"; | 
|  22078 } |  20835 } | 
|  22079  |  20836  | 
|  22080  |  | 
|  22081 bool Array::CanonicalizeEquals(const Instance& other) const { |  20837 bool Array::CanonicalizeEquals(const Instance& other) const { | 
|  22082   if (this->raw() == other.raw()) { |  20838   if (this->raw() == other.raw()) { | 
|  22083     // Both handles point to the same raw instance. |  20839     // Both handles point to the same raw instance. | 
|  22084     return true; |  20840     return true; | 
|  22085   } |  20841   } | 
|  22086  |  20842  | 
|  22087   // An Array may be compared to an ImmutableArray. |  20843   // An Array may be compared to an ImmutableArray. | 
|  22088   if (!other.IsArray() || other.IsNull()) { |  20844   if (!other.IsArray() || other.IsNull()) { | 
|  22089     return false; |  20845     return false; | 
|  22090   } |  20846   } | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  22109   } |  20865   } | 
|  22110   const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); |  20866   const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); | 
|  22111   const TypeArguments& other_type_args = |  20867   const TypeArguments& other_type_args = | 
|  22112       TypeArguments::Handle(other.GetTypeArguments()); |  20868       TypeArguments::Handle(other.GetTypeArguments()); | 
|  22113   if (!type_args.Equals(other_type_args)) { |  20869   if (!type_args.Equals(other_type_args)) { | 
|  22114     return false; |  20870     return false; | 
|  22115   } |  20871   } | 
|  22116   return true; |  20872   return true; | 
|  22117 } |  20873 } | 
|  22118  |  20874  | 
|  22119  |  | 
|  22120 uword Array::ComputeCanonicalTableHash() const { |  20875 uword Array::ComputeCanonicalTableHash() const { | 
|  22121   ASSERT(!IsNull()); |  20876   ASSERT(!IsNull()); | 
|  22122   NoSafepointScope no_safepoint; |  20877   NoSafepointScope no_safepoint; | 
|  22123   intptr_t len = Length(); |  20878   intptr_t len = Length(); | 
|  22124   uword hash = len; |  20879   uword hash = len; | 
|  22125   uword value = reinterpret_cast<uword>(GetTypeArguments()); |  20880   uword value = reinterpret_cast<uword>(GetTypeArguments()); | 
|  22126   hash = CombineHashes(hash, value); |  20881   hash = CombineHashes(hash, value); | 
|  22127   for (intptr_t i = 0; i < len; i++) { |  20882   for (intptr_t i = 0; i < len; i++) { | 
|  22128     value = reinterpret_cast<uword>(At(i)); |  20883     value = reinterpret_cast<uword>(At(i)); | 
|  22129     hash = CombineHashes(hash, value); |  20884     hash = CombineHashes(hash, value); | 
|  22130   } |  20885   } | 
|  22131   return FinalizeHash(hash, kHashBits); |  20886   return FinalizeHash(hash, kHashBits); | 
|  22132 } |  20887 } | 
|  22133  |  20888  | 
|  22134  |  | 
|  22135 RawArray* Array::New(intptr_t len, Heap::Space space) { |  20889 RawArray* Array::New(intptr_t len, Heap::Space space) { | 
|  22136   ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); |  20890   ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); | 
|  22137   return New(kClassId, len, space); |  20891   return New(kClassId, len, space); | 
|  22138 } |  20892 } | 
|  22139  |  20893  | 
|  22140  |  | 
|  22141 RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) { |  20894 RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) { | 
|  22142   if ((len < 0) || (len > Array::kMaxElements)) { |  20895   if ((len < 0) || (len > Array::kMaxElements)) { | 
|  22143     // This should be caught before we reach here. |  20896     // This should be caught before we reach here. | 
|  22144     FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); |  20897     FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len); | 
|  22145   } |  20898   } | 
|  22146   { |  20899   { | 
|  22147     RawArray* raw = reinterpret_cast<RawArray*>( |  20900     RawArray* raw = reinterpret_cast<RawArray*>( | 
|  22148         Object::Allocate(class_id, Array::InstanceSize(len), space)); |  20901         Object::Allocate(class_id, Array::InstanceSize(len), space)); | 
|  22149     NoSafepointScope no_safepoint; |  20902     NoSafepointScope no_safepoint; | 
|  22150     raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); |  20903     raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len)); | 
|  22151     return raw; |  20904     return raw; | 
|  22152   } |  20905   } | 
|  22153 } |  20906 } | 
|  22154  |  20907  | 
|  22155  |  | 
|  22156 RawArray* Array::Slice(intptr_t start, |  20908 RawArray* Array::Slice(intptr_t start, | 
|  22157                        intptr_t count, |  20909                        intptr_t count, | 
|  22158                        bool with_type_argument) const { |  20910                        bool with_type_argument) const { | 
|  22159   // TODO(vegorov) introduce an array allocation method that fills newly |  20911   // TODO(vegorov) introduce an array allocation method that fills newly | 
|  22160   // allocated array with values from the given source array instead of |  20912   // allocated array with values from the given source array instead of | 
|  22161   // null-initializing all elements. |  20913   // null-initializing all elements. | 
|  22162   Array& dest = Array::Handle(Array::New(count)); |  20914   Array& dest = Array::Handle(Array::New(count)); | 
|  22163   dest.StorePointers(dest.ObjectAddr(0), ObjectAddr(start), count); |  20915   dest.StorePointers(dest.ObjectAddr(0), ObjectAddr(start), count); | 
|  22164  |  20916  | 
|  22165   if (with_type_argument) { |  20917   if (with_type_argument) { | 
|  22166     dest.SetTypeArguments(TypeArguments::Handle(GetTypeArguments())); |  20918     dest.SetTypeArguments(TypeArguments::Handle(GetTypeArguments())); | 
|  22167   } |  20919   } | 
|  22168  |  20920  | 
|  22169   return dest.raw(); |  20921   return dest.raw(); | 
|  22170 } |  20922 } | 
|  22171  |  20923  | 
|  22172  |  | 
|  22173 void Array::MakeImmutable() const { |  20924 void Array::MakeImmutable() const { | 
|  22174   if (IsImmutable()) return; |  20925   if (IsImmutable()) return; | 
|  22175   ASSERT(!IsCanonical()); |  20926   ASSERT(!IsCanonical()); | 
|  22176   NoSafepointScope no_safepoint; |  20927   NoSafepointScope no_safepoint; | 
|  22177   uint32_t tags = raw_ptr()->tags_; |  20928   uint32_t tags = raw_ptr()->tags_; | 
|  22178   uint32_t old_tags; |  20929   uint32_t old_tags; | 
|  22179   do { |  20930   do { | 
|  22180     old_tags = tags; |  20931     old_tags = tags; | 
|  22181     uint32_t new_tags = |  20932     uint32_t new_tags = | 
|  22182         RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); |  20933         RawObject::ClassIdTag::update(kImmutableArrayCid, old_tags); | 
|  22183     tags = CompareAndSwapTags(old_tags, new_tags); |  20934     tags = CompareAndSwapTags(old_tags, new_tags); | 
|  22184   } while (tags != old_tags); |  20935   } while (tags != old_tags); | 
|  22185 } |  20936 } | 
|  22186  |  20937  | 
|  22187  |  | 
|  22188 const char* Array::ToCString() const { |  20938 const char* Array::ToCString() const { | 
|  22189   if (IsNull()) { |  20939   if (IsNull()) { | 
|  22190     return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; |  20940     return IsImmutable() ? "_ImmutableList NULL" : "_List NULL"; | 
|  22191   } |  20941   } | 
|  22192   Zone* zone = Thread::Current()->zone(); |  20942   Zone* zone = Thread::Current()->zone(); | 
|  22193   const char* format = |  20943   const char* format = | 
|  22194       IsImmutable() ? "_ImmutableList len:%" Pd : "_List len:%" Pd; |  20944       IsImmutable() ? "_ImmutableList len:%" Pd : "_List len:%" Pd; | 
|  22195   return zone->PrintToString(format, Length()); |  20945   return zone->PrintToString(format, Length()); | 
|  22196 } |  20946 } | 
|  22197  |  20947  | 
|  22198  |  | 
|  22199 RawArray* Array::Grow(const Array& source, |  20948 RawArray* Array::Grow(const Array& source, | 
|  22200                       intptr_t new_length, |  20949                       intptr_t new_length, | 
|  22201                       Heap::Space space) { |  20950                       Heap::Space space) { | 
|  22202   Zone* zone = Thread::Current()->zone(); |  20951   Zone* zone = Thread::Current()->zone(); | 
|  22203   const Array& result = Array::Handle(zone, Array::New(new_length, space)); |  20952   const Array& result = Array::Handle(zone, Array::New(new_length, space)); | 
|  22204   intptr_t len = 0; |  20953   intptr_t len = 0; | 
|  22205   if (!source.IsNull()) { |  20954   if (!source.IsNull()) { | 
|  22206     len = source.Length(); |  20955     len = source.Length(); | 
|  22207     result.SetTypeArguments( |  20956     result.SetTypeArguments( | 
|  22208         TypeArguments::Handle(zone, source.GetTypeArguments())); |  20957         TypeArguments::Handle(zone, source.GetTypeArguments())); | 
|  22209   } |  20958   } | 
|  22210   ASSERT(new_length >= len);  // Cannot copy 'source' into new array. |  20959   ASSERT(new_length >= len);  // Cannot copy 'source' into new array. | 
|  22211   ASSERT(new_length != len);  // Unnecessary copying of array. |  20960   ASSERT(new_length != len);  // Unnecessary copying of array. | 
|  22212   PassiveObject& obj = PassiveObject::Handle(zone); |  20961   PassiveObject& obj = PassiveObject::Handle(zone); | 
|  22213   for (int i = 0; i < len; i++) { |  20962   for (int i = 0; i < len; i++) { | 
|  22214     obj = source.At(i); |  20963     obj = source.At(i); | 
|  22215     result.SetAt(i, obj); |  20964     result.SetAt(i, obj); | 
|  22216   } |  20965   } | 
|  22217   return result.raw(); |  20966   return result.raw(); | 
|  22218 } |  20967 } | 
|  22219  |  20968  | 
|  22220  |  | 
|  22221 RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array, |  20969 RawArray* Array::MakeFixedLength(const GrowableObjectArray& growable_array, | 
|  22222                                  bool unique) { |  20970                                  bool unique) { | 
|  22223   ASSERT(!growable_array.IsNull()); |  20971   ASSERT(!growable_array.IsNull()); | 
|  22224   Thread* thread = Thread::Current(); |  20972   Thread* thread = Thread::Current(); | 
|  22225   Zone* zone = thread->zone(); |  20973   Zone* zone = thread->zone(); | 
|  22226   intptr_t used_len = growable_array.Length(); |  20974   intptr_t used_len = growable_array.Length(); | 
|  22227   // Get the type arguments and prepare to copy them. |  20975   // Get the type arguments and prepare to copy them. | 
|  22228   const TypeArguments& type_arguments = |  20976   const TypeArguments& type_arguments = | 
|  22229       TypeArguments::Handle(growable_array.GetTypeArguments()); |  20977       TypeArguments::Handle(growable_array.GetTypeArguments()); | 
|  22230   if (used_len == 0) { |  20978   if (used_len == 0) { | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  22274   // in RawObject::SizeFromClass must handle this special case. |  21022   // in RawObject::SizeFromClass must handle this special case. | 
|  22275   array.SetLength(used_len); |  21023   array.SetLength(used_len); | 
|  22276  |  21024  | 
|  22277   // Null the GrowableObjectArray, we are removing its backing array. |  21025   // Null the GrowableObjectArray, we are removing its backing array. | 
|  22278   growable_array.SetLength(0); |  21026   growable_array.SetLength(0); | 
|  22279   growable_array.SetData(Object::empty_array()); |  21027   growable_array.SetData(Object::empty_array()); | 
|  22280  |  21028  | 
|  22281   return array.raw(); |  21029   return array.raw(); | 
|  22282 } |  21030 } | 
|  22283  |  21031  | 
|  22284  |  | 
|  22285 bool Array::CheckAndCanonicalizeFields(Thread* thread, |  21032 bool Array::CheckAndCanonicalizeFields(Thread* thread, | 
|  22286                                        const char** error_str) const { |  21033                                        const char** error_str) const { | 
|  22287   intptr_t len = Length(); |  21034   intptr_t len = Length(); | 
|  22288   if (len > 0) { |  21035   if (len > 0) { | 
|  22289     Zone* zone = thread->zone(); |  21036     Zone* zone = thread->zone(); | 
|  22290     Object& obj = Object::Handle(zone); |  21037     Object& obj = Object::Handle(zone); | 
|  22291     // Iterate over all elements, canonicalize numbers and strings, expect all |  21038     // Iterate over all elements, canonicalize numbers and strings, expect all | 
|  22292     // other instances to be canonical otherwise report error (return false). |  21039     // other instances to be canonical otherwise report error (return false). | 
|  22293     for (intptr_t i = 0; i < len; i++) { |  21040     for (intptr_t i = 0; i < len; i++) { | 
|  22294       obj = At(i); |  21041       obj = At(i); | 
|  22295       if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |  21042       if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | 
|  22296         if (obj.IsNumber() || obj.IsString()) { |  21043         if (obj.IsNumber() || obj.IsString()) { | 
|  22297           obj = Instance::Cast(obj).CheckAndCanonicalize(thread, NULL); |  21044           obj = Instance::Cast(obj).CheckAndCanonicalize(thread, NULL); | 
|  22298           ASSERT(!obj.IsNull()); |  21045           ASSERT(!obj.IsNull()); | 
|  22299           this->SetAt(i, obj); |  21046           this->SetAt(i, obj); | 
|  22300         } else { |  21047         } else { | 
|  22301           ASSERT(error_str != NULL); |  21048           ASSERT(error_str != NULL); | 
|  22302           char* chars = OS::SCreate(zone, "element at index %" Pd ": %s\n", i, |  21049           char* chars = OS::SCreate(zone, "element at index %" Pd ": %s\n", i, | 
|  22303                                     obj.ToCString()); |  21050                                     obj.ToCString()); | 
|  22304           *error_str = chars; |  21051           *error_str = chars; | 
|  22305           return false; |  21052           return false; | 
|  22306         } |  21053         } | 
|  22307       } |  21054       } | 
|  22308     } |  21055     } | 
|  22309   } |  21056   } | 
|  22310   return true; |  21057   return true; | 
|  22311 } |  21058 } | 
|  22312  |  21059  | 
|  22313  |  | 
|  22314 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) { |  21060 RawImmutableArray* ImmutableArray::New(intptr_t len, Heap::Space space) { | 
|  22315   ASSERT(Isolate::Current()->object_store()->immutable_array_class() != |  21061   ASSERT(Isolate::Current()->object_store()->immutable_array_class() != | 
|  22316          Class::null()); |  21062          Class::null()); | 
|  22317   return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); |  21063   return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); | 
|  22318 } |  21064 } | 
|  22319  |  21065  | 
|  22320  |  | 
|  22321 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { |  21066 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { | 
|  22322   ASSERT(!IsNull()); |  21067   ASSERT(!IsNull()); | 
|  22323   if (Length() == Capacity()) { |  21068   if (Length() == Capacity()) { | 
|  22324     // Grow from 0 to 3, and then double + 1. |  21069     // Grow from 0 to 3, and then double + 1. | 
|  22325     intptr_t new_capacity = (Capacity() * 2) | 3; |  21070     intptr_t new_capacity = (Capacity() * 2) | 3; | 
|  22326     if (new_capacity <= Capacity()) { |  21071     if (new_capacity <= Capacity()) { | 
|  22327       Exceptions::ThrowOOM(); |  21072       Exceptions::ThrowOOM(); | 
|  22328       UNREACHABLE(); |  21073       UNREACHABLE(); | 
|  22329     } |  21074     } | 
|  22330     Grow(new_capacity, space); |  21075     Grow(new_capacity, space); | 
|  22331   } |  21076   } | 
|  22332   ASSERT(Length() < Capacity()); |  21077   ASSERT(Length() < Capacity()); | 
|  22333   intptr_t index = Length(); |  21078   intptr_t index = Length(); | 
|  22334   SetLength(index + 1); |  21079   SetLength(index + 1); | 
|  22335   SetAt(index, value); |  21080   SetAt(index, value); | 
|  22336 } |  21081 } | 
|  22337  |  21082  | 
|  22338  |  | 
|  22339 void GrowableObjectArray::Grow(intptr_t new_capacity, Heap::Space space) const { |  21083 void GrowableObjectArray::Grow(intptr_t new_capacity, Heap::Space space) const { | 
|  22340   ASSERT(new_capacity > Capacity()); |  21084   ASSERT(new_capacity > Capacity()); | 
|  22341   const Array& contents = Array::Handle(data()); |  21085   const Array& contents = Array::Handle(data()); | 
|  22342   const Array& new_contents = |  21086   const Array& new_contents = | 
|  22343       Array::Handle(Array::Grow(contents, new_capacity, space)); |  21087       Array::Handle(Array::Grow(contents, new_capacity, space)); | 
|  22344   StorePointer(&(raw_ptr()->data_), new_contents.raw()); |  21088   StorePointer(&(raw_ptr()->data_), new_contents.raw()); | 
|  22345 } |  21089 } | 
|  22346  |  21090  | 
|  22347  |  | 
|  22348 RawObject* GrowableObjectArray::RemoveLast() const { |  21091 RawObject* GrowableObjectArray::RemoveLast() const { | 
|  22349   ASSERT(!IsNull()); |  21092   ASSERT(!IsNull()); | 
|  22350   ASSERT(Length() > 0); |  21093   ASSERT(Length() > 0); | 
|  22351   intptr_t index = Length() - 1; |  21094   intptr_t index = Length() - 1; | 
|  22352   const Array& contents = Array::Handle(data()); |  21095   const Array& contents = Array::Handle(data()); | 
|  22353   const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); |  21096   const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); | 
|  22354   contents.SetAt(index, Object::null_object()); |  21097   contents.SetAt(index, Object::null_object()); | 
|  22355   SetLength(index); |  21098   SetLength(index); | 
|  22356   return obj.raw(); |  21099   return obj.raw(); | 
|  22357 } |  21100 } | 
|  22358  |  21101  | 
|  22359  |  | 
|  22360 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, |  21102 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, | 
|  22361                                                  Heap::Space space) { |  21103                                                  Heap::Space space) { | 
|  22362   RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw() |  21104   RawArray* raw_data = (capacity == 0) ? Object::empty_array().raw() | 
|  22363                                        : Array::New(capacity, space); |  21105                                        : Array::New(capacity, space); | 
|  22364   const Array& data = Array::Handle(raw_data); |  21106   const Array& data = Array::Handle(raw_data); | 
|  22365   return New(data, space); |  21107   return New(data, space); | 
|  22366 } |  21108 } | 
|  22367  |  21109  | 
|  22368  |  | 
|  22369 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, |  21110 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, | 
|  22370                                                  Heap::Space space) { |  21111                                                  Heap::Space space) { | 
|  22371   ASSERT(Isolate::Current()->object_store()->growable_object_array_class() != |  21112   ASSERT(Isolate::Current()->object_store()->growable_object_array_class() != | 
|  22372          Class::null()); |  21113          Class::null()); | 
|  22373   GrowableObjectArray& result = GrowableObjectArray::Handle(); |  21114   GrowableObjectArray& result = GrowableObjectArray::Handle(); | 
|  22374   { |  21115   { | 
|  22375     RawObject* raw = |  21116     RawObject* raw = | 
|  22376         Object::Allocate(GrowableObjectArray::kClassId, |  21117         Object::Allocate(GrowableObjectArray::kClassId, | 
|  22377                          GrowableObjectArray::InstanceSize(), space); |  21118                          GrowableObjectArray::InstanceSize(), space); | 
|  22378     NoSafepointScope no_safepoint; |  21119     NoSafepointScope no_safepoint; | 
|  22379     result ^= raw; |  21120     result ^= raw; | 
|  22380     result.SetLength(0); |  21121     result.SetLength(0); | 
|  22381     result.SetData(array); |  21122     result.SetData(array); | 
|  22382   } |  21123   } | 
|  22383   return result.raw(); |  21124   return result.raw(); | 
|  22384 } |  21125 } | 
|  22385  |  21126  | 
|  22386  |  | 
|  22387 const char* GrowableObjectArray::ToCString() const { |  21127 const char* GrowableObjectArray::ToCString() const { | 
|  22388   if (IsNull()) { |  21128   if (IsNull()) { | 
|  22389     return "_GrowableList: null"; |  21129     return "_GrowableList: null"; | 
|  22390   } |  21130   } | 
|  22391   return OS::SCreate(Thread::Current()->zone(), |  21131   return OS::SCreate(Thread::Current()->zone(), | 
|  22392                      "Instance(length:%" Pd ") of '_GrowableList'", Length()); |  21132                      "Instance(length:%" Pd ") of '_GrowableList'", Length()); | 
|  22393 } |  21133 } | 
|  22394  |  21134  | 
|  22395  |  | 
|  22396 // Equivalent to Dart's operator "==" and hashCode. |  21135 // Equivalent to Dart's operator "==" and hashCode. | 
|  22397 class DefaultHashTraits { |  21136 class DefaultHashTraits { | 
|  22398  public: |  21137  public: | 
|  22399   static const char* Name() { return "DefaultHashTraits"; } |  21138   static const char* Name() { return "DefaultHashTraits"; } | 
|  22400   static bool ReportStats() { return false; } |  21139   static bool ReportStats() { return false; } | 
|  22401  |  21140  | 
|  22402   static bool IsMatch(const Object& a, const Object& b) { |  21141   static bool IsMatch(const Object& a, const Object& b) { | 
|  22403     if (a.IsNull() || b.IsNull()) { |  21142     if (a.IsNull() || b.IsNull()) { | 
|  22404       return (a.IsNull() && b.IsNull()); |  21143       return (a.IsNull() && b.IsNull()); | 
|  22405     } else { |  21144     } else { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  22421       return static_cast<uword>(Smi::Cast(hash_code).AsTruncatedUint32Value()); |  21160       return static_cast<uword>(Smi::Cast(hash_code).AsTruncatedUint32Value()); | 
|  22422     } else if (hash_code.IsInteger()) { |  21161     } else if (hash_code.IsInteger()) { | 
|  22423       return static_cast<uword>( |  21162       return static_cast<uword>( | 
|  22424           Integer::Cast(hash_code).AsTruncatedUint32Value()); |  21163           Integer::Cast(hash_code).AsTruncatedUint32Value()); | 
|  22425     } else { |  21164     } else { | 
|  22426       return 0; |  21165       return 0; | 
|  22427     } |  21166     } | 
|  22428   } |  21167   } | 
|  22429 }; |  21168 }; | 
|  22430  |  21169  | 
|  22431  |  | 
|  22432 RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) { |  21170 RawLinkedHashMap* LinkedHashMap::NewDefault(Heap::Space space) { | 
|  22433   const Array& data = Array::Handle(Array::New(kInitialIndexSize, space)); |  21171   const Array& data = Array::Handle(Array::New(kInitialIndexSize, space)); | 
|  22434   const TypedData& index = TypedData::Handle( |  21172   const TypedData& index = TypedData::Handle( | 
|  22435       TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space)); |  21173       TypedData::New(kTypedDataUint32ArrayCid, kInitialIndexSize, space)); | 
|  22436   // On 32-bit, the top bits are wasted to avoid Mint allocation. |  21174   // On 32-bit, the top bits are wasted to avoid Mint allocation. | 
|  22437   static const intptr_t kAvailableBits = (kSmiBits >= 32) ? 32 : kSmiBits; |  21175   static const intptr_t kAvailableBits = (kSmiBits >= 32) ? 32 : kSmiBits; | 
|  22438   static const intptr_t kInitialHashMask = |  21176   static const intptr_t kInitialHashMask = | 
|  22439       (1 << (kAvailableBits - kInitialIndexBits)) - 1; |  21177       (1 << (kAvailableBits - kInitialIndexBits)) - 1; | 
|  22440   return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space); |  21178   return LinkedHashMap::New(data, index, kInitialHashMask, 0, 0, space); | 
|  22441 } |  21179 } | 
|  22442  |  21180  | 
|  22443  |  | 
|  22444 RawLinkedHashMap* LinkedHashMap::New(const Array& data, |  21181 RawLinkedHashMap* LinkedHashMap::New(const Array& data, | 
|  22445                                      const TypedData& index, |  21182                                      const TypedData& index, | 
|  22446                                      intptr_t hash_mask, |  21183                                      intptr_t hash_mask, | 
|  22447                                      intptr_t used_data, |  21184                                      intptr_t used_data, | 
|  22448                                      intptr_t deleted_keys, |  21185                                      intptr_t deleted_keys, | 
|  22449                                      Heap::Space space) { |  21186                                      Heap::Space space) { | 
|  22450   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != |  21187   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != | 
|  22451          Class::null()); |  21188          Class::null()); | 
|  22452   LinkedHashMap& result = |  21189   LinkedHashMap& result = | 
|  22453       LinkedHashMap::Handle(LinkedHashMap::NewUninitialized(space)); |  21190       LinkedHashMap::Handle(LinkedHashMap::NewUninitialized(space)); | 
|  22454   result.SetData(data); |  21191   result.SetData(data); | 
|  22455   result.SetIndex(index); |  21192   result.SetIndex(index); | 
|  22456   result.SetHashMask(hash_mask); |  21193   result.SetHashMask(hash_mask); | 
|  22457   result.SetUsedData(used_data); |  21194   result.SetUsedData(used_data); | 
|  22458   result.SetDeletedKeys(deleted_keys); |  21195   result.SetDeletedKeys(deleted_keys); | 
|  22459   return result.raw(); |  21196   return result.raw(); | 
|  22460 } |  21197 } | 
|  22461  |  21198  | 
|  22462  |  | 
|  22463 RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) { |  21199 RawLinkedHashMap* LinkedHashMap::NewUninitialized(Heap::Space space) { | 
|  22464   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != |  21200   ASSERT(Isolate::Current()->object_store()->linked_hash_map_class() != | 
|  22465          Class::null()); |  21201          Class::null()); | 
|  22466   LinkedHashMap& result = LinkedHashMap::Handle(); |  21202   LinkedHashMap& result = LinkedHashMap::Handle(); | 
|  22467   { |  21203   { | 
|  22468     RawObject* raw = Object::Allocate(LinkedHashMap::kClassId, |  21204     RawObject* raw = Object::Allocate(LinkedHashMap::kClassId, | 
|  22469                                       LinkedHashMap::InstanceSize(), space); |  21205                                       LinkedHashMap::InstanceSize(), space); | 
|  22470     NoSafepointScope no_safepoint; |  21206     NoSafepointScope no_safepoint; | 
|  22471     result ^= raw; |  21207     result ^= raw; | 
|  22472   } |  21208   } | 
|  22473   return result.raw(); |  21209   return result.raw(); | 
|  22474 } |  21210 } | 
|  22475  |  21211  | 
|  22476  |  | 
|  22477 const char* LinkedHashMap::ToCString() const { |  21212 const char* LinkedHashMap::ToCString() const { | 
|  22478   Zone* zone = Thread::Current()->zone(); |  21213   Zone* zone = Thread::Current()->zone(); | 
|  22479   return zone->PrintToString("_LinkedHashMap len:%" Pd, Length()); |  21214   return zone->PrintToString("_LinkedHashMap len:%" Pd, Length()); | 
|  22480 } |  21215 } | 
|  22481  |  21216  | 
|  22482  |  | 
|  22483 RawFloat32x4* Float32x4::New(float v0, |  21217 RawFloat32x4* Float32x4::New(float v0, | 
|  22484                              float v1, |  21218                              float v1, | 
|  22485                              float v2, |  21219                              float v2, | 
|  22486                              float v3, |  21220                              float v3, | 
|  22487                              Heap::Space space) { |  21221                              Heap::Space space) { | 
|  22488   ASSERT(Isolate::Current()->object_store()->float32x4_class() != |  21222   ASSERT(Isolate::Current()->object_store()->float32x4_class() != | 
|  22489          Class::null()); |  21223          Class::null()); | 
|  22490   Float32x4& result = Float32x4::Handle(); |  21224   Float32x4& result = Float32x4::Handle(); | 
|  22491   { |  21225   { | 
|  22492     RawObject* raw = |  21226     RawObject* raw = | 
|  22493         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); |  21227         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); | 
|  22494     NoSafepointScope no_safepoint; |  21228     NoSafepointScope no_safepoint; | 
|  22495     result ^= raw; |  21229     result ^= raw; | 
|  22496   } |  21230   } | 
|  22497   result.set_x(v0); |  21231   result.set_x(v0); | 
|  22498   result.set_y(v1); |  21232   result.set_y(v1); | 
|  22499   result.set_z(v2); |  21233   result.set_z(v2); | 
|  22500   result.set_w(v3); |  21234   result.set_w(v3); | 
|  22501   return result.raw(); |  21235   return result.raw(); | 
|  22502 } |  21236 } | 
|  22503  |  21237  | 
|  22504  |  | 
|  22505 RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) { |  21238 RawFloat32x4* Float32x4::New(simd128_value_t value, Heap::Space space) { | 
|  22506   ASSERT(Isolate::Current()->object_store()->float32x4_class() != |  21239   ASSERT(Isolate::Current()->object_store()->float32x4_class() != | 
|  22507          Class::null()); |  21240          Class::null()); | 
|  22508   Float32x4& result = Float32x4::Handle(); |  21241   Float32x4& result = Float32x4::Handle(); | 
|  22509   { |  21242   { | 
|  22510     RawObject* raw = |  21243     RawObject* raw = | 
|  22511         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); |  21244         Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space); | 
|  22512     NoSafepointScope no_safepoint; |  21245     NoSafepointScope no_safepoint; | 
|  22513     result ^= raw; |  21246     result ^= raw; | 
|  22514   } |  21247   } | 
|  22515   result.set_value(value); |  21248   result.set_value(value); | 
|  22516   return result.raw(); |  21249   return result.raw(); | 
|  22517 } |  21250 } | 
|  22518  |  21251  | 
|  22519  |  | 
|  22520 simd128_value_t Float32x4::value() const { |  21252 simd128_value_t Float32x4::value() const { | 
|  22521   return ReadUnaligned( |  21253   return ReadUnaligned( | 
|  22522       reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); |  21254       reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); | 
|  22523 } |  21255 } | 
|  22524  |  21256  | 
|  22525  |  | 
|  22526 void Float32x4::set_value(simd128_value_t value) const { |  21257 void Float32x4::set_value(simd128_value_t value) const { | 
|  22527   StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), |  21258   StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), | 
|  22528                  value); |  21259                  value); | 
|  22529 } |  21260 } | 
|  22530  |  21261  | 
|  22531  |  | 
|  22532 void Float32x4::set_x(float value) const { |  21262 void Float32x4::set_x(float value) const { | 
|  22533   StoreNonPointer(&raw_ptr()->value_[0], value); |  21263   StoreNonPointer(&raw_ptr()->value_[0], value); | 
|  22534 } |  21264 } | 
|  22535  |  21265  | 
|  22536  |  | 
|  22537 void Float32x4::set_y(float value) const { |  21266 void Float32x4::set_y(float value) const { | 
|  22538   StoreNonPointer(&raw_ptr()->value_[1], value); |  21267   StoreNonPointer(&raw_ptr()->value_[1], value); | 
|  22539 } |  21268 } | 
|  22540  |  21269  | 
|  22541  |  | 
|  22542 void Float32x4::set_z(float value) const { |  21270 void Float32x4::set_z(float value) const { | 
|  22543   StoreNonPointer(&raw_ptr()->value_[2], value); |  21271   StoreNonPointer(&raw_ptr()->value_[2], value); | 
|  22544 } |  21272 } | 
|  22545  |  21273  | 
|  22546  |  | 
|  22547 void Float32x4::set_w(float value) const { |  21274 void Float32x4::set_w(float value) const { | 
|  22548   StoreNonPointer(&raw_ptr()->value_[3], value); |  21275   StoreNonPointer(&raw_ptr()->value_[3], value); | 
|  22549 } |  21276 } | 
|  22550  |  21277  | 
|  22551  |  | 
|  22552 float Float32x4::x() const { |  21278 float Float32x4::x() const { | 
|  22553   return raw_ptr()->value_[0]; |  21279   return raw_ptr()->value_[0]; | 
|  22554 } |  21280 } | 
|  22555  |  21281  | 
|  22556  |  | 
|  22557 float Float32x4::y() const { |  21282 float Float32x4::y() const { | 
|  22558   return raw_ptr()->value_[1]; |  21283   return raw_ptr()->value_[1]; | 
|  22559 } |  21284 } | 
|  22560  |  21285  | 
|  22561  |  | 
|  22562 float Float32x4::z() const { |  21286 float Float32x4::z() const { | 
|  22563   return raw_ptr()->value_[2]; |  21287   return raw_ptr()->value_[2]; | 
|  22564 } |  21288 } | 
|  22565  |  21289  | 
|  22566  |  | 
|  22567 float Float32x4::w() const { |  21290 float Float32x4::w() const { | 
|  22568   return raw_ptr()->value_[3]; |  21291   return raw_ptr()->value_[3]; | 
|  22569 } |  21292 } | 
|  22570  |  21293  | 
|  22571  |  | 
|  22572 const char* Float32x4::ToCString() const { |  21294 const char* Float32x4::ToCString() const { | 
|  22573   float _x = x(); |  21295   float _x = x(); | 
|  22574   float _y = y(); |  21296   float _y = y(); | 
|  22575   float _z = z(); |  21297   float _z = z(); | 
|  22576   float _w = w(); |  21298   float _w = w(); | 
|  22577   return OS::SCreate(Thread::Current()->zone(), "[%f, %f, %f, %f]", _x, _y, _z, |  21299   return OS::SCreate(Thread::Current()->zone(), "[%f, %f, %f, %f]", _x, _y, _z, | 
|  22578                      _w); |  21300                      _w); | 
|  22579 } |  21301 } | 
|  22580  |  21302  | 
|  22581  |  | 
|  22582 RawInt32x4* Int32x4::New(int32_t v0, |  21303 RawInt32x4* Int32x4::New(int32_t v0, | 
|  22583                          int32_t v1, |  21304                          int32_t v1, | 
|  22584                          int32_t v2, |  21305                          int32_t v2, | 
|  22585                          int32_t v3, |  21306                          int32_t v3, | 
|  22586                          Heap::Space space) { |  21307                          Heap::Space space) { | 
|  22587   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); |  21308   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); | 
|  22588   Int32x4& result = Int32x4::Handle(); |  21309   Int32x4& result = Int32x4::Handle(); | 
|  22589   { |  21310   { | 
|  22590     RawObject* raw = |  21311     RawObject* raw = | 
|  22591         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); |  21312         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); | 
|  22592     NoSafepointScope no_safepoint; |  21313     NoSafepointScope no_safepoint; | 
|  22593     result ^= raw; |  21314     result ^= raw; | 
|  22594   } |  21315   } | 
|  22595   result.set_x(v0); |  21316   result.set_x(v0); | 
|  22596   result.set_y(v1); |  21317   result.set_y(v1); | 
|  22597   result.set_z(v2); |  21318   result.set_z(v2); | 
|  22598   result.set_w(v3); |  21319   result.set_w(v3); | 
|  22599   return result.raw(); |  21320   return result.raw(); | 
|  22600 } |  21321 } | 
|  22601  |  21322  | 
|  22602  |  | 
|  22603 RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) { |  21323 RawInt32x4* Int32x4::New(simd128_value_t value, Heap::Space space) { | 
|  22604   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); |  21324   ASSERT(Isolate::Current()->object_store()->int32x4_class() != Class::null()); | 
|  22605   Int32x4& result = Int32x4::Handle(); |  21325   Int32x4& result = Int32x4::Handle(); | 
|  22606   { |  21326   { | 
|  22607     RawObject* raw = |  21327     RawObject* raw = | 
|  22608         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); |  21328         Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space); | 
|  22609     NoSafepointScope no_safepoint; |  21329     NoSafepointScope no_safepoint; | 
|  22610     result ^= raw; |  21330     result ^= raw; | 
|  22611   } |  21331   } | 
|  22612   result.set_value(value); |  21332   result.set_value(value); | 
|  22613   return result.raw(); |  21333   return result.raw(); | 
|  22614 } |  21334 } | 
|  22615  |  21335  | 
|  22616  |  | 
|  22617 void Int32x4::set_x(int32_t value) const { |  21336 void Int32x4::set_x(int32_t value) const { | 
|  22618   StoreNonPointer(&raw_ptr()->value_[0], value); |  21337   StoreNonPointer(&raw_ptr()->value_[0], value); | 
|  22619 } |  21338 } | 
|  22620  |  21339  | 
|  22621  |  | 
|  22622 void Int32x4::set_y(int32_t value) const { |  21340 void Int32x4::set_y(int32_t value) const { | 
|  22623   StoreNonPointer(&raw_ptr()->value_[1], value); |  21341   StoreNonPointer(&raw_ptr()->value_[1], value); | 
|  22624 } |  21342 } | 
|  22625  |  21343  | 
|  22626  |  | 
|  22627 void Int32x4::set_z(int32_t value) const { |  21344 void Int32x4::set_z(int32_t value) const { | 
|  22628   StoreNonPointer(&raw_ptr()->value_[2], value); |  21345   StoreNonPointer(&raw_ptr()->value_[2], value); | 
|  22629 } |  21346 } | 
|  22630  |  21347  | 
|  22631  |  | 
|  22632 void Int32x4::set_w(int32_t value) const { |  21348 void Int32x4::set_w(int32_t value) const { | 
|  22633   StoreNonPointer(&raw_ptr()->value_[3], value); |  21349   StoreNonPointer(&raw_ptr()->value_[3], value); | 
|  22634 } |  21350 } | 
|  22635  |  21351  | 
|  22636  |  | 
|  22637 int32_t Int32x4::x() const { |  21352 int32_t Int32x4::x() const { | 
|  22638   return raw_ptr()->value_[0]; |  21353   return raw_ptr()->value_[0]; | 
|  22639 } |  21354 } | 
|  22640  |  21355  | 
|  22641  |  | 
|  22642 int32_t Int32x4::y() const { |  21356 int32_t Int32x4::y() const { | 
|  22643   return raw_ptr()->value_[1]; |  21357   return raw_ptr()->value_[1]; | 
|  22644 } |  21358 } | 
|  22645  |  21359  | 
|  22646  |  | 
|  22647 int32_t Int32x4::z() const { |  21360 int32_t Int32x4::z() const { | 
|  22648   return raw_ptr()->value_[2]; |  21361   return raw_ptr()->value_[2]; | 
|  22649 } |  21362 } | 
|  22650  |  21363  | 
|  22651  |  | 
|  22652 int32_t Int32x4::w() const { |  21364 int32_t Int32x4::w() const { | 
|  22653   return raw_ptr()->value_[3]; |  21365   return raw_ptr()->value_[3]; | 
|  22654 } |  21366 } | 
|  22655  |  21367  | 
|  22656  |  | 
|  22657 simd128_value_t Int32x4::value() const { |  21368 simd128_value_t Int32x4::value() const { | 
|  22658   return ReadUnaligned( |  21369   return ReadUnaligned( | 
|  22659       reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); |  21370       reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_)); | 
|  22660 } |  21371 } | 
|  22661  |  21372  | 
|  22662  |  | 
|  22663 void Int32x4::set_value(simd128_value_t value) const { |  21373 void Int32x4::set_value(simd128_value_t value) const { | 
|  22664   StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), |  21374   StoreUnaligned(reinterpret_cast<simd128_value_t*>(&raw()->ptr()->value_), | 
|  22665                  value); |  21375                  value); | 
|  22666 } |  21376 } | 
|  22667  |  21377  | 
|  22668  |  | 
|  22669 const char* Int32x4::ToCString() const { |  21378 const char* Int32x4::ToCString() const { | 
|  22670   int32_t _x = x(); |  21379   int32_t _x = x(); | 
|  22671   int32_t _y = y(); |  21380   int32_t _y = y(); | 
|  22672   int32_t _z = z(); |  21381   int32_t _z = z(); | 
|  22673   int32_t _w = w(); |  21382   int32_t _w = w(); | 
|  22674   return OS::SCreate(Thread::Current()->zone(), "[%08x, %08x, %08x, %08x]", _x, |  21383   return OS::SCreate(Thread::Current()->zone(), "[%08x, %08x, %08x, %08x]", _x, | 
|  22675                      _y, _z, _w); |  21384                      _y, _z, _w); | 
|  22676 } |  21385 } | 
|  22677  |  21386  | 
|  22678  |  | 
|  22679 RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) { |  21387 RawFloat64x2* Float64x2::New(double value0, double value1, Heap::Space space) { | 
|  22680   ASSERT(Isolate::Current()->object_store()->float64x2_class() != |  21388   ASSERT(Isolate::Current()->object_store()->float64x2_class() != | 
|  22681          Class::null()); |  21389          Class::null()); | 
|  22682   Float64x2& result = Float64x2::Handle(); |  21390   Float64x2& result = Float64x2::Handle(); | 
|  22683   { |  21391   { | 
|  22684     RawObject* raw = |  21392     RawObject* raw = | 
|  22685         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); |  21393         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); | 
|  22686     NoSafepointScope no_safepoint; |  21394     NoSafepointScope no_safepoint; | 
|  22687     result ^= raw; |  21395     result ^= raw; | 
|  22688   } |  21396   } | 
|  22689   result.set_x(value0); |  21397   result.set_x(value0); | 
|  22690   result.set_y(value1); |  21398   result.set_y(value1); | 
|  22691   return result.raw(); |  21399   return result.raw(); | 
|  22692 } |  21400 } | 
|  22693  |  21401  | 
|  22694  |  | 
|  22695 RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) { |  21402 RawFloat64x2* Float64x2::New(simd128_value_t value, Heap::Space space) { | 
|  22696   ASSERT(Isolate::Current()->object_store()->float64x2_class() != |  21403   ASSERT(Isolate::Current()->object_store()->float64x2_class() != | 
|  22697          Class::null()); |  21404          Class::null()); | 
|  22698   Float64x2& result = Float64x2::Handle(); |  21405   Float64x2& result = Float64x2::Handle(); | 
|  22699   { |  21406   { | 
|  22700     RawObject* raw = |  21407     RawObject* raw = | 
|  22701         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); |  21408         Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space); | 
|  22702     NoSafepointScope no_safepoint; |  21409     NoSafepointScope no_safepoint; | 
|  22703     result ^= raw; |  21410     result ^= raw; | 
|  22704   } |  21411   } | 
|  22705   result.set_value(value); |  21412   result.set_value(value); | 
|  22706   return result.raw(); |  21413   return result.raw(); | 
|  22707 } |  21414 } | 
|  22708  |  21415  | 
|  22709  |  | 
|  22710 double Float64x2::x() const { |  21416 double Float64x2::x() const { | 
|  22711   return raw_ptr()->value_[0]; |  21417   return raw_ptr()->value_[0]; | 
|  22712 } |  21418 } | 
|  22713  |  21419  | 
|  22714  |  | 
|  22715 double Float64x2::y() const { |  21420 double Float64x2::y() const { | 
|  22716   return raw_ptr()->value_[1]; |  21421   return raw_ptr()->value_[1]; | 
|  22717 } |  21422 } | 
|  22718  |  21423  | 
|  22719  |  | 
|  22720 void Float64x2::set_x(double x) const { |  21424 void Float64x2::set_x(double x) const { | 
|  22721   StoreNonPointer(&raw_ptr()->value_[0], x); |  21425   StoreNonPointer(&raw_ptr()->value_[0], x); | 
|  22722 } |  21426 } | 
|  22723  |  21427  | 
|  22724  |  | 
|  22725 void Float64x2::set_y(double y) const { |  21428 void Float64x2::set_y(double y) const { | 
|  22726   StoreNonPointer(&raw_ptr()->value_[1], y); |  21429   StoreNonPointer(&raw_ptr()->value_[1], y); | 
|  22727 } |  21430 } | 
|  22728  |  21431  | 
|  22729  |  | 
|  22730 simd128_value_t Float64x2::value() const { |  21432 simd128_value_t Float64x2::value() const { | 
|  22731   return simd128_value_t().readFrom(&raw_ptr()->value_[0]); |  21433   return simd128_value_t().readFrom(&raw_ptr()->value_[0]); | 
|  22732 } |  21434 } | 
|  22733  |  21435  | 
|  22734  |  | 
|  22735 void Float64x2::set_value(simd128_value_t value) const { |  21436 void Float64x2::set_value(simd128_value_t value) const { | 
|  22736   StoreSimd128(&raw_ptr()->value_[0], value); |  21437   StoreSimd128(&raw_ptr()->value_[0], value); | 
|  22737 } |  21438 } | 
|  22738  |  21439  | 
|  22739  |  | 
|  22740 const char* Float64x2::ToCString() const { |  21440 const char* Float64x2::ToCString() const { | 
|  22741   double _x = x(); |  21441   double _x = x(); | 
|  22742   double _y = y(); |  21442   double _y = y(); | 
|  22743   return OS::SCreate(Thread::Current()->zone(), "[%f, %f]", _x, _y); |  21443   return OS::SCreate(Thread::Current()->zone(), "[%f, %f]", _x, _y); | 
|  22744 } |  21444 } | 
|  22745  |  21445  | 
|  22746  |  | 
|  22747 const intptr_t TypedData::element_size_table[TypedData::kNumElementSizes] = { |  21446 const intptr_t TypedData::element_size_table[TypedData::kNumElementSizes] = { | 
|  22748     1,   // kTypedDataInt8ArrayCid. |  21447     1,   // kTypedDataInt8ArrayCid. | 
|  22749     1,   // kTypedDataUint8ArrayCid. |  21448     1,   // kTypedDataUint8ArrayCid. | 
|  22750     1,   // kTypedDataUint8ClampedArrayCid. |  21449     1,   // kTypedDataUint8ClampedArrayCid. | 
|  22751     2,   // kTypedDataInt16ArrayCid. |  21450     2,   // kTypedDataInt16ArrayCid. | 
|  22752     2,   // kTypedDataUint16ArrayCid. |  21451     2,   // kTypedDataUint16ArrayCid. | 
|  22753     4,   // kTypedDataInt32ArrayCid. |  21452     4,   // kTypedDataInt32ArrayCid. | 
|  22754     4,   // kTypedDataUint32ArrayCid. |  21453     4,   // kTypedDataUint32ArrayCid. | 
|  22755     8,   // kTypedDataInt64ArrayCid. |  21454     8,   // kTypedDataInt64ArrayCid. | 
|  22756     8,   // kTypedDataUint64ArrayCid. |  21455     8,   // kTypedDataUint64ArrayCid. | 
|  22757     4,   // kTypedDataFloat32ArrayCid. |  21456     4,   // kTypedDataFloat32ArrayCid. | 
|  22758     8,   // kTypedDataFloat64ArrayCid. |  21457     8,   // kTypedDataFloat64ArrayCid. | 
|  22759     16,  // kTypedDataFloat32x4ArrayCid. |  21458     16,  // kTypedDataFloat32x4ArrayCid. | 
|  22760     16,  // kTypedDataInt32x4ArrayCid. |  21459     16,  // kTypedDataInt32x4ArrayCid. | 
|  22761     16,  // kTypedDataFloat64x2ArrayCid, |  21460     16,  // kTypedDataFloat64x2ArrayCid, | 
|  22762 }; |  21461 }; | 
|  22763  |  21462  | 
|  22764  |  | 
|  22765 bool TypedData::CanonicalizeEquals(const Instance& other) const { |  21463 bool TypedData::CanonicalizeEquals(const Instance& other) const { | 
|  22766   if (this->raw() == other.raw()) { |  21464   if (this->raw() == other.raw()) { | 
|  22767     // Both handles point to the same raw instance. |  21465     // Both handles point to the same raw instance. | 
|  22768     return true; |  21466     return true; | 
|  22769   } |  21467   } | 
|  22770  |  21468  | 
|  22771   if (!other.IsTypedData() || other.IsNull()) { |  21469   if (!other.IsTypedData() || other.IsNull()) { | 
|  22772     return false; |  21470     return false; | 
|  22773   } |  21471   } | 
|  22774  |  21472  | 
|  22775   const TypedData& other_typed_data = TypedData::Cast(other); |  21473   const TypedData& other_typed_data = TypedData::Cast(other); | 
|  22776  |  21474  | 
|  22777   if (this->ElementType() != other_typed_data.ElementType()) { |  21475   if (this->ElementType() != other_typed_data.ElementType()) { | 
|  22778     return false; |  21476     return false; | 
|  22779   } |  21477   } | 
|  22780  |  21478  | 
|  22781   const intptr_t len = this->LengthInBytes(); |  21479   const intptr_t len = this->LengthInBytes(); | 
|  22782   if (len != other_typed_data.LengthInBytes()) { |  21480   if (len != other_typed_data.LengthInBytes()) { | 
|  22783     return false; |  21481     return false; | 
|  22784   } |  21482   } | 
|  22785   NoSafepointScope no_safepoint; |  21483   NoSafepointScope no_safepoint; | 
|  22786   return (len == 0) || |  21484   return (len == 0) || | 
|  22787          (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0); |  21485          (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0); | 
|  22788 } |  21486 } | 
|  22789  |  21487  | 
|  22790  |  | 
|  22791 uword TypedData::ComputeCanonicalTableHash() const { |  21488 uword TypedData::ComputeCanonicalTableHash() const { | 
|  22792   const intptr_t len = this->LengthInBytes(); |  21489   const intptr_t len = this->LengthInBytes(); | 
|  22793   ASSERT(len != 0); |  21490   ASSERT(len != 0); | 
|  22794   uword hash = len; |  21491   uword hash = len; | 
|  22795   for (intptr_t i = 0; i < len; i++) { |  21492   for (intptr_t i = 0; i < len; i++) { | 
|  22796     hash = CombineHashes(len, GetUint8(i)); |  21493     hash = CombineHashes(len, GetUint8(i)); | 
|  22797   } |  21494   } | 
|  22798   return FinalizeHash(hash, kHashBits); |  21495   return FinalizeHash(hash, kHashBits); | 
|  22799 } |  21496 } | 
|  22800  |  21497  | 
|  22801  |  | 
|  22802 RawTypedData* TypedData::New(intptr_t class_id, |  21498 RawTypedData* TypedData::New(intptr_t class_id, | 
|  22803                              intptr_t len, |  21499                              intptr_t len, | 
|  22804                              Heap::Space space) { |  21500                              Heap::Space space) { | 
|  22805   if (len < 0 || len > TypedData::MaxElements(class_id)) { |  21501   if (len < 0 || len > TypedData::MaxElements(class_id)) { | 
|  22806     FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len); |  21502     FATAL1("Fatal error in TypedData::New: invalid len %" Pd "\n", len); | 
|  22807   } |  21503   } | 
|  22808   TypedData& result = TypedData::Handle(); |  21504   TypedData& result = TypedData::Handle(); | 
|  22809   { |  21505   { | 
|  22810     const intptr_t lengthInBytes = len * ElementSizeInBytes(class_id); |  21506     const intptr_t lengthInBytes = len * ElementSizeInBytes(class_id); | 
|  22811     RawObject* raw = Object::Allocate( |  21507     RawObject* raw = Object::Allocate( | 
|  22812         class_id, TypedData::InstanceSize(lengthInBytes), space); |  21508         class_id, TypedData::InstanceSize(lengthInBytes), space); | 
|  22813     NoSafepointScope no_safepoint; |  21509     NoSafepointScope no_safepoint; | 
|  22814     result ^= raw; |  21510     result ^= raw; | 
|  22815     result.SetLength(len); |  21511     result.SetLength(len); | 
|  22816     if (len > 0) { |  21512     if (len > 0) { | 
|  22817       memset(result.DataAddr(0), 0, lengthInBytes); |  21513       memset(result.DataAddr(0), 0, lengthInBytes); | 
|  22818     } |  21514     } | 
|  22819   } |  21515   } | 
|  22820   return result.raw(); |  21516   return result.raw(); | 
|  22821 } |  21517 } | 
|  22822  |  21518  | 
|  22823  |  | 
|  22824 RawTypedData* TypedData::EmptyUint32Array(Thread* thread) { |  21519 RawTypedData* TypedData::EmptyUint32Array(Thread* thread) { | 
|  22825   ASSERT(thread != NULL); |  21520   ASSERT(thread != NULL); | 
|  22826   Isolate* isolate = thread->isolate(); |  21521   Isolate* isolate = thread->isolate(); | 
|  22827   ASSERT(isolate != NULL); |  21522   ASSERT(isolate != NULL); | 
|  22828   ASSERT(isolate->object_store() != NULL); |  21523   ASSERT(isolate->object_store() != NULL); | 
|  22829   if (isolate->object_store()->empty_uint32_array() != TypedData::null()) { |  21524   if (isolate->object_store()->empty_uint32_array() != TypedData::null()) { | 
|  22830     // Already created. |  21525     // Already created. | 
|  22831     return isolate->object_store()->empty_uint32_array(); |  21526     return isolate->object_store()->empty_uint32_array(); | 
|  22832   } |  21527   } | 
|  22833   const TypedData& array = TypedData::Handle( |  21528   const TypedData& array = TypedData::Handle( | 
|  22834       thread->zone(), TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld)); |  21529       thread->zone(), TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld)); | 
|  22835   isolate->object_store()->set_empty_uint32_array(array); |  21530   isolate->object_store()->set_empty_uint32_array(array); | 
|  22836   return array.raw(); |  21531   return array.raw(); | 
|  22837 } |  21532 } | 
|  22838  |  21533  | 
|  22839  |  | 
|  22840 const char* TypedData::ToCString() const { |  21534 const char* TypedData::ToCString() const { | 
|  22841   switch (GetClassId()) { |  21535   switch (GetClassId()) { | 
|  22842 #define CASE_TYPED_DATA_CLASS(clazz)                                           \ |  21536 #define CASE_TYPED_DATA_CLASS(clazz)                                           \ | 
|  22843   case kTypedData##clazz##Cid:                                                 \ |  21537   case kTypedData##clazz##Cid:                                                 \ | 
|  22844     return #clazz; |  21538     return #clazz; | 
|  22845     CLASS_LIST_TYPED_DATA(CASE_TYPED_DATA_CLASS); |  21539     CLASS_LIST_TYPED_DATA(CASE_TYPED_DATA_CLASS); | 
|  22846 #undef CASE_TYPED_DATA_CLASS |  21540 #undef CASE_TYPED_DATA_CLASS | 
|  22847   } |  21541   } | 
|  22848   return "TypedData"; |  21542   return "TypedData"; | 
|  22849 } |  21543 } | 
|  22850  |  21544  | 
|  22851  |  | 
|  22852 FinalizablePersistentHandle* ExternalTypedData::AddFinalizer( |  21545 FinalizablePersistentHandle* ExternalTypedData::AddFinalizer( | 
|  22853     void* peer, |  21546     void* peer, | 
|  22854     Dart_WeakPersistentHandleFinalizer callback, |  21547     Dart_WeakPersistentHandleFinalizer callback, | 
|  22855     intptr_t external_size) const { |  21548     intptr_t external_size) const { | 
|  22856   return dart::AddFinalizer(*this, peer, callback, external_size); |  21549   return dart::AddFinalizer(*this, peer, callback, external_size); | 
|  22857 } |  21550 } | 
|  22858  |  21551  | 
|  22859  |  | 
|  22860 RawExternalTypedData* ExternalTypedData::New(intptr_t class_id, |  21552 RawExternalTypedData* ExternalTypedData::New(intptr_t class_id, | 
|  22861                                              uint8_t* data, |  21553                                              uint8_t* data, | 
|  22862                                              intptr_t len, |  21554                                              intptr_t len, | 
|  22863                                              Heap::Space space) { |  21555                                              Heap::Space space) { | 
|  22864   ExternalTypedData& result = ExternalTypedData::Handle(); |  21556   ExternalTypedData& result = ExternalTypedData::Handle(); | 
|  22865   { |  21557   { | 
|  22866     RawObject* raw = |  21558     RawObject* raw = | 
|  22867         Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space); |  21559         Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space); | 
|  22868     NoSafepointScope no_safepoint; |  21560     NoSafepointScope no_safepoint; | 
|  22869     result ^= raw; |  21561     result ^= raw; | 
|  22870     result.SetLength(len); |  21562     result.SetLength(len); | 
|  22871     result.SetData(data); |  21563     result.SetData(data); | 
|  22872   } |  21564   } | 
|  22873   return result.raw(); |  21565   return result.raw(); | 
|  22874 } |  21566 } | 
|  22875  |  21567  | 
|  22876  |  | 
|  22877 const char* ExternalTypedData::ToCString() const { |  21568 const char* ExternalTypedData::ToCString() const { | 
|  22878   return "ExternalTypedData"; |  21569   return "ExternalTypedData"; | 
|  22879 } |  21570 } | 
|  22880  |  21571  | 
|  22881  |  | 
|  22882 RawCapability* Capability::New(uint64_t id, Heap::Space space) { |  21572 RawCapability* Capability::New(uint64_t id, Heap::Space space) { | 
|  22883   Capability& result = Capability::Handle(); |  21573   Capability& result = Capability::Handle(); | 
|  22884   { |  21574   { | 
|  22885     RawObject* raw = Object::Allocate(Capability::kClassId, |  21575     RawObject* raw = Object::Allocate(Capability::kClassId, | 
|  22886                                       Capability::InstanceSize(), space); |  21576                                       Capability::InstanceSize(), space); | 
|  22887     NoSafepointScope no_safepoint; |  21577     NoSafepointScope no_safepoint; | 
|  22888     result ^= raw; |  21578     result ^= raw; | 
|  22889     result.StoreNonPointer(&result.raw_ptr()->id_, id); |  21579     result.StoreNonPointer(&result.raw_ptr()->id_, id); | 
|  22890   } |  21580   } | 
|  22891   return result.raw(); |  21581   return result.raw(); | 
|  22892 } |  21582 } | 
|  22893  |  21583  | 
|  22894  |  | 
|  22895 const char* Capability::ToCString() const { |  21584 const char* Capability::ToCString() const { | 
|  22896   return "Capability"; |  21585   return "Capability"; | 
|  22897 } |  21586 } | 
|  22898  |  21587  | 
|  22899  |  | 
|  22900 RawReceivePort* ReceivePort::New(Dart_Port id, |  21588 RawReceivePort* ReceivePort::New(Dart_Port id, | 
|  22901                                  bool is_control_port, |  21589                                  bool is_control_port, | 
|  22902                                  Heap::Space space) { |  21590                                  Heap::Space space) { | 
|  22903   ASSERT(id != ILLEGAL_PORT); |  21591   ASSERT(id != ILLEGAL_PORT); | 
|  22904   Thread* thread = Thread::Current(); |  21592   Thread* thread = Thread::Current(); | 
|  22905   Zone* zone = thread->zone(); |  21593   Zone* zone = thread->zone(); | 
|  22906   const SendPort& send_port = |  21594   const SendPort& send_port = | 
|  22907       SendPort::Handle(zone, SendPort::New(id, thread->isolate()->origin_id())); |  21595       SendPort::Handle(zone, SendPort::New(id, thread->isolate()->origin_id())); | 
|  22908  |  21596  | 
|  22909   ReceivePort& result = ReceivePort::Handle(zone); |  21597   ReceivePort& result = ReceivePort::Handle(zone); | 
|  22910   { |  21598   { | 
|  22911     RawObject* raw = Object::Allocate(ReceivePort::kClassId, |  21599     RawObject* raw = Object::Allocate(ReceivePort::kClassId, | 
|  22912                                       ReceivePort::InstanceSize(), space); |  21600                                       ReceivePort::InstanceSize(), space); | 
|  22913     NoSafepointScope no_safepoint; |  21601     NoSafepointScope no_safepoint; | 
|  22914     result ^= raw; |  21602     result ^= raw; | 
|  22915     result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw()); |  21603     result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw()); | 
|  22916   } |  21604   } | 
|  22917   if (is_control_port) { |  21605   if (is_control_port) { | 
|  22918     PortMap::SetPortState(id, PortMap::kControlPort); |  21606     PortMap::SetPortState(id, PortMap::kControlPort); | 
|  22919   } else { |  21607   } else { | 
|  22920     PortMap::SetPortState(id, PortMap::kLivePort); |  21608     PortMap::SetPortState(id, PortMap::kLivePort); | 
|  22921   } |  21609   } | 
|  22922   return result.raw(); |  21610   return result.raw(); | 
|  22923 } |  21611 } | 
|  22924  |  21612  | 
|  22925  |  | 
|  22926 const char* ReceivePort::ToCString() const { |  21613 const char* ReceivePort::ToCString() const { | 
|  22927   return "ReceivePort"; |  21614   return "ReceivePort"; | 
|  22928 } |  21615 } | 
|  22929  |  21616  | 
|  22930  |  | 
|  22931 RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) { |  21617 RawSendPort* SendPort::New(Dart_Port id, Heap::Space space) { | 
|  22932   return New(id, Isolate::Current()->origin_id(), space); |  21618   return New(id, Isolate::Current()->origin_id(), space); | 
|  22933 } |  21619 } | 
|  22934  |  21620  | 
|  22935  |  | 
|  22936 RawSendPort* SendPort::New(Dart_Port id, |  21621 RawSendPort* SendPort::New(Dart_Port id, | 
|  22937                            Dart_Port origin_id, |  21622                            Dart_Port origin_id, | 
|  22938                            Heap::Space space) { |  21623                            Heap::Space space) { | 
|  22939   ASSERT(id != ILLEGAL_PORT); |  21624   ASSERT(id != ILLEGAL_PORT); | 
|  22940   SendPort& result = SendPort::Handle(); |  21625   SendPort& result = SendPort::Handle(); | 
|  22941   { |  21626   { | 
|  22942     RawObject* raw = |  21627     RawObject* raw = | 
|  22943         Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space); |  21628         Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space); | 
|  22944     NoSafepointScope no_safepoint; |  21629     NoSafepointScope no_safepoint; | 
|  22945     result ^= raw; |  21630     result ^= raw; | 
|  22946     result.StoreNonPointer(&result.raw_ptr()->id_, id); |  21631     result.StoreNonPointer(&result.raw_ptr()->id_, id); | 
|  22947     result.StoreNonPointer(&result.raw_ptr()->origin_id_, origin_id); |  21632     result.StoreNonPointer(&result.raw_ptr()->origin_id_, origin_id); | 
|  22948   } |  21633   } | 
|  22949   return result.raw(); |  21634   return result.raw(); | 
|  22950 } |  21635 } | 
|  22951  |  21636  | 
|  22952  |  | 
|  22953 const char* SendPort::ToCString() const { |  21637 const char* SendPort::ToCString() const { | 
|  22954   return "SendPort"; |  21638   return "SendPort"; | 
|  22955 } |  21639 } | 
|  22956  |  21640  | 
|  22957  |  | 
|  22958 const char* Closure::ToCString() const { |  21641 const char* Closure::ToCString() const { | 
|  22959   const Function& fun = Function::Handle(function()); |  21642   const Function& fun = Function::Handle(function()); | 
|  22960   const bool is_implicit_closure = fun.IsImplicitClosureFunction(); |  21643   const bool is_implicit_closure = fun.IsImplicitClosureFunction(); | 
|  22961   const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); |  21644   const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString(); | 
|  22962   const char* from = is_implicit_closure ? " from " : ""; |  21645   const char* from = is_implicit_closure ? " from " : ""; | 
|  22963   const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; |  21646   const char* fun_desc = is_implicit_closure ? fun.ToCString() : ""; | 
|  22964   return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, |  21647   return OS::SCreate(Thread::Current()->zone(), "Closure: %s%s%s", fun_sig, | 
|  22965                      from, fun_desc); |  21648                      from, fun_desc); | 
|  22966 } |  21649 } | 
|  22967  |  21650  | 
|  22968  |  | 
|  22969 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, |  21651 RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments, | 
|  22970                          const TypeArguments& function_type_arguments, |  21652                          const TypeArguments& function_type_arguments, | 
|  22971                          const Function& function, |  21653                          const Function& function, | 
|  22972                          const Context& context, |  21654                          const Context& context, | 
|  22973                          Heap::Space space) { |  21655                          Heap::Space space) { | 
|  22974   Closure& result = Closure::Handle(); |  21656   Closure& result = Closure::Handle(); | 
|  22975   { |  21657   { | 
|  22976     RawObject* raw = |  21658     RawObject* raw = | 
|  22977         Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); |  21659         Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space); | 
|  22978     NoSafepointScope no_safepoint; |  21660     NoSafepointScope no_safepoint; | 
|  22979     result ^= raw; |  21661     result ^= raw; | 
|  22980     result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_, |  21662     result.StorePointer(&result.raw_ptr()->instantiator_type_arguments_, | 
|  22981                         instantiator_type_arguments.raw()); |  21663                         instantiator_type_arguments.raw()); | 
|  22982     result.StorePointer(&result.raw_ptr()->function_type_arguments_, |  21664     result.StorePointer(&result.raw_ptr()->function_type_arguments_, | 
|  22983                         function_type_arguments.raw()); |  21665                         function_type_arguments.raw()); | 
|  22984     result.StorePointer(&result.raw_ptr()->function_, function.raw()); |  21666     result.StorePointer(&result.raw_ptr()->function_, function.raw()); | 
|  22985     result.StorePointer(&result.raw_ptr()->context_, context.raw()); |  21667     result.StorePointer(&result.raw_ptr()->context_, context.raw()); | 
|  22986   } |  21668   } | 
|  22987   return result.raw(); |  21669   return result.raw(); | 
|  22988 } |  21670 } | 
|  22989  |  21671  | 
|  22990  |  | 
|  22991 RawClosure* Closure::New() { |  21672 RawClosure* Closure::New() { | 
|  22992   RawObject* raw = |  21673   RawObject* raw = | 
|  22993       Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); |  21674       Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld); | 
|  22994   return reinterpret_cast<RawClosure*>(raw); |  21675   return reinterpret_cast<RawClosure*>(raw); | 
|  22995 } |  21676 } | 
|  22996  |  21677  | 
|  22997  |  | 
|  22998 intptr_t StackTrace::Length() const { |  21678 intptr_t StackTrace::Length() const { | 
|  22999   const Array& code_array = Array::Handle(raw_ptr()->code_array_); |  21679   const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 
|  23000   return code_array.Length(); |  21680   return code_array.Length(); | 
|  23001 } |  21681 } | 
|  23002  |  21682  | 
|  23003  |  | 
|  23004 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const { |  21683 RawCode* StackTrace::CodeAtFrame(intptr_t frame_index) const { | 
|  23005   const Array& code_array = Array::Handle(raw_ptr()->code_array_); |  21684   const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 
|  23006   return reinterpret_cast<RawCode*>(code_array.At(frame_index)); |  21685   return reinterpret_cast<RawCode*>(code_array.At(frame_index)); | 
|  23007 } |  21686 } | 
|  23008  |  21687  | 
|  23009  |  | 
|  23010 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { |  21688 void StackTrace::SetCodeAtFrame(intptr_t frame_index, const Code& code) const { | 
|  23011   const Array& code_array = Array::Handle(raw_ptr()->code_array_); |  21689   const Array& code_array = Array::Handle(raw_ptr()->code_array_); | 
|  23012   code_array.SetAt(frame_index, code); |  21690   code_array.SetAt(frame_index, code); | 
|  23013 } |  21691 } | 
|  23014  |  21692  | 
|  23015  |  | 
|  23016 RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const { |  21693 RawSmi* StackTrace::PcOffsetAtFrame(intptr_t frame_index) const { | 
|  23017   const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |  21694   const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 
|  23018   return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index)); |  21695   return reinterpret_cast<RawSmi*>(pc_offset_array.At(frame_index)); | 
|  23019 } |  21696 } | 
|  23020  |  21697  | 
|  23021  |  | 
|  23022 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index, |  21698 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index, | 
|  23023                                     const Smi& pc_offset) const { |  21699                                     const Smi& pc_offset) const { | 
|  23024   const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); |  21700   const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); | 
|  23025   pc_offset_array.SetAt(frame_index, pc_offset); |  21701   pc_offset_array.SetAt(frame_index, pc_offset); | 
|  23026 } |  21702 } | 
|  23027  |  21703  | 
|  23028  |  | 
|  23029 void StackTrace::set_async_link(const StackTrace& async_link) const { |  21704 void StackTrace::set_async_link(const StackTrace& async_link) const { | 
|  23030   StorePointer(&raw_ptr()->async_link_, async_link.raw()); |  21705   StorePointer(&raw_ptr()->async_link_, async_link.raw()); | 
|  23031 } |  21706 } | 
|  23032  |  21707  | 
|  23033  |  | 
|  23034 void StackTrace::set_code_array(const Array& code_array) const { |  21708 void StackTrace::set_code_array(const Array& code_array) const { | 
|  23035   StorePointer(&raw_ptr()->code_array_, code_array.raw()); |  21709   StorePointer(&raw_ptr()->code_array_, code_array.raw()); | 
|  23036 } |  21710 } | 
|  23037  |  21711  | 
|  23038  |  | 
|  23039 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const { |  21712 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const { | 
|  23040   StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); |  21713   StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); | 
|  23041 } |  21714 } | 
|  23042  |  21715  | 
|  23043  |  | 
|  23044 void StackTrace::set_expand_inlined(bool value) const { |  21716 void StackTrace::set_expand_inlined(bool value) const { | 
|  23045   StoreNonPointer(&raw_ptr()->expand_inlined_, value); |  21717   StoreNonPointer(&raw_ptr()->expand_inlined_, value); | 
|  23046 } |  21718 } | 
|  23047  |  21719  | 
|  23048  |  | 
|  23049 bool StackTrace::expand_inlined() const { |  21720 bool StackTrace::expand_inlined() const { | 
|  23050   return raw_ptr()->expand_inlined_; |  21721   return raw_ptr()->expand_inlined_; | 
|  23051 } |  21722 } | 
|  23052  |  21723  | 
|  23053  |  | 
|  23054 RawStackTrace* StackTrace::New(const Array& code_array, |  21724 RawStackTrace* StackTrace::New(const Array& code_array, | 
|  23055                                const Array& pc_offset_array, |  21725                                const Array& pc_offset_array, | 
|  23056                                Heap::Space space) { |  21726                                Heap::Space space) { | 
|  23057   StackTrace& result = StackTrace::Handle(); |  21727   StackTrace& result = StackTrace::Handle(); | 
|  23058   { |  21728   { | 
|  23059     RawObject* raw = Object::Allocate(StackTrace::kClassId, |  21729     RawObject* raw = Object::Allocate(StackTrace::kClassId, | 
|  23060                                       StackTrace::InstanceSize(), space); |  21730                                       StackTrace::InstanceSize(), space); | 
|  23061     NoSafepointScope no_safepoint; |  21731     NoSafepointScope no_safepoint; | 
|  23062     result ^= raw; |  21732     result ^= raw; | 
|  23063   } |  21733   } | 
|  23064   result.set_code_array(code_array); |  21734   result.set_code_array(code_array); | 
|  23065   result.set_pc_offset_array(pc_offset_array); |  21735   result.set_pc_offset_array(pc_offset_array); | 
|  23066   result.set_expand_inlined(true);  // default. |  21736   result.set_expand_inlined(true);  // default. | 
|  23067   return result.raw(); |  21737   return result.raw(); | 
|  23068 } |  21738 } | 
|  23069  |  21739  | 
|  23070  |  | 
|  23071 RawStackTrace* StackTrace::New(const Array& code_array, |  21740 RawStackTrace* StackTrace::New(const Array& code_array, | 
|  23072                                const Array& pc_offset_array, |  21741                                const Array& pc_offset_array, | 
|  23073                                const StackTrace& async_link, |  21742                                const StackTrace& async_link, | 
|  23074                                Heap::Space space) { |  21743                                Heap::Space space) { | 
|  23075   StackTrace& result = StackTrace::Handle(); |  21744   StackTrace& result = StackTrace::Handle(); | 
|  23076   { |  21745   { | 
|  23077     RawObject* raw = Object::Allocate(StackTrace::kClassId, |  21746     RawObject* raw = Object::Allocate(StackTrace::kClassId, | 
|  23078                                       StackTrace::InstanceSize(), space); |  21747                                       StackTrace::InstanceSize(), space); | 
|  23079     NoSafepointScope no_safepoint; |  21748     NoSafepointScope no_safepoint; | 
|  23080     result ^= raw; |  21749     result ^= raw; | 
|  23081   } |  21750   } | 
|  23082   result.set_async_link(async_link); |  21751   result.set_async_link(async_link); | 
|  23083   result.set_code_array(code_array); |  21752   result.set_code_array(code_array); | 
|  23084   result.set_pc_offset_array(pc_offset_array); |  21753   result.set_pc_offset_array(pc_offset_array); | 
|  23085   result.set_expand_inlined(true);  // default. |  21754   result.set_expand_inlined(true);  // default. | 
|  23086   return result.raw(); |  21755   return result.raw(); | 
|  23087 } |  21756 } | 
|  23088  |  21757  | 
|  23089  |  | 
|  23090 static void PrintStackTraceFrame(Zone* zone, |  21758 static void PrintStackTraceFrame(Zone* zone, | 
|  23091                                  ZoneTextBuffer* buffer, |  21759                                  ZoneTextBuffer* buffer, | 
|  23092                                  const Function& function, |  21760                                  const Function& function, | 
|  23093                                  TokenPosition token_pos, |  21761                                  TokenPosition token_pos, | 
|  23094                                  intptr_t frame_index) { |  21762                                  intptr_t frame_index) { | 
|  23095   const Script& script = Script::Handle(zone, function.script()); |  21763   const Script& script = Script::Handle(zone, function.script()); | 
|  23096   const String& function_name = |  21764   const String& function_name = | 
|  23097       String::Handle(zone, function.QualifiedUserVisibleName()); |  21765       String::Handle(zone, function.QualifiedUserVisibleName()); | 
|  23098   const String& url = String::Handle( |  21766   const String& url = String::Handle( | 
|  23099       zone, script.IsNull() ? String::New("Kernel") : script.url()); |  21767       zone, script.IsNull() ? String::New("Kernel") : script.url()); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  23115                    function_name.ToCString(), url.ToCString(), line, column); |  21783                    function_name.ToCString(), url.ToCString(), line, column); | 
|  23116   } else if (line >= 0) { |  21784   } else if (line >= 0) { | 
|  23117     buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, |  21785     buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index, | 
|  23118                    function_name.ToCString(), url.ToCString(), line); |  21786                    function_name.ToCString(), url.ToCString(), line); | 
|  23119   } else { |  21787   } else { | 
|  23120     buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, |  21788     buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index, | 
|  23121                    function_name.ToCString(), url.ToCString()); |  21789                    function_name.ToCString(), url.ToCString()); | 
|  23122   } |  21790   } | 
|  23123 } |  21791 } | 
|  23124  |  21792  | 
|  23125  |  | 
|  23126 const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) { |  21793 const char* StackTrace::ToDartCString(const StackTrace& stack_trace_in) { | 
|  23127   Zone* zone = Thread::Current()->zone(); |  21794   Zone* zone = Thread::Current()->zone(); | 
|  23128   StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); |  21795   StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); | 
|  23129   Function& function = Function::Handle(zone); |  21796   Function& function = Function::Handle(zone); | 
|  23130   Code& code = Code::Handle(zone); |  21797   Code& code = Code::Handle(zone); | 
|  23131  |  21798  | 
|  23132   GrowableArray<const Function*> inlined_functions; |  21799   GrowableArray<const Function*> inlined_functions; | 
|  23133   GrowableArray<TokenPosition> inlined_token_positions; |  21800   GrowableArray<TokenPosition> inlined_token_positions; | 
|  23134   ZoneTextBuffer buffer(zone, 1024); |  21801   ZoneTextBuffer buffer(zone, 1024); | 
|  23135  |  21802  | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  23183         } |  21850         } | 
|  23184       } |  21851       } | 
|  23185     } |  21852     } | 
|  23186     // Follow the link. |  21853     // Follow the link. | 
|  23187     stack_trace ^= stack_trace.async_link(); |  21854     stack_trace ^= stack_trace.async_link(); | 
|  23188   } while (!stack_trace.IsNull()); |  21855   } while (!stack_trace.IsNull()); | 
|  23189  |  21856  | 
|  23190   return buffer.buffer(); |  21857   return buffer.buffer(); | 
|  23191 } |  21858 } | 
|  23192  |  21859  | 
|  23193  |  | 
|  23194 const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) { |  21860 const char* StackTrace::ToDwarfCString(const StackTrace& stack_trace_in) { | 
|  23195 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |  21861 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 
|  23196   Zone* zone = Thread::Current()->zone(); |  21862   Zone* zone = Thread::Current()->zone(); | 
|  23197   StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); |  21863   StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); | 
|  23198   Code& code = Code::Handle(zone); |  21864   Code& code = Code::Handle(zone); | 
|  23199   ZoneTextBuffer buffer(zone, 1024); |  21865   ZoneTextBuffer buffer(zone, 1024); | 
|  23200  |  21866  | 
|  23201   // The Dart standard requires the output of StackTrace.toString to include |  21867   // The Dart standard requires the output of StackTrace.toString to include | 
|  23202   // all pending activations with precise source locations (i.e., to expand |  21868   // all pending activations with precise source locations (i.e., to expand | 
|  23203   // inlined frames and provide line and column numbers). |  21869   // inlined frames and provide line and column numbers). | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  23257     stack_trace ^= stack_trace.async_link(); |  21923     stack_trace ^= stack_trace.async_link(); | 
|  23258   } while (!stack_trace.IsNull()); |  21924   } while (!stack_trace.IsNull()); | 
|  23259  |  21925  | 
|  23260   return buffer.buffer(); |  21926   return buffer.buffer(); | 
|  23261 #else |  21927 #else | 
|  23262   UNREACHABLE(); |  21928   UNREACHABLE(); | 
|  23263   return NULL; |  21929   return NULL; | 
|  23264 #endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |  21930 #endif  // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 
|  23265 } |  21931 } | 
|  23266  |  21932  | 
|  23267  |  | 
|  23268 const char* StackTrace::ToCString() const { |  21933 const char* StackTrace::ToCString() const { | 
|  23269 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) |  21934 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | 
|  23270   if (FLAG_dwarf_stack_traces) { |  21935   if (FLAG_dwarf_stack_traces) { | 
|  23271     return ToDwarfCString(*this); |  21936     return ToDwarfCString(*this); | 
|  23272   } |  21937   } | 
|  23273 #endif |  21938 #endif | 
|  23274   return ToDartCString(*this); |  21939   return ToDartCString(*this); | 
|  23275 } |  21940 } | 
|  23276  |  21941  | 
|  23277  |  | 
|  23278 void RegExp::set_pattern(const String& pattern) const { |  21942 void RegExp::set_pattern(const String& pattern) const { | 
|  23279   StorePointer(&raw_ptr()->pattern_, pattern.raw()); |  21943   StorePointer(&raw_ptr()->pattern_, pattern.raw()); | 
|  23280 } |  21944 } | 
|  23281  |  21945  | 
|  23282  |  | 
|  23283 void RegExp::set_function(intptr_t cid, |  21946 void RegExp::set_function(intptr_t cid, | 
|  23284                           bool sticky, |  21947                           bool sticky, | 
|  23285                           const Function& value) const { |  21948                           const Function& value) const { | 
|  23286   StorePointer(FunctionAddr(cid, sticky), value.raw()); |  21949   StorePointer(FunctionAddr(cid, sticky), value.raw()); | 
|  23287 } |  21950 } | 
|  23288  |  21951  | 
|  23289  |  | 
|  23290 void RegExp::set_bytecode(bool is_one_byte, |  21952 void RegExp::set_bytecode(bool is_one_byte, | 
|  23291                           bool sticky, |  21953                           bool sticky, | 
|  23292                           const TypedData& bytecode) const { |  21954                           const TypedData& bytecode) const { | 
|  23293   if (sticky) { |  21955   if (sticky) { | 
|  23294     if (is_one_byte) { |  21956     if (is_one_byte) { | 
|  23295       StorePointer(&raw_ptr()->one_byte_sticky_.bytecode_, bytecode.raw()); |  21957       StorePointer(&raw_ptr()->one_byte_sticky_.bytecode_, bytecode.raw()); | 
|  23296     } else { |  21958     } else { | 
|  23297       StorePointer(&raw_ptr()->two_byte_sticky_.bytecode_, bytecode.raw()); |  21959       StorePointer(&raw_ptr()->two_byte_sticky_.bytecode_, bytecode.raw()); | 
|  23298     } |  21960     } | 
|  23299   } else { |  21961   } else { | 
|  23300     if (is_one_byte) { |  21962     if (is_one_byte) { | 
|  23301       StorePointer(&raw_ptr()->one_byte_.bytecode_, bytecode.raw()); |  21963       StorePointer(&raw_ptr()->one_byte_.bytecode_, bytecode.raw()); | 
|  23302     } else { |  21964     } else { | 
|  23303       StorePointer(&raw_ptr()->two_byte_.bytecode_, bytecode.raw()); |  21965       StorePointer(&raw_ptr()->two_byte_.bytecode_, bytecode.raw()); | 
|  23304     } |  21966     } | 
|  23305   } |  21967   } | 
|  23306 } |  21968 } | 
|  23307  |  21969  | 
|  23308  |  | 
|  23309 void RegExp::set_num_bracket_expressions(intptr_t value) const { |  21970 void RegExp::set_num_bracket_expressions(intptr_t value) const { | 
|  23310   StoreSmi(&raw_ptr()->num_bracket_expressions_, Smi::New(value)); |  21971   StoreSmi(&raw_ptr()->num_bracket_expressions_, Smi::New(value)); | 
|  23311 } |  21972 } | 
|  23312  |  21973  | 
|  23313  |  | 
|  23314 RawRegExp* RegExp::New(Heap::Space space) { |  21974 RawRegExp* RegExp::New(Heap::Space space) { | 
|  23315   RegExp& result = RegExp::Handle(); |  21975   RegExp& result = RegExp::Handle(); | 
|  23316   { |  21976   { | 
|  23317     RawObject* raw = |  21977     RawObject* raw = | 
|  23318         Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space); |  21978         Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space); | 
|  23319     NoSafepointScope no_safepoint; |  21979     NoSafepointScope no_safepoint; | 
|  23320     result ^= raw; |  21980     result ^= raw; | 
|  23321     result.set_type(kUnitialized); |  21981     result.set_type(kUnitialized); | 
|  23322     result.set_flags(0); |  21982     result.set_flags(0); | 
|  23323     result.set_num_registers(-1); |  21983     result.set_num_registers(-1); | 
|  23324   } |  21984   } | 
|  23325   return result.raw(); |  21985   return result.raw(); | 
|  23326 } |  21986 } | 
|  23327  |  21987  | 
|  23328  |  | 
|  23329 void* RegExp::GetDataStartAddress() const { |  21988 void* RegExp::GetDataStartAddress() const { | 
|  23330   intptr_t addr = reinterpret_cast<intptr_t>(raw_ptr()); |  21989   intptr_t addr = reinterpret_cast<intptr_t>(raw_ptr()); | 
|  23331   return reinterpret_cast<void*>(addr + sizeof(RawRegExp)); |  21990   return reinterpret_cast<void*>(addr + sizeof(RawRegExp)); | 
|  23332 } |  21991 } | 
|  23333  |  21992  | 
|  23334  |  | 
|  23335 RawRegExp* RegExp::FromDataStartAddress(void* data) { |  21993 RawRegExp* RegExp::FromDataStartAddress(void* data) { | 
|  23336   RegExp& regexp = RegExp::Handle(); |  21994   RegExp& regexp = RegExp::Handle(); | 
|  23337   intptr_t addr = reinterpret_cast<intptr_t>(data) - sizeof(RawRegExp); |  21995   intptr_t addr = reinterpret_cast<intptr_t>(data) - sizeof(RawRegExp); | 
|  23338   regexp ^= RawObject::FromAddr(addr); |  21996   regexp ^= RawObject::FromAddr(addr); | 
|  23339   return regexp.raw(); |  21997   return regexp.raw(); | 
|  23340 } |  21998 } | 
|  23341  |  21999  | 
|  23342  |  | 
|  23343 const char* RegExp::Flags() const { |  22000 const char* RegExp::Flags() const { | 
|  23344   switch (flags()) { |  22001   switch (flags()) { | 
|  23345     case kGlobal | kIgnoreCase | kMultiLine: |  22002     case kGlobal | kIgnoreCase | kMultiLine: | 
|  23346     case kIgnoreCase | kMultiLine: |  22003     case kIgnoreCase | kMultiLine: | 
|  23347       return "im"; |  22004       return "im"; | 
|  23348     case kGlobal | kIgnoreCase: |  22005     case kGlobal | kIgnoreCase: | 
|  23349     case kIgnoreCase: |  22006     case kIgnoreCase: | 
|  23350       return "i"; |  22007       return "i"; | 
|  23351     case kGlobal | kMultiLine: |  22008     case kGlobal | kMultiLine: | 
|  23352     case kMultiLine: |  22009     case kMultiLine: | 
|  23353       return "m"; |  22010       return "m"; | 
|  23354     default: |  22011     default: | 
|  23355       break; |  22012       break; | 
|  23356   } |  22013   } | 
|  23357   return ""; |  22014   return ""; | 
|  23358 } |  22015 } | 
|  23359  |  22016  | 
|  23360  |  | 
|  23361 bool RegExp::CanonicalizeEquals(const Instance& other) const { |  22017 bool RegExp::CanonicalizeEquals(const Instance& other) const { | 
|  23362   if (this->raw() == other.raw()) { |  22018   if (this->raw() == other.raw()) { | 
|  23363     return true;  // "===". |  22019     return true;  // "===". | 
|  23364   } |  22020   } | 
|  23365   if (other.IsNull() || !other.IsRegExp()) { |  22021   if (other.IsNull() || !other.IsRegExp()) { | 
|  23366     return false; |  22022     return false; | 
|  23367   } |  22023   } | 
|  23368   const RegExp& other_js = RegExp::Cast(other); |  22024   const RegExp& other_js = RegExp::Cast(other); | 
|  23369   // Match the pattern. |  22025   // Match the pattern. | 
|  23370   const String& str1 = String::Handle(pattern()); |  22026   const String& str1 = String::Handle(pattern()); | 
|  23371   const String& str2 = String::Handle(other_js.pattern()); |  22027   const String& str2 = String::Handle(other_js.pattern()); | 
|  23372   if (!str1.Equals(str2)) { |  22028   if (!str1.Equals(str2)) { | 
|  23373     return false; |  22029     return false; | 
|  23374   } |  22030   } | 
|  23375   // Match the flags. |  22031   // Match the flags. | 
|  23376   if ((is_global() != other_js.is_global()) || |  22032   if ((is_global() != other_js.is_global()) || | 
|  23377       (is_ignore_case() != other_js.is_ignore_case()) || |  22033       (is_ignore_case() != other_js.is_ignore_case()) || | 
|  23378       (is_multi_line() != other_js.is_multi_line())) { |  22034       (is_multi_line() != other_js.is_multi_line())) { | 
|  23379     return false; |  22035     return false; | 
|  23380   } |  22036   } | 
|  23381   return true; |  22037   return true; | 
|  23382 } |  22038 } | 
|  23383  |  22039  | 
|  23384  |  | 
|  23385 const char* RegExp::ToCString() const { |  22040 const char* RegExp::ToCString() const { | 
|  23386   const String& str = String::Handle(pattern()); |  22041   const String& str = String::Handle(pattern()); | 
|  23387   return OS::SCreate(Thread::Current()->zone(), "RegExp: pattern=%s flags=%s", |  22042   return OS::SCreate(Thread::Current()->zone(), "RegExp: pattern=%s flags=%s", | 
|  23388                      str.ToCString(), Flags()); |  22043                      str.ToCString(), Flags()); | 
|  23389 } |  22044 } | 
|  23390  |  22045  | 
|  23391  |  | 
|  23392 RawWeakProperty* WeakProperty::New(Heap::Space space) { |  22046 RawWeakProperty* WeakProperty::New(Heap::Space space) { | 
|  23393   ASSERT(Isolate::Current()->object_store()->weak_property_class() != |  22047   ASSERT(Isolate::Current()->object_store()->weak_property_class() != | 
|  23394          Class::null()); |  22048          Class::null()); | 
|  23395   RawObject* raw = Object::Allocate(WeakProperty::kClassId, |  22049   RawObject* raw = Object::Allocate(WeakProperty::kClassId, | 
|  23396                                     WeakProperty::InstanceSize(), space); |  22050                                     WeakProperty::InstanceSize(), space); | 
|  23397   RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw); |  22051   RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw); | 
|  23398   result->ptr()->next_ = 0;  // Init the list to NULL. |  22052   result->ptr()->next_ = 0;  // Init the list to NULL. | 
|  23399   return result; |  22053   return result; | 
|  23400 } |  22054 } | 
|  23401  |  22055  | 
|  23402  |  | 
|  23403 const char* WeakProperty::ToCString() const { |  22056 const char* WeakProperty::ToCString() const { | 
|  23404   return "_WeakProperty"; |  22057   return "_WeakProperty"; | 
|  23405 } |  22058 } | 
|  23406  |  22059  | 
|  23407  |  | 
|  23408 RawAbstractType* MirrorReference::GetAbstractTypeReferent() const { |  22060 RawAbstractType* MirrorReference::GetAbstractTypeReferent() const { | 
|  23409   ASSERT(Object::Handle(referent()).IsAbstractType()); |  22061   ASSERT(Object::Handle(referent()).IsAbstractType()); | 
|  23410   return AbstractType::Cast(Object::Handle(referent())).raw(); |  22062   return AbstractType::Cast(Object::Handle(referent())).raw(); | 
|  23411 } |  22063 } | 
|  23412  |  22064  | 
|  23413  |  | 
|  23414 RawClass* MirrorReference::GetClassReferent() const { |  22065 RawClass* MirrorReference::GetClassReferent() const { | 
|  23415   ASSERT(Object::Handle(referent()).IsClass()); |  22066   ASSERT(Object::Handle(referent()).IsClass()); | 
|  23416   return Class::Cast(Object::Handle(referent())).raw(); |  22067   return Class::Cast(Object::Handle(referent())).raw(); | 
|  23417 } |  22068 } | 
|  23418  |  22069  | 
|  23419  |  | 
|  23420 RawField* MirrorReference::GetFieldReferent() const { |  22070 RawField* MirrorReference::GetFieldReferent() const { | 
|  23421   ASSERT(Object::Handle(referent()).IsField()); |  22071   ASSERT(Object::Handle(referent()).IsField()); | 
|  23422   return Field::Cast(Object::Handle(referent())).raw(); |  22072   return Field::Cast(Object::Handle(referent())).raw(); | 
|  23423 } |  22073 } | 
|  23424  |  22074  | 
|  23425  |  | 
|  23426 RawFunction* MirrorReference::GetFunctionReferent() const { |  22075 RawFunction* MirrorReference::GetFunctionReferent() const { | 
|  23427   ASSERT(Object::Handle(referent()).IsFunction()); |  22076   ASSERT(Object::Handle(referent()).IsFunction()); | 
|  23428   return Function::Cast(Object::Handle(referent())).raw(); |  22077   return Function::Cast(Object::Handle(referent())).raw(); | 
|  23429 } |  22078 } | 
|  23430  |  22079  | 
|  23431  |  | 
|  23432 RawLibrary* MirrorReference::GetLibraryReferent() const { |  22080 RawLibrary* MirrorReference::GetLibraryReferent() const { | 
|  23433   ASSERT(Object::Handle(referent()).IsLibrary()); |  22081   ASSERT(Object::Handle(referent()).IsLibrary()); | 
|  23434   return Library::Cast(Object::Handle(referent())).raw(); |  22082   return Library::Cast(Object::Handle(referent())).raw(); | 
|  23435 } |  22083 } | 
|  23436  |  22084  | 
|  23437  |  | 
|  23438 RawTypeParameter* MirrorReference::GetTypeParameterReferent() const { |  22085 RawTypeParameter* MirrorReference::GetTypeParameterReferent() const { | 
|  23439   ASSERT(Object::Handle(referent()).IsTypeParameter()); |  22086   ASSERT(Object::Handle(referent()).IsTypeParameter()); | 
|  23440   return TypeParameter::Cast(Object::Handle(referent())).raw(); |  22087   return TypeParameter::Cast(Object::Handle(referent())).raw(); | 
|  23441 } |  22088 } | 
|  23442  |  22089  | 
|  23443  |  | 
|  23444 RawMirrorReference* MirrorReference::New(const Object& referent, |  22090 RawMirrorReference* MirrorReference::New(const Object& referent, | 
|  23445                                          Heap::Space space) { |  22091                                          Heap::Space space) { | 
|  23446   MirrorReference& result = MirrorReference::Handle(); |  22092   MirrorReference& result = MirrorReference::Handle(); | 
|  23447   { |  22093   { | 
|  23448     RawObject* raw = Object::Allocate(MirrorReference::kClassId, |  22094     RawObject* raw = Object::Allocate(MirrorReference::kClassId, | 
|  23449                                       MirrorReference::InstanceSize(), space); |  22095                                       MirrorReference::InstanceSize(), space); | 
|  23450     NoSafepointScope no_safepoint; |  22096     NoSafepointScope no_safepoint; | 
|  23451     result ^= raw; |  22097     result ^= raw; | 
|  23452   } |  22098   } | 
|  23453   result.set_referent(referent); |  22099   result.set_referent(referent); | 
|  23454   return result.raw(); |  22100   return result.raw(); | 
|  23455 } |  22101 } | 
|  23456  |  22102  | 
|  23457  |  | 
|  23458 const char* MirrorReference::ToCString() const { |  22103 const char* MirrorReference::ToCString() const { | 
|  23459   return "_MirrorReference"; |  22104   return "_MirrorReference"; | 
|  23460 } |  22105 } | 
|  23461  |  22106  | 
|  23462  |  | 
|  23463 void UserTag::MakeActive() const { |  22107 void UserTag::MakeActive() const { | 
|  23464   Isolate* isolate = Isolate::Current(); |  22108   Isolate* isolate = Isolate::Current(); | 
|  23465   ASSERT(isolate != NULL); |  22109   ASSERT(isolate != NULL); | 
|  23466   isolate->set_current_tag(*this); |  22110   isolate->set_current_tag(*this); | 
|  23467 } |  22111 } | 
|  23468  |  22112  | 
|  23469  |  | 
|  23470 RawUserTag* UserTag::New(const String& label, Heap::Space space) { |  22113 RawUserTag* UserTag::New(const String& label, Heap::Space space) { | 
|  23471   Thread* thread = Thread::Current(); |  22114   Thread* thread = Thread::Current(); | 
|  23472   Isolate* isolate = thread->isolate(); |  22115   Isolate* isolate = thread->isolate(); | 
|  23473   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |  22116   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 
|  23474   // Canonicalize by name. |  22117   // Canonicalize by name. | 
|  23475   UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label)); |  22118   UserTag& result = UserTag::Handle(FindTagInIsolate(thread, label)); | 
|  23476   if (!result.IsNull()) { |  22119   if (!result.IsNull()) { | 
|  23477     // Tag already exists, return existing instance. |  22120     // Tag already exists, return existing instance. | 
|  23478     return result.raw(); |  22121     return result.raw(); | 
|  23479   } |  22122   } | 
|  23480   if (TagTableIsFull(thread)) { |  22123   if (TagTableIsFull(thread)) { | 
|  23481     const String& error = String::Handle(String::NewFormatted( |  22124     const String& error = String::Handle(String::NewFormatted( | 
|  23482         "UserTag instance limit (%" Pd ") reached.", UserTags::kMaxUserTags)); |  22125         "UserTag instance limit (%" Pd ") reached.", UserTags::kMaxUserTags)); | 
|  23483     const Array& args = Array::Handle(Array::New(1)); |  22126     const Array& args = Array::Handle(Array::New(1)); | 
|  23484     args.SetAt(0, error); |  22127     args.SetAt(0, error); | 
|  23485     Exceptions::ThrowByType(Exceptions::kUnsupported, args); |  22128     Exceptions::ThrowByType(Exceptions::kUnsupported, args); | 
|  23486   } |  22129   } | 
|  23487   // No tag with label exists, create and register with isolate tag table. |  22130   // No tag with label exists, create and register with isolate tag table. | 
|  23488   { |  22131   { | 
|  23489     RawObject* raw = |  22132     RawObject* raw = | 
|  23490         Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space); |  22133         Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space); | 
|  23491     NoSafepointScope no_safepoint; |  22134     NoSafepointScope no_safepoint; | 
|  23492     result ^= raw; |  22135     result ^= raw; | 
|  23493   } |  22136   } | 
|  23494   result.set_label(label); |  22137   result.set_label(label); | 
|  23495   AddTagToIsolate(thread, result); |  22138   AddTagToIsolate(thread, result); | 
|  23496   return result.raw(); |  22139   return result.raw(); | 
|  23497 } |  22140 } | 
|  23498  |  22141  | 
|  23499  |  | 
|  23500 RawUserTag* UserTag::DefaultTag() { |  22142 RawUserTag* UserTag::DefaultTag() { | 
|  23501   Thread* thread = Thread::Current(); |  22143   Thread* thread = Thread::Current(); | 
|  23502   Zone* zone = thread->zone(); |  22144   Zone* zone = thread->zone(); | 
|  23503   Isolate* isolate = thread->isolate(); |  22145   Isolate* isolate = thread->isolate(); | 
|  23504   ASSERT(isolate != NULL); |  22146   ASSERT(isolate != NULL); | 
|  23505   if (isolate->default_tag() != UserTag::null()) { |  22147   if (isolate->default_tag() != UserTag::null()) { | 
|  23506     // Already created. |  22148     // Already created. | 
|  23507     return isolate->default_tag(); |  22149     return isolate->default_tag(); | 
|  23508   } |  22150   } | 
|  23509   // Create default tag. |  22151   // Create default tag. | 
|  23510   const UserTag& result = |  22152   const UserTag& result = | 
|  23511       UserTag::Handle(zone, UserTag::New(Symbols::Default())); |  22153       UserTag::Handle(zone, UserTag::New(Symbols::Default())); | 
|  23512   ASSERT(result.tag() == UserTags::kDefaultUserTag); |  22154   ASSERT(result.tag() == UserTags::kDefaultUserTag); | 
|  23513   isolate->set_default_tag(result); |  22155   isolate->set_default_tag(result); | 
|  23514   return result.raw(); |  22156   return result.raw(); | 
|  23515 } |  22157 } | 
|  23516  |  22158  | 
|  23517  |  | 
|  23518 RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) { |  22159 RawUserTag* UserTag::FindTagInIsolate(Thread* thread, const String& label) { | 
|  23519   Isolate* isolate = thread->isolate(); |  22160   Isolate* isolate = thread->isolate(); | 
|  23520   Zone* zone = thread->zone(); |  22161   Zone* zone = thread->zone(); | 
|  23521   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |  22162   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 
|  23522   const GrowableObjectArray& tag_table = |  22163   const GrowableObjectArray& tag_table = | 
|  23523       GrowableObjectArray::Handle(zone, isolate->tag_table()); |  22164       GrowableObjectArray::Handle(zone, isolate->tag_table()); | 
|  23524   UserTag& other = UserTag::Handle(zone); |  22165   UserTag& other = UserTag::Handle(zone); | 
|  23525   String& tag_label = String::Handle(zone); |  22166   String& tag_label = String::Handle(zone); | 
|  23526   for (intptr_t i = 0; i < tag_table.Length(); i++) { |  22167   for (intptr_t i = 0; i < tag_table.Length(); i++) { | 
|  23527     other ^= tag_table.At(i); |  22168     other ^= tag_table.At(i); | 
|  23528     ASSERT(!other.IsNull()); |  22169     ASSERT(!other.IsNull()); | 
|  23529     tag_label ^= other.label(); |  22170     tag_label ^= other.label(); | 
|  23530     ASSERT(!tag_label.IsNull()); |  22171     ASSERT(!tag_label.IsNull()); | 
|  23531     if (tag_label.Equals(label)) { |  22172     if (tag_label.Equals(label)) { | 
|  23532       return other.raw(); |  22173       return other.raw(); | 
|  23533     } |  22174     } | 
|  23534   } |  22175   } | 
|  23535   return UserTag::null(); |  22176   return UserTag::null(); | 
|  23536 } |  22177 } | 
|  23537  |  22178  | 
|  23538  |  | 
|  23539 void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) { |  22179 void UserTag::AddTagToIsolate(Thread* thread, const UserTag& tag) { | 
|  23540   Isolate* isolate = thread->isolate(); |  22180   Isolate* isolate = thread->isolate(); | 
|  23541   Zone* zone = thread->zone(); |  22181   Zone* zone = thread->zone(); | 
|  23542   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |  22182   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 
|  23543   const GrowableObjectArray& tag_table = |  22183   const GrowableObjectArray& tag_table = | 
|  23544       GrowableObjectArray::Handle(zone, isolate->tag_table()); |  22184       GrowableObjectArray::Handle(zone, isolate->tag_table()); | 
|  23545   ASSERT(!TagTableIsFull(thread)); |  22185   ASSERT(!TagTableIsFull(thread)); | 
|  23546 #if defined(DEBUG) |  22186 #if defined(DEBUG) | 
|  23547   // Verify that no existing tag has the same tag id. |  22187   // Verify that no existing tag has the same tag id. | 
|  23548   UserTag& other = UserTag::Handle(thread->zone()); |  22188   UserTag& other = UserTag::Handle(thread->zone()); | 
|  23549   for (intptr_t i = 0; i < tag_table.Length(); i++) { |  22189   for (intptr_t i = 0; i < tag_table.Length(); i++) { | 
|  23550     other ^= tag_table.At(i); |  22190     other ^= tag_table.At(i); | 
|  23551     ASSERT(!other.IsNull()); |  22191     ASSERT(!other.IsNull()); | 
|  23552     ASSERT(tag.tag() != other.tag()); |  22192     ASSERT(tag.tag() != other.tag()); | 
|  23553   } |  22193   } | 
|  23554 #endif |  22194 #endif | 
|  23555   // Generate the UserTag tag id by taking the length of the isolate's |  22195   // Generate the UserTag tag id by taking the length of the isolate's | 
|  23556   // tag table + kUserTagIdOffset. |  22196   // tag table + kUserTagIdOffset. | 
|  23557   uword tag_id = tag_table.Length() + UserTags::kUserTagIdOffset; |  22197   uword tag_id = tag_table.Length() + UserTags::kUserTagIdOffset; | 
|  23558   ASSERT(tag_id >= UserTags::kUserTagIdOffset); |  22198   ASSERT(tag_id >= UserTags::kUserTagIdOffset); | 
|  23559   ASSERT(tag_id < (UserTags::kUserTagIdOffset + UserTags::kMaxUserTags)); |  22199   ASSERT(tag_id < (UserTags::kUserTagIdOffset + UserTags::kMaxUserTags)); | 
|  23560   tag.set_tag(tag_id); |  22200   tag.set_tag(tag_id); | 
|  23561   tag_table.Add(tag); |  22201   tag_table.Add(tag); | 
|  23562 } |  22202 } | 
|  23563  |  22203  | 
|  23564  |  | 
|  23565 bool UserTag::TagTableIsFull(Thread* thread) { |  22204 bool UserTag::TagTableIsFull(Thread* thread) { | 
|  23566   Isolate* isolate = thread->isolate(); |  22205   Isolate* isolate = thread->isolate(); | 
|  23567   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |  22206   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 
|  23568   const GrowableObjectArray& tag_table = |  22207   const GrowableObjectArray& tag_table = | 
|  23569       GrowableObjectArray::Handle(thread->zone(), isolate->tag_table()); |  22208       GrowableObjectArray::Handle(thread->zone(), isolate->tag_table()); | 
|  23570   ASSERT(tag_table.Length() <= UserTags::kMaxUserTags); |  22209   ASSERT(tag_table.Length() <= UserTags::kMaxUserTags); | 
|  23571   return tag_table.Length() == UserTags::kMaxUserTags; |  22210   return tag_table.Length() == UserTags::kMaxUserTags; | 
|  23572 } |  22211 } | 
|  23573  |  22212  | 
|  23574  |  | 
|  23575 RawUserTag* UserTag::FindTagById(uword tag_id) { |  22213 RawUserTag* UserTag::FindTagById(uword tag_id) { | 
|  23576   Thread* thread = Thread::Current(); |  22214   Thread* thread = Thread::Current(); | 
|  23577   Zone* zone = thread->zone(); |  22215   Zone* zone = thread->zone(); | 
|  23578   Isolate* isolate = thread->isolate(); |  22216   Isolate* isolate = thread->isolate(); | 
|  23579   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); |  22217   ASSERT(isolate->tag_table() != GrowableObjectArray::null()); | 
|  23580   const GrowableObjectArray& tag_table = |  22218   const GrowableObjectArray& tag_table = | 
|  23581       GrowableObjectArray::Handle(zone, isolate->tag_table()); |  22219       GrowableObjectArray::Handle(zone, isolate->tag_table()); | 
|  23582   UserTag& tag = UserTag::Handle(zone); |  22220   UserTag& tag = UserTag::Handle(zone); | 
|  23583   for (intptr_t i = 0; i < tag_table.Length(); i++) { |  22221   for (intptr_t i = 0; i < tag_table.Length(); i++) { | 
|  23584     tag ^= tag_table.At(i); |  22222     tag ^= tag_table.At(i); | 
|  23585     if (tag.tag() == tag_id) { |  22223     if (tag.tag() == tag_id) { | 
|  23586       return tag.raw(); |  22224       return tag.raw(); | 
|  23587     } |  22225     } | 
|  23588   } |  22226   } | 
|  23589   return UserTag::null(); |  22227   return UserTag::null(); | 
|  23590 } |  22228 } | 
|  23591  |  22229  | 
|  23592  |  | 
|  23593 const char* UserTag::ToCString() const { |  22230 const char* UserTag::ToCString() const { | 
|  23594   const String& tag_label = String::Handle(label()); |  22231   const String& tag_label = String::Handle(label()); | 
|  23595   return tag_label.ToCString(); |  22232   return tag_label.ToCString(); | 
|  23596 } |  22233 } | 
|  23597  |  22234  | 
|  23598 }  // namespace dart |  22235 }  // namespace dart | 
| OLD | NEW |