OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/disasm.h" | 7 #include "src/disasm.h" |
8 #include "src/disassembler.h" | 8 #include "src/disassembler.h" |
9 #include "src/heap/objects-visiting.h" | 9 #include "src/heap/objects-visiting.h" |
10 #include "src/jsregexp.h" | 10 #include "src/jsregexp.h" |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 void Map::MapVerify() { | 313 void Map::MapVerify() { |
314 Heap* heap = GetHeap(); | 314 Heap* heap = GetHeap(); |
315 CHECK(!heap->InNewSpace(this)); | 315 CHECK(!heap->InNewSpace(this)); |
316 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); | 316 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); |
317 CHECK(instance_size() == kVariableSizeSentinel || | 317 CHECK(instance_size() == kVariableSizeSentinel || |
318 (kPointerSize <= instance_size() && | 318 (kPointerSize <= instance_size() && |
319 instance_size() < heap->Capacity())); | 319 instance_size() < heap->Capacity())); |
320 VerifyHeapPointer(prototype()); | 320 VerifyHeapPointer(prototype()); |
321 VerifyHeapPointer(instance_descriptors()); | 321 VerifyHeapPointer(instance_descriptors()); |
322 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); | 322 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); |
323 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); | 323 if (HasTransitionArray()) { |
324 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); | 324 SLOW_DCHECK(transitions()->IsSortedNoDuplicates()); |
| 325 SLOW_DCHECK(transitions()->IsConsistentWithBackPointers(this)); |
| 326 } |
325 // TODO(ishell): turn it back to SLOW_DCHECK. | 327 // TODO(ishell): turn it back to SLOW_DCHECK. |
326 CHECK(!FLAG_unbox_double_fields || | 328 CHECK(!FLAG_unbox_double_fields || |
327 layout_descriptor()->IsConsistentWithMap(this)); | 329 layout_descriptor()->IsConsistentWithMap(this)); |
328 } | 330 } |
329 | 331 |
330 | 332 |
331 void Map::DictionaryMapVerify() { | 333 void Map::DictionaryMapVerify() { |
332 MapVerify(); | 334 MapVerify(); |
333 CHECK(is_dictionary_map()); | 335 CHECK(is_dictionary_map()); |
334 CHECK(instance_descriptors()->IsEmpty()); | 336 CHECK(instance_descriptors()->IsEmpty()); |
335 CHECK_EQ(0, pre_allocated_property_fields()); | 337 CHECK_EQ(0, pre_allocated_property_fields()); |
336 CHECK_EQ(0, unused_property_fields()); | 338 CHECK_EQ(0, unused_property_fields()); |
337 CHECK_EQ(StaticVisitorBase::GetVisitorId(this), visitor_id()); | 339 CHECK_EQ(StaticVisitorBase::GetVisitorId(this), visitor_id()); |
338 } | 340 } |
339 | 341 |
340 | 342 |
341 void Map::VerifyOmittedMapChecks() { | 343 void Map::VerifyOmittedMapChecks() { |
342 if (!FLAG_omit_map_checks_for_leaf_maps) return; | 344 if (!FLAG_omit_map_checks_for_leaf_maps) return; |
343 if (!is_stable() || | 345 if (!is_stable() || |
344 is_deprecated() || | 346 is_deprecated() || |
| 347 HasTransitionArray() || |
345 is_dictionary_map()) { | 348 is_dictionary_map()) { |
346 CHECK_EQ(0, dependent_code()->number_of_entries( | 349 CHECK_EQ(0, dependent_code()->number_of_entries( |
347 DependentCode::kPrototypeCheckGroup)); | 350 DependentCode::kPrototypeCheckGroup)); |
348 } | 351 } |
349 } | 352 } |
350 | 353 |
351 | 354 |
352 void CodeCache::CodeCacheVerify() { | 355 void CodeCache::CodeCacheVerify() { |
353 VerifyHeapPointer(default_cache()); | 356 VerifyHeapPointer(default_cache()); |
354 VerifyHeapPointer(normal_type_cache()); | 357 VerifyHeapPointer(normal_type_cache()); |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 } | 1201 } |
1199 prev_key = key; | 1202 prev_key = key; |
1200 prev_hash = hash; | 1203 prev_hash = hash; |
1201 prev_attributes = attributes; | 1204 prev_attributes = attributes; |
1202 prev_kind = kind; | 1205 prev_kind = kind; |
1203 } | 1206 } |
1204 return true; | 1207 return true; |
1205 } | 1208 } |
1206 | 1209 |
1207 | 1210 |
1208 // static | |
1209 bool TransitionArray::IsSortedNoDuplicates(Map* map) { | |
1210 Object* raw_transitions = map->raw_transitions(); | |
1211 if (IsFullTransitionArray(raw_transitions)) { | |
1212 return TransitionArray::cast(raw_transitions)->IsSortedNoDuplicates(); | |
1213 } | |
1214 // Simple and non-existent transitions are always sorted. | |
1215 return true; | |
1216 } | |
1217 | |
1218 | |
1219 static bool CheckOneBackPointer(Map* current_map, Object* target) { | 1211 static bool CheckOneBackPointer(Map* current_map, Object* target) { |
1220 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map; | 1212 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map; |
1221 } | 1213 } |
1222 | 1214 |
1223 | 1215 |
1224 // static | 1216 bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) { |
1225 bool TransitionArray::IsConsistentWithBackPointers(Map* map) { | 1217 for (int i = 0; i < number_of_transitions(); ++i) { |
1226 Object* transitions = map->raw_transitions(); | 1218 if (!CheckOneBackPointer(current_map, GetTarget(i))) return false; |
1227 for (int i = 0; i < TransitionArray::NumberOfTransitions(transitions); ++i) { | |
1228 Map* target = TransitionArray::GetTarget(transitions, i); | |
1229 if (!CheckOneBackPointer(map, target)) return false; | |
1230 } | 1219 } |
1231 return true; | 1220 return true; |
1232 } | 1221 } |
1233 | 1222 |
1234 | 1223 |
1235 // Estimates if there is a path from the object to a context. | 1224 // Estimates if there is a path from the object to a context. |
1236 // This function is not precise, and can return false even if | 1225 // This function is not precise, and can return false even if |
1237 // there is a path to a context. | 1226 // there is a path to a context. |
1238 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) { | 1227 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) { |
1239 if (!obj->IsHeapObject()) return false; | 1228 if (!obj->IsHeapObject()) return false; |
(...skipping 30 matching lines...) Expand all Loading... |
1270 ? it.rinfo()->target_cell() | 1259 ? it.rinfo()->target_cell() |
1271 : it.rinfo()->target_object(); | 1260 : it.rinfo()->target_object(); |
1272 CHECK(!CanLeak(target, heap, skip_weak_cell)); | 1261 CHECK(!CanLeak(target, heap, skip_weak_cell)); |
1273 } | 1262 } |
1274 } | 1263 } |
1275 | 1264 |
1276 | 1265 |
1277 #endif // DEBUG | 1266 #endif // DEBUG |
1278 | 1267 |
1279 } } // namespace v8::internal | 1268 } } // namespace v8::internal |
OLD | NEW |