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

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

Issue 17104002: Fix a bug in instance canonicalization and add debug mode checks that we are not missing any fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 9184 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 #if defined(DEBUG)
9206 class CheckForPointers : public ObjectPointerVisitor {
9207 public:
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 }
9217 }
9218
9219 private:
9220 bool has_pointers_;
9221
9222 DISALLOW_COPY_AND_ASSIGN(CheckForPointers);
9223 };
9224 #endif // DEBUG
9225
9226
9205 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { 9227 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const {
9206 ASSERT(!IsNull()); 9228 ASSERT(!IsNull());
9207 if (this->IsCanonical()) { 9229 if (this->IsCanonical()) {
9208 return this->raw(); 9230 return this->raw();
9209 } 9231 }
9210 Instance& result = Instance::Handle(); 9232 Instance& result = Instance::Handle();
9211 const Class& cls = Class::Handle(this->clazz()); 9233 const Class& cls = Class::Handle(this->clazz());
9212 // TODO(srdjan): Check that predefined classes do not have fields that need 9234 // TODO(srdjan): Check that predefined classes do not have fields that need
9213 // to be checked/canonicalized as well. 9235 // to be checked/canonicalized as well.
9214 if ((cls.id() >= kNumPredefinedCids) || cls.IsArray()) { 9236 if ((cls.id() >= kNumPredefinedCids) || IsArray()) {
9215 // Iterate over all fields, canonicalize numbers and strings, expect all 9237 // Iterate over all fields, canonicalize numbers and strings, expect all
9216 // other instances to be canonical otherwise report error (return 9238 // other instances to be canonical otherwise report error (return
9217 // Instance::null()). 9239 // Instance::null()).
9218 Object& obj = Object::Handle(); 9240 Object& obj = Object::Handle();
9219 const intptr_t end_field_offset = cls.instance_size() - kWordSize; 9241 const intptr_t end_field_offset = cls.instance_size() - kWordSize;
siva 2013/06/14 21:04:03 cls.instance_size() is not the right size for Obje
srdjan 2013/06/14 21:43:45 Done.
9220 for (intptr_t field_offset = 0; 9242 for (intptr_t field_offset = 0;
9221 field_offset <= end_field_offset; 9243 field_offset <= end_field_offset;
9222 field_offset += kWordSize) { 9244 field_offset += kWordSize) {
9223 obj = *this->FieldAddrAtOffset(field_offset); 9245 obj = *this->FieldAddrAtOffset(field_offset);
9224 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { 9246 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) {
9225 if (obj.IsNumber() || obj.IsString()) { 9247 if (obj.IsNumber() || obj.IsString()) {
9226 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); 9248 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL);
9227 ASSERT(!obj.IsNull()); 9249 ASSERT(!obj.IsNull());
9228 this->SetFieldAtOffset(field_offset, obj); 9250 this->SetFieldAtOffset(field_offset, obj);
9229 } else { 9251 } else {
9230 ASSERT(error_str != NULL); 9252 ASSERT(error_str != NULL);
9231 const char* kFormat = "field: %s\n"; 9253 const char* kFormat = "field: %s\n";
9232 const intptr_t len = 9254 const intptr_t len =
9233 OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1; 9255 OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1;
9234 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 9256 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
9235 OS::SNPrint(chars, len, kFormat, obj.ToCString()); 9257 OS::SNPrint(chars, len, kFormat, obj.ToCString());
9236 *error_str = chars; 9258 *error_str = chars;
9237 return Instance::null(); 9259 return Instance::null();
9238 } 9260 }
9239 } 9261 }
9240 } 9262 }
9263 } else {
9264 #if defined(DEBUG)
9265 // Make sure that we are not missing any fields.
9266 CheckForPointers has_pointers(Isolate::Current());
9267 this->raw()->VisitPointers(&has_pointers);
9268 ASSERT(!has_pointers.has_pointers());
9269 #endif // DEBUG
9241 } 9270 }
9242 Array& constants = Array::Handle(cls.constants()); 9271 Array& constants = Array::Handle(cls.constants());
9243 const intptr_t constants_len = constants.Length(); 9272 const intptr_t constants_len = constants.Length();
9244 // Linear search to see whether this value is already present in the 9273 // Linear search to see whether this value is already present in the
9245 // list of canonicalized constants. 9274 // list of canonicalized constants.
9246 intptr_t index = 0; 9275 intptr_t index = 0;
9247 while (index < constants_len) { 9276 while (index < constants_len) {
9248 result ^= constants.At(index); 9277 result ^= constants.At(index);
9249 if (result.IsNull()) { 9278 if (result.IsNull()) {
9250 break; 9279 break;
(...skipping 4288 matching lines...) Expand 10 before | Expand all | Expand 10 after
13539 space); 13568 space);
13540 return reinterpret_cast<RawWeakProperty*>(raw); 13569 return reinterpret_cast<RawWeakProperty*>(raw);
13541 } 13570 }
13542 13571
13543 13572
13544 const char* WeakProperty::ToCString() const { 13573 const char* WeakProperty::ToCString() const {
13545 return "_WeakProperty"; 13574 return "_WeakProperty";
13546 } 13575 }
13547 13576
13548 } // namespace dart 13577 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698