Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 1d0e862e03e53ef805ca38fdb661568f1dc4084f..45421bf890ae02e2eb28559b0e3cc12f6041b4cb 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -517,7 +517,7 @@ RawError* Object::Init(Isolate* isolate) { |
| GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); |
| object_store->set_pending_classes(pending_classes); |
| - Context& context = Context::Handle(Context::New(0)); |
| + Context& context = Context::Handle(Context::New(0, Heap::kOld)); |
| object_store->set_empty_context(context); |
| // Now that the symbol table is initialized and that the core dictionary as |
| @@ -1003,6 +1003,39 @@ RawObject* Object::Allocate(const Class& cls, |
| } |
| +class StoreBufferObjectPointerVisitor : public ObjectPointerVisitor { |
| + public: |
| + explicit StoreBufferObjectPointerVisitor(Isolate* isolate) : |
| + ObjectPointerVisitor(isolate) { |
| + } |
| + void VisitPointers(RawObject** first, RawObject** last) { |
| + for (RawObject** curr = first; curr <= last; ++curr) { |
| + if ((*curr)->IsNewObject()) { |
| + uword ptr = reinterpret_cast<uword>(curr); |
| + isolate()->store_buffer()->AddPointer(ptr); |
| + } |
| + } |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(StoreBufferObjectPointerVisitor); |
| +}; |
| + |
| + |
| +RawObject* Object::Clone(const Object& src, Heap::Space space) { |
| + const Class& cls = Class::Handle(src.clazz()); |
| + intptr_t size = src.raw()->Size(); |
| + RawObject* raw_obj = Object::Allocate(cls, size, space); |
| + NoGCScope no_gc; |
| + memmove(raw_obj->ptr(), src.raw()->ptr(), size); |
| + if (space == Heap::kOld) { |
| + StoreBufferObjectPointerVisitor visitor(Isolate::Current()); |
| + raw_obj->VisitPointers(&visitor); |
| + } |
| + return raw_obj; |
| +} |
| + |
| + |
| RawString* Class::Name() const { |
| if (raw_ptr()->name_ != String::null()) { |
| return raw_ptr()->name_; |
| @@ -2772,6 +2805,7 @@ RawAbstractType* Type::Canonicalize() const { |
| } else { |
| canonical_types.SetAt(index, *this); |
| } |
| + ASSERT(IsOld()); |
| SetCanonical(); |
| return this->raw(); |
| } |
| @@ -4423,6 +4457,7 @@ RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { |
| result.set_literal(literal); |
| if (kind == Token::kINTEGER) { |
| const Integer& value = Integer::Handle(Integer::New(literal, Heap::kOld)); |
| + ASSERT(value.IsSmi() || value.IsOld()); |
| result.set_value(value); |
| } else if (kind == Token::kDOUBLE) { |
| const Double& value = Double::Handle(Double::NewCanonical(literal)); |
| @@ -7548,31 +7583,38 @@ bool Instance::Equals(const Instance& other) const { |
| RawInstance* Instance::Canonicalize() const { |
| ASSERT(!IsNull()); |
| - if (!IsCanonical()) { |
| - const Class& cls = Class::Handle(this->clazz()); |
| - 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 |
| - // list of canonicalized constants. |
| - Instance& norm_value = Instance::Handle(); |
| - intptr_t index = 0; |
| - while (index < constants_len) { |
| - norm_value ^= constants.At(index); |
| - if (norm_value.IsNull()) { |
| - break; |
| - } |
| - if (this->Equals(norm_value)) { |
| - return norm_value.raw(); |
| - } |
| - index++; |
| + if (this->IsCanonical()) { |
| + return this->raw(); |
| + } |
| + Instance& result = Instance::Handle(); |
| + const Class& cls = Class::Handle(this->clazz()); |
| + 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 |
| + // list of canonicalized constants. |
| + intptr_t index = 0; |
| + while (index < constants_len) { |
| + result ^= constants.At(index); |
| + if (result.IsNull()) { |
| + break; |
| + } |
| + if (this->Equals(result)) { |
| + return result.raw(); |
| } |
| - // The value needs to be added to the list. Grow the list if |
| - // it is full. |
| - // TODO(srdjan): Copy instance into old space if canonicalized? |
| - cls.InsertCanonicalConstant(index, *this); |
| - SetCanonical(); |
| + index++; |
| } |
| - return this->raw(); |
| + // The value needs to be added to the list. Grow the list if |
| + // it is full. |
| + // TODO(srdjan): Copy instance into old space if canonicalized? |
|
regis
2012/07/13 22:32:16
You can remove this TODO.
cshapiro
2012/07/13 23:17:00
Done.
|
| + result ^= this->raw(); |
| + if (result.IsNew()) { |
| + // Create a canonical object in old space. |
| + result ^= Object::Clone(result, Heap::kOld); |
| + ASSERT(result.IsOld()); |
| + } |
| + cls.InsertCanonicalConstant(index, result); |
| + result.SetCanonical(); |
| + return result.raw(); |
| } |