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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 4199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4210 const char* Class::ToCString() const { | 4210 const char* Class::ToCString() const { |
4211 const Library& lib = Library::Handle(library()); | 4211 const Library& lib = Library::Handle(library()); |
4212 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); | 4212 const char* library_name = lib.IsNull() ? "" : lib.ToCString(); |
4213 const char* patch_prefix = is_patch() ? "Patch " : ""; | 4213 const char* patch_prefix = is_patch() ? "Patch " : ""; |
4214 const char* class_name = String::Handle(Name()).ToCString(); | 4214 const char* class_name = String::Handle(Name()).ToCString(); |
4215 return OS::SCreate(Thread::Current()->zone(), | 4215 return OS::SCreate(Thread::Current()->zone(), |
4216 "%s %sClass: %s", library_name, patch_prefix, class_name); | 4216 "%s %sClass: %s", library_name, patch_prefix, class_name); |
4217 } | 4217 } |
4218 | 4218 |
4219 | 4219 |
4220 // Returns an instance of Double or Double::null(). | |
4221 // 'index' points to either: | |
4222 // - constants_list_ position of found element, or | |
4223 // - constants_list_ position where new canonical can be inserted. | |
4224 RawDouble* Class::LookupCanonicalDouble( | |
4225 Zone* zone, double value, intptr_t* index) const { | |
4226 ASSERT(this->raw() == Isolate::Current()->object_store()->double_class()); | |
4227 const Array& constants = Array::Handle(zone, this->constants()); | |
4228 const intptr_t constants_len = constants.Length(); | |
4229 // Linear search to see whether this value is already present in the | |
4230 // list of canonicalized constants. | |
4231 Double& canonical_value = Double::Handle(zone); | |
4232 while (*index < constants_len) { | |
4233 canonical_value ^= constants.At(*index); | |
4234 if (canonical_value.IsNull()) { | |
4235 break; | |
4236 } | |
4237 if (canonical_value.BitwiseEqualsToDouble(value)) { | |
4238 ASSERT(canonical_value.IsCanonical()); | |
4239 return canonical_value.raw(); | |
4240 } | |
4241 *index = *index + 1; | |
4242 } | |
4243 return Double::null(); | |
4244 } | |
4245 | |
4246 | |
4247 RawMint* Class::LookupCanonicalMint( | |
4248 Zone* zone, int64_t value, intptr_t* index) const { | |
4249 ASSERT(this->raw() == Isolate::Current()->object_store()->mint_class()); | |
4250 const Array& constants = Array::Handle(zone, this->constants()); | |
4251 const intptr_t constants_len = constants.Length(); | |
4252 // Linear search to see whether this value is already present in the | |
4253 // list of canonicalized constants. | |
4254 Mint& canonical_value = Mint::Handle(zone); | |
4255 while (*index < constants_len) { | |
4256 canonical_value ^= constants.At(*index); | |
4257 if (canonical_value.IsNull()) { | |
4258 break; | |
4259 } | |
4260 if (canonical_value.value() == value) { | |
4261 ASSERT(canonical_value.IsCanonical()); | |
4262 return canonical_value.raw(); | |
4263 } | |
4264 *index = *index + 1; | |
4265 } | |
4266 return Mint::null(); | |
4267 } | |
4268 | |
4269 | |
4270 RawBigint* Class::LookupCanonicalBigint(Zone* zone, | |
4271 const Bigint& value, | |
4272 intptr_t* index) const { | |
4273 ASSERT(this->raw() == Isolate::Current()->object_store()->bigint_class()); | |
4274 const Array& constants = Array::Handle(zone, this->constants()); | |
4275 const intptr_t constants_len = constants.Length(); | |
4276 // Linear search to see whether this value is already present in the | |
4277 // list of canonicalized constants. | |
4278 Bigint& canonical_value = Bigint::Handle(zone); | |
4279 while (*index < constants_len) { | |
4280 canonical_value ^= constants.At(*index); | |
4281 if (canonical_value.IsNull()) { | |
4282 break; | |
4283 } | |
4284 if (canonical_value.Equals(value)) { | |
4285 ASSERT(canonical_value.IsCanonical()); | |
4286 return canonical_value.raw(); | |
4287 } | |
4288 *index = *index + 1; | |
4289 } | |
4290 return Bigint::null(); | |
4291 } | |
4292 | |
4293 | |
4294 RawInstance* Class::LookupCanonicalInstance(Zone* zone, | |
4295 const Instance& value, | |
4296 intptr_t* index) const { | |
4297 ASSERT(this->raw() == value.clazz()); | |
4298 const Array& constants = Array::Handle(zone, this->constants()); | |
4299 const intptr_t constants_len = constants.Length(); | |
4300 // Linear search to see whether this value is already present in the | |
4301 // list of canonicalized constants. | |
4302 Instance& canonical_value = Instance::Handle(zone); | |
4303 while (*index < constants_len) { | |
4304 canonical_value ^= constants.At(*index); | |
4305 if (canonical_value.IsNull()) { | |
4306 break; | |
4307 } | |
4308 if (value.CanonicalizeEquals(canonical_value)) { | |
4309 ASSERT(canonical_value.IsCanonical()); | |
4310 return canonical_value.raw(); | |
4311 } | |
4312 *index = *index + 1; | |
4313 } | |
4314 return Instance::null(); | |
4315 } | |
4316 | |
4317 | |
4220 void Class::InsertCanonicalConstant(intptr_t index, | 4318 void Class::InsertCanonicalConstant(intptr_t index, |
4221 const Instance& constant) const { | 4319 const Instance& constant) const { |
4222 // The constant needs to be added to the list. Grow the list if it is full. | 4320 // The constant needs to be added to the list. Grow the list if it is full. |
4223 Array& canonical_list = Array::Handle(constants()); | 4321 Array& canonical_list = Array::Handle(constants()); |
4224 const intptr_t list_len = canonical_list.Length(); | 4322 const intptr_t list_len = canonical_list.Length(); |
4225 if (index >= list_len) { | 4323 if (index >= list_len) { |
4226 const intptr_t new_length = (list_len == 0) ? 4 : list_len + 4; | 4324 const intptr_t new_length = (list_len == 0) ? 4 : list_len + 4; |
4227 const Array& new_canonical_list = | 4325 const Array& new_canonical_list = |
4228 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); | 4326 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); |
4229 set_constants(new_canonical_list); | 4327 set_constants(new_canonical_list); |
(...skipping 10119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14349 return this->raw(); | 14447 return this->raw(); |
14350 } | 14448 } |
14351 if (!CheckAndCanonicalizeFields(error_str)) { | 14449 if (!CheckAndCanonicalizeFields(error_str)) { |
14352 return Instance::null(); | 14450 return Instance::null(); |
14353 } | 14451 } |
14354 Thread* thread = Thread::Current(); | 14452 Thread* thread = Thread::Current(); |
14355 Zone* zone = thread->zone(); | 14453 Zone* zone = thread->zone(); |
14356 Isolate* isolate = thread->isolate(); | 14454 Isolate* isolate = thread->isolate(); |
14357 Instance& result = Instance::Handle(zone); | 14455 Instance& result = Instance::Handle(zone); |
14358 const Class& cls = Class::Handle(zone, this->clazz()); | 14456 const Class& cls = Class::Handle(zone, this->clazz()); |
14359 Array& constants = Array::Handle(zone, cls.constants()); | |
14360 const intptr_t constants_len = constants.Length(); | |
14361 // Linear search to see whether this value is already present in the | |
14362 // list of canonicalized constants. | |
14363 intptr_t index = 0; | 14457 intptr_t index = 0; |
14364 while (index < constants_len) { | 14458 result ^= cls.LookupCanonicalInstance(zone, *this, &index); |
14365 result ^= constants.At(index); | 14459 if (!result.IsNull()) { |
14366 if (result.IsNull()) { | 14460 return result.raw(); |
14367 break; | |
14368 } | |
14369 if (this->CanonicalizeEquals(result)) { | |
14370 ASSERT(result.IsCanonical()); | |
14371 return result.raw(); | |
14372 } | |
14373 index++; | |
14374 } | 14461 } |
14375 // The value needs to be added to the list. Grow the list if | 14462 // The value needs to be added to the list. Grow the list if |
14376 // it is full. | 14463 // it is full. |
14377 result ^= this->raw(); | 14464 result ^= this->raw(); |
14378 if (result.IsNew() || | 14465 if (result.IsNew() || |
14379 (result.InVMHeap() && (isolate != Dart::vm_isolate()))) { | 14466 (result.InVMHeap() && (isolate != Dart::vm_isolate()))) { |
14380 /** | 14467 /** |
14381 * When a snapshot is generated on a 64 bit architecture and then read | 14468 * When a snapshot is generated on a 64 bit architecture and then read |
14382 * into a 32 bit architecture, values which are Smi on the 64 bit | 14469 * into a 32 bit architecture, values which are Smi on the 64 bit |
14383 * architecture could potentially be converted to Mint objects, however | 14470 * architecture could potentially be converted to Mint objects, however |
14384 * since Smi values do not have any notion of canonical bits we lose | 14471 * since Smi values do not have any notion of canonical bits we lose |
14385 * that information when the object becomes a Mint. | 14472 * that information when the object becomes a Mint. |
14386 * Some of these values could be literal values and end up in the | 14473 * Some of these values could be literal values and end up in the |
14387 * VM isolate heap. Later when these values are referenced in a | 14474 * VM isolate heap. Later when these values are referenced in a |
14388 * constant list we try to ensure that all the objects in the list | 14475 * constant list we try to ensure that all the objects in the list |
14389 * are canonical and try to canonicalize them. When these Mint objects | 14476 * are canonical and try to canonicalize them. When these Mint objects |
14390 * are encountered they do not have the canonical bit set and | 14477 * are encountered they do not have the canonical bit set and |
14391 * canonicalizing them won't work as the VM heap is read only now. | 14478 * canonicalizing them won't work as the VM heap is read only now. |
14392 * In these cases we clone the object into the isolate and then | 14479 * In these cases we clone the object into the isolate and then |
14393 * canonicalize it. | 14480 * canonicalize it. |
14394 */ | 14481 */ |
14395 // Create a canonical object in old space. | 14482 // Create a canonical object in old space. |
14396 result ^= Object::Clone(result, Heap::kOld); | 14483 result ^= Object::Clone(result, Heap::kOld); |
14397 } | 14484 } |
siva
2016/03/02 19:12:07
As discussed offline this piece of code could move
| |
14398 ASSERT(result.IsOld()); | 14485 ASSERT(result.IsOld()); |
14399 cls.InsertCanonicalConstant(index, result); | 14486 { |
14400 result.SetCanonical(); | 14487 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
14401 return result.raw(); | 14488 // Retry lookup. |
14489 { | |
14490 Instance& temp_result = Instance::Handle(zone, | |
14491 cls.LookupCanonicalInstance(zone, *this, &index)); | |
14492 if (!temp_result.IsNull()) { | |
14493 return temp_result.raw(); | |
14494 } | |
14495 } | |
14496 result.SetCanonical(); | |
14497 cls.InsertCanonicalConstant(index, result); | |
14498 return result.raw(); | |
14499 } | |
14402 } | 14500 } |
14403 | 14501 |
14404 | 14502 |
14405 RawAbstractType* Instance::GetType() const { | 14503 RawAbstractType* Instance::GetType() const { |
14406 if (IsNull()) { | 14504 if (IsNull()) { |
14407 return Type::NullType(); | 14505 return Type::NullType(); |
14408 } | 14506 } |
14409 const Class& cls = Class::Handle(clazz()); | 14507 const Class& cls = Class::Handle(clazz()); |
14410 if (cls.IsClosureClass()) { | 14508 if (cls.IsClosureClass()) { |
14411 const Function& signature = | 14509 const Function& signature = |
(...skipping 3184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17596 result ^= raw; | 17694 result ^= raw; |
17597 } | 17695 } |
17598 result.set_value(val); | 17696 result.set_value(val); |
17599 return result.raw(); | 17697 return result.raw(); |
17600 } | 17698 } |
17601 | 17699 |
17602 | 17700 |
17603 RawMint* Mint::NewCanonical(int64_t value) { | 17701 RawMint* Mint::NewCanonical(int64_t value) { |
17604 // Do not allocate a Mint if Smi would do. | 17702 // Do not allocate a Mint if Smi would do. |
17605 ASSERT(!Smi::IsValid(value)); | 17703 ASSERT(!Smi::IsValid(value)); |
17606 const Class& cls = | 17704 Thread* thread = Thread::Current(); |
17607 Class::Handle(Isolate::Current()->object_store()->mint_class()); | 17705 Zone* zone = thread->zone(); |
17608 const Array& constants = Array::Handle(cls.constants()); | 17706 Isolate* isolate = thread->isolate(); |
17609 const intptr_t constants_len = constants.Length(); | 17707 const Class& cls = Class::Handle(zone, isolate->object_store()->mint_class()); |
17610 // Linear search to see whether this value is already present in the | 17708 Mint& canonical_value = Mint::Handle(zone); |
17611 // list of canonicalized constants. | |
17612 Mint& canonical_value = Mint::Handle(); | |
17613 intptr_t index = 0; | 17709 intptr_t index = 0; |
17614 while (index < constants_len) { | 17710 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); |
17615 canonical_value ^= constants.At(index); | 17711 if (!canonical_value.IsNull()) { |
17616 if (canonical_value.IsNull()) { | 17712 return canonical_value.raw(); |
17617 break; | 17713 } |
17714 canonical_value = Mint::New(value, Heap::kOld); | |
17715 { | |
17716 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | |
17717 // Retry lookup. | |
17718 { | |
17719 const Mint& result = | |
17720 Mint::Handle(zone, cls.LookupCanonicalMint(zone, value, &index)); | |
17721 if (!result.IsNull()) { | |
17722 return result.raw(); | |
17723 } | |
17618 } | 17724 } |
17619 if (canonical_value.value() == value) { | 17725 canonical_value.SetCanonical(); |
17620 ASSERT(canonical_value.IsCanonical()); | 17726 // The value needs to be added to the constants list. Grow the list if |
17621 return canonical_value.raw(); | 17727 // it is full. |
17622 } | 17728 cls.InsertCanonicalConstant(index, canonical_value); |
17623 index++; | 17729 return canonical_value.raw(); |
17624 } | 17730 } |
17625 // The value needs to be added to the constants list. Grow the list if | |
17626 // it is full. | |
17627 canonical_value = Mint::New(value, Heap::kOld); | |
17628 cls.InsertCanonicalConstant(index, canonical_value); | |
17629 canonical_value.SetCanonical(); | |
17630 return canonical_value.raw(); | |
17631 } | 17731 } |
17632 | 17732 |
17633 | 17733 |
17634 bool Mint::Equals(const Instance& other) const { | 17734 bool Mint::Equals(const Instance& other) const { |
17635 if (this->raw() == other.raw()) { | 17735 if (this->raw() == other.raw()) { |
17636 // Both handles point to the same raw instance. | 17736 // Both handles point to the same raw instance. |
17637 return true; | 17737 return true; |
17638 } | 17738 } |
17639 if (!other.IsMint() || other.IsNull()) { | 17739 if (!other.IsMint() || other.IsNull()) { |
17640 return false; | 17740 return false; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17744 RawDouble* Double::New(const String& str, Heap::Space space) { | 17844 RawDouble* Double::New(const String& str, Heap::Space space) { |
17745 double double_value; | 17845 double double_value; |
17746 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 17846 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |
17747 return Double::Handle().raw(); | 17847 return Double::Handle().raw(); |
17748 } | 17848 } |
17749 return New(double_value, space); | 17849 return New(double_value, space); |
17750 } | 17850 } |
17751 | 17851 |
17752 | 17852 |
17753 RawDouble* Double::NewCanonical(double value) { | 17853 RawDouble* Double::NewCanonical(double value) { |
17754 const Class& cls = | 17854 Thread* thread = Thread::Current(); |
17755 Class::Handle(Isolate::Current()->object_store()->double_class()); | 17855 Zone* zone = thread->zone(); |
17756 const Array& constants = Array::Handle(cls.constants()); | 17856 Isolate* isolate = thread->isolate(); |
17757 const intptr_t constants_len = constants.Length(); | 17857 const Class& cls = Class::Handle(isolate->object_store()->double_class()); |
17758 // Linear search to see whether this value is already present in the | 17858 // Linear search to see whether this value is already present in the |
17759 // list of canonicalized constants. | 17859 // list of canonicalized constants. |
17760 Double& canonical_value = Double::Handle(); | 17860 Double& canonical_value = Double::Handle(zone); |
17761 intptr_t index = 0; | 17861 intptr_t index = 0; |
17762 while (index < constants_len) { | 17862 |
17763 canonical_value ^= constants.At(index); | 17863 canonical_value ^= cls.LookupCanonicalDouble(zone, value, &index); |
17764 if (canonical_value.IsNull()) { | 17864 if (!canonical_value.IsNull()) { |
17765 break; | 17865 return canonical_value.raw(); |
17866 } | |
17867 canonical_value = Double::New(value, Heap::kOld); | |
17868 { | |
17869 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | |
17870 // Retry lookup. | |
17871 { | |
17872 const Double& result = | |
17873 Double::Handle(zone, cls.LookupCanonicalDouble(zone, value, &index)); | |
17874 if (!result.IsNull()) { | |
17875 return result.raw(); | |
17876 } | |
17766 } | 17877 } |
17767 if (canonical_value.BitwiseEqualsToDouble(value)) { | 17878 canonical_value.SetCanonical(); |
17768 return canonical_value.raw(); | 17879 // The value needs to be added to the constants list. Grow the list if |
17769 } | 17880 // it is full. |
17770 index++; | 17881 cls.InsertCanonicalConstant(index, canonical_value); |
17882 return canonical_value.raw(); | |
17771 } | 17883 } |
17772 // The value needs to be added to the constants list. Grow the list if | |
17773 // it is full. | |
17774 canonical_value = Double::New(value, Heap::kOld); | |
17775 cls.InsertCanonicalConstant(index, canonical_value); | |
17776 canonical_value.SetCanonical(); | |
17777 return canonical_value.raw(); | |
17778 } | 17884 } |
17779 | 17885 |
17780 | 17886 |
17781 RawDouble* Double::NewCanonical(const String& str) { | 17887 RawDouble* Double::NewCanonical(const String& str) { |
17782 double double_value; | 17888 double double_value; |
17783 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 17889 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |
17784 return Double::Handle().raw(); | 17890 return Double::Handle().raw(); |
17785 } | 17891 } |
17786 return NewCanonical(double_value); | 17892 return NewCanonical(double_value); |
17787 } | 17893 } |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
18048 ((str[1] == 'x') || (str[1] == 'X'))) { | 18154 ((str[1] == 'x') || (str[1] == 'X'))) { |
18049 digits = NewDigitsFromHexCString(&str[2], &used, space); | 18155 digits = NewDigitsFromHexCString(&str[2], &used, space); |
18050 } else { | 18156 } else { |
18051 digits = NewDigitsFromDecCString(str, &used, space); | 18157 digits = NewDigitsFromDecCString(str, &used, space); |
18052 } | 18158 } |
18053 return New(neg, used, digits, space); | 18159 return New(neg, used, digits, space); |
18054 } | 18160 } |
18055 | 18161 |
18056 | 18162 |
18057 RawBigint* Bigint::NewCanonical(const String& str) { | 18163 RawBigint* Bigint::NewCanonical(const String& str) { |
18164 Thread* thread = Thread::Current(); | |
18165 Zone* zone = thread->zone(); | |
18166 Isolate* isolate = thread->isolate(); | |
18058 const Bigint& value = Bigint::Handle( | 18167 const Bigint& value = Bigint::Handle( |
18059 Bigint::NewFromCString(str.ToCString(), Heap::kOld)); | 18168 zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); |
18060 const Class& cls = | 18169 const Class& cls = |
18061 Class::Handle(Isolate::Current()->object_store()->bigint_class()); | 18170 Class::Handle(zone, isolate->object_store()->bigint_class()); |
18062 const Array& constants = Array::Handle(cls.constants()); | |
18063 const intptr_t constants_len = constants.Length(); | |
18064 // Linear search to see whether this value is already present in the | |
18065 // list of canonicalized constants. | |
18066 Bigint& canonical_value = Bigint::Handle(); | |
18067 intptr_t index = 0; | 18171 intptr_t index = 0; |
18068 while (index < constants_len) { | 18172 const Bigint& canonical_value = |
18069 canonical_value ^= constants.At(index); | 18173 Bigint::Handle(zone, cls.LookupCanonicalBigint(zone, value, &index)); |
18070 if (canonical_value.IsNull()) { | 18174 if (!canonical_value.IsNull()) { |
18071 break; | 18175 return canonical_value.raw(); |
18176 } | |
18177 { | |
18178 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | |
18179 // Retry lookup. | |
18180 { | |
18181 const Bigint& result = | |
18182 Bigint::Handle(zone, cls.LookupCanonicalBigint(zone, value, &index)); | |
18183 if (!result.IsNull()) { | |
18184 return result.raw(); | |
18185 } | |
18072 } | 18186 } |
18073 if (canonical_value.Equals(value)) { | 18187 value.SetCanonical(); |
18074 return canonical_value.raw(); | 18188 // The value needs to be added to the constants list. Grow the list if |
18075 } | 18189 // it is full. |
18076 index++; | 18190 cls.InsertCanonicalConstant(index, value); |
18191 return value.raw(); | |
18077 } | 18192 } |
18078 // The value needs to be added to the constants list. Grow the list if | |
18079 // it is full. | |
18080 cls.InsertCanonicalConstant(index, value); | |
18081 value.SetCanonical(); | |
18082 return value.raw(); | |
18083 } | 18193 } |
18084 | 18194 |
18085 | 18195 |
18086 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used, | 18196 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used, |
18087 Heap::Space space) { | 18197 Heap::Space space) { |
18088 const int kBitsPerHexDigit = 4; | 18198 const int kBitsPerHexDigit = 4; |
18089 const int kHexDigitsPerDigit = 8; | 18199 const int kHexDigitsPerDigit = 8; |
18090 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; | 18200 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; |
18091 intptr_t hex_i = strlen(str); // Terminating byte excluded. | 18201 intptr_t hex_i = strlen(str); // Terminating byte excluded. |
18092 if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { | 18202 if ((hex_i <= 0) || (hex_i >= kMaxInt32)) { |
(...skipping 3608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
21701 return UserTag::null(); | 21811 return UserTag::null(); |
21702 } | 21812 } |
21703 | 21813 |
21704 | 21814 |
21705 const char* UserTag::ToCString() const { | 21815 const char* UserTag::ToCString() const { |
21706 const String& tag_label = String::Handle(label()); | 21816 const String& tag_label = String::Handle(label()); |
21707 return tag_label.ToCString(); | 21817 return tag_label.ToCString(); |
21708 } | 21818 } |
21709 | 21819 |
21710 } // namespace dart | 21820 } // namespace dart |
OLD | NEW |