v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
objects-debug.cc
Go to the documentation of this file.
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 VERIFY_HEAP
39 
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 
54 void Object::VerifyPointer(Object* p) {
55  if (p->IsHeapObject()) {
56  HeapObject::VerifyHeapPointer(p);
57  } else {
58  CHECK(p->IsSmi());
59  }
60 }
61 
62 
63 void Smi::SmiVerify() {
64  CHECK(IsSmi());
65 }
66 
67 
68 void Failure::FailureVerify() {
69  CHECK(IsFailure());
70 }
71 
72 
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;
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;
101  ExternalPixelArray::cast(this)->ExternalPixelArrayVerify();
102  break;
104  ExternalByteArray::cast(this)->ExternalByteArrayVerify();
105  break;
107  ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
108  break;
110  ExternalShortArray::cast(this)->ExternalShortArrayVerify();
111  break;
114  ExternalUnsignedShortArrayVerify();
115  break;
117  ExternalIntArray::cast(this)->ExternalIntArrayVerify();
118  break;
120  ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
121  break;
123  ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
124  break;
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:
136  JSObject::cast(this)->JSObjectVerify();
137  break;
138  case JS_MODULE_TYPE:
139  JSModule::cast(this)->JSModuleVerify();
140  break;
141  case JS_VALUE_TYPE:
142  JSValue::cast(this)->JSValueVerify();
143  break;
144  case JS_DATE_TYPE:
145  JSDate::cast(this)->JSDateVerify();
146  break;
147  case JS_FUNCTION_TYPE:
148  JSFunction::cast(this)->JSFunctionVerify();
149  break;
151  JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
152  break;
154  JSGlobalObject::cast(this)->JSGlobalObjectVerify();
155  break;
157  JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
158  break;
160  JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
161  break;
162  case JS_ARRAY_TYPE:
163  JSArray::cast(this)->JSArrayVerify();
164  break;
165  case JS_SET_TYPE:
166  JSSet::cast(this)->JSSetVerify();
167  break;
168  case JS_MAP_TYPE:
169  JSMap::cast(this)->JSMapVerify();
170  break;
171  case JS_WEAK_MAP_TYPE:
172  JSWeakMap::cast(this)->JSWeakMapVerify();
173  break;
174  case JS_REGEXP_TYPE:
175  JSRegExp::cast(this)->JSRegExpVerify();
176  break;
177  case FILLER_TYPE:
178  break;
179  case JS_PROXY_TYPE:
180  JSProxy::cast(this)->JSProxyVerify();
181  break;
183  JSFunctionProxy::cast(this)->JSFunctionProxyVerify();
184  break;
185  case FOREIGN_TYPE:
186  Foreign::cast(this)->ForeignVerify();
187  break;
189  SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
190  break;
192  JSMessageObject::cast(this)->JSMessageObjectVerify();
193  break;
194 
195 #define MAKE_STRUCT_CASE(NAME, Name, name) \
196  case NAME##_TYPE: \
197  Name::cast(this)->Name##Verify(); \
198  break;
200 #undef MAKE_STRUCT_CASE
201 
202  default:
203  UNREACHABLE();
204  break;
205  }
206 }
207 
208 
209 void HeapObject::VerifyHeapPointer(Object* p) {
210  CHECK(p->IsHeapObject());
211  CHECK(HEAP->Contains(HeapObject::cast(p)));
212 }
213 
214 
215 void HeapNumber::HeapNumberVerify() {
216  CHECK(IsHeapNumber());
217 }
218 
219 
220 void ByteArray::ByteArrayVerify() {
221  CHECK(IsByteArray());
222 }
223 
224 
225 void FreeSpace::FreeSpaceVerify() {
226  CHECK(IsFreeSpace());
227 }
228 
229 
230 void ExternalPixelArray::ExternalPixelArrayVerify() {
231  CHECK(IsExternalPixelArray());
232 }
233 
234 
235 void ExternalByteArray::ExternalByteArrayVerify() {
236  CHECK(IsExternalByteArray());
237 }
238 
239 
240 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
241  CHECK(IsExternalUnsignedByteArray());
242 }
243 
244 
245 void ExternalShortArray::ExternalShortArrayVerify() {
246  CHECK(IsExternalShortArray());
247 }
248 
249 
250 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
251  CHECK(IsExternalUnsignedShortArray());
252 }
253 
254 
255 void ExternalIntArray::ExternalIntArrayVerify() {
256  CHECK(IsExternalIntArray());
257 }
258 
259 
260 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
261  CHECK(IsExternalUnsignedIntArray());
262 }
263 
264 
265 void ExternalFloatArray::ExternalFloatArrayVerify() {
266  CHECK(IsExternalFloatArray());
267 }
268 
269 
270 void ExternalDoubleArray::ExternalDoubleArrayVerify() {
271  CHECK(IsExternalDoubleArray());
272 }
273 
274 
275 void JSObject::JSObjectVerify() {
276  VerifyHeapPointer(properties());
277  VerifyHeapPointer(elements());
278 
280  CHECK(this->elements()->IsFixedArray());
281  CHECK_GE(this->elements()->length(), 2);
282  }
283 
284  if (HasFastProperties()) {
285  CHECK_EQ(map()->unused_property_fields(),
286  (map()->inobject_properties() + properties()->length() -
287  map()->NextFreePropertyIndex()));
288  }
289  CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
290  (elements() == GetHeap()->empty_fixed_array())),
291  (elements()->map() == GetHeap()->fixed_array_map() ||
292  elements()->map() == GetHeap()->fixed_cow_array_map()));
293  CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
294 }
295 
296 
297 void Map::MapVerify() {
298  CHECK(!HEAP->InNewSpace(this));
301  (kPointerSize <= instance_size() &&
302  instance_size() < HEAP->Capacity()));
303  VerifyHeapPointer(prototype());
304  VerifyHeapPointer(instance_descriptors());
305  DescriptorArray* descriptors = instance_descriptors();
306  for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
307  CHECK_EQ(i, descriptors->GetDetails(i).descriptor_index() - 1);
308  }
309  SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
310  if (HasTransitionArray()) {
311  SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
312  SLOW_ASSERT(transitions()->IsConsistentWithBackPointers(this));
313  }
314 }
315 
316 
317 void Map::SharedMapVerify() {
318  MapVerify();
319  CHECK(is_shared());
320  CHECK(instance_descriptors()->IsEmpty());
324  visitor_id());
325 }
326 
327 
328 void CodeCache::CodeCacheVerify() {
329  VerifyHeapPointer(default_cache());
330  VerifyHeapPointer(normal_type_cache());
331  CHECK(default_cache()->IsFixedArray());
332  CHECK(normal_type_cache()->IsUndefined()
333  || normal_type_cache()->IsCodeCacheHashTable());
334 }
335 
336 
337 void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
338  VerifyHeapPointer(cache());
339  CHECK(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
340 }
341 
342 
343 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
344  VerifyObjectField(kStorage1Offset);
345  VerifyObjectField(kStorage2Offset);
346  VerifyHeapPointer(type_feedback_cells());
347 }
348 
349 
350 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
351  VerifySmiField(kAliasedContextSlot);
352 }
353 
354 
355 void FixedArray::FixedArrayVerify() {
356  for (int i = 0; i < length(); i++) {
357  Object* e = get(i);
358  if (e->IsHeapObject()) {
359  VerifyHeapPointer(e);
360  } else {
361  e->Verify();
362  }
363  }
364 }
365 
366 
367 void FixedDoubleArray::FixedDoubleArrayVerify() {
368  for (int i = 0; i < length(); i++) {
369  if (!is_the_hole(i)) {
370  double value = get_scalar(i);
371  CHECK(!isnan(value) ||
372  (BitCast<uint64_t>(value) ==
373  BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
374  ((BitCast<uint64_t>(value) & Double::kSignMask) != 0));
375  }
376  }
377 }
378 
379 
380 void JSModule::JSModuleVerify() {
381  VerifyObjectField(kContextOffset);
382  VerifyObjectField(kScopeInfoOffset);
383  CHECK(context()->IsUndefined() ||
384  Context::cast(context())->IsModuleContext());
385 }
386 
387 
388 void JSValue::JSValueVerify() {
389  Object* v = value();
390  if (v->IsHeapObject()) {
391  VerifyHeapPointer(v);
392  }
393 }
394 
395 
396 void JSDate::JSDateVerify() {
397  if (value()->IsHeapObject()) {
398  VerifyHeapPointer(value());
399  }
400  CHECK(value()->IsUndefined() || value()->IsSmi() || value()->IsHeapNumber());
401  CHECK(year()->IsUndefined() || year()->IsSmi() || year()->IsNaN());
402  CHECK(month()->IsUndefined() || month()->IsSmi() || month()->IsNaN());
403  CHECK(day()->IsUndefined() || day()->IsSmi() || day()->IsNaN());
404  CHECK(weekday()->IsUndefined() || weekday()->IsSmi() || weekday()->IsNaN());
405  CHECK(hour()->IsUndefined() || hour()->IsSmi() || hour()->IsNaN());
406  CHECK(min()->IsUndefined() || min()->IsSmi() || min()->IsNaN());
407  CHECK(sec()->IsUndefined() || sec()->IsSmi() || sec()->IsNaN());
408  CHECK(cache_stamp()->IsUndefined() ||
409  cache_stamp()->IsSmi() ||
410  cache_stamp()->IsNaN());
411 
412  if (month()->IsSmi()) {
413  int month = Smi::cast(this->month())->value();
414  CHECK(0 <= month && month <= 11);
415  }
416  if (day()->IsSmi()) {
417  int day = Smi::cast(this->day())->value();
418  CHECK(1 <= day && day <= 31);
419  }
420  if (hour()->IsSmi()) {
421  int hour = Smi::cast(this->hour())->value();
422  CHECK(0 <= hour && hour <= 23);
423  }
424  if (min()->IsSmi()) {
425  int min = Smi::cast(this->min())->value();
426  CHECK(0 <= min && min <= 59);
427  }
428  if (sec()->IsSmi()) {
429  int sec = Smi::cast(this->sec())->value();
430  CHECK(0 <= sec && sec <= 59);
431  }
432  if (weekday()->IsSmi()) {
433  int weekday = Smi::cast(this->weekday())->value();
434  CHECK(0 <= weekday && weekday <= 6);
435  }
436  if (cache_stamp()->IsSmi()) {
437  CHECK(Smi::cast(cache_stamp())->value() <=
438  Smi::cast(Isolate::Current()->date_cache()->stamp())->value());
439  }
440 }
441 
442 
443 void JSMessageObject::JSMessageObjectVerify() {
444  CHECK(IsJSMessageObject());
445  CHECK(type()->IsString());
446  CHECK(arguments()->IsJSArray());
447  VerifyObjectField(kStartPositionOffset);
448  VerifyObjectField(kEndPositionOffset);
449  VerifyObjectField(kArgumentsOffset);
450  VerifyObjectField(kScriptOffset);
451  VerifyObjectField(kStackTraceOffset);
452  VerifyObjectField(kStackFramesOffset);
453 }
454 
455 
456 void String::StringVerify() {
457  CHECK(IsString());
458  CHECK(length() >= 0 && length() <= Smi::kMaxValue);
459  if (IsSymbol()) {
460  CHECK(!HEAP->InNewSpace(this));
461  }
462  if (IsConsString()) {
463  ConsString::cast(this)->ConsStringVerify();
464  } else if (IsSlicedString()) {
465  SlicedString::cast(this)->SlicedStringVerify();
466  } else if (IsSeqAsciiString()) {
467  SeqAsciiString::cast(this)->SeqAsciiStringVerify();
468  }
469 }
470 
471 
472 void SeqAsciiString::SeqAsciiStringVerify() {
474 }
475 
476 
477 void ConsString::ConsStringVerify() {
478  CHECK(this->first()->IsString());
479  CHECK(this->second() == GetHeap()->empty_string() ||
480  this->second()->IsString());
481  CHECK(this->length() >= ConsString::kMinLength);
482  if (this->IsFlat()) {
483  // A flat cons can only be created by String::SlowTryFlatten.
484  // Afterwards, the first part may be externalized.
485  CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
486  }
487 }
488 
489 
490 void SlicedString::SlicedStringVerify() {
491  CHECK(!this->parent()->IsConsString());
492  CHECK(!this->parent()->IsSlicedString());
494 }
495 
496 
497 void JSFunction::JSFunctionVerify() {
498  CHECK(IsJSFunction());
499  VerifyObjectField(kPrototypeOrInitialMapOffset);
500  VerifyObjectField(kNextFunctionLinkOffset);
501  CHECK(code()->IsCode());
502  CHECK(next_function_link()->IsUndefined() ||
503  next_function_link()->IsJSFunction());
504 }
505 
506 
507 void SharedFunctionInfo::SharedFunctionInfoVerify() {
508  CHECK(IsSharedFunctionInfo());
509  VerifyObjectField(kNameOffset);
510  VerifyObjectField(kCodeOffset);
511  VerifyObjectField(kOptimizedCodeMapOffset);
512  VerifyObjectField(kScopeInfoOffset);
513  VerifyObjectField(kInstanceClassNameOffset);
514  VerifyObjectField(kFunctionDataOffset);
515  VerifyObjectField(kScriptOffset);
516  VerifyObjectField(kDebugInfoOffset);
517 }
518 
519 
520 void JSGlobalProxy::JSGlobalProxyVerify() {
521  CHECK(IsJSGlobalProxy());
522  JSObjectVerify();
523  VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
524  // Make sure that this object has no properties, elements.
525  CHECK_EQ(0, properties()->length());
527  CHECK_EQ(0, FixedArray::cast(elements())->length());
528 }
529 
530 
531 void JSGlobalObject::JSGlobalObjectVerify() {
532  CHECK(IsJSGlobalObject());
533  JSObjectVerify();
534  for (int i = GlobalObject::kBuiltinsOffset;
536  i += kPointerSize) {
537  VerifyObjectField(i);
538  }
539 }
540 
541 
542 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
543  CHECK(IsJSBuiltinsObject());
544  JSObjectVerify();
545  for (int i = GlobalObject::kBuiltinsOffset;
547  i += kPointerSize) {
548  VerifyObjectField(i);
549  }
550 }
551 
552 
553 void Oddball::OddballVerify() {
554  CHECK(IsOddball());
555  VerifyHeapPointer(to_string());
556  Object* number = to_number();
557  if (number->IsHeapObject()) {
558  CHECK(number == HEAP->nan_value());
559  } else {
560  CHECK(number->IsSmi());
561  int value = Smi::cast(number)->value();
562  // Hidden oddballs have negative smis.
563  const int kLeastHiddenOddballNumber = -4;
564  CHECK_LE(value, 1);
565  CHECK(value >= kLeastHiddenOddballNumber);
566  }
567 }
568 
569 
570 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
571  CHECK(IsJSGlobalPropertyCell());
572  VerifyObjectField(kValueOffset);
573 }
574 
575 
576 void Code::CodeVerify() {
577  CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
578  kCodeAlignment));
579  relocation_info()->Verify();
580  Address last_gc_pc = NULL;
581  for (RelocIterator it(this); !it.done(); it.next()) {
582  it.rinfo()->Verify();
583  // Ensure that GC will not iterate twice over the same pointer.
584  if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
585  CHECK(it.rinfo()->pc() != last_gc_pc);
586  last_gc_pc = it.rinfo()->pc();
587  }
588  }
589 }
590 
591 
592 void JSArray::JSArrayVerify() {
593  JSObjectVerify();
594  CHECK(length()->IsNumber() || length()->IsUndefined());
595  CHECK(elements()->IsUndefined() ||
596  elements()->IsFixedArray() ||
597  elements()->IsFixedDoubleArray());
598 }
599 
600 
601 void JSSet::JSSetVerify() {
602  CHECK(IsJSSet());
603  JSObjectVerify();
604  VerifyHeapPointer(table());
605  CHECK(table()->IsHashTable() || table()->IsUndefined());
606 }
607 
608 
609 void JSMap::JSMapVerify() {
610  CHECK(IsJSMap());
611  JSObjectVerify();
612  VerifyHeapPointer(table());
613  CHECK(table()->IsHashTable() || table()->IsUndefined());
614 }
615 
616 
617 void JSWeakMap::JSWeakMapVerify() {
618  CHECK(IsJSWeakMap());
619  JSObjectVerify();
620  VerifyHeapPointer(table());
621  CHECK(table()->IsHashTable() || table()->IsUndefined());
622 }
623 
624 
625 void JSRegExp::JSRegExpVerify() {
626  JSObjectVerify();
627  CHECK(data()->IsUndefined() || data()->IsFixedArray());
628  switch (TypeTag()) {
629  case JSRegExp::ATOM: {
630  FixedArray* arr = FixedArray::cast(data());
631  CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
632  break;
633  }
634  case JSRegExp::IRREGEXP: {
635  bool is_native = RegExpImpl::UsesNativeRegExp();
636 
637  FixedArray* arr = FixedArray::cast(data());
638  Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
639  // Smi : Not compiled yet (-1) or code prepared for flushing.
640  // JSObject: Compilation error.
641  // Code/ByteArray: Compiled code.
642  CHECK(ascii_data->IsSmi() ||
643  (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
644  Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
645  CHECK(uc16_data->IsSmi() ||
646  (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
647 
648  Object* ascii_saved = arr->get(JSRegExp::kIrregexpASCIICodeSavedIndex);
649  CHECK(ascii_saved->IsSmi() || ascii_saved->IsString() ||
650  ascii_saved->IsCode());
651  Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
652  CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
653  uc16_saved->IsCode());
654 
655  CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
657  break;
658  }
659  default:
661  CHECK(data()->IsUndefined());
662  break;
663  }
664 }
665 
666 
667 void JSProxy::JSProxyVerify() {
668  CHECK(IsJSProxy());
669  VerifyPointer(handler());
670  CHECK(hash()->IsSmi() || hash()->IsUndefined());
671 }
672 
673 
674 void JSFunctionProxy::JSFunctionProxyVerify() {
675  CHECK(IsJSFunctionProxy());
676  JSProxyVerify();
677  VerifyPointer(call_trap());
678  VerifyPointer(construct_trap());
679 }
680 
681 
682 void Foreign::ForeignVerify() {
683  CHECK(IsForeign());
684 }
685 
686 
687 void AccessorInfo::AccessorInfoVerify() {
688  CHECK(IsAccessorInfo());
689  VerifyPointer(getter());
690  VerifyPointer(setter());
691  VerifyPointer(name());
692  VerifyPointer(data());
693  VerifyPointer(flag());
694  VerifyPointer(expected_receiver_type());
695 }
696 
697 
698 void AccessorPair::AccessorPairVerify() {
699  CHECK(IsAccessorPair());
700  VerifyPointer(getter());
701  VerifyPointer(setter());
702 }
703 
704 
705 void AccessCheckInfo::AccessCheckInfoVerify() {
706  CHECK(IsAccessCheckInfo());
707  VerifyPointer(named_callback());
708  VerifyPointer(indexed_callback());
709  VerifyPointer(data());
710 }
711 
712 
713 void InterceptorInfo::InterceptorInfoVerify() {
714  CHECK(IsInterceptorInfo());
715  VerifyPointer(getter());
716  VerifyPointer(setter());
717  VerifyPointer(query());
718  VerifyPointer(deleter());
719  VerifyPointer(enumerator());
720  VerifyPointer(data());
721 }
722 
723 
724 void CallHandlerInfo::CallHandlerInfoVerify() {
725  CHECK(IsCallHandlerInfo());
726  VerifyPointer(callback());
727  VerifyPointer(data());
728 }
729 
730 
731 void TemplateInfo::TemplateInfoVerify() {
732  VerifyPointer(tag());
733  VerifyPointer(property_list());
734 }
735 
736 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
737  CHECK(IsFunctionTemplateInfo());
738  TemplateInfoVerify();
739  VerifyPointer(serial_number());
740  VerifyPointer(call_code());
741  VerifyPointer(property_accessors());
742  VerifyPointer(prototype_template());
743  VerifyPointer(parent_template());
744  VerifyPointer(named_property_handler());
745  VerifyPointer(indexed_property_handler());
746  VerifyPointer(instance_template());
747  VerifyPointer(signature());
748  VerifyPointer(access_check_info());
749 }
750 
751 
752 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
753  CHECK(IsObjectTemplateInfo());
754  TemplateInfoVerify();
755  VerifyPointer(constructor());
756  VerifyPointer(internal_field_count());
757 }
758 
759 
760 void SignatureInfo::SignatureInfoVerify() {
761  CHECK(IsSignatureInfo());
762  VerifyPointer(receiver());
763  VerifyPointer(args());
764 }
765 
766 
767 void TypeSwitchInfo::TypeSwitchInfoVerify() {
768  CHECK(IsTypeSwitchInfo());
769  VerifyPointer(types());
770 }
771 
772 
773 void Script::ScriptVerify() {
774  CHECK(IsScript());
775  VerifyPointer(source());
776  VerifyPointer(name());
777  line_offset()->SmiVerify();
778  column_offset()->SmiVerify();
779  VerifyPointer(data());
780  VerifyPointer(wrapper());
781  type()->SmiVerify();
782  VerifyPointer(line_ends());
783  VerifyPointer(id());
784 }
785 
786 
787 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
788  JSFunction::cast(get(kFactoryIndex))->Verify();
789 
790  int size = Smi::cast(get(kCacheSizeIndex))->value();
791  CHECK(kEntriesIndex <= size);
792  CHECK(size <= length());
793  CHECK_EQ(0, size % kEntrySize);
794 
795  int finger = Smi::cast(get(kFingerIndex))->value();
796  CHECK(kEntriesIndex <= finger);
797  CHECK((finger < size) || (finger == kEntriesIndex && finger == size));
798  CHECK_EQ(0, finger % kEntrySize);
799 
801  for (int i = kEntriesIndex; i < size; i++) {
802  CHECK(!get(i)->IsTheHole());
803  get(i)->Verify();
804  }
805  for (int i = size; i < length(); i++) {
806  CHECK(get(i)->IsTheHole());
807  get(i)->Verify();
808  }
809  }
810 }
811 
812 
813 void NormalizedMapCache::NormalizedMapCacheVerify() {
814  FixedArray::cast(this)->Verify();
816  for (int i = 0; i < length(); i++) {
817  Object* e = get(i);
818  if (e->IsMap()) {
819  Map::cast(e)->SharedMapVerify();
820  } else {
821  CHECK(e->IsUndefined());
822  }
823  }
824  }
825 }
826 
827 
828 #ifdef ENABLE_DEBUGGER_SUPPORT
829 void DebugInfo::DebugInfoVerify() {
830  CHECK(IsDebugInfo());
831  VerifyPointer(shared());
832  VerifyPointer(original_code());
833  VerifyPointer(code());
834  VerifyPointer(break_points());
835 }
836 
837 
838 void BreakPointInfo::BreakPointInfoVerify() {
839  CHECK(IsBreakPointInfo());
840  code_position()->SmiVerify();
841  source_position()->SmiVerify();
842  statement_position()->SmiVerify();
843  VerifyPointer(break_point_objects());
844 }
845 #endif // ENABLE_DEBUGGER_SUPPORT
846 #endif // VERIFY_HEAP
847 
848 #ifdef DEBUG
849 
850 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
851  info->number_of_objects_++;
852  // Named properties
853  if (HasFastProperties()) {
854  info->number_of_objects_with_fast_properties_++;
855  info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
856  info->number_of_fast_unused_fields_ += map()->unused_property_fields();
857  } else {
858  StringDictionary* dict = property_dictionary();
859  info->number_of_slow_used_properties_ += dict->NumberOfElements();
860  info->number_of_slow_unused_properties_ +=
861  dict->Capacity() - dict->NumberOfElements();
862  }
863  // Indexed properties
864  switch (GetElementsKind()) {
866  case FAST_SMI_ELEMENTS:
869  case FAST_HOLEY_ELEMENTS:
870  case FAST_ELEMENTS: {
871  info->number_of_objects_with_fast_elements_++;
872  int holes = 0;
873  FixedArray* e = FixedArray::cast(elements());
874  int len = e->length();
875  Heap* heap = HEAP;
876  for (int i = 0; i < len; i++) {
877  if (e->get(i) == heap->the_hole_value()) holes++;
878  }
879  info->number_of_fast_used_elements_ += len - holes;
880  info->number_of_fast_unused_elements_ += holes;
881  break;
882  }
892  info->number_of_objects_with_fast_elements_++;
893  ExternalPixelArray* e = ExternalPixelArray::cast(elements());
894  info->number_of_fast_used_elements_ += e->length();
895  break;
896  }
897  case DICTIONARY_ELEMENTS: {
898  SeededNumberDictionary* dict = element_dictionary();
899  info->number_of_slow_used_elements_ += dict->NumberOfElements();
900  info->number_of_slow_unused_elements_ +=
901  dict->Capacity() - dict->NumberOfElements();
902  break;
903  }
905  break;
906  }
907 }
908 
909 
910 void JSObject::SpillInformation::Clear() {
911  number_of_objects_ = 0;
912  number_of_objects_with_fast_properties_ = 0;
913  number_of_objects_with_fast_elements_ = 0;
914  number_of_fast_used_fields_ = 0;
915  number_of_fast_unused_fields_ = 0;
916  number_of_slow_used_properties_ = 0;
917  number_of_slow_unused_properties_ = 0;
918  number_of_fast_used_elements_ = 0;
919  number_of_fast_unused_elements_ = 0;
920  number_of_slow_used_elements_ = 0;
921  number_of_slow_unused_elements_ = 0;
922 }
923 
925  PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
926 
927  PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
928  number_of_objects_with_fast_properties_,
929  number_of_fast_used_fields_, number_of_fast_unused_fields_);
930 
931  PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
932  number_of_objects_ - number_of_objects_with_fast_properties_,
933  number_of_slow_used_properties_, number_of_slow_unused_properties_);
934 
935  PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
936  number_of_objects_with_fast_elements_,
937  number_of_fast_used_elements_, number_of_fast_unused_elements_);
938 
939  PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
940  number_of_objects_ - number_of_objects_with_fast_elements_,
941  number_of_slow_used_elements_, number_of_slow_unused_elements_);
942 
943  PrintF("\n");
944 }
945 
946 
947 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
948  if (valid_entries == -1) valid_entries = number_of_descriptors();
949  String* current_key = NULL;
950  uint32_t current = 0;
951  for (int i = 0; i < number_of_descriptors(); i++) {
952  String* key = GetSortedKey(i);
953  if (key == current_key) {
954  PrintDescriptors();
955  return false;
956  }
957  current_key = key;
958  uint32_t hash = GetSortedKey(i)->Hash();
959  if (hash < current) {
960  PrintDescriptors();
961  return false;
962  }
963  current = hash;
964  }
965  return true;
966 }
967 
968 
969 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
970  ASSERT(valid_entries == -1);
971  String* current_key = NULL;
972  uint32_t current = 0;
973  for (int i = 0; i < number_of_transitions(); i++) {
974  String* key = GetSortedKey(i);
975  if (key == current_key) {
976  PrintTransitions();
977  return false;
978  }
979  current_key = key;
980  uint32_t hash = GetSortedKey(i)->Hash();
981  if (hash < current) {
982  PrintTransitions();
983  return false;
984  }
985  current = hash;
986  }
987  return true;
988 }
989 
990 
991 static bool CheckOneBackPointer(Map* current_map, Object* target) {
992  return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
993 }
994 
995 
996 bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) {
997  if (HasElementsTransition() &&
998  !CheckOneBackPointer(current_map, elements_transition())) {
999  return false;
1000  }
1001  for (int i = 0; i < number_of_transitions(); ++i) {
1002  if (!CheckOneBackPointer(current_map, GetTarget(i))) return false;
1003  }
1004  return true;
1005 }
1006 
1007 
1008 #endif // DEBUG
1009 
1010 } } // namespace v8::internal
static const int kStartPositionOffset
Definition: objects.h:6541
byte * Address
Definition: globals.h:157
bool FLAG_enable_slow_asserts
static const int kArgumentsOffset
Definition: objects.h:6537
static const int kScopeInfoOffset
Definition: objects.h:6015
#define SLOW_ASSERT(condition)
Definition: checks.h:276
static const int kCodeOffset
Definition: objects.h:5796
#define CHECK_EQ(expected, value)
Definition: checks.h:219
static const int kIrregexpMaxRegisterCountIndex
Definition: objects.h:6657
static const int kPrototypeOrInitialMapOffset
Definition: objects.h:6183
static const int kCacheSizeIndex
Definition: objects.h:3377
static const int kBuiltinsOffset
Definition: objects.h:6285
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static const int kSize
Definition: objects.h:6350
static String * cast(Object *obj)
int unused_property_fields()
Definition: objects-inl.h:3019
static const int kStorage2Offset
Definition: objects.h:6923
int NumberOfOwnDescriptors()
Definition: objects.h:4944
static const int kOptimizedCodeMapOffset
Definition: objects.h:5797
static HeapObject * cast(Object *obj)
static JSBuiltinsObject * cast(Object *obj)
const int kVariableSizeSentinel
Definition: objects.h:199
static JSSet * cast(Object *obj)
SeededNumberDictionary * element_dictionary()
Definition: objects-inl.h:4905
static Map * cast(Object *obj)
static ByteArray * cast(Object *obj)
static FreeSpace * cast(Object *obj)
static Foreign * cast(Object *obj)
static const int kContextOffset
Definition: objects.h:6014
static const int kIrregexpASCIICodeIndex
Definition: objects.h:6642
#define ASSERT(condition)
Definition: checks.h:270
static const int kIrregexpUC16CodeIndex
Definition: objects.h:6646
v8::Handle< v8::Value > Print(const v8::Arguments &args)
static const int kIrregexpASCIICodeSavedIndex
Definition: objects.h:6650
static ExternalUnsignedShortArray * cast(Object *obj)
static const int kDebugInfoOffset
Definition: objects.h:5805
static JSRegExp * cast(Object *obj)
static const int kNativeContextOffset
Definition: objects.h:6234
static Context * cast(Object *context)
Definition: contexts.h:212
const intptr_t kCodeAlignment
Definition: v8globals.h:58
kPropertyAccessorsOffset kNamedPropertyHandlerOffset instance_template
Definition: objects-inl.h:3860
static SharedFunctionInfo * cast(Object *obj)
#define CHECK(condition)
Definition: checks.h:56
static const int kInstanceClassNameOffset
Definition: objects.h:5800
int isnan(double x)
#define CHECK_GE(a, b)
Definition: checks.h:228
static Code * cast(Object *obj)
static Smi * cast(Object *object)
static bool IsAscii(const char *chars, int length)
Definition: objects.h:7443
static ExternalShortArray * cast(Object *obj)
static const int kMinLength
Definition: objects.h:7666
static JSFunctionProxy * cast(Object *obj)
#define UNREACHABLE()
Definition: checks.h:50
static const int kIrregexpUC16CodeSavedIndex
Definition: objects.h:6653
static JSGlobalProxy * cast(Object *obj)
static const uint64_t kSignMask
Definition: double.h:43
static const int kAliasedContextSlot
Definition: objects.h:6968
static const int kStackFramesOffset
Definition: objects.h:6540
static SlicedString * cast(Object *obj)
static ExternalIntArray * cast(Object *obj)
int pre_allocated_property_fields()
Definition: objects-inl.h:2949
static const int kScopeInfoOffset
Definition: objects.h:5798
static Failure * cast(MaybeObject *object)
Definition: objects-inl.h:496
ElementsKind GetElementsKind()
Definition: objects-inl.h:4776
byte * instruction_start()
Definition: objects-inl.h:4649
const int kPointerSize
Definition: globals.h:220
static Oddball * cast(Object *obj)
bool IsAligned(T value, U alignment)
Definition: utils.h:206
static SeqAsciiString * cast(Object *obj)
static ExternalUnsignedByteArray * cast(Object *obj)
static const int kNameOffset
Definition: objects.h:5795
kPropertyAccessorsOffset named_property_handler
Definition: objects-inl.h:3856
static const int kStorage1Offset
Definition: objects.h:6922
static FixedDoubleArray * cast(Object *obj)
static ExternalPixelArray * cast(Object *obj)
static const int kMinLength
Definition: objects.h:7717
static const int kNextFunctionLinkOffset
Definition: objects.h:6190
static const int kIrregexpCaptureCountIndex
Definition: objects.h:6659
static JSMap * cast(Object *obj)
double get_scalar(int index)
Definition: objects-inl.h:1783
static JSMessageObject * cast(Object *obj)
Definition: objects-inl.h:4634
static const int kEndPositionOffset
Definition: objects.h:6542
#define CHECK_LE(a, b)
Definition: checks.h:230
static JSArray * cast(Object *obj)
static JSDate * cast(Object *obj)
Definition: objects-inl.h:4618
bool HasTransitionArray()
Definition: objects-inl.h:3675
static ExternalDoubleArray * cast(Object *obj)
static ExternalFloatArray * cast(Object *obj)
static const int kFunctionDataOffset
Definition: objects.h:5802
static HeapNumber * cast(Object *obj)
#define STRUCT_LIST(V)
Definition: objects.h:448
static const int kAtomPatternIndex
Definition: objects.h:6635
Map * GetTarget(int transition_number)
static bool UsesNativeRegExp()
Definition: jsregexp.h:48
static JSGlobalPropertyCell * cast(Object *obj)
Object * GetBackPointer()
Definition: objects-inl.h:3659
static JSValue * cast(Object *obj)
Definition: objects-inl.h:4600
static JSWeakMap * cast(Object *obj)
#define HEAP
Definition: isolate.h:1433
static const int kStackTraceOffset
Definition: objects.h:6539
InstanceType instance_type()
Definition: objects-inl.h:3009
static JSProxy * cast(Object *obj)
static double canonical_not_the_hole_nan_as_double()
Definition: objects-inl.h:1776
static FixedArray * cast(Object *obj)
static const int kScriptOffset
Definition: objects.h:5804
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
static VisitorId GetVisitorId(int instance_type, int instance_size)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
String * GetSortedKey(int transition_number)
Definition: transitions.h:67
static ExternalByteArray * cast(Object *obj)
static const int kScriptOffset
Definition: objects.h:6538
String * GetSortedKey(int descriptor_number)
Definition: objects-inl.h:2104
static const int kSize
Definition: objects.h:6312
static ConsString * cast(Object *obj)
static JSModule * cast(Object *obj)
Definition: objects-inl.h:4590
static const int kMaxValue
Definition: objects.h:1050
int NextFreePropertyIndex()
Definition: objects.cc:4241
static ExternalUnsignedIntArray * cast(Object *obj)
StringDictionary * property_dictionary()
Definition: objects-inl.h:4899
static JSObject * cast(Object *obj)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset access_check_info
Definition: objects-inl.h:3866
#define MAKE_STRUCT_CASE(NAME, Name, name)
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset flag
Definition: objects-inl.h:3923
static JSGlobalObject * cast(Object *obj)
static JSFunction * cast(Object *obj)