Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 23823) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -50,6 +50,8 @@ |
| "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
| DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
| "Huge method cutoff in unoptimized code size (in bytes)."); |
| +DEFINE_FLAG(bool, report_incorrect_const_objects, true, |
|
hausner
2013/06/11 23:29:24
Why do we need the flag?
srdjan
2013/06/12 00:22:22
Removing. It is easy to disable the error reportin
|
| + "Report if a const object has incorrect fields."); |
| DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, |
| "Throw an exception when integer arithmetic exceeds 53 bits."); |
| DECLARE_FLAG(bool, trace_compiler); |
| @@ -9094,13 +9096,43 @@ |
| } |
| -RawInstance* Instance::Canonicalize() const { |
| +RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { |
| ASSERT(!IsNull()); |
| if (this->IsCanonical()) { |
| return this->raw(); |
| } |
| Instance& result = Instance::Handle(); |
| const Class& cls = Class::Handle(this->clazz()); |
| + if (cls.id() >= kNumPredefinedCids) { |
|
hausner
2013/06/11 23:29:24
As discussed offline, this excludes arrays.
srdjan
2013/06/12 00:22:22
Added arrays.
|
| + // Iterate over all fields, canonicalize numbers and strings, expect all |
| + // other instances to be canonical otherwise report error (return |
| + // Instance::null()). |
| + Object& obj = Object::Handle(); |
| + const intptr_t end_field_offset = cls.instance_size() - kWordSize; |
| + for (intptr_t field_offset = 0; |
| + field_offset <= end_field_offset; |
| + field_offset += kWordSize) { |
| + obj = *this->FieldAddrAtOffset(field_offset); |
| + if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
| + if (obj.IsNumber() || obj.IsString()) { |
| + obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); |
| + ASSERT(!obj.IsNull()); |
| + this->SetFieldAtOffset(field_offset, obj); |
| + } else { |
| + if (FLAG_report_incorrect_const_objects) { |
| + ASSERT(error_str != NULL); |
| + const char* kFormat = "field: %s\n"; |
| + const intptr_t len = |
| + OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1; |
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| + OS::SNPrint(chars, len, kFormat, obj.ToCString()); |
| + *error_str = chars; |
| + return Instance::null(); |
| + } |
| + } |
| + } |
| + } |
| + } |
| Array& constants = Array::Handle(cls.constants()); |
| const intptr_t constants_len = constants.Length(); |
| // Linear search to see whether this value is already present in the |
| @@ -11448,7 +11480,7 @@ |
| } |
| -RawInstance* String::Canonicalize() const { |
| +RawInstance* String::CheckAndCanonicalize(const char** error_str) const { |
| if (IsCanonical()) { |
| return this->raw(); |
| } |