• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "disassembler.h"
31 #include "disasm.h"
32 #include "jsregexp.h"
33 #include "objects-visiting.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 #ifdef DEBUG
39 
Verify()40 void MaybeObject::Verify() {
41   Object* this_as_object;
42   if (ToObject(&this_as_object)) {
43     if (this_as_object->IsSmi()) {
44       Smi::cast(this_as_object)->SmiVerify();
45     } else {
46       HeapObject::cast(this_as_object)->HeapObjectVerify();
47     }
48   } else {
49     Failure::cast(this)->FailureVerify();
50   }
51 }
52 
53 
VerifyPointer(Object * p)54 void Object::VerifyPointer(Object* p) {
55   if (p->IsHeapObject()) {
56     HeapObject::VerifyHeapPointer(p);
57   } else {
58     ASSERT(p->IsSmi());
59   }
60 }
61 
62 
SmiVerify()63 void Smi::SmiVerify() {
64   ASSERT(IsSmi());
65 }
66 
67 
FailureVerify()68 void Failure::FailureVerify() {
69   ASSERT(IsFailure());
70 }
71 
72 
HeapObjectVerify()73 void HeapObject::HeapObjectVerify() {
74   InstanceType instance_type = map()->instance_type();
75 
76   if (instance_type < FIRST_NONSTRING_TYPE) {
77     String::cast(this)->StringVerify();
78     return;
79   }
80 
81   switch (instance_type) {
82     case MAP_TYPE:
83       Map::cast(this)->MapVerify();
84       break;
85     case HEAP_NUMBER_TYPE:
86       HeapNumber::cast(this)->HeapNumberVerify();
87       break;
88     case FIXED_ARRAY_TYPE:
89       FixedArray::cast(this)->FixedArrayVerify();
90       break;
91     case FIXED_DOUBLE_ARRAY_TYPE:
92       FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
93       break;
94     case BYTE_ARRAY_TYPE:
95       ByteArray::cast(this)->ByteArrayVerify();
96       break;
97     case FREE_SPACE_TYPE:
98       FreeSpace::cast(this)->FreeSpaceVerify();
99       break;
100     case EXTERNAL_PIXEL_ARRAY_TYPE:
101       ExternalPixelArray::cast(this)->ExternalPixelArrayVerify();
102       break;
103     case EXTERNAL_BYTE_ARRAY_TYPE:
104       ExternalByteArray::cast(this)->ExternalByteArrayVerify();
105       break;
106     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
107       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
108       break;
109     case EXTERNAL_SHORT_ARRAY_TYPE:
110       ExternalShortArray::cast(this)->ExternalShortArrayVerify();
111       break;
112     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
113       ExternalUnsignedShortArray::cast(this)->
114           ExternalUnsignedShortArrayVerify();
115       break;
116     case EXTERNAL_INT_ARRAY_TYPE:
117       ExternalIntArray::cast(this)->ExternalIntArrayVerify();
118       break;
119     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
120       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
121       break;
122     case EXTERNAL_FLOAT_ARRAY_TYPE:
123       ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
124       break;
125     case EXTERNAL_DOUBLE_ARRAY_TYPE:
126       ExternalDoubleArray::cast(this)->ExternalDoubleArrayVerify();
127       break;
128     case CODE_TYPE:
129       Code::cast(this)->CodeVerify();
130       break;
131     case ODDBALL_TYPE:
132       Oddball::cast(this)->OddballVerify();
133       break;
134     case JS_OBJECT_TYPE:
135     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
136       JSObject::cast(this)->JSObjectVerify();
137       break;
138     case JS_VALUE_TYPE:
139       JSValue::cast(this)->JSValueVerify();
140       break;
141     case JS_DATE_TYPE:
142       JSDate::cast(this)->JSDateVerify();
143       break;
144     case JS_FUNCTION_TYPE:
145       JSFunction::cast(this)->JSFunctionVerify();
146       break;
147     case JS_GLOBAL_PROXY_TYPE:
148       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
149       break;
150     case JS_GLOBAL_OBJECT_TYPE:
151       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
152       break;
153     case JS_BUILTINS_OBJECT_TYPE:
154       JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
155       break;
156     case JS_GLOBAL_PROPERTY_CELL_TYPE:
157       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
158       break;
159     case JS_ARRAY_TYPE:
160       JSArray::cast(this)->JSArrayVerify();
161       break;
162     case JS_SET_TYPE:
163       JSSet::cast(this)->JSSetVerify();
164       break;
165     case JS_MAP_TYPE:
166       JSMap::cast(this)->JSMapVerify();
167       break;
168     case JS_WEAK_MAP_TYPE:
169       JSWeakMap::cast(this)->JSWeakMapVerify();
170       break;
171     case JS_REGEXP_TYPE:
172       JSRegExp::cast(this)->JSRegExpVerify();
173       break;
174     case FILLER_TYPE:
175       break;
176     case JS_PROXY_TYPE:
177       JSProxy::cast(this)->JSProxyVerify();
178       break;
179     case JS_FUNCTION_PROXY_TYPE:
180       JSFunctionProxy::cast(this)->JSFunctionProxyVerify();
181       break;
182     case FOREIGN_TYPE:
183       Foreign::cast(this)->ForeignVerify();
184       break;
185     case SHARED_FUNCTION_INFO_TYPE:
186       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
187       break;
188     case JS_MESSAGE_OBJECT_TYPE:
189       JSMessageObject::cast(this)->JSMessageObjectVerify();
190       break;
191 
192 #define MAKE_STRUCT_CASE(NAME, Name, name) \
193   case NAME##_TYPE:                        \
194     Name::cast(this)->Name##Verify();      \
195     break;
196     STRUCT_LIST(MAKE_STRUCT_CASE)
197 #undef MAKE_STRUCT_CASE
198 
199     default:
200       UNREACHABLE();
201       break;
202   }
203 }
204 
205 
VerifyHeapPointer(Object * p)206 void HeapObject::VerifyHeapPointer(Object* p) {
207   ASSERT(p->IsHeapObject());
208   ASSERT(HEAP->Contains(HeapObject::cast(p)));
209 }
210 
211 
HeapNumberVerify()212 void HeapNumber::HeapNumberVerify() {
213   ASSERT(IsHeapNumber());
214 }
215 
216 
ByteArrayVerify()217 void ByteArray::ByteArrayVerify() {
218   ASSERT(IsByteArray());
219 }
220 
221 
FreeSpaceVerify()222 void FreeSpace::FreeSpaceVerify() {
223   ASSERT(IsFreeSpace());
224 }
225 
226 
ExternalPixelArrayVerify()227 void ExternalPixelArray::ExternalPixelArrayVerify() {
228   ASSERT(IsExternalPixelArray());
229 }
230 
231 
ExternalByteArrayVerify()232 void ExternalByteArray::ExternalByteArrayVerify() {
233   ASSERT(IsExternalByteArray());
234 }
235 
236 
ExternalUnsignedByteArrayVerify()237 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
238   ASSERT(IsExternalUnsignedByteArray());
239 }
240 
241 
ExternalShortArrayVerify()242 void ExternalShortArray::ExternalShortArrayVerify() {
243   ASSERT(IsExternalShortArray());
244 }
245 
246 
ExternalUnsignedShortArrayVerify()247 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
248   ASSERT(IsExternalUnsignedShortArray());
249 }
250 
251 
ExternalIntArrayVerify()252 void ExternalIntArray::ExternalIntArrayVerify() {
253   ASSERT(IsExternalIntArray());
254 }
255 
256 
ExternalUnsignedIntArrayVerify()257 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
258   ASSERT(IsExternalUnsignedIntArray());
259 }
260 
261 
ExternalFloatArrayVerify()262 void ExternalFloatArray::ExternalFloatArrayVerify() {
263   ASSERT(IsExternalFloatArray());
264 }
265 
266 
ExternalDoubleArrayVerify()267 void ExternalDoubleArray::ExternalDoubleArrayVerify() {
268   ASSERT(IsExternalDoubleArray());
269 }
270 
271 
JSObjectVerify()272 void JSObject::JSObjectVerify() {
273   VerifyHeapPointer(properties());
274   VerifyHeapPointer(elements());
275 
276   if (GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
277     ASSERT(this->elements()->IsFixedArray());
278     ASSERT(this->elements()->length() >= 2);
279   }
280 
281   if (HasFastProperties()) {
282     CHECK_EQ(map()->unused_property_fields(),
283              (map()->inobject_properties() + properties()->length() -
284               map()->NextFreePropertyIndex()));
285   }
286   ASSERT_EQ((map()->has_fast_elements() ||
287              map()->has_fast_smi_only_elements() ||
288              (elements() == GetHeap()->empty_fixed_array())),
289             (elements()->map() == GetHeap()->fixed_array_map() ||
290              elements()->map() == GetHeap()->fixed_cow_array_map()));
291   ASSERT(map()->has_fast_elements() == HasFastElements());
292 }
293 
294 
MapVerify()295 void Map::MapVerify() {
296   ASSERT(!HEAP->InNewSpace(this));
297   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
298   ASSERT(instance_size() == kVariableSizeSentinel ||
299          (kPointerSize <= instance_size() &&
300           instance_size() < HEAP->Capacity()));
301   VerifyHeapPointer(prototype());
302   VerifyHeapPointer(instance_descriptors());
303 }
304 
305 
SharedMapVerify()306 void Map::SharedMapVerify() {
307   MapVerify();
308   ASSERT(is_shared());
309   ASSERT(instance_descriptors()->IsEmpty());
310   ASSERT_EQ(0, pre_allocated_property_fields());
311   ASSERT_EQ(0, unused_property_fields());
312   ASSERT_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
313       visitor_id());
314 }
315 
316 
CodeCacheVerify()317 void CodeCache::CodeCacheVerify() {
318   VerifyHeapPointer(default_cache());
319   VerifyHeapPointer(normal_type_cache());
320   ASSERT(default_cache()->IsFixedArray());
321   ASSERT(normal_type_cache()->IsUndefined()
322          || normal_type_cache()->IsCodeCacheHashTable());
323 }
324 
325 
PolymorphicCodeCacheVerify()326 void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
327   VerifyHeapPointer(cache());
328   ASSERT(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
329 }
330 
331 
TypeFeedbackInfoVerify()332 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
333   VerifyObjectField(kIcTotalCountOffset);
334   VerifyObjectField(kIcWithTypeinfoCountOffset);
335   VerifyHeapPointer(type_feedback_cells());
336 }
337 
338 
AliasedArgumentsEntryVerify()339 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
340   VerifySmiField(kAliasedContextSlot);
341 }
342 
343 
FixedArrayVerify()344 void FixedArray::FixedArrayVerify() {
345   for (int i = 0; i < length(); i++) {
346     Object* e = get(i);
347     if (e->IsHeapObject()) {
348       VerifyHeapPointer(e);
349     } else {
350       e->Verify();
351     }
352   }
353 }
354 
355 
FixedDoubleArrayVerify()356 void FixedDoubleArray::FixedDoubleArrayVerify() {
357   for (int i = 0; i < length(); i++) {
358     if (!is_the_hole(i)) {
359       double value = get_scalar(i);
360       ASSERT(!isnan(value) ||
361              (BitCast<uint64_t>(value) ==
362               BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
363              ((BitCast<uint64_t>(value) & Double::kSignMask) != 0));
364     }
365   }
366 }
367 
368 
JSValueVerify()369 void JSValue::JSValueVerify() {
370   Object* v = value();
371   if (v->IsHeapObject()) {
372     VerifyHeapPointer(v);
373   }
374 }
375 
376 
JSDateVerify()377 void JSDate::JSDateVerify() {
378   if (value()->IsHeapObject()) {
379     VerifyHeapPointer(value());
380   }
381   CHECK(value()->IsUndefined() || value()->IsSmi() || value()->IsHeapNumber());
382   CHECK(year()->IsUndefined() || year()->IsSmi() || year()->IsNaN());
383   CHECK(month()->IsUndefined() || month()->IsSmi() || month()->IsNaN());
384   CHECK(day()->IsUndefined() || day()->IsSmi() || day()->IsNaN());
385   CHECK(weekday()->IsUndefined() || weekday()->IsSmi() || weekday()->IsNaN());
386   CHECK(hour()->IsUndefined() || hour()->IsSmi() || hour()->IsNaN());
387   CHECK(min()->IsUndefined() || min()->IsSmi() || min()->IsNaN());
388   CHECK(sec()->IsUndefined() || sec()->IsSmi() || sec()->IsNaN());
389   CHECK(cache_stamp()->IsUndefined() ||
390         cache_stamp()->IsSmi() ||
391         cache_stamp()->IsNaN());
392 
393   if (month()->IsSmi()) {
394     int month = Smi::cast(this->month())->value();
395     CHECK(0 <= month && month <= 11);
396   }
397   if (day()->IsSmi()) {
398     int day = Smi::cast(this->day())->value();
399     CHECK(1 <= day && day <= 31);
400   }
401   if (hour()->IsSmi()) {
402     int hour = Smi::cast(this->hour())->value();
403     CHECK(0 <= hour && hour <= 23);
404   }
405   if (min()->IsSmi()) {
406     int min = Smi::cast(this->min())->value();
407     CHECK(0 <= min && min <= 59);
408   }
409   if (sec()->IsSmi()) {
410     int sec = Smi::cast(this->sec())->value();
411     CHECK(0 <= sec && sec <= 59);
412   }
413   if (weekday()->IsSmi()) {
414     int weekday = Smi::cast(this->weekday())->value();
415     CHECK(0 <= weekday && weekday <= 6);
416   }
417   if (cache_stamp()->IsSmi()) {
418     CHECK(Smi::cast(cache_stamp())->value() <=
419           Smi::cast(Isolate::Current()->date_cache()->stamp())->value());
420   }
421 }
422 
423 
JSMessageObjectVerify()424 void JSMessageObject::JSMessageObjectVerify() {
425   CHECK(IsJSMessageObject());
426   CHECK(type()->IsString());
427   CHECK(arguments()->IsJSArray());
428   VerifyObjectField(kStartPositionOffset);
429   VerifyObjectField(kEndPositionOffset);
430   VerifyObjectField(kArgumentsOffset);
431   VerifyObjectField(kScriptOffset);
432   VerifyObjectField(kStackTraceOffset);
433   VerifyObjectField(kStackFramesOffset);
434 }
435 
436 
StringVerify()437 void String::StringVerify() {
438   CHECK(IsString());
439   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
440   if (IsSymbol()) {
441     CHECK(!HEAP->InNewSpace(this));
442   }
443   if (IsConsString()) {
444     ConsString::cast(this)->ConsStringVerify();
445   } else if (IsSlicedString()) {
446     SlicedString::cast(this)->SlicedStringVerify();
447   }
448 }
449 
450 
ConsStringVerify()451 void ConsString::ConsStringVerify() {
452   CHECK(this->first()->IsString());
453   CHECK(this->second() == GetHeap()->empty_string() ||
454         this->second()->IsString());
455   CHECK(this->length() >= ConsString::kMinLength);
456   if (this->IsFlat()) {
457     // A flat cons can only be created by String::SlowTryFlatten.
458     // Afterwards, the first part may be externalized.
459     CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
460   }
461 }
462 
463 
SlicedStringVerify()464 void SlicedString::SlicedStringVerify() {
465   CHECK(!this->parent()->IsConsString());
466   CHECK(!this->parent()->IsSlicedString());
467   CHECK(this->length() >= SlicedString::kMinLength);
468 }
469 
470 
JSFunctionVerify()471 void JSFunction::JSFunctionVerify() {
472   CHECK(IsJSFunction());
473   VerifyObjectField(kPrototypeOrInitialMapOffset);
474   VerifyObjectField(kNextFunctionLinkOffset);
475   CHECK(code()->IsCode());
476   CHECK(next_function_link()->IsUndefined() ||
477         next_function_link()->IsJSFunction());
478 }
479 
480 
SharedFunctionInfoVerify()481 void SharedFunctionInfo::SharedFunctionInfoVerify() {
482   CHECK(IsSharedFunctionInfo());
483   VerifyObjectField(kNameOffset);
484   VerifyObjectField(kCodeOffset);
485   VerifyObjectField(kScopeInfoOffset);
486   VerifyObjectField(kInstanceClassNameOffset);
487   VerifyObjectField(kFunctionDataOffset);
488   VerifyObjectField(kScriptOffset);
489   VerifyObjectField(kDebugInfoOffset);
490 }
491 
492 
JSGlobalProxyVerify()493 void JSGlobalProxy::JSGlobalProxyVerify() {
494   CHECK(IsJSGlobalProxy());
495   JSObjectVerify();
496   VerifyObjectField(JSGlobalProxy::kContextOffset);
497   // Make sure that this object has no properties, elements.
498   CHECK_EQ(0, properties()->length());
499   CHECK(HasFastElements());
500   CHECK_EQ(0, FixedArray::cast(elements())->length());
501 }
502 
503 
JSGlobalObjectVerify()504 void JSGlobalObject::JSGlobalObjectVerify() {
505   CHECK(IsJSGlobalObject());
506   JSObjectVerify();
507   for (int i = GlobalObject::kBuiltinsOffset;
508        i < JSGlobalObject::kSize;
509        i += kPointerSize) {
510     VerifyObjectField(i);
511   }
512 }
513 
514 
JSBuiltinsObjectVerify()515 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
516   CHECK(IsJSBuiltinsObject());
517   JSObjectVerify();
518   for (int i = GlobalObject::kBuiltinsOffset;
519        i < JSBuiltinsObject::kSize;
520        i += kPointerSize) {
521     VerifyObjectField(i);
522   }
523 }
524 
525 
OddballVerify()526 void Oddball::OddballVerify() {
527   CHECK(IsOddball());
528   VerifyHeapPointer(to_string());
529   Object* number = to_number();
530   if (number->IsHeapObject()) {
531     ASSERT(number == HEAP->nan_value());
532   } else {
533     ASSERT(number->IsSmi());
534     int value = Smi::cast(number)->value();
535     // Hidden oddballs have negative smis.
536     const int kLeastHiddenOddballNumber = -4;
537     ASSERT(value <= 1);
538     ASSERT(value >= kLeastHiddenOddballNumber);
539   }
540 }
541 
542 
JSGlobalPropertyCellVerify()543 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
544   CHECK(IsJSGlobalPropertyCell());
545   VerifyObjectField(kValueOffset);
546 }
547 
548 
CodeVerify()549 void Code::CodeVerify() {
550   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
551                   kCodeAlignment));
552   relocation_info()->Verify();
553   Address last_gc_pc = NULL;
554   for (RelocIterator it(this); !it.done(); it.next()) {
555     it.rinfo()->Verify();
556     // Ensure that GC will not iterate twice over the same pointer.
557     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
558       CHECK(it.rinfo()->pc() != last_gc_pc);
559       last_gc_pc = it.rinfo()->pc();
560     }
561   }
562 }
563 
564 
JSArrayVerify()565 void JSArray::JSArrayVerify() {
566   JSObjectVerify();
567   ASSERT(length()->IsNumber() || length()->IsUndefined());
568   ASSERT(elements()->IsUndefined() ||
569          elements()->IsFixedArray() ||
570          elements()->IsFixedDoubleArray());
571 }
572 
573 
JSSetVerify()574 void JSSet::JSSetVerify() {
575   CHECK(IsJSSet());
576   JSObjectVerify();
577   VerifyHeapPointer(table());
578   ASSERT(table()->IsHashTable() || table()->IsUndefined());
579 }
580 
581 
JSMapVerify()582 void JSMap::JSMapVerify() {
583   CHECK(IsJSMap());
584   JSObjectVerify();
585   VerifyHeapPointer(table());
586   ASSERT(table()->IsHashTable() || table()->IsUndefined());
587 }
588 
589 
JSWeakMapVerify()590 void JSWeakMap::JSWeakMapVerify() {
591   CHECK(IsJSWeakMap());
592   JSObjectVerify();
593   VerifyHeapPointer(table());
594   ASSERT(table()->IsHashTable() || table()->IsUndefined());
595 }
596 
597 
JSRegExpVerify()598 void JSRegExp::JSRegExpVerify() {
599   JSObjectVerify();
600   ASSERT(data()->IsUndefined() || data()->IsFixedArray());
601   switch (TypeTag()) {
602     case JSRegExp::ATOM: {
603       FixedArray* arr = FixedArray::cast(data());
604       ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
605       break;
606     }
607     case JSRegExp::IRREGEXP: {
608       bool is_native = RegExpImpl::UsesNativeRegExp();
609 
610       FixedArray* arr = FixedArray::cast(data());
611       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
612       // Smi : Not compiled yet (-1) or code prepared for flushing.
613       // JSObject: Compilation error.
614       // Code/ByteArray: Compiled code.
615       ASSERT(ascii_data->IsSmi() ||
616              (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
617       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
618       ASSERT(uc16_data->IsSmi() ||
619              (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
620 
621       Object* ascii_saved = arr->get(JSRegExp::kIrregexpASCIICodeSavedIndex);
622       ASSERT(ascii_saved->IsSmi() || ascii_saved->IsString() ||
623              ascii_saved->IsCode());
624       Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
625       ASSERT(uc16_saved->IsSmi() || uc16_saved->IsString() ||
626              uc16_saved->IsCode());
627 
628       ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
629       ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
630       break;
631     }
632     default:
633       ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
634       ASSERT(data()->IsUndefined());
635       break;
636   }
637 }
638 
639 
JSProxyVerify()640 void JSProxy::JSProxyVerify() {
641   CHECK(IsJSProxy());
642   VerifyPointer(handler());
643   ASSERT(hash()->IsSmi() || hash()->IsUndefined());
644 }
645 
646 
JSFunctionProxyVerify()647 void JSFunctionProxy::JSFunctionProxyVerify() {
648   CHECK(IsJSFunctionProxy());
649   JSProxyVerify();
650   VerifyPointer(call_trap());
651   VerifyPointer(construct_trap());
652 }
653 
654 
ForeignVerify()655 void Foreign::ForeignVerify() {
656   ASSERT(IsForeign());
657 }
658 
659 
AccessorInfoVerify()660 void AccessorInfo::AccessorInfoVerify() {
661   CHECK(IsAccessorInfo());
662   VerifyPointer(getter());
663   VerifyPointer(setter());
664   VerifyPointer(name());
665   VerifyPointer(data());
666   VerifyPointer(flag());
667 }
668 
669 
AccessorPairVerify()670 void AccessorPair::AccessorPairVerify() {
671   CHECK(IsAccessorPair());
672   VerifyPointer(getter());
673   VerifyPointer(setter());
674 }
675 
676 
AccessCheckInfoVerify()677 void AccessCheckInfo::AccessCheckInfoVerify() {
678   CHECK(IsAccessCheckInfo());
679   VerifyPointer(named_callback());
680   VerifyPointer(indexed_callback());
681   VerifyPointer(data());
682 }
683 
684 
InterceptorInfoVerify()685 void InterceptorInfo::InterceptorInfoVerify() {
686   CHECK(IsInterceptorInfo());
687   VerifyPointer(getter());
688   VerifyPointer(setter());
689   VerifyPointer(query());
690   VerifyPointer(deleter());
691   VerifyPointer(enumerator());
692   VerifyPointer(data());
693 }
694 
695 
CallHandlerInfoVerify()696 void CallHandlerInfo::CallHandlerInfoVerify() {
697   CHECK(IsCallHandlerInfo());
698   VerifyPointer(callback());
699   VerifyPointer(data());
700 }
701 
702 
TemplateInfoVerify()703 void TemplateInfo::TemplateInfoVerify() {
704   VerifyPointer(tag());
705   VerifyPointer(property_list());
706 }
707 
FunctionTemplateInfoVerify()708 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
709   CHECK(IsFunctionTemplateInfo());
710   TemplateInfoVerify();
711   VerifyPointer(serial_number());
712   VerifyPointer(call_code());
713   VerifyPointer(property_accessors());
714   VerifyPointer(prototype_template());
715   VerifyPointer(parent_template());
716   VerifyPointer(named_property_handler());
717   VerifyPointer(indexed_property_handler());
718   VerifyPointer(instance_template());
719   VerifyPointer(signature());
720   VerifyPointer(access_check_info());
721 }
722 
723 
ObjectTemplateInfoVerify()724 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
725   CHECK(IsObjectTemplateInfo());
726   TemplateInfoVerify();
727   VerifyPointer(constructor());
728   VerifyPointer(internal_field_count());
729 }
730 
731 
SignatureInfoVerify()732 void SignatureInfo::SignatureInfoVerify() {
733   CHECK(IsSignatureInfo());
734   VerifyPointer(receiver());
735   VerifyPointer(args());
736 }
737 
738 
TypeSwitchInfoVerify()739 void TypeSwitchInfo::TypeSwitchInfoVerify() {
740   CHECK(IsTypeSwitchInfo());
741   VerifyPointer(types());
742 }
743 
744 
ScriptVerify()745 void Script::ScriptVerify() {
746   CHECK(IsScript());
747   VerifyPointer(source());
748   VerifyPointer(name());
749   line_offset()->SmiVerify();
750   column_offset()->SmiVerify();
751   VerifyPointer(data());
752   VerifyPointer(wrapper());
753   type()->SmiVerify();
754   VerifyPointer(line_ends());
755   VerifyPointer(id());
756 }
757 
758 
759 #ifdef ENABLE_DEBUGGER_SUPPORT
DebugInfoVerify()760 void DebugInfo::DebugInfoVerify() {
761   CHECK(IsDebugInfo());
762   VerifyPointer(shared());
763   VerifyPointer(original_code());
764   VerifyPointer(code());
765   VerifyPointer(break_points());
766 }
767 
768 
BreakPointInfoVerify()769 void BreakPointInfo::BreakPointInfoVerify() {
770   CHECK(IsBreakPointInfo());
771   code_position()->SmiVerify();
772   source_position()->SmiVerify();
773   statement_position()->SmiVerify();
774   VerifyPointer(break_point_objects());
775 }
776 #endif  // ENABLE_DEBUGGER_SUPPORT
777 
778 
IncrementSpillStatistics(SpillInformation * info)779 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
780   info->number_of_objects_++;
781   // Named properties
782   if (HasFastProperties()) {
783     info->number_of_objects_with_fast_properties_++;
784     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
785     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
786   } else {
787     StringDictionary* dict = property_dictionary();
788     info->number_of_slow_used_properties_ += dict->NumberOfElements();
789     info->number_of_slow_unused_properties_ +=
790         dict->Capacity() - dict->NumberOfElements();
791   }
792   // Indexed properties
793   switch (GetElementsKind()) {
794     case FAST_ELEMENTS: {
795       info->number_of_objects_with_fast_elements_++;
796       int holes = 0;
797       FixedArray* e = FixedArray::cast(elements());
798       int len = e->length();
799       Heap* heap = HEAP;
800       for (int i = 0; i < len; i++) {
801         if (e->get(i) == heap->the_hole_value()) holes++;
802       }
803       info->number_of_fast_used_elements_   += len - holes;
804       info->number_of_fast_unused_elements_ += holes;
805       break;
806     }
807     case EXTERNAL_PIXEL_ELEMENTS: {
808       info->number_of_objects_with_fast_elements_++;
809       ExternalPixelArray* e = ExternalPixelArray::cast(elements());
810       info->number_of_fast_used_elements_ += e->length();
811       break;
812     }
813     case DICTIONARY_ELEMENTS: {
814       SeededNumberDictionary* dict = element_dictionary();
815       info->number_of_slow_used_elements_ += dict->NumberOfElements();
816       info->number_of_slow_unused_elements_ +=
817           dict->Capacity() - dict->NumberOfElements();
818       break;
819     }
820     default:
821       UNREACHABLE();
822       break;
823   }
824 }
825 
826 
Clear()827 void JSObject::SpillInformation::Clear() {
828   number_of_objects_ = 0;
829   number_of_objects_with_fast_properties_ = 0;
830   number_of_objects_with_fast_elements_ = 0;
831   number_of_fast_used_fields_ = 0;
832   number_of_fast_unused_fields_ = 0;
833   number_of_slow_used_properties_ = 0;
834   number_of_slow_unused_properties_ = 0;
835   number_of_fast_used_elements_ = 0;
836   number_of_fast_unused_elements_ = 0;
837   number_of_slow_used_elements_ = 0;
838   number_of_slow_unused_elements_ = 0;
839 }
840 
Print()841 void JSObject::SpillInformation::Print() {
842   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
843 
844   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
845          number_of_objects_with_fast_properties_,
846          number_of_fast_used_fields_, number_of_fast_unused_fields_);
847 
848   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
849          number_of_objects_ - number_of_objects_with_fast_properties_,
850          number_of_slow_used_properties_, number_of_slow_unused_properties_);
851 
852   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
853          number_of_objects_with_fast_elements_,
854          number_of_fast_used_elements_, number_of_fast_unused_elements_);
855 
856   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
857          number_of_objects_ - number_of_objects_with_fast_elements_,
858          number_of_slow_used_elements_, number_of_slow_unused_elements_);
859 
860   PrintF("\n");
861 }
862 
863 
IsSortedNoDuplicates()864 bool DescriptorArray::IsSortedNoDuplicates() {
865   String* current_key = NULL;
866   uint32_t current = 0;
867   for (int i = 0; i < number_of_descriptors(); i++) {
868     String* key = GetKey(i);
869     if (key == current_key) {
870       PrintDescriptors();
871       return false;
872     }
873     current_key = key;
874     uint32_t hash = GetKey(i)->Hash();
875     if (hash < current) {
876       PrintDescriptors();
877       return false;
878     }
879     current = hash;
880   }
881   return true;
882 }
883 
884 
JSFunctionResultCacheVerify()885 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
886   JSFunction::cast(get(kFactoryIndex))->Verify();
887 
888   int size = Smi::cast(get(kCacheSizeIndex))->value();
889   ASSERT(kEntriesIndex <= size);
890   ASSERT(size <= length());
891   ASSERT_EQ(0, size % kEntrySize);
892 
893   int finger = Smi::cast(get(kFingerIndex))->value();
894   ASSERT(kEntriesIndex <= finger);
895   ASSERT((finger < size) || (finger == kEntriesIndex && finger == size));
896   ASSERT_EQ(0, finger % kEntrySize);
897 
898   if (FLAG_enable_slow_asserts) {
899     for (int i = kEntriesIndex; i < size; i++) {
900       ASSERT(!get(i)->IsTheHole());
901       get(i)->Verify();
902     }
903     for (int i = size; i < length(); i++) {
904       ASSERT(get(i)->IsTheHole());
905       get(i)->Verify();
906     }
907   }
908 }
909 
910 
NormalizedMapCacheVerify()911 void NormalizedMapCache::NormalizedMapCacheVerify() {
912   FixedArray::cast(this)->Verify();
913   if (FLAG_enable_slow_asserts) {
914     for (int i = 0; i < length(); i++) {
915       Object* e = get(i);
916       if (e->IsMap()) {
917         Map::cast(e)->SharedMapVerify();
918       } else {
919         ASSERT(e->IsUndefined());
920       }
921     }
922   }
923 }
924 
925 
926 #endif  // DEBUG
927 
928 } }  // namespace v8::internal
929