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

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

Issue 2005723004: Fraction class prototype and test (not to be committed). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: work in progress Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 cls = Class::NewStringClass(kOneByteStringCid); 696 cls = Class::NewStringClass(kOneByteStringCid);
697 isolate->object_store()->set_one_byte_string_class(cls); 697 isolate->object_store()->set_one_byte_string_class(cls);
698 cls = Class::NewStringClass(kTwoByteStringCid); 698 cls = Class::NewStringClass(kTwoByteStringCid);
699 isolate->object_store()->set_two_byte_string_class(cls); 699 isolate->object_store()->set_two_byte_string_class(cls);
700 cls = Class::New<Mint>(); 700 cls = Class::New<Mint>();
701 isolate->object_store()->set_mint_class(cls); 701 isolate->object_store()->set_mint_class(cls);
702 cls = Class::New<Bigint>(); 702 cls = Class::New<Bigint>();
703 isolate->object_store()->set_bigint_class(cls); 703 isolate->object_store()->set_bigint_class(cls);
704 cls = Class::New<Double>(); 704 cls = Class::New<Double>();
705 isolate->object_store()->set_double_class(cls); 705 isolate->object_store()->set_double_class(cls);
706 cls = Class::New<Fraction>();
707 // TODO(regis): Remove once native getters are implemented for _Fraction.
708 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
709 isolate->object_store()->set_fraction_class(cls);
706 710
707 // Ensure that class kExternalTypedDataUint8ArrayCid is registered as we 711 // Ensure that class kExternalTypedDataUint8ArrayCid is registered as we
708 // need it when reading in the token stream of bootstrap classes in the VM 712 // need it when reading in the token stream of bootstrap classes in the VM
709 // isolate. 713 // isolate.
710 Class::NewExternalTypedDataClass(kExternalTypedDataUint8ArrayCid); 714 Class::NewExternalTypedDataClass(kExternalTypedDataUint8ArrayCid);
711 715
712 // Needed for object pools of VM isolate stubs. 716 // Needed for object pools of VM isolate stubs.
713 Class::NewTypedDataClass(kTypedDataInt8ArrayCid); 717 Class::NewTypedDataClass(kTypedDataInt8ArrayCid);
714 718
715 // Allocate and initialize the empty_array instance. 719 // Allocate and initialize the empty_array instance.
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 cls = Class::New<Bigint>(); 1375 cls = Class::New<Bigint>();
1372 object_store->set_bigint_class(cls); 1376 object_store->set_bigint_class(cls);
1373 RegisterPrivateClass(cls, Symbols::_Bigint(), core_lib); 1377 RegisterPrivateClass(cls, Symbols::_Bigint(), core_lib);
1374 pending_classes.Add(cls); 1378 pending_classes.Add(cls);
1375 1379
1376 cls = Class::New<Double>(); 1380 cls = Class::New<Double>();
1377 object_store->set_double_class(cls); 1381 object_store->set_double_class(cls);
1378 RegisterPrivateClass(cls, Symbols::_Double(), core_lib); 1382 RegisterPrivateClass(cls, Symbols::_Double(), core_lib);
1379 pending_classes.Add(cls); 1383 pending_classes.Add(cls);
1380 1384
1385 cls = Class::New<Fraction>();
1386 object_store->set_fraction_class(cls);
1387 // TODO(regis): Remove once native getters are implemented for _Fraction.
1388 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
1389 RegisterPrivateClass(cls, Symbols::_Fraction(), core_lib);
1390 pending_classes.Add(cls);
1391
1381 // Class that represents the Dart class _Closure and C++ class Closure. 1392 // Class that represents the Dart class _Closure and C++ class Closure.
1382 cls = Class::New<Closure>(); 1393 cls = Class::New<Closure>();
1383 cls.set_type_arguments_field_offset(Closure::type_arguments_offset()); 1394 cls.set_type_arguments_field_offset(Closure::type_arguments_offset());
1384 cls.set_num_type_arguments(0); // Although a closure has type_arguments_. 1395 cls.set_num_type_arguments(0); // Although a closure has type_arguments_.
1385 cls.set_num_own_type_arguments(0); 1396 cls.set_num_own_type_arguments(0);
1386 RegisterPrivateClass(cls, Symbols::_Closure(), core_lib); 1397 RegisterPrivateClass(cls, Symbols::_Closure(), core_lib);
1387 pending_classes.Add(cls); 1398 pending_classes.Add(cls);
1388 object_store->set_closure_class(cls); 1399 object_store->set_closure_class(cls);
1389 1400
1390 cls = Class::New<WeakProperty>(); 1401 cls = Class::New<WeakProperty>();
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 cls = Class::NewTypedDataViewClass(kTypedData##clazz##ViewCid); 1702 cls = Class::NewTypedDataViewClass(kTypedData##clazz##ViewCid);
1692 CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_VIEW_CLASS); 1703 CLASS_LIST_TYPED_DATA(REGISTER_TYPED_DATA_VIEW_CLASS);
1693 #undef REGISTER_TYPED_DATA_VIEW_CLASS 1704 #undef REGISTER_TYPED_DATA_VIEW_CLASS
1694 cls = Class::NewTypedDataViewClass(kByteDataViewCid); 1705 cls = Class::NewTypedDataViewClass(kByteDataViewCid);
1695 #define REGISTER_EXT_TYPED_DATA_CLASS(clazz) \ 1706 #define REGISTER_EXT_TYPED_DATA_CLASS(clazz) \
1696 cls = Class::NewExternalTypedDataClass(kExternalTypedData##clazz##Cid); 1707 cls = Class::NewExternalTypedDataClass(kExternalTypedData##clazz##Cid);
1697 CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS); 1708 CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS);
1698 #undef REGISTER_EXT_TYPED_DATA_CLASS 1709 #undef REGISTER_EXT_TYPED_DATA_CLASS
1699 1710
1700 cls = Class::New<Instance>(kByteBufferCid); 1711 cls = Class::New<Instance>(kByteBufferCid);
1712 object_store->set_byte_buffer_class(cls);
1701 1713
1702 cls = Class::New<Integer>(); 1714 cls = Class::New<Integer>();
1703 object_store->set_integer_implementation_class(cls); 1715 object_store->set_integer_implementation_class(cls);
1704 1716
1705 cls = Class::New<Smi>(); 1717 cls = Class::New<Smi>();
1706 object_store->set_smi_class(cls); 1718 object_store->set_smi_class(cls);
1707 1719
1708 cls = Class::New<Mint>(); 1720 cls = Class::New<Mint>();
1709 object_store->set_mint_class(cls); 1721 object_store->set_mint_class(cls);
1710 1722
1711 cls = Class::New<Double>(); 1723 cls = Class::New<Double>();
1712 object_store->set_double_class(cls); 1724 object_store->set_double_class(cls);
1713 1725
1726 cls = Class::New<Fraction>();
1727 // TODO(regis): Remove once native getters are implemented for _Fraction.
1728 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
1729 object_store->set_fraction_class(cls);
1730
1714 cls = Class::New<Closure>(); 1731 cls = Class::New<Closure>();
1715 object_store->set_closure_class(cls); 1732 object_store->set_closure_class(cls);
1716 1733
1717 cls = Class::New<Bigint>(); 1734 cls = Class::New<Bigint>();
1718 object_store->set_bigint_class(cls); 1735 object_store->set_bigint_class(cls);
1719 1736
1720 cls = Class::NewStringClass(kOneByteStringCid); 1737 cls = Class::NewStringClass(kOneByteStringCid);
1721 object_store->set_one_byte_string_class(cls); 1738 object_store->set_one_byte_string_class(cls);
1722 1739
1723 cls = Class::NewStringClass(kTwoByteStringCid); 1740 cls = Class::NewStringClass(kTwoByteStringCid);
(...skipping 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after
3565 3582
3566 3583
3567 void Class::set_is_finalized() const { 3584 void Class::set_is_finalized() const {
3568 ASSERT(!is_finalized()); 3585 ASSERT(!is_finalized());
3569 set_state_bits(ClassFinalizedBits::update(RawClass::kFinalized, 3586 set_state_bits(ClassFinalizedBits::update(RawClass::kFinalized,
3570 raw_ptr()->state_bits_)); 3587 raw_ptr()->state_bits_));
3571 } 3588 }
3572 3589
3573 3590
3574 void Class::SetRefinalizeAfterPatch() const { 3591 void Class::SetRefinalizeAfterPatch() const {
3575 ASSERT(!IsTopLevel()); 3592 ASSERT((raw_ptr()->name_ == String::null()) || !IsTopLevel());
3576 set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch, 3593 set_state_bits(ClassFinalizedBits::update(RawClass::kRefinalizeAfterPatch,
3577 raw_ptr()->state_bits_)); 3594 raw_ptr()->state_bits_));
3578 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_)); 3595 set_state_bits(TypeFinalizedBit::update(false, raw_ptr()->state_bits_));
3579 } 3596 }
3580 3597
3581 3598
3582 void Class::ResetFinalization() const { 3599 void Class::ResetFinalization() const {
3583 ASSERT(IsTopLevel()); 3600 ASSERT(IsTopLevel());
3584 set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated, 3601 set_state_bits(ClassFinalizedBits::update(RawClass::kAllocated,
3585 raw_ptr()->state_bits_)); 3602 raw_ptr()->state_bits_));
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 if (canonical_value.Equals(value)) { 4348 if (canonical_value.Equals(value)) {
4332 ASSERT(canonical_value.IsCanonical()); 4349 ASSERT(canonical_value.IsCanonical());
4333 return canonical_value.raw(); 4350 return canonical_value.raw();
4334 } 4351 }
4335 *index = *index + 1; 4352 *index = *index + 1;
4336 } 4353 }
4337 return Bigint::null(); 4354 return Bigint::null();
4338 } 4355 }
4339 4356
4340 4357
4358 RawFraction* Class::LookupCanonicalFraction(Zone* zone,
4359 const Fraction& value,
4360 intptr_t* index) const {
4361 ASSERT(this->raw() == Isolate::Current()->object_store()->fraction_class());
4362 const Array& constants = Array::Handle(zone, this->constants());
4363 const intptr_t constants_len = constants.Length();
4364 // Linear search to see whether this value is already present in the
4365 // list of canonicalized constants.
4366 Fraction& canonical_value = Fraction::Handle(zone);
4367 while (*index < constants_len) {
4368 canonical_value ^= constants.At(*index);
4369 if (canonical_value.IsNull()) {
4370 break;
4371 }
4372 if (canonical_value.CanonicalizeEquals(value)) {
4373 ASSERT(canonical_value.IsCanonical());
4374 return canonical_value.raw();
4375 }
4376 *index = *index + 1;
4377 }
4378 return Fraction::null();
4379 }
4380
4381
4341 class CanonicalInstanceKey { 4382 class CanonicalInstanceKey {
4342 public: 4383 public:
4343 explicit CanonicalInstanceKey(const Instance& key) : key_(key) { 4384 explicit CanonicalInstanceKey(const Instance& key) : key_(key) {
4344 ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType())); 4385 ASSERT(!(key.IsString() || key.IsInteger() || key.IsAbstractType()));
4345 } 4386 }
4346 bool Matches(const Instance& obj) const { 4387 bool Matches(const Instance& obj) const {
4347 ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType())); 4388 ASSERT(!(obj.IsString() || obj.IsInteger() || obj.IsAbstractType()));
4348 if (key_.CanonicalizeEquals(obj)) { 4389 if (key_.CanonicalizeEquals(obj)) {
4349 ASSERT(obj.IsCanonical()); 4390 ASSERT(obj.IsCanonical());
4350 return true; 4391 return true;
(...skipping 3659 matching lines...) Expand 10 before | Expand all | Expand 10 after
8010 8051
8011 8052
8012 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { 8053 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) {
8013 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); 8054 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New());
8014 result.set_kind(kind); 8055 result.set_kind(kind);
8015 result.set_literal(literal); 8056 result.set_literal(literal);
8016 if (kind == Token::kINTEGER) { 8057 if (kind == Token::kINTEGER) {
8017 const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); 8058 const Integer& value = Integer::Handle(Integer::NewCanonical(literal));
8018 ASSERT(value.IsSmi() || value.IsOld()); 8059 ASSERT(value.IsSmi() || value.IsOld());
8019 result.set_value(value); 8060 result.set_value(value);
8061 } else if (kind == Token::kRATIONAL) {
8062 const Fraction& value = Fraction::Handle(Fraction::NewCanonical(literal));
8063 result.set_value(value);
8020 } else if (kind == Token::kDOUBLE) { 8064 } else if (kind == Token::kDOUBLE) {
8021 const Double& value = Double::Handle(Double::NewCanonical(literal)); 8065 const Double& value = Double::Handle(Double::NewCanonical(literal));
8022 result.set_value(value); 8066 result.set_value(value);
8023 } else { 8067 } else {
8024 ASSERT(Token::NeedsLiteralToken(kind)); 8068 ASSERT(Token::NeedsLiteralToken(kind));
8025 result.set_value(literal); 8069 result.set_value(literal);
8026 } 8070 }
8027 return result.raw(); 8071 return result.raw();
8028 } 8072 }
8029 8073
(...skipping 10024 matching lines...) Expand 10 before | Expand all | Expand 10 after
18054 if (result.IsNew()) { 18098 if (result.IsNew()) {
18055 // Create a canonical object in old space. 18099 // Create a canonical object in old space.
18056 result ^= Object::Clone(result, Heap::kOld); 18100 result ^= Object::Clone(result, Heap::kOld);
18057 } 18101 }
18058 ASSERT(result.IsOld()); 18102 ASSERT(result.IsOld());
18059 result.SetCanonical(); 18103 result.SetCanonical();
18060 cls.InsertCanonicalNumber(zone, index, result); 18104 cls.InsertCanonicalNumber(zone, index, result);
18061 return result.raw(); 18105 return result.raw();
18062 } 18106 }
18063 } 18107 }
18108 case kFractionCid: {
18109 return Fraction::NewCanonical(Fraction::Cast(*this));
18110 }
18064 default: 18111 default:
18065 UNREACHABLE(); 18112 UNREACHABLE();
18066 } 18113 }
18067 return Instance::null(); 18114 return Instance::null();
18068 } 18115 }
18069 18116
18070 18117
18071 const char* Number::ToCString() const { 18118 const char* Number::ToCString() const {
18072 // Number is an interface. No instances of Number should exist. 18119 // Number is an interface. No instances of Number should exist.
18073 UNREACHABLE(); 18120 UNREACHABLE();
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
18952 } 18999 }
18953 { 19000 {
18954 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); 19001 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
18955 // Retry lookup. 19002 // Retry lookup.
18956 { 19003 {
18957 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index); 19004 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index);
18958 if (!canonical_value.IsNull()) { 19005 if (!canonical_value.IsNull()) {
18959 return canonical_value.raw(); 19006 return canonical_value.raw();
18960 } 19007 }
18961 } 19008 }
19009 ASSERT(value.IsOld());
18962 value.SetCanonical(); 19010 value.SetCanonical();
18963 // The value needs to be added to the constants list. Grow the list if 19011 // The value needs to be added to the constants list. Grow the list if
18964 // it is full. 19012 // it is full.
18965 cls.InsertCanonicalNumber(zone, index, value); 19013 cls.InsertCanonicalNumber(zone, index, value);
18966 return value.raw(); 19014 return value.raw();
18967 } 19015 }
18968 } 19016 }
18969 19017
18970 19018
18971 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used, 19019 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used,
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
19444 Zone* zone = Thread::Current()->zone(); 19492 Zone* zone = Thread::Current()->zone();
19445 return zone->AllocUnsafe(size); 19493 return zone->AllocUnsafe(size);
19446 } 19494 }
19447 19495
19448 19496
19449 const char* Bigint::ToCString() const { 19497 const char* Bigint::ToCString() const {
19450 return ToDecCString(&BigintAllocator); 19498 return ToDecCString(&BigintAllocator);
19451 } 19499 }
19452 19500
19453 19501
19502 bool Fraction::CanonicalizeEquals(const Instance& other) const {
19503 if (this->raw() == other.raw()) {
19504 return true; // "===".
19505 }
19506 if (other.IsNull() || !other.IsFraction()) {
19507 return false;
19508 }
19509 return (numerator() == Fraction::Cast(other).numerator()) &&
19510 (denominator() == Fraction::Cast(other).denominator());
19511 }
19512
19513
19514 RawFraction* Fraction::New(Heap::Space space) {
19515 return Fraction::New(0, 0, space);
19516 }
19517
19518
19519 RawFraction* Fraction::New(uint64_t numerator,
19520 uint64_t denominator,
19521 Heap::Space space) {
19522 Thread* thread = Thread::Current();
19523 Zone* zone = thread->zone();
19524 Isolate* isolate = thread->isolate();
19525 ASSERT(isolate->object_store()->fraction_class() != Class::null());
19526 Fraction& result = Fraction::Handle(zone);
19527 {
19528 RawObject* raw = Object::Allocate(Fraction::kClassId,
19529 Fraction::InstanceSize(),
19530 space);
19531 NoSafepointScope no_safepoint;
19532 result ^= raw;
19533 }
19534 result.set_numerator(Integer::Handle(
19535 Integer::NewFromUint64(numerator, space)));
19536 result.set_denominator(Integer::Handle(
19537 Integer::NewFromUint64(denominator, space)));
19538 return result.raw();
19539 }
19540
19541
19542 void Fraction::set_numerator(const Integer& value) const {
19543 StorePointer(&raw_ptr()->numerator_, value.raw());
19544 }
19545
19546
19547 static bool CStringToFraction(const char* str,
19548 intptr_t length,
19549 uint64_t* numerator,
19550 uint64_t* denominator) {
19551 ASSERT(str != NULL);
19552 ASSERT(length > 0);
19553 const uint64_t max_accum = (1ULL << 63) / 10;
19554 uint64_t num = 0ULL;
19555 uint64_t denom = 1ULL;
19556 bool seen_decimal_point = false;
19557 for (intptr_t i = 0; i < length; i++) {
19558 char c = str[i];
19559 if (!seen_decimal_point && (c == '.')) {
19560 seen_decimal_point = true;
19561 } else if (('0' <= c) && (c <= '9')) {
19562 // Bail if numerator or denominator get close to Bigint.
19563 if ((num > max_accum) || (denom > max_accum)) {
19564 return false;
19565 }
19566 num = num*10 + (c - '0');
19567 if (seen_decimal_point) denom *= 10;
19568 } else {
19569 if ((str[i] != 'r') && (str[i] != 'R')) {
19570 return false;
19571 }
19572 break;
19573 }
19574 }
19575 // Reduce somewhat. Do not reduce if denominator is 100.
19576 while ((denom != 100ULL) && ((num & 1) == 0) && ((denom & 1) == 0)) {
19577 num >>= 1;
19578 denom >>= 1;
19579 }
19580 // TODO(regis): Reduce further using gcd.
19581 *numerator = num;
19582 *denominator = denom;
19583 return true;
19584 }
19585
19586
19587 RawFraction* Fraction::NewCanonical(const String& str) {
19588 uint64_t nominator;
19589 uint64_t denominator;
19590 if (!CStringToFraction(str.ToCString(), str.Length(),
19591 &nominator, &denominator)) {
19592 // Call the Dart version, which supports Bigint.
19593 // Not supported when called early from core lib itself.
19594 const Library& core_lib = Library::Handle(Library::CoreLibrary());
19595 ASSERT(!core_lib.IsNull());
19596 const String& fraction_class_name = Symbols::_Fraction();
19597 const String& constructor_name = Symbols::DotFromRationalLiteral();
19598 const Array& constructor_args = Array::Handle(Array::New(1));
19599 constructor_args.SetAt(0, str);
19600 Object& value = Object::Handle(
19601 DartLibraryCalls::InstanceCreate(core_lib,
19602 fraction_class_name,
19603 constructor_name,
19604 true, // A factory.
19605 constructor_args));
19606 ASSERT(!value.IsError());
19607 return Fraction::NewCanonical(Fraction::Cast(value));
19608 }
19609 return Fraction::NewCanonical(Fraction::Handle(
19610 Fraction::New(nominator, denominator, Heap::kOld)));
19611 }
19612
19613
19614 RawFraction* Fraction::NewCanonical(const Fraction& value) {
19615 // TODO(regis): Canonicalize fields.
19616 Thread* thread = Thread::Current();
19617 Zone* zone = thread->zone();
19618 Isolate* isolate = thread->isolate();
19619 const Class& cls =
19620 Class::Handle(zone, isolate->object_store()->fraction_class());
19621 intptr_t index = 0;
19622 Fraction& canonical_value = Fraction::Handle(zone);
19623 canonical_value ^= cls.LookupCanonicalFraction(zone, value, &index);
19624 if (!canonical_value.IsNull()) {
19625 return canonical_value.raw();
19626 }
19627 {
19628 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
19629 // Retry lookup.
19630 {
19631 canonical_value ^= cls.LookupCanonicalFraction(zone, value, &index);
19632 if (!canonical_value.IsNull()) {
19633 return canonical_value.raw();
19634 }
19635 }
19636 Fraction& result = Fraction::Handle(zone, value.raw());
19637 if (result.IsNew()) {
19638 // Create a canonical object in old space.
19639 result ^= Object::Clone(result, Heap::kOld);
19640 }
19641 ASSERT(result.IsOld());
19642 result.SetCanonical();
19643 // The value needs to be added to the constants list. Grow the list if
19644 // it is full.
19645 cls.InsertCanonicalNumber(zone, index, result);
19646 return result.raw();
19647 }
19648 }
19649
19650
19651 void Fraction::set_denominator(const Integer& value) const {
19652 StorePointer(&raw_ptr()->denominator_, value.raw());
19653 }
19654
19655
19656 const char* Fraction::ToCString() const {
19657 if (IsNull()) {
19658 return "_Fraction NULL";
19659 }
19660 return OS::SCreate(Thread::Current()->zone(), "_Fraction %s/%s",
19661 Integer::Handle(numerator()).ToCString(),
19662 Integer::Handle(denominator()).ToCString());
19663 }
19664
19665
19454 // Synchronize with implementation in compiler (intrinsifier). 19666 // Synchronize with implementation in compiler (intrinsifier).
19455 class StringHasher : ValueObject { 19667 class StringHasher : ValueObject {
19456 public: 19668 public:
19457 StringHasher() : hash_(0) {} 19669 StringHasher() : hash_(0) {}
19458 void Add(int32_t ch) { 19670 void Add(int32_t ch) {
19459 hash_ = CombineHashes(hash_, ch); 19671 hash_ = CombineHashes(hash_, ch);
19460 } 19672 }
19461 void Add(const String& str, intptr_t begin_index, intptr_t len); 19673 void Add(const String& str, intptr_t begin_index, intptr_t len);
19462 19674
19463 // Return a non-zero hash of at most 'bits' bits. 19675 // Return a non-zero hash of at most 'bits' bits.
(...skipping 3131 matching lines...) Expand 10 before | Expand all | Expand 10 after
22595 return UserTag::null(); 22807 return UserTag::null();
22596 } 22808 }
22597 22809
22598 22810
22599 const char* UserTag::ToCString() const { 22811 const char* UserTag::ToCString() const {
22600 const String& tag_label = String::Handle(label()); 22812 const String& tag_label = String::Handle(label());
22601 return tag_label.ToCString(); 22813 return tag_label.ToCString();
22602 } 22814 }
22603 22815
22604 } // namespace dart 22816 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698