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

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

Issue 10786003: Ensure objects emitted in code are allocated in old space. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address review comments Created 8 years, 5 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 | « runtime/vm/object.h ('k') | runtime/vm/object_ia32_test.cc » ('j') | 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 "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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_ia32_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698