1// Copyright 2006-2008 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 34namespace v8 { 35namespace internal { 36 37#ifdef DEBUG 38 39static const char* TypeToString(InstanceType type); 40 41 42void Object::Print() { 43 if (IsSmi()) { 44 Smi::cast(this)->SmiPrint(); 45 } else if (IsFailure()) { 46 Failure::cast(this)->FailurePrint(); 47 } else { 48 HeapObject::cast(this)->HeapObjectPrint(); 49 } 50 Flush(); 51} 52 53 54void Object::PrintLn() { 55 Print(); 56 PrintF("\n"); 57} 58 59 60void Object::Verify() { 61 if (IsSmi()) { 62 Smi::cast(this)->SmiVerify(); 63 } else if (IsFailure()) { 64 Failure::cast(this)->FailureVerify(); 65 } else { 66 HeapObject::cast(this)->HeapObjectVerify(); 67 } 68} 69 70 71void Object::VerifyPointer(Object* p) { 72 if (p->IsHeapObject()) { 73 HeapObject::VerifyHeapPointer(p); 74 } else { 75 ASSERT(p->IsSmi()); 76 } 77} 78 79 80void Smi::SmiVerify() { 81 ASSERT(IsSmi()); 82} 83 84 85void Failure::FailureVerify() { 86 ASSERT(IsFailure()); 87} 88 89 90void HeapObject::PrintHeader(const char* id) { 91 PrintF("%p: [%s]\n", this, id); 92} 93 94 95void HeapObject::HeapObjectPrint() { 96 InstanceType instance_type = map()->instance_type(); 97 98 HandleScope scope; 99 if (instance_type < FIRST_NONSTRING_TYPE) { 100 String::cast(this)->StringPrint(); 101 return; 102 } 103 104 switch (instance_type) { 105 case MAP_TYPE: 106 Map::cast(this)->MapPrint(); 107 break; 108 case HEAP_NUMBER_TYPE: 109 HeapNumber::cast(this)->HeapNumberPrint(); 110 break; 111 case FIXED_ARRAY_TYPE: 112 FixedArray::cast(this)->FixedArrayPrint(); 113 break; 114 case BYTE_ARRAY_TYPE: 115 ByteArray::cast(this)->ByteArrayPrint(); 116 break; 117 case PIXEL_ARRAY_TYPE: 118 PixelArray::cast(this)->PixelArrayPrint(); 119 break; 120 case EXTERNAL_BYTE_ARRAY_TYPE: 121 ExternalByteArray::cast(this)->ExternalByteArrayPrint(); 122 break; 123 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 124 ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayPrint(); 125 break; 126 case EXTERNAL_SHORT_ARRAY_TYPE: 127 ExternalShortArray::cast(this)->ExternalShortArrayPrint(); 128 break; 129 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 130 ExternalUnsignedShortArray::cast(this)->ExternalUnsignedShortArrayPrint(); 131 break; 132 case EXTERNAL_INT_ARRAY_TYPE: 133 ExternalIntArray::cast(this)->ExternalIntArrayPrint(); 134 break; 135 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 136 ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(); 137 break; 138 case EXTERNAL_FLOAT_ARRAY_TYPE: 139 ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(); 140 break; 141 case FILLER_TYPE: 142 PrintF("filler"); 143 break; 144 case JS_OBJECT_TYPE: // fall through 145 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 146 case JS_ARRAY_TYPE: 147 case JS_REGEXP_TYPE: 148 JSObject::cast(this)->JSObjectPrint(); 149 break; 150 case ODDBALL_TYPE: 151 Oddball::cast(this)->to_string()->Print(); 152 break; 153 case JS_FUNCTION_TYPE: 154 JSFunction::cast(this)->JSFunctionPrint(); 155 break; 156 case JS_GLOBAL_PROXY_TYPE: 157 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(); 158 break; 159 case JS_GLOBAL_OBJECT_TYPE: 160 JSGlobalObject::cast(this)->JSGlobalObjectPrint(); 161 break; 162 case JS_BUILTINS_OBJECT_TYPE: 163 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(); 164 break; 165 case JS_VALUE_TYPE: 166 PrintF("Value wrapper around:"); 167 JSValue::cast(this)->value()->Print(); 168 break; 169 case CODE_TYPE: 170 Code::cast(this)->CodePrint(); 171 break; 172 case PROXY_TYPE: 173 Proxy::cast(this)->ProxyPrint(); 174 break; 175 case SHARED_FUNCTION_INFO_TYPE: 176 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(); 177 break; 178 case JS_GLOBAL_PROPERTY_CELL_TYPE: 179 JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(); 180 break; 181#define MAKE_STRUCT_CASE(NAME, Name, name) \ 182 case NAME##_TYPE: \ 183 Name::cast(this)->Name##Print(); \ 184 break; 185 STRUCT_LIST(MAKE_STRUCT_CASE) 186#undef MAKE_STRUCT_CASE 187 188 default: 189 PrintF("UNKNOWN TYPE %d", map()->instance_type()); 190 UNREACHABLE(); 191 break; 192 } 193} 194 195 196void HeapObject::HeapObjectVerify() { 197 InstanceType instance_type = map()->instance_type(); 198 199 if (instance_type < FIRST_NONSTRING_TYPE) { 200 String::cast(this)->StringVerify(); 201 return; 202 } 203 204 switch (instance_type) { 205 case MAP_TYPE: 206 Map::cast(this)->MapVerify(); 207 break; 208 case HEAP_NUMBER_TYPE: 209 HeapNumber::cast(this)->HeapNumberVerify(); 210 break; 211 case FIXED_ARRAY_TYPE: 212 FixedArray::cast(this)->FixedArrayVerify(); 213 break; 214 case BYTE_ARRAY_TYPE: 215 ByteArray::cast(this)->ByteArrayVerify(); 216 break; 217 case PIXEL_ARRAY_TYPE: 218 PixelArray::cast(this)->PixelArrayVerify(); 219 break; 220 case EXTERNAL_BYTE_ARRAY_TYPE: 221 ExternalByteArray::cast(this)->ExternalByteArrayVerify(); 222 break; 223 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 224 ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify(); 225 break; 226 case EXTERNAL_SHORT_ARRAY_TYPE: 227 ExternalShortArray::cast(this)->ExternalShortArrayVerify(); 228 break; 229 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 230 ExternalUnsignedShortArray::cast(this)-> 231 ExternalUnsignedShortArrayVerify(); 232 break; 233 case EXTERNAL_INT_ARRAY_TYPE: 234 ExternalIntArray::cast(this)->ExternalIntArrayVerify(); 235 break; 236 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 237 ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify(); 238 break; 239 case EXTERNAL_FLOAT_ARRAY_TYPE: 240 ExternalFloatArray::cast(this)->ExternalFloatArrayVerify(); 241 break; 242 case CODE_TYPE: 243 Code::cast(this)->CodeVerify(); 244 break; 245 case ODDBALL_TYPE: 246 Oddball::cast(this)->OddballVerify(); 247 break; 248 case JS_OBJECT_TYPE: 249 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 250 JSObject::cast(this)->JSObjectVerify(); 251 break; 252 case JS_VALUE_TYPE: 253 JSValue::cast(this)->JSValueVerify(); 254 break; 255 case JS_FUNCTION_TYPE: 256 JSFunction::cast(this)->JSFunctionVerify(); 257 break; 258 case JS_GLOBAL_PROXY_TYPE: 259 JSGlobalProxy::cast(this)->JSGlobalProxyVerify(); 260 break; 261 case JS_GLOBAL_OBJECT_TYPE: 262 JSGlobalObject::cast(this)->JSGlobalObjectVerify(); 263 break; 264 case JS_BUILTINS_OBJECT_TYPE: 265 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify(); 266 break; 267 case JS_GLOBAL_PROPERTY_CELL_TYPE: 268 JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify(); 269 break; 270 case JS_ARRAY_TYPE: 271 JSArray::cast(this)->JSArrayVerify(); 272 break; 273 case JS_REGEXP_TYPE: 274 JSRegExp::cast(this)->JSRegExpVerify(); 275 break; 276 case FILLER_TYPE: 277 break; 278 case PROXY_TYPE: 279 Proxy::cast(this)->ProxyVerify(); 280 break; 281 case SHARED_FUNCTION_INFO_TYPE: 282 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify(); 283 break; 284 285#define MAKE_STRUCT_CASE(NAME, Name, name) \ 286 case NAME##_TYPE: \ 287 Name::cast(this)->Name##Verify(); \ 288 break; 289 STRUCT_LIST(MAKE_STRUCT_CASE) 290#undef MAKE_STRUCT_CASE 291 292 default: 293 UNREACHABLE(); 294 break; 295 } 296} 297 298 299void HeapObject::VerifyHeapPointer(Object* p) { 300 ASSERT(p->IsHeapObject()); 301 ASSERT(Heap::Contains(HeapObject::cast(p))); 302} 303 304 305void HeapNumber::HeapNumberVerify() { 306 ASSERT(IsHeapNumber()); 307} 308 309 310void ByteArray::ByteArrayPrint() { 311 PrintF("byte array, data starts at %p", GetDataStartAddress()); 312} 313 314 315void PixelArray::PixelArrayPrint() { 316 PrintF("pixel array"); 317} 318 319 320void ExternalByteArray::ExternalByteArrayPrint() { 321 PrintF("external byte array"); 322} 323 324 325void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint() { 326 PrintF("external unsigned byte array"); 327} 328 329 330void ExternalShortArray::ExternalShortArrayPrint() { 331 PrintF("external short array"); 332} 333 334 335void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint() { 336 PrintF("external unsigned short array"); 337} 338 339 340void ExternalIntArray::ExternalIntArrayPrint() { 341 PrintF("external int array"); 342} 343 344 345void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint() { 346 PrintF("external unsigned int array"); 347} 348 349 350void ExternalFloatArray::ExternalFloatArrayPrint() { 351 PrintF("external float array"); 352} 353 354 355void ByteArray::ByteArrayVerify() { 356 ASSERT(IsByteArray()); 357} 358 359 360void PixelArray::PixelArrayVerify() { 361 ASSERT(IsPixelArray()); 362} 363 364 365void ExternalByteArray::ExternalByteArrayVerify() { 366 ASSERT(IsExternalByteArray()); 367} 368 369 370void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() { 371 ASSERT(IsExternalUnsignedByteArray()); 372} 373 374 375void ExternalShortArray::ExternalShortArrayVerify() { 376 ASSERT(IsExternalShortArray()); 377} 378 379 380void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() { 381 ASSERT(IsExternalUnsignedShortArray()); 382} 383 384 385void ExternalIntArray::ExternalIntArrayVerify() { 386 ASSERT(IsExternalIntArray()); 387} 388 389 390void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() { 391 ASSERT(IsExternalUnsignedIntArray()); 392} 393 394 395void ExternalFloatArray::ExternalFloatArrayVerify() { 396 ASSERT(IsExternalFloatArray()); 397} 398 399 400void JSObject::PrintProperties() { 401 if (HasFastProperties()) { 402 DescriptorArray* descs = map()->instance_descriptors(); 403 for (int i = 0; i < descs->number_of_descriptors(); i++) { 404 PrintF(" "); 405 descs->GetKey(i)->StringPrint(); 406 PrintF(": "); 407 switch (descs->GetType(i)) { 408 case FIELD: { 409 int index = descs->GetFieldIndex(i); 410 FastPropertyAt(index)->ShortPrint(); 411 PrintF(" (field at offset %d)\n", index); 412 break; 413 } 414 case CONSTANT_FUNCTION: 415 descs->GetConstantFunction(i)->ShortPrint(); 416 PrintF(" (constant function)\n"); 417 break; 418 case CALLBACKS: 419 descs->GetCallbacksObject(i)->ShortPrint(); 420 PrintF(" (callback)\n"); 421 break; 422 case MAP_TRANSITION: 423 PrintF(" (map transition)\n"); 424 break; 425 case CONSTANT_TRANSITION: 426 PrintF(" (constant transition)\n"); 427 break; 428 case NULL_DESCRIPTOR: 429 PrintF(" (null descriptor)\n"); 430 break; 431 default: 432 UNREACHABLE(); 433 break; 434 } 435 } 436 } else { 437 property_dictionary()->Print(); 438 } 439} 440 441 442void JSObject::PrintElements() { 443 switch (GetElementsKind()) { 444 case FAST_ELEMENTS: { 445 // Print in array notation for non-sparse arrays. 446 FixedArray* p = FixedArray::cast(elements()); 447 for (int i = 0; i < p->length(); i++) { 448 PrintF(" %d: ", i); 449 p->get(i)->ShortPrint(); 450 PrintF("\n"); 451 } 452 break; 453 } 454 case PIXEL_ELEMENTS: { 455 PixelArray* p = PixelArray::cast(elements()); 456 for (int i = 0; i < p->length(); i++) { 457 PrintF(" %d: %d\n", i, p->get(i)); 458 } 459 break; 460 } 461 case EXTERNAL_BYTE_ELEMENTS: { 462 ExternalByteArray* p = ExternalByteArray::cast(elements()); 463 for (int i = 0; i < p->length(); i++) { 464 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 465 } 466 break; 467 } 468 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 469 ExternalUnsignedByteArray* p = 470 ExternalUnsignedByteArray::cast(elements()); 471 for (int i = 0; i < p->length(); i++) { 472 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 473 } 474 break; 475 } 476 case EXTERNAL_SHORT_ELEMENTS: { 477 ExternalShortArray* p = ExternalShortArray::cast(elements()); 478 for (int i = 0; i < p->length(); i++) { 479 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 480 } 481 break; 482 } 483 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { 484 ExternalUnsignedShortArray* p = 485 ExternalUnsignedShortArray::cast(elements()); 486 for (int i = 0; i < p->length(); i++) { 487 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 488 } 489 break; 490 } 491 case EXTERNAL_INT_ELEMENTS: { 492 ExternalIntArray* p = ExternalIntArray::cast(elements()); 493 for (int i = 0; i < p->length(); i++) { 494 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 495 } 496 break; 497 } 498 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 499 ExternalUnsignedIntArray* p = 500 ExternalUnsignedIntArray::cast(elements()); 501 for (int i = 0; i < p->length(); i++) { 502 PrintF(" %d: %d\n", i, static_cast<int>(p->get(i))); 503 } 504 break; 505 } 506 case EXTERNAL_FLOAT_ELEMENTS: { 507 ExternalFloatArray* p = ExternalFloatArray::cast(elements()); 508 for (int i = 0; i < p->length(); i++) { 509 PrintF(" %d: %f\n", i, p->get(i)); 510 } 511 break; 512 } 513 case DICTIONARY_ELEMENTS: 514 elements()->Print(); 515 break; 516 default: 517 UNREACHABLE(); 518 break; 519 } 520} 521 522 523void JSObject::JSObjectPrint() { 524 PrintF("%p: [JSObject]\n", this); 525 PrintF(" - map = %p\n", map()); 526 PrintF(" - prototype = %p\n", GetPrototype()); 527 PrintF(" {\n"); 528 PrintProperties(); 529 PrintElements(); 530 PrintF(" }\n"); 531} 532 533 534void JSObject::JSObjectVerify() { 535 VerifyHeapPointer(properties()); 536 VerifyHeapPointer(elements()); 537 if (HasFastProperties()) { 538 CHECK_EQ(map()->unused_property_fields(), 539 (map()->inobject_properties() + properties()->length() - 540 map()->NextFreePropertyIndex())); 541 } 542} 543 544 545static const char* TypeToString(InstanceType type) { 546 switch (type) { 547 case INVALID_TYPE: return "INVALID"; 548 case MAP_TYPE: return "MAP"; 549 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER"; 550 case SYMBOL_TYPE: return "SYMBOL"; 551 case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL"; 552 case CONS_SYMBOL_TYPE: return "CONS_SYMBOL"; 553 case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL"; 554 case EXTERNAL_ASCII_SYMBOL_TYPE: 555 case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL"; 556 case ASCII_STRING_TYPE: return "ASCII_STRING"; 557 case STRING_TYPE: return "TWO_BYTE_STRING"; 558 case CONS_STRING_TYPE: 559 case CONS_ASCII_STRING_TYPE: return "CONS_STRING"; 560 case EXTERNAL_ASCII_STRING_TYPE: 561 case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING"; 562 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY"; 563 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY"; 564 case PIXEL_ARRAY_TYPE: return "PIXEL_ARRAY"; 565 case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY"; 566 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 567 return "EXTERNAL_UNSIGNED_BYTE_ARRAY"; 568 case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY"; 569 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 570 return "EXTERNAL_UNSIGNED_SHORT_ARRAY"; 571 case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY"; 572 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 573 return "EXTERNAL_UNSIGNED_INT_ARRAY"; 574 case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY"; 575 case FILLER_TYPE: return "FILLER"; 576 case JS_OBJECT_TYPE: return "JS_OBJECT"; 577 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT"; 578 case ODDBALL_TYPE: return "ODDBALL"; 579 case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL"; 580 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO"; 581 case JS_FUNCTION_TYPE: return "JS_FUNCTION"; 582 case CODE_TYPE: return "CODE"; 583 case JS_ARRAY_TYPE: return "JS_ARRAY"; 584 case JS_REGEXP_TYPE: return "JS_REGEXP"; 585 case JS_VALUE_TYPE: return "JS_VALUE"; 586 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT"; 587 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT"; 588 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY"; 589 case PROXY_TYPE: return "PROXY"; 590#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME; 591 STRUCT_LIST(MAKE_STRUCT_CASE) 592#undef MAKE_STRUCT_CASE 593 } 594 return "UNKNOWN"; 595} 596 597 598void Map::MapPrint() { 599 HeapObject::PrintHeader("Map"); 600 PrintF(" - type: %s\n", TypeToString(instance_type())); 601 PrintF(" - instance size: %d\n", instance_size()); 602 PrintF(" - inobject properties: %d\n", inobject_properties()); 603 PrintF(" - pre-allocated property fields: %d\n", 604 pre_allocated_property_fields()); 605 PrintF(" - unused property fields: %d\n", unused_property_fields()); 606 if (is_hidden_prototype()) { 607 PrintF(" - hidden_prototype\n"); 608 } 609 if (has_named_interceptor()) { 610 PrintF(" - named_interceptor\n"); 611 } 612 if (has_indexed_interceptor()) { 613 PrintF(" - indexed_interceptor\n"); 614 } 615 if (is_undetectable()) { 616 PrintF(" - undetectable\n"); 617 } 618 if (has_instance_call_handler()) { 619 PrintF(" - instance_call_handler\n"); 620 } 621 if (is_access_check_needed()) { 622 PrintF(" - access_check_needed\n"); 623 } 624 PrintF(" - instance descriptors: "); 625 instance_descriptors()->ShortPrint(); 626 PrintF("\n - prototype: "); 627 prototype()->ShortPrint(); 628 PrintF("\n - constructor: "); 629 constructor()->ShortPrint(); 630 PrintF("\n"); 631} 632 633 634void Map::MapVerify() { 635 ASSERT(!Heap::InNewSpace(this)); 636 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); 637 ASSERT(kPointerSize <= instance_size() 638 && instance_size() < Heap::Capacity()); 639 VerifyHeapPointer(prototype()); 640 VerifyHeapPointer(instance_descriptors()); 641} 642 643 644void FixedArray::FixedArrayPrint() { 645 HeapObject::PrintHeader("FixedArray"); 646 PrintF(" - length: %d", length()); 647 for (int i = 0; i < length(); i++) { 648 PrintF("\n [%d]: ", i); 649 get(i)->ShortPrint(); 650 } 651 PrintF("\n"); 652} 653 654 655void FixedArray::FixedArrayVerify() { 656 for (int i = 0; i < length(); i++) { 657 Object* e = get(i); 658 if (e->IsHeapObject()) { 659 VerifyHeapPointer(e); 660 } else { 661 e->Verify(); 662 } 663 } 664} 665 666 667void JSValue::JSValuePrint() { 668 HeapObject::PrintHeader("ValueObject"); 669 value()->Print(); 670} 671 672 673void JSValue::JSValueVerify() { 674 Object* v = value(); 675 if (v->IsHeapObject()) { 676 VerifyHeapPointer(v); 677 } 678} 679 680 681void String::StringPrint() { 682 if (StringShape(this).IsSymbol()) { 683 PrintF("#"); 684 } else if (StringShape(this).IsCons()) { 685 PrintF("c\""); 686 } else { 687 PrintF("\""); 688 } 689 690 for (int i = 0; i < length(); i++) { 691 PrintF("%c", Get(i)); 692 } 693 694 if (!StringShape(this).IsSymbol()) PrintF("\""); 695} 696 697 698void String::StringVerify() { 699 CHECK(IsString()); 700 CHECK(length() >= 0 && length() <= Smi::kMaxValue); 701 if (IsSymbol()) { 702 CHECK(!Heap::InNewSpace(this)); 703 } 704} 705 706 707void JSFunction::JSFunctionPrint() { 708 HeapObject::PrintHeader("Function"); 709 PrintF(" - map = 0x%p\n", map()); 710 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no"); 711 PrintF(" - initial_map = "); 712 if (has_initial_map()) { 713 initial_map()->ShortPrint(); 714 } 715 PrintF("\n - shared_info = "); 716 shared()->ShortPrint(); 717 PrintF("\n - name = "); 718 shared()->name()->Print(); 719 PrintF("\n - context = "); 720 unchecked_context()->ShortPrint(); 721 PrintF("\n - code = "); 722 code()->ShortPrint(); 723 PrintF("\n"); 724 725 PrintProperties(); 726 PrintElements(); 727 728 PrintF("\n"); 729} 730 731 732void JSFunction::JSFunctionVerify() { 733 CHECK(IsJSFunction()); 734 VerifyObjectField(kPrototypeOrInitialMapOffset); 735} 736 737 738void SharedFunctionInfo::SharedFunctionInfoPrint() { 739 HeapObject::PrintHeader("SharedFunctionInfo"); 740 PrintF(" - name: "); 741 name()->ShortPrint(); 742 PrintF("\n - expected_nof_properties: %d", expected_nof_properties()); 743 PrintF("\n - instance class name = "); 744 instance_class_name()->Print(); 745 PrintF("\n - code = "); 746 code()->ShortPrint(); 747 PrintF("\n - source code = "); 748 GetSourceCode()->ShortPrint(); 749 // Script files are often large, hard to read. 750 // PrintF("\n - script ="); 751 // script()->Print(); 752 PrintF("\n - function token position = %d", function_token_position()); 753 PrintF("\n - start position = %d", start_position()); 754 PrintF("\n - end position = %d", end_position()); 755 PrintF("\n - is expression = %d", is_expression()); 756 PrintF("\n - debug info = "); 757 debug_info()->ShortPrint(); 758 PrintF("\n - length = %d", length()); 759 PrintF("\n - has_only_simple_this_property_assignments = %d", 760 has_only_simple_this_property_assignments()); 761 PrintF("\n - this_property_assignments = "); 762 this_property_assignments()->ShortPrint(); 763 PrintF("\n"); 764} 765 766void SharedFunctionInfo::SharedFunctionInfoVerify() { 767 CHECK(IsSharedFunctionInfo()); 768 VerifyObjectField(kNameOffset); 769 VerifyObjectField(kCodeOffset); 770 VerifyObjectField(kInstanceClassNameOffset); 771 VerifyObjectField(kExternalReferenceDataOffset); 772 VerifyObjectField(kScriptOffset); 773 VerifyObjectField(kDebugInfoOffset); 774} 775 776 777void JSGlobalProxy::JSGlobalProxyPrint() { 778 PrintF("global_proxy"); 779 JSObjectPrint(); 780 PrintF("context : "); 781 context()->ShortPrint(); 782 PrintF("\n"); 783} 784 785 786void JSGlobalProxy::JSGlobalProxyVerify() { 787 CHECK(IsJSGlobalProxy()); 788 JSObjectVerify(); 789 VerifyObjectField(JSGlobalProxy::kContextOffset); 790 // Make sure that this object has no properties, elements. 791 CHECK_EQ(0, properties()->length()); 792 CHECK_EQ(0, elements()->length()); 793} 794 795 796void JSGlobalObject::JSGlobalObjectPrint() { 797 PrintF("global "); 798 JSObjectPrint(); 799 PrintF("global context : "); 800 global_context()->ShortPrint(); 801 PrintF("\n"); 802} 803 804 805void JSGlobalObject::JSGlobalObjectVerify() { 806 CHECK(IsJSGlobalObject()); 807 JSObjectVerify(); 808 for (int i = GlobalObject::kBuiltinsOffset; 809 i < JSGlobalObject::kSize; 810 i += kPointerSize) { 811 VerifyObjectField(i); 812 } 813} 814 815 816void JSBuiltinsObject::JSBuiltinsObjectPrint() { 817 PrintF("builtins "); 818 JSObjectPrint(); 819} 820 821 822void JSBuiltinsObject::JSBuiltinsObjectVerify() { 823 CHECK(IsJSBuiltinsObject()); 824 JSObjectVerify(); 825 for (int i = GlobalObject::kBuiltinsOffset; 826 i < JSBuiltinsObject::kSize; 827 i += kPointerSize) { 828 VerifyObjectField(i); 829 } 830} 831 832 833void Oddball::OddballVerify() { 834 CHECK(IsOddball()); 835 VerifyHeapPointer(to_string()); 836 Object* number = to_number(); 837 if (number->IsHeapObject()) { 838 ASSERT(number == Heap::nan_value()); 839 } else { 840 ASSERT(number->IsSmi()); 841 int value = Smi::cast(number)->value(); 842 ASSERT(value == 0 || value == 1 || value == -1 || 843 value == -2 || value == -3); 844 } 845} 846 847 848void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() { 849 CHECK(IsJSGlobalPropertyCell()); 850 VerifyObjectField(kValueOffset); 851} 852 853 854void JSGlobalPropertyCell::JSGlobalPropertyCellPrint() { 855 HeapObject::PrintHeader("JSGlobalPropertyCell"); 856} 857 858 859void Code::CodePrint() { 860 HeapObject::PrintHeader("Code"); 861#ifdef ENABLE_DISASSEMBLER 862 Disassemble(NULL); 863#endif 864} 865 866 867void Code::CodeVerify() { 868 CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()), 869 static_cast<intptr_t>(kCodeAlignment))); 870 Address last_gc_pc = NULL; 871 for (RelocIterator it(this); !it.done(); it.next()) { 872 it.rinfo()->Verify(); 873 // Ensure that GC will not iterate twice over the same pointer. 874 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) { 875 CHECK(it.rinfo()->pc() != last_gc_pc); 876 last_gc_pc = it.rinfo()->pc(); 877 } 878 } 879} 880 881 882void JSArray::JSArrayVerify() { 883 JSObjectVerify(); 884 ASSERT(length()->IsNumber() || length()->IsUndefined()); 885 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray()); 886} 887 888 889void JSRegExp::JSRegExpVerify() { 890 JSObjectVerify(); 891 ASSERT(data()->IsUndefined() || data()->IsFixedArray()); 892 switch (TypeTag()) { 893 case JSRegExp::ATOM: { 894 FixedArray* arr = FixedArray::cast(data()); 895 ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString()); 896 break; 897 } 898 case JSRegExp::IRREGEXP: { 899 bool is_native = RegExpImpl::UsesNativeRegExp(); 900 901 FixedArray* arr = FixedArray::cast(data()); 902 Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex); 903 // TheHole : Not compiled yet. 904 // JSObject: Compilation error. 905 // Code/ByteArray: Compiled code. 906 ASSERT(ascii_data->IsTheHole() || ascii_data->IsJSObject() || 907 (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray())); 908 Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex); 909 ASSERT(uc16_data->IsTheHole() || ascii_data->IsJSObject() || 910 (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray())); 911 ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi()); 912 ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi()); 913 break; 914 } 915 default: 916 ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag()); 917 ASSERT(data()->IsUndefined()); 918 break; 919 } 920} 921 922 923void Proxy::ProxyPrint() { 924 PrintF("proxy to %p", proxy()); 925} 926 927 928void Proxy::ProxyVerify() { 929 ASSERT(IsProxy()); 930} 931 932 933void AccessorInfo::AccessorInfoVerify() { 934 CHECK(IsAccessorInfo()); 935 VerifyPointer(getter()); 936 VerifyPointer(setter()); 937 VerifyPointer(name()); 938 VerifyPointer(data()); 939 VerifyPointer(flag()); 940 VerifyPointer(load_stub_cache()); 941} 942 943void AccessorInfo::AccessorInfoPrint() { 944 HeapObject::PrintHeader("AccessorInfo"); 945 PrintF("\n - getter: "); 946 getter()->ShortPrint(); 947 PrintF("\n - setter: "); 948 setter()->ShortPrint(); 949 PrintF("\n - name: "); 950 name()->ShortPrint(); 951 PrintF("\n - data: "); 952 data()->ShortPrint(); 953 PrintF("\n - flag: "); 954 flag()->ShortPrint(); 955} 956 957void AccessCheckInfo::AccessCheckInfoVerify() { 958 CHECK(IsAccessCheckInfo()); 959 VerifyPointer(named_callback()); 960 VerifyPointer(indexed_callback()); 961 VerifyPointer(data()); 962} 963 964void AccessCheckInfo::AccessCheckInfoPrint() { 965 HeapObject::PrintHeader("AccessCheckInfo"); 966 PrintF("\n - named_callback: "); 967 named_callback()->ShortPrint(); 968 PrintF("\n - indexed_callback: "); 969 indexed_callback()->ShortPrint(); 970 PrintF("\n - data: "); 971 data()->ShortPrint(); 972} 973 974void InterceptorInfo::InterceptorInfoVerify() { 975 CHECK(IsInterceptorInfo()); 976 VerifyPointer(getter()); 977 VerifyPointer(setter()); 978 VerifyPointer(query()); 979 VerifyPointer(deleter()); 980 VerifyPointer(enumerator()); 981 VerifyPointer(data()); 982} 983 984void InterceptorInfo::InterceptorInfoPrint() { 985 HeapObject::PrintHeader("InterceptorInfo"); 986 PrintF("\n - getter: "); 987 getter()->ShortPrint(); 988 PrintF("\n - setter: "); 989 setter()->ShortPrint(); 990 PrintF("\n - query: "); 991 query()->ShortPrint(); 992 PrintF("\n - deleter: "); 993 deleter()->ShortPrint(); 994 PrintF("\n - enumerator: "); 995 enumerator()->ShortPrint(); 996 PrintF("\n - data: "); 997 data()->ShortPrint(); 998} 999 1000void CallHandlerInfo::CallHandlerInfoVerify() { 1001 CHECK(IsCallHandlerInfo()); 1002 VerifyPointer(callback()); 1003 VerifyPointer(data()); 1004} 1005 1006void CallHandlerInfo::CallHandlerInfoPrint() { 1007 HeapObject::PrintHeader("CallHandlerInfo"); 1008 PrintF("\n - callback: "); 1009 callback()->ShortPrint(); 1010 PrintF("\n - data: "); 1011 data()->ShortPrint(); 1012} 1013 1014void TemplateInfo::TemplateInfoVerify() { 1015 VerifyPointer(tag()); 1016 VerifyPointer(property_list()); 1017} 1018 1019void FunctionTemplateInfo::FunctionTemplateInfoVerify() { 1020 CHECK(IsFunctionTemplateInfo()); 1021 TemplateInfoVerify(); 1022 VerifyPointer(serial_number()); 1023 VerifyPointer(call_code()); 1024 VerifyPointer(property_accessors()); 1025 VerifyPointer(prototype_template()); 1026 VerifyPointer(parent_template()); 1027 VerifyPointer(named_property_handler()); 1028 VerifyPointer(indexed_property_handler()); 1029 VerifyPointer(instance_template()); 1030 VerifyPointer(signature()); 1031 VerifyPointer(access_check_info()); 1032} 1033 1034void FunctionTemplateInfo::FunctionTemplateInfoPrint() { 1035 HeapObject::PrintHeader("FunctionTemplateInfo"); 1036 PrintF("\n - class name: "); 1037 class_name()->ShortPrint(); 1038 PrintF("\n - tag: "); 1039 tag()->ShortPrint(); 1040 PrintF("\n - property_list: "); 1041 property_list()->ShortPrint(); 1042 PrintF("\n - serial_number: "); 1043 serial_number()->ShortPrint(); 1044 PrintF("\n - call_code: "); 1045 call_code()->ShortPrint(); 1046 PrintF("\n - property_accessors: "); 1047 property_accessors()->ShortPrint(); 1048 PrintF("\n - prototype_template: "); 1049 prototype_template()->ShortPrint(); 1050 PrintF("\n - parent_template: "); 1051 parent_template()->ShortPrint(); 1052 PrintF("\n - named_property_handler: "); 1053 named_property_handler()->ShortPrint(); 1054 PrintF("\n - indexed_property_handler: "); 1055 indexed_property_handler()->ShortPrint(); 1056 PrintF("\n - instance_template: "); 1057 instance_template()->ShortPrint(); 1058 PrintF("\n - signature: "); 1059 signature()->ShortPrint(); 1060 PrintF("\n - access_check_info: "); 1061 access_check_info()->ShortPrint(); 1062 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false"); 1063 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false"); 1064 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false"); 1065} 1066 1067void ObjectTemplateInfo::ObjectTemplateInfoVerify() { 1068 CHECK(IsObjectTemplateInfo()); 1069 TemplateInfoVerify(); 1070 VerifyPointer(constructor()); 1071 VerifyPointer(internal_field_count()); 1072} 1073 1074void ObjectTemplateInfo::ObjectTemplateInfoPrint() { 1075 HeapObject::PrintHeader("ObjectTemplateInfo"); 1076 PrintF("\n - constructor: "); 1077 constructor()->ShortPrint(); 1078 PrintF("\n - internal_field_count: "); 1079 internal_field_count()->ShortPrint(); 1080} 1081 1082void SignatureInfo::SignatureInfoVerify() { 1083 CHECK(IsSignatureInfo()); 1084 VerifyPointer(receiver()); 1085 VerifyPointer(args()); 1086} 1087 1088void SignatureInfo::SignatureInfoPrint() { 1089 HeapObject::PrintHeader("SignatureInfo"); 1090 PrintF("\n - receiver: "); 1091 receiver()->ShortPrint(); 1092 PrintF("\n - args: "); 1093 args()->ShortPrint(); 1094} 1095 1096void TypeSwitchInfo::TypeSwitchInfoVerify() { 1097 CHECK(IsTypeSwitchInfo()); 1098 VerifyPointer(types()); 1099} 1100 1101void TypeSwitchInfo::TypeSwitchInfoPrint() { 1102 HeapObject::PrintHeader("TypeSwitchInfo"); 1103 PrintF("\n - types: "); 1104 types()->ShortPrint(); 1105} 1106 1107 1108void Script::ScriptVerify() { 1109 CHECK(IsScript()); 1110 VerifyPointer(source()); 1111 VerifyPointer(name()); 1112 line_offset()->SmiVerify(); 1113 column_offset()->SmiVerify(); 1114 VerifyPointer(data()); 1115 VerifyPointer(wrapper()); 1116 type()->SmiVerify(); 1117 VerifyPointer(line_ends()); 1118 VerifyPointer(id()); 1119} 1120 1121 1122void Script::ScriptPrint() { 1123 HeapObject::PrintHeader("Script"); 1124 PrintF("\n - source: "); 1125 source()->ShortPrint(); 1126 PrintF("\n - name: "); 1127 name()->ShortPrint(); 1128 PrintF("\n - line_offset: "); 1129 line_offset()->ShortPrint(); 1130 PrintF("\n - column_offset: "); 1131 column_offset()->ShortPrint(); 1132 PrintF("\n - type: "); 1133 type()->ShortPrint(); 1134 PrintF("\n - id: "); 1135 id()->ShortPrint(); 1136 PrintF("\n - data: "); 1137 data()->ShortPrint(); 1138 PrintF("\n - context data: "); 1139 context_data()->ShortPrint(); 1140 PrintF("\n - wrapper: "); 1141 wrapper()->ShortPrint(); 1142 PrintF("\n - compilation type: "); 1143 compilation_type()->ShortPrint(); 1144 PrintF("\n - line ends: "); 1145 line_ends()->ShortPrint(); 1146 PrintF("\n - eval from shared: "); 1147 eval_from_shared()->ShortPrint(); 1148 PrintF("\n - eval from instructions offset: "); 1149 eval_from_instructions_offset()->ShortPrint(); 1150 PrintF("\n"); 1151} 1152 1153 1154#ifdef ENABLE_DEBUGGER_SUPPORT 1155void DebugInfo::DebugInfoVerify() { 1156 CHECK(IsDebugInfo()); 1157 VerifyPointer(shared()); 1158 VerifyPointer(original_code()); 1159 VerifyPointer(code()); 1160 VerifyPointer(break_points()); 1161} 1162 1163 1164void DebugInfo::DebugInfoPrint() { 1165 HeapObject::PrintHeader("DebugInfo"); 1166 PrintF("\n - shared: "); 1167 shared()->ShortPrint(); 1168 PrintF("\n - original_code: "); 1169 original_code()->ShortPrint(); 1170 PrintF("\n - code: "); 1171 code()->ShortPrint(); 1172 PrintF("\n - break_points: "); 1173 break_points()->Print(); 1174} 1175 1176 1177void BreakPointInfo::BreakPointInfoVerify() { 1178 CHECK(IsBreakPointInfo()); 1179 code_position()->SmiVerify(); 1180 source_position()->SmiVerify(); 1181 statement_position()->SmiVerify(); 1182 VerifyPointer(break_point_objects()); 1183} 1184 1185 1186void BreakPointInfo::BreakPointInfoPrint() { 1187 HeapObject::PrintHeader("BreakPointInfo"); 1188 PrintF("\n - code_position: %d", code_position()); 1189 PrintF("\n - source_position: %d", source_position()); 1190 PrintF("\n - statement_position: %d", statement_position()); 1191 PrintF("\n - break_point_objects: "); 1192 break_point_objects()->ShortPrint(); 1193} 1194#endif 1195 1196 1197void JSObject::IncrementSpillStatistics(SpillInformation* info) { 1198 info->number_of_objects_++; 1199 // Named properties 1200 if (HasFastProperties()) { 1201 info->number_of_objects_with_fast_properties_++; 1202 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex(); 1203 info->number_of_fast_unused_fields_ += map()->unused_property_fields(); 1204 } else { 1205 StringDictionary* dict = property_dictionary(); 1206 info->number_of_slow_used_properties_ += dict->NumberOfElements(); 1207 info->number_of_slow_unused_properties_ += 1208 dict->Capacity() - dict->NumberOfElements(); 1209 } 1210 // Indexed properties 1211 switch (GetElementsKind()) { 1212 case FAST_ELEMENTS: { 1213 info->number_of_objects_with_fast_elements_++; 1214 int holes = 0; 1215 FixedArray* e = FixedArray::cast(elements()); 1216 int len = e->length(); 1217 for (int i = 0; i < len; i++) { 1218 if (e->get(i) == Heap::the_hole_value()) holes++; 1219 } 1220 info->number_of_fast_used_elements_ += len - holes; 1221 info->number_of_fast_unused_elements_ += holes; 1222 break; 1223 } 1224 case PIXEL_ELEMENTS: { 1225 info->number_of_objects_with_fast_elements_++; 1226 PixelArray* e = PixelArray::cast(elements()); 1227 info->number_of_fast_used_elements_ += e->length(); 1228 break; 1229 } 1230 case DICTIONARY_ELEMENTS: { 1231 NumberDictionary* dict = element_dictionary(); 1232 info->number_of_slow_used_elements_ += dict->NumberOfElements(); 1233 info->number_of_slow_unused_elements_ += 1234 dict->Capacity() - dict->NumberOfElements(); 1235 break; 1236 } 1237 default: 1238 UNREACHABLE(); 1239 break; 1240 } 1241} 1242 1243 1244void JSObject::SpillInformation::Clear() { 1245 number_of_objects_ = 0; 1246 number_of_objects_with_fast_properties_ = 0; 1247 number_of_objects_with_fast_elements_ = 0; 1248 number_of_fast_used_fields_ = 0; 1249 number_of_fast_unused_fields_ = 0; 1250 number_of_slow_used_properties_ = 0; 1251 number_of_slow_unused_properties_ = 0; 1252 number_of_fast_used_elements_ = 0; 1253 number_of_fast_unused_elements_ = 0; 1254 number_of_slow_used_elements_ = 0; 1255 number_of_slow_unused_elements_ = 0; 1256} 1257 1258void JSObject::SpillInformation::Print() { 1259 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_); 1260 1261 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n", 1262 number_of_objects_with_fast_properties_, 1263 number_of_fast_used_fields_, number_of_fast_unused_fields_); 1264 1265 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n", 1266 number_of_objects_ - number_of_objects_with_fast_properties_, 1267 number_of_slow_used_properties_, number_of_slow_unused_properties_); 1268 1269 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n", 1270 number_of_objects_with_fast_elements_, 1271 number_of_fast_used_elements_, number_of_fast_unused_elements_); 1272 1273 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n", 1274 number_of_objects_ - number_of_objects_with_fast_elements_, 1275 number_of_slow_used_elements_, number_of_slow_unused_elements_); 1276 1277 PrintF("\n"); 1278} 1279 1280 1281void DescriptorArray::PrintDescriptors() { 1282 PrintF("Descriptor array %d\n", number_of_descriptors()); 1283 for (int i = 0; i < number_of_descriptors(); i++) { 1284 PrintF(" %d: ", i); 1285 Descriptor desc; 1286 Get(i, &desc); 1287 desc.Print(); 1288 } 1289 PrintF("\n"); 1290} 1291 1292 1293bool DescriptorArray::IsSortedNoDuplicates() { 1294 String* current_key = NULL; 1295 uint32_t current = 0; 1296 for (int i = 0; i < number_of_descriptors(); i++) { 1297 String* key = GetKey(i); 1298 if (key == current_key) { 1299 PrintDescriptors(); 1300 return false; 1301 } 1302 current_key = key; 1303 uint32_t hash = GetKey(i)->Hash(); 1304 if (hash < current) { 1305 PrintDescriptors(); 1306 return false; 1307 } 1308 current = hash; 1309 } 1310 return true; 1311} 1312 1313 1314#endif // DEBUG 1315 1316} } // namespace v8::internal 1317