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

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

Issue 2035453002: Pixels class prototype and test (not to be committed). 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<Pixels>();
707 // TODO(regis): Remove once native getters are implemented for _Pixels.
708 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
709 isolate->object_store()->set_pixels_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<Pixels>();
1386 object_store->set_pixels_class(cls);
1387 // TODO(regis): Remove once native getters are implemented for _Pixels.
1388 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
1389 RegisterPrivateClass(cls, Symbols::_Pixels(), 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<Pixels>();
1727 // TODO(regis): Remove once native getters are implemented for _Pixels.
1728 cls.SetRefinalizeAfterPatch(); // Fields are defined both in C++ and in Dart.
1729 object_store->set_pixels_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 RawPixels* Class::LookupCanonicalPixels(Zone* zone,
4359 intptr_t value,
4360 intptr_t* index) const {
4361 ASSERT(this->raw() == Isolate::Current()->object_store()->pixels_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 Pixels& canonical_value = Pixels::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.Value() == value) {
4373 ASSERT(canonical_value.IsCanonical());
4374 return canonical_value.raw();
4375 }
4376 *index = *index + 1;
4377 }
4378 return Pixels::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::kPIXELS) {
8062 const Pixels& value = Pixels::Handle(Pixels::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 kPixelsCid: {
18109 return Pixels::NewCanonical(Pixels::Cast(*this).Value());
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 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after
19444 Zone* zone = Thread::Current()->zone(); 19491 Zone* zone = Thread::Current()->zone();
19445 return zone->AllocUnsafe(size); 19492 return zone->AllocUnsafe(size);
19446 } 19493 }
19447 19494
19448 19495
19449 const char* Bigint::ToCString() const { 19496 const char* Bigint::ToCString() const {
19450 return ToDecCString(&BigintAllocator); 19497 return ToDecCString(&BigintAllocator);
19451 } 19498 }
19452 19499
19453 19500
19501 bool Pixels::CanonicalizeEquals(const Instance& other) const {
19502 if (this->raw() == other.raw()) {
19503 return true; // "===".
19504 }
19505 if (other.IsNull() || !other.IsPixels()) {
19506 return false;
19507 }
19508 return Value() == Pixels::Cast(other).Value();
19509 }
19510
19511
19512 RawPixels* Pixels::New(intptr_t value, Heap::Space space) {
19513 Thread* thread = Thread::Current();
19514 Zone* zone = thread->zone();
19515 Isolate* isolate = thread->isolate();
19516 ASSERT(isolate->object_store()->pixels_class() != Class::null());
19517 Pixels& result = Pixels::Handle(zone);
19518 {
19519 RawObject* raw = Object::Allocate(Pixels::kClassId,
19520 Pixels::InstanceSize(),
19521 space);
19522 NoSafepointScope no_safepoint;
19523 result ^= raw;
19524 }
19525 result.set_value(value);
19526 return result.raw();
19527 }
19528
19529
19530 static bool CStringToPixels(const char* str,
19531 intptr_t length,
19532 intptr_t* result) {
19533 ASSERT(str != NULL);
19534 ASSERT(length > 0);
19535 const uint64_t max_accum = (1LL << (63 - Pixels::kFractionalBits)) / 10;
19536 uint64_t numerator = 0LL;
19537 uint64_t denominator = 1LL;
19538 bool seen_decimal_point = false;
19539 for (intptr_t i = 0; i < length; i++) {
19540 char c = str[i];
19541 if (!seen_decimal_point && (c == '.')) {
19542 seen_decimal_point = true;
19543 } else if (('0' <= c) && (c <= '9')) {
19544 // Ignore extra digits not contributing to the result.
19545 if ((numerator < max_accum) && (denominator < max_accum)) {
19546 numerator = numerator*10 + (c - '0');
19547 if (seen_decimal_point) denominator *= 10;
19548 }
19549 } else {
19550 if ((strcmp(str + i, "px") != 0) && (strcmp(str + i, "PX") != 0)) {
19551 return false;
19552 }
19553 break;
19554 }
19555 }
19556 uint64_t value = (numerator << Pixels::kFractionalBits) / denominator;
19557 if (value > Pixels::kPlusInfinity) value = Pixels::kPlusInfinity;
19558 *result = static_cast<intptr_t>(value);
19559 return true;
19560 }
19561
19562
19563 RawPixels* Pixels::NewCanonical(const String& str) {
19564 intptr_t value;
19565 if (!CStringToPixels(str.ToCString(), str.Length(), &value)) {
19566 return Pixels::null();
19567 }
19568 return Pixels::NewCanonical(value);
19569 }
19570
19571 RawPixels* Pixels::NewCanonical(intptr_t value) {
19572 Thread* thread = Thread::Current();
19573 Zone* zone = thread->zone();
19574 Isolate* isolate = thread->isolate();
19575 const Class& cls =
19576 Class::Handle(zone, isolate->object_store()->pixels_class());
19577 intptr_t index = 0;
19578 Pixels& canonical_value = Pixels::Handle(zone);
19579 canonical_value ^= cls.LookupCanonicalPixels(zone, value, &index);
19580 if (!canonical_value.IsNull()) {
19581 return canonical_value.raw();
19582 }
19583 {
19584 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
19585 // Retry lookup.
19586 {
19587 canonical_value ^= cls.LookupCanonicalPixels(zone, value, &index);
19588 if (!canonical_value.IsNull()) {
19589 return canonical_value.raw();
19590 }
19591 }
19592 canonical_value = Pixels::New(value, Heap::kOld);
19593 canonical_value.SetCanonical();
19594 // The value needs to be added to the constants list. Grow the list if
19595 // it is full.
19596 cls.InsertCanonicalNumber(zone, index, canonical_value);
19597 return canonical_value.raw();
19598 }
19599 }
19600
19601
19602 void Pixels::set_value(intptr_t value) const {
19603 ASSERT((kMinusInfinity <= value) && (value <= kPlusInfinity));
19604 StoreSmi(&raw_ptr()->value_, Smi::New(value));
19605 }
19606
19607
19608 const char* Pixels::ToCString() const {
19609 if (IsNull()) {
19610 return "_Pixels NULL";
19611 }
19612 // TODO(regis): Handle non finite values.
19613 return OS::SCreate(Thread::Current()->zone(), "_Pixels %f",
19614 static_cast<double>(Value()) / Pixels::kScaling);
19615 }
19616
19617
19454 // Synchronize with implementation in compiler (intrinsifier). 19618 // Synchronize with implementation in compiler (intrinsifier).
19455 class StringHasher : ValueObject { 19619 class StringHasher : ValueObject {
19456 public: 19620 public:
19457 StringHasher() : hash_(0) {} 19621 StringHasher() : hash_(0) {}
19458 void Add(int32_t ch) { 19622 void Add(int32_t ch) {
19459 hash_ = CombineHashes(hash_, ch); 19623 hash_ = CombineHashes(hash_, ch);
19460 } 19624 }
19461 void Add(const String& str, intptr_t begin_index, intptr_t len); 19625 void Add(const String& str, intptr_t begin_index, intptr_t len);
19462 19626
19463 // Return a non-zero hash of at most 'bits' bits. 19627 // 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(); 22759 return UserTag::null();
22596 } 22760 }
22597 22761
22598 22762
22599 const char* UserTag::ToCString() const { 22763 const char* UserTag::ToCString() const {
22600 const String& tag_label = String::Handle(label()); 22764 const String& tag_label = String::Handle(label());
22601 return tag_label.ToCString(); 22765 return tag_label.ToCString();
22602 } 22766 }
22603 22767
22604 } // namespace dart 22768 } // 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