Chromium Code Reviews| 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 9184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9195 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != | 9195 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != |
| 9196 (*reinterpret_cast<RawObject**>(other_addr + offset))) { | 9196 (*reinterpret_cast<RawObject**>(other_addr + offset))) { |
| 9197 return false; | 9197 return false; |
| 9198 } | 9198 } |
| 9199 } | 9199 } |
| 9200 } | 9200 } |
| 9201 return true; | 9201 return true; |
| 9202 } | 9202 } |
| 9203 | 9203 |
| 9204 | 9204 |
| 9205 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { | 9205 #if defined(DEBUG) |
| 9206 ASSERT(!IsNull()); | 9206 class CheckForPointers : public ObjectPointerVisitor { |
| 9207 if (this->IsCanonical()) { | 9207 public: |
| 9208 return this->raw(); | 9208 explicit CheckForPointers(Isolate* isolate) |
| 9209 : ObjectPointerVisitor(isolate), has_pointers_(false) {} | |
| 9210 | |
| 9211 bool has_pointers() const { return has_pointers_; } | |
| 9212 | |
| 9213 void VisitPointers(RawObject** first, RawObject** last) { | |
| 9214 if (first != last) { | |
| 9215 has_pointers_ = true; | |
| 9216 } | |
| 9209 } | 9217 } |
| 9210 Instance& result = Instance::Handle(); | 9218 |
| 9219 private: | |
| 9220 bool has_pointers_; | |
| 9221 | |
| 9222 DISALLOW_COPY_AND_ASSIGN(CheckForPointers); | |
| 9223 }; | |
| 9224 #endif // DEBUG | |
| 9225 | |
| 9226 | |
| 9227 bool Instance::CheckAndCanonicalizeFields(const char** error_str) const { | |
| 9211 const Class& cls = Class::Handle(this->clazz()); | 9228 const Class& cls = Class::Handle(this->clazz()); |
| 9212 // TODO(srdjan): Check that predefined classes do not have fields that need | 9229 if ((cls.id() >= kNumPredefinedCids)) { |
| 9213 // to be checked/canonicalized as well. | |
| 9214 if ((cls.id() >= kNumPredefinedCids) || cls.IsArray()) { | |
| 9215 // Iterate over all fields, canonicalize numbers and strings, expect all | 9230 // Iterate over all fields, canonicalize numbers and strings, expect all |
| 9216 // other instances to be canonical otherwise report error (return | 9231 // other instances to be canonical otherwise report error (return false). |
| 9217 // Instance::null()). | |
| 9218 Object& obj = Object::Handle(); | 9232 Object& obj = Object::Handle(); |
| 9219 const intptr_t end_field_offset = cls.instance_size() - kWordSize; | 9233 intptr_t end_field_offset = cls.instance_size() - kWordSize; |
| 9220 for (intptr_t field_offset = 0; | 9234 for (intptr_t field_offset = 0; |
| 9221 field_offset <= end_field_offset; | 9235 field_offset <= end_field_offset; |
| 9222 field_offset += kWordSize) { | 9236 field_offset += kWordSize) { |
| 9223 obj = *this->FieldAddrAtOffset(field_offset); | 9237 obj = *this->FieldAddrAtOffset(field_offset); |
| 9224 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | 9238 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
| 9225 if (obj.IsNumber() || obj.IsString()) { | 9239 if (obj.IsNumber() || obj.IsString()) { |
| 9226 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); | 9240 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); |
| 9227 ASSERT(!obj.IsNull()); | 9241 ASSERT(!obj.IsNull()); |
| 9228 this->SetFieldAtOffset(field_offset, obj); | 9242 this->SetFieldAtOffset(field_offset, obj); |
| 9229 } else { | 9243 } else { |
| 9230 ASSERT(error_str != NULL); | 9244 ASSERT(error_str != NULL); |
| 9231 const char* kFormat = "field: %s\n"; | 9245 const char* kFormat = "field: %s\n"; |
| 9232 const intptr_t len = | 9246 const intptr_t len = |
| 9233 OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1; | 9247 OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1; |
| 9234 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 9248 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 9235 OS::SNPrint(chars, len, kFormat, obj.ToCString()); | 9249 OS::SNPrint(chars, len, kFormat, obj.ToCString()); |
| 9236 *error_str = chars; | 9250 *error_str = chars; |
| 9237 return Instance::null(); | 9251 return false; |
| 9238 } | 9252 } |
| 9239 } | 9253 } |
| 9240 } | 9254 } |
| 9255 } else { | |
| 9256 #if defined(DEBUG) | |
| 9257 // Make sure that we are not missing any fields. | |
| 9258 CheckForPointers has_pointers(Isolate::Current()); | |
| 9259 this->raw()->VisitPointers(&has_pointers); | |
| 9260 ASSERT(!has_pointers.has_pointers()); | |
| 9261 #endif // DEBUG | |
| 9262 } | |
| 9263 return true; | |
| 9264 } | |
| 9265 | |
| 9266 | |
| 9267 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { | |
| 9268 ASSERT(!IsNull()); | |
| 9269 if (this->IsCanonical()) { | |
| 9270 return this->raw(); | |
| 9271 } | |
| 9272 Instance& result = Instance::Handle(); | |
|
siva
2013/06/14 22:19:49
This can be moved below the call to CheckAndCanoni
srdjan
2013/06/14 22:34:39
Done.
| |
| 9273 const Class& cls = Class::Handle(this->clazz()); | |
|
siva
2013/06/14 22:19:49
This line is not needed anymore. Done inside Check
srdjan
2013/06/14 22:34:39
Done.
| |
| 9274 if (!CheckAndCanonicalizeFields(error_str)) { | |
| 9275 return Instance::null(); | |
| 9241 } | 9276 } |
| 9242 Array& constants = Array::Handle(cls.constants()); | 9277 Array& constants = Array::Handle(cls.constants()); |
| 9243 const intptr_t constants_len = constants.Length(); | 9278 const intptr_t constants_len = constants.Length(); |
| 9244 // Linear search to see whether this value is already present in the | 9279 // Linear search to see whether this value is already present in the |
| 9245 // list of canonicalized constants. | 9280 // list of canonicalized constants. |
| 9246 intptr_t index = 0; | 9281 intptr_t index = 0; |
| 9247 while (index < constants_len) { | 9282 while (index < constants_len) { |
| 9248 result ^= constants.At(index); | 9283 result ^= constants.At(index); |
| 9249 if (result.IsNull()) { | 9284 if (result.IsNull()) { |
| 9250 break; | 9285 break; |
| (...skipping 3500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12751 | 12786 |
| 12752 // If there is any left over space fill it with either an Array object or | 12787 // If there is any left over space fill it with either an Array object or |
| 12753 // just a plain object (depending on the amount of left over space) so | 12788 // just a plain object (depending on the amount of left over space) so |
| 12754 // that it can be traversed over successfully during garbage collection. | 12789 // that it can be traversed over successfully during garbage collection. |
| 12755 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size); | 12790 Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size); |
| 12756 | 12791 |
| 12757 return array.raw(); | 12792 return array.raw(); |
| 12758 } | 12793 } |
| 12759 | 12794 |
| 12760 | 12795 |
| 12796 bool Array::CheckAndCanonicalizeFields(const char** error_str) const { | |
| 12797 Object& obj = Object::Handle(); | |
| 12798 // Iterate over all elements, canonicalize numbers and strings, expect all | |
| 12799 // other instances to be canonical otherwise report error (return false). | |
| 12800 for (intptr_t i = 0; i < Length(); i++) { | |
| 12801 obj = At(i); | |
| 12802 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | |
| 12803 if (obj.IsNumber() || obj.IsString()) { | |
| 12804 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); | |
| 12805 ASSERT(!obj.IsNull()); | |
| 12806 this->SetAt(i, obj); | |
| 12807 } else { | |
| 12808 ASSERT(error_str != NULL); | |
| 12809 const char* kFormat = "element at index %"Pd": %s\n"; | |
| 12810 const intptr_t len = | |
| 12811 OS::SNPrint(NULL, 0, kFormat, i, obj.ToCString()) + 1; | |
| 12812 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 12813 OS::SNPrint(chars, len, kFormat, i, obj.ToCString()); | |
| 12814 *error_str = chars; | |
| 12815 return false; | |
| 12816 } | |
| 12817 } | |
| 12818 } | |
| 12819 return true; | |
| 12820 } | |
| 12821 | |
| 12822 | |
| 12761 RawImmutableArray* ImmutableArray::New(intptr_t len, | 12823 RawImmutableArray* ImmutableArray::New(intptr_t len, |
| 12762 Heap::Space space) { | 12824 Heap::Space space) { |
| 12763 ASSERT(Isolate::Current()->object_store()->immutable_array_class() != | 12825 ASSERT(Isolate::Current()->object_store()->immutable_array_class() != |
| 12764 Class::null()); | 12826 Class::null()); |
| 12765 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); | 12827 return reinterpret_cast<RawImmutableArray*>(Array::New(kClassId, len, space)); |
| 12766 } | 12828 } |
| 12767 | 12829 |
| 12768 | 12830 |
| 12769 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { | 12831 void GrowableObjectArray::Add(const Object& value, Heap::Space space) const { |
| 12770 ASSERT(!IsNull()); | 12832 ASSERT(!IsNull()); |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13539 space); | 13601 space); |
| 13540 return reinterpret_cast<RawWeakProperty*>(raw); | 13602 return reinterpret_cast<RawWeakProperty*>(raw); |
| 13541 } | 13603 } |
| 13542 | 13604 |
| 13543 | 13605 |
| 13544 const char* WeakProperty::ToCString() const { | 13606 const char* WeakProperty::ToCString() const { |
| 13545 return "_WeakProperty"; | 13607 return "_WeakProperty"; |
| 13546 } | 13608 } |
| 13547 | 13609 |
| 13548 } // namespace dart | 13610 } // namespace dart |
| OLD | NEW |