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 if (HasTransitionArray()) { | 323 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); |
324 SLOW_DCHECK(transitions()->IsSortedNoDuplicates()); | 324 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); |
325 SLOW_DCHECK(transitions()->IsConsistentWithBackPointers(this)); | |
326 } | |
327 // TODO(ishell): turn it back to SLOW_DCHECK. | 325 // TODO(ishell): turn it back to SLOW_DCHECK. |
328 CHECK(!FLAG_unbox_double_fields || | 326 CHECK(!FLAG_unbox_double_fields || |
329 layout_descriptor()->IsConsistentWithMap(this)); | 327 layout_descriptor()->IsConsistentWithMap(this)); |
330 } | 328 } |
331 | 329 |
332 | 330 |
333 void Map::DictionaryMapVerify() { | 331 void Map::DictionaryMapVerify() { |
334 MapVerify(); | 332 MapVerify(); |
335 CHECK(is_dictionary_map()); | 333 CHECK(is_dictionary_map()); |
336 CHECK(instance_descriptors()->IsEmpty()); | 334 CHECK(instance_descriptors()->IsEmpty()); |
337 CHECK_EQ(0, pre_allocated_property_fields()); | 335 CHECK_EQ(0, pre_allocated_property_fields()); |
338 CHECK_EQ(0, unused_property_fields()); | 336 CHECK_EQ(0, unused_property_fields()); |
339 CHECK_EQ(StaticVisitorBase::GetVisitorId(this), visitor_id()); | 337 CHECK_EQ(StaticVisitorBase::GetVisitorId(this), visitor_id()); |
340 } | 338 } |
341 | 339 |
342 | 340 |
343 void Map::VerifyOmittedMapChecks() { | 341 void Map::VerifyOmittedMapChecks() { |
344 if (!FLAG_omit_map_checks_for_leaf_maps) return; | 342 if (!FLAG_omit_map_checks_for_leaf_maps) return; |
345 if (!is_stable() || | 343 if (!is_stable() || |
346 is_deprecated() || | 344 is_deprecated() || |
347 HasTransitionArray() || | |
348 is_dictionary_map()) { | 345 is_dictionary_map()) { |
349 CHECK_EQ(0, dependent_code()->number_of_entries( | 346 CHECK_EQ(0, dependent_code()->number_of_entries( |
350 DependentCode::kPrototypeCheckGroup)); | 347 DependentCode::kPrototypeCheckGroup)); |
351 } | 348 } |
352 } | 349 } |
353 | 350 |
354 | 351 |
355 void CodeCache::CodeCacheVerify() { | 352 void CodeCache::CodeCacheVerify() { |
356 VerifyHeapPointer(default_cache()); | 353 VerifyHeapPointer(default_cache()); |
357 VerifyHeapPointer(normal_type_cache()); | 354 VerifyHeapPointer(normal_type_cache()); |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 } | 1198 } |
1202 prev_key = key; | 1199 prev_key = key; |
1203 prev_hash = hash; | 1200 prev_hash = hash; |
1204 prev_attributes = attributes; | 1201 prev_attributes = attributes; |
1205 prev_kind = kind; | 1202 prev_kind = kind; |
1206 } | 1203 } |
1207 return true; | 1204 return true; |
1208 } | 1205 } |
1209 | 1206 |
1210 | 1207 |
| 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 |
1211 static bool CheckOneBackPointer(Map* current_map, Object* target) { | 1219 static bool CheckOneBackPointer(Map* current_map, Object* target) { |
1212 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map; | 1220 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map; |
1213 } | 1221 } |
1214 | 1222 |
1215 | 1223 |
1216 bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) { | 1224 // static |
1217 for (int i = 0; i < number_of_transitions(); ++i) { | 1225 bool TransitionArray::IsConsistentWithBackPointers(Map* map) { |
1218 if (!CheckOneBackPointer(current_map, GetTarget(i))) return false; | 1226 Object* transitions = map->raw_transitions(); |
| 1227 for (int i = 0; i < TransitionArray::NumberOfTransitions(transitions); ++i) { |
| 1228 Map* target = TransitionArray::GetTarget(transitions, i); |
| 1229 if (!CheckOneBackPointer(map, target)) return false; |
1219 } | 1230 } |
1220 return true; | 1231 return true; |
1221 } | 1232 } |
1222 | 1233 |
1223 | 1234 |
1224 // Estimates if there is a path from the object to a context. | 1235 // Estimates if there is a path from the object to a context. |
1225 // This function is not precise, and can return false even if | 1236 // This function is not precise, and can return false even if |
1226 // there is a path to a context. | 1237 // there is a path to a context. |
1227 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) { | 1238 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) { |
1228 if (!obj->IsHeapObject()) return false; | 1239 if (!obj->IsHeapObject()) return false; |
(...skipping 30 matching lines...) Expand all Loading... |
1259 ? it.rinfo()->target_cell() | 1270 ? it.rinfo()->target_cell() |
1260 : it.rinfo()->target_object(); | 1271 : it.rinfo()->target_object(); |
1261 CHECK(!CanLeak(target, heap, skip_weak_cell)); | 1272 CHECK(!CanLeak(target, heap, skip_weak_cell)); |
1262 } | 1273 } |
1263 } | 1274 } |
1264 | 1275 |
1265 | 1276 |
1266 #endif // DEBUG | 1277 #endif // DEBUG |
1267 | 1278 |
1268 } } // namespace v8::internal | 1279 } } // namespace v8::internal |
OLD | NEW |