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

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

Issue 56033002: Compute next field offset correctly. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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
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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag); 473 class_class_ = reinterpret_cast<RawClass*>(address + kHeapObjectTag);
474 InitializeObject(address, Class::kClassId, size); 474 InitializeObject(address, Class::kClassId, size);
475 475
476 Class fake; 476 Class fake;
477 // Initialization from Class::New<Class>. 477 // Initialization from Class::New<Class>.
478 // Directly set raw_ to break a circular dependency: SetRaw will attempt 478 // Directly set raw_ to break a circular dependency: SetRaw will attempt
479 // to lookup class class in the class table where it is not registered yet. 479 // to lookup class class in the class table where it is not registered yet.
480 cls.raw_ = class_class_; 480 cls.raw_ = class_class_;
481 cls.set_handle_vtable(fake.vtable()); 481 cls.set_handle_vtable(fake.vtable());
482 cls.set_instance_size(Class::InstanceSize()); 482 cls.set_instance_size(Class::InstanceSize());
483 cls.set_next_field_offset(Class::InstanceSize()); 483 cls.set_next_field_offset(Class::NextFieldOffset());
484 cls.set_id(Class::kClassId); 484 cls.set_id(Class::kClassId);
485 cls.set_state_bits(0); 485 cls.set_state_bits(0);
486 cls.set_is_finalized(); 486 cls.set_is_finalized();
487 cls.set_is_type_finalized(); 487 cls.set_is_type_finalized();
488 cls.set_type_arguments_field_offset_in_words(Class::kNoTypeArguments); 488 cls.set_type_arguments_field_offset_in_words(Class::kNoTypeArguments);
489 cls.set_num_type_arguments(0); 489 cls.set_num_type_arguments(0);
490 cls.set_num_own_type_arguments(0); 490 cls.set_num_own_type_arguments(0);
491 cls.set_num_native_fields(0); 491 cls.set_num_native_fields(0);
492 cls.InitEmptyFields(); 492 cls.InitEmptyFields();
493 isolate->RegisterClass(cls); 493 isolate->RegisterClass(cls);
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 { 1655 {
1656 RawObject* raw = Object::Allocate(Class::kClassId, 1656 RawObject* raw = Object::Allocate(Class::kClassId,
1657 Class::InstanceSize(), 1657 Class::InstanceSize(),
1658 Heap::kOld); 1658 Heap::kOld);
1659 NoGCScope no_gc; 1659 NoGCScope no_gc;
1660 result ^= raw; 1660 result ^= raw;
1661 } 1661 }
1662 FakeObject fake; 1662 FakeObject fake;
1663 result.set_handle_vtable(fake.vtable()); 1663 result.set_handle_vtable(fake.vtable());
1664 result.set_instance_size(FakeObject::InstanceSize()); 1664 result.set_instance_size(FakeObject::InstanceSize());
1665 result.set_next_field_offset(FakeObject::InstanceSize()); 1665 result.set_next_field_offset(FakeObject::NextFieldOffset());
1666 ASSERT((FakeObject::kClassId != kInstanceCid)); 1666 ASSERT((FakeObject::kClassId != kInstanceCid));
1667 result.set_id(FakeObject::kClassId); 1667 result.set_id(FakeObject::kClassId);
1668 result.set_state_bits(0); 1668 result.set_state_bits(0);
1669 // VM backed classes are almost ready: run checks and resolve class 1669 // VM backed classes are almost ready: run checks and resolve class
1670 // references, but do not recompute size. 1670 // references, but do not recompute size.
1671 result.set_is_prefinalized(); 1671 result.set_is_prefinalized();
1672 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); 1672 result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
1673 result.set_num_type_arguments(0); 1673 result.set_num_type_arguments(0);
1674 result.set_num_own_type_arguments(0); 1674 result.set_num_own_type_arguments(0);
1675 result.set_num_native_fields(0); 1675 result.set_num_native_fields(0);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 return TypeParameter::null(); 2025 return TypeParameter::null();
2026 } 2026 }
2027 2027
2028 2028
2029 void Class::CalculateFieldOffsets() const { 2029 void Class::CalculateFieldOffsets() const {
2030 Array& flds = Array::Handle(fields()); 2030 Array& flds = Array::Handle(fields());
2031 const Class& super = Class::Handle(SuperClass()); 2031 const Class& super = Class::Handle(SuperClass());
2032 intptr_t offset = 0; 2032 intptr_t offset = 0;
2033 intptr_t type_args_field_offset = kNoTypeArguments; 2033 intptr_t type_args_field_offset = kNoTypeArguments;
2034 if (super.IsNull()) { 2034 if (super.IsNull()) {
2035 offset = sizeof(RawObject); 2035 offset = Instance::NextFieldOffset();
2036 ASSERT(offset > 0);
2036 } else { 2037 } else {
2037 ASSERT(super.is_finalized() || super.is_prefinalized()); 2038 ASSERT(super.is_finalized() || super.is_prefinalized());
2038 type_args_field_offset = super.type_arguments_field_offset(); 2039 type_args_field_offset = super.type_arguments_field_offset();
2039 offset = super.next_field_offset(); 2040 offset = super.next_field_offset();
2040 ASSERT(offset > 0); 2041 ASSERT(offset > 0);
2041 // We should never call CalculateFieldOffsets for native wrapper 2042 // We should never call CalculateFieldOffsets for native wrapper
2042 // classes, assert this. 2043 // classes, assert this.
2043 ASSERT(num_native_fields() == 0); 2044 ASSERT(num_native_fields() == 0);
2044 set_num_native_fields(super.num_native_fields()); 2045 set_num_native_fields(super.num_native_fields());
2045 } 2046 }
2046 // If the super class is parameterized, use the same type_arguments field, 2047 // If the super class is parameterized, use the same type_arguments field,
2047 // otherwise, if this class is the first in the super chain to be 2048 // otherwise, if this class is the first in the super chain to be
2048 // parameterized, introduce a new type_arguments field. 2049 // parameterized, introduce a new type_arguments field.
2049 if (type_args_field_offset == kNoTypeArguments) { 2050 if (type_args_field_offset == kNoTypeArguments) {
2050 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); 2051 const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
2051 if (!type_params.IsNull()) { 2052 if (!type_params.IsNull()) {
2052 ASSERT(type_params.Length() > 0); 2053 ASSERT(type_params.Length() > 0);
2053 // The instance needs a type_arguments field. 2054 // The instance needs a type_arguments field.
2054 type_args_field_offset = offset; 2055 type_args_field_offset = offset;
2055 offset += kWordSize; 2056 offset += kWordSize;
2056 } 2057 }
2057 } 2058 }
2058 set_type_arguments_field_offset(type_args_field_offset); 2059 set_type_arguments_field_offset(type_args_field_offset);
2059 ASSERT(offset != 0); 2060 ASSERT(offset > 0);
2060 Field& field = Field::Handle(); 2061 Field& field = Field::Handle();
2061 intptr_t len = flds.Length(); 2062 intptr_t len = flds.Length();
2062 for (intptr_t i = 0; i < len; i++) { 2063 for (intptr_t i = 0; i < len; i++) {
2063 field ^= flds.At(i); 2064 field ^= flds.At(i);
2064 // Offset is computed only for instance fields. 2065 // Offset is computed only for instance fields.
2065 if (!field.is_static()) { 2066 if (!field.is_static()) {
2066 ASSERT(field.Offset() == 0); 2067 ASSERT(field.Offset() == 0);
2067 field.SetOffset(offset); 2068 field.SetOffset(offset);
2068 offset += kWordSize; 2069 offset += kWordSize;
2069 } 2070 }
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2387 RawObject* raw = Object::Allocate(Class::kClassId, 2388 RawObject* raw = Object::Allocate(Class::kClassId,
2388 Class::InstanceSize(), 2389 Class::InstanceSize(),
2389 Heap::kOld); 2390 Heap::kOld);
2390 NoGCScope no_gc; 2391 NoGCScope no_gc;
2391 result ^= raw; 2392 result ^= raw;
2392 } 2393 }
2393 FakeInstance fake; 2394 FakeInstance fake;
2394 ASSERT(fake.IsInstance()); 2395 ASSERT(fake.IsInstance());
2395 result.set_handle_vtable(fake.vtable()); 2396 result.set_handle_vtable(fake.vtable());
2396 result.set_instance_size(FakeInstance::InstanceSize()); 2397 result.set_instance_size(FakeInstance::InstanceSize());
2397 result.set_next_field_offset(FakeInstance::InstanceSize()); 2398 result.set_next_field_offset(FakeInstance::NextFieldOffset());
2398 result.set_id(index); 2399 result.set_id(index);
2399 result.set_state_bits(0); 2400 result.set_state_bits(0);
2400 result.set_type_arguments_field_offset_in_words(kNoTypeArguments); 2401 result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
2401 result.set_num_type_arguments(kUnknownNumTypeArguments); 2402 result.set_num_type_arguments(kUnknownNumTypeArguments);
2402 result.set_num_own_type_arguments(kUnknownNumTypeArguments); 2403 result.set_num_own_type_arguments(kUnknownNumTypeArguments);
2403 result.set_num_native_fields(0); 2404 result.set_num_native_fields(0);
2404 result.set_token_pos(Scanner::kDummyTokenIndex); 2405 result.set_token_pos(Scanner::kDummyTokenIndex);
2405 result.InitEmptyFields(); 2406 result.InitEmptyFields();
2406 Isolate::Current()->RegisterClass(result); 2407 Isolate::Current()->RegisterClass(result);
2407 return result.raw(); 2408 return result.raw();
(...skipping 11 matching lines...) Expand all
2419 } 2420 }
2420 2421
2421 2422
2422 RawClass* Class::NewSignatureClass(const String& name, 2423 RawClass* Class::NewSignatureClass(const String& name,
2423 const Function& signature_function, 2424 const Function& signature_function,
2424 const Script& script, 2425 const Script& script,
2425 intptr_t token_pos) { 2426 intptr_t token_pos) {
2426 const Class& result = Class::Handle(New(name, script, token_pos)); 2427 const Class& result = Class::Handle(New(name, script, token_pos));
2427 // Instances of a signature class can only be closures. 2428 // Instances of a signature class can only be closures.
2428 result.set_instance_size(Closure::InstanceSize()); 2429 result.set_instance_size(Closure::InstanceSize());
2429 result.set_next_field_offset(Closure::InstanceSize()); 2430 result.set_next_field_offset(Closure::NextFieldOffset());
2430 // Signature classes extend the _FunctionImpl class. 2431 // Signature classes extend the _FunctionImpl class.
2431 result.set_super_type(Type::Handle( 2432 result.set_super_type(Type::Handle(
2432 Isolate::Current()->object_store()->function_impl_type())); 2433 Isolate::Current()->object_store()->function_impl_type()));
2433 result.set_is_synthesized_class(); 2434 result.set_is_synthesized_class();
2434 result.set_type_arguments_field_offset(Closure::type_arguments_offset()); 2435 result.set_type_arguments_field_offset(Closure::type_arguments_offset());
2435 if (!signature_function.IsNull()) { 2436 if (!signature_function.IsNull()) {
2436 result.PatchSignatureFunction(signature_function); 2437 result.PatchSignatureFunction(signature_function);
2437 } 2438 }
2438 return result.raw(); 2439 return result.raw();
2439 } 2440 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 int field_count) { 2492 int field_count) {
2492 Class& cls = Class::Handle(library.LookupClass(name)); 2493 Class& cls = Class::Handle(library.LookupClass(name));
2493 if (cls.IsNull()) { 2494 if (cls.IsNull()) {
2494 cls = New(name, Script::Handle(), Scanner::kDummyTokenIndex); 2495 cls = New(name, Script::Handle(), Scanner::kDummyTokenIndex);
2495 cls.SetFields(Object::empty_array()); 2496 cls.SetFields(Object::empty_array());
2496 cls.SetFunctions(Object::empty_array()); 2497 cls.SetFunctions(Object::empty_array());
2497 // Set super class to Object. 2498 // Set super class to Object.
2498 cls.set_super_type(Type::Handle(Type::ObjectType())); 2499 cls.set_super_type(Type::Handle(Type::ObjectType()));
2499 // Compute instance size. First word contains a pointer to a properly 2500 // Compute instance size. First word contains a pointer to a properly
2500 // sized typed array once the first native field has been set. 2501 // sized typed array once the first native field has been set.
2501 intptr_t instance_size = sizeof(RawObject) + kWordSize; 2502 intptr_t instance_size = sizeof(RawInstance) + kWordSize;
2502 cls.set_instance_size(RoundedAllocationSize(instance_size)); 2503 cls.set_instance_size(RoundedAllocationSize(instance_size));
2503 cls.set_next_field_offset(instance_size); 2504 cls.set_next_field_offset(instance_size);
2504 cls.set_num_native_fields(field_count); 2505 cls.set_num_native_fields(field_count);
2505 cls.set_is_finalized(); 2506 cls.set_is_finalized();
2506 cls.set_is_type_finalized(); 2507 cls.set_is_type_finalized();
2507 library.AddClass(cls); 2508 library.AddClass(cls);
2508 return cls.raw(); 2509 return cls.raw();
2509 } else { 2510 } else {
2510 return Class::null(); 2511 return Class::null();
2511 } 2512 }
2512 } 2513 }
2513 2514
2514 2515
2515 RawClass* Class::NewStringClass(intptr_t class_id) { 2516 RawClass* Class::NewStringClass(intptr_t class_id) {
2516 intptr_t instance_size; 2517 intptr_t instance_size;
2518 intptr_t next_field_offset;
2517 if (class_id == kOneByteStringCid) { 2519 if (class_id == kOneByteStringCid) {
2520 next_field_offset = OneByteString::NextFieldOffset();
2518 instance_size = OneByteString::InstanceSize(); 2521 instance_size = OneByteString::InstanceSize();
2519 } else if (class_id == kTwoByteStringCid) { 2522 } else if (class_id == kTwoByteStringCid) {
2523 next_field_offset = TwoByteString::NextFieldOffset();
2520 instance_size = TwoByteString::InstanceSize(); 2524 instance_size = TwoByteString::InstanceSize();
2521 } else if (class_id == kExternalOneByteStringCid) { 2525 } else if (class_id == kExternalOneByteStringCid) {
2526 next_field_offset = ExternalOneByteString::NextFieldOffset();
2522 instance_size = ExternalOneByteString::InstanceSize(); 2527 instance_size = ExternalOneByteString::InstanceSize();
2523 } else { 2528 } else {
2524 ASSERT(class_id == kExternalTwoByteStringCid); 2529 ASSERT(class_id == kExternalTwoByteStringCid);
2530 next_field_offset = ExternalTwoByteString::NextFieldOffset();
2525 instance_size = ExternalTwoByteString::InstanceSize(); 2531 instance_size = ExternalTwoByteString::InstanceSize();
2526 } 2532 }
2527 Class& result = Class::Handle(New<String>(class_id)); 2533 Class& result = Class::Handle(New<String>(class_id));
2528 result.set_instance_size(instance_size); 2534 result.set_instance_size(instance_size);
2529 result.set_next_field_offset(instance_size); 2535 result.set_next_field_offset(next_field_offset);
2530 result.set_is_prefinalized(); 2536 result.set_is_prefinalized();
2531 return result.raw(); 2537 return result.raw();
2532 } 2538 }
2533 2539
2534 2540
2535 RawClass* Class::NewTypedDataClass(intptr_t class_id) { 2541 RawClass* Class::NewTypedDataClass(intptr_t class_id) {
2536 ASSERT(RawObject::IsTypedDataClassId(class_id)); 2542 ASSERT(RawObject::IsTypedDataClassId(class_id));
2537 intptr_t instance_size = TypedData::InstanceSize(); 2543 intptr_t instance_size = TypedData::InstanceSize();
2538 Class& result = Class::Handle(New<TypedData>(class_id)); 2544 Class& result = Class::Handle(New<TypedData>(class_id));
2539 result.set_instance_size(instance_size); 2545 result.set_instance_size(instance_size);
2540 result.set_next_field_offset(instance_size); 2546 result.set_next_field_offset(TypedData::NextFieldOffset());
2541 result.set_is_prefinalized(); 2547 result.set_is_prefinalized();
2542 return result.raw(); 2548 return result.raw();
2543 } 2549 }
2544 2550
2545 2551
2546 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) { 2552 RawClass* Class::NewTypedDataViewClass(intptr_t class_id) {
2547 ASSERT(RawObject::IsTypedDataViewClassId(class_id)); 2553 ASSERT(RawObject::IsTypedDataViewClassId(class_id));
2548 Class& result = Class::Handle(New<Instance>(class_id)); 2554 Class& result = Class::Handle(New<Instance>(class_id));
2549 result.set_instance_size(0); 2555 result.set_instance_size(0);
2550 result.set_next_field_offset(0); 2556 result.set_next_field_offset(-1);
Ivan Posva 2013/11/03 16:08:51 -kWordSize
siva 2013/11/04 16:05:01 Done.
2551 return result.raw(); 2557 return result.raw();
2552 } 2558 }
2553 2559
2554 2560
2555 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) { 2561 RawClass* Class::NewExternalTypedDataClass(intptr_t class_id) {
2556 ASSERT(RawObject::IsExternalTypedDataClassId(class_id)); 2562 ASSERT(RawObject::IsExternalTypedDataClassId(class_id));
2557 intptr_t instance_size = ExternalTypedData::InstanceSize(); 2563 intptr_t instance_size = ExternalTypedData::InstanceSize();
2558 Class& result = Class::Handle(New<ExternalTypedData>(class_id)); 2564 Class& result = Class::Handle(New<ExternalTypedData>(class_id));
2559 result.set_instance_size(instance_size); 2565 result.set_instance_size(instance_size);
2560 result.set_next_field_offset(instance_size); 2566 result.set_next_field_offset(ExternalTypedData::NextFieldOffset());
2561 result.set_is_prefinalized(); 2567 result.set_is_prefinalized();
2562 return result.raw(); 2568 return result.raw();
2563 } 2569 }
2564 2570
2565 2571
2566 void Class::set_name(const String& value) const { 2572 void Class::set_name(const String& value) const {
2567 ASSERT(value.IsSymbol()); 2573 ASSERT(value.IsSymbol());
2568 StorePointer(&raw_ptr()->name_, value.raw()); 2574 StorePointer(&raw_ptr()->name_, value.raw());
2569 } 2575 }
2570 2576
(...skipping 8236 matching lines...) Expand 10 before | Expand all | Expand 10 after
10807 return false; 10813 return false;
10808 } 10814 }
10809 10815
10810 { 10816 {
10811 NoGCScope no_gc; 10817 NoGCScope no_gc;
10812 // Raw bits compare. 10818 // Raw bits compare.
10813 const intptr_t instance_size = Class::Handle(this->clazz()).instance_size(); 10819 const intptr_t instance_size = Class::Handle(this->clazz()).instance_size();
10814 ASSERT(instance_size != 0); 10820 ASSERT(instance_size != 0);
10815 uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); 10821 uword this_addr = reinterpret_cast<uword>(this->raw_ptr());
10816 uword other_addr = reinterpret_cast<uword>(other.raw_ptr()); 10822 uword other_addr = reinterpret_cast<uword>(other.raw_ptr());
10817 for (intptr_t offset = sizeof(RawObject); 10823 for (intptr_t offset = Instance::NextFieldOffset();
10818 offset < instance_size; 10824 offset < instance_size;
10819 offset += kWordSize) { 10825 offset += kWordSize) {
10820 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != 10826 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) !=
10821 (*reinterpret_cast<RawObject**>(other_addr + offset))) { 10827 (*reinterpret_cast<RawObject**>(other_addr + offset))) {
10822 return false; 10828 return false;
10823 } 10829 }
10824 } 10830 }
10825 } 10831 }
10826 return true; 10832 return true;
10827 } 10833 }
(...skipping 4873 matching lines...) Expand 10 before | Expand all | Expand 10 after
15701 return "_MirrorReference"; 15707 return "_MirrorReference";
15702 } 15708 }
15703 15709
15704 15710
15705 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 15711 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
15706 JSONObject jsobj(stream); 15712 JSONObject jsobj(stream);
15707 } 15713 }
15708 15714
15709 15715
15710 } // namespace dart 15716 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698