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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/disasm.h" | 8 #include "src/disasm.h" |
9 #include "src/disassembler.h" | 9 #include "src/disassembler.h" |
10 #include "src/field-type.h" | 10 #include "src/field-type.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 #undef VERIFY_TYPED_ARRAY | 93 #undef VERIFY_TYPED_ARRAY |
94 | 94 |
95 case CODE_TYPE: | 95 case CODE_TYPE: |
96 Code::cast(this)->CodeVerify(); | 96 Code::cast(this)->CodeVerify(); |
97 break; | 97 break; |
98 case ODDBALL_TYPE: | 98 case ODDBALL_TYPE: |
99 Oddball::cast(this)->OddballVerify(); | 99 Oddball::cast(this)->OddballVerify(); |
100 break; | 100 break; |
101 case JS_OBJECT_TYPE: | 101 case JS_OBJECT_TYPE: |
102 case JS_ERROR_TYPE: | 102 case JS_ERROR_TYPE: |
103 case JS_ARGUMENTS_TYPE: | |
104 case JS_API_OBJECT_TYPE: | 103 case JS_API_OBJECT_TYPE: |
105 case JS_SPECIAL_API_OBJECT_TYPE: | 104 case JS_SPECIAL_API_OBJECT_TYPE: |
106 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 105 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
107 case JS_PROMISE_TYPE: | 106 case JS_PROMISE_TYPE: |
108 JSObject::cast(this)->JSObjectVerify(); | 107 JSObject::cast(this)->JSObjectVerify(); |
109 break; | 108 break; |
109 case JS_ARGUMENTS_TYPE: | |
110 JSArgumentsObject::cast(this)->JSArgumentsObjectVerify(); | |
111 break; | |
110 case JS_GENERATOR_OBJECT_TYPE: | 112 case JS_GENERATOR_OBJECT_TYPE: |
111 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(); | 113 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(); |
112 break; | 114 break; |
113 case JS_VALUE_TYPE: | 115 case JS_VALUE_TYPE: |
114 JSValue::cast(this)->JSValueVerify(); | 116 JSValue::cast(this)->JSValueVerify(); |
115 break; | 117 break; |
116 case JS_DATE_TYPE: | 118 case JS_DATE_TYPE: |
117 JSDate::cast(this)->JSDateVerify(); | 119 JSDate::cast(this)->JSDateVerify(); |
118 break; | 120 break; |
119 case JS_BOUND_FUNCTION_TYPE: | 121 case JS_BOUND_FUNCTION_TYPE: |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 } | 241 } |
240 | 242 |
241 | 243 |
242 void FreeSpace::FreeSpaceVerify() { | 244 void FreeSpace::FreeSpaceVerify() { |
243 CHECK(IsFreeSpace()); | 245 CHECK(IsFreeSpace()); |
244 } | 246 } |
245 | 247 |
246 | 248 |
247 template <class Traits> | 249 template <class Traits> |
248 void FixedTypedArray<Traits>::FixedTypedArrayVerify() { | 250 void FixedTypedArray<Traits>::FixedTypedArrayVerify() { |
249 CHECK(IsHeapObject() && | 251 CHECK(IsHeapObject()); |
250 HeapObject::cast(this)->map()->instance_type() == | 252 CHECK(HeapObject::cast(this)->map()->instance_type() == |
251 Traits::kInstanceType); | 253 Traits::kInstanceType); |
252 if (base_pointer() == this) { | 254 if (base_pointer() == this) { |
253 CHECK(external_pointer() == | 255 CHECK(external_pointer() == |
254 ExternalReference::fixed_typed_array_base_data_offset().address()); | 256 ExternalReference::fixed_typed_array_base_data_offset().address()); |
255 } else { | 257 } else { |
256 CHECK(base_pointer() == nullptr); | 258 CHECK(base_pointer() == nullptr); |
257 } | 259 } |
258 } | 260 } |
259 | 261 |
260 | 262 |
261 bool JSObject::ElementsAreSafeToExamine() { | 263 bool JSObject::ElementsAreSafeToExamine() { |
262 // If a GC was caused while constructing this object, the elements | 264 // If a GC was caused while constructing this object, the elements |
263 // pointer may point to a one pointer filler map. | 265 // pointer may point to a one pointer filler map. |
264 return reinterpret_cast<Map*>(elements()) != | 266 return reinterpret_cast<Map*>(elements()) != |
265 GetHeap()->one_pointer_filler_map(); | 267 GetHeap()->one_pointer_filler_map(); |
266 } | 268 } |
267 | 269 |
270 namespace { | |
268 | 271 |
269 void JSObject::JSObjectVerify() { | 272 void VerifyFastProperties(JSReceiver* receiver) { |
270 VerifyHeapPointer(properties()); | 273 // TODO(cbruni): JSProxy support for slow properties |
271 VerifyHeapPointer(elements()); | 274 if (!receiver->IsJSObject()) return; |
275 Isolate* isolate = receiver->GetIsolate(); | |
276 Map* map = receiver->map(); | |
277 CHECK(!map->is_dictionary_map()); | |
278 JSObject* obj = JSObject::cast(receiver); | |
279 int actual_unused_property_fields = map->GetInObjectProperties() + | |
280 obj->properties()->length() - | |
281 map->NextFreePropertyIndex(); | |
282 if (map->unused_property_fields() != actual_unused_property_fields) { | |
283 // This could actually happen in the middle of StoreTransitionStub | |
284 // when the new extended backing store is already set into the object and | |
285 // the allocation of the MutableHeapNumber triggers GC (in this case map | |
286 // is not updated yet). | |
287 CHECK_EQ(map->unused_property_fields(), | |
288 actual_unused_property_fields - JSObject::kFieldsAdded); | |
289 } | |
290 DescriptorArray* descriptors = map->instance_descriptors(); | |
291 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | |
292 if (descriptors->GetDetails(i).type() != DATA) continue; | |
293 Representation r = descriptors->GetDetails(i).representation(); | |
294 FieldIndex index = FieldIndex::ForDescriptor(map, i); | |
295 if (obj->IsUnboxedDoubleField(index)) { | |
296 DCHECK(r.IsDouble()); | |
297 continue; | |
298 } | |
299 Object* value = obj->RawFastPropertyAt(index); | |
300 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber()); | |
301 if (value->IsUninitialized(isolate)) continue; | |
302 if (r.IsSmi()) DCHECK(value->IsSmi()); | |
303 if (r.IsHeapObject()) DCHECK(value->IsHeapObject()); | |
304 FieldType* field_type = descriptors->GetFieldType(i); | |
305 bool type_is_none = field_type->IsNone(); | |
306 bool type_is_any = field_type->IsAny(); | |
307 if (r.IsNone()) { | |
308 CHECK(type_is_none); | |
309 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) { | |
310 // If allocation folding is off then GC could happen during inner | |
311 // object literal creation and we will end up having and undefined | |
312 // value that does not match the field type. | |
313 CHECK(!field_type->NowStable() || field_type->NowContains(value) || | |
314 (!FLAG_use_allocation_folding && value->IsUndefined(isolate))); | |
315 } | |
316 } | |
317 } | |
272 | 318 |
273 if (HasSloppyArgumentsElements()) { | 319 template <typename T> |
274 CHECK(this->elements()->IsFixedArray()); | 320 void VerifyDictionary(T* dict) { |
275 CHECK_GE(this->elements()->length(), 2); | 321 CHECK(dict->IsFixedArray()); |
322 CHECK(dict->IsDictionary()); | |
323 int capacity = dict->Capacity(); | |
324 int nof = dict->NumberOfElements(); | |
325 int nod = dict->NumberOfDeletedElements(); | |
326 CHECK_LE(capacity, dict->length()); | |
327 CHECK_LE(nof, capacity); | |
328 CHECK_LE(0, nof + nod); | |
329 CHECK_LE(nof + nod, capacity); | |
330 } | |
331 | |
332 void VerifySlowProperties(JSReceiver* obj) { | |
333 Map* map = obj->map(); | |
334 CHECK(map->is_dictionary_map()); | |
335 CHECK_EQ(0, map->NumberOfOwnDescriptors()); | |
336 CHECK_EQ(0, map->unused_property_fields()); | |
337 CHECK_EQ(kInvalidEnumCacheSentinel, map->EnumLength()); | |
338 CHECK(obj->properties()->IsDictionary()); | |
339 // Kept in-object properties for sow-mode object need to be zapped: | |
340 int nof_in_object_properties = map->GetInObjectProperties(); | |
341 if (nof_in_object_properties > 0) { | |
342 JSObject* js_object = JSObject::cast(obj); | |
343 Smi* zap_value = Smi::FromInt(0); | |
344 for (int i = 0; i < nof_in_object_properties; i++) { | |
345 FieldIndex index = FieldIndex::ForLoadByFieldIndex(map, i); | |
346 Object* field = js_object->RawFastPropertyAt(index); | |
347 CHECK_EQ(field, zap_value); | |
348 } | |
276 } | 349 } |
350 if (obj->IsJSGlobalObject()) { | |
351 VerifyDictionary(JSObject::cast(obj)->global_dictionary()); | |
352 } else { | |
353 VerifyDictionary(obj->property_dictionary()); | |
354 } | |
355 } | |
277 | 356 |
278 if (HasFastProperties()) { | 357 void VerifyProperties(JSReceiver* obj) { |
279 int actual_unused_property_fields = map()->GetInObjectProperties() + | 358 obj->VerifyHeapPointer(obj->properties()); |
280 properties()->length() - | 359 if (obj->HasFastProperties()) { |
281 map()->NextFreePropertyIndex(); | 360 VerifyFastProperties(obj); |
282 if (map()->unused_property_fields() != actual_unused_property_fields) { | 361 } else { |
283 // This could actually happen in the middle of StoreTransitionStub | 362 VerifySlowProperties(obj); |
284 // when the new extended backing store is already set into the object and | 363 } |
285 // the allocation of the MutableHeapNumber triggers GC (in this case map | 364 } |
286 // is not updated yet). | 365 |
287 CHECK_EQ(map()->unused_property_fields(), | 366 void VerifyElements(JSObject* obj) { |
288 actual_unused_property_fields - JSObject::kFieldsAdded); | 367 obj->VerifyHeapPointer(obj->elements()); |
368 // If a GC was caused while constructing this object, the elements | |
369 // pointer may point to a one pointer filler map. | |
370 if (!obj->ElementsAreSafeToExamine()) return; | |
371 Map* map = obj->map(); | |
372 Heap* heap = obj->GetHeap(); | |
373 FixedArrayBase* elements = obj->elements(); | |
374 CHECK_EQ((map->has_fast_smi_or_object_elements() || | |
375 (elements == heap->empty_fixed_array()) || | |
376 obj->HasFastStringWrapperElements()), | |
377 (elements->map() == heap->fixed_array_map() || | |
378 elements->map() == heap->fixed_cow_array_map())); | |
379 CHECK_EQ(map->has_fast_object_elements(), obj->HasFastObjectElements()); | |
380 | |
381 ElementsKind kind = obj->GetElementsKind(); | |
382 if (IsFastSmiOrObjectElementsKind(kind)) { | |
383 CHECK(elements->map() == heap->fixed_array_map() || | |
384 elements->map() == heap->fixed_cow_array_map()); | |
385 } else if (IsFastDoubleElementsKind(kind)) { | |
386 CHECK(elements->IsFixedDoubleArray() || | |
387 elements == heap->empty_fixed_array()); | |
388 } else if (kind == DICTIONARY_ELEMENTS) { | |
389 CHECK(elements->IsSeededNumberDictionary()); | |
390 VerifyDictionary(SeededNumberDictionary::cast(elements)); | |
391 return; | |
392 } else { | |
393 CHECK(kind > DICTIONARY_ELEMENTS); | |
394 } | |
395 CHECK(!IsSloppyArgumentsElements(kind) || | |
396 (elements->IsFixedArray() && elements->length() >= 2)); | |
397 | |
398 if (IsFastPackedElementsKind(kind)) { | |
399 uint32_t length = elements->length(); | |
400 if (obj->IsJSArray()) { | |
401 Object* number = JSArray::cast(obj)->length(); | |
402 if (number->IsSmi()) { | |
403 length = Min(length, static_cast<uint32_t>(Smi::cast(number)->value())); | |
404 } | |
289 } | 405 } |
290 DescriptorArray* descriptors = map()->instance_descriptors(); | 406 if (kind == FAST_DOUBLE_ELEMENTS) { |
291 Isolate* isolate = GetIsolate(); | 407 for (uint32_t i = 0; i < length; i++) { |
292 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { | 408 CHECK(!FixedDoubleArray::cast(elements)->is_the_hole(i)); |
293 if (descriptors->GetDetails(i).type() == DATA) { | 409 } |
294 Representation r = descriptors->GetDetails(i).representation(); | 410 } else { |
295 FieldIndex index = FieldIndex::ForDescriptor(map(), i); | 411 for (uint32_t i = 0; i < length; i++) { |
296 if (IsUnboxedDoubleField(index)) { | 412 CHECK_NE(FixedArray::cast(elements)->get(i), heap->the_hole_value()); |
297 DCHECK(r.IsDouble()); | |
298 continue; | |
299 } | |
300 Object* value = RawFastPropertyAt(index); | |
301 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber()); | |
302 if (value->IsUninitialized(isolate)) continue; | |
303 if (r.IsSmi()) DCHECK(value->IsSmi()); | |
304 if (r.IsHeapObject()) DCHECK(value->IsHeapObject()); | |
305 FieldType* field_type = descriptors->GetFieldType(i); | |
306 bool type_is_none = field_type->IsNone(); | |
307 bool type_is_any = field_type->IsAny(); | |
308 if (r.IsNone()) { | |
309 CHECK(type_is_none); | |
310 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) { | |
311 // If allocation folding is off then GC could happen during inner | |
312 // object literal creation and we will end up having and undefined | |
313 // value that does not match the field type. | |
314 CHECK(!field_type->NowStable() || field_type->NowContains(value) || | |
315 (!FLAG_use_allocation_folding && value->IsUndefined(isolate))); | |
316 } | |
317 } | 413 } |
318 } | 414 } |
319 } | 415 } |
320 | |
321 // If a GC was caused while constructing this object, the elements | |
322 // pointer may point to a one pointer filler map. | |
323 if (ElementsAreSafeToExamine()) { | |
324 CHECK_EQ((map()->has_fast_smi_or_object_elements() || | |
325 (elements() == GetHeap()->empty_fixed_array()) || | |
326 HasFastStringWrapperElements()), | |
327 (elements()->map() == GetHeap()->fixed_array_map() || | |
328 elements()->map() == GetHeap()->fixed_cow_array_map())); | |
329 CHECK(map()->has_fast_object_elements() == HasFastObjectElements()); | |
330 } | |
331 } | 416 } |
332 | 417 |
418 } // namespace | |
419 | |
420 void JSObject::JSObjectVerify() { | |
421 VerifyProperties(this); | |
422 VerifyElements(this); | |
423 } | |
333 | 424 |
334 void Map::MapVerify() { | 425 void Map::MapVerify() { |
335 Heap* heap = GetHeap(); | 426 Heap* heap = GetHeap(); |
336 CHECK(!heap->InNewSpace(this)); | 427 CHECK(!heap->InNewSpace(this)); |
337 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); | 428 CHECK_LE(FIRST_TYPE, instance_type()); |
429 CHECK_LE(instance_type(), LAST_TYPE); | |
338 CHECK(instance_size() == kVariableSizeSentinel || | 430 CHECK(instance_size() == kVariableSizeSentinel || |
339 (kPointerSize <= instance_size() && | 431 (kPointerSize <= instance_size() && |
340 instance_size() < heap->Capacity())); | 432 instance_size() < heap->Capacity())); |
341 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) || | 433 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) || |
342 !Map::cast(GetBackPointer())->is_stable()); | 434 !Map::cast(GetBackPointer())->is_stable()); |
343 VerifyHeapPointer(prototype()); | 435 VerifyHeapPointer(prototype()); |
344 VerifyHeapPointer(instance_descriptors()); | 436 VerifyHeapPointer(instance_descriptors()); |
345 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); | 437 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); |
346 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); | 438 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); |
347 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); | 439 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); |
348 // TODO(ishell): turn it back to SLOW_DCHECK. | 440 // TODO(ishell): turn it back to SLOW_DCHECK. |
349 CHECK(!FLAG_unbox_double_fields || | 441 CHECK(!FLAG_unbox_double_fields || |
350 layout_descriptor()->IsConsistentWithMap(this)); | 442 layout_descriptor()->IsConsistentWithMap(this)); |
351 } | 443 } |
352 | 444 |
353 | 445 |
354 void Map::DictionaryMapVerify() { | 446 void Map::DictionaryMapVerify() { |
355 MapVerify(); | 447 MapVerify(); |
356 CHECK(is_dictionary_map()); | 448 CHECK(is_dictionary_map()); |
357 CHECK(instance_descriptors()->IsEmpty()); | 449 CHECK(instance_descriptors()->IsEmpty()); |
358 CHECK_EQ(0, unused_property_fields()); | 450 CHECK_EQ(0, unused_property_fields()); |
359 CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id()); | 451 CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id()); |
452 CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength()); | |
360 } | 453 } |
361 | 454 |
362 | 455 |
363 void Map::VerifyOmittedMapChecks() { | 456 void Map::VerifyOmittedMapChecks() { |
364 if (!FLAG_omit_map_checks_for_leaf_maps) return; | 457 if (!FLAG_omit_map_checks_for_leaf_maps) return; |
365 if (!is_stable() || | 458 if (!is_stable() || |
366 is_deprecated() || | 459 is_deprecated() || |
367 is_dictionary_map()) { | 460 is_dictionary_map()) { |
368 CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup)); | 461 CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup)); |
369 } | 462 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 | 512 |
420 void JSGeneratorObject::JSGeneratorObjectVerify() { | 513 void JSGeneratorObject::JSGeneratorObjectVerify() { |
421 // In an expression like "new g()", there can be a point where a generator | 514 // In an expression like "new g()", there can be a point where a generator |
422 // object is allocated but its fields are all undefined, as it hasn't yet been | 515 // object is allocated but its fields are all undefined, as it hasn't yet been |
423 // initialized by the generator. Hence these weak checks. | 516 // initialized by the generator. Hence these weak checks. |
424 VerifyObjectField(kFunctionOffset); | 517 VerifyObjectField(kFunctionOffset); |
425 VerifyObjectField(kContextOffset); | 518 VerifyObjectField(kContextOffset); |
426 VerifyObjectField(kReceiverOffset); | 519 VerifyObjectField(kReceiverOffset); |
427 VerifyObjectField(kOperandStackOffset); | 520 VerifyObjectField(kOperandStackOffset); |
428 VerifyObjectField(kContinuationOffset); | 521 VerifyObjectField(kContinuationOffset); |
522 JSObjectVerify(); | |
523 } | |
524 | |
525 namespace { | |
526 | |
527 void VerifyArgumentsParameterMap(FixedArray* elements) { | |
528 Isolate* isolate = elements->GetIsolate(); | |
529 CHECK(elements->IsFixedArray()); | |
530 CHECK_GE(elements->length(), 2); | |
531 HeapObject* context = HeapObject::cast(elements->get(0)); | |
532 HeapObject* arguments = HeapObject::cast(elements->get(1)); | |
533 // TODO(cbruni): fix arguments creation to be atomic. | |
534 CHECK(!(context->IsUndefined(isolate) && !arguments->IsUndefined(isolate))); | |
Igor Sheludko
2016/07/11 15:37:10
CHECK_IMPLIES?
| |
535 CHECK(context->IsUndefined(isolate) || context->IsContext()); | |
536 CHECK(arguments->IsUndefined(isolate) || arguments->IsFixedArray()); | |
537 } | |
538 | |
539 } // namespace | |
540 | |
541 void JSArgumentsObject::JSArgumentsObjectVerify() { | |
542 VerifyObjectField(kLengthOffset); | |
543 JSObjectVerify(); | |
544 Isolate* isolate = GetIsolate(); | |
545 | |
546 if (isolate->bootstrapper()->IsActive()) return; | |
547 Context* context = isolate->context(); | |
548 Object* constructor = map()->GetConstructor(); | |
549 if (constructor->IsJSFunction()) { | |
550 context = JSFunction::cast(constructor)->context(); | |
551 } | |
552 // TODO(cbruni): replace with NULL check once all hydrogren stubs manage to | |
553 // set up the contexts properly. | |
554 if (isolate->context()->IsSmi()) return; | |
555 Context* native_context = context->native_context(); | |
556 if (map() == native_context->sloppy_arguments_map()) { | |
557 // Sloppy arguments without aliased arguments has a normal elements backing | |
558 // store which is already verified by JSObjectVerify() above. | |
559 } else if (map() == native_context->fast_aliased_arguments_map()) { | |
560 CHECK(HasFastArgumentsElements()); | |
561 FixedArray* elements = FixedArray::cast(this->elements()); | |
562 VerifyArgumentsParameterMap(FixedArray::cast(elements)); | |
563 CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map()); | |
564 } else if (map() == native_context->slow_aliased_arguments_map()) { | |
565 CHECK(HasSlowArgumentsElements()); | |
566 FixedArray* elements = FixedArray::cast(this->elements()); | |
567 VerifyArgumentsParameterMap(elements); | |
568 VerifyDictionary(SeededNumberDictionary::cast(elements->get(1))); | |
569 CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map()); | |
570 } else if (map() == native_context->strict_arguments_map()) { | |
571 CHECK(HasFastElements()); | |
572 } else { | |
573 // TODO(cbruni): follow up on normalized argument maps. | |
574 } | |
429 } | 575 } |
430 | 576 |
431 | 577 |
432 void JSValue::JSValueVerify() { | 578 void JSValue::JSValueVerify() { |
433 Object* v = value(); | 579 Object* v = value(); |
434 if (v->IsHeapObject()) { | 580 if (v->IsHeapObject()) { |
435 VerifyHeapPointer(v); | 581 VerifyHeapPointer(v); |
436 } | 582 } |
583 JSObjectVerify(); | |
437 } | 584 } |
438 | 585 |
439 | 586 |
440 void JSDate::JSDateVerify() { | 587 void JSDate::JSDateVerify() { |
441 if (value()->IsHeapObject()) { | 588 if (value()->IsHeapObject()) { |
442 VerifyHeapPointer(value()); | 589 VerifyHeapPointer(value()); |
443 } | 590 } |
Igor Sheludko
2016/07/11 15:37:10
Either add JSObjectVerify(); here or even replace
| |
444 Isolate* isolate = GetIsolate(); | 591 Isolate* isolate = GetIsolate(); |
445 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() || | 592 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() || |
446 value()->IsHeapNumber()); | 593 value()->IsHeapNumber()); |
447 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN()); | 594 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN()); |
448 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN()); | 595 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN()); |
449 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN()); | 596 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN()); |
450 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() || | 597 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() || |
451 weekday()->IsNaN()); | 598 weekday()->IsNaN()); |
452 CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN()); | 599 CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN()); |
453 CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN()); | 600 CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 } | 632 } |
486 } | 633 } |
487 | 634 |
488 | 635 |
489 void JSMessageObject::JSMessageObjectVerify() { | 636 void JSMessageObject::JSMessageObjectVerify() { |
490 CHECK(IsJSMessageObject()); | 637 CHECK(IsJSMessageObject()); |
491 VerifyObjectField(kStartPositionOffset); | 638 VerifyObjectField(kStartPositionOffset); |
492 VerifyObjectField(kEndPositionOffset); | 639 VerifyObjectField(kEndPositionOffset); |
493 VerifyObjectField(kArgumentsOffset); | 640 VerifyObjectField(kArgumentsOffset); |
494 VerifyObjectField(kScriptOffset); | 641 VerifyObjectField(kScriptOffset); |
495 VerifyObjectField(kStackFramesOffset); | 642 VerifyObjectField(kStackFramesOffset); |
Igor Sheludko
2016/07/11 15:37:10
JSObjectVerify();
| |
496 } | 643 } |
497 | 644 |
498 | 645 |
499 void String::StringVerify() { | 646 void String::StringVerify() { |
500 CHECK(IsString()); | 647 CHECK(IsString()); |
501 CHECK(length() >= 0 && length() <= Smi::kMaxValue); | 648 CHECK(length() >= 0 && length() <= Smi::kMaxValue); |
502 if (IsInternalizedString()) { | 649 if (IsInternalizedString()) { |
503 CHECK(!GetHeap()->InNewSpace(this)); | 650 CHECK(!GetHeap()->InNewSpace(this)); |
504 } | 651 } |
505 if (IsConsString()) { | 652 if (IsConsString()) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 VerifyObjectField(kBoundTargetFunctionOffset); | 685 VerifyObjectField(kBoundTargetFunctionOffset); |
539 VerifyObjectField(kBoundArgumentsOffset); | 686 VerifyObjectField(kBoundArgumentsOffset); |
540 CHECK(bound_target_function()->IsCallable()); | 687 CHECK(bound_target_function()->IsCallable()); |
541 CHECK(IsCallable()); | 688 CHECK(IsCallable()); |
542 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor()); | 689 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor()); |
543 } | 690 } |
544 | 691 |
545 | 692 |
546 void JSFunction::JSFunctionVerify() { | 693 void JSFunction::JSFunctionVerify() { |
547 CHECK(IsJSFunction()); | 694 CHECK(IsJSFunction()); |
695 JSObjectVerify(); | |
548 VerifyObjectField(kPrototypeOrInitialMapOffset); | 696 VerifyObjectField(kPrototypeOrInitialMapOffset); |
549 VerifyObjectField(kNextFunctionLinkOffset); | 697 VerifyObjectField(kNextFunctionLinkOffset); |
550 CHECK(code()->IsCode()); | 698 CHECK(code()->IsCode()); |
551 CHECK(next_function_link() == NULL || | 699 CHECK(next_function_link() == NULL || |
552 next_function_link()->IsUndefined(GetIsolate()) || | 700 next_function_link()->IsUndefined(GetIsolate()) || |
553 next_function_link()->IsJSFunction()); | 701 next_function_link()->IsJSFunction()); |
554 CHECK(map()->is_callable()); | 702 CHECK(map()->is_callable()); |
555 } | 703 } |
556 | 704 |
557 | 705 |
(...skipping 26 matching lines...) Expand all Loading... | |
584 } | 732 } |
585 | 733 |
586 | 734 |
587 void JSGlobalObject::JSGlobalObjectVerify() { | 735 void JSGlobalObject::JSGlobalObjectVerify() { |
588 CHECK(IsJSGlobalObject()); | 736 CHECK(IsJSGlobalObject()); |
589 // Do not check the dummy global object for the builtins. | 737 // Do not check the dummy global object for the builtins. |
590 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 && | 738 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 && |
591 elements()->length() == 0) { | 739 elements()->length() == 0) { |
592 return; | 740 return; |
593 } | 741 } |
742 CHECK(!HasFastProperties()); | |
594 JSObjectVerify(); | 743 JSObjectVerify(); |
595 } | 744 } |
596 | 745 |
597 | 746 |
598 void Oddball::OddballVerify() { | 747 void Oddball::OddballVerify() { |
599 CHECK(IsOddball()); | 748 CHECK(IsOddball()); |
600 Heap* heap = GetHeap(); | 749 Heap* heap = GetHeap(); |
601 VerifyHeapPointer(to_string()); | 750 VerifyHeapPointer(to_string()); |
602 Object* number = to_number(); | 751 Object* number = to_number(); |
603 if (number->IsHeapObject()) { | 752 if (number->IsHeapObject()) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { | 836 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { |
688 Object* obj = it.rinfo()->target_object(); | 837 Object* obj = it.rinfo()->target_object(); |
689 if (IsWeakObject(obj)) { | 838 if (IsWeakObject(obj)) { |
690 if (obj->IsMap()) { | 839 if (obj->IsMap()) { |
691 Map* map = Map::cast(obj); | 840 Map* map = Map::cast(obj); |
692 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup, | 841 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup, |
693 cell)); | 842 cell)); |
694 } else if (obj->IsJSObject()) { | 843 } else if (obj->IsJSObject()) { |
695 if (isolate->heap()->InNewSpace(obj)) { | 844 if (isolate->heap()->InNewSpace(obj)) { |
696 ArrayList* list = | 845 ArrayList* list = |
697 GetIsolate()->heap()->weak_new_space_object_to_code_list(); | 846 isolate->heap()->weak_new_space_object_to_code_list(); |
698 bool found = false; | 847 bool found = false; |
699 for (int i = 0; i < list->Length(); i += 2) { | 848 for (int i = 0; i < list->Length(); i += 2) { |
700 WeakCell* obj_cell = WeakCell::cast(list->Get(i)); | 849 WeakCell* obj_cell = WeakCell::cast(list->Get(i)); |
701 if (!obj_cell->cleared() && obj_cell->value() == obj && | 850 if (!obj_cell->cleared() && obj_cell->value() == obj && |
702 WeakCell::cast(list->Get(i + 1)) == cell) { | 851 WeakCell::cast(list->Get(i + 1)) == cell) { |
703 found = true; | 852 found = true; |
704 break; | 853 break; |
705 } | 854 } |
706 } | 855 } |
707 CHECK(found); | 856 CHECK(found); |
708 } else { | 857 } else { |
709 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate); | 858 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate); |
710 DependentCode* dep = | 859 DependentCode* dep = |
711 GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj); | 860 isolate->heap()->LookupWeakObjectToCodeDependency(key_obj); |
712 dep->Contains(DependentCode::kWeakCodeGroup, cell); | 861 dep->Contains(DependentCode::kWeakCodeGroup, cell); |
713 } | 862 } |
714 } | 863 } |
715 } | 864 } |
716 } | 865 } |
717 } | 866 } |
718 | 867 |
719 | 868 |
720 void JSArray::JSArrayVerify() { | 869 void JSArray::JSArrayVerify() { |
870 CHECK(IsJSArray()); | |
721 JSObjectVerify(); | 871 JSObjectVerify(); |
722 Isolate* isolate = GetIsolate(); | 872 Isolate* isolate = GetIsolate(); |
723 CHECK(length()->IsNumber() || length()->IsUndefined(isolate)); | 873 // Allow undefined for not fully initialized JSArrays |
874 if (length()->IsUndefined(isolate)) { | |
875 CHECK_EQ(FixedArray::cast(elements()), | |
876 isolate->heap()->empty_fixed_array()); | |
877 return; | |
878 } | |
879 CHECK(length()->IsNumber()); | |
724 // If a GC was caused while constructing this array, the elements | 880 // If a GC was caused while constructing this array, the elements |
725 // pointer may point to a one pointer filler map. | 881 // pointer may point to a one pointer filler map. |
726 if (ElementsAreSafeToExamine()) { | 882 if (ElementsAreSafeToExamine()) { |
727 CHECK(elements()->IsUndefined(isolate) || elements()->IsFixedArray() || | 883 CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray()); |
728 elements()->IsFixedDoubleArray()); | |
729 } | 884 } |
730 } | 885 } |
731 | 886 |
732 | |
733 void JSSet::JSSetVerify() { | 887 void JSSet::JSSetVerify() { |
734 CHECK(IsJSSet()); | 888 CHECK(IsJSSet()); |
735 JSObjectVerify(); | 889 JSObjectVerify(); |
736 VerifyHeapPointer(table()); | 890 VerifyHeapPointer(table()); |
737 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate())); | 891 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate())); |
738 // TODO(arv): Verify OrderedHashTable too. | 892 // TODO(arv): Verify OrderedHashTable too. |
739 } | 893 } |
740 | 894 |
741 | 895 |
742 void JSMap::JSMapVerify() { | 896 void JSMap::JSMapVerify() { |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1289 if (isolate->bootstrapper()->IsActive()) return; | 1443 if (isolate->bootstrapper()->IsActive()) return; |
1290 | 1444 |
1291 static const int mask = RelocInfo::kCodeTargetMask; | 1445 static const int mask = RelocInfo::kCodeTargetMask; |
1292 RelocIterator old_it(old_code, mask); | 1446 RelocIterator old_it(old_code, mask); |
1293 RelocIterator new_it(new_code, mask); | 1447 RelocIterator new_it(new_code, mask); |
1294 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck); | 1448 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck); |
1295 | 1449 |
1296 while (!old_it.done()) { | 1450 while (!old_it.done()) { |
1297 RelocInfo* rinfo = old_it.rinfo(); | 1451 RelocInfo* rinfo = old_it.rinfo(); |
1298 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 1452 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
1299 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); | 1453 CHECK(!target->is_handler()); |
1454 CHECK(!target->is_inline_cache_stub()); | |
1300 if (target == stack_check) break; | 1455 if (target == stack_check) break; |
1301 old_it.next(); | 1456 old_it.next(); |
1302 } | 1457 } |
1303 | 1458 |
1304 while (!new_it.done()) { | 1459 while (!new_it.done()) { |
1305 RelocInfo* rinfo = new_it.rinfo(); | 1460 RelocInfo* rinfo = new_it.rinfo(); |
1306 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 1461 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
1307 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); | 1462 CHECK(!target->is_handler()); |
1463 CHECK(!target->is_inline_cache_stub()); | |
1308 if (target == stack_check) break; | 1464 if (target == stack_check) break; |
1309 new_it.next(); | 1465 new_it.next(); |
1310 } | 1466 } |
1311 | 1467 |
1312 // Either both are done because there is no stack check. | 1468 // Either both are done because there is no stack check. |
1313 // Or we are past the prologue for both. | 1469 // Or we are past the prologue for both. |
1314 CHECK_EQ(new_it.done(), old_it.done()); | 1470 CHECK_EQ(new_it.done(), old_it.done()); |
1315 | 1471 |
1316 // After the prologue, each call in the old code has a corresponding call | 1472 // After the prologue, each call in the old code has a corresponding call |
1317 // in the new code. | 1473 // in the new code. |
(...skipping 15 matching lines...) Expand all Loading... | |
1333 | 1489 |
1334 // Both are done at the same time. | 1490 // Both are done at the same time. |
1335 CHECK_EQ(new_it.done(), old_it.done()); | 1491 CHECK_EQ(new_it.done(), old_it.done()); |
1336 } | 1492 } |
1337 | 1493 |
1338 | 1494 |
1339 #endif // DEBUG | 1495 #endif // DEBUG |
1340 | 1496 |
1341 } // namespace internal | 1497 } // namespace internal |
1342 } // namespace v8 | 1498 } // namespace v8 |
OLD | NEW |