Chromium Code Reviews| 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/raw_object.h" | 5 #include "vm/raw_object.h" |
| 6 | 6 |
| 7 #include "vm/class_table.h" | 7 #include "vm/class_table.h" |
| 8 #include "vm/dart.h" | 8 #include "vm/dart.h" |
| 9 #include "vm/freelist.h" | 9 #include "vm/freelist.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 return; | 58 return; |
| 59 } | 59 } |
| 60 intptr_t size = SizeTag::decode(tags); | 60 intptr_t size = SizeTag::decode(tags); |
| 61 if (size != 0 && size != SizeFromClass()) { | 61 if (size != 0 && size != SizeFromClass()) { |
| 62 FATAL1("Inconsistent class size encountered %" Pd "\n", size); | 62 FATAL1("Inconsistent class size encountered %" Pd "\n", size); |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 intptr_t RawObject::SizeFromClass() const { | 67 intptr_t RawObject::SizeFromClass() const { |
| 68 Isolate* isolate = Isolate::Current(); | |
| 69 NoHandleScope no_handles(isolate); | |
| 70 | |
| 71 // Only reasonable to be called on heap objects. | 68 // Only reasonable to be called on heap objects. |
| 72 ASSERT(IsHeapObject()); | 69 ASSERT(IsHeapObject()); |
| 73 | 70 |
| 74 intptr_t class_id = GetClassId(); | 71 intptr_t class_id = GetClassId(); |
| 75 ClassTable* class_table = isolate->class_table(); | 72 intptr_t instance_size = 0; |
| 73 switch (class_id) { | |
| 74 case kCodeCid: { | |
| 75 const RawCode* raw_code = reinterpret_cast<const RawCode*>(this); | |
| 76 intptr_t pointer_offsets_length = | |
| 77 Code::PtrOffBits::decode(raw_code->ptr()->state_bits_); | |
|
Ivan Posva
2015/03/19 23:19:36
4 spaces
koda
2015/03/19 23:22:37
Done.
| |
| 78 instance_size = Code::InstanceSize(pointer_offsets_length); | |
| 79 break; | |
| 80 } | |
| 81 case kInstructionsCid: { | |
| 82 const RawInstructions* raw_instructions = | |
| 83 reinterpret_cast<const RawInstructions*>(this); | |
| 84 intptr_t instructions_size = raw_instructions->ptr()->size_; | |
| 85 instance_size = Instructions::InstanceSize(instructions_size); | |
| 86 break; | |
| 87 } | |
| 88 case kContextCid: { | |
| 89 const RawContext* raw_context = | |
| 90 reinterpret_cast<const RawContext*>(this); | |
| 91 intptr_t num_variables = raw_context->ptr()->num_variables_; | |
| 92 instance_size = Context::InstanceSize(num_variables); | |
| 93 break; | |
| 94 } | |
| 95 case kContextScopeCid: { | |
| 96 const RawContextScope* raw_context_scope = | |
| 97 reinterpret_cast<const RawContextScope*>(this); | |
| 98 intptr_t num_variables = raw_context_scope->ptr()->num_variables_; | |
| 99 instance_size = ContextScope::InstanceSize(num_variables); | |
| 100 break; | |
| 101 } | |
| 102 case kOneByteStringCid: { | |
| 103 const RawOneByteString* raw_string = | |
| 104 reinterpret_cast<const RawOneByteString*>(this); | |
| 105 intptr_t string_length = Smi::Value(raw_string->ptr()->length_); | |
| 106 instance_size = OneByteString::InstanceSize(string_length); | |
| 107 break; | |
| 108 } | |
| 109 case kTwoByteStringCid: { | |
| 110 const RawTwoByteString* raw_string = | |
| 111 reinterpret_cast<const RawTwoByteString*>(this); | |
| 112 intptr_t string_length = Smi::Value(raw_string->ptr()->length_); | |
| 113 instance_size = TwoByteString::InstanceSize(string_length); | |
| 114 break; | |
| 115 } | |
| 116 case kArrayCid: | |
| 117 case kImmutableArrayCid: { | |
| 118 const RawArray* raw_array = reinterpret_cast<const RawArray*>(this); | |
| 119 intptr_t array_length = Smi::Value(raw_array->ptr()->length_); | |
| 120 instance_size = Array::InstanceSize(array_length); | |
| 121 break; | |
| 122 } | |
| 123 #define SIZE_FROM_CLASS(clazz) \ | |
| 124 case kTypedData##clazz##Cid: | |
| 125 CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) { | |
| 126 const RawTypedData* raw_obj = | |
| 127 reinterpret_cast<const RawTypedData*>(this); | |
| 128 intptr_t cid = raw_obj->GetClassId(); | |
| 129 intptr_t array_len = Smi::Value(raw_obj->ptr()->length_); | |
| 130 intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid); | |
| 131 instance_size = TypedData::InstanceSize(lengthInBytes); | |
| 132 break; | |
| 133 } | |
| 134 #undef SIZE_FROM_CLASS | |
| 135 case kTypeArgumentsCid: { | |
| 136 const RawTypeArguments* raw_array = | |
| 137 reinterpret_cast<const RawTypeArguments*>(this); | |
| 138 intptr_t array_length = Smi::Value(raw_array->ptr()->length_); | |
| 139 instance_size = TypeArguments::InstanceSize(array_length); | |
| 140 break; | |
| 141 } | |
| 142 case kPcDescriptorsCid: { | |
| 143 const RawPcDescriptors* raw_descriptors = | |
| 144 reinterpret_cast<const RawPcDescriptors*>(this); | |
| 145 const intptr_t num_descriptors = raw_descriptors->ptr()->length_; | |
| 146 const intptr_t rec_size_in_bytes = | |
| 147 raw_descriptors->ptr()->record_size_in_bytes_; | |
| 148 instance_size = PcDescriptors::InstanceSize(num_descriptors, | |
| 149 rec_size_in_bytes); | |
| 150 break; | |
| 151 } | |
| 152 case kStackmapCid: { | |
| 153 const RawStackmap* map = reinterpret_cast<const RawStackmap*>(this); | |
| 154 intptr_t length = map->ptr()->length_; | |
| 155 instance_size = Stackmap::InstanceSize(length); | |
| 156 break; | |
| 157 } | |
| 158 case kLocalVarDescriptorsCid: { | |
| 159 const RawLocalVarDescriptors* raw_descriptors = | |
| 160 reinterpret_cast<const RawLocalVarDescriptors*>(this); | |
| 161 intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_; | |
| 162 instance_size = LocalVarDescriptors::InstanceSize(num_descriptors); | |
| 163 break; | |
| 164 } | |
| 165 case kExceptionHandlersCid: { | |
| 166 const RawExceptionHandlers* raw_handlers = | |
| 167 reinterpret_cast<const RawExceptionHandlers*>(this); | |
| 168 intptr_t num_handlers = raw_handlers->ptr()->num_entries_; | |
| 169 instance_size = ExceptionHandlers::InstanceSize(num_handlers); | |
| 170 break; | |
| 171 } | |
| 172 case kDeoptInfoCid: { | |
| 173 const RawDeoptInfo* raw_deopt_info = | |
| 174 reinterpret_cast<const RawDeoptInfo*>(this); | |
| 175 intptr_t num_entries = Smi::Value(raw_deopt_info->ptr()->length_); | |
| 176 instance_size = DeoptInfo::InstanceSize(num_entries); | |
| 177 break; | |
| 178 } | |
| 179 case kJSRegExpCid: { | |
| 180 const RawJSRegExp* raw_jsregexp = | |
| 181 reinterpret_cast<const RawJSRegExp*>(this); | |
| 182 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); | |
| 183 instance_size = JSRegExp::InstanceSize(data_length); | |
| 184 break; | |
| 185 } | |
| 186 case kFreeListElement: { | |
| 187 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); | |
| 188 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | |
| 189 instance_size = element->Size(); | |
| 190 break; | |
| 191 } | |
| 192 default: { | |
| 193 // Get the (constant) instance size out of the class object. | |
| 194 // TODO(koda): Add Size(ClassTable*) interface to allow caching in loops. | |
| 195 Isolate* isolate = Isolate::Current(); | |
| 196 ClassTable* class_table = isolate->class_table(); | |
| 76 #if defined(DEBUG) | 197 #if defined(DEBUG) |
| 77 if (!class_table->IsValidIndex(class_id) || | 198 if (!class_table->IsValidIndex(class_id) || |
| 78 !class_table->HasValidClassAt(class_id)) { | 199 !class_table->HasValidClassAt(class_id)) { |
| 79 FATAL2("Invalid class id: %" Pd " from tags %" Px "\n", | 200 FATAL2("Invalid class id: %" Pd " from tags %" Px "\n", |
| 80 class_id, ptr()->tags_); | 201 class_id, ptr()->tags_); |
| 81 } | 202 } |
| 82 #endif // DEBUG | 203 #endif // DEBUG |
| 83 RawClass* raw_class = class_table->At(class_id); | 204 RawClass* raw_class = class_table->At(class_id); |
| 84 ASSERT(raw_class->ptr()->id_ == class_id); | 205 ASSERT(raw_class->ptr()->id_ == class_id); |
| 85 | 206 instance_size = |
| 86 // Get the instance size out of the class. | 207 raw_class->ptr()->instance_size_in_words_ << kWordSizeLog2; |
| 87 intptr_t instance_size = | |
| 88 raw_class->ptr()->instance_size_in_words_ << kWordSizeLog2; | |
| 89 | |
| 90 if (instance_size == 0) { | |
| 91 switch (class_id) { | |
| 92 case kCodeCid: { | |
| 93 const RawCode* raw_code = reinterpret_cast<const RawCode*>(this); | |
| 94 intptr_t pointer_offsets_length = | |
| 95 Code::PtrOffBits::decode(raw_code->ptr()->state_bits_); | |
| 96 instance_size = Code::InstanceSize(pointer_offsets_length); | |
| 97 break; | |
| 98 } | |
| 99 case kInstructionsCid: { | |
| 100 const RawInstructions* raw_instructions = | |
| 101 reinterpret_cast<const RawInstructions*>(this); | |
| 102 intptr_t instructions_size = raw_instructions->ptr()->size_; | |
| 103 instance_size = Instructions::InstanceSize(instructions_size); | |
| 104 break; | |
| 105 } | |
| 106 case kContextCid: { | |
| 107 const RawContext* raw_context = | |
| 108 reinterpret_cast<const RawContext*>(this); | |
| 109 intptr_t num_variables = raw_context->ptr()->num_variables_; | |
| 110 instance_size = Context::InstanceSize(num_variables); | |
| 111 break; | |
| 112 } | |
| 113 case kContextScopeCid: { | |
| 114 const RawContextScope* raw_context_scope = | |
| 115 reinterpret_cast<const RawContextScope*>(this); | |
| 116 intptr_t num_variables = raw_context_scope->ptr()->num_variables_; | |
| 117 instance_size = ContextScope::InstanceSize(num_variables); | |
| 118 break; | |
| 119 } | |
| 120 case kOneByteStringCid: { | |
| 121 const RawOneByteString* raw_string = | |
| 122 reinterpret_cast<const RawOneByteString*>(this); | |
| 123 intptr_t string_length = Smi::Value(raw_string->ptr()->length_); | |
| 124 instance_size = OneByteString::InstanceSize(string_length); | |
| 125 break; | |
| 126 } | |
| 127 case kTwoByteStringCid: { | |
| 128 const RawTwoByteString* raw_string = | |
| 129 reinterpret_cast<const RawTwoByteString*>(this); | |
| 130 intptr_t string_length = Smi::Value(raw_string->ptr()->length_); | |
| 131 instance_size = TwoByteString::InstanceSize(string_length); | |
| 132 break; | |
| 133 } | |
| 134 case kArrayCid: | |
| 135 case kImmutableArrayCid: { | |
| 136 const RawArray* raw_array = reinterpret_cast<const RawArray*>(this); | |
| 137 intptr_t array_length = Smi::Value(raw_array->ptr()->length_); | |
| 138 instance_size = Array::InstanceSize(array_length); | |
| 139 break; | |
| 140 } | |
| 141 #define SIZE_FROM_CLASS(clazz) \ | |
| 142 case kTypedData##clazz##Cid: | |
| 143 CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) { | |
| 144 const RawTypedData* raw_obj = | |
| 145 reinterpret_cast<const RawTypedData*>(this); | |
| 146 intptr_t cid = raw_obj->GetClassId(); | |
| 147 intptr_t array_len = Smi::Value(raw_obj->ptr()->length_); | |
| 148 intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid); | |
| 149 instance_size = TypedData::InstanceSize(lengthInBytes); | |
| 150 break; | |
| 151 } | |
| 152 #undef SIZE_FROM_CLASS | |
| 153 case kTypeArgumentsCid: { | |
| 154 const RawTypeArguments* raw_array = | |
| 155 reinterpret_cast<const RawTypeArguments*>(this); | |
| 156 intptr_t array_length = Smi::Value(raw_array->ptr()->length_); | |
| 157 instance_size = TypeArguments::InstanceSize(array_length); | |
| 158 break; | |
| 159 } | |
| 160 case kPcDescriptorsCid: { | |
| 161 const RawPcDescriptors* raw_descriptors = | |
| 162 reinterpret_cast<const RawPcDescriptors*>(this); | |
| 163 const intptr_t num_descriptors = raw_descriptors->ptr()->length_; | |
| 164 const intptr_t rec_size_in_bytes = | |
| 165 raw_descriptors->ptr()->record_size_in_bytes_; | |
| 166 instance_size = PcDescriptors::InstanceSize(num_descriptors, | |
| 167 rec_size_in_bytes); | |
| 168 break; | |
| 169 } | |
| 170 case kStackmapCid: { | |
| 171 const RawStackmap* map = reinterpret_cast<const RawStackmap*>(this); | |
| 172 intptr_t length = map->ptr()->length_; | |
| 173 instance_size = Stackmap::InstanceSize(length); | |
| 174 break; | |
| 175 } | |
| 176 case kLocalVarDescriptorsCid: { | |
| 177 const RawLocalVarDescriptors* raw_descriptors = | |
| 178 reinterpret_cast<const RawLocalVarDescriptors*>(this); | |
| 179 intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_; | |
| 180 instance_size = LocalVarDescriptors::InstanceSize(num_descriptors); | |
| 181 break; | |
| 182 } | |
| 183 case kExceptionHandlersCid: { | |
| 184 const RawExceptionHandlers* raw_handlers = | |
| 185 reinterpret_cast<const RawExceptionHandlers*>(this); | |
| 186 intptr_t num_handlers = raw_handlers->ptr()->num_entries_; | |
| 187 instance_size = ExceptionHandlers::InstanceSize(num_handlers); | |
| 188 break; | |
| 189 } | |
| 190 case kDeoptInfoCid: { | |
| 191 const RawDeoptInfo* raw_deopt_info = | |
| 192 reinterpret_cast<const RawDeoptInfo*>(this); | |
| 193 intptr_t num_entries = Smi::Value(raw_deopt_info->ptr()->length_); | |
| 194 instance_size = DeoptInfo::InstanceSize(num_entries); | |
| 195 break; | |
| 196 } | |
| 197 case kJSRegExpCid: { | |
| 198 const RawJSRegExp* raw_jsregexp = | |
| 199 reinterpret_cast<const RawJSRegExp*>(this); | |
| 200 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); | |
| 201 instance_size = JSRegExp::InstanceSize(data_length); | |
| 202 break; | |
| 203 } | |
| 204 case kFreeListElement: { | |
| 205 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); | |
| 206 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | |
| 207 instance_size = element->Size(); | |
| 208 break; | |
| 209 } | |
| 210 default: | |
| 211 UNREACHABLE(); | |
| 212 break; | |
| 213 } | 208 } |
| 214 } | 209 } |
| 215 ASSERT(instance_size != 0); | 210 ASSERT(instance_size != 0); |
| 216 #if defined(DEBUG) | 211 #if defined(DEBUG) |
| 217 uword tags = ptr()->tags_; | 212 uword tags = ptr()->tags_; |
| 218 intptr_t tags_size = SizeTag::decode(tags); | 213 intptr_t tags_size = SizeTag::decode(tags); |
| 219 if ((class_id == kArrayCid) && (instance_size > tags_size && tags_size > 0)) { | 214 if ((class_id == kArrayCid) && (instance_size > tags_size && tags_size > 0)) { |
| 220 // TODO(22501): Array::MakeArray could be in the process of shrinking | 215 // TODO(22501): Array::MakeArray could be in the process of shrinking |
| 221 // the array (see comment therein), having already updated the tags but not | 216 // the array (see comment therein), having already updated the tags but not |
| 222 // yet set the new length. Wait a millisecond and try again. | 217 // yet set the new length. Wait a millisecond and try again. |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 intptr_t RawUserTag::VisitUserTagPointers( | 931 intptr_t RawUserTag::VisitUserTagPointers( |
| 937 RawUserTag* raw_obj, ObjectPointerVisitor* visitor) { | 932 RawUserTag* raw_obj, ObjectPointerVisitor* visitor) { |
| 938 // Make sure that we got here with the tagged pointer as this. | 933 // Make sure that we got here with the tagged pointer as this. |
| 939 ASSERT(raw_obj->IsHeapObject()); | 934 ASSERT(raw_obj->IsHeapObject()); |
| 940 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); | 935 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); |
| 941 return UserTag::InstanceSize(); | 936 return UserTag::InstanceSize(); |
| 942 } | 937 } |
| 943 | 938 |
| 944 | 939 |
| 945 } // namespace dart | 940 } // namespace dart |
| OLD | NEW |