| 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 "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 Library::InitCoreLibrary(isolate); | 510 Library::InitCoreLibrary(isolate); |
| 511 Library& core_lib = Library::Handle(Library::CoreLibrary()); | 511 Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 512 ASSERT(!core_lib.IsNull()); | 512 ASSERT(!core_lib.IsNull()); |
| 513 Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | 513 Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 514 ASSERT(!core_impl_lib.IsNull()); | 514 ASSERT(!core_impl_lib.IsNull()); |
| 515 | 515 |
| 516 const GrowableObjectArray& pending_classes = | 516 const GrowableObjectArray& pending_classes = |
| 517 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); | 517 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); |
| 518 object_store->set_pending_classes(pending_classes); | 518 object_store->set_pending_classes(pending_classes); |
| 519 | 519 |
| 520 Context& context = Context::Handle(Context::New(0)); | 520 Context& context = Context::Handle(Context::New(0, Heap::kOld)); |
| 521 object_store->set_empty_context(context); | 521 object_store->set_empty_context(context); |
| 522 | 522 |
| 523 // Now that the symbol table is initialized and that the core dictionary as | 523 // Now that the symbol table is initialized and that the core dictionary as |
| 524 // well as the core implementation dictionary have been setup, preallocate | 524 // well as the core implementation dictionary have been setup, preallocate |
| 525 // remaining classes and register them by name in the dictionaries. | 525 // remaining classes and register them by name in the dictionaries. |
| 526 const Script& impl_script = Script::Handle(Bootstrap::LoadImplScript()); | 526 const Script& impl_script = Script::Handle(Bootstrap::LoadImplScript()); |
| 527 | 527 |
| 528 cls = Class::New<Smi>(); | 528 cls = Class::New<Smi>(); |
| 529 object_store->set_smi_class(cls); | 529 object_store->set_smi_class(cls); |
| 530 RegisterClass(cls, "Smi", impl_script, core_impl_lib); | 530 RegisterClass(cls, "Smi", impl_script, core_impl_lib); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 UNREACHABLE(); | 996 UNREACHABLE(); |
| 997 } | 997 } |
| 998 NoGCScope no_gc; | 998 NoGCScope no_gc; |
| 999 InitializeObject(address, cls.id(), size); | 999 InitializeObject(address, cls.id(), size); |
| 1000 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 1000 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 1001 ASSERT(cls.id() == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); | 1001 ASSERT(cls.id() == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_)); |
| 1002 return raw_obj; | 1002 return raw_obj; |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 | 1005 |
| 1006 class StoreBufferObjectPointerVisitor : public ObjectPointerVisitor { |
| 1007 public: |
| 1008 explicit StoreBufferObjectPointerVisitor(Isolate* isolate) : |
| 1009 ObjectPointerVisitor(isolate) { |
| 1010 } |
| 1011 void VisitPointers(RawObject** first, RawObject** last) { |
| 1012 for (RawObject** curr = first; curr <= last; ++curr) { |
| 1013 if ((*curr)->IsNewObject()) { |
| 1014 uword ptr = reinterpret_cast<uword>(curr); |
| 1015 isolate()->store_buffer()->AddPointer(ptr); |
| 1016 } |
| 1017 } |
| 1018 } |
| 1019 |
| 1020 private: |
| 1021 DISALLOW_COPY_AND_ASSIGN(StoreBufferObjectPointerVisitor); |
| 1022 }; |
| 1023 |
| 1024 |
| 1025 RawObject* Object::Clone(const Object& src, Heap::Space space) { |
| 1026 const Class& cls = Class::Handle(src.clazz()); |
| 1027 intptr_t size = src.raw()->Size(); |
| 1028 RawObject* raw_obj = Object::Allocate(cls, size, space); |
| 1029 NoGCScope no_gc; |
| 1030 memmove(raw_obj->ptr(), src.raw()->ptr(), size); |
| 1031 if (space == Heap::kOld) { |
| 1032 StoreBufferObjectPointerVisitor visitor(Isolate::Current()); |
| 1033 raw_obj->VisitPointers(&visitor); |
| 1034 } |
| 1035 return raw_obj; |
| 1036 } |
| 1037 |
| 1038 |
| 1006 RawString* Class::Name() const { | 1039 RawString* Class::Name() const { |
| 1007 if (raw_ptr()->name_ != String::null()) { | 1040 if (raw_ptr()->name_ != String::null()) { |
| 1008 return raw_ptr()->name_; | 1041 return raw_ptr()->name_; |
| 1009 } | 1042 } |
| 1010 ASSERT(class_class() != Class::null()); // class_class_ should be set up. | 1043 ASSERT(class_class() != Class::null()); // class_class_ should be set up. |
| 1011 intptr_t index = GetSingletonClassIndex(raw()); | 1044 intptr_t index = GetSingletonClassIndex(raw()); |
| 1012 return String::NewSymbol(GetSingletonClassName(index)); | 1045 return String::NewSymbol(GetSingletonClassName(index)); |
| 1013 } | 1046 } |
| 1014 | 1047 |
| 1015 | 1048 |
| (...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 ASSERT((index == 0) && cls.IsSignatureClass()); | 2787 ASSERT((index == 0) && cls.IsSignatureClass()); |
| 2755 index++; | 2788 index++; |
| 2756 continue; | 2789 continue; |
| 2757 } | 2790 } |
| 2758 if (this->Equals(type)) { | 2791 if (this->Equals(type)) { |
| 2759 return type.raw(); | 2792 return type.raw(); |
| 2760 } | 2793 } |
| 2761 index++; | 2794 index++; |
| 2762 } | 2795 } |
| 2763 // The type needs to be added to the list. Grow the list if it is full. | 2796 // The type needs to be added to the list. Grow the list if it is full. |
| 2764 // TODO(srdjan): Copy type into old space if canonicalized? | |
| 2765 if (index == canonical_types_len) { | 2797 if (index == canonical_types_len) { |
| 2766 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | 2798 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
| 2767 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | 2799 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
| 2768 const Array& new_canonical_types = | 2800 const Array& new_canonical_types = |
| 2769 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); | 2801 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); |
| 2770 cls.set_canonical_types(new_canonical_types); | 2802 cls.set_canonical_types(new_canonical_types); |
| 2771 new_canonical_types.SetAt(index, *this); | 2803 new_canonical_types.SetAt(index, *this); |
| 2772 } else { | 2804 } else { |
| 2773 canonical_types.SetAt(index, *this); | 2805 canonical_types.SetAt(index, *this); |
| 2774 } | 2806 } |
| 2807 ASSERT(IsOld()); |
| 2775 SetCanonical(); | 2808 SetCanonical(); |
| 2776 return this->raw(); | 2809 return this->raw(); |
| 2777 } | 2810 } |
| 2778 | 2811 |
| 2779 | 2812 |
| 2780 void Type::set_type_class(const Object& value) const { | 2813 void Type::set_type_class(const Object& value) const { |
| 2781 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 2814 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
| 2782 StorePointer(&raw_ptr()->type_class_, value.raw()); | 2815 StorePointer(&raw_ptr()->type_class_, value.raw()); |
| 2783 } | 2816 } |
| 2784 | 2817 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3407 | 3440 |
| 3408 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { | 3441 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { |
| 3409 if (IsNull() || IsCanonical() || !IsInstantiated()) { | 3442 if (IsNull() || IsCanonical() || !IsInstantiated()) { |
| 3410 return this->raw(); | 3443 return this->raw(); |
| 3411 } | 3444 } |
| 3412 ObjectStore* object_store = Isolate::Current()->object_store(); | 3445 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 3413 // 'table' must be null terminated. | 3446 // 'table' must be null terminated. |
| 3414 Array& table = Array::Handle(object_store->canonical_type_arguments()); | 3447 Array& table = Array::Handle(object_store->canonical_type_arguments()); |
| 3415 ASSERT(table.Length() > 0); | 3448 ASSERT(table.Length() > 0); |
| 3416 intptr_t index = 0; | 3449 intptr_t index = 0; |
| 3417 TypeArguments& other = TypeArguments::Handle(); | 3450 TypeArguments& result = TypeArguments::Handle(); |
| 3418 other ^= table.At(index); | 3451 result ^= table.At(index); |
| 3419 while (!other.IsNull()) { | 3452 while (!result.IsNull()) { |
| 3420 if (this->Equals(other)) { | 3453 if (this->Equals(result)) { |
| 3421 return other.raw(); | 3454 return result.raw(); |
| 3422 } | 3455 } |
| 3423 other ^= table.At(++index); | 3456 result ^= table.At(++index); |
| 3424 } | 3457 } |
| 3425 // Not found. Add 'this' to table. | 3458 // Not found. Add 'this' to table. |
| 3426 // TODO(srdjan): Copy 'this' into old space if canonicalized? | 3459 result ^= this->raw(); |
| 3460 if (result.IsNew()) { |
| 3461 result ^= Object::Clone(result, Heap::kOld); |
| 3462 } |
| 3463 ASSERT(result.IsOld()); |
| 3427 if (index == table.Length() - 1) { | 3464 if (index == table.Length() - 1) { |
| 3428 table = Array::Grow(table, table.Length() + 4, Heap::kOld); | 3465 table = Array::Grow(table, table.Length() + 4, Heap::kOld); |
| 3429 object_store->set_canonical_type_arguments(table); | 3466 object_store->set_canonical_type_arguments(table); |
| 3430 } | 3467 } |
| 3431 table.SetAt(index, *this); | 3468 table.SetAt(index, result); |
| 3432 SetCanonical(); | 3469 result.SetCanonical(); |
| 3433 return this->raw(); | 3470 return result.raw(); |
| 3434 } | 3471 } |
| 3435 | 3472 |
| 3436 | 3473 |
| 3437 const char* TypeArguments::ToCString() const { | 3474 const char* TypeArguments::ToCString() const { |
| 3438 if (IsNull()) { | 3475 if (IsNull()) { |
| 3439 return "NULL TypeArguments"; | 3476 return "NULL TypeArguments"; |
| 3440 } | 3477 } |
| 3441 const char* format = "%s [%s]"; | 3478 const char* format = "%s [%s]"; |
| 3442 const char* prev_cstr = "TypeArguments:"; | 3479 const char* prev_cstr = "TypeArguments:"; |
| 3443 for (int i = 0; i < Length(); i++) { | 3480 for (int i = 0; i < Length(); i++) { |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4416 return reinterpret_cast<RawLiteralToken*>(raw); | 4453 return reinterpret_cast<RawLiteralToken*>(raw); |
| 4417 } | 4454 } |
| 4418 | 4455 |
| 4419 | 4456 |
| 4420 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { | 4457 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { |
| 4421 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); | 4458 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); |
| 4422 result.set_kind(kind); | 4459 result.set_kind(kind); |
| 4423 result.set_literal(literal); | 4460 result.set_literal(literal); |
| 4424 if (kind == Token::kINTEGER) { | 4461 if (kind == Token::kINTEGER) { |
| 4425 const Integer& value = Integer::Handle(Integer::New(literal, Heap::kOld)); | 4462 const Integer& value = Integer::Handle(Integer::New(literal, Heap::kOld)); |
| 4463 ASSERT(value.IsSmi() || value.IsOld()); |
| 4426 result.set_value(value); | 4464 result.set_value(value); |
| 4427 } else if (kind == Token::kDOUBLE) { | 4465 } else if (kind == Token::kDOUBLE) { |
| 4428 const Double& value = Double::Handle(Double::NewCanonical(literal)); | 4466 const Double& value = Double::Handle(Double::NewCanonical(literal)); |
| 4429 result.set_value(value); | 4467 result.set_value(value); |
| 4430 } else { | 4468 } else { |
| 4431 ASSERT(Token::NeedsLiteralToken(kind)); | 4469 ASSERT(Token::NeedsLiteralToken(kind)); |
| 4432 result.set_value(literal); | 4470 result.set_value(literal); |
| 4433 } | 4471 } |
| 4434 return result.raw(); | 4472 return result.raw(); |
| 4435 } | 4473 } |
| (...skipping 3105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7541 return false; | 7579 return false; |
| 7542 } | 7580 } |
| 7543 } | 7581 } |
| 7544 } | 7582 } |
| 7545 return true; | 7583 return true; |
| 7546 } | 7584 } |
| 7547 | 7585 |
| 7548 | 7586 |
| 7549 RawInstance* Instance::Canonicalize() const { | 7587 RawInstance* Instance::Canonicalize() const { |
| 7550 ASSERT(!IsNull()); | 7588 ASSERT(!IsNull()); |
| 7551 if (!IsCanonical()) { | 7589 if (this->IsCanonical()) { |
| 7552 const Class& cls = Class::Handle(this->clazz()); | 7590 return this->raw(); |
| 7553 Array& constants = Array::Handle(cls.constants()); | 7591 } |
| 7554 const intptr_t constants_len = constants.Length(); | 7592 Instance& result = Instance::Handle(); |
| 7555 // Linear search to see whether this value is already present in the | 7593 const Class& cls = Class::Handle(this->clazz()); |
| 7556 // list of canonicalized constants. | 7594 Array& constants = Array::Handle(cls.constants()); |
| 7557 Instance& norm_value = Instance::Handle(); | 7595 const intptr_t constants_len = constants.Length(); |
| 7558 intptr_t index = 0; | 7596 // Linear search to see whether this value is already present in the |
| 7559 while (index < constants_len) { | 7597 // list of canonicalized constants. |
| 7560 norm_value ^= constants.At(index); | 7598 intptr_t index = 0; |
| 7561 if (norm_value.IsNull()) { | 7599 while (index < constants_len) { |
| 7562 break; | 7600 result ^= constants.At(index); |
| 7563 } | 7601 if (result.IsNull()) { |
| 7564 if (this->Equals(norm_value)) { | 7602 break; |
| 7565 return norm_value.raw(); | |
| 7566 } | |
| 7567 index++; | |
| 7568 } | 7603 } |
| 7569 // The value needs to be added to the list. Grow the list if | 7604 if (this->Equals(result)) { |
| 7570 // it is full. | 7605 return result.raw(); |
| 7571 // TODO(srdjan): Copy instance into old space if canonicalized? | 7606 } |
| 7572 cls.InsertCanonicalConstant(index, *this); | 7607 index++; |
| 7573 SetCanonical(); | |
| 7574 } | 7608 } |
| 7575 return this->raw(); | 7609 // The value needs to be added to the list. Grow the list if |
| 7610 // it is full. |
| 7611 result ^= this->raw(); |
| 7612 if (result.IsNew()) { |
| 7613 // Create a canonical object in old space. |
| 7614 result ^= Object::Clone(result, Heap::kOld); |
| 7615 } |
| 7616 ASSERT(result.IsOld()); |
| 7617 cls.InsertCanonicalConstant(index, result); |
| 7618 result.SetCanonical(); |
| 7619 return result.raw(); |
| 7576 } | 7620 } |
| 7577 | 7621 |
| 7578 | 7622 |
| 7579 RawType* Instance::GetType() const { | 7623 RawType* Instance::GetType() const { |
| 7580 if (IsNull()) { | 7624 if (IsNull()) { |
| 7581 return Type::NullType(); | 7625 return Type::NullType(); |
| 7582 } | 7626 } |
| 7583 const Class& cls = Class::Handle(clazz()); | 7627 const Class& cls = Class::Handle(clazz()); |
| 7584 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | 7628 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
| 7585 if (cls.HasTypeArguments()) { | 7629 if (cls.HasTypeArguments()) { |
| (...skipping 3157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10743 const String& str = String::Handle(pattern()); | 10787 const String& str = String::Handle(pattern()); |
| 10744 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10788 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10745 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10789 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10746 char* chars = reinterpret_cast<char*>( | 10790 char* chars = reinterpret_cast<char*>( |
| 10747 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10791 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10748 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10792 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10749 return chars; | 10793 return chars; |
| 10750 } | 10794 } |
| 10751 | 10795 |
| 10752 } // namespace dart | 10796 } // namespace dart |
| OLD | NEW |