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

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

Issue 8442001: Simplify canonicalization of constants and types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/assert.h" 8 #include "vm/assert.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 result.set_handle_vtable(fake.vtable()); 765 result.set_handle_vtable(fake.vtable());
766 result.set_instance_size(FakeObject::InstanceSize()); 766 result.set_instance_size(FakeObject::InstanceSize());
767 result.set_next_field_offset(FakeObject::InstanceSize()); 767 result.set_next_field_offset(FakeObject::InstanceSize());
768 result.set_instance_kind(FakeObject::kInstanceKind); 768 result.set_instance_kind(FakeObject::kInstanceKind);
769 result.raw_ptr()->is_const_ = false; 769 result.raw_ptr()->is_const_ = false;
770 result.raw_ptr()->is_interface_ = false; 770 result.raw_ptr()->is_interface_ = false;
771 // VM backed classes are almost ready: run checks and resolve class 771 // VM backed classes are almost ready: run checks and resolve class
772 // references, but do not recompute size. 772 // references, but do not recompute size.
773 result.raw_ptr()->class_state_ = RawClass::kPreFinalized; 773 result.raw_ptr()->class_state_ = RawClass::kPreFinalized;
774 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; 774 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
775 result.raw_ptr()->num_constants_ = 0;
776 result.raw_ptr()->num_canonical_types_ = 0;
777 result.raw_ptr()->num_native_fields_ = 0; 775 result.raw_ptr()->num_native_fields_ = 0;
778 result.InitEmptyFields(); 776 result.InitEmptyFields();
779 return result.raw(); 777 return result.raw();
780 } 778 }
781 779
782 780
783 // Initialize class fields of type Array with empty array. 781 // Initialize class fields of type Array with empty array.
784 void Class::InitEmptyFields() { 782 void Class::InitEmptyFields() {
785 const Array& empty_array = Array::Handle(Array::Empty()); 783 const Array& empty_array = Array::Handle(Array::Empty());
786 if (empty_array.IsNull()) { 784 if (empty_array.IsNull()) {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 result.set_handle_vtable(fake.vtable()); 1001 result.set_handle_vtable(fake.vtable());
1004 result.set_instance_size(FakeInstance::InstanceSize()); 1002 result.set_instance_size(FakeInstance::InstanceSize());
1005 result.set_next_field_offset(FakeInstance::InstanceSize()); 1003 result.set_next_field_offset(FakeInstance::InstanceSize());
1006 result.set_instance_kind(FakeInstance::kInstanceKind); 1004 result.set_instance_kind(FakeInstance::kInstanceKind);
1007 result.set_name(name); 1005 result.set_name(name);
1008 result.set_script(script); 1006 result.set_script(script);
1009 result.raw_ptr()->is_const_ = false; 1007 result.raw_ptr()->is_const_ = false;
1010 result.raw_ptr()->is_interface_ = false; 1008 result.raw_ptr()->is_interface_ = false;
1011 result.raw_ptr()->class_state_ = RawClass::kAllocated; 1009 result.raw_ptr()->class_state_ = RawClass::kAllocated;
1012 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments; 1010 result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
1013 result.raw_ptr()->num_constants_ = 0;
1014 result.raw_ptr()->num_canonical_types_ = 0;
1015 result.raw_ptr()->num_native_fields_ = 0; 1011 result.raw_ptr()->num_native_fields_ = 0;
1016 result.InitEmptyFields(); 1012 result.InitEmptyFields();
1017 return result.raw(); 1013 return result.raw();
1018 } 1014 }
1019 1015
1020 1016
1021 RawClass* Class::New(const String& name, const Script& script) { 1017 RawClass* Class::New(const String& name, const Script& script) {
1022 Class& result = Class::Handle(New<Instance>(name, script)); 1018 Class& result = Class::Handle(New<Instance>(name, script));
1023 return result.raw(); 1019 return result.raw();
1024 } 1020 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 RawArray* Class::constants() const { 1191 RawArray* Class::constants() const {
1196 return raw_ptr()->constants_; 1192 return raw_ptr()->constants_;
1197 } 1193 }
1198 1194
1199 void Class::set_constants(const Array& value) const { 1195 void Class::set_constants(const Array& value) const {
1200 ASSERT(!value.IsNull()); 1196 ASSERT(!value.IsNull());
1201 StorePointer(&raw_ptr()->constants_, value.raw()); 1197 StorePointer(&raw_ptr()->constants_, value.raw());
1202 } 1198 }
1203 1199
1204 1200
1205 intptr_t Class::num_constants() const {
1206 return raw_ptr()->num_constants_;
1207 }
1208
1209
1210 void Class::set_num_constants(intptr_t value) const {
1211 raw_ptr()->num_constants_ = value;
1212 }
1213
1214
1215 RawArray* Class::canonical_types() const { 1201 RawArray* Class::canonical_types() const {
1216 return raw_ptr()->canonical_types_; 1202 return raw_ptr()->canonical_types_;
1217 } 1203 }
1218 1204
1219 void Class::set_canonical_types(const Array& value) const { 1205 void Class::set_canonical_types(const Array& value) const {
1220 ASSERT(!value.IsNull()); 1206 ASSERT(!value.IsNull());
1221 StorePointer(&raw_ptr()->canonical_types_, value.raw()); 1207 StorePointer(&raw_ptr()->canonical_types_, value.raw());
1222 } 1208 }
1223 1209
1224 1210
1225 intptr_t Class::num_canonical_types() const {
1226 return raw_ptr()->num_canonical_types_;
1227 }
1228
1229
1230 void Class::set_num_canonical_types(intptr_t value) const {
1231 raw_ptr()->num_canonical_types_ = value;
1232 }
1233
1234
1235 void Class::set_allocation_stub(const Code& value) const { 1211 void Class::set_allocation_stub(const Code& value) const {
1236 ASSERT(!value.IsNull()); 1212 ASSERT(!value.IsNull());
1237 ASSERT(raw_ptr()->allocation_stub_ == Code::null()); 1213 ASSERT(raw_ptr()->allocation_stub_ == Code::null());
1238 StorePointer(&raw_ptr()->allocation_stub_, value.raw()); 1214 StorePointer(&raw_ptr()->allocation_stub_, value.raw());
1239 } 1215 }
1240 1216
1241 1217
1242 bool Class::IsObjectClass() const { 1218 bool Class::IsObjectClass() const {
1243 return raw() == Type::Handle(Type::ObjectType()).type_class(); 1219 return raw() == Type::Handle(Type::ObjectType()).type_class();
1244 } 1220 }
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 RawType* ParameterizedType::Canonicalize() const { 2031 RawType* ParameterizedType::Canonicalize() const {
2056 const Class& cls = Class::Handle(type_class()); 2032 const Class& cls = Class::Handle(type_class());
2057 Array& canonical_types = Array::Handle(cls.canonical_types()); 2033 Array& canonical_types = Array::Handle(cls.canonical_types());
2058 if (canonical_types.IsNull()) { 2034 if (canonical_types.IsNull()) {
2059 // Types defined in the VM isolate are canonicalized via the object store. 2035 // Types defined in the VM isolate are canonicalized via the object store.
2060 // TODO(regis): Should we add null_class_, void_class_, dynamic_class_ to 2036 // TODO(regis): Should we add null_class_, void_class_, dynamic_class_ to
2061 // the object store, remove all types from the object store, and replace 2037 // the object store, remove all types from the object store, and replace
2062 // the test above by an assert? 2038 // the test above by an assert?
2063 return this->raw(); 2039 return this->raw();
2064 } 2040 }
2065 const intptr_t num_canonical_types = cls.num_canonical_types(); 2041 const intptr_t canonical_types_len = canonical_types.Length();
2066 ASSERT(canonical_types.Length() >= num_canonical_types);
2067 // Linear search to see whether this type is already present in the 2042 // Linear search to see whether this type is already present in the
2068 // list of canonicalized types. 2043 // list of canonicalized types.
2069 Type& type = Type::Handle(); 2044 Type& type = Type::Handle();
2070 for (int i = 0; i < num_canonical_types; i++) { 2045 intptr_t index = 0;
2071 type ^= canonical_types.At(i); 2046 while (index < canonical_types_len) {
2072 ASSERT(!type.IsNull()); 2047 type ^= canonical_types.At(index);
2048 if (type.IsNull()) {
2049 break;
2050 }
2073 if (this->Equals(type)) { 2051 if (this->Equals(type)) {
2074 return type.raw(); 2052 return type.raw();
2075 } 2053 }
2054 index++;
2076 } 2055 }
2077 // The type needs to be added to the list. Grow the list if it is full. 2056 // The type needs to be added to the list. Grow the list if it is full.
2078 if (canonical_types.Length() == num_canonical_types) { 2057 if (index == canonical_types_len) {
2079 const intptr_t kLengthIncrement = 2; // Raw and parameterized. 2058 const intptr_t kLengthIncrement = 2; // Raw and parameterized.
2080 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; 2059 const intptr_t new_length = canonical_types.Length() + kLengthIncrement;
2081 const Array& new_canonical_types = 2060 const Array& new_canonical_types =
2082 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); 2061 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld));
2083 cls.set_canonical_types(new_canonical_types); 2062 cls.set_canonical_types(new_canonical_types);
2084 new_canonical_types.SetAt(num_canonical_types, *this); 2063 new_canonical_types.SetAt(index, *this);
2085 } else { 2064 } else {
2086 canonical_types.SetAt(num_canonical_types, *this); 2065 canonical_types.SetAt(index, *this);
2087 } 2066 }
2088 cls.set_num_canonical_types(num_canonical_types + 1);
2089 return this->raw(); 2067 return this->raw();
2090 } 2068 }
2091 2069
2092 2070
2093 void ParameterizedType::set_type_class(const Object& value) const { 2071 void ParameterizedType::set_type_class(const Object& value) const {
2094 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); 2072 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass()));
2095 StorePointer(&raw_ptr()->type_class_, value.raw()); 2073 StorePointer(&raw_ptr()->type_class_, value.raw());
2096 } 2074 }
2097 2075
2098 2076
(...skipping 2704 matching lines...) Expand 10 before | Expand all | Expand 10 after
4803 (*reinterpret_cast<RawObject**>(other_addr + offset))) { 4781 (*reinterpret_cast<RawObject**>(other_addr + offset))) {
4804 return false; 4782 return false;
4805 } 4783 }
4806 } 4784 }
4807 } 4785 }
4808 return true; 4786 return true;
4809 } 4787 }
4810 4788
4811 4789
4812 RawInstance* Instance::Canonicalize() const { 4790 RawInstance* Instance::Canonicalize() const {
4791 ASSERT(!IsNull());
4813 const Class& cls = Class::Handle(this->clazz()); 4792 const Class& cls = Class::Handle(this->clazz());
4814 Array& constants = Array::Handle(cls.constants()); 4793 Array& constants = Array::Handle(cls.constants());
4815 const intptr_t num_constants = cls.num_constants(); 4794 const intptr_t constants_len = constants.Length();
4816 ASSERT(constants.Length() >= num_constants);
4817 // Linear search to see whether this value is already present in the 4795 // Linear search to see whether this value is already present in the
4818 // list of canonicalized constants. 4796 // list of canonicalized constants.
4819 Instance& norm_value = Instance::Handle(); 4797 Instance& norm_value = Instance::Handle();
4820 for (int i = 0; i < num_constants; i++) { 4798 intptr_t index = 0;
4821 norm_value ^= constants.At(i); 4799 while (index < constants_len) {
4822 ASSERT(!norm_value.IsNull()); 4800 norm_value ^= constants.At(index);
4801 if (norm_value.IsNull()) {
4802 break;
4803 }
4823 if (this->Equals(norm_value)) { 4804 if (this->Equals(norm_value)) {
4824 return norm_value.raw(); 4805 return norm_value.raw();
4825 } 4806 }
4807 index++;
4826 } 4808 }
4827 // The value needs to be added to the list. Grow the list if 4809 // The value needs to be added to the list. Grow the list if
4828 // it is full. 4810 // it is full.
4829 if (constants.Length() == num_constants) { 4811 if (index == constants_len) {
4830 const intptr_t kInitialConstLength = 4; 4812 const intptr_t kInitialConstLength = 4;
4831 const intptr_t old_length = constants.Length(); 4813 const intptr_t old_length = constants.Length();
4832 const intptr_t new_length = 4814 const intptr_t new_length =
4833 (old_length == 0) ? kInitialConstLength : old_length * 2; 4815 (old_length == 0) ? kInitialConstLength : old_length * 2;
4834 const Array& new_constants = 4816 const Array& new_constants =
4835 Array::Handle(Array::Grow(constants, new_length, Heap::kOld)); 4817 Array::Handle(Array::Grow(constants, new_length, Heap::kOld));
4836 cls.set_constants(new_constants); 4818 cls.set_constants(new_constants);
4837 new_constants.SetAt(num_constants, *this); 4819 new_constants.SetAt(index, *this);
4838 } else { 4820 } else {
4839 constants.SetAt(num_constants, *this); 4821 constants.SetAt(index, *this);
4840 } 4822 }
4841 cls.set_num_constants(num_constants + 1);
4842 return this->raw(); 4823 return this->raw();
4843 } 4824 }
4844 4825
4845 4826
4846 RawType* Instance::GetType() const { 4827 RawType* Instance::GetType() const {
4847 if (IsNull()) { 4828 if (IsNull()) {
4848 return Type::NullType(); 4829 return Type::NullType();
4849 } 4830 }
4850 const Class& cls = Class::Handle(clazz()); 4831 const Class& cls = Class::Handle(clazz());
4851 TypeArguments& type_arguments = TypeArguments::Handle(); 4832 TypeArguments& type_arguments = TypeArguments::Handle();
(...skipping 2106 matching lines...) Expand 10 before | Expand all | Expand 10 after
6958 const String& str = String::Handle(pattern()); 6939 const String& str = String::Handle(pattern());
6959 const char* format = "JSRegExp: pattern=%s flags=%s"; 6940 const char* format = "JSRegExp: pattern=%s flags=%s";
6960 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 6941 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
6961 char* chars = reinterpret_cast<char*>( 6942 char* chars = reinterpret_cast<char*>(
6962 Isolate::Current()->current_zone()->Allocate(len + 1)); 6943 Isolate::Current()->current_zone()->Allocate(len + 1));
6963 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 6944 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
6964 return chars; 6945 return chars;
6965 } 6946 }
6966 6947
6967 } // namespace dart 6948 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698